Bug 602431, part 5: Add an extra phase to update shadow-layer attributes (not used for anything interesting yet). r=tn
authorChris Jones <jones.chris.g@gmail.com>
Wed, 13 Oct 2010 17:55:45 -0500
changeset 55447 d580cff50255e93b1fc9396ddd04b8782b39f363
parent 55446 d35dc3b25cfa4d593e45976964e19523de72f027
child 55448 8652586c3908a26a37681eb94a31fbfc81184d3f
push idunknown
push userunknown
push dateunknown
reviewerstn
bugs602431
milestone2.0b8pre
Bug 602431, part 5: Add an extra phase to update shadow-layer attributes (not used for anything interesting yet). r=tn
layout/ipc/RenderFrameParent.cpp
layout/ipc/RenderFrameParent.h
--- a/layout/ipc/RenderFrameParent.cpp
+++ b/layout/ipc/RenderFrameParent.cpp
@@ -107,16 +107,53 @@ ComputeShadowTreeTransform(nsIFrame* aCo
   scrollCompensation.x -= aMetrics.mViewportScrollOffset.x * aConfig.mXScale;
   scrollCompensation.y -= aMetrics.mViewportScrollOffset.y * aConfig.mYScale;
   *aShadowTranslation -= scrollCompensation;
 
   *aShadowXScale = aConfig.mXScale;
   *aShadowYScale = aConfig.mYScale;
 }
 
+static void
+UpdateShadowSubtree(Layer* aSubtreeRoot)
+{
+  ShadowLayer* shadow = aSubtreeRoot->AsShadowLayer();
+
+  shadow->SetShadowClipRect(aSubtreeRoot->GetClipRect());
+  shadow->SetShadowTransform(aSubtreeRoot->GetTransform());
+  shadow->SetShadowVisibleRegion(aSubtreeRoot->GetVisibleRegion());
+
+  for (Layer* child = aSubtreeRoot->GetFirstChild(); child;
+       child = child->GetNextSibling()) {
+    UpdateShadowSubtree(child);
+  }
+}
+
+static void
+TransformShadowTreeTo(ContainerLayer* aRoot,
+                      const nsIntRect& aVisibleRect,
+                      const nsIntPoint& aTranslation,
+                      float aXScale, float aYScale)
+{
+  UpdateShadowSubtree(aRoot);
+
+  ShadowLayer* shadow = aRoot->AsShadowLayer();
+  NS_ABORT_IF_FALSE(aRoot->GetTransform() == shadow->GetShadowTransform(),
+                    "transforms should be the same now");
+  NS_ABORT_IF_FALSE(aRoot->GetTransform().Is2D(),
+                    "only 2D transforms expected currently");
+  gfxMatrix shadowTransform;
+  shadow->GetShadowTransform().Is2D(&shadowTransform);
+  // Pre-multiply this transform into the shadow's transform, so that
+  // it occurs before any transform set by the child
+  shadowTransform.Translate(gfxPoint(aTranslation.x, aTranslation.y));
+  shadowTransform.Scale(aXScale, aYScale);
+  shadow->SetShadowTransform(gfx3DMatrix::From2D(shadowTransform));
+}
+
 static Layer*
 ShadowRootOf(ContainerLayer* aContainer)
 {
   NS_ABORT_IF_FALSE(aContainer, "need a non-null container");
 
   Layer* shadowRoot = aContainer->GetFirstChild();
   NS_ABORT_IF_FALSE(!shadowRoot || nsnull == shadowRoot->GetNextSibling(),
                     "shadow root container may only have 0 or 1 children");
@@ -167,17 +204,18 @@ RenderFrameParent::ShadowLayersUpdated()
   // way to repaint shadow layers from this process.
   nsRect rect = nsRect(nsPoint(0, 0), docFrame->GetRect().Size());
   docFrame->InvalidateWithFlags(rect, nsIFrame::INVALIDATE_NO_THEBES_LAYERS);
 }
 
 already_AddRefed<Layer>
 RenderFrameParent::BuildLayer(nsDisplayListBuilder* aBuilder,
                               nsIFrame* aFrame,
-                              LayerManager* aManager)
+                              LayerManager* aManager,
+                              const nsIntRect& aVisibleRect)
 {
   NS_ABORT_IF_FALSE(aFrame,
                     "makes no sense to have a shadow tree without a frame");
   NS_ABORT_IF_FALSE(!mContainer ||
                     IsTempLayerManager(aManager) ||
                     mContainer->Manager() == aManager,
                     "retaining manager changed out from under us ... HELP!");
 
@@ -223,16 +261,20 @@ RenderFrameParent::BuildLayer(nsDisplayL
     nsIntPoint shadowTranslation;
     float shadowXScale, shadowYScale;
     ComputeShadowTreeTransform(aFrame,
                                shadowRoot->GetFrameMetrics(),
                                mFrameLoader->GetViewportConfig(),
                                aBuilder,
                                &shadowTranslation,
                                &shadowXScale, &shadowYScale);
+    TransformShadowTreeTo(shadowRoot, aVisibleRect,
+                          shadowTranslation, shadowXScale, shadowYScale);
+    // FIXME/bug 602431: this is dead code that will be obsoleted in
+    // favor of the above transformations
     gfxMatrix transform;
     transform.Translate(gfxPoint(shadowTranslation.x, shadowTranslation.y));
     transform.Scale(shadowXScale, shadowYScale);
     mContainer->SetTransform(gfx3DMatrix::From2D(transform));
     mContainer->SetClipRect(nsnull);
   }
 
   AssertValidContainerOfShadowTree(mContainer, shadowRoot);
@@ -300,11 +342,13 @@ RenderFrameParent::GetRootLayer() const
 
 }  // namespace layout
 }  // namespace mozilla
 
 already_AddRefed<Layer>
 nsDisplayRemote::BuildLayer(nsDisplayListBuilder* aBuilder,
                             LayerManager* aManager)
 {
-  nsRefPtr<Layer> layer = mRemoteFrame->BuildLayer(aBuilder, mFrame, aManager);
+  PRInt32 appUnitsPerDevPixel = mFrame->PresContext()->AppUnitsPerDevPixel();
+  nsIntRect visibleRect = GetVisibleRect().ToNearestPixels(appUnitsPerDevPixel);
+  nsRefPtr<Layer> layer = mRemoteFrame->BuildLayer(aBuilder, mFrame, aManager, visibleRect);
   return layer.forget();
 }
--- a/layout/ipc/RenderFrameParent.h
+++ b/layout/ipc/RenderFrameParent.h
@@ -67,17 +67,18 @@ class RenderFrameParent : public PRender
 public:
   RenderFrameParent(nsFrameLoader* aFrameLoader);
   virtual ~RenderFrameParent();
 
   void ShadowLayersUpdated();
 
   already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
                                      nsIFrame* aFrame,
-                                     LayerManager* aManager);
+                                     LayerManager* aManager,
+                                     const nsIntRect& aVisibleRect);
 
 protected:
   NS_OVERRIDE void ActorDestroy(ActorDestroyReason why);
 
   NS_OVERRIDE virtual PLayersParent* AllocPLayers();
   NS_OVERRIDE virtual bool DeallocPLayers(PLayersParent* aLayers);
 
 private: