Bug 890279 - Create ScrollInfoLayers for frames we want APZC support. r=kats
authorBenoit Girard <b56girard@gmail.com>
Tue, 02 Jul 2013 11:16:05 -0400
changeset 137871 48d6452c9d104d5937739e7d4fe1ba89210242dc
parent 137870 24c5584de2205ed2a74dda60edf9f705f5a23211
child 137872 e051a209206c3b1e9271b975421886e92eaf45b9
push id24939
push userryanvm@gmail.com
push dateWed, 10 Jul 2013 17:49:39 +0000
treeherdermozilla-central@dde4dcd6fa46 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskats
bugs890279
milestone25.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 890279 - Create ScrollInfoLayers for frames we want APZC support. r=kats
gfx/layers/composite/ContainerLayerComposite.cpp
gfx/layers/ipc/AsyncPanZoomController.cpp
gfx/tests/gtest/TestAsyncPanZoomController.cpp
layout/base/nsDisplayList.cpp
layout/generic/nsGfxScrollFrame.cpp
--- a/gfx/layers/composite/ContainerLayerComposite.cpp
+++ b/gfx/layers/composite/ContainerLayerComposite.cpp
@@ -104,17 +104,18 @@ ContainerRender(ContainerT* aContainer,
   aContainer->SortChildrenBy3DZOrder(children);
 
   /**
    * Render this container's contents.
    */
   for (uint32_t i = 0; i < children.Length(); i++) {
     LayerComposite* layerToRender = static_cast<LayerComposite*>(children.ElementAt(i)->ImplData());
 
-    if (layerToRender->GetLayer()->GetEffectiveVisibleRegion().IsEmpty()) {
+    if (layerToRender->GetLayer()->GetEffectiveVisibleRegion().IsEmpty() &&
+        !layerToRender->GetLayer()->AsContainerLayer()) {
       continue;
     }
 
     nsIntRect clipRect = layerToRender->GetLayer()->
         CalculateScissorRect(aClipRect, &aManager->GetWorldTransform());
     if (clipRect.IsEmpty()) {
       continue;
     }
@@ -149,17 +150,19 @@ ContainerRender(ContainerT* aContainer,
     aManager->GetCompositor()->DrawQuad(rect, clipRect, effectChain, opacity,
                                         transform, gfx::Point(aOffset.x, aOffset.y));
   }
 
   if (aContainer->GetFrameMetrics().IsScrollable()) {
     gfx::Matrix4x4 transform;
     ToMatrix4x4(aContainer->GetEffectiveTransform(), transform);
 
-    gfx::Rect rect(visibleRect.x, visibleRect.y, visibleRect.width, visibleRect.height);
+    const FrameMetrics& frame = aContainer->GetFrameMetrics();
+    LayerRect layerViewport = frame.mViewport * frame.LayersPixelsPerCSSPixel();
+    gfx::Rect rect(layerViewport.x, layerViewport.y, layerViewport.width, layerViewport.height);
     gfx::Rect clipRect(aClipRect.x, aClipRect.y, aClipRect.width, aClipRect.height);
     aManager->GetCompositor()->DrawDiagnostics(gfx::Color(1.0, 0.0, 0.0, 1.0),
                                                rect, clipRect,
                                                transform, gfx::Point(aOffset.x, aOffset.y));
   }
 }
 
 ContainerLayerComposite::ContainerLayerComposite(LayerManagerComposite *aManager)
--- a/gfx/layers/ipc/AsyncPanZoomController.cpp
+++ b/gfx/layers/ipc/AsyncPanZoomController.cpp
@@ -1475,20 +1475,22 @@ static void GetAPZCAtPointOnSubtree(cons
       GetAPZCAtPointOnSubtree(*currLayer->AsContainerLayer(), layerPoint, aApzcOut, aRelativePointOut);
     }
     if (*aApzcOut) {
         return;
     }
     currLayer = currLayer->GetPrevSibling();
   }
 
-  bool intersect = aLayer.GetVisibleRegion().Contains(nsIntRect(layerPoint.x, layerPoint.y, 1, 1));
+  if (aLayer.GetFrameMetrics().IsScrollable()) {
+    const FrameMetrics& frame = aLayer.GetFrameMetrics();
+    LayerRect layerViewport = frame.mViewport * frame.LayersPixelsPerCSSPixel();
+    bool intersect = layerViewport.Contains(layerPoint.x, layerPoint.y);
 
-  if (intersect) {
-    if (aLayer.GetFrameMetrics().IsScrollable()) {
+    if (intersect) {
       *aApzcOut = aLayer.GetAsyncPanZoomController();
       *aRelativePointOut = LayerIntPoint(NS_lround(layerPoint.x), NS_lround(layerPoint.y));
     }
   }
 
 }
 
 void AsyncPanZoomController::GetAPZCAtPoint(const ContainerLayer& aLayerTree,
--- a/gfx/tests/gtest/TestAsyncPanZoomController.cpp
+++ b/gfx/tests/gtest/TestAsyncPanZoomController.cpp
@@ -332,53 +332,63 @@ TEST(AsyncPanZoomController, GetAPZCAtPo
 
   nsRefPtr<MockContentController> mcc = new MockContentController();
   nsRefPtr<AsyncPanZoomController> apzcMain = new AsyncPanZoomController(mcc);
   nsRefPtr<AsyncPanZoomController> apzcSub3 = new AsyncPanZoomController(mcc);
   nsRefPtr<AsyncPanZoomController> apzcSub4 = new AsyncPanZoomController(mcc);
   nsRefPtr<AsyncPanZoomController> apzcSub7 = new AsyncPanZoomController(mcc);
   apzcMain->NotifyLayersUpdated(TestFrameMetrics(), true);
 
+  nsIntRect layerBound;
   ScreenIntPoint touchPoint(20, 20);
   AsyncPanZoomController* apzcOut;
   LayerIntPoint relativePointOut;
 
   FrameMetrics scrollable;
 
   // No APZC attached so hit testing will return no APZC at (20,20)
   AsyncPanZoomController::GetAPZCAtPoint(*root->AsContainerLayer(), touchPoint,
                  &apzcOut, &relativePointOut);
 
   AsyncPanZoomController* nullAPZC = nullptr;
   EXPECT_EQ(apzcOut, nullAPZC);
 
   // Now we have a root APZC that will match the page
   scrollable.mScrollId = FrameMetrics::ROOT_SCROLL_ID;
+  layerBound = root->GetVisibleRegion().GetBounds();
+  scrollable.mViewport = CSSRect(layerBound.x, layerBound.y,
+                                 layerBound.width, layerBound.height);
   root->AsContainerLayer()->SetFrameMetrics(scrollable);
   root->AsContainerLayer()->SetAsyncPanZoomController(apzcMain);
   AsyncPanZoomController::GetAPZCAtPoint(*root->AsContainerLayer(), touchPoint,
                  &apzcOut, &relativePointOut);
   EXPECT_EQ(apzcOut, apzcMain.get());
   EXPECT_EQ(LayerIntPoint(20, 20), relativePointOut);
 
   // Now we have a sub APZC with a better fit
   scrollable.mScrollId = FrameMetrics::START_SCROLL_ID;
+  layerBound = layers[3]->GetVisibleRegion().GetBounds();
+  scrollable.mViewport = CSSRect(layerBound.x, layerBound.y,
+                                 layerBound.width, layerBound.height);
   layers[3]->AsContainerLayer()->SetFrameMetrics(scrollable);
   layers[3]->AsContainerLayer()->SetAsyncPanZoomController(apzcSub3);
   AsyncPanZoomController::GetAPZCAtPoint(*root->AsContainerLayer(), touchPoint,
                  &apzcOut, &relativePointOut);
   EXPECT_EQ(apzcOut, apzcSub3.get());
   EXPECT_EQ(LayerIntPoint(20, 20), relativePointOut);
 
   // Now test hit testing when we have two scrollable layers
   touchPoint = ScreenIntPoint(15,15);
   AsyncPanZoomController::GetAPZCAtPoint(*root->AsContainerLayer(), touchPoint,
                  &apzcOut, &relativePointOut);
   EXPECT_EQ(apzcOut, apzcSub3.get()); // We haven't bound apzcSub4 yet
   scrollable.mScrollId++;
+  layerBound = layers[4]->GetVisibleRegion().GetBounds();
+  scrollable.mViewport = CSSRect(layerBound.x, layerBound.y,
+                                 layerBound.width, layerBound.height);
   layers[4]->AsContainerLayer()->SetFrameMetrics(scrollable);
   layers[4]->AsContainerLayer()->SetAsyncPanZoomController(apzcSub4);
   AsyncPanZoomController::GetAPZCAtPoint(*root->AsContainerLayer(), touchPoint,
                  &apzcOut, &relativePointOut);
   EXPECT_EQ(apzcOut, apzcSub4.get());
   EXPECT_EQ(LayerIntPoint(15, 15), relativePointOut);
 
   // Hit test ouside the reach of apzc3/4 but inside apzcMain
@@ -420,16 +430,19 @@ TEST(AsyncPanZoomController, GetAPZCAtPo
   // Does not contain (2, 2)
   AsyncPanZoomController::GetAPZCAtPoint(*root->AsContainerLayer(), touchPoint,
                  &apzcOut, &relativePointOut);
   EXPECT_EQ(apzcOut, apzcSub3.get());
   EXPECT_EQ(LayerIntPoint(20, 20), relativePointOut);
 
   // Transformation chain to layer 7
   scrollable.mScrollId++;
+  layerBound = layers[7]->GetVisibleRegion().GetBounds();
+  scrollable.mViewport = CSSRect(layerBound.x, layerBound.y,
+                                 layerBound.width, layerBound.height);
   layers[7]->AsContainerLayer()->SetFrameMetrics(scrollable);
   layers[7]->AsContainerLayer()->SetAsyncPanZoomController(apzcSub7);
 
   gfx3DMatrix translateTransform;
   translateTransform.Translate(gfxPoint3D(10, 10, 0));
   layers[5]->SetBaseTransform(translateTransform);
 
   gfx3DMatrix translateTransform2;
--- a/layout/base/nsDisplayList.cpp
+++ b/layout/base/nsDisplayList.cpp
@@ -630,17 +630,17 @@ static void RecordFrameMetrics(nsIFrame*
                                const nsDisplayItem::ContainerParameters& aContainerParameters,
                                bool aMayHaveTouchListeners) {
   nsPresContext* presContext = aForFrame->PresContext();
   int32_t auPerDevPixel = presContext->AppUnitsPerDevPixel();
   LayoutDeviceToLayerScale resolution(aContainerParameters.mXScale, aContainerParameters.mYScale);
 
   nsIntRect visible = aVisibleRect.ScaleToNearestPixels(
     resolution.scale, resolution.scale, auPerDevPixel);
-  aRoot->SetVisibleRegion(nsIntRegion(visible));
+  aRoot->SetVisibleRegion(visible);
 
   FrameMetrics metrics;
   metrics.mViewport = CSSRect::FromAppUnits(aViewport);
   if (aDisplayPort) {
     metrics.mDisplayPort = CSSRect::FromAppUnits(*aDisplayPort);
     if (aCriticalDisplayPort) {
       metrics.mCriticalDisplayPort = CSSRect::FromAppUnits(*aCriticalDisplayPort);
     }
@@ -3273,17 +3273,17 @@ nsDisplayScrollLayer::RemoveScrollLayerC
   return result;
 }
 
 
 nsDisplayScrollInfoLayer::nsDisplayScrollInfoLayer(
   nsDisplayListBuilder* aBuilder,
   nsIFrame* aScrolledFrame,
   nsIFrame* aScrollFrame)
-  : nsDisplayScrollLayer(aBuilder, aScrolledFrame, aScrolledFrame, aScrollFrame)
+  : nsDisplayScrollLayer(aBuilder, aScrollFrame, aScrolledFrame, aScrollFrame)
 {
 #ifdef NS_BUILD_REFCNT_LOGGING
   MOZ_COUNT_CTOR(nsDisplayScrollInfoLayer);
 #endif
 }
 
 #ifdef NS_BUILD_REFCNT_LOGGING
 nsDisplayScrollInfoLayer::~nsDisplayScrollInfoLayer()
--- a/layout/generic/nsGfxScrollFrame.cpp
+++ b/layout/generic/nsGfxScrollFrame.cpp
@@ -2233,22 +2233,26 @@ nsGfxScrollFrameInner::BuildDisplayList(
   // When a displayport is being used, force building of a layer so that
   // CompositorParent can always find the scrollable layer for the root content
   // document.
   if (usingDisplayport) {
     mShouldBuildLayer = true;
   } else {
     nsRect scrollRange = GetScrollRange();
     ScrollbarStyles styles = GetScrollbarStylesFromFrame();
+    bool hasScrollableOverflow =
+      (scrollRange.width > 0 || scrollRange.height > 0) &&
+      ((styles.mHorizontal != NS_STYLE_OVERFLOW_HIDDEN && mHScrollbarBox) ||
+       (styles.mVertical   != NS_STYLE_OVERFLOW_HIDDEN && mVScrollbarBox));
+    // TODO Turn this on for inprocess OMTC
+    bool wantSubAPZC = (XRE_GetProcessType() == GeckoProcessType_Content);
     mShouldBuildLayer =
-       ((styles.mHorizontal != NS_STYLE_OVERFLOW_HIDDEN && mHScrollbarBox) ||
-        (styles.mVertical   != NS_STYLE_OVERFLOW_HIDDEN && mVScrollbarBox)) &&
-       (XRE_GetProcessType() == GeckoProcessType_Content &&
-        (scrollRange.width > 0 || scrollRange.height > 0) &&
-        (!mIsRoot || !mOuter->PresContext()->IsRootContentDocument()));
+      wantSubAPZC &&
+      hasScrollableOverflow &&
+      (!mIsRoot || !mOuter->PresContext()->IsRootContentDocument());
   }
 
   if (ShouldBuildLayer()) {
     // ScrollLayerWrapper must always be created because it initializes the
     // scroll layer count. The display lists depend on this.
     ScrollLayerWrapper wrapper(mOuter, mScrolledFrame);
 
     if (usingDisplayport) {