Bug 1345017 - Update WebRenderAPIs to enable OMTA, r?kats
MozReview-Commit-ID: L8HSxvzoEJZ
--- a/gfx/webrender_bindings/WebRenderAPI.cpp
+++ b/gfx/webrender_bindings/WebRenderAPI.cpp
@@ -174,16 +174,29 @@ WebRenderAPI::~WebRenderAPI()
void
WebRenderAPI::GenerateFrame()
{
wr_api_generate_frame(mWrApi);
}
void
+WebRenderAPI::GenerateFrame(const nsTArray<WrOpacityProperty>& aOpacityArray,
+ const nsTArray<WrTransformProperty>& aTransformArray)
+{
+ wr_api_generate_frame_with_properties(mWrApi,
+ aOpacityArray.IsEmpty() ?
+ nullptr : aOpacityArray.Elements(),
+ aOpacityArray.Length(),
+ aTransformArray.IsEmpty() ?
+ nullptr : aTransformArray.Elements(),
+ aTransformArray.Length());
+}
+
+void
WebRenderAPI::SetRootDisplayList(gfx::Color aBgColor,
Epoch aEpoch,
LayerSize aViewportSize,
WrPipelineId pipeline_id,
WrBuiltDisplayListDescriptor dl_descriptor,
uint8_t *dl_data,
size_t dl_size,
WrAuxiliaryListsDescriptor aux_descriptor,
@@ -521,22 +534,38 @@ DisplayListBuilder::Finalize()
&dl.dl.inner,
&dl.aux_desc,
&dl.aux.inner);
return dl;
}
void
DisplayListBuilder::PushStackingContext(const WrRect& aBounds,
+ const uint64_t& aAnimationId,
+ const float* aOpacity,
+ const gfx::Matrix4x4* aTransform,
+ const WrMixBlendMode& aMixBlendMode)
+{
+ WrMatrix matrix;
+ if (aTransform) {
+ matrix = ToWrMatrix(*aTransform);
+ }
+ const WrMatrix* maybeTransform = aTransform ? &matrix : nullptr;
+ wr_dp_push_stacking_context(mWrState, aBounds, aAnimationId, aOpacity,
+ maybeTransform, aMixBlendMode);
+}
+
+void
+DisplayListBuilder::PushStackingContext(const WrRect& aBounds,
const float aOpacity,
const gfx::Matrix4x4& aTransform,
const WrMixBlendMode& aMixBlendMode)
{
- wr_dp_push_stacking_context(mWrState, aBounds, aOpacity,
- ToWrMatrix(aTransform), aMixBlendMode);
+ PushStackingContext(aBounds, 0, &aOpacity,
+ &aTransform, aMixBlendMode);
}
void
DisplayListBuilder::PopStackingContext()
{
wr_dp_pop_stacking_context(mWrState);
}
--- a/gfx/webrender_bindings/WebRenderAPI.h
+++ b/gfx/webrender_bindings/WebRenderAPI.h
@@ -40,16 +40,18 @@ public:
static already_AddRefed<WebRenderAPI> Create(bool aEnableProfiler,
layers::CompositorBridgeParentBase* aBridge,
RefPtr<widget::CompositorWidget>&& aWidget,
LayoutDeviceIntSize aSize);
wr::WindowId GetId() const { return mId; }
void GenerateFrame();
+ void GenerateFrame(const nsTArray<WrOpacityProperty>& aOpacityArray,
+ const nsTArray<WrTransformProperty>& aTransformArray);
void SetWindowParameters(LayoutDeviceIntSize size);
void SetRootDisplayList(gfx::Color aBgColor,
Epoch aEpoch,
LayerSize aViewportSize,
WrPipelineId pipeline_id,
WrBuiltDisplayListDescriptor dl_descriptor,
uint8_t *dl_data,
@@ -137,16 +139,21 @@ public:
void End();
wr::BuiltDisplayList Finalize();
void PushStackingContext(const WrRect& aBounds, // TODO: We should work with strongly typed rects
const float aOpacity,
const gfx::Matrix4x4& aTransform,
const WrMixBlendMode& aMixBlendMode);
+ void PushStackingContext(const WrRect& aBounds, // TODO: We should work with strongly typed rects
+ const uint64_t& aAnimationId,
+ const float* aOpacity,
+ const gfx::Matrix4x4* aTransform,
+ const WrMixBlendMode& aMixBlendMode);
void PopStackingContext();
void PushBuiltDisplayList(wr::BuiltDisplayList dl);
void PushScrollLayer(const WrRect& aBounds, // TODO: We should work with strongly typed rects
const WrRect& aOverflow,
const WrImageMask* aMask); // TODO: needs a wrapper.
--- a/gfx/webrender_bindings/src/bindings.rs
+++ b/gfx/webrender_bindings/src/bindings.rs
@@ -607,16 +607,30 @@ impl WrVecU8 {
}
}
#[no_mangle]
pub extern "C" fn wr_vec_u8_free(v: WrVecU8) {
v.to_vec();
}
+#[repr(C)]
+#[derive(Debug)]
+pub struct WrTransformProperty {
+ pub id: u64,
+ pub transform: WrMatrix,
+}
+
+#[repr(C)]
+#[derive(Copy, Clone, Debug)]
+pub struct WrOpacityProperty {
+ pub id: u64,
+ pub opacity: f32,
+}
+
fn get_proc_address(glcontext_ptr: *mut c_void, name: &str) -> *const c_void {
extern "C" {
fn get_proc_address_from_glcontext(glcontext_ptr: *mut c_void,
procname: *const c_char)
-> *const c_void;
}
@@ -980,16 +994,55 @@ pub unsafe extern "C" fn wr_api_clear_ro
preserve_frame_state);
}
#[no_mangle]
pub extern "C" fn wr_api_generate_frame(api: &mut WrAPI) {
api.generate_frame(None);
}
+#[no_mangle]
+pub extern "C" fn wr_api_generate_frame_with_properties(api: &mut WrAPI,
+ opacity_array: *const WrOpacityProperty,
+ opacity_count: usize,
+ transform_array: *const WrTransformProperty,
+ transform_count: usize) {
+ let mut properties = DynamicProperties {
+ transforms: Vec::new(),
+ floats: Vec::new()
+ };
+
+ if transform_count > 0 {
+ let transform_slice = unsafe { slice::from_raw_parts(transform_array, transform_count) };
+
+ for element in transform_slice.iter() {
+ let prop = PropertyValue {
+ key: PropertyBindingKey::new(element.id),
+ value: element.transform.to_transform(),
+ };
+
+ properties.transforms.push(prop);
+ }
+ }
+
+ if opacity_count > 0 {
+ let opacity_slice = unsafe { slice::from_raw_parts(opacity_array, opacity_count) };
+
+ for element in opacity_slice.iter() {
+ let prop = PropertyValue {
+ key: PropertyBindingKey::new(element.id),
+ value: element.opacity,
+ };
+ properties.floats.push(prop);
+ }
+ }
+
+ api.generate_frame(Some(properties));
+}
+
/// cbindgen:function-postfix=WR_DESTRUCTOR_SAFE_FUNC
#[no_mangle]
pub extern "C" fn wr_api_send_external_event(api: &mut WrAPI, evt: usize) {
assert!(unsafe { !is_in_render_thread() });
api.send_external_event(ExternalEvent::from_raw(evt));
}
@@ -1122,35 +1175,48 @@ pub extern "C" fn wr_dp_new_clip_region(
let clip_region = state.frame_builder.dl_builder.new_clip_region(&main, complex, mask);
clip_region.into()
}
#[no_mangle]
pub extern "C" fn wr_dp_push_stacking_context(state: &mut WrState,
bounds: WrRect,
- opacity: f32,
- transform: WrMatrix,
+ animation_id: u64,
+ opacity: *const f32,
+ transform: *const WrMatrix,
mix_blend_mode: WrMixBlendMode) {
assert!(unsafe { is_in_main_thread() });
state.z_index += 1;
let bounds = bounds.to_rect();
let mut filters: Vec<FilterOp> = Vec::new();
- if opacity < 1.0 {
- filters.push(FilterOp::Opacity(PropertyBinding::Value(opacity)));
+ let opacity = unsafe { opacity.as_ref() };
+ if let Some(opacity) = opacity {
+ if *opacity < 1.0 {
+ filters.push(FilterOp::Opacity(PropertyBinding::Value(*opacity)));
+ }
+ } else {
+ filters.push(FilterOp::Opacity(
+ PropertyBinding::Binding(PropertyBindingKey::new(animation_id))));
}
+ let transform = unsafe { transform.as_ref() };
+ let transform_binding = match transform {
+ Some(transform) => PropertyBinding::Value(transform.to_transform()),
+ None => PropertyBinding::Binding(PropertyBindingKey::new(animation_id)),
+ };
+
state.frame_builder
.dl_builder
.push_stacking_context(webrender_traits::ScrollPolicy::Scrollable,
bounds,
state.z_index,
- Some(PropertyBinding::Value(transform.to_transform())),
+ Some(transform_binding),
TransformStyle::Flat,
None,
mix_blend_mode,
filters);
}
#[no_mangle]
pub extern "C" fn wr_dp_pop_stacking_context(state: &mut WrState) {
--- a/gfx/webrender_bindings/webrender_ffi_generated.h
+++ b/gfx/webrender_bindings/webrender_ffi_generated.h
@@ -196,16 +196,44 @@ struct WrAuxiliaryListsDescriptor {
bool operator==(const WrAuxiliaryListsDescriptor& aOther) const {
return gradient_stops_size == aOther.gradient_stops_size &&
complex_clip_regions_size == aOther.complex_clip_regions_size &&
filters_size == aOther.filters_size &&
glyph_instances_size == aOther.glyph_instances_size;
}
};
+struct WrOpacityProperty {
+ uint64_t id;
+ float opacity;
+
+ bool operator==(const WrOpacityProperty& aOther) const {
+ return id == aOther.id &&
+ opacity == aOther.opacity;
+ }
+};
+
+struct WrMatrix {
+ float values[16];
+
+ bool operator==(const WrMatrix& aOther) const {
+ return values == aOther.values;
+ }
+};
+
+struct WrTransformProperty {
+ uint64_t id;
+ WrMatrix transform;
+
+ bool operator==(const WrTransformProperty& aOther) const {
+ return id == aOther.id &&
+ transform == aOther.transform;
+ }
+};
+
struct WrIdNamespace {
uint32_t mHandle;
bool operator==(const WrIdNamespace& aOther) const {
return mHandle == aOther.mHandle;
}
bool operator<(const WrIdNamespace& aOther) const {
@@ -394,24 +422,16 @@ struct WrNinePatchDescriptor {
bool operator==(const WrNinePatchDescriptor& aOther) const {
return width == aOther.width &&
height == aOther.height &&
slice == aOther.slice;
}
};
-struct WrMatrix {
- float values[16];
-
- bool operator==(const WrMatrix& aOther) const {
- return values == aOther.values;
- }
-};
-
struct WrGlyphInstance {
uint32_t index;
WrPoint point;
bool operator==(const WrGlyphInstance& aOther) const {
return index == aOther.index &&
point == aOther.point;
}
@@ -553,16 +573,24 @@ wr_api_finalize_builder(WrState* state,
WrAuxiliaryListsDescriptor* aux_descriptor,
WrVecU8* aux_data)
WR_FUNC;
WR_INLINE void
wr_api_generate_frame(WrAPI* api)
WR_FUNC;
+WR_INLINE void
+wr_api_generate_frame_with_properties(WrAPI* api,
+ const WrOpacityProperty* opacity_array,
+ size_t opacity_count,
+ const WrTransformProperty* transform_array,
+ size_t transform_count)
+WR_FUNC;
+
WR_INLINE WrIdNamespace
wr_api_get_namespace(WrAPI* api)
WR_FUNC;
WR_INLINE void
wr_api_send_external_event(WrAPI* api,
size_t evt)
WR_DESTRUCTOR_SAFE_FUNC;
@@ -751,18 +779,19 @@ wr_dp_push_scroll_layer(WrState* state,
WrRect bounds,
WrRect overflow,
const WrImageMask* mask)
WR_FUNC;
WR_INLINE void
wr_dp_push_stacking_context(WrState* state,
WrRect bounds,
- float opacity,
- WrMatrix transform,
+ uint64_t animation_id,
+ const float* opacity,
+ const WrMatrix* transform,
WrMixBlendMode mix_blend_mode)
WR_FUNC;
WR_INLINE void
wr_dp_push_text(WrState* state,
WrRect bounds,
WrClipRegion clip,
WrColor color,