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()); }
void ClientTiledThebesLayer::BeginPaint() { if (ClientManager()->IsRepeatTransaction()) { return; } 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. ContainerLayer* scrollAncestor = nullptr; ContainerLayer* displayPortAncestor = nullptr; for (ContainerLayer* ancestor = GetParent(); ancestor; ancestor = ancestor->GetParent()) { const FrameMetrics& metrics = ancestor->GetFrameMetrics(); if (!scrollAncestor && metrics.GetScrollId() != FrameMetrics::NULL_SCROLL_ID) { scrollAncestor = ancestor; } if (!metrics.mDisplayPort.IsEmpty()) { displayPortAncestor = ancestor; // Any layer that has a displayport must be scrollable, so we can break // here. break; } } 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 Thebes layer with no scrollable container ancestor"); #endif return; } TILING_PRLOG(("TILING 0x%p: Found scrollAncestor 0x%p and displayPortAncestor 0x%p\n", this, scrollAncestor, displayPortAncestor)); const FrameMetrics& scrollMetrics = scrollAncestor->GetFrameMetrics(); const FrameMetrics& displayportMetrics = displayPortAncestor->GetFrameMetrics(); // Calculate the transform required to convert ParentLayer space of our // display port ancestor to the Layer space of this layer. gfx3DMatrix transformToDisplayPort = GetTransformToAncestorsParentLayer(this, displayPortAncestor); mPaintData.mTransformDisplayPortToLayer = transformToDisplayPort.Inverse(); // Note that below we use GetZoomToParent() in a number of places. Because this // code runs on the client side, the mTransformScale field of the FrameMetrics // will not have been set. This can result in incorrect values being returned // by GetZoomToParent() when we have CSS transforms set on some of these layers. // This code should be audited and updated as part of fixing bug 993525. // Compute the critical display port that applies to this layer in the // LayoutDevice space of this layer. ParentLayerRect criticalDisplayPort = (displayportMetrics.mCriticalDisplayPort * displayportMetrics.GetZoomToParent()) + displayportMetrics.mCompositionBounds.TopLeft(); mPaintData.mCriticalDisplayPort = RoundedOut( ApplyParentLayerToLayerTransform(mPaintData.mTransformDisplayPortToLayer, criticalDisplayPort)); TILING_PRLOG_OBJ(("TILING 0x%p: Critical displayport %s\n", this, tmpstr.get()), mPaintData.mCriticalDisplayPort); // Compute the viewport that applies to this layer in the LayoutDevice // space of this layer. ParentLayerRect viewport = (displayportMetrics.mViewport * displayportMetrics.GetZoomToParent()) + displayportMetrics.mCompositionBounds.TopLeft(); mPaintData.mViewport = ApplyParentLayerToLayerTransform( mPaintData.mTransformDisplayPortToLayer, viewport); TILING_PRLOG_OBJ(("TILING 0x%p: Viewport %s\n", this, tmpstr.get()), mPaintData.mViewport); // 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.GetZoomToParent(); TILING_PRLOG(("TILING 0x%p: Resolution %f\n", this, mPaintData.mResolution.scale)); // Store the applicable composition bounds in this layer's Layer units. gfx3DMatrix transformToCompBounds = GetTransformToAncestorsParentLayer(this, scrollAncestor); mPaintData.mCompositionBounds = ApplyParentLayerToLayerTransform( transformToCompBounds.Inverse(), ParentLayerRect(scrollMetrics.mCompositionBounds)); TILING_PRLOG_OBJ(("TILING 0x%p: Composition bounds %s\n", this, tmpstr.get()), mPaintData.mCompositionBounds); // Calculate the scroll offset since the last transaction mPaintData.mScrollOffset = displayportMetrics.GetScrollOffset() * displayportMetrics.GetZoomToParent(); TILING_PRLOG_OBJ(("TILING 0x%p: Scroll offset %s\n", this, tmpstr.get()), mPaintData.mScrollOffset); }
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()); }