bool
ClientTiledPaintedLayer::UseFastPath()
{
  LayerMetricsWrapper scrollAncestor;
  GetAncestorLayers(&scrollAncestor, nullptr);
  if (!scrollAncestor) {
    return true;
  }
  const FrameMetrics& parentMetrics = scrollAncestor.Metrics();

  bool multipleTransactionsNeeded = gfxPlatform::GetPlatform()->UseProgressivePaint()
                                 || gfxPrefs::UseLowPrecisionBuffer()
                                 || !parentMetrics.GetCriticalDisplayPort().IsEmpty();
  bool isFixed = GetIsFixedPosition() || GetParent()->GetIsFixedPosition();
  return !multipleTransactionsNeeded || isFixed || parentMetrics.GetDisplayPort().IsEmpty();
}
Пример #2
0
bool
ClientTiledPaintedLayer::UseProgressiveDraw() {
  if (!gfxPlatform::GetPlatform()->UseProgressivePaint()) {
    // pref is disabled, so never do progressive
    return false;
  }

  if (!mContentClient->GetTiledBuffer()->SupportsProgressiveUpdate()) {
    return false;
  }

  if (ClientManager()->HasShadowTarget()) {
    // This condition is true when we are in a reftest scenario. We don't want
    // to draw progressively here because it can cause intermittent reftest
    // failures because the harness won't wait for all the tiles to be drawn.
    return false;
  }

  if (mPaintData.mCriticalDisplayPort.IsEmpty()) {
    // This catches three scenarios:
    // 1) This layer doesn't have a scrolling ancestor
    // 2) This layer is subject to OMTA transforms
    // 3) Low-precision painting is disabled
    // In all of these cases, we don't want to draw this layer progressively.
    return false;
  }

  if (GetIsFixedPosition() || GetParent()->GetIsFixedPosition()) {
    // This layer is fixed-position and so even if it does have a scrolling
    // ancestor it will likely be entirely on-screen all the time, so we
    // should draw it all at once
    return false;
  }

  if (ClientManager()->AsyncPanZoomEnabled()) {
    LayerMetricsWrapper scrollAncestor;
    GetAncestorLayers(&scrollAncestor, nullptr, nullptr);
    MOZ_ASSERT(scrollAncestor); // because mPaintData.mCriticalDisplayPort is non-empty
    const FrameMetrics& parentMetrics = scrollAncestor.Metrics();
    if (!IsScrollingOnCompositor(parentMetrics)) {
      return false;
    }
  }

  return true;
}
bool
ClientTiledPaintedLayer::UseFastPath()
{
  LayerMetricsWrapper scrollAncestor;
  GetAncestorLayers(&scrollAncestor, nullptr);
  if (!scrollAncestor) {
    return true;
  }
  const FrameMetrics& parentMetrics = scrollAncestor.Metrics();

  bool multipleTransactionsNeeded = gfxPlatform::GetPlatform()->UseProgressivePaint()
                                 || gfxPrefs::UseLowPrecisionBuffer()
                                 || !parentMetrics.GetCriticalDisplayPort().IsEmpty();
  bool isFixed = GetIsFixedPosition() || GetParent()->GetIsFixedPosition();
  bool isScrollable = parentMetrics.IsScrollable();

  return !multipleTransactionsNeeded || isFixed || !isScrollable
#if !defined(MOZ_WIDGET_ANDROID) || defined(MOZ_ANDROID_APZ)
         || !IsScrollingOnCompositor(parentMetrics)
#endif
         ;
}
void
ClientTiledPaintedLayer::BeginPaint()
{
  mPaintData.mLowPrecisionPaintCount = 0;
  mPaintData.mPaintFinished = false;
  mPaintData.mCompositionBounds.SetEmpty();
  mPaintData.mCriticalDisplayPort.SetEmpty();

  if (!GetBaseTransform().Is2D()) {
    // Give up if there is a complex CSS transform on the layer. We might
    // eventually support these but for now it's too complicated to handle
    // given that it's a pretty rare scenario.
    return;
  }

  // Get the metrics of the nearest scrollable layer and the nearest layer
  // with a displayport.
  LayerMetricsWrapper scrollAncestor;
  LayerMetricsWrapper displayPortAncestor;
  GetAncestorLayers(&scrollAncestor, &displayPortAncestor);

  if (!displayPortAncestor || !scrollAncestor) {
    // No displayport or scroll ancestor, so we can't do progressive rendering.
#if defined(MOZ_WIDGET_ANDROID) || defined(MOZ_B2G)
    // Both Android and b2g are guaranteed to have a displayport set, so this
    // should never happen.
    NS_WARNING("Tiled PaintedLayer with no scrollable container ancestor");
#endif
    return;
  }

  TILING_LOG("TILING %p: Found scrollAncestor %p and displayPortAncestor %p\n", this,
    scrollAncestor.GetLayer(), displayPortAncestor.GetLayer());

  const FrameMetrics& scrollMetrics = scrollAncestor.Metrics();
  const FrameMetrics& displayportMetrics = displayPortAncestor.Metrics();

  // Calculate the transform required to convert ParentLayer space of our
  // display port ancestor to the Layer space of this layer.
  gfx::Matrix4x4 transformDisplayPortToLayer =
    GetTransformToAncestorsParentLayer(this, displayPortAncestor);
  transformDisplayPortToLayer.Invert();

  // Compute the critical display port that applies to this layer in the
  // LayoutDevice space of this layer.
  ParentLayerRect criticalDisplayPort =
    (displayportMetrics.GetCriticalDisplayPort() * displayportMetrics.GetZoom())
    + displayportMetrics.mCompositionBounds.TopLeft();
  mPaintData.mCriticalDisplayPort = RoundedOut(
    ApplyParentLayerToLayerTransform(transformDisplayPortToLayer, criticalDisplayPort));
  TILING_LOG("TILING %p: Critical displayport %s\n", this, Stringify(mPaintData.mCriticalDisplayPort).c_str());

  // Store the resolution from the displayport ancestor layer. Because this is Gecko-side,
  // before any async transforms have occurred, we can use the zoom for this.
  mPaintData.mResolution = displayportMetrics.GetZoom();
  TILING_LOG("TILING %p: Resolution %f\n", this, mPaintData.mPresShellResolution.scale);

  // Store the applicable composition bounds in this layer's Layer units.
  mPaintData.mTransformToCompBounds =
    GetTransformToAncestorsParentLayer(this, scrollAncestor);
  gfx::Matrix4x4 transformToBounds = mPaintData.mTransformToCompBounds;
  transformToBounds.Invert();
  mPaintData.mCompositionBounds = ApplyParentLayerToLayerTransform(
    transformToBounds, scrollMetrics.mCompositionBounds);
  TILING_LOG("TILING %p: Composition bounds %s\n", this, Stringify(mPaintData.mCompositionBounds).c_str());

  // Calculate the scroll offset since the last transaction
  mPaintData.mScrollOffset = displayportMetrics.GetScrollOffset() * displayportMetrics.GetZoom();
  TILING_LOG("TILING %p: Scroll offset %s\n", this, Stringify(mPaintData.mScrollOffset).c_str());
}
Пример #5
0
void
ClientTiledPaintedLayer::BeginPaint()
{
  mPaintData.ResetPaintData();

  if (!GetBaseTransform().Is2D()) {
    // Give up if there is a complex CSS transform on the layer. We might
    // eventually support these but for now it's too complicated to handle
    // given that it's a pretty rare scenario.
    return;
  }

  // Get the metrics of the nearest scrollable layer and the nearest layer
  // with a displayport.
  LayerMetricsWrapper scrollAncestor;
  LayerMetricsWrapper displayPortAncestor;
  bool hasTransformAnimation;
  GetAncestorLayers(&scrollAncestor, &displayPortAncestor, &hasTransformAnimation);

  if (!displayPortAncestor || !scrollAncestor) {
    // No displayport or scroll ancestor, so we can't do progressive rendering.
#if defined(MOZ_WIDGET_ANDROID) || defined(MOZ_WIDGET_GONK)
    // Both Android and b2g on phones are guaranteed to have a displayport set, so this
    // should never happen.
    NS_WARNING("Tiled PaintedLayer with no scrollable container ancestor");
#endif
    return;
  }

  TILING_LOG("TILING %p: Found scrollAncestor %p, displayPortAncestor %p, transform %d\n", this,
    scrollAncestor.GetLayer(), displayPortAncestor.GetLayer(), hasTransformAnimation);

  const FrameMetrics& scrollMetrics = scrollAncestor.Metrics();
  const FrameMetrics& displayportMetrics = displayPortAncestor.Metrics();

  // Calculate the transform required to convert ParentLayer space of our
  // display port ancestor to the Layer space of this layer.
  gfx::Matrix4x4 transformDisplayPortToLayer =
    GetTransformToAncestorsParentLayer(this, displayPortAncestor);
  transformDisplayPortToLayer.Invert();

  LayerRect layerBounds = ViewAs<LayerPixel>(Rect(GetLayerBounds()));

  // Compute the critical display port that applies to this layer in the
  // LayoutDevice space of this layer, but only if there is no OMT animation
  // on this layer. If there is an OMT animation then we need to draw the whole
  // visible region of this layer as determined by layout, because we don't know
  // what parts of it might move into view in the compositor.
  if (!hasTransformAnimation &&
      mContentClient->GetLowPrecisionTiledBuffer()) {
    ParentLayerRect criticalDisplayPort =
      (displayportMetrics.GetCriticalDisplayPort() * displayportMetrics.GetZoom())
      + displayportMetrics.GetCompositionBounds().TopLeft();
    Maybe<LayerRect> criticalDisplayPortTransformed =
      ApplyParentLayerToLayerTransform(transformDisplayPortToLayer, criticalDisplayPort, layerBounds);
    if (!criticalDisplayPortTransformed) {
      mPaintData.ResetPaintData();
      return;
    }
    mPaintData.mCriticalDisplayPort = RoundedToInt(*criticalDisplayPortTransformed);
  }
  TILING_LOG("TILING %p: Critical displayport %s\n", this, Stringify(mPaintData.mCriticalDisplayPort).c_str());

  // Store the resolution from the displayport ancestor layer. Because this is Gecko-side,
  // before any async transforms have occurred, we can use the zoom for this.
  mPaintData.mResolution = displayportMetrics.GetZoom();
  TILING_LOG("TILING %p: Resolution %s\n", this, Stringify(mPaintData.mResolution).c_str());

  // Store the applicable composition bounds in this layer's Layer units.
  mPaintData.mTransformToCompBounds =
    GetTransformToAncestorsParentLayer(this, scrollAncestor);
  gfx::Matrix4x4 transformToBounds = mPaintData.mTransformToCompBounds;
  transformToBounds.Invert();
  Maybe<LayerRect> compositionBoundsTransformed = ApplyParentLayerToLayerTransform(
    transformToBounds, scrollMetrics.GetCompositionBounds(), layerBounds);
  if (!compositionBoundsTransformed) {
    mPaintData.ResetPaintData();
    return;
  }
  mPaintData.mCompositionBounds = *compositionBoundsTransformed;
  TILING_LOG("TILING %p: Composition bounds %s\n", this, Stringify(mPaintData.mCompositionBounds).c_str());

  // Calculate the scroll offset since the last transaction
  mPaintData.mScrollOffset = displayportMetrics.GetScrollOffset() * displayportMetrics.GetZoom();
  TILING_LOG("TILING %p: Scroll offset %s\n", this, Stringify(mPaintData.mScrollOffset).c_str());
}