Bug 1372321 - When pushing a clip item, ensure the clip rect and mask rect are relative to the content rect. r=mrobinson draft
authorKartikaya Gupta <kgupta@mozilla.com>
Tue, 13 Jun 2017 08:42:37 -0400
changeset 593331 3f1dbd33553bd1053f9feaf8db7a8fd9ac3f4896
parent 592668 2a63a6c35033b5cbc6c98cabc7657c7290284691
child 593332 e1311d451cb73365f7a21198231f9505a6695407
push id63654
push userkgupta@mozilla.com
push dateTue, 13 Jun 2017 12:43:18 +0000
reviewersmrobinson
bugs1372321
milestone56.0a1
Bug 1372321 - When pushing a clip item, ensure the clip rect and mask rect are relative to the content rect. r=mrobinson MozReview-Commit-ID: BGnsq9qoinV
gfx/webrender_bindings/src/bindings.rs
gfx/webrender_bindings/webrender_ffi_generated.h
--- a/gfx/webrender_bindings/src/bindings.rs
+++ b/gfx/webrender_bindings/src/bindings.rs
@@ -1320,24 +1320,34 @@ pub extern "C" fn wr_dp_push_stacking_co
 #[no_mangle]
 pub extern "C" fn wr_dp_pop_stacking_context(state: &mut WrState) {
     assert!(unsafe { !is_in_render_thread() });
     state.frame_builder.dl_builder.pop_stacking_context();
 }
 
 #[no_mangle]
 pub extern "C" fn wr_dp_push_clip(state: &mut WrState,
-                                  clip_rect: WrRect,
+                                  rect: WrRect,
                                   mask: *const WrImageMask)
                                   -> u64 {
     assert!(unsafe { is_in_main_thread() });
-    let clip_rect = clip_rect.into();
-    let mask = unsafe { mask.as_ref() }.map(|x| x.into());
+    let content_rect: LayoutRect = rect.into();
+
+    // Both the clip rect and mask rect need to be relative to the
+    // content rect when the clip region is being used as part of a clip item.
+    // Since the clip_rect is the same as the content_rect we can just set the
+    // origin to zero.
+    let clip_rect = LayoutRect::new(LayoutPoint::zero(), content_rect.size);
+    let mut mask : Option<ImageMask> = unsafe { mask.as_ref() }.map(|x| x.into());
+    if let Some(ref mut m) = mask {
+        m.rect.origin = m.rect.origin - content_rect.origin;
+    }
+
     let clip_region = state.frame_builder.dl_builder.push_clip_region(&clip_rect, vec![], mask);
-    let clip_id = state.frame_builder.dl_builder.define_clip(clip_rect, clip_region, None);
+    let clip_id = state.frame_builder.dl_builder.define_clip(content_rect, clip_region, None);
     state.frame_builder.dl_builder.push_clip_id(clip_id);
     // return the u64 id value from inside the ClipId::Clip(..)
     match clip_id {
         ClipId::Clip(id, pipeline_id) => {
             assert!(pipeline_id == state.pipeline_id);
             id
         },
         _ => panic!("Got unexpected clip id type"),
@@ -1355,18 +1365,24 @@ pub extern "C" fn wr_dp_push_scroll_laye
                                           scroll_id: u64,
                                           content_rect: WrRect,
                                           clip_rect: WrRect) {
     assert!(unsafe { is_in_main_thread() });
     let clip_id = ClipId::new(scroll_id, state.pipeline_id);
     // Avoid defining multiple scroll clips with the same clip id, as that
     // results in undefined behaviour or assertion failures.
     if !state.frame_builder.scroll_clips_defined.contains(&clip_id) {
-        let content_rect = content_rect.into();
-        let clip_rect = clip_rect.into();
+        let content_rect: LayoutRect = content_rect.into();
+
+        // Both the clip rect and mask rect need to be relative to the
+        // content_rect when the clip region is being used as part of a clip
+        // item. In this case there is no mask rect so that's a no-op.
+        let mut clip_rect: LayoutRect = clip_rect.into();
+        clip_rect.origin = clip_rect.origin - content_rect.origin;
+
         let clip_region = state.frame_builder.dl_builder.push_clip_region(&clip_rect, vec![], None);
         state.frame_builder.dl_builder.define_clip(content_rect, clip_region, Some(clip_id));
         state.frame_builder.scroll_clips_defined.insert(clip_id);
     }
     state.frame_builder.dl_builder.push_clip_id(clip_id);
 }
 
 #[no_mangle]
--- a/gfx/webrender_bindings/webrender_ffi_generated.h
+++ b/gfx/webrender_bindings/webrender_ffi_generated.h
@@ -732,17 +732,17 @@ WR_FUNC;
 WR_INLINE
 void wr_dp_push_built_display_list(WrState *aState,
                                    WrBuiltDisplayListDescriptor aDlDescriptor,
                                    WrVecU8 aDlData)
 WR_FUNC;
 
 WR_INLINE
 uint64_t wr_dp_push_clip(WrState *aState,
-                         WrRect aClipRect,
+                         WrRect aRect,
                          const WrImageMask *aMask)
 WR_FUNC;
 
 WR_INLINE
 void wr_dp_push_clip_and_scroll_info(WrState *aState,
                                      uint64_t aScrollId,
                                      const uint64_t *aClipId)
 WR_FUNC;