// Go down the composite layer tree, setting properties to match their // content-side counterparts. static void SetShadowProperties(Layer* aLayer) { // FIXME: Bug 717688 -- Do these updates in LayerTransactionParent::RecvUpdate. LayerComposite* layerComposite = aLayer->AsLayerComposite(); // Set the layerComposite's base transform to the layer's base transform. layerComposite->SetShadowTransform(aLayer->GetBaseTransform()); layerComposite->SetShadowTransformSetByAnimation(false); layerComposite->SetShadowVisibleRegion(aLayer->GetVisibleRegion()); layerComposite->SetShadowClipRect(aLayer->GetClipRect()); layerComposite->SetShadowOpacity(aLayer->GetOpacity()); for (Layer* child = aLayer->GetFirstChild(); child; child = child->GetNextSibling()) { SetShadowProperties(child); } }
static void TranslateShadowLayer2D(Layer* aLayer, const gfxPoint& aTranslation) { // This layer might also be a scrollable layer and have an async transform. // To make sure we don't clobber that, we start with the shadow transform. // Any adjustments to the shadow transform made in this function in previous // frames have been cleared in ClearAsyncTransforms(), so such adjustments // will not compound over successive frames. Matrix layerTransform; if (!aLayer->GetLocalTransform().Is2D(&layerTransform)) { return; } // Apply the 2D translation to the layer transform. layerTransform._31 += aTranslation.x; layerTransform._32 += aTranslation.y; // The transform already takes the resolution scale into account. Since we // will apply the resolution scale again when computing the effective // transform, we must apply the inverse resolution scale here. Matrix4x4 layerTransform3D = Matrix4x4::From2D(layerTransform); if (ContainerLayer* c = aLayer->AsContainerLayer()) { layerTransform3D.Scale(1.0f/c->GetPreXScale(), 1.0f/c->GetPreYScale(), 1); } layerTransform3D = layerTransform3D * Matrix4x4().Scale(1.0f/aLayer->GetPostXScale(), 1.0f/aLayer->GetPostYScale(), 1); LayerComposite* layerComposite = aLayer->AsLayerComposite(); layerComposite->SetShadowTransform(layerTransform3D); layerComposite->SetShadowTransformSetByAnimation(false); const nsIntRect* clipRect = aLayer->GetClipRect(); if (clipRect) { nsIntRect transformedClipRect(*clipRect); transformedClipRect.MoveBy(aTranslation.x, aTranslation.y); layerComposite->SetShadowClipRect(&transformedClipRect); } }
static void TranslateShadowLayer2D(Layer* aLayer, const gfxPoint& aTranslation) { gfxMatrix layerTransform; if (!GetBaseTransform2D(aLayer, &layerTransform)) { return; } // Apply the 2D translation to the layer transform. layerTransform.x0 += aTranslation.x; layerTransform.y0 += aTranslation.y; // The transform already takes the resolution scale into account. Since we // will apply the resolution scale again when computing the effective // transform, we must apply the inverse resolution scale here. gfx3DMatrix layerTransform3D = gfx3DMatrix::From2D(layerTransform); if (ContainerLayer* c = aLayer->AsContainerLayer()) { layerTransform3D.Scale(1.0f/c->GetPreXScale(), 1.0f/c->GetPreYScale(), 1); } layerTransform3D.ScalePost(1.0f/aLayer->GetPostXScale(), 1.0f/aLayer->GetPostYScale(), 1); LayerComposite* layerComposite = aLayer->AsLayerComposite(); layerComposite->SetShadowTransform(layerTransform3D); layerComposite->SetShadowTransformSetByAnimation(false); const nsIntRect* clipRect = aLayer->GetClipRect(); if (clipRect) { nsIntRect transformedClipRect(*clipRect); transformedClipRect.MoveBy(aTranslation.x, aTranslation.y); layerComposite->SetShadowClipRect(&transformedClipRect); } }
// Go down shadow layer tree and apply transformations for scrollable layers. static void TransformShadowTree(nsDisplayListBuilder* aBuilder, nsFrameLoader* aFrameLoader, nsIFrame* aFrame, Layer* aLayer, const ViewTransform& aTransform, float aTempScaleDiffX = 1.0, float aTempScaleDiffY = 1.0) { LayerComposite* shadow = aLayer->AsLayerComposite(); shadow->SetShadowClipRect(aLayer->GetClipRect()); shadow->SetShadowVisibleRegion(aLayer->GetVisibleRegion()); shadow->SetShadowOpacity(aLayer->GetOpacity()); const FrameMetrics* metrics = GetFrameMetrics(aLayer); gfx3DMatrix shadowTransform = aLayer->GetTransform(); ViewTransform layerTransform = aTransform; if (metrics && metrics->IsScrollable()) { const ViewID scrollId = metrics->mScrollId; const nsContentView* view = aFrameLoader->GetCurrentRemoteFrame()->GetContentView(scrollId); NS_ABORT_IF_FALSE(view, "Array of views should be consistent with layer tree"); const gfx3DMatrix& currentTransform = aLayer->GetTransform(); const ViewConfig& config = view->GetViewConfig(); // With temporary scale we should compensate translation // using temporary scale value aTempScaleDiffX *= GetXScale(shadowTransform) * config.mXScale; aTempScaleDiffY *= GetYScale(shadowTransform) * config.mYScale; ViewTransform viewTransform = ComputeShadowTreeTransform( aFrame, aFrameLoader, metrics, view->GetViewConfig(), aTempScaleDiffX, aTempScaleDiffY ); // Apply the layer's own transform *before* the view transform shadowTransform = gfx3DMatrix(viewTransform) * currentTransform; layerTransform = viewTransform; if (metrics->IsRootScrollable()) { // Apply the translation *before* we do the rest of the transforms. nsIntPoint offset = GetContentRectLayerOffset(aFrame, aBuilder); shadowTransform = shadowTransform * gfx3DMatrix::Translation(float(offset.x), float(offset.y), 0.0); } } if (aLayer->GetIsFixedPosition() && !aLayer->GetParent()->GetIsFixedPosition()) { // Alter the shadow transform of fixed position layers in the situation // that the view transform's scroll position doesn't match the actual // scroll position, due to asynchronous layer scrolling. float offsetX = layerTransform.mTranslation.x; float offsetY = layerTransform.mTranslation.y; ReverseTranslate(shadowTransform, gfxPoint(offsetX, offsetY)); const nsIntRect* clipRect = shadow->GetShadowClipRect(); if (clipRect) { nsIntRect transformedClipRect(*clipRect); transformedClipRect.MoveBy(-offsetX, -offsetY); shadow->SetShadowClipRect(&transformedClipRect); } } // The transform already takes the resolution scale into account. Since we // will apply the resolution scale again when computing the effective // transform, we must apply the inverse resolution scale here. if (ContainerLayer* c = aLayer->AsContainerLayer()) { shadowTransform.Scale(1.0f/c->GetPreXScale(), 1.0f/c->GetPreYScale(), 1); } shadowTransform.ScalePost(1.0f/aLayer->GetPostXScale(), 1.0f/aLayer->GetPostYScale(), 1); shadow->SetShadowTransform(shadowTransform); for (Layer* child = aLayer->GetFirstChild(); child; child = child->GetNextSibling()) { TransformShadowTree(aBuilder, aFrameLoader, aFrame, child, layerTransform, aTempScaleDiffX, aTempScaleDiffY); } }