diff --git a/gfx/layers/apz/src/APZCTreeManager.cpp b/gfx/layers/apz/src/APZCTreeManager.cpp index 240549ae4b73..8499ee7db541 100644 --- a/gfx/layers/apz/src/APZCTreeManager.cpp +++ b/gfx/layers/apz/src/APZCTreeManager.cpp @@ -2848,19 +2848,19 @@ APZCTreeManager::HitTestResult APZCTreeManager::GetAPZCAtPointWR( return hit; } - wr::WrPipelineId pipelineId; - ScrollableLayerGuid::ViewID scrollId; - gfx::CompositorHitTestInfo hitInfo; - SideBits sideBits = SideBits::eNone; APZCTM_LOG("Hit-testing point %s with WR\n", Stringify(aHitTestPoint).c_str()); - bool hitSomething = wr->HitTest(wr::ToWorldPoint(aHitTestPoint), pipelineId, - scrollId, hitInfo, sideBits); - if (!hitSomething) { + std::vector results = + wr->HitTest(wr::ToWorldPoint(aHitTestPoint)); + if (results.empty()) { return hit; } - hit.mLayersId = wr::AsLayersId(pipelineId); + hit.mLayersId = results[0].mLayersId; + ScrollableLayerGuid::ViewID scrollId = results[0].mScrollId; + gfx::CompositorHitTestInfo hitInfo = results[0].mHitInfo; + SideBits sideBits = results[0].mSideBits; + ScrollableLayerGuid guid{hit.mLayersId, 0, scrollId}; if (RefPtr node = GetTargetNode(guid, &GuidComparatorIgnoringPresShell)) { diff --git a/gfx/webrender_bindings/WebRenderAPI.cpp b/gfx/webrender_bindings/WebRenderAPI.cpp index 36bcecc4f3e0..d17dc0e2abea 100644 --- a/gfx/webrender_bindings/WebRenderAPI.cpp +++ b/gfx/webrender_bindings/WebRenderAPI.cpp @@ -463,24 +463,25 @@ SideBits ExtractSideBitsFromHitInfoBits(uint16_t& aHitInfoBits) { return sideBits; } -bool WebRenderAPI::HitTest(const wr::WorldPoint& aPoint, - wr::WrPipelineId& aOutPipelineId, - layers::ScrollableLayerGuid::ViewID& aOutScrollId, - gfx::CompositorHitTestInfo& aOutHitInfo, - SideBits& aOutSideBits) { +std::vector WebRenderAPI::HitTest(const wr::WorldPoint& aPoint) { static_assert(gfx::DoesCompositorHitTestInfoFitIntoBits<12>(), "CompositorHitTestFlags MAX value has to be less than number " "of bits in uint16_t minus 4 for SideBitsPacked"); - uint16_t serialized = static_cast(aOutHitInfo.serialize()); - const bool result = wr_api_hit_test(mDocHandle, aPoint, &aOutPipelineId, - &aOutScrollId, &serialized); + nsTArray wrResults; + wr_api_hit_test(mDocHandle, aPoint, &wrResults); - if (result) { - aOutSideBits = ExtractSideBitsFromHitInfoBits(serialized); - aOutHitInfo.deserialize(serialized); + std::vector geckoResults; + for (wr::HitResult wrResult : wrResults) { + WrHitResult geckoResult; + geckoResult.mLayersId = wr::AsLayersId(wrResult.pipeline_id); + geckoResult.mScrollId = + static_cast(wrResult.scroll_id); + geckoResult.mSideBits = ExtractSideBitsFromHitInfoBits(wrResult.hit_info); + geckoResult.mHitInfo.deserialize(wrResult.hit_info); + geckoResults.push_back(geckoResult); } - return result; + return geckoResults; } void WebRenderAPI::Readback(const TimeStamp& aStartTime, gfx::IntSize size, diff --git a/gfx/webrender_bindings/WebRenderAPI.h b/gfx/webrender_bindings/WebRenderAPI.h index 93cc10d06ea7..9e6d5cf018ab 100644 --- a/gfx/webrender_bindings/WebRenderAPI.h +++ b/gfx/webrender_bindings/WebRenderAPI.h @@ -79,6 +79,13 @@ class NotificationHandler { virtual ~NotificationHandler() = default; }; +struct WrHitResult { + layers::LayersId mLayersId; + layers::ScrollableLayerGuid::ViewID mScrollId; + gfx::CompositorHitTestInfo mHitInfo; + SideBits mSideBits; +}; + class TransactionBuilder final { public: explicit TransactionBuilder(bool aUseSceneBuilderThread = true); @@ -235,14 +242,9 @@ class WebRenderAPI final { wr::WindowId GetId() const { return mId; } - /// Do a non-blocking hit-testing query on a shared hit-testing information. - bool HitTest(const wr::WorldPoint& aPoint, wr::WrPipelineId& aOutPipelineId, - layers::ScrollableLayerGuid::ViewID& aOutScrollId, - gfx::CompositorHitTestInfo& aOutHitInfo, SideBits& aOutSideBits); - - /// Do a non-blocking hit-testing query on a shared version of the hit testing - /// information. - /// + /// Do a non-blocking hit-testing query on a shared version of the hit + /// testing information. + std::vector HitTest(const wr::WorldPoint& aPoint); void SendTransaction(TransactionBuilder& aTxn); diff --git a/gfx/webrender_bindings/src/bindings.rs b/gfx/webrender_bindings/src/bindings.rs index 5209258d4a1c..0305c1acb82c 100644 --- a/gfx/webrender_bindings/src/bindings.rs +++ b/gfx/webrender_bindings/src/bindings.rs @@ -3590,34 +3590,30 @@ pub extern "C" fn wr_clear_item_tag(state: &mut WrState) { state.current_tag = None; } +#[repr(C)] +pub struct HitResult { + pipeline_id: WrPipelineId, + scroll_id: u64, + hit_info: u16, +} + #[no_mangle] -pub extern "C" fn wr_api_hit_test( - dh: &mut DocumentHandle, - point: WorldPoint, - out_pipeline_id: &mut WrPipelineId, - out_scroll_id: &mut u64, - out_hit_info: &mut u16, -) -> bool { +pub extern "C" fn wr_api_hit_test(dh: &mut DocumentHandle, point: WorldPoint, out_results: &mut ThinVec) { dh.ensure_hit_tester(); let result = dh .hit_tester .as_ref() .unwrap() - .hit_test(None, point, HitTestFlags::empty()); + .hit_test(None, point, HitTestFlags::FIND_ALL); for item in &result.items { - // For now we should never be getting results back for which the tag is - // 0 (== CompositorHitTestInvisibleToHit). In the future if we allow this, - // we'll want to |continue| on the loop in this scenario. - debug_assert!(item.tag.1 != 0); - *out_pipeline_id = item.pipeline; - *out_scroll_id = item.tag.0; - *out_hit_info = item.tag.1; - return true; + out_results.push(HitResult { + pipeline_id: item.pipeline, + scroll_id: item.tag.0, + hit_info: item.tag.1, + }); } - - false } pub type VecU8 = Vec;