summaryrefslogtreecommitdiffstats
path: root/gfx/layers
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/layers')
-rw-r--r--gfx/layers/AnimationHelper.cpp12
-rw-r--r--gfx/layers/CanvasDrawEventRecorder.cpp6
-rw-r--r--gfx/layers/GPUVideoImage.h4
-rw-r--r--gfx/layers/LayersTypes.cpp12
-rw-r--r--gfx/layers/LayersTypes.h2
-rw-r--r--gfx/layers/ScrollableLayerGuid.cpp3
-rw-r--r--gfx/layers/apz/src/AsyncPanZoomController.cpp10
-rw-r--r--gfx/layers/apz/src/FocusState.cpp1
-rw-r--r--gfx/layers/apz/src/InputBlockState.h4
-rw-r--r--gfx/layers/apz/src/InputQueue.cpp14
-rw-r--r--gfx/layers/apz/test/gtest/TestGestureDetector.cpp100
-rw-r--r--gfx/layers/apz/test/mochitest/helper_doubletap_zoom_textarea.html6
-rw-r--r--gfx/layers/apz/test/mochitest/helper_scroll_over_subframe.html146
-rw-r--r--gfx/layers/apz/test/mochitest/helper_scroll_over_subframe_child.html29
-rw-r--r--gfx/layers/apz/test/mochitest/test_group_double_tap_zoom.html2
-rw-r--r--gfx/layers/apz/test/mochitest/test_group_pointerevents.html9
-rw-r--r--gfx/layers/apz/test/mochitest/test_group_wheelevents.html11
-rw-r--r--gfx/layers/d3d11/TextureHostWrapperD3D11.cpp9
-rw-r--r--gfx/layers/ipc/APZCTreeManagerChild.cpp42
-rw-r--r--gfx/layers/ipc/APZCTreeManagerChild.h7
-rw-r--r--gfx/layers/ipc/APZInputBridgeChild.cpp74
-rw-r--r--gfx/layers/ipc/APZInputBridgeChild.h22
-rw-r--r--gfx/layers/ipc/APZInputBridgeParent.cpp10
-rw-r--r--gfx/layers/ipc/APZInputBridgeParent.h3
-rw-r--r--gfx/layers/ipc/CanvasChild.cpp9
-rw-r--r--gfx/layers/ipc/CanvasTranslator.cpp47
-rw-r--r--gfx/layers/ipc/CompositorBridgeParent.cpp22
-rw-r--r--gfx/layers/ipc/CompositorBridgeParent.h15
-rw-r--r--gfx/layers/ipc/PAPZCTreeManager.ipdl4
-rw-r--r--gfx/layers/ipc/PAPZInputBridge.ipdl8
-rw-r--r--gfx/layers/ipc/RemoteContentController.cpp62
-rw-r--r--gfx/layers/ipc/RemoteContentController.h8
-rw-r--r--gfx/layers/wr/WebRenderImageHost.cpp15
33 files changed, 600 insertions, 128 deletions
diff --git a/gfx/layers/AnimationHelper.cpp b/gfx/layers/AnimationHelper.cpp
index 8cb97f19a1..ece69cd403 100644
--- a/gfx/layers/AnimationHelper.cpp
+++ b/gfx/layers/AnimationHelper.cpp
@@ -15,13 +15,13 @@
#include "mozilla/ServoStyleConsts.h" // for StyleComputedTimingFunction
#include "mozilla/dom/AnimationEffectBinding.h" // for dom::FillMode
#include "mozilla/dom/KeyframeEffectBinding.h" // for dom::IterationComposite
-#include "mozilla/dom/KeyframeEffect.h" // for dom::KeyFrameEffectReadOnly
-#include "mozilla/dom/Nullable.h" // for dom::Nullable
-#include "mozilla/layers/APZSampler.h" // for APZSampler
+#include "mozilla/dom/KeyframeEffect.h" // for dom::KeyFrameEffectReadOnly
+#include "mozilla/dom/Nullable.h" // for dom::Nullable
+#include "mozilla/layers/APZSampler.h" // for APZSampler
#include "mozilla/AnimatedPropertyID.h"
-#include "mozilla/LayerAnimationInfo.h" // for GetCSSPropertiesFor()
-#include "mozilla/Maybe.h" // for Maybe<>
-#include "mozilla/MotionPathUtils.h" // for ResolveMotionPath()
+#include "mozilla/LayerAnimationInfo.h" // for GetCSSPropertiesFor()
+#include "mozilla/Maybe.h" // for Maybe<>
+#include "mozilla/MotionPathUtils.h" // for ResolveMotionPath()
#include "mozilla/StyleAnimationValue.h" // for StyleAnimationValue, etc
#include "nsCSSPropertyID.h" // for eCSSProperty_offset_path, etc
#include "nsDisplayList.h" // for nsDisplayTransform, etc
diff --git a/gfx/layers/CanvasDrawEventRecorder.cpp b/gfx/layers/CanvasDrawEventRecorder.cpp
index 6140fc4ba7..8f3cd4be5c 100644
--- a/gfx/layers/CanvasDrawEventRecorder.cpp
+++ b/gfx/layers/CanvasDrawEventRecorder.cpp
@@ -362,11 +362,11 @@ void CanvasDrawEventRecorder::QueueProcessPendingDeletionsLocked(
return;
}
- class ProcessPendingRunnable final : public dom::WorkerRunnable {
+ class ProcessPendingRunnable final : public dom::WorkerThreadRunnable {
public:
ProcessPendingRunnable(dom::WorkerPrivate* aWorkerPrivate,
RefPtr<CanvasDrawEventRecorder>&& aRecorder)
- : dom::WorkerRunnable(aWorkerPrivate),
+ : dom::WorkerThreadRunnable("ProcessPendingRunnable"),
mRecorder(std::move(aRecorder)) {}
bool WorkerRun(JSContext*, dom::WorkerPrivate*) override {
@@ -381,7 +381,7 @@ void CanvasDrawEventRecorder::QueueProcessPendingDeletionsLocked(
auto task = MakeRefPtr<ProcessPendingRunnable>(mWorkerRef->Private(),
std::move(aRecorder));
- if (NS_WARN_IF(!task->Dispatch())) {
+ if (NS_WARN_IF(!task->Dispatch(mWorkerRef->Private()))) {
MOZ_CRASH("ProcessPendingRunnable leaked!");
}
}
diff --git a/gfx/layers/GPUVideoImage.h b/gfx/layers/GPUVideoImage.h
index a9bbb5950d..b511d55ccc 100644
--- a/gfx/layers/GPUVideoImage.h
+++ b/gfx/layers/GPUVideoImage.h
@@ -72,7 +72,9 @@ class GPUVideoImage final : public Image {
gfx::ColorDepth GetColorDepth() const override { return mColorDepth; }
gfx::ColorSpace2 GetColorPrimaries() const { return mColorSpace; }
gfx::YUVColorSpace GetYUVColorSpace() const { return mYUVColorSpace; }
- gfx::TransferFunction GetTransferFunction() const { return mTransferFunction; }
+ gfx::TransferFunction GetTransferFunction() const {
+ return mTransferFunction;
+ }
gfx::ColorRange GetColorRange() const { return mColorRange; }
Maybe<SurfaceDescriptor> GetDesc() override {
diff --git a/gfx/layers/LayersTypes.cpp b/gfx/layers/LayersTypes.cpp
index 81ea1aa88f..392af31862 100644
--- a/gfx/layers/LayersTypes.cpp
+++ b/gfx/layers/LayersTypes.cpp
@@ -91,5 +91,17 @@ GpuProcessQueryId GpuProcessQueryId::GetNext() {
return GpuProcessQueryId{++sCounter};
}
+std::ostream& operator<<(std::ostream& os, ScrollDirection aDirection) {
+ switch (aDirection) {
+ case ScrollDirection::eHorizontal:
+ os << "horizontal";
+ break;
+ case ScrollDirection::eVertical:
+ os << "vertical";
+ break;
+ }
+ return os;
+}
+
} // namespace layers
} // namespace mozilla
diff --git a/gfx/layers/LayersTypes.h b/gfx/layers/LayersTypes.h
index c02851d81f..ab26523e60 100644
--- a/gfx/layers/LayersTypes.h
+++ b/gfx/layers/LayersTypes.h
@@ -463,6 +463,8 @@ MOZ_DEFINE_ENUM_CLASS_WITH_BASE(ScrollDirection, uint8_t, (
eHorizontal
));
+std::ostream& operator<<(std::ostream& os, ScrollDirection aDirection);
+
using ScrollDirections = EnumSet<ScrollDirection, uint8_t>;
constexpr ScrollDirections EitherScrollDirection(ScrollDirection::eVertical,ScrollDirection::eHorizontal);
diff --git a/gfx/layers/ScrollableLayerGuid.cpp b/gfx/layers/ScrollableLayerGuid.cpp
index 914a8ad124..42a8a4824f 100644
--- a/gfx/layers/ScrollableLayerGuid.cpp
+++ b/gfx/layers/ScrollableLayerGuid.cpp
@@ -8,7 +8,8 @@
#include <ostream>
#include "mozilla/HashFunctions.h" // for HashGeneric
-#include "nsPrintfCString.h" // for nsPrintfCString
+#include "mozilla/IntegerPrintfMacros.h"
+#include "nsPrintfCString.h" // for nsPrintfCString
namespace mozilla {
namespace layers {
diff --git a/gfx/layers/apz/src/AsyncPanZoomController.cpp b/gfx/layers/apz/src/AsyncPanZoomController.cpp
index a070340421..84b4a95b9e 100644
--- a/gfx/layers/apz/src/AsyncPanZoomController.cpp
+++ b/gfx/layers/apz/src/AsyncPanZoomController.cpp
@@ -1988,6 +1988,10 @@ ParentLayerPoint AsyncPanZoomController::GetScrollWheelDelta(
// Apply user-set multipliers.
delta.x *= aMultiplierX;
delta.y *= aMultiplierY;
+ APZC_LOGV(
+ "user-multiplied delta is %s (deltaType %d, line size %s, page size %s)",
+ ToString(delta).c_str(), (int)aEvent.mDeltaType,
+ ToString(scrollAmount).c_str(), ToString(pageScrollSize).c_str());
// For the conditions under which we allow system scroll overrides, see
// WidgetWheelEvent::OverriddenDelta{X,Y}.
@@ -1999,6 +2003,7 @@ ParentLayerPoint AsyncPanZoomController::GetScrollWheelDelta(
aEvent.mAllowToOverrideSystemScrollSpeed) {
delta.x = WidgetWheelEvent::ComputeOverriddenDelta(delta.x, false);
delta.y = WidgetWheelEvent::ComputeOverriddenDelta(delta.y, true);
+ APZC_LOGV("overridden delta is %s", ToString(delta).c_str());
}
// If this is a line scroll, and this event was part of a scroll series, then
@@ -2258,6 +2263,8 @@ bool AsyncPanZoomController::AllowOneTouchPinch() const {
// Return whether or not the underlying layer can be scrolled on either axis.
bool AsyncPanZoomController::CanScroll(const InputData& aEvent) const {
ParentLayerPoint delta = GetDeltaForEvent(aEvent);
+ APZC_LOGV_DETAIL("CanScroll: event delta is %s", this,
+ ToString(delta).c_str());
if (!delta.x && !delta.y) {
return false;
}
@@ -2330,6 +2337,9 @@ bool AsyncPanZoomController::CanScrollWithWheel(
disregardedDirection != Some(ScrollDirection::eVertical)) {
return true;
}
+ APZC_LOGV_FM(Metrics(),
+ "cannot scroll with wheel (disregarded direction is %s)",
+ ToString(disregardedDirection).c_str());
return false;
}
diff --git a/gfx/layers/apz/src/FocusState.cpp b/gfx/layers/apz/src/FocusState.cpp
index 0230676e7e..84bf0b4570 100644
--- a/gfx/layers/apz/src/FocusState.cpp
+++ b/gfx/layers/apz/src/FocusState.cpp
@@ -7,6 +7,7 @@
#include "FocusState.h"
#include "mozilla/Logging.h"
+#include "mozilla/IntegerPrintfMacros.h"
#include "mozilla/layers/APZThreadUtils.h"
static mozilla::LazyLogModule sApzFstLog("apz.focusstate");
diff --git a/gfx/layers/apz/src/InputBlockState.h b/gfx/layers/apz/src/InputBlockState.h
index d65b1cb57b..d27e7ead27 100644
--- a/gfx/layers/apz/src/InputBlockState.h
+++ b/gfx/layers/apz/src/InputBlockState.h
@@ -501,9 +501,9 @@ class TouchBlockState : public CancelableBlockState {
mIsWaitingLongTapResult = false;
}
- void SetWaitingLongTapResult() {
+ void SetWaitingLongTapResult(bool aResult) {
MOZ_ASSERT(!mForLongTap);
- mIsWaitingLongTapResult = true;
+ mIsWaitingLongTapResult = aResult;
}
bool IsWaitingLongTapResult() const { return mIsWaitingLongTapResult; }
diff --git a/gfx/layers/apz/src/InputQueue.cpp b/gfx/layers/apz/src/InputQueue.cpp
index 8ad75a9794..78b70fddf4 100644
--- a/gfx/layers/apz/src/InputQueue.cpp
+++ b/gfx/layers/apz/src/InputQueue.cpp
@@ -204,8 +204,8 @@ APZEventResult InputQueue::ReceiveTouchInput(
} else {
// If all following conditions are met, we need to wait for a content
// response (again);
- // 1) this is the first event bailing out from in-slop state after a
- // long-tap event has been fired
+ // 1) this is the first touch-move event bailing out from in-slop state
+ // after a long-tap event has been fired
// 2) there's any APZ-aware event listeners
// 3) the event block hasn't yet been prevented
//
@@ -216,7 +216,7 @@ APZEventResult InputQueue::ReceiveTouchInput(
// until a long-tap event happens, then if the user started moving their
// finger, we have to wait for a content response twice, one is for
// `touchstart` and one is for `touchmove`.
- if (wasInSlop &&
+ if (wasInSlop && aEvent.mType == MultiTouchInput::MULTITOUCH_MOVE &&
(block->WasLongTapProcessed() || block->IsWaitingLongTapResult()) &&
!block->IsTargetOriginallyConfirmed() && !block->ShouldDropEvents()) {
INPQ_LOG(
@@ -637,6 +637,12 @@ uint64_t InputQueue::InjectNewTouchBlock(AsyncPanZoomController* aTarget) {
TouchBlockState* InputQueue::StartNewTouchBlock(
const RefPtr<AsyncPanZoomController>& aTarget,
TargetConfirmationFlags aFlags) {
+ if (mPrevActiveTouchBlock && mActiveTouchBlock &&
+ mActiveTouchBlock->ForLongTap()) {
+ mPrevActiveTouchBlock->SetWaitingLongTapResult(false);
+ mPrevActiveTouchBlock = nullptr;
+ }
+
TouchBlockState* newBlock =
new TouchBlockState(aTarget, aFlags, mTouchCounter);
@@ -664,7 +670,7 @@ TouchBlockState* InputQueue::StartNewTouchBlockForLongTap(
// touch block because if the long-tap event response prevents us from
// scrolling we must stop processing any subsequent touch-move events in the
// same block.
- currentBlock->SetWaitingLongTapResult();
+ currentBlock->SetWaitingLongTapResult(true);
// We need to keep the current block alive, it will be used once after this
// new touch block for long-tap was processed.
diff --git a/gfx/layers/apz/test/gtest/TestGestureDetector.cpp b/gfx/layers/apz/test/gtest/TestGestureDetector.cpp
index 8256667d6b..f5024e8208 100644
--- a/gfx/layers/apz/test/gtest/TestGestureDetector.cpp
+++ b/gfx/layers/apz/test/gtest/TestGestureDetector.cpp
@@ -10,6 +10,7 @@
#include "APZCBasicTester.h"
#include "APZTestCommon.h"
#include "InputUtils.h"
+#include "apz/src/InputBlockState.h"
#include "mozilla/StaticPrefs_apz.h"
// Note: There are additional tests that test gesture detection behaviour
@@ -553,6 +554,83 @@ class APZCLongPressTester : public APZCGestureDetectorTester {
apzc->AssertStateIsReset();
}
+
+ // Tests a scenario that after a long-press event happened the original touch
+ // block initiated by a touch-start event and the touch block initiated by a
+ // long-tap event have been discarded when a new touch-start event happens.
+ void DoLongPressDiscardTouchBlockTest(bool aWithTouchMove) {
+ // Set apz.content_response_timeout > ui.click_hold_context_menus.delay and
+ // apz.touch_start_tolerance explicitly to match Android preferences.
+ SCOPED_GFX_PREF_INT("apz.content_response_timeout", 60);
+ SCOPED_GFX_PREF_INT("ui.click_hold_context_menus.delay", 30);
+ SCOPED_GFX_PREF_FLOAT("apz.touch_start_tolerance", 0.06);
+
+ MockFunction<void(std::string checkPointName)> check;
+ {
+ InSequence s;
+ EXPECT_CALL(check, Call("pre long-tap dispatch"));
+ EXPECT_CALL(*mcc, HandleTap(TapType::eLongTap, LayoutDevicePoint(10, 10),
+ 0, apzc->GetGuid(), _, _))
+ .Times(1);
+ EXPECT_CALL(check, Call("post long-tap dispatch"));
+
+ // If a touch-move happens while long-tap is happening, there's no
+ // eLongTapUp event.
+ if (!aWithTouchMove) {
+ EXPECT_CALL(*mcc,
+ HandleTap(TapType::eLongTapUp, LayoutDevicePoint(10, 20), 0,
+ apzc->GetGuid(), _, _))
+ .Times(1);
+ }
+ EXPECT_CALL(*mcc, HandleTap(TapType::eLongTap, LayoutDevicePoint(10, 10),
+ 0, apzc->GetGuid(), _, _))
+ .Times(1);
+ }
+
+ // Keep touching for a while to trigger a long tap event.
+ uint64_t firstTouchBlockId =
+ TouchDown(apzc, ScreenIntPoint(10, 10), mcc->Time()).mInputBlockId;
+ TouchBlockState* firstTouchBlock =
+ tm->GetInputQueue()->GetCurrentTouchBlock();
+ EXPECT_NE(firstTouchBlock, nullptr);
+ EXPECT_EQ(tm->GetInputQueue()->GetBlockForId(firstTouchBlockId),
+ firstTouchBlock);
+
+ // Wait for a long tap.
+ check.Call("pre long-tap dispatch");
+ mcc->AdvanceByMillis(30);
+ check.Call("post long-tap dispatch");
+
+ // Now the current touch block is not the first touch block, it should be
+ // a new touch block for the long tap event.
+ TouchBlockState* secondTouchBlock =
+ tm->GetInputQueue()->GetCurrentTouchBlock();
+ EXPECT_NE(secondTouchBlock, firstTouchBlock);
+ EXPECT_TRUE(secondTouchBlock->ForLongTap());
+ uint64_t secondTouchBlockId = secondTouchBlock->GetBlockId();
+
+ if (aWithTouchMove) {
+ mcc->AdvanceByMillis(10);
+ TouchMove(apzc, ScreenIntPoint(10, 20), mcc->Time());
+ }
+
+ // Finish the first touch block.
+ mcc->AdvanceByMillis(10);
+ TouchUp(apzc, ScreenIntPoint(10, 20), mcc->Time());
+
+ // And start a new touch block.
+ mcc->AdvanceByMillis(10);
+ uint64_t newTouchBlockId =
+ TouchDown(apzc, ScreenIntPoint(10, 10), mcc->Time()).mInputBlockId;
+
+ mcc->AdvanceByMillis(10);
+ // Now the original touch block and the touch block for long-tap should have
+ // been discarded from the input queue.
+ EXPECT_EQ(tm->GetInputQueue()->GetBlockForId(firstTouchBlockId), nullptr);
+ EXPECT_EQ(tm->GetInputQueue()->GetBlockForId(secondTouchBlockId), nullptr);
+ EXPECT_EQ(tm->GetInputQueue()->GetBlockForId(newTouchBlockId),
+ tm->GetInputQueue()->GetCurrentBlock());
+ }
};
TEST_F(APZCLongPressTester, LongPress) {
@@ -563,6 +641,28 @@ TEST_F(APZCLongPressTester, LongPressPreventDefault) {
DoLongPressPreventDefaultTest(kDefaultTouchBehavior);
}
+TEST_F(APZCLongPressTester, LongPressDiscardBlock) {
+ DoLongPressDiscardTouchBlockTest(true /* with touch-move */);
+}
+
+// Similar to above LongPressDiscardBlock but APZ is waiting for responses from
+// the content.
+TEST_F(APZCLongPressTester, LongPressDiscardBlock2) {
+ MakeApzcWaitForMainThread();
+ DoLongPressDiscardTouchBlockTest(true /* with touch-move */);
+}
+
+// Similar to above LongPressDiscardBlock/LongPressDiscardBlock2 without
+// touch-move events.
+TEST_F(APZCLongPressTester, LongPressDiscardBlock3) {
+ DoLongPressDiscardTouchBlockTest(false /* without touch-move */);
+}
+
+TEST_F(APZCLongPressTester, LongPressDiscardBlock4) {
+ MakeApzcWaitForMainThread();
+ DoLongPressDiscardTouchBlockTest(false /* without touch-move */);
+}
+
TEST_F(APZCGestureDetectorTester, DoubleTap) {
MakeApzcWaitForMainThread();
MakeApzcZoomable();
diff --git a/gfx/layers/apz/test/mochitest/helper_doubletap_zoom_textarea.html b/gfx/layers/apz/test/mochitest/helper_doubletap_zoom_textarea.html
index 99616d9834..762e1cef69 100644
--- a/gfx/layers/apz/test/mochitest/helper_doubletap_zoom_textarea.html
+++ b/gfx/layers/apz/test/mochitest/helper_doubletap_zoom_textarea.html
@@ -7,6 +7,12 @@
<script src="apz_test_native_event_utils.js"></script>
<script src="apz_test_utils.js"></script>
<script src="/tests/SimpleTest/paint_listener.js"></script>
+ <style>
+ #target {
+ width: 100px;
+ height: 100px;
+ }
+ </style>
<script>
async function test() {
diff --git a/gfx/layers/apz/test/mochitest/helper_scroll_over_subframe.html b/gfx/layers/apz/test/mochitest/helper_scroll_over_subframe.html
new file mode 100644
index 0000000000..21efcbd9d6
--- /dev/null
+++ b/gfx/layers/apz/test/mochitest/helper_scroll_over_subframe.html
@@ -0,0 +1,146 @@
+<!DOCTYPE html>
+<html>
+ <title>A scroll over an iframe should not terminate the wheel transaction</title>
+ <script type="application/javascript" src="apz_test_utils.js"></script>
+ <script type="application/javascript" src="apz_test_native_event_utils.js"></script>
+ <script src="/tests/SimpleTest/paint_listener.js"></script>
+<head>
+<style>
+body {
+ height: 250vh;
+ width: 100%;
+ margin: 0;
+ padding: 0;
+}
+
+#spacer {
+ height: 50px;
+ width: 100vw;
+ background: yellow;
+}
+
+#subframe {
+ width: 80vw;
+ height: 60vh;
+}
+</style>
+</head>
+<body>
+ <div id="spacer"></div>
+ <iframe id="subframe">
+ </iframe>
+</body>
+<script>
+const searchParams = new URLSearchParams(location.search);
+
+async function scrollWithPan() {
+ await NativePanHandler.promiseNativePanEvent(
+ document.scrollingElement,
+ 50,
+ 30,
+ 0,
+ NativePanHandler.delta,
+ NativePanHandler.beginPhase,
+ );
+
+ await NativePanHandler.promiseNativePanEvent(
+ document.scrollingElement,
+ 50,
+ 30,
+ 0,
+ NativePanHandler.delta,
+ NativePanHandler.updatePhase,
+ );
+
+ await NativePanHandler.promiseNativePanEvent(
+ document.scrollingElement,
+ 50,
+ 30,
+ 0,
+ NativePanHandler.delta,
+ NativePanHandler.endPhase,
+ );
+}
+
+async function scrollWithWheel() {
+ await promiseMoveMouseAndScrollWheelOver(document.scrollingElement, 50, 30,
+ false, 100);
+}
+
+async function test() {
+ let iframeURL =
+ SimpleTest.getTestFileURL("helper_scroll_over_subframe_child.html");
+
+ switch (searchParams.get("oop")) {
+ case "true":
+ iframeURL = iframeURL.replace(window.location.origin, "https://example.com/");
+ break;
+ default:
+ break;
+ }
+
+ const iframeLoadPromise = promiseOneEvent(subframe, "load", null);
+ subframe.src = iframeURL;
+ await iframeLoadPromise;
+
+ await SpecialPowers.spawn(subframe, [], async () => {
+ await content.wrappedJSObject.waitUntilApzStable();
+ await SpecialPowers.contentTransformsReceived(content);
+ });
+
+ let childWindowReceivedWheelEvent = false;
+
+ window.addEventListener("message", e => {
+ if (e.data == "child-received-wheel-event") {
+ childWindowReceivedWheelEvent = true;
+ }
+ });
+
+ await SpecialPowers.spawn(subframe, [], () => {
+ let target = content.document.getElementById("target")
+ target.style.backgroundColor = "green";
+ content.getComputedStyle(target).backgroundColor;
+ target.addEventListener("wheel", () => {
+ target.style.backgroundColor = "red";
+ content.getComputedStyle(target).backgroundColor;
+ });
+ return new Promise(resolve => resolve());
+ });
+
+ await promiseFrame();
+
+ let transformEndPromise = promiseTransformEnd();
+
+ // Scroll over the iframe
+ switch (searchParams.get("scroll")) {
+ case "wheel":
+ await scrollWithWheel();
+ break;
+ case "pan":
+ await scrollWithPan();
+ break;
+ default:
+ ok(false, "Unsupported scroll value: " + searchParams.get("scroll"));
+ break;
+ }
+
+ await transformEndPromise;
+
+ // Wait an extra frame to ensure any message from the child has
+ // extra time to be sent to the parent.
+ await promiseFrame();
+
+ let res = await SpecialPowers.spawn(subframe, [], () => {
+ let target = content.document.getElementById("target")
+ return target.style.backgroundColor;
+ });
+
+ await promiseFrame();
+
+ // We should not have fired a wheel event to the element in the iframe
+ ok(!childWindowReceivedWheelEvent, "Child window should not receive wheel events");
+ is(res, "green", "OOP iframe does not halt user scroll of parent");
+}
+waitUntilApzStable().then(test).then(subtestDone, subtestFailed);
+</script>
+</html>
diff --git a/gfx/layers/apz/test/mochitest/helper_scroll_over_subframe_child.html b/gfx/layers/apz/test/mochitest/helper_scroll_over_subframe_child.html
new file mode 100644
index 0000000000..48f03a51d9
--- /dev/null
+++ b/gfx/layers/apz/test/mochitest/helper_scroll_over_subframe_child.html
@@ -0,0 +1,29 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<script src="/tests/SimpleTest/SimpleTest.js"></script>
+<script src="/tests/SimpleTest/paint_listener.js"></script>
+<script src="apz_test_utils.js"></script>
+<style>
+body {
+ margin: 0px;
+}
+
+#target {
+ width: 100%;
+ height: 100vh;
+ background: blue;
+ overflow: scroll;
+}
+</style>
+</head>
+<body>
+<div id="target">
+</div>
+</body>
+<script>
+ window.addEventListener("wheel", () => {
+ window.parent.postMessage("child-received-wheel-event", "*");
+ });
+</script>
+</html>
diff --git a/gfx/layers/apz/test/mochitest/test_group_double_tap_zoom.html b/gfx/layers/apz/test/mochitest/test_group_double_tap_zoom.html
index fe4a0784a9..c1e0351ccb 100644
--- a/gfx/layers/apz/test/mochitest/test_group_double_tap_zoom.html
+++ b/gfx/layers/apz/test/mochitest/test_group_double_tap_zoom.html
@@ -24,12 +24,12 @@ var logging_and_doubletap_prefs = [
var subtests = [
{"file": "helper_doubletap_zoom.html", "prefs": doubletap_prefs},
{"file": "helper_doubletap_zoom_img.html", "prefs": doubletap_prefs},
- {"file": "helper_doubletap_zoom_textarea.html", "prefs": doubletap_prefs},
{"file": "helper_doubletap_zoom_horizontal_center.html", "prefs": doubletap_prefs},
{"file": "helper_doubletap_zoom_bug1702464.html", "prefs": doubletap_prefs},
{"file": "helper_doubletap_zoom_large_overflow.html", "prefs": doubletap_prefs},
{"file": "helper_doubletap_zoom_fixedpos.html", "prefs": logging_and_doubletap_prefs},
{"file": "helper_doubletap_zoom_tallwide.html", "prefs": doubletap_prefs},
+ {"file": "helper_doubletap_zoom_textarea.html", "prefs": doubletap_prefs},
];
if (getPlatform() == "mac") {
diff --git a/gfx/layers/apz/test/mochitest/test_group_pointerevents.html b/gfx/layers/apz/test/mochitest/test_group_pointerevents.html
index 9ec03edd59..8bc0690bfc 100644
--- a/gfx/layers/apz/test/mochitest/test_group_pointerevents.html
+++ b/gfx/layers/apz/test/mochitest/test_group_pointerevents.html
@@ -24,14 +24,13 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1285070
{"file": "helper_bug1682170_pointercancel_on_touchaction_pinchzoom.html",
"prefs": touch_action_prefs},
{"file": "helper_bug1719855_pointercancel_on_touchmove_after_contextmenu_prevented.html"},
+ {"file": "helper_bug1285070.html"},
+ {"file": "helper_bug1299195.html", "prefs": [["dom.meta-viewport.enabled", isMac]]},
];
+
if (getPlatform() != "android") {
// Bug 1858610: these subtests are flaky on Android.
- subtests.push(
- {"file": "helper_bug1285070.html"},
- {"file": "helper_bug1299195.html", "prefs": [["dom.meta-viewport.enabled", isMac]]},
- {"file": "helper_bug1502010_unconsumed_pan.html"}
- )
+ subtests.push({"file": "helper_bug1502010_unconsumed_pan.html"});
}
if (isApzEnabled()) {
diff --git a/gfx/layers/apz/test/mochitest/test_group_wheelevents.html b/gfx/layers/apz/test/mochitest/test_group_wheelevents.html
index 42ce15a247..93746b9f6f 100644
--- a/gfx/layers/apz/test/mochitest/test_group_wheelevents.html
+++ b/gfx/layers/apz/test/mochitest/test_group_wheelevents.html
@@ -20,6 +20,13 @@ var prefs = [
["mousewheel.transaction.timeout", 0],
];
+var wheel_transaction_prefs = [
+ ["dom.event.wheel-event-groups.enabled", true],
+ ["mousewheel.transaction.timeout", 10000],
+ ["apz.test.mac.synth_wheel_input", true],
+ ...getSmoothScrollPrefs("wheel"),
+];
+
// For helper_scroll_over_scrollbar, we need to set a pref to force
// layerization of the scrollbar track to reproduce the bug being fixed.
// Otherwise, the bug only manifests with overlay scrollbars on macOS,
@@ -48,6 +55,10 @@ var subtests = [
prefs: [["general.smoothScroll", false],
["apz.test.mac.synth_wheel_input", true]]},
{"file": "helper_scroll_anchoring_on_wheel.html", prefs: smoothness_prefs},
+ {"file": "helper_scroll_over_subframe.html?scroll=wheel", prefs: wheel_transaction_prefs},
+ {"file": "helper_scroll_over_subframe.html?oop=true&scroll=wheel", prefs: wheel_transaction_prefs},
+ {"file": "helper_scroll_over_subframe.html?scroll=pan", prefs: wheel_transaction_prefs},
+ {"file": "helper_scroll_over_subframe.html?oop=true&scroll=pan", prefs: wheel_transaction_prefs},
];
subtests.push(...buildRelativeScrollSmoothnessVariants("wheel", ["scrollBy", "scrollTo", "scrollTop"]));
diff --git a/gfx/layers/d3d11/TextureHostWrapperD3D11.cpp b/gfx/layers/d3d11/TextureHostWrapperD3D11.cpp
index 380307fcea..aa6cb49f39 100644
--- a/gfx/layers/d3d11/TextureHostWrapperD3D11.cpp
+++ b/gfx/layers/d3d11/TextureHostWrapperD3D11.cpp
@@ -14,6 +14,7 @@
#include "mozilla/layers/GpuProcessD3D11TextureMap.h"
#include "mozilla/layers/TextureD3D11.h"
#include "mozilla/layers/WebRenderTextureHost.h"
+#include "mozilla/ProfilerMarkers.h"
#include "mozilla/SharedThreadPool.h"
namespace mozilla {
@@ -236,6 +237,14 @@ RefPtr<TextureHost> TextureHostWrapperD3D11::CreateFromBufferTexture(
colorDepth != gfx::ColorDepth::COLOR_8 ||
colorRange != gfx::ColorRange::LIMITED ||
chromaSubsampling != gfx::ChromaSubsampling::HALF_WIDTH_AND_HEIGHT) {
+ if (profiler_thread_is_being_profiled_for_markers()) {
+ nsPrintfCString str(
+ "Unsupported size(%dx%d) colorDepth %hhu colorRange %hhu "
+ "chromaSubsampling %hhu",
+ size.width, size.height, uint8_t(colorDepth), uint8_t(colorRange),
+ uint8_t(chromaSubsampling));
+ PROFILER_MARKER_TEXT("TextureHostWrapperD3D11", GRAPHICS, {}, str);
+ }
return nullptr;
}
diff --git a/gfx/layers/ipc/APZCTreeManagerChild.cpp b/gfx/layers/ipc/APZCTreeManagerChild.cpp
index b7f50c1c92..5dec4ca065 100644
--- a/gfx/layers/ipc/APZCTreeManagerChild.cpp
+++ b/gfx/layers/ipc/APZCTreeManagerChild.cpp
@@ -31,6 +31,9 @@ void APZCTreeManagerChild::SetCompositorSession(
// we're setting mCompositorSession or we're clearing it).
MOZ_ASSERT(!mCompositorSession ^ !aSession);
mCompositorSession = aSession;
+ if (mInputBridge) {
+ mInputBridge->SetCompositorSession(aSession);
+ }
}
void APZCTreeManagerChild::SetInputBridge(APZInputBridgeChild* aInputBridge) {
@@ -143,45 +146,6 @@ void APZCTreeManagerChild::ActorDestroy(ActorDestroyReason aWhy) {
mIPCOpen = false;
}
-mozilla::ipc::IPCResult APZCTreeManagerChild::RecvHandleTap(
- const TapType& aType, const LayoutDevicePoint& aPoint,
- const Modifiers& aModifiers, const ScrollableLayerGuid& aGuid,
- const uint64_t& aInputBlockId,
- const Maybe<DoubleTapToZoomMetrics>& aDoubleTapToZoomMetrics) {
- MOZ_ASSERT(XRE_IsParentProcess());
- if (mCompositorSession &&
- mCompositorSession->RootLayerTreeId() == aGuid.mLayersId &&
- mCompositorSession->GetContentController()) {
- RefPtr<GeckoContentController> controller =
- mCompositorSession->GetContentController();
- controller->HandleTap(aType, aPoint, aModifiers, aGuid, aInputBlockId,
- aDoubleTapToZoomMetrics);
- return IPC_OK();
- }
- dom::BrowserParent* tab =
- dom::BrowserParent::GetBrowserParentFromLayersId(aGuid.mLayersId);
- if (tab) {
-#ifdef MOZ_WIDGET_ANDROID
- // On Android, touch events are dispatched from the UI thread to the main
- // thread using the Android priority queue. It is possible that this tap has
- // made it to the GPU process and back before they have been processed. We
- // must therefore dispatch this message to the same queue, otherwise the tab
- // may receive the tap event before the touch events that synthesized it.
- mozilla::jni::DispatchToGeckoPriorityQueue(
- NewRunnableMethod<TapType, LayoutDevicePoint, Modifiers,
- ScrollableLayerGuid, uint64_t,
- Maybe<DoubleTapToZoomMetrics>>(
- "dom::BrowserParent::SendHandleTap", tab,
- &dom::BrowserParent::SendHandleTap, aType, aPoint, aModifiers,
- aGuid, aInputBlockId, aDoubleTapToZoomMetrics));
-#else
- tab->SendHandleTap(aType, aPoint, aModifiers, aGuid, aInputBlockId,
- aDoubleTapToZoomMetrics);
-#endif
- }
- return IPC_OK();
-}
-
mozilla::ipc::IPCResult APZCTreeManagerChild::RecvNotifyPinchGesture(
const PinchGestureType& aType, const ScrollableLayerGuid& aGuid,
const LayoutDevicePoint& aFocusPoint, const LayoutDeviceCoord& aSpanChange,
diff --git a/gfx/layers/ipc/APZCTreeManagerChild.h b/gfx/layers/ipc/APZCTreeManagerChild.h
index 756677e1e3..4d79a18d5a 100644
--- a/gfx/layers/ipc/APZCTreeManagerChild.h
+++ b/gfx/layers/ipc/APZCTreeManagerChild.h
@@ -73,13 +73,6 @@ class APZCTreeManagerChild : public IAPZCTreeManager,
void ActorDestroy(ActorDestroyReason aWhy) override;
protected:
- MOZ_CAN_RUN_SCRIPT_BOUNDARY
- mozilla::ipc::IPCResult RecvHandleTap(
- const TapType& aType, const LayoutDevicePoint& aPoint,
- const Modifiers& aModifiers, const ScrollableLayerGuid& aGuid,
- const uint64_t& aInputBlockId,
- const Maybe<DoubleTapToZoomMetrics>& aDoubleTapToZoomMetrics);
-
mozilla::ipc::IPCResult RecvNotifyPinchGesture(
const PinchGestureType& aType, const ScrollableLayerGuid& aGuid,
const LayoutDevicePoint& aFocusPoint,
diff --git a/gfx/layers/ipc/APZInputBridgeChild.cpp b/gfx/layers/ipc/APZInputBridgeChild.cpp
index bf059143ec..f9de8575a6 100644
--- a/gfx/layers/ipc/APZInputBridgeChild.cpp
+++ b/gfx/layers/ipc/APZInputBridgeChild.cpp
@@ -12,6 +12,14 @@
#include "mozilla/layers/APZThreadUtils.h"
#include "mozilla/layers/SynchronousTask.h"
+#include "mozilla/layers/GeckoContentController.h" // for GeckoContentController
+#include "mozilla/layers/DoubleTapToZoom.h" // for DoubleTapToZoomMetrics
+#include "mozilla/layers/RemoteCompositorSession.h" // for RemoteCompositorSession
+#include "mozilla/dom/BrowserParent.h" // for BrowserParent
+#ifdef MOZ_WIDGET_ANDROID
+# include "mozilla/jni/Utils.h" // for DispatchToGeckoPriorityQueue
+#endif
+
namespace mozilla {
namespace layers {
@@ -31,13 +39,20 @@ RefPtr<APZInputBridgeChild> APZInputBridgeChild::Create(
}
APZInputBridgeChild::APZInputBridgeChild(const uint64_t& aProcessToken)
- : mIsOpen(false), mProcessToken(aProcessToken) {
+ : mIsOpen(false),
+ mProcessToken(aProcessToken),
+ mCompositorSession(nullptr) {
MOZ_ASSERT(XRE_IsParentProcess());
MOZ_ASSERT(NS_IsMainThread());
}
APZInputBridgeChild::~APZInputBridgeChild() = default;
+void APZInputBridgeChild::SetCompositorSession(
+ RemoteCompositorSession* aSession) {
+ mCompositorSession = aSession;
+}
+
void APZInputBridgeChild::Open(Endpoint<PAPZInputBridgeChild>&& aEndpoint) {
APZThreadUtils::AssertOnControllerThread();
@@ -176,6 +191,63 @@ APZEventResult APZInputBridgeChild::ReceiveInputEvent(
return res;
}
+void APZInputBridgeChild::HandleTapOnMainThread(
+ const TapType& aType, const LayoutDevicePoint& aPoint,
+ const Modifiers& aModifiers, const ScrollableLayerGuid& aGuid,
+ const uint64_t& aInputBlockId,
+ const Maybe<DoubleTapToZoomMetrics>& aDoubleTapToZoomMetrics) {
+ if (mCompositorSession &&
+ mCompositorSession->RootLayerTreeId() == aGuid.mLayersId &&
+ mCompositorSession->GetContentController()) {
+ RefPtr<GeckoContentController> controller =
+ mCompositorSession->GetContentController();
+ controller->HandleTap(aType, aPoint, aModifiers, aGuid, aInputBlockId,
+ aDoubleTapToZoomMetrics);
+ return;
+ }
+ dom::BrowserParent* tab =
+ dom::BrowserParent::GetBrowserParentFromLayersId(aGuid.mLayersId);
+ if (tab) {
+#ifdef MOZ_WIDGET_ANDROID
+ // On Android, touch events are dispatched from the UI thread to the main
+ // thread using the Android priority queue. It is possible that this tap has
+ // made it to the GPU process and back before they have been processed. We
+ // must therefore dispatch this message to the same queue, otherwise the tab
+ // may receive the tap event before the touch events that synthesized it.
+ mozilla::jni::DispatchToGeckoPriorityQueue(
+ NewRunnableMethod<TapType, LayoutDevicePoint, Modifiers,
+ ScrollableLayerGuid, uint64_t,
+ Maybe<DoubleTapToZoomMetrics>>(
+ "dom::BrowserParent::SendHandleTap", tab,
+ &dom::BrowserParent::SendHandleTap, aType, aPoint, aModifiers,
+ aGuid, aInputBlockId, aDoubleTapToZoomMetrics));
+#else
+ tab->SendHandleTap(aType, aPoint, aModifiers, aGuid, aInputBlockId,
+ aDoubleTapToZoomMetrics);
+#endif
+ }
+}
+
+mozilla::ipc::IPCResult APZInputBridgeChild::RecvHandleTap(
+ const TapType& aType, const LayoutDevicePoint& aPoint,
+ const Modifiers& aModifiers, const ScrollableLayerGuid& aGuid,
+ const uint64_t& aInputBlockId,
+ const Maybe<DoubleTapToZoomMetrics>& aDoubleTapToZoomMetrics) {
+ if (NS_IsMainThread()) {
+ HandleTapOnMainThread(aType, aPoint, aModifiers, aGuid, aInputBlockId,
+ aDoubleTapToZoomMetrics);
+ } else {
+ NS_DispatchToMainThread(
+ NewRunnableMethod<TapType, LayoutDevicePoint, Modifiers,
+ ScrollableLayerGuid, uint64_t,
+ Maybe<DoubleTapToZoomMetrics>>(
+ "layers::APZInputBridgeChild::HandleTapOnMainThread", this,
+ &APZInputBridgeChild::HandleTapOnMainThread, aType, aPoint,
+ aModifiers, aGuid, aInputBlockId, aDoubleTapToZoomMetrics));
+ }
+ return IPC_OK();
+}
+
mozilla::ipc::IPCResult APZInputBridgeChild::RecvCallInputBlockCallback(
uint64_t aInputBlockId, const APZHandledResult& aHandledResult) {
auto it = mInputBlockCallbacks.find(aInputBlockId);
diff --git a/gfx/layers/ipc/APZInputBridgeChild.h b/gfx/layers/ipc/APZInputBridgeChild.h
index dd77d95f36..4b14e3aa0d 100644
--- a/gfx/layers/ipc/APZInputBridgeChild.h
+++ b/gfx/layers/ipc/APZInputBridgeChild.h
@@ -10,11 +10,16 @@
#include "mozilla/layers/APZInputBridge.h"
#include "mozilla/layers/PAPZInputBridgeChild.h"
+#include "mozilla/layers/GeckoContentControllerTypes.h"
+
namespace mozilla {
namespace layers {
+class RemoteCompositorSession;
+
class APZInputBridgeChild : public PAPZInputBridgeChild, public APZInputBridge {
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(APZInputBridgeChild, final)
+ using TapType = GeckoContentController_TapType;
public:
static RefPtr<APZInputBridgeChild> Create(
@@ -23,10 +28,19 @@ class APZInputBridgeChild : public PAPZInputBridgeChild, public APZInputBridge {
void Destroy();
+ void SetCompositorSession(RemoteCompositorSession* aSession);
+
APZEventResult ReceiveInputEvent(
InputData& aEvent,
InputBlockCallback&& aCallback = InputBlockCallback()) override;
+ MOZ_CAN_RUN_SCRIPT_BOUNDARY
+ mozilla::ipc::IPCResult RecvHandleTap(
+ const TapType& aType, const LayoutDevicePoint& aPoint,
+ const Modifiers& aModifiers, const ScrollableLayerGuid& aGuid,
+ const uint64_t& aInputBlockId,
+ const Maybe<DoubleTapToZoomMetrics>& aDoubleTapToZoomMetrics);
+
mozilla::ipc::IPCResult RecvCallInputBlockCallback(
uint64_t aInputBlockId, const APZHandledResult& handledResult);
@@ -48,8 +62,16 @@ class APZInputBridgeChild : public PAPZInputBridgeChild, public APZInputBridge {
private:
void Open(Endpoint<PAPZInputBridgeChild>&& aEndpoint);
+ MOZ_CAN_RUN_SCRIPT_BOUNDARY
+ void HandleTapOnMainThread(
+ const TapType& aType, const LayoutDevicePoint& aPoint,
+ const Modifiers& aModifiers, const ScrollableLayerGuid& aGuid,
+ const uint64_t& aInputBlockId,
+ const Maybe<DoubleTapToZoomMetrics>& aDoubleTapToZoomMetrics);
+
bool mIsOpen;
uint64_t mProcessToken;
+ MOZ_NON_OWNING_REF RemoteCompositorSession* mCompositorSession = nullptr;
using InputBlockCallbackMap =
std::unordered_map<uint64_t, InputBlockCallback>;
diff --git a/gfx/layers/ipc/APZInputBridgeParent.cpp b/gfx/layers/ipc/APZInputBridgeParent.cpp
index fcc642ff7a..475c15abca 100644
--- a/gfx/layers/ipc/APZInputBridgeParent.cpp
+++ b/gfx/layers/ipc/APZInputBridgeParent.cpp
@@ -16,14 +16,15 @@ namespace mozilla {
namespace layers {
/* static */
-RefPtr<APZInputBridgeParent> APZInputBridgeParent::Create(
+APZInputBridgeParent* APZInputBridgeParent::Create(
const LayersId& aLayersId, Endpoint<PAPZInputBridgeParent>&& aEndpoint) {
- RefPtr<APZInputBridgeParent> parent = new APZInputBridgeParent(aLayersId);
+ APZInputBridgeParent* parent = new APZInputBridgeParent(aLayersId);
if (!aEndpoint.Bind(parent)) {
// We can't recover from this.
MOZ_CRASH("Failed to bind APZInputBridgeParent to endpoint");
}
+ CompositorBridgeParent::SetAPZInputBridgeParent(aLayersId, parent);
return parent;
}
@@ -31,6 +32,7 @@ APZInputBridgeParent::APZInputBridgeParent(const LayersId& aLayersId) {
MOZ_ASSERT(XRE_IsGPUProcess());
MOZ_ASSERT(NS_IsMainThread());
+ mLayersId = aLayersId;
mTreeManager = CompositorBridgeParent::GetAPZCTreeManager(aLayersId);
MOZ_ASSERT(mTreeManager);
}
@@ -205,6 +207,10 @@ mozilla::ipc::IPCResult APZInputBridgeParent::RecvProcessUnhandledEvent(
}
void APZInputBridgeParent::ActorDestroy(ActorDestroyReason aWhy) {
+ StaticMonitorAutoLock lock(CompositorBridgeParent::sIndirectLayerTreesLock);
+ CompositorBridgeParent::LayerTreeState& state =
+ CompositorBridgeParent::sIndirectLayerTrees[mLayersId];
+ state.mApzInputBridgeParent = nullptr;
// We shouldn't need it after this
mTreeManager = nullptr;
}
diff --git a/gfx/layers/ipc/APZInputBridgeParent.h b/gfx/layers/ipc/APZInputBridgeParent.h
index 71f43d092b..62e6427bb5 100644
--- a/gfx/layers/ipc/APZInputBridgeParent.h
+++ b/gfx/layers/ipc/APZInputBridgeParent.h
@@ -18,7 +18,7 @@ class APZInputBridgeParent : public PAPZInputBridgeParent {
NS_INLINE_DECL_REFCOUNTING(APZInputBridgeParent, final)
public:
- static RefPtr<APZInputBridgeParent> Create(
+ static APZInputBridgeParent* Create(
const LayersId& aLayersId, Endpoint<PAPZInputBridgeParent>&& aEndpoint);
mozilla::ipc::IPCResult RecvReceiveMultiTouchInputEvent(
@@ -67,6 +67,7 @@ class APZInputBridgeParent : public PAPZInputBridgeParent {
private:
RefPtr<IAPZCTreeManager> mTreeManager;
+ LayersId mLayersId;
};
} // namespace layers
diff --git a/gfx/layers/ipc/CanvasChild.cpp b/gfx/layers/ipc/CanvasChild.cpp
index a25d5e6799..efcd520300 100644
--- a/gfx/layers/ipc/CanvasChild.cpp
+++ b/gfx/layers/ipc/CanvasChild.cpp
@@ -206,13 +206,11 @@ class CanvasDataShmemHolder {
}
void Destroy() {
- class DestroyRunnable final : public dom::WorkerRunnable {
+ class DestroyRunnable final : public dom::WorkerThreadRunnable {
public:
DestroyRunnable(dom::WorkerPrivate* aWorkerPrivate,
CanvasDataShmemHolder* aShmemHolder)
- : dom::WorkerRunnable(aWorkerPrivate,
- "CanvasDataShmemHolder::Destroy",
- dom::WorkerRunnable::WorkerThread),
+ : dom::WorkerThreadRunnable("CanvasDataShmemHolder::Destroy"),
mShmemHolder(aShmemHolder) {}
bool WorkerRun(JSContext* aCx,
@@ -241,8 +239,9 @@ class CanvasDataShmemHolder {
if (mWorkerRef) {
if (!mWorkerRef->Private()->IsOnCurrentThread()) {
auto task = MakeRefPtr<DestroyRunnable>(mWorkerRef->Private(), this);
+ dom::WorkerPrivate* worker = mWorkerRef->Private();
mMutex.Unlock();
- task->Dispatch();
+ task->Dispatch(worker);
return;
}
} else if (!NS_IsMainThread()) {
diff --git a/gfx/layers/ipc/CanvasTranslator.cpp b/gfx/layers/ipc/CanvasTranslator.cpp
index 3fd7a4c4c4..46cab838de 100644
--- a/gfx/layers/ipc/CanvasTranslator.cpp
+++ b/gfx/layers/ipc/CanvasTranslator.cpp
@@ -1190,23 +1190,42 @@ already_AddRefed<gfx::SourceSurface> CanvasTranslator::LookupExternalSurface(
// Check if the surface descriptor describes a GPUVideo texture for which we
// only have an opaque source/handle from SurfaceDescriptorRemoteDecoder to
// derive the actual texture from.
-static bool SDIsNullRemoteDecoder(const SurfaceDescriptor& sd) {
- return sd.type() == SurfaceDescriptor::TSurfaceDescriptorGPUVideo &&
- sd.get_SurfaceDescriptorGPUVideo()
- .get_SurfaceDescriptorRemoteDecoder()
- .subdesc()
- .type() == RemoteDecoderVideoSubDescriptor::Tnull_t;
+static bool SDIsSupportedRemoteDecoder(const SurfaceDescriptor& sd) {
+ if (sd.type() != SurfaceDescriptor::TSurfaceDescriptorGPUVideo) {
+ return false;
+ }
+
+ const auto& sdv = sd.get_SurfaceDescriptorGPUVideo();
+ const auto& sdvType = sdv.type();
+ if (sdvType != SurfaceDescriptorGPUVideo::TSurfaceDescriptorRemoteDecoder) {
+ return false;
+ }
+
+ const auto& sdrd = sdv.get_SurfaceDescriptorRemoteDecoder();
+ const auto& subdesc = sdrd.subdesc();
+ const auto& subdescType = subdesc.type();
+
+ if (subdescType == RemoteDecoderVideoSubDescriptor::Tnull_t ||
+ subdescType ==
+ RemoteDecoderVideoSubDescriptor::TSurfaceDescriptorMacIOSurface) {
+ return true;
+ }
+
+ return false;
}
already_AddRefed<gfx::SourceSurface>
CanvasTranslator::LookupSourceSurfaceFromSurfaceDescriptor(
const SurfaceDescriptor& aDesc) {
- if (!SDIsNullRemoteDecoder(aDesc)) {
+ if (!SDIsSupportedRemoteDecoder(aDesc)) {
return nullptr;
}
const auto& sdrd = aDesc.get_SurfaceDescriptorGPUVideo()
.get_SurfaceDescriptorRemoteDecoder();
+ const auto& subdesc = sdrd.subdesc();
+ const auto& subdescType = subdesc.type();
+
RefPtr<VideoBridgeParent> parent =
VideoBridgeParent::GetSingleton(sdrd.source());
if (!parent) {
@@ -1222,9 +1241,19 @@ CanvasTranslator::LookupSourceSurfaceFromSurfaceDescriptor(
return nullptr;
}
- RefPtr<gfx::DataSourceSurface> surf = texture->GetAsSurface();
+ if (subdescType ==
+ RemoteDecoderVideoSubDescriptor::TSurfaceDescriptorMacIOSurface) {
+ MOZ_ASSERT(texture->AsMacIOSurfaceTextureHost());
+ return texture->GetAsSurface();
+ }
+
+ if (subdescType == RemoteDecoderVideoSubDescriptor::Tnull_t) {
+ RefPtr<gfx::DataSourceSurface> surf = texture->GetAsSurface();
+ return surf.forget();
+ }
- return surf.forget();
+ MOZ_ASSERT_UNREACHABLE("unexpected to be called");
+ return nullptr;
}
void CanvasTranslator::CheckpointReached() { CheckAndSignalWriter(); }
diff --git a/gfx/layers/ipc/CompositorBridgeParent.cpp b/gfx/layers/ipc/CompositorBridgeParent.cpp
index 767ea47b2f..d6efb2c991 100644
--- a/gfx/layers/ipc/CompositorBridgeParent.cpp
+++ b/gfx/layers/ipc/CompositorBridgeParent.cpp
@@ -167,6 +167,7 @@ bool CompositorBridgeParentBase::DeallocShmem(ipc::Shmem& aShmem) {
CompositorBridgeParent::LayerTreeState::LayerTreeState()
: mApzcTreeManagerParent(nullptr),
+ mApzInputBridgeParent(nullptr),
mParent(nullptr),
mContentCompositorBridgeParent(nullptr) {}
@@ -645,9 +646,21 @@ bool CompositorBridgeParent::DeallocPAPZCTreeManagerParent(
return true;
}
+void CompositorBridgeParent::SetAPZInputBridgeParent(
+ const LayersId& aLayersId, APZInputBridgeParent* aInputBridgeParent) {
+ MOZ_RELEASE_ASSERT(XRE_IsGPUProcess());
+ MOZ_ASSERT(NS_IsMainThread());
+ StaticMonitorAutoLock lock(CompositorBridgeParent::sIndirectLayerTreesLock);
+ CompositorBridgeParent::LayerTreeState& state =
+ CompositorBridgeParent::sIndirectLayerTrees[aLayersId];
+ MOZ_ASSERT(!state.mApzInputBridgeParent);
+ state.mApzInputBridgeParent = aInputBridgeParent;
+}
+
void CompositorBridgeParent::AllocateAPZCTreeManagerParent(
const StaticMonitorAutoLock& aProofOfLayerTreeStateLock,
const LayersId& aLayersId, LayerTreeState& aState) {
+ MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
MOZ_ASSERT(aState.mParent == this);
MOZ_ASSERT(mApzcTreeManager);
MOZ_ASSERT(mApzUpdater);
@@ -1713,6 +1726,15 @@ APZCTreeManagerParent* CompositorBridgeParent::GetApzcTreeManagerParentForRoot(
}
/* static */
+APZInputBridgeParent* CompositorBridgeParent::GetApzInputBridgeParentForRoot(
+ LayersId aContentLayersId) {
+ StaticMonitorAutoLock lock(sIndirectLayerTreesLock);
+ CompositorBridgeParent::LayerTreeState* state =
+ GetStateForRoot(aContentLayersId, lock);
+ return state ? state->mApzInputBridgeParent : nullptr;
+}
+
+/* static */
GeckoContentController*
CompositorBridgeParent::GetGeckoContentControllerForRoot(
LayersId aContentLayersId) {
diff --git a/gfx/layers/ipc/CompositorBridgeParent.h b/gfx/layers/ipc/CompositorBridgeParent.h
index 0e6bd48f9a..c7cb530989 100644
--- a/gfx/layers/ipc/CompositorBridgeParent.h
+++ b/gfx/layers/ipc/CompositorBridgeParent.h
@@ -24,6 +24,7 @@
#include "mozilla/layers/ISurfaceAllocator.h" // for IShmemAllocator
#include "mozilla/layers/LayersTypes.h"
#include "mozilla/layers/PCompositorBridgeParent.h"
+#include "mozilla/layers/APZInputBridgeParent.h"
#include "mozilla/webrender/WebRenderTypes.h"
namespace mozilla {
@@ -394,6 +395,10 @@ class CompositorBridgeParent final : public CompositorBridgeParentBase,
~LayerTreeState();
RefPtr<GeckoContentController> mController;
APZCTreeManagerParent* mApzcTreeManagerParent;
+ // The mApzInputBridgeParent is only populated for LayerTreeState
+ // objects corresponding to root LayerIds (one for each top-level
+ // window).
+ APZInputBridgeParent* mApzInputBridgeParent;
RefPtr<CompositorBridgeParent> mParent;
RefPtr<WebRenderBridgeParent> mWrBridge;
// Pointer to the ContentCompositorBridgeParent. Used by APZCs to share
@@ -438,6 +443,13 @@ class CompositorBridgeParent final : public CompositorBridgeParentBase,
LayersId aContentLayersId);
/**
+ * Same as the GetApzcTreeManagerParentForRoot function, but returns
+ * the APZInputBridge for the parent process.
+ */
+ static APZInputBridgeParent* GetApzInputBridgeParentForRoot(
+ LayersId aContentLayersId);
+
+ /**
* Used by the profiler to denote when a vsync occured
*/
static void PostInsertVsyncProfilerMarker(mozilla::TimeStamp aVsyncTimestamp);
@@ -454,6 +466,9 @@ class CompositorBridgeParent final : public CompositorBridgeParentBase,
const StaticMonitorAutoLock& aProofOfLayerTreeStateLock,
const LayersId& aLayersId, LayerTreeState& aLayerTreeStateToUpdate);
+ static void SetAPZInputBridgeParent(const LayersId& aLayersId,
+ APZInputBridgeParent* aInputBridgeParent);
+
PAPZParent* AllocPAPZParent(const LayersId& aLayersId) override;
bool DeallocPAPZParent(PAPZParent* aActor) override;
diff --git a/gfx/layers/ipc/PAPZCTreeManager.ipdl b/gfx/layers/ipc/PAPZCTreeManager.ipdl
index a08e2cfeb1..75cb04bea6 100644
--- a/gfx/layers/ipc/PAPZCTreeManager.ipdl
+++ b/gfx/layers/ipc/PAPZCTreeManager.ipdl
@@ -80,10 +80,6 @@ parent:
child:
- async HandleTap(GeckoContentController_TapType aType, LayoutDevicePoint point, Modifiers aModifiers,
- ScrollableLayerGuid aGuid, uint64_t aInputBlockId,
- DoubleTapToZoomMetrics? aDoubleTapToZoomMetrics);
-
async NotifyPinchGesture(PinchGestureType aType, ScrollableLayerGuid aGuid,
LayoutDevicePoint aFocusPoint, LayoutDeviceCoord aSpanChange,
Modifiers aModifiers);
diff --git a/gfx/layers/ipc/PAPZInputBridge.ipdl b/gfx/layers/ipc/PAPZInputBridge.ipdl
index 7564757b28..35ca82c018 100644
--- a/gfx/layers/ipc/PAPZInputBridge.ipdl
+++ b/gfx/layers/ipc/PAPZInputBridge.ipdl
@@ -6,11 +6,15 @@
include "ipc/nsGUIEventIPC.h";
using mozilla::LayoutDeviceIntPoint from "Units.h";
+using mozilla::LayoutDevicePoint from "Units.h";
+using mozilla::layers::GeckoContentController_TapType from "mozilla/layers/GeckoContentControllerTypes.h";
+using mozilla::layers::DoubleTapToZoomMetrics from "mozilla/layers/DoubleTapToZoom.h";
using struct mozilla::layers::ScrollableLayerGuid from "mozilla/layers/ScrollableLayerGuid.h";
using struct mozilla::layers::APZEventResult from "mozilla/layers/APZInputBridge.h";
using struct mozilla::layers::APZHandledResult from "mozilla/layers/APZInputBridge.h";
using mozilla::EventMessage from "mozilla/EventForwards.h";
+using mozilla::Modifiers from "mozilla/EventForwards.h";
using class mozilla::MultiTouchInput from "InputData.h";
using class mozilla::MouseInput from "InputData.h";
using class mozilla::PanGestureInput from "InputData.h";
@@ -82,6 +86,10 @@ parent:
child:
async CallInputBlockCallback(uint64_t aInputBlockId,
APZHandledResult aHandledResult);
+
+ async HandleTap(GeckoContentController_TapType aType, LayoutDevicePoint point,
+ Modifiers aModifiers, ScrollableLayerGuid aGuid,
+ uint64_t aInputBlockId, DoubleTapToZoomMetrics? aDoubleTapToZoomMetrics);
};
} // namespace gfx
diff --git a/gfx/layers/ipc/RemoteContentController.cpp b/gfx/layers/ipc/RemoteContentController.cpp
index 682331362b..8c6ab22acd 100644
--- a/gfx/layers/ipc/RemoteContentController.cpp
+++ b/gfx/layers/ipc/RemoteContentController.cpp
@@ -62,7 +62,7 @@ void RemoteContentController::RequestContentRepaint(
}
}
-void RemoteContentController::HandleTapOnMainThread(
+void RemoteContentController::HandleTapOnParentProcessMainThread(
TapType aTapType, LayoutDevicePoint aPoint, Modifiers aModifiers,
ScrollableLayerGuid aGuid, uint64_t aInputBlockId,
const Maybe<DoubleTapToZoomMetrics>& aDoubleTapToZoomMetrics) {
@@ -78,20 +78,19 @@ void RemoteContentController::HandleTapOnMainThread(
}
}
-void RemoteContentController::HandleTapOnCompositorThread(
+void RemoteContentController::HandleTapOnGPUProcessMainThread(
TapType aTapType, LayoutDevicePoint aPoint, Modifiers aModifiers,
ScrollableLayerGuid aGuid, uint64_t aInputBlockId,
const Maybe<DoubleTapToZoomMetrics>& aDoubleTapToZoomMetrics) {
MOZ_ASSERT(XRE_IsGPUProcess());
- MOZ_ASSERT(mCompositorThread->IsOnCurrentThread());
+ MOZ_ASSERT(NS_IsMainThread());
- // The raw pointer to APZCTreeManagerParent is ok here because we are on
- // the compositor thread.
- APZCTreeManagerParent* apzctmp =
- CompositorBridgeParent::GetApzcTreeManagerParentForRoot(aGuid.mLayersId);
- if (apzctmp) {
- Unused << apzctmp->SendHandleTap(aTapType, aPoint, aModifiers, aGuid,
- aInputBlockId, aDoubleTapToZoomMetrics);
+ // Send a message to the controller thread to handle the single-tap gesture.
+ APZInputBridgeParent* apzib =
+ CompositorBridgeParent::GetApzInputBridgeParentForRoot(aGuid.mLayersId);
+ if (apzib) {
+ Unused << apzib->SendHandleTap(aTapType, aPoint, aModifiers, aGuid,
+ aInputBlockId, aDoubleTapToZoomMetrics);
}
}
@@ -103,19 +102,18 @@ void RemoteContentController::HandleTap(
APZThreadUtils::AssertOnControllerThread();
if (XRE_GetProcessType() == GeckoProcessType_GPU) {
- if (mCompositorThread->IsOnCurrentThread()) {
- HandleTapOnCompositorThread(aTapType, aPoint, aModifiers, aGuid,
- aInputBlockId, aDoubleTapToZoomMetrics);
+ if (NS_IsMainThread()) {
+ HandleTapOnGPUProcessMainThread(aTapType, aPoint, aModifiers, aGuid,
+ aInputBlockId, aDoubleTapToZoomMetrics);
} else {
- // We have to send messages from the compositor thread
- mCompositorThread->Dispatch(
- NewRunnableMethod<TapType, LayoutDevicePoint, Modifiers,
- ScrollableLayerGuid, uint64_t,
- Maybe<DoubleTapToZoomMetrics>>(
- "layers::RemoteContentController::HandleTapOnCompositorThread",
- this, &RemoteContentController::HandleTapOnCompositorThread,
- aTapType, aPoint, aModifiers, aGuid, aInputBlockId,
- aDoubleTapToZoomMetrics));
+ NS_DispatchToMainThread(NewRunnableMethod<TapType, LayoutDevicePoint,
+ Modifiers, ScrollableLayerGuid,
+ uint64_t,
+ Maybe<DoubleTapToZoomMetrics>>(
+ "layers::RemoteContentController::HandleTapOnGPUProcessMainThread",
+ this, &RemoteContentController::HandleTapOnGPUProcessMainThread,
+ aTapType, aPoint, aModifiers, aGuid, aInputBlockId,
+ aDoubleTapToZoomMetrics));
}
return;
}
@@ -123,8 +121,8 @@ void RemoteContentController::HandleTap(
MOZ_ASSERT(XRE_IsParentProcess());
if (NS_IsMainThread()) {
- HandleTapOnMainThread(aTapType, aPoint, aModifiers, aGuid, aInputBlockId,
- aDoubleTapToZoomMetrics);
+ HandleTapOnParentProcessMainThread(aTapType, aPoint, aModifiers, aGuid,
+ aInputBlockId, aDoubleTapToZoomMetrics);
} else {
// We must be on Android, running on the Java UI thread
#ifndef MOZ_WIDGET_ANDROID
@@ -138,13 +136,15 @@ void RemoteContentController::HandleTap(
// using NS_DispatchToMainThread would post to a different message loop,
// and introduces the possibility of this tap event getting processed
// out of order with respect to the touch events that synthesized it.
- mozilla::jni::DispatchToGeckoPriorityQueue(
- NewRunnableMethod<TapType, LayoutDevicePoint, Modifiers,
- ScrollableLayerGuid, uint64_t,
- Maybe<DoubleTapToZoomMetrics>>(
- "layers::RemoteContentController::HandleTapOnMainThread", this,
- &RemoteContentController::HandleTapOnMainThread, aTapType, aPoint,
- aModifiers, aGuid, aInputBlockId, aDoubleTapToZoomMetrics));
+ mozilla::jni::DispatchToGeckoPriorityQueue(NewRunnableMethod<
+ TapType, LayoutDevicePoint,
+ Modifiers, ScrollableLayerGuid,
+ uint64_t,
+ Maybe<DoubleTapToZoomMetrics>>(
+ "layers::RemoteContentController::HandleTapOnParentProcessMainThread",
+ this, &RemoteContentController::HandleTapOnParentProcessMainThread,
+ aTapType, aPoint, aModifiers, aGuid, aInputBlockId,
+ aDoubleTapToZoomMetrics));
#endif
}
}
diff --git a/gfx/layers/ipc/RemoteContentController.h b/gfx/layers/ipc/RemoteContentController.h
index 7c2ef3789f..34f85004d2 100644
--- a/gfx/layers/ipc/RemoteContentController.h
+++ b/gfx/layers/ipc/RemoteContentController.h
@@ -98,12 +98,12 @@ class RemoteContentController : public GeckoContentController,
nsCOMPtr<nsISerialEventTarget> mCompositorThread;
bool mCanSend;
- void HandleTapOnMainThread(
- TapType aType, LayoutDevicePoint aPoint, Modifiers aModifiers,
+ void HandleTapOnParentProcessMainThread(
+ TapType aTapType, LayoutDevicePoint aPoint, Modifiers aModifiers,
ScrollableLayerGuid aGuid, uint64_t aInputBlockId,
const Maybe<DoubleTapToZoomMetrics>& aDoubleTapToZoomMetrics);
- void HandleTapOnCompositorThread(
- TapType aType, LayoutDevicePoint aPoint, Modifiers aModifiers,
+ void HandleTapOnGPUProcessMainThread(
+ TapType aTapType, LayoutDevicePoint aPoint, Modifiers aModifiers,
ScrollableLayerGuid aGuid, uint64_t aInputBlockId,
const Maybe<DoubleTapToZoomMetrics>& aDoubleTapToZoomMetrics);
void NotifyPinchGestureOnCompositorThread(
diff --git a/gfx/layers/wr/WebRenderImageHost.cpp b/gfx/layers/wr/WebRenderImageHost.cpp
index 5016bc30f8..3febc5872b 100644
--- a/gfx/layers/wr/WebRenderImageHost.cpp
+++ b/gfx/layers/wr/WebRenderImageHost.cpp
@@ -18,6 +18,7 @@
#include "mozilla/layers/RemoteTextureMap.h"
#include "mozilla/layers/WebRenderBridgeParent.h"
#include "mozilla/layers/WebRenderTextureHost.h"
+#include "mozilla/ProfilerMarkers.h"
#include "mozilla/StaticPrefs_webgl.h"
#include "nsAString.h"
#include "nsDebug.h" // for NS_WARNING, NS_ASSERTION
@@ -311,12 +312,15 @@ TextureHost* WebRenderImageHost::GetAsTextureHostForComposite(
// Convert YUV BufferTextureHost to TextureHostWrapperD3D11 if possible
if (texture->AsBufferTextureHost()) {
auto identifier = aAsyncImageManager->GetTextureFactoryIdentifier();
- const bool convertToNV12 =
+ const bool tryConvertToNV12 =
StaticPrefs::gfx_video_convert_yuv_to_nv12_image_host_win() &&
identifier.mSupportsD3D11NV12 &&
KnowsCompositor::SupportsD3D11(identifier) &&
texture->GetFormat() == gfx::SurfaceFormat::YUV;
- if (convertToNV12) {
+ if (tryConvertToNV12) {
+ PROFILER_MARKER_TEXT("WebRenderImageHost", GRAPHICS, {},
+ "Try ConvertToNV12"_ns);
+
if (!mTextureAllocator) {
mTextureAllocator = new TextureWrapperD3D11Allocator();
}
@@ -326,6 +330,13 @@ TextureHost* WebRenderImageHost::GetAsTextureHostForComposite(
if (textureWrapper) {
texture = textureWrapper;
}
+ } else if (profiler_thread_is_being_profiled_for_markers() &&
+ StaticPrefs::gfx_video_convert_yuv_to_nv12_image_host_win() &&
+ texture->GetFormat() == gfx::SurfaceFormat::YUV) {
+ nsPrintfCString str("No ConvertToNV12 D3D11 %d NV12 %d",
+ KnowsCompositor::SupportsD3D11(identifier),
+ identifier.mSupportsD3D11NV12);
+ PROFILER_MARKER_TEXT("WebRenderImageHost", GRAPHICS, {}, str);
}
}
#endif