mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-29 07:42:04 +00:00
Bug 1389149 - Add WR bindings for setting hit-test info and doing hit-tests. r=mstange
This exposes some functions on wr::DisplayListBuilder to set hit-test info and to do hit-tests. The mechanism to set hit-test info is made a little more generic than is actually used in this patchset, because doing it this way allows for more optimization possibilities. Specifically, the API allows setting some hit-testing state which is then applied to all display items that are created until that state is updated or cleared. An alternative would be to specify the hit-testing state explicitly when creating particular display items; however doing that would force the call sites that create the display items to compute or obtain the hit-testing state, which would make the code less encapsulated and harder to refactor/optimize. MozReview-Commit-ID: EJoCFv83iu8 --HG-- extra : rebase_source : d2a117a52144f76dcc312de2a4047298e78135cb
This commit is contained in:
parent
26f0373ad0
commit
a02e29e13b
@ -11,7 +11,6 @@
|
||||
#include "mozilla/gfx/gfxVars.h"
|
||||
#include "mozilla/layers/CompositorThread.h"
|
||||
#include "mozilla/widget/CompositorWidget.h"
|
||||
#include "mozilla/widget/CompositorWidget.h"
|
||||
#include "mozilla/layers/SynchronousTask.h"
|
||||
|
||||
#define WRDL_LOG(...)
|
||||
@ -222,6 +221,18 @@ WebRenderAPI::UpdateScrollPosition(const wr::WrPipelineId& aPipelineId,
|
||||
wr_scroll_layer_with_id(mDocHandle, aPipelineId, aScrollId, aScrollPosition);
|
||||
}
|
||||
|
||||
bool
|
||||
WebRenderAPI::HitTest(const wr::WorldPoint& aPoint,
|
||||
wr::WrPipelineId& aOutPipelineId,
|
||||
layers::FrameMetrics::ViewID& aOutScrollId,
|
||||
gfx::CompositorHitTestInfo& aOutHitInfo)
|
||||
{
|
||||
static_assert(sizeof(gfx::CompositorHitTestInfo) == sizeof(uint8_t),
|
||||
"CompositorHitTestInfo should be u8-sized");
|
||||
return wr_api_hit_test(mDocHandle, aPoint,
|
||||
&aOutPipelineId, &aOutScrollId, (uint8_t*)&aOutHitInfo);
|
||||
}
|
||||
|
||||
void
|
||||
WebRenderAPI::GenerateFrame()
|
||||
{
|
||||
@ -1248,5 +1259,20 @@ DisplayListBuilder::TopmostIsClip()
|
||||
return mClipStack.back().is<wr::WrClipId>();
|
||||
}
|
||||
|
||||
void
|
||||
DisplayListBuilder::SetHitTestInfo(const layers::FrameMetrics::ViewID& aScrollId,
|
||||
gfx::CompositorHitTestInfo aHitInfo)
|
||||
{
|
||||
static_assert(sizeof(gfx::CompositorHitTestInfo) == sizeof(uint8_t),
|
||||
"CompositorHitTestInfo should be u8-sized");
|
||||
wr_set_item_tag(mWrState, aScrollId, static_cast<uint8_t>(aHitInfo));
|
||||
}
|
||||
|
||||
void
|
||||
DisplayListBuilder::ClearHitTestInfo()
|
||||
{
|
||||
wr_clear_item_tag(mWrState);
|
||||
}
|
||||
|
||||
} // namespace wr
|
||||
} // namespace mozilla
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include <unordered_set>
|
||||
|
||||
#include "mozilla/AlreadyAddRefed.h"
|
||||
#include "mozilla/gfx/CompositorHitTestInfo.h"
|
||||
#include "mozilla/layers/SyncObject.h"
|
||||
#include "mozilla/Range.h"
|
||||
#include "mozilla/webrender/webrender_ffi.h"
|
||||
@ -143,6 +144,10 @@ public:
|
||||
void UpdateScrollPosition(const wr::WrPipelineId& aPipelineId,
|
||||
const layers::FrameMetrics::ViewID& aScrollId,
|
||||
const wr::LayoutPoint& aScrollPosition);
|
||||
bool HitTest(const wr::WorldPoint& aPoint,
|
||||
wr::WrPipelineId& aOutPipelineId,
|
||||
layers::FrameMetrics::ViewID& aOutScrollId,
|
||||
gfx::CompositorHitTestInfo& aOutHitInfo);
|
||||
|
||||
void GenerateFrame();
|
||||
void GenerateFrame(const nsTArray<wr::WrOpacityProperty>& aOpacityArray,
|
||||
@ -421,6 +426,13 @@ public:
|
||||
// If the topmost item on the stack is a clip or a scroll layer
|
||||
bool TopmostIsClip();
|
||||
|
||||
// Set the hit-test info to be used for all display items until the next call
|
||||
// to SetHitTestInfo or ClearHitTestInfo.
|
||||
void SetHitTestInfo(const layers::FrameMetrics::ViewID& aScrollId,
|
||||
gfx::CompositorHitTestInfo aHitInfo);
|
||||
// Clears the hit-test info so that subsequent display items will not have it.
|
||||
void ClearHitTestInfo();
|
||||
|
||||
// Try to avoid using this when possible.
|
||||
wr::WrState* Raw() { return mWrState; }
|
||||
|
||||
|
@ -1190,6 +1190,7 @@ impl WebRenderFrameBuilder {
|
||||
pub struct WrState {
|
||||
pipeline_id: WrPipelineId,
|
||||
frame_builder: WebRenderFrameBuilder,
|
||||
current_tag: Option<ItemTag>,
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
@ -1203,6 +1204,7 @@ pub extern "C" fn wr_state_new(pipeline_id: WrPipelineId,
|
||||
frame_builder: WebRenderFrameBuilder::with_capacity(pipeline_id,
|
||||
content_size,
|
||||
capacity),
|
||||
current_tag: None,
|
||||
});
|
||||
|
||||
Box::into_raw(state)
|
||||
@ -1292,6 +1294,7 @@ pub extern "C" fn wr_dp_push_stacking_context(state: &mut WrState,
|
||||
|
||||
let mut prim_info = LayoutPrimitiveInfo::new(bounds);
|
||||
prim_info.is_backface_visible = is_backface_visible;
|
||||
prim_info.tag = state.current_tag;
|
||||
|
||||
state.frame_builder
|
||||
.dl_builder
|
||||
@ -1482,6 +1485,7 @@ pub extern "C" fn wr_dp_push_iframe(state: &mut WrState,
|
||||
|
||||
let mut prim_info = LayoutPrimitiveInfo::new(rect);
|
||||
prim_info.is_backface_visible = is_backface_visible;
|
||||
prim_info.tag = state.current_tag;
|
||||
state.frame_builder.dl_builder.push_iframe(&prim_info, pipeline_id);
|
||||
}
|
||||
|
||||
@ -1495,6 +1499,7 @@ pub extern "C" fn wr_dp_push_rect(state: &mut WrState,
|
||||
|
||||
let mut prim_info = LayoutPrimitiveInfo::with_clip_rect(rect, clip.into());
|
||||
prim_info.is_backface_visible = is_backface_visible;
|
||||
prim_info.tag = state.current_tag;
|
||||
state.frame_builder.dl_builder.push_rect(&prim_info,
|
||||
color);
|
||||
}
|
||||
@ -1521,6 +1526,7 @@ pub extern "C" fn wr_dp_push_image(state: &mut WrState,
|
||||
|
||||
let mut prim_info = LayoutPrimitiveInfo::with_clip_rect(bounds, clip.into());
|
||||
prim_info.is_backface_visible = is_backface_visible;
|
||||
prim_info.tag = state.current_tag;
|
||||
state.frame_builder
|
||||
.dl_builder
|
||||
.push_image(&prim_info,
|
||||
@ -1545,6 +1551,7 @@ pub extern "C" fn wr_dp_push_yuv_planar_image(state: &mut WrState,
|
||||
|
||||
let mut prim_info = LayoutPrimitiveInfo::with_clip_rect(bounds, clip.into());
|
||||
prim_info.is_backface_visible = is_backface_visible;
|
||||
prim_info.tag = state.current_tag;
|
||||
state.frame_builder
|
||||
.dl_builder
|
||||
.push_yuv_image(&prim_info,
|
||||
@ -1567,6 +1574,7 @@ pub extern "C" fn wr_dp_push_yuv_NV12_image(state: &mut WrState,
|
||||
|
||||
let mut prim_info = LayoutPrimitiveInfo::with_clip_rect(bounds, clip.into());
|
||||
prim_info.is_backface_visible = is_backface_visible;
|
||||
prim_info.tag = state.current_tag;
|
||||
state.frame_builder
|
||||
.dl_builder
|
||||
.push_yuv_image(&prim_info,
|
||||
@ -1588,6 +1596,7 @@ pub extern "C" fn wr_dp_push_yuv_interleaved_image(state: &mut WrState,
|
||||
|
||||
let mut prim_info = LayoutPrimitiveInfo::with_clip_rect(bounds, clip.into());
|
||||
prim_info.is_backface_visible = is_backface_visible;
|
||||
prim_info.tag = state.current_tag;
|
||||
state.frame_builder
|
||||
.dl_builder
|
||||
.push_yuv_image(&prim_info,
|
||||
@ -1612,6 +1621,7 @@ pub extern "C" fn wr_dp_push_text(state: &mut WrState,
|
||||
|
||||
let mut prim_info = LayoutPrimitiveInfo::with_clip_rect(bounds, clip.into());
|
||||
prim_info.is_backface_visible = is_backface_visible;
|
||||
prim_info.tag = state.current_tag;
|
||||
state.frame_builder
|
||||
.dl_builder
|
||||
.push_text(&prim_info,
|
||||
@ -1631,6 +1641,7 @@ pub extern "C" fn wr_dp_push_shadow(state: &mut WrState,
|
||||
|
||||
let mut prim_info = LayoutPrimitiveInfo::with_clip_rect(bounds, clip.into());
|
||||
prim_info.is_backface_visible = is_backface_visible;
|
||||
prim_info.tag = state.current_tag;
|
||||
state.frame_builder.dl_builder.push_shadow(&prim_info, shadow.into());
|
||||
}
|
||||
|
||||
@ -1654,6 +1665,7 @@ pub extern "C" fn wr_dp_push_line(state: &mut WrState,
|
||||
|
||||
let mut prim_info = LayoutPrimitiveInfo::with_clip_rect(*bounds, (*clip).into());
|
||||
prim_info.is_backface_visible = is_backface_visible;
|
||||
prim_info.tag = state.current_tag;
|
||||
state.frame_builder
|
||||
.dl_builder
|
||||
.push_line(&prim_info,
|
||||
@ -1686,6 +1698,7 @@ pub extern "C" fn wr_dp_push_border(state: &mut WrState,
|
||||
});
|
||||
let mut prim_info = LayoutPrimitiveInfo::with_clip_rect(rect, clip.into());
|
||||
prim_info.is_backface_visible = is_backface_visible;
|
||||
prim_info.tag = state.current_tag;
|
||||
state.frame_builder
|
||||
.dl_builder
|
||||
.push_border(&prim_info,
|
||||
@ -1716,6 +1729,7 @@ pub extern "C" fn wr_dp_push_border_image(state: &mut WrState,
|
||||
});
|
||||
let mut prim_info = LayoutPrimitiveInfo::with_clip_rect(rect, clip.into());
|
||||
prim_info.is_backface_visible = is_backface_visible;
|
||||
prim_info.tag = state.current_tag;
|
||||
state.frame_builder
|
||||
.dl_builder
|
||||
.push_border(&prim_info,
|
||||
@ -1752,6 +1766,7 @@ pub extern "C" fn wr_dp_push_border_gradient(state: &mut WrState,
|
||||
});
|
||||
let mut prim_info = LayoutPrimitiveInfo::with_clip_rect(rect, clip.into());
|
||||
prim_info.is_backface_visible = is_backface_visible;
|
||||
prim_info.tag = state.current_tag;
|
||||
state.frame_builder
|
||||
.dl_builder
|
||||
.push_border(&prim_info,
|
||||
@ -1789,6 +1804,7 @@ pub extern "C" fn wr_dp_push_border_radial_gradient(state: &mut WrState,
|
||||
});
|
||||
let mut prim_info = LayoutPrimitiveInfo::with_clip_rect(rect, clip.into());
|
||||
prim_info.is_backface_visible = is_backface_visible;
|
||||
prim_info.tag = state.current_tag;
|
||||
state.frame_builder
|
||||
.dl_builder
|
||||
.push_border(&prim_info,
|
||||
@ -1821,6 +1837,7 @@ pub extern "C" fn wr_dp_push_linear_gradient(state: &mut WrState,
|
||||
extend_mode.into());
|
||||
let mut prim_info = LayoutPrimitiveInfo::with_clip_rect(rect, clip.into());
|
||||
prim_info.is_backface_visible = is_backface_visible;
|
||||
prim_info.tag = state.current_tag;
|
||||
state.frame_builder
|
||||
.dl_builder
|
||||
.push_gradient(&prim_info,
|
||||
@ -1854,6 +1871,7 @@ pub extern "C" fn wr_dp_push_radial_gradient(state: &mut WrState,
|
||||
extend_mode.into());
|
||||
let mut prim_info = LayoutPrimitiveInfo::with_clip_rect(rect, clip.into());
|
||||
prim_info.is_backface_visible = is_backface_visible;
|
||||
prim_info.tag = state.current_tag;
|
||||
state.frame_builder
|
||||
.dl_builder
|
||||
.push_radial_gradient(&prim_info,
|
||||
@ -1878,6 +1896,7 @@ pub extern "C" fn wr_dp_push_box_shadow(state: &mut WrState,
|
||||
|
||||
let mut prim_info = LayoutPrimitiveInfo::with_clip_rect(rect, clip.into());
|
||||
prim_info.is_backface_visible = is_backface_visible;
|
||||
prim_info.tag = state.current_tag;
|
||||
state.frame_builder
|
||||
.dl_builder
|
||||
.push_box_shadow(&prim_info,
|
||||
@ -1905,6 +1924,38 @@ pub unsafe extern "C" fn wr_api_finalize_builder(state: &mut WrState,
|
||||
*dl_descriptor = descriptor;
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn wr_set_item_tag(state: &mut WrState,
|
||||
scroll_id: u64,
|
||||
hit_info: u8) {
|
||||
state.current_tag = Some((scroll_id, hit_info));
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn wr_clear_item_tag(state: &mut WrState) {
|
||||
state.current_tag = None;
|
||||
}
|
||||
|
||||
#[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 u8) -> bool {
|
||||
let result = dh.api.hit_test(dh.document_id, None, point, HitTestFlags::empty());
|
||||
for item in &result.items {
|
||||
// For now we should never be getting results back for which the tag is
|
||||
// 0 (== CompositorHitTestInfo::eInvisibleToHitTest). 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;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
pub type VecU8 = Vec<u8>;
|
||||
pub type ArcVecU8 = Arc<VecU8>;
|
||||
|
||||
|
@ -438,6 +438,19 @@ struct WrTransformProperty {
|
||||
|
||||
typedef IdNamespace WrIdNamespace;
|
||||
|
||||
// A 2d Point tagged with a unit.
|
||||
struct TypedPoint2D_f32__WorldPixel {
|
||||
float x;
|
||||
float y;
|
||||
|
||||
bool operator==(const TypedPoint2D_f32__WorldPixel& aOther) const {
|
||||
return x == aOther.x &&
|
||||
y == aOther.y;
|
||||
}
|
||||
};
|
||||
|
||||
typedef TypedPoint2D_f32__WorldPixel WorldPoint;
|
||||
|
||||
// Represents RGBA screen colors with floating point numbers.
|
||||
//
|
||||
// All components must be between 0.0 and 1.0.
|
||||
@ -1022,6 +1035,14 @@ WR_INLINE
|
||||
WrIdNamespace wr_api_get_namespace(DocumentHandle *aDh)
|
||||
WR_FUNC;
|
||||
|
||||
WR_INLINE
|
||||
bool wr_api_hit_test(DocumentHandle *aDh,
|
||||
WorldPoint aPoint,
|
||||
WrPipelineId *aOutPipelineId,
|
||||
uint64_t *aOutScrollId,
|
||||
uint8_t *aOutHitInfo)
|
||||
WR_FUNC;
|
||||
|
||||
WR_INLINE
|
||||
void wr_api_remove_pipeline(DocumentHandle *aDh,
|
||||
WrPipelineId aPipelineId)
|
||||
@ -1069,6 +1090,10 @@ void wr_api_update_resources(DocumentHandle *aDh,
|
||||
ResourceUpdates *aResources)
|
||||
WR_FUNC;
|
||||
|
||||
WR_INLINE
|
||||
void wr_clear_item_tag(WrState *aState)
|
||||
WR_FUNC;
|
||||
|
||||
WR_INLINE
|
||||
void wr_dec_ref_arc(const VecU8 *aArc)
|
||||
WR_FUNC;
|
||||
@ -1541,6 +1566,12 @@ void wr_scroll_layer_with_id(DocumentHandle *aDh,
|
||||
LayoutPoint aNewScrollOrigin)
|
||||
WR_FUNC;
|
||||
|
||||
WR_INLINE
|
||||
void wr_set_item_tag(WrState *aState,
|
||||
uint64_t aScrollId,
|
||||
uint8_t aHitInfo)
|
||||
WR_FUNC;
|
||||
|
||||
WR_INLINE
|
||||
void wr_shutdown_external_log_handler()
|
||||
WR_FUNC;
|
||||
|
Loading…
Reference in New Issue
Block a user