Bug 959198 - Have APZ hit testing respect mozpasspointerevents. r=kats a=1.3+
authorBotond Ballo <botond@mozilla.com>
Thu, 16 Jan 2014 15:19:59 -0500
changeset 176004 7ab536f59d749a76db7b957760d13408306dba6e
parent 176003 376a27142809f956fb8293e68f0e7ce20dc2a923
child 176005 222070c7fdec8ea3f704a8a852c68253f54e9cc3
push id445
push userffxbld
push dateMon, 10 Mar 2014 22:05:19 +0000
treeherdermozilla-release@dc38b741b04e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskats, 1
bugs959198
milestone28.0a2
Bug 959198 - Have APZ hit testing respect mozpasspointerevents. r=kats a=1.3+
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
@@ -166,17 +166,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(nsFrameLoader* aFrameLoader,
                                      ScrollingBehavior aScrollingBehavior,
                                      TextureFactoryIdentifier* aTextureFactoryIdentifier,
                                      uint64_t* aId)
   : mLayersId(0)
   , mFrameLoader(aFrameLoader)
@@ -928,16 +944,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;