Bug 1345017 - Update WebRenderAPIs to enable OMTA, r?kats draft
authorpeter chang <pchang@mozilla.com>
Wed, 29 Mar 2017 17:23:08 +0800
changeset 564065 cf5a0ee96189d6646637f4a93c81c30367b47995
parent 563689 43856e04b4c140cc789a0f31edf253f985b0daf8
child 564066 85d1de0c7e17cafde693932c8e64c14556a69c25
push id54512
push userbmo:howareyou322@gmail.com
push dateTue, 18 Apr 2017 08:40:13 +0000
reviewerskats
bugs1345017
milestone55.0a1
Bug 1345017 - Update WebRenderAPIs to enable OMTA, r?kats MozReview-Commit-ID: L8HSxvzoEJZ
gfx/webrender_bindings/WebRenderAPI.cpp
gfx/webrender_bindings/WebRenderAPI.h
gfx/webrender_bindings/src/bindings.rs
gfx/webrender_bindings/webrender_ffi_generated.h
--- 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,