Bug 1566599 - Have the WR hit-test return all results to the caller. r=botond

No functional changes here, just plumbing to allow the caller to
access all the results instead of just the one picked out by
bindings.rs.

Differential Revision: https://phabricator.services.mozilla.com/D69202

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Kartikaya Gupta 2020-04-14 00:43:18 +00:00
Родитель df9f30b0b8
Коммит 442f54f533
4 изменённых файлов: 45 добавлений и 46 удалений

Просмотреть файл

@ -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<wr::WrHitResult> 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<HitTestingTreeNode> node =
GetTargetNode(guid, &GuidComparatorIgnoringPresShell)) {

Просмотреть файл

@ -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<WrHitResult> 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<uint16_t>(aOutHitInfo.serialize());
const bool result = wr_api_hit_test(mDocHandle, aPoint, &aOutPipelineId,
&aOutScrollId, &serialized);
nsTArray<wr::HitResult> wrResults;
wr_api_hit_test(mDocHandle, aPoint, &wrResults);
if (result) {
aOutSideBits = ExtractSideBitsFromHitInfoBits(serialized);
aOutHitInfo.deserialize(serialized);
std::vector<WrHitResult> geckoResults;
for (wr::HitResult wrResult : wrResults) {
WrHitResult geckoResult;
geckoResult.mLayersId = wr::AsLayersId(wrResult.pipeline_id);
geckoResult.mScrollId =
static_cast<layers::ScrollableLayerGuid::ViewID>(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,

Просмотреть файл

@ -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<WrHitResult> HitTest(const wr::WorldPoint& aPoint);
void SendTransaction(TransactionBuilder& aTxn);

Просмотреть файл

@ -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<HitResult>) {
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<u8>;