示例#1
0
/// Update the specified region of the widget.
/// \param widget The target Qt widget.
/// \param rect The region inside the widget.
/// \param waveform The waveform used to update screen. If it's INVALID, the default
/// waveform is applied.
/// \param update_whole Update whole screen or not.
/// \param wait The synchronous way between ScreenProxy and server.
void ScreenProxy::updateWidgetRegion(const QWidget *widget,
                                     const QRect &rect,
                                     Waveform waveform,
                                     bool update_whole,
                                     ScreenCommand::WaitMode wait)
{
    if (!isUpdateEnabled() && waveform != onyx::screen::ScreenProxy::DW)
    {
        return;
    }

    QRect & rc = screenRegion(widget, &rect);
    if (waveform == INVALID)
    {
        waveform = waveform_;
    }

    // Construct command.
    command_.type = ScreenCommand::SYNC_AND_UPDATE;
    command_.top = rc.top();
    command_.left = rc.left();
    command_.width = rc.width();
    command_.height = rc.height();
    command_.waveform = waveform;
    if (update_whole)
    {
        command_.update_flags = ScreenCommand::FULL_UPDATE;
    }
    else
    {
        command_.update_flags = ScreenCommand::PARTIAL_UPDATE;
    }
    sendCommand(command_, wait);
}
示例#2
0
/// This function asks screen daemon to copy data from
/// Qt framebuffer to display controller.
/// \param widget The source widget to copy data from.
/// \param region The region inside the widget. If it's NULL, all data in
/// widget is copied to display controller.
QRect & ScreenProxy::sync(const QWidget *widget,
                          const QRect * region)
{
    QRect & rc = screenRegion(widget, region);
    command_.type = ScreenCommand::SYNC;
    command_.top = rc.top();
    command_.left = rc.left();
    command_.width = rc.width();
    command_.height = rc.height();
    sendCommand(command_);
    return rc;
}
float
LayerManagerComposite::ComputeRenderIntegrity()
{
  // We only ever have incomplete rendering when progressive tiles are enabled.
  Layer* root = GetRoot();
  if (!gfxPlatform::GetPlatform()->UseProgressivePaint() || !root) {
    return 1.f;
  }

  FrameMetrics rootMetrics = LayerMetricsWrapper::TopmostScrollableMetrics(root);
  if (!rootMetrics.IsScrollable()) {
    // The root may not have any scrollable metrics, in which case rootMetrics
    // will just be an empty FrameMetrics. Instead use the actual metrics from
    // the root layer.
    rootMetrics = LayerMetricsWrapper(root).Metrics();
  }
  ParentLayerIntRect bounds = RoundedToInt(rootMetrics.GetCompositionBounds());
  IntRect screenRect(bounds.x,
                       bounds.y,
                       bounds.width,
                       bounds.height);

  float lowPrecisionMultiplier = 1.0f;
  float highPrecisionMultiplier = 1.0f;

#ifdef MOZ_WIDGET_ANDROID
  // Use the transform on the primary scrollable layer and its FrameMetrics
  // to find out how much of the viewport the current displayport covers
  nsTArray<Layer*> rootScrollableLayers;
  GetRootScrollableLayers(rootScrollableLayers);
  if (rootScrollableLayers.Length() > 0) {
    // This is derived from the code in
    // AsyncCompositionManager::TransformScrollableLayer
    Layer* rootScrollable = rootScrollableLayers[0];
    const FrameMetrics& metrics = LayerMetricsWrapper::TopmostScrollableMetrics(rootScrollable);
    Matrix4x4 transform = rootScrollable->GetEffectiveTransform();
    transform.PostScale(metrics.GetPresShellResolution(), metrics.GetPresShellResolution(), 1);

    // Clip the screen rect to the document bounds
    Rect documentBounds =
      transform.TransformBounds(Rect(metrics.GetScrollableRect().x - metrics.GetScrollOffset().x,
                                     metrics.GetScrollableRect().y - metrics.GetScrollOffset().y,
                                     metrics.GetScrollableRect().width,
                                     metrics.GetScrollableRect().height));
    documentBounds.RoundOut();
    screenRect = screenRect.Intersect(IntRect(documentBounds.x, documentBounds.y,
                                                documentBounds.width, documentBounds.height));

    // If the screen rect is empty, the user has scrolled entirely into
    // over-scroll and so we can be considered to have full integrity.
    if (screenRect.IsEmpty()) {
      return 1.0f;
    }

    // Work out how much of the critical display-port covers the screen
    bool hasLowPrecision = false;
    if (!metrics.GetCriticalDisplayPort().IsEmpty()) {
      hasLowPrecision = true;
      highPrecisionMultiplier =
        GetDisplayportCoverage(metrics.GetCriticalDisplayPort(), transform, screenRect);
    }

    // Work out how much of the display-port covers the screen
    if (!metrics.GetDisplayPort().IsEmpty()) {
      if (hasLowPrecision) {
        lowPrecisionMultiplier =
          GetDisplayportCoverage(metrics.GetDisplayPort(), transform, screenRect);
      } else {
        lowPrecisionMultiplier = highPrecisionMultiplier =
          GetDisplayportCoverage(metrics.GetDisplayPort(), transform, screenRect);
      }
    }
  }

  // If none of the screen is covered, we have zero integrity.
  if (highPrecisionMultiplier <= 0.0f && lowPrecisionMultiplier <= 0.0f) {
    return 0.0f;
  }
#endif // MOZ_WIDGET_ANDROID

  nsIntRegion screenRegion(screenRect);
  nsIntRegion lowPrecisionScreenRegion(screenRect);
  Matrix4x4 transform;
  ComputeRenderIntegrityInternal(root, screenRegion,
                                 lowPrecisionScreenRegion, transform);

  if (!screenRegion.IsEqual(screenRect)) {
    // Calculate the area of the region. All rects in an nsRegion are
    // non-overlapping.
    float screenArea = screenRect.width * screenRect.height;
    float highPrecisionIntegrity = screenRegion.Area() / screenArea;
    float lowPrecisionIntegrity = 1.f;
    if (!lowPrecisionScreenRegion.IsEqual(screenRect)) {
      lowPrecisionIntegrity = lowPrecisionScreenRegion.Area() / screenArea;
    }

    return ((highPrecisionIntegrity * highPrecisionMultiplier) +
            (lowPrecisionIntegrity * lowPrecisionMultiplier)) / 2;
  }

  return 1.f;
}
示例#4
0
float
LayerManagerComposite::ComputeRenderIntegrity()
{
  // We only ever have incomplete rendering when progressive tiles are enabled.
  Layer* root = GetRoot();
  if (!gfxPrefs::UseProgressiveTilePainting() || !root) {
    return 1.f;
  }

  const FrameMetrics& rootMetrics = root->GetFrameMetrics();
  ParentLayerIntRect bounds = RoundedToInt(rootMetrics.mCompositionBounds);
  nsIntRect screenRect(bounds.x,
                       bounds.y,
                       bounds.width,
                       bounds.height);

  float lowPrecisionMultiplier = 1.0f;
  float highPrecisionMultiplier = 1.0f;

#ifdef MOZ_ANDROID_OMTC
  // Use the transform on the primary scrollable layer and its FrameMetrics
  // to find out how much of the viewport the current displayport covers
  Layer* primaryScrollable = GetPrimaryScrollableLayer();
  if (primaryScrollable) {
    // This is derived from the code in
    // AsyncCompositionManager::TransformScrollableLayer
    const FrameMetrics& metrics = primaryScrollable->GetFrameMetrics();
    Matrix4x4 transform = primaryScrollable->GetEffectiveTransform();
    transform.ScalePost(metrics.mResolution.scale, metrics.mResolution.scale, 1);

    // Clip the screen rect to the document bounds
    Rect documentBounds =
      transform.TransformBounds(Rect(metrics.mScrollableRect.x - metrics.GetScrollOffset().x,
                                     metrics.mScrollableRect.y - metrics.GetScrollOffset().y,
                                     metrics.mScrollableRect.width,
                                     metrics.mScrollableRect.height));
    documentBounds.RoundOut();
    screenRect = screenRect.Intersect(nsIntRect(documentBounds.x, documentBounds.y,
                                                documentBounds.width, documentBounds.height));

    // If the screen rect is empty, the user has scrolled entirely into
    // over-scroll and so we can be considered to have full integrity.
    if (screenRect.IsEmpty()) {
      return 1.0f;
    }

    // Work out how much of the critical display-port covers the screen
    bool hasLowPrecision = false;
    if (!metrics.mCriticalDisplayPort.IsEmpty()) {
      hasLowPrecision = true;
      highPrecisionMultiplier =
        GetDisplayportCoverage(metrics.mCriticalDisplayPort, transform, screenRect);
    }

    // Work out how much of the display-port covers the screen
    if (!metrics.mDisplayPort.IsEmpty()) {
      if (hasLowPrecision) {
        lowPrecisionMultiplier =
          GetDisplayportCoverage(metrics.mDisplayPort, transform, screenRect);
      } else {
        lowPrecisionMultiplier = highPrecisionMultiplier =
          GetDisplayportCoverage(metrics.mDisplayPort, transform, screenRect);
      }
    }
  }

  // If none of the screen is covered, we have zero integrity.
  if (highPrecisionMultiplier <= 0.0f && lowPrecisionMultiplier <= 0.0f) {
    return 0.0f;
  }
#endif // MOZ_ANDROID_OMTC

  nsIntRegion screenRegion(screenRect);
  nsIntRegion lowPrecisionScreenRegion(screenRect);
  Matrix4x4 transform;
  ComputeRenderIntegrityInternal(root, screenRegion,
                                 lowPrecisionScreenRegion, transform);

  if (!screenRegion.IsEqual(screenRect)) {
    // Calculate the area of the region. All rects in an nsRegion are
    // non-overlapping.
    float screenArea = screenRect.width * screenRect.height;
    float highPrecisionIntegrity = screenRegion.Area() / screenArea;
    float lowPrecisionIntegrity = 1.f;
    if (!lowPrecisionScreenRegion.IsEqual(screenRect)) {
      lowPrecisionIntegrity = lowPrecisionScreenRegion.Area() / screenArea;
    }

    return ((highPrecisionIntegrity * highPrecisionMultiplier) +
            (lowPrecisionIntegrity * lowPrecisionMultiplier)) / 2;
  }

  return 1.f;
}