Mozilla Home
Privacy
Cookies
Legal
Bugzilla
Browse
Advanced Search
New Bug
Reports
Documentation
Log In
Log In with GitHub
or
Remember me
Browse
Advanced Search
New Bug
Reports
Documentation
Attachment 809410 Details for
Bug 920036
[patch]
(WIP) Part 4 - Move the APZC event routing to widget code
7-b2ginput-a5678f2 (text/plain), 19.08 KB, created by
Kartikaya Gupta (email:kats@mozilla.staktrace.com)
(
hide
)
Description:
(WIP) Part 4 - Move the APZC event routing to widget code
Filename:
MIME Type:
Creator:
Kartikaya Gupta (email:kats@mozilla.staktrace.com)
Size:
19.08 KB
patch
obsolete
># HG changeset patch ># User Kartikaya Gupta <kgupta@mozilla.com> >Bug 920036 - Move routing of events to APZCTreeManager to widget code from TabParent code. r= > > >diff --git a/dom/ipc/TabParent.cpp b/dom/ipc/TabParent.cpp >index 2681475..85c14a2 100644 >--- a/dom/ipc/TabParent.cpp >+++ b/dom/ipc/TabParent.cpp >@@ -630,48 +630,42 @@ TabParent::MapEventCoordinatesForChildProcess( > } > } > > bool TabParent::SendRealMouseEvent(nsMouseEvent& event) > { > if (mIsDestroyed) { > return false; > } >- nsMouseEvent e(event); >- MaybeForwardEventToRenderFrame(e); >- if (!MapEventCoordinatesForChildProcess(&e)) { >+ if (!MapEventCoordinatesForChildProcess(&event)) { > return false; > } >- return PBrowserParent::SendRealMouseEvent(e); >+ return PBrowserParent::SendRealMouseEvent(event); > } > > bool TabParent::SendMouseWheelEvent(WheelEvent& event) > { > if (mIsDestroyed) { > return false; > } >- WheelEvent e(event); >- MaybeForwardEventToRenderFrame(e); >- if (!MapEventCoordinatesForChildProcess(&e)) { >+ if (!MapEventCoordinatesForChildProcess(&event)) { > return false; > } >- return PBrowserParent::SendMouseWheelEvent(e); >+ return PBrowserParent::SendMouseWheelEvent(event); > } > > bool TabParent::SendRealKeyEvent(nsKeyEvent& event) > { > if (mIsDestroyed) { > return false; > } >- nsKeyEvent e(event); >- MaybeForwardEventToRenderFrame(e); >- if (!MapEventCoordinatesForChildProcess(&e)) { >+ if (!MapEventCoordinatesForChildProcess(&event)) { > return false; > } >- return PBrowserParent::SendRealKeyEvent(e); >+ return PBrowserParent::SendRealKeyEvent(event); > } > > bool TabParent::SendRealTouchEvent(nsTouchEvent& event) > { > if (mIsDestroyed) { > return false; > } > if (event.message == NS_TOUCH_START) { >@@ -694,18 +688,16 @@ bool TabParent::SendRealTouchEvent(nsTouchEvent& event) > if (event.message == NS_TOUCH_END || event.message == NS_TOUCH_CANCEL) { > for (int i = e.touches.Length() - 1; i >= 0; i--) { > if (!e.touches[i]->mChanged) { > e.touches.RemoveElementAt(i); > } > } > } > >- MaybeForwardEventToRenderFrame(e); >- > MapEventCoordinatesForChildProcess(mChildProcessOffsetAtTouchStart, &e); > > return (e.message == NS_TOUCH_MOVE) ? > PBrowserParent::SendRealTouchMoveEvent(e) : > PBrowserParent::SendRealTouchEvent(e); > } > > bool >@@ -1457,24 +1449,16 @@ TabParent::UseAsyncPanZoom() > { > bool usingOffMainThreadCompositing = !!CompositorParent::CompositorLoop(); > bool asyncPanZoomEnabled = > Preferences::GetBool("layers.async-pan-zoom.enabled", false); > return (usingOffMainThreadCompositing && asyncPanZoomEnabled && > GetScrollingBehavior() == ASYNC_PAN_ZOOM); > } > >-void >-TabParent::MaybeForwardEventToRenderFrame(nsInputEvent& aEvent); >-{ >- if (RenderFrameParent* rfp = GetRenderFrame()) { >- rfp->NotifyInputEvent(aEvent); >- } >-} >- > bool > TabParent::RecvBrowserFrameOpenWindow(PBrowserParent* aOpener, > const nsString& aURL, > const nsString& aName, > const nsString& aFeatures, > bool* aOutWindowOpened) > { > BrowserElementParent::OpenWindowResult opened = >diff --git a/dom/ipc/TabParent.h b/dom/ipc/TabParent.h >index 3a98e76..49d3283 100644 >--- a/dom/ipc/TabParent.h >+++ b/dom/ipc/TabParent.h >@@ -291,21 +291,16 @@ private: > already_AddRefed<nsIWidget> GetWidget() const; > layout::RenderFrameParent* GetRenderFrame(); > nsRefPtr<ContentParent> mManager; > void TryCacheDPIAndScale(); > > // When true, we create a pan/zoom controller for our frame and > // notify it of input events targeting us. > bool UseAsyncPanZoom(); >- // If we have a render frame currently, notify it that we're about >- // to dispatch |aEvent| to our child. If there's a relevant >- // transform in place, |aEvent| is un-transformed so that it can >- // be dispatched to content. >- void MaybeForwardEventToRenderFrame(nsInputEvent& aEvent); > // The offset for the child process which is sampled at touch start. This > // means that the touch events are relative to where the frame was at the > // start of the touch. We need to look for a better solution to this > // problem see bug 872911. > LayoutDeviceIntPoint mChildProcessOffsetAtTouchStart; > // When true, we've initiated normal shutdown and notified our > // managing PContent. > bool mMarkedDestroying; >diff --git a/gfx/layers/composite/APZCTreeManager.cpp b/gfx/layers/composite/APZCTreeManager.cpp >index 17fb928..c452b8d 100644 >--- a/gfx/layers/composite/APZCTreeManager.cpp >+++ b/gfx/layers/composite/APZCTreeManager.cpp >@@ -319,27 +319,30 @@ APZCTreeManager::GetTouchInputBlockAPZC(const nsTouchEvent& aEvent, ScreenPoint > if (apzc) { > // Cache apz transform so it can be used for future events in this block. > GetInputTransforms(apzc, mCachedTransformToApzcForInputBlock, transformToScreen); > } > return apzc.get(); > } > > nsEventStatus >-APZCTreeManager::ProcessTouchEvent(nsTouchEvent& aEvent) >+APZCTreeManager::ProcessTouchEvent(nsTouchEvent& aEvent, ScrollableLayerGuid& aGuid) > { > // For computing the input for the APZC, used the cached transform. > // This ensures that the sequence of touch points an APZC sees in an > // input block are all in the same coordinate space. > gfx3DMatrix transformToApzc = mCachedTransformToApzcForInputBlock; > MultiTouchInput inputForApzc(aEvent); > for (size_t i = 0; i < inputForApzc.mTouches.Length(); i++) { > ApplyTransform(&(inputForApzc.mTouches[i].mScreenPoint), transformToApzc); > } > nsEventStatus ret = mApzcForInputBlock->ReceiveInputEvent(inputForApzc); >+ if (ret != nsEventStatus_eIgnore) { >+ aGuid = mApzcForInputBlock->GetGuid(); >+ } > > // For computing the event to pass back to Gecko, use the up-to-date transforms. > // This ensures that transformToApzc and transformToScreen are in sync > // (note that transformToScreen isn't cached). > gfx3DMatrix transformToScreen; > GetInputTransforms(mApzcForInputBlock, transformToApzc, transformToScreen); > gfx3DMatrix outTransform = transformToApzc * transformToScreen; > for (size_t i = 0; i < aEvent.touches.Length(); i++) { >@@ -351,77 +354,79 @@ APZCTreeManager::ProcessTouchEvent(nsTouchEvent& aEvent) > if (aEvent.message == NS_TOUCH_CANCEL || > (aEvent.message == NS_TOUCH_END && aEvent.touches.Length() == 1)) { > mApzcForInputBlock = nullptr; > } > return ret; > } > > nsEventStatus >-APZCTreeManager::ProcessMouseEvent(nsMouseEvent& aEvent) >+APZCTreeManager::ProcessMouseEvent(nsMouseEvent& aEvent, ScrollableLayerGuid& aGuid) > { > nsRefPtr<AsyncPanZoomController> apzc = GetTargetAPZC(ScreenPoint(aEvent.refPoint.x, aEvent.refPoint.y)); > if (!apzc) { > return nsEventStatus_eIgnore; > } >+ aGuid = apzc->GetGuid(); > gfx3DMatrix transformToApzc; > gfx3DMatrix transformToScreen; > GetInputTransforms(apzc, transformToApzc, transformToScreen); > MultiTouchInput inputForApzc(aEvent); > ApplyTransform(&(inputForApzc.mTouches[0].mScreenPoint), transformToApzc); > gfx3DMatrix outTransform = transformToApzc * transformToScreen; > ApplyTransform(&(aEvent.refPoint), outTransform); > return apzc->ReceiveInputEvent(inputForApzc); > } > > nsEventStatus >-APZCTreeManager::ProcessEvent(nsInputEvent& aEvent) >+APZCTreeManager::ProcessEvent(nsInputEvent& aEvent, ScrollableLayerGuid& aGuid) > { > // Transform the refPoint > nsRefPtr<AsyncPanZoomController> apzc = GetTargetAPZC(ScreenPoint(aEvent.refPoint.x, aEvent.refPoint.y)); > if (!apzc) { > return nsEventStatus_eIgnore; > } >+ aGuid = apzc->GetGuid(); > gfx3DMatrix transformToApzc; > gfx3DMatrix transformToScreen; > GetInputTransforms(apzc, transformToApzc, transformToScreen); > ApplyTransform(&(aEvent.refPoint), transformToApzc); > gfx3DMatrix outTransform = transformToApzc * transformToScreen; > ApplyTransform(&(aEvent.refPoint), outTransform); > return nsEventStatus_eIgnore; > } > > nsEventStatus >-APZCTreeManager::ReceiveInputEvent(nsInputEvent& aEvent) >+APZCTreeManager::ReceiveInputEvent(nsInputEvent& aEvent, ScrollableLayerGuid& aGuid) > { > MOZ_ASSERT(NS_IsMainThread()); > > switch (aEvent.eventStructType) { > case NS_TOUCH_EVENT: { > nsTouchEvent& touchEvent = static_cast<nsTouchEvent&>(aEvent); > if (!touchEvent.touches.Length()) { > return nsEventStatus_eIgnore; > } > if (touchEvent.message == NS_TOUCH_START) { > ScreenPoint point = ScreenPoint(touchEvent.touches[0]->mRefPoint.x, touchEvent.touches[0]->mRefPoint.y); > mApzcForInputBlock = GetTouchInputBlockAPZC(touchEvent, point); > } > if (!mApzcForInputBlock) { > return nsEventStatus_eIgnore; > } >- return ProcessTouchEvent(touchEvent); >+ return ProcessTouchEvent(touchEvent, aGuid); > } > #ifdef XP_UNIX > case NS_MOUSE_EVENT: { > nsMouseEvent& mouseEvent = static_cast<nsMouseEvent&>(aEvent); >- return ProcessMouseEvent(mouseEvent); >+ return ProcessMouseEvent(mouseEvent, aGuid); > } > #endif > default: { >- return ProcessEvent(aEvent); >+ return ProcessEvent(aEvent, aGuid); > } > } > } > > void > APZCTreeManager::UpdateCompositionBounds(const ScrollableLayerGuid& aGuid, > const ScreenIntRect& aCompositionBounds) > { >diff --git a/gfx/layers/composite/APZCTreeManager.h b/gfx/layers/composite/APZCTreeManager.h >index 12024fd..dec0ae9 100644 >--- a/gfx/layers/composite/APZCTreeManager.h >+++ b/gfx/layers/composite/APZCTreeManager.h >@@ -154,18 +154,20 @@ public: > * > * NOTE: Be careful of invoking the nsInputEvent variant. This can only be > * called on the main thread. See widget/InputData.h for more information on > * why we have InputData and nsInputEvent separated. > * NOTE: On unix, mouse events are treated as touch and are forwarded > * to the appropriate apz as such. > * > * @param aEvent event object, will be untransformed >+ * @param aGuid will be populated with the guid for the matching APZC iff >+ * the return value is not nsEventStatus_eIgnore. > */ >- nsEventStatus ReceiveInputEvent(nsInputEvent& aEvent); >+ nsEventStatus ReceiveInputEvent(nsInputEvent& aEvent, ScrollableLayerGuid& aGuid); > > /** > * Updates the composition bounds, i.e. the dimensions of the final size of > * the frame this is tied to during composition onto, in device pixels. In > * general, this will just be: > * { x = 0, y = 0, width = surface.width, height = surface.height }, however > * there is no hard requirement for this. > */ >@@ -287,19 +289,19 @@ public: > gfx3DMatrix& aTransformToScreenOut); > private: > /* Helpers */ > AsyncPanZoomController* FindTargetAPZC(AsyncPanZoomController* aApzc, const ScrollableLayerGuid& aGuid); > AsyncPanZoomController* GetAPZCAtPoint(AsyncPanZoomController* aApzc, const gfxPoint& aHitTestPoint); > AsyncPanZoomController* CommonAncestor(AsyncPanZoomController* aApzc1, AsyncPanZoomController* aApzc2); > AsyncPanZoomController* RootAPZCForLayersId(AsyncPanZoomController* aApzc); > AsyncPanZoomController* GetTouchInputBlockAPZC(const nsTouchEvent& aEvent, ScreenPoint aPoint); >- nsEventStatus ProcessTouchEvent(nsTouchEvent& touchEvent); >- nsEventStatus ProcessMouseEvent(nsMouseEvent& mouseEvent); >- nsEventStatus ProcessEvent(nsInputEvent& inputEvent); >+ nsEventStatus ProcessTouchEvent(nsTouchEvent& touchEvent, ScrollableLayerGuid& aGuid); >+ nsEventStatus ProcessMouseEvent(nsMouseEvent& mouseEvent, ScrollableLayerGuid& aGuid); >+ nsEventStatus ProcessEvent(nsInputEvent& inputEvent, ScrollableLayerGuid& aGuid); > > /** > * Recursive helper function to build the APZC tree. The tree of APZC instances has > * the same shape as the layer tree, but excludes all the layers that are not scrollable. > * Note that this means APZCs corresponding to layers at different depths in the tree > * may end up becoming siblings. It also means that the "root" APZC may have siblings. > * This function walks the layer tree backwards through siblings and constructs the APZC > * tree also as a last-child-prev-sibling tree because that simplifies the hit detection >diff --git a/gfx/layers/ipc/AsyncPanZoomController.cpp b/gfx/layers/ipc/AsyncPanZoomController.cpp >index 6027a7e..4ee1f74 100644 >--- a/gfx/layers/ipc/AsyncPanZoomController.cpp >+++ b/gfx/layers/ipc/AsyncPanZoomController.cpp >@@ -1443,10 +1443,15 @@ void AsyncPanZoomController::UpdateScrollOffset(const CSSPoint& aScrollOffset) > > bool AsyncPanZoomController::Matches(const ScrollableLayerGuid& aGuid) > { > // TODO: also check the presShellId, once that is fully propagated > // everywhere in RenderFrameParent and AndroidJNI. > return aGuid.mLayersId == mLayersId && aGuid.mScrollId == mFrameMetrics.mScrollId; > } > >+ScrollableLayerGuid AsyncPanZoomController::GetGuid() >+{ >+ return ScrollableLayerGuid(mLayersId, mFrameMetrics); >+} >+ > } > } >diff --git a/gfx/layers/ipc/AsyncPanZoomController.h b/gfx/layers/ipc/AsyncPanZoomController.h >index 96a1a440..19246ce 100644 >--- a/gfx/layers/ipc/AsyncPanZoomController.h >+++ b/gfx/layers/ipc/AsyncPanZoomController.h >@@ -236,16 +236,23 @@ public: > nsEventStatus HandleInputEvent(const InputData& aEvent); > > /** > * Returns true if this APZC instance is for the layer identified by the guid. > */ > bool Matches(const ScrollableLayerGuid& aGuid); > > /** >+ * Returns a ScrollableLayerGuid that identifies this APZC. A guid returned from >+ * this function will always return true when passed into the Matches() function >+ * of the same object. >+ */ >+ ScrollableLayerGuid GetGuid(); >+ >+ /** > * Sync panning and zooming animation using a fixed frame time. > * This will ensure that we animate the APZC correctly with other external > * animations to the same timestamp. > */ > static void SetFrameTime(const TimeStamp& aMilliseconds); > > /** > * Update mFrameMetrics.mScrollOffset to the given offset. >diff --git a/layout/ipc/RenderFrameParent.cpp b/layout/ipc/RenderFrameParent.cpp >index 1f170d1..b7f8ac8 100644 >--- a/layout/ipc/RenderFrameParent.cpp >+++ b/layout/ipc/RenderFrameParent.cpp >@@ -821,24 +821,16 @@ void > RenderFrameParent::OwnerContentChanged(nsIContent* aContent) > { > NS_ABORT_IF_FALSE(mFrameLoader->GetOwnerContent() == aContent, > "Don't build new map if owner is same!"); > BuildViewMap(); > } > > void >-RenderFrameParent::NotifyInputEvent(nsInputEvent& aEvent) >-{ >- if (GetApzcTreeManager()) { >- GetApzcTreeManager()->ReceiveInputEvent(aEvent); >- } >-} >- >-void > RenderFrameParent::NotifyDimensionsChanged(ScreenIntSize size) > { > if (GetApzcTreeManager()) { > GetApzcTreeManager()->UpdateCompositionBounds(ScrollableLayerGuid(mLayersId), > ScreenIntRect(ScreenIntPoint(), size)); > } > } > >diff --git a/layout/ipc/RenderFrameParent.h b/layout/ipc/RenderFrameParent.h >index c882c53..f825430 100644 >--- a/layout/ipc/RenderFrameParent.h >+++ b/layout/ipc/RenderFrameParent.h >@@ -88,18 +88,16 @@ public: > const nsIntRect& aVisibleRect, > nsDisplayItem* aItem, > const ContainerParameters& aContainerParameters); > > void OwnerContentChanged(nsIContent* aContent); > > void SetBackgroundColor(nscolor aColor) { mBackgroundColor = gfxRGBA(aColor); }; > >- void NotifyInputEvent(nsInputEvent& aEvent); >- > void NotifyDimensionsChanged(ScreenIntSize size); > > void ZoomToRect(const CSSRect& aRect); > > void ContentReceivedTouch(bool aPreventDefault); > > void UpdateZoomConstraints(bool aAllowZoom, > const CSSToScreenScale& aMinZoom, >diff --git a/widget/gonk/nsWindow.cpp b/widget/gonk/nsWindow.cpp >index 0743872..b6b7936 100644 >--- a/widget/gonk/nsWindow.cpp >+++ b/widget/gonk/nsWindow.cpp >@@ -37,16 +37,18 @@ > #include "nsTArray.h" > #include "nsWindow.h" > #include "nsIWidgetListener.h" > #include "cutils/properties.h" > #include "ClientLayerManager.h" > #include "BasicLayers.h" > #include "libdisplay/GonkDisplay.h" > #include "pixelflinger/format.h" >+#include "mozilla/layers/APZCTreeManager.h" >+#include "mozilla/layers/CompositorParent.h" > > #include "HwcComposer2D.h" > > #define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "Gonk" , ## args) > #define LOGW(args...) __android_log_print(ANDROID_LOG_WARN, "Gonk", ## args) > #define LOGE(args...) __android_log_print(ANDROID_LOG_ERROR, "Gonk", ## args) > > #define IS_TOPLEVEL() (mWindowType == eWindowType_toplevel || mWindowType == eWindowType_dialog) >@@ -265,18 +267,31 @@ nsWindow::DispatchInputEvent(nsInputEvent &aEvent) > if (!gFocusedWindow) { > return nsEventStatus_eIgnore; > } > > gFocusedWindow->UserActivity(); > > aEvent.widget = gFocusedWindow; > >+ bool guidIsValid = false; >+ ScrollableLayerGuid guid(0); >+ if (gFocusedWindow->mApzcTreeManager) { >+ // Note that the call below will modify the aEvent parameter so as to unapply async >+ // transforms. This puts the event coordinates in a space that Gecko knows about, so >+ // that we can dispatch it to Gecko and have it behave correctly. >+ guidIsValid = (gFocusedWindow->mApzcTreeManager->ReceiveInputEvent(aEvent, guid) != nsEventStatus_eIgnore); >+ } > nsEventStatus status; > gFocusedWindow->DispatchEvent(&aEvent, status); >+ if (status == nsEventStatus_eConsumeNoDefault && guidIsValid) { >+ // Some listener in Gecko consumed the event, so cancel any pan/zoom actions in >+ // the APZC code. >+ gFocusedWindow->mApzcTreeManager->ContentReceivedTouch(guid, true); >+ } > return status; > } > > NS_IMETHODIMP > nsWindow::Create(nsIWidget *aParent, > void *aNativeParent, > const nsIntRect &aRect, > nsDeviceContext *aContext, >@@ -568,16 +583,20 @@ nsWindow::GetLayerManager(PLayerTransactionChild* aShadowManager, > > if (!topWindow) { > LOGW(" -- no topwindow\n"); > return nullptr; > } > > if (sUsingOMTC) { > CreateCompositor(); >+ if (mCompositorParent) { >+ uint64_t rootLayerTreeId = mCompositorParent->RootLayerTreeId(); >+ mApzcTreeManager = CompositorParent::GetAPZCTreeManager(rootLayerTreeId); >+ } > if (mLayerManager) > return mLayerManager; > } > > if (mUseLayersAcceleration) { > DebugOnly<nsIntRect> fbBounds = gScreenBounds; > if (!sGLContext) { > sGLContext = GLContextProvider::CreateForWindow(this); >diff --git a/widget/gonk/nsWindow.h b/widget/gonk/nsWindow.h >index 88dddcf..8716d24 100644 >--- a/widget/gonk/nsWindow.h >+++ b/widget/gonk/nsWindow.h >@@ -22,16 +22,17 @@ > > extern nsIntRect gScreenBounds; > > namespace mozilla { > namespace gl { > class GLContext; > } > namespace layers { >+class APZCTreeManager; > class LayersManager; > } > } > > namespace android { > class FramebufferNativeWindow; > } > >@@ -113,16 +114,17 @@ public: > virtual Composer2D* GetComposer2D() MOZ_OVERRIDE; > > protected: > nsWindow* mParent; > bool mVisible; > nsIntRegion mDirtyRegion; > InputContext mInputContext; > nsCOMPtr<nsIIdleServiceInternal> mIdleService; >+ nsRefPtr<mozilla::layers::APZCTreeManager> mApzcTreeManager; > > void BringToTop(); > > // Call this function when the users activity is the direct cause of an > // event (like a keypress or mouse click). > void UserActivity(); > }; >
Actions:
View
|
Diff
|
Review
Attachments on
bug 920036
:
809320
|
809321
|
809408
|
809410
|
809411
|
8536252
|
8536253
|
8536254
|
8536255
|
8536257
|
8542237
|
8542238
|
8542239