Bug 959198 - Have APZ hit testing respect mozpasspointerevents. r=kats
authorBotond Ballo <botond@mozilla.com>
Thu, 16 Jan 2014 15:19:59 -0500
changeset 164094 dbe8147a798142b5b467df1d9b631331c972634d
parent 164093 63fd0e5db62207614927a1c4924c9745064c0a00
child 164095 56580a9e6ca61f8a762136469da802e3821f91e8
push id26026
push userphilringnalda@gmail.com
push dateSat, 18 Jan 2014 23:17:27 +0000
treeherdermozilla-central@61fd0f987cf2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskats
bugs959198
milestone29.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 959198 - Have APZ hit testing respect mozpasspointerevents. r=kats
gfx/layers/composite/APZCTreeManager.cpp
gfx/layers/ipc/GeckoContentController.h
layout/ipc/RenderFrameParent.cpp
--- a/gfx/layers/composite/APZCTreeManager.cpp
+++ b/gfx/layers/composite/APZCTreeManager.cpp
@@ -198,17 +198,27 @@ APZCTreeManager::UpdatePanZoomController
           apzc->SetPrevSibling(nullptr);
           apzc->SetLastChild(nullptr);
         }
         APZC_LOG("Using APZC %p for layer %p with identifiers %lld %lld\n", apzc, aLayer, aLayersId, container->GetFrameMetrics().mScrollId);
 
         apzc->NotifyLayersUpdated(container->GetFrameMetrics(),
                                   aIsFirstPaint && (aLayersId == aFirstPaintLayersId));
 
+        // Use the composition bounds as the hit test region.
+        // Optionally, the GeckoContentController can provide a touch-sensitive
+        // region that constrains all frames associated with the controller.
+        // In this case we intersect the composition bounds with that region.
         ScreenRect visible(container->GetFrameMetrics().mCompositionBounds);
+        CSSRect touchSensitiveRegion;
+        if (state->mController->GetTouchSensitiveRegion(&touchSensitiveRegion)) {
+          visible = visible.Intersect(touchSensitiveRegion
+                                      * container->GetFrameMetrics().LayersPixelsPerCSSPixel()
+                                      * LayerToScreenScale(1.0));
+        }
         apzc->SetLayerHitTestData(visible, aTransform, aLayer->GetTransform());
         APZC_LOG("Setting rect(%f %f %f %f) as visible region for APZC %p\n", visible.x, visible.y,
                                                                               visible.width, visible.height,
                                                                               apzc);
 
         // Bind the APZC instance into the tree of APZCs
         if (aNextSibling) {
           aNextSibling->SetPrevSibling(apzc);
--- a/gfx/layers/ipc/GeckoContentController.h
+++ b/gfx/layers/ipc/GeckoContentController.h
@@ -77,16 +77,32 @@ public:
    * last known zoom constraints.
    */
   virtual bool GetRootZoomConstraints(ZoomConstraints* aOutConstraints)
   {
     return false;
   }
 
   /**
+   * APZ uses |FrameMetrics::mCompositionBounds| for hit testing. Sometimes,
+   * widget code has knowledge of a touch-sensitive region that should
+   * additionally constrain hit testing for all frames associated with the
+   * controller. This method allows APZ to query the controller for such a
+   * region. A return value of true indicates that the controller has such a
+   * region, and it is returned in |aOutRegion|.
+   * TODO: once bug 928833 is implemented, this should be removed, as
+   * APZ can then get the correct touch-sensitive region for each frame
+   * directly from the layer.
+   */
+  virtual bool GetTouchSensitiveRegion(CSSRect* aOutRegion)
+  {
+    return false;
+  }
+
+  /**
    * General tranformation notices for consumers. These fire any time
    * the apzc is modifying the view, including panning, zooming, and
    * fling.
    */
   virtual void NotifyTransformBegin(const ScrollableLayerGuid& aGuid) {}
   virtual void NotifyTransformEnd(const ScrollableLayerGuid& aGuid) {}
 
   GeckoContentController() {}
--- a/layout/ipc/RenderFrameParent.cpp
+++ b/layout/ipc/RenderFrameParent.cpp
@@ -605,30 +605,33 @@ public:
     }
   }
 
   virtual void PostDelayedTask(Task* aTask, int aDelayMs) MOZ_OVERRIDE
   {
     MessageLoop::current()->PostDelayedTask(FROM_HERE, aTask, aDelayMs);
   }
 
-  void SaveZoomConstraints(const ZoomConstraints& aConstraints)
-  {
-    mHaveZoomConstraints = true;
-    mZoomConstraints = aConstraints;
-  }
-
   virtual bool GetRootZoomConstraints(ZoomConstraints* aOutConstraints)
   {
     if (mHaveZoomConstraints && aOutConstraints) {
       *aOutConstraints = mZoomConstraints;
     }
     return mHaveZoomConstraints;
   }
 
+  virtual bool GetTouchSensitiveRegion(CSSRect* aOutRegion)
+  {
+    if (mTouchSensitiveRegion.IsEmpty())
+      return false;
+
+    *aOutRegion = CSSRect::FromAppUnits(mTouchSensitiveRegion.GetBounds());
+    return true;
+  }
+
   virtual void NotifyTransformBegin(const ScrollableLayerGuid& aGuid)
   {
     if (MessageLoop::current() != mUILoop) {
       mUILoop->PostTask(
         FROM_HERE,
         NewRunnableMethod(this, &RemoteContentController::NotifyTransformBegin,
                           aGuid));
       return;
@@ -649,30 +652,43 @@ public:
       return;
     }
     if (mRenderFrame) {
       TabParent* browser = static_cast<TabParent*>(mRenderFrame->Manager());
       browser->NotifyTransformEnd(aGuid.mScrollId);
     }
   }
 
+  // Methods used by RenderFrameParent to set fields stored here.
+
+  void SaveZoomConstraints(const ZoomConstraints& aConstraints)
+  {
+    mHaveZoomConstraints = true;
+    mZoomConstraints = aConstraints;
+  }
+
+  void SetTouchSensitiveRegion(const nsRegion& aRegion)
+  {
+    mTouchSensitiveRegion = aRegion;
+  }
 private:
   void DoRequestContentRepaint(const FrameMetrics& aFrameMetrics)
   {
     if (mRenderFrame) {
       TabParent* browser = static_cast<TabParent*>(mRenderFrame->Manager());
       browser->UpdateFrame(aFrameMetrics);
     }
   }
 
   MessageLoop* mUILoop;
   RenderFrameParent* mRenderFrame;
 
   bool mHaveZoomConstraints;
   ZoomConstraints mZoomConstraints;
+  nsRegion mTouchSensitiveRegion;
 };
 
 RenderFrameParent::RenderFrameParent()
   : mLayersId(0)
   , mFrameLoaderDestroyed(false)
   , mBackgroundColor(gfxRGBA(1, 1, 1))
 {
 }
@@ -936,16 +952,23 @@ RenderFrameParent::RecvNotifyCompositorT
   TriggerRepaint();
   return true;
 }
 
 bool
 RenderFrameParent::RecvUpdateHitRegion(const nsRegion& aRegion)
 {
   mTouchRegion = aRegion;
+  if (mContentController) {
+    // Tell the content controller about the touch-sensitive region, so
+    // that it can provide it to APZ. This is required for APZ to do
+    // correct hit testing for a remote 'mozpasspointerevents' iframe
+    // until bug 928833 is fixed.
+    mContentController->SetTouchSensitiveRegion(aRegion);
+  }
   return true;
 }
 
 PLayerTransactionParent*
 RenderFrameParent::AllocPLayerTransactionParent()
 {
   if (!mFrameLoader || mFrameLoaderDestroyed) {
     return nullptr;