From 47a70ddc0aaf07e3769b67da0f1b445d5ffb7b42 Mon Sep 17 00:00:00 2001 From: Dzmitry Malyshau Date: Wed, 6 Dec 2017 12:42:19 -0500 Subject: [PATCH 1/2] Proper inner rectangle for the clips --- webrender/src/clip.rs | 4 ++-- webrender/src/util.rs | 52 ++++++++++++++++++++++++++++++++++--------- 2 files changed, 44 insertions(+), 12 deletions(-) diff --git a/webrender/src/clip.rs b/webrender/src/clip.rs index ce59bd392c..24a3e7f1b5 100644 --- a/webrender/src/clip.rs +++ b/webrender/src/clip.rs @@ -10,7 +10,7 @@ use freelist::{FreeList, FreeListHandle, WeakFreeListHandle}; use gpu_cache::{GpuCache, GpuCacheHandle, ToGpuBlocks}; use prim_store::{ClipData, ImageMaskData}; use resource_cache::ResourceCache; -use util::{MaxRect, calculate_screen_bounding_rect, extract_inner_rect_safe}; +use util::{MaxRect, calculate_screen_inner_rect, calculate_screen_bounding_rect, extract_inner_rect_safe}; pub type ClipStore = FreeList; pub type ClipSourcesHandle = FreeListHandle; @@ -252,7 +252,7 @@ impl ClipSources { device_pixel_ratio: f32, ) -> (DeviceIntRect, Option) { let screen_inner_rect = - calculate_screen_bounding_rect(transform, &self.local_inner_rect, device_pixel_ratio); + calculate_screen_inner_rect(transform, &self.local_inner_rect, device_pixel_ratio); let screen_outer_rect = self.local_outer_rect.map(|outer_rect| calculate_screen_bounding_rect(transform, &outer_rect, device_pixel_ratio) ); diff --git a/webrender/src/util.rs b/webrender/src/util.rs index e3e9ea73cc..b6252883f5 100644 --- a/webrender/src/util.rs +++ b/webrender/src/util.rs @@ -4,11 +4,11 @@ use api::{BorderRadius, DeviceIntPoint, DeviceIntRect, DeviceIntSize, DevicePoint, DeviceRect}; use api::{DeviceSize, LayerPoint, LayerRect, LayerSize, LayerToWorldTransform, WorldRect}; -use euclid::{Point2D, Rect, Size2D, TypedPoint2D, TypedRect, TypedSize2D, TypedTransform2D}; -use euclid::TypedTransform3D; +use euclid::{Point2D, Rect, ScaleFactor, Size2D, TypedPoint2D, TypedRect, TypedSize2D}; +use euclid::{TypedTransform2D, TypedTransform3D}; use num_traits::Zero; -use std::i32; -use std::f32; +use std::{i32, f32}; +use std::cmp::Ordering; // Matches the definition of SK_ScalarNearlyZero in Skia. const NEARLY_ZERO: f32 = 1.0 / 4096.0; @@ -143,20 +143,52 @@ pub fn calculate_screen_bounding_rect( rect: &LayerRect, device_pixel_ratio: f32 ) -> DeviceIntRect { - let rect = WorldRect::from_points(&[ + let points = [ transform.transform_point2d(&rect.origin), transform.transform_point2d(&rect.top_right()), transform.transform_point2d(&rect.bottom_left()), transform.transform_point2d(&rect.bottom_right()), - ]) * device_pixel_ratio; + ]; + + let scale = ScaleFactor::new(device_pixel_ratio); + let rect: DeviceRect = WorldRect::from_points(&points) * scale; + + let max_rect = DeviceRect::max_rect(); + rect + .round_out() + .intersection(&max_rect) + .unwrap_or(max_rect) + .to_i32() +} + +pub fn calculate_screen_inner_rect( + transform: &LayerToWorldTransform, + rect: &LayerRect, + device_pixel_ratio: f32 +) -> DeviceIntRect { + let points = [ + transform.transform_point2d(&rect.origin), + transform.transform_point2d(&rect.top_right()), + transform.transform_point2d(&rect.bottom_left()), + transform.transform_point2d(&rect.bottom_right()), + ]; + let mut xs = [points[0].x, points[1].x, points[2].x, points[3].x]; + let mut ys = [points[0].y, points[1].y, points[2].y, points[3].y]; + + xs.sort_by(|a, b| a.partial_cmp(b).unwrap_or(Ordering::Equal)); + ys.sort_by(|a, b| a.partial_cmp(b).unwrap_or(Ordering::Equal)); let rect = DeviceRect::new( - DevicePoint::new(rect.origin.x, rect.origin.y), - DeviceSize::new(rect.size.width, rect.size.height), - ); + DevicePoint::new(xs[1], ys[1]), + DeviceSize::new(xs[2] - xs[1], ys[2] - ys[1]), + ) * device_pixel_ratio; let max_rect = DeviceRect::max_rect(); - rect.round_out().intersection(&max_rect).unwrap_or(max_rect).to_i32() + rect + .intersection(&max_rect) + .unwrap_or(max_rect) + .round_in() + .to_i32() } pub fn _subtract_rect( From 6b4ddfb2fb92c1f51ecbd7cee53f695d4992be8f Mon Sep 17 00:00:00 2001 From: Martin Robinson Date: Wed, 6 Dec 2017 13:50:51 -0500 Subject: [PATCH 2/2] Add a test for non-axis-aligned clipping --- .../clip/clip-45-degree-rotation-ref.png | Bin 0 -> 2871 bytes .../clip/clip-45-degree-rotation.yaml | 35 ++++++++++++++++++ wrench/reftests/clip/reftest.list | 2 +- 3 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 wrench/reftests/clip/clip-45-degree-rotation-ref.png create mode 100644 wrench/reftests/clip/clip-45-degree-rotation.yaml diff --git a/wrench/reftests/clip/clip-45-degree-rotation-ref.png b/wrench/reftests/clip/clip-45-degree-rotation-ref.png new file mode 100644 index 0000000000000000000000000000000000000000..5a5e9ac10b9bd525d53087572f72b15aefbe51e2 GIT binary patch literal 2871 zcmc&$3rtg27(Tb{=;hf9KB6LU9U8L->Y^E8-r<3Pg&@c_*u%w0bWRpCCPT+HLbynU zI;W73;RCE>F(FXJ7%>{O8>>8Aa8O6GiNRspNT*C~7ay2S*niHwEud`KmL&^mIp6>P z-{U{I$?fjU41I9GoB)JSaB51@8wfE+;B$=igNiDsX+Qk)Tc4&+LSy8w-qKJF75^rORpZar$7%}g?*iUA(ZESrJKR%it#C}?r6xw_E{KMkI@33{RaVsMI zdpcU1H#6(D7oIoYUw{0LHw{?p6fc7$0RBps>zv7X)o$t4~^nXBa7}l zQ!ygR^2D1b`;<`(F^C1lJT~fREM8zahnijo;D`*BVT2dTQ|^9Ms7iz-S~D=MkQXS0c)Ss3>Wj^dh6(lqjgRO!vkW*$@ z)qr`DyV8v&Q3)ow!7N$;sY-u?R+A#N>qW$bMZuZ%ghpZ+Cl(pB98WP9WoI-gUOe%P zrSUqJCd>`(k-cdaR!6*O7OUFl?MAHa=(t~4eZEr;MH**)4NdNVH!)Hz%k!o{%$!)b zcDlKQ_J(^SVyScQxRtXLR_hG04Z*(1sm*;8WTiM&%R!KA6PT+>AeYmOPItlBP+;a} z0(;Qu4g!NS(+IqSIv^KPO((K!<}xtl@nzskDEa?sxB_g?3h1c1h1H>(D8{PBui!my zR23qZ?>QU~wsMhZw6V`T*tD;!wfKHt^;lQ(@zaOGq>^EmbM)IIhhm1**Pk2h)^BmB zv4H>KS6lzJF?ZuFyS;mGak{E4&hlu>+PmvYj~F5CfV^J{H%IyanYAuM)UUd^r@{54<4Ml3Ewk|{Sc2AoaLMPpn%2Za!cpN;nkTEvJ(N$6bJK?+eo(S73c`v zWRr>V=%Pzk!`56Ry@!Jf!Je(8J71ax3I;uG+Q%EbFtIU2@>!#0)}>^{m$I-(tY{8{ ze!^Mni(yajI@4JVYnZynjR)~0NLVDeXNIYE2Nk#4`?vRgCdXhoRwr+)Q)#Sa@{;iO zaPyGxNep}Pm>0<9zy`tsd}2ia2SqN#cH;}+7^l`yI7Cyi0}V17?Zqm?Q#}#|qQM(U z@XnF5V!>nDqcP{p=Xrt>c|wonUS$wg6&C3sR~eBgNumm=$a9?rufMVjr}&fqGz5o)4#`uRjk^VKvc z3Dv}>eXehx`cn)|OBra|~gX`X%kWJSf`@a+>T-pVFRCk5Vf p