Bug 1559861: WR - Scale picture tasks based on their surface to parent transform scale factors r=gw,Bert
authorcbrewster <connorbrewster@yahoo.com>
Wed, 20 May 2020 17:19:06 +0000
changeset 531301 a94271c84318acba14a63c52ba98afe512b071f7
parent 531300 6e5ab322dc4d0a68833dbd73e55a4657d0c219c2
child 531302 c271cdf24dd59ba81b6c5948f796132fcd906e0c
push id37437
push usernerli@mozilla.com
push dateThu, 21 May 2020 02:34:41 +0000
treeherdermozilla-central@3d91ba9e1d25 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgw, Bert
bugs1559861
milestone78.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1559861: WR - Scale picture tasks based on their surface to parent transform scale factors r=gw,Bert This patch adjusts the device pixel scale for raster root surfaces so that the surface's content is not pixelated/blurred when it is composited into its parent surface where a transform scales up the surface. This only fixes the referenced bug when WebRender is used. Differential Revision: https://phabricator.services.mozilla.com/D75236
gfx/wr/webrender/src/picture.rs
gfx/wr/wrench/reftests/filters/svg-filter-blur-transforms.png
gfx/wr/wrench/reftests/transforms/raster-root-scaling-ref.yaml
gfx/wr/wrench/reftests/transforms/raster-root-scaling.yaml
gfx/wr/wrench/reftests/transforms/reftest.list
--- a/gfx/wr/webrender/src/picture.rs
+++ b/gfx/wr/webrender/src/picture.rs
@@ -5936,26 +5936,36 @@ impl PicturePrimitive {
 
             // Filters must be applied before transforms, to do this, we can mark this picture as establishing a raster root.
             let has_svg_filter = if let PictureCompositeMode::SvgFilter(..) = composite_mode {
                 true
             } else {
                 false
             };
 
+            let surface_to_parent_transform = frame_context.spatial_tree
+                .get_relative_transform(surface_spatial_node_index, parent_raster_node_index);
+
             // Check if there is perspective or if an SVG filter is applied, and thus whether a new
             // rasterization root should be established.
-            let establishes_raster_root = has_svg_filter || frame_context.spatial_tree
-                .get_relative_transform(surface_spatial_node_index, parent_raster_node_index)
-                .is_perspective();
-
-            let raster_spatial_node_index = if establishes_raster_root {
-                surface_spatial_node_index
+            let establishes_raster_root = has_svg_filter || surface_to_parent_transform.is_perspective();
+
+            let (raster_spatial_node_index, device_pixel_scale) = if establishes_raster_root {
+                // If a raster root is established, this surface should be scaled based on the scale factors of the surface raster to parent raster transform.
+                // This scaling helps ensure that the content in this surface does not become blurry or pixelated when composited in the parent surface.
+                let scale_factors = surface_to_parent_transform.scale_factors();
+
+                // Pick the largest scale factor of the transform for the scaling factor.
+                // Currently, we ensure that the scaling factor is >= 1.0 as a smaller scale factor can result in blurry output.
+                let scaling_factor = scale_factors.0.max(scale_factors.1).max(1.0);
+
+                let device_pixel_scale = frame_context.global_device_pixel_scale * Scale::new(scaling_factor);
+                (surface_spatial_node_index, device_pixel_scale)
             } else {
-                parent_raster_node_index
+                (parent_raster_node_index, frame_context.global_device_pixel_scale)
             };
 
             let scale_factors = frame_context
                     .spatial_tree
                     .get_relative_transform(surface_spatial_node_index, raster_spatial_node_index)
                     .scale_factors();
 
             // This inflation factor is to be applied to all primitives within the surface.
@@ -5997,17 +6007,17 @@ impl PicturePrimitive {
             }
 
             let surface = SurfaceInfo::new(
                 surface_spatial_node_index,
                 raster_spatial_node_index,
                 inflation_factor,
                 frame_context.global_screen_world_rect,
                 &frame_context.spatial_tree,
-                frame_context.global_device_pixel_scale,
+                device_pixel_scale,
                 scale_factors,
             );
 
             self.raster_config = Some(RasterConfig {
                 composite_mode,
                 establishes_raster_root,
                 surface_index: state.push_surface(surface),
                 root_scaling_factor: 1.0,
index 65a448e773b65b78a9ebcb24ec4161d4c84bb126..7bd8b5c4b67df98dc744353e8ca85d979fe61fbe
GIT binary patch
literal 6159
zc%0Q(d05ifyDw8iv|Mt@+z>+%Xi>|w+yzB)mk8X7f*jMCMoU98GZRxVQ4&*Aa~r|<
zW(?K1wW1bcwwdP4WKNWoT1{zY+TuOb{mpdmpZC8D56^R+_k7;<yyrddOMYmu{}T8L
z_<{usmIM&-;R_Zl#HoHTO+ZOISeUY4fyrP1-kZ#-d{vo$?kV~Aqa&MMNRCL?sBLv#
zxavWjm-FIJ9RxjiLrrLL%zKNlqJ#Rgm(yG>-zs++-v9bu)vbVP;rNEX5AZLKz1}xT
z<_F&%oVP&X@f*G9`NR!qoc@?58-*OMk>DH53`_I&9g!In{}f6^-dh6SjBoe;{|9nE
z-tqU~;N3%wJek3mAoW4j;q!*2#62(1_XbBt!Z$bA4aEcmVVhFjtO0qAL~Kwqxa0JJ
zA8srIatka{@9Km`5NWlqYb`<+uu+b?hTMBLjFeO$Y}CFI_ZP|xOtCL3@-T~Fc?$$y
z6cJ#xsF&ccYj&*k4xgV5Y06@a|7WAB4s57**v!sNAhCS&jpXbMM=w;7(YWOwNk`GR
z;$N>e%kLUW=Vq>Op|ac`!pUTxQwuSNq0pH-g`0eVJquHP)!CxUpQL23;1s>3f;(|p
zBn0-p`}rq@z}1tvF-7&K&tB$yP;!yDM(fgu;QSA__H$|+1BC{2I-yz&cKgxPhg$H>
zjN_7zN$c1R9-q&{xcxqi9LSM05oK5^Z}bY3k5ApU@t8v^&)rt6TbWa%vf}nd9a-(a
zBHWSz)YdDoQZ1Q0efAI`<5N;wF5645fB%&zeqEhGy1L-;+wW}mF91<m!RWR}_-~p2
z6xU=PZ*7s2Ba-qBjRbe5hW@AQa3H$~fo+aB_{O_yWIh(-9|?Q%<}p&Fv!m`SgN;b%
zPzdUsX^nv#o}&ATl>;JYy?ui(CHkyVH2$i^=F3|iat;1)iQZt7u+-y7nP??}fO-eR
zbS8^(JQk7FXmpyVN=rN41Tc{g{e3C#!8RUiX4uisAa8M)HO_}u<9Ji}A7#DuU#-K5
zZT#u^(6ZDus~c^E`yb`AW=Hc{9&tWAJznp`%dT<E<B(qHlQkW}0yy7Rv!PlCHAU*8
z@?dZ{6WKA^G;6z+(=u)SvzI8VrB1rDh{iw_G%fHuCao|PQ{dwCd#ZD?kVGZTY?P)y
zIhGf9>KJS6mt^fl!lT5+))xZ8!nE9ZeF$63*A-HMKw@fde@g^$ZVa53v}Ztk*3WI0
z;o7d;aX^7#o=3a#NH1nj{u9Rr9iKXWyIp}QwIG93J4ScB)dTUD$rE{T)%GK><n+8y
zJ-q<aRis<>sw1VllD{5qPKkG5pfJvI=iJgTpes8@i+1n>y^FiX&+QAVD<VX&N4?F#
zkk*jl_^LJdzgg4B*+t7EwA{my1zP<g7<XTu%z&ox(ofDwARqb|)m6{)b9;-Q-Bo1f
ztFN)cd!zlSz)j7^r$jl`ql_Xw!5i~}rkv_KPNysnr(m$a!^P|v7%l0++|+G<w@IRF
zd-_!06DIp-5%FksMf{DFWJ|%FbCo*CI)iGigTR4j_bzaPN&&TDsal7w@PK^0?K#pi
z(?$8~4Mkt=!|q%9OQghj24Um7``@WG6fkb@4Bm8x%;-)SGiRfu+lErYDbdtJZ>}X{
z@}Lh|OB>u^bxl}gt#H>LNmZ5psCPKK&b_1ilAo0ms5hU;Ir~6$_+9s<vwZyX3>UIw
zA(XsBxE6=|Ql&hXvkvCdgx&Ey?~$5YE;h=S=eUxx>%{}=3=NO~XC=K2P<7@;<(H3K
zsP)+4`4P@65#y9|UL+rf&LMBPZ%|h5RlL*cfrEsO-M&A7meeadI74uI7n*^^zTO?@
zk?mth#B{F1WFwF2T5T)Vc3<CLIPvr%WFC}6PI;83Kk_lQYfO0Jd1Vm<-hh|JsYZ-$
ziwS#db5zppEtWKEOg2vRodA7Zl>ieB+QIpc`X;f<lfKN3mJ~fNFZ;@^nR+~uGV|y_
zAmx+#(Nhl*=mtFMcN?A#ICBo7p&f}x-`!}jEO;I!^$9-_ZIJY~8!(RshN{jcShIt;
zN<8wpIht{n$wt7keMn@!J72N(7>5e;IgRzH6Yd&!s6&3OI!CPV(dqGRsof(}8OsPj
zvwDZWf@9^dmoa_Rv&712>cF)UBYurR`d0&*R0ia#46se#oeN|{lb?&mPm7Vwt#y?K
zj;EfNuLZF-eYxTS<RU%I?B<n&n@9@<`C7++SxnB2C#w_mf@31W@9RjF#BpgavboK6
z$AL}CY;A>Gsb><1J#uK3aSvxis}b6sF!2Gg1XJt(kNGvQ?9*6eop7?xYGgrdW?I+u
z1OMm)KXwsJ1Y@}UnxK9er{<RoY@2UC2W3SrPWxYq$uSAEm^5bBu?>C?fA)1nF*Y9Z
zTn1jNB^{lPw6`PIaeSlD2?Ppg#QdX?sNg8#5f4Pawb*1%9ybWqYCCv%H1WsoXmEM7
zI%GdF1P$o%NIRy_i(&%-gV*2~SdYZqQ;a|N<bC-4wxT8b;pM9%dw%S$1o*2zNx*qp
zZM7Fu^jw=0s!HJB`6h80ezLBJJ8|U`Q%jg5=iK=9W_hgyKctarBW^Gv6i!4gwg>e|
zTKml(bDA}FH8hg3x95Fo+YDzmD$2p%u=J*x^ZX?_CZ1jVq<zqvME2qB6RkYJAhgP>
zrR~#$c~L**x6X|x|82x$nmQ5aJsI@=5gx>+m;-YxzzM&TA0@rek}4|(QXUx5hEt<l
zQBNOXpG~zm`O$ma=;u8102rYHKLuc79;sDc2({jThYe>Q&^H0sk$a`w6~6h|;**~+
z48eJ1Pg2YT!VUy9QqJl3Vz5Q8FP?iB7(to$rT1LizIWR%Kpa{n4o^VIIW}Ue&uC@g
zCJxl<K&Dk?$@sHZ8!s=Vq0Uf~qaSP}a{n}O8TAd#8{crn-d!z%Vpk(!SW3#zMo<E<
zW#$joAAwvrO8Izm2eQ!I-m@c&vN??EcyOreXwjB?9NQZyK{W7IL$5D)$T{&hpEx9|
z!8bQ9IXP1#B}G1dTBf+WYzK)pyf>sPXoDbLu^WUl(8T#w5C~^?rwg+iWPv#I<Dbc(
zy4OfI+5=v#lhd|L!F@FnEs4Q~CgmjBs}*ci|B;|{9VtmqU#i%%sMyG#qS$>KjVm`!
zytR{Wgb>fEU}gYzI4BKLMY`B#blsa9o)pSQJiTY#b|=eoUqxBK*r?B)wh*-Iu#A71
zKDC8%&YK=^MKXpF(`qFRAw!9RftR7wdsc~3#qLrxZcN*GD|0>QJ>D%kd0JYr9=>@l
ztB*|Uvt*;591SAVdcq7#3(TBDn5cPh@GN>inG#+rVN^<J7;Jnf)zM>Ur9go5qW83J
z-%F-Q)dAb#pfFm`QZ&wVabm856r3&N_jTHeAchGV_d6~zQ$b422c&C_LWrRYNIHqB
z3ex*L8UHc;cmzeNYgnqIee$G~f3Qx%a2dK^A}|M?U+2|bjnLC9G>+z(xI;mrfJ2^^
zJ^KY>5CF+4F%pn~gz2lh0I3_0+!MnUq(OihkUeXF7(sw!kw^k0fEu{E3y}KII9HcM
z9|cJh7=La1R2aok55D=m?#V(ae_<F^>N%8HBG4(2@h^4S)<cX%z*4is)e4exj*LIt
z*;ofLjsTKHqAef+)bUPRKvD-JQ)gW!%Ep`ClRUJpL{I?EgG)abN^x{FEUko{%#rf-
z>m*NEL*`)5kd3;rJp%0QFf273(g76k&M8Qsr|z@x$Yi3bY9!BetS(9UpsU!+=Ecwg
z;?R(*%)c3G@HHHK_}3E(<(@q}A^1%g7CW|_z24+QnLq$uy^2K{T?&$ImaJl9#znBm
zmQ^@roCk{>Sp_Bo0*hQ(1u~-nEb?R(D>5p<f+MRi$S47e0$Bw-qW~;`9JP!b1!-57
zY}~@bgNbtTrcdiwRZ01#wUTr;FNoH2GnDEs^KXP0xoGIoUr)j*juD2GkT+rW*m4KB
z7?@KcxM|KFSd@WRknr?lmL8T&)Z{97!p%2#(b(eoTFG^|6<2EDx|F@%?*p+!AlE`e
zzh1jh3*n9HB-hog*ir);N47#cLq|bk_!|x`|H~$ng0v&he_TPiA~pEk2%d0UGA<Cv
zo5QFlvj>_X{QDf)AL>vt6D5r^9K0iG2YZ)8slKw)6bkaAAAO02m`2Mthq2eILpzwL
z<n4xo?eu93wpdUj8PpO}X!(#1`@(AK8KCbMG?a1`vxS1h`qR&>pa_92+VBK{1OsIL
z5lR(j4~QWAAV(Id0r>!ZsfL3fKK9sR?@;RE!&`(9UelNU%7k)KYG7)}zF<XV0+~M>
z4#v_`0O(ka<h`1hM9WVE`l6^oV6Pqx4PV8CQ;=r<^eP<+5AbQg6YQw#!QMJF#FRvW
z0Et4W-0cDoyt}oMNU8<cDnUalC?HU#tKeArdax5#FUi_c1L6I6GUY2Qws>_}i-a|y
zAT^jh!{Q$OCN&u2q`|o@5QJ~vnF%1k`_<(qBrGw2L_M>?J!%AyiZmFv1^Cw<HwPfV
z;DEJ1(%%jO3m9e15>}MG*zOcg+CKjUDc1EY_%Jt7ue)M72q>b_9`}eZH7GalUuL{V
zC@>NpzU{e<ArKyR`w0!WNoA!H7S>)Ytlk(#c~xx0+qMDtzzp=KUR=VM{_=5DKK|%{
z$tlgr){4}NBo#w>u7ss+k1d3XKv9%)_AH8`F@yeiivfv%6&|9$olKy8{xYMl>lVuB
zE;gEC=^Xye_SFXj2*iau!0|EI*b!Y0^t$737O1z=eH%uTOn*qYS2%M7oTu4mIQPV{
zA{S};v-0Fi<JT7RVz&D;+!~FHRYF*6R6_0vC9EEMaonj@55$(~B6C_&AL#Bss_|@m
ziJL*bRDH?m?j=wvH9cmcT~Diu`t-n7LMQ_rugZlNo2eH;2ODN6%*-2qeAFhERU7C_
zA;Mjm%cu6|I9ynIetrB6F7V~ZU7mzhF6Y#v!H8*@wo=(`(tCc*WpuIvA=KIVrFw1S
zpvtCJKU%&H$x5a~A;mlo4j4(0r~R$mZN+P@;HI>`flGatM@)D{9Zyx=nxC()!Npoi
zy(woe8oV9asn7F_?dp#I>-j0GWnc)2D~iZ<=(Q<mN~t*$;12GH8U3M5`HOXVh(|ta
zdLYm9v%T{6q18$s;9v4EXOBjNYAE&&HocBJ@ztWi%480>h<Z<qjMr$_BE%aW<*}6c
zlc(NXnk2a{ftZ5zs^QPHR6xHuskL*r#Sd5z(_@ao^tXJy9^om!i_?^@{*V(FzoffL
zmFw1`1_o8LQ5<zwuEXuGZp64QahrLF1k)e#b(=qM{-z6?9awa4)88e3nzW8^>T!io
z*)2k<I-!Uh^^bKI56a3S7mHN=r0PP^Gh{yI#IZ{=ik7U0vN!Mlyuo0X=o#1A5l^47
z$AH1@jk)P{NKIB&u`qa1@xb&06I#*=R=?_2E-Kheg&j$V__R3V>?Py3lfC+XUyizL
zji(Sfs-Ev(3DH1;rmTz<2{Pap2=9EImBU8sE%9tio9aux#HojPo*uCjQ_Ib$cj^Hb
zzJ;aQsk3ZLvFkoGm?A)qwqrrUKQlcl(bG(ROyo>ZqJMaf=5k+i83I*T7D5gF=HcTu
zrvjRVIj!noYVknTeq-7&s~#M}+LI>6Av|)?GJi5?(o4FR>sR53`JglFO-N9Uw@z}*
zk%Dl_{)hTWGsD2Om5CIp+xp25FV7+E3s1MU-YQF=$!!Vvn9_6)ckl2YN89uaRVf1Q
za9ov9(yI&lEhCmmPxC;n(LcG&IE0JVTgF#@!8C7m@N-kYTlBK2H~hBnKM}E$!)P&k
zgSvif5pZA1Ic5Y<Hqk=`5*DfOhazoZCXB0a>GtV!=&5eUO=qO@drv2DFxa!tZ#r?I
z%+C|a!{fPTARO}Lu~at;sgHSds6Y9BiB7*$!QPGE@hIS6YE#VurBR9$>`!{5>x#_$
zT7L7vU%w`iDVt!@zwWOgu)Rt(uDw}~`Iiq{nVH_TWh>!f#$H#Wr#m`;PpD2f*9Kd-
zyGTPuN<yq{j4*9^oOB^WDqOwU{Z#c+spw*9M98t$Nk!ha&lu%kludI-bEPJzo?(ua
z5>^F;^lqgvju~r)kLa~KFfP46HKx_8Oe-2-o*;Zunv9Z*Cbm9QJyCwWYh_A%mpX4l
zdmY(2bwY?#IN9n96PAX&zt3!X-hb{>=TV#0m)0qTo~!(~Zrv91diPcevVPZR*^ajj
zrOOUhRR&9i$R=l^-Kek1xLa}M#4#necmB7lcLzXQA67CJ6=jWl!u%}rA-ZW8C@T6z
zrVN=I-`yzSLcqeX0HB6W`}FjgOuM%w%RDCOGo0oSL(4Cyo`!P?HudcW>ESc#O$f|4
z25%LEvzw)T)&AHvZk3h8w#+v0Kom@Cal2m|suRYm5okOCSXAX~j|LI0c$@^w-!q^2
zp)>hUHIqNv!pOAzecf|8?2N4LxU7oD4h^rhvVF)a4`3$ak7t89tLf(A)uL@lgtpeq
z9@MB`7!!5RVnUy?nor6iWmR~G{)0Ez4e-0lZaK~#M2x_a_o5%1EgGox^&e5$b8J9c
z92@;U1?AO;Km+@|tyT7$UhodLUv)jJa&^0?QZ4pp@2+?uD9eSkvl7IO|An=`5I}po
zAH?O;RPQRCPxoz^DCDp-lkOcX#xC5gdAF$D4h9b^e%T~%TH4QY+mM@FTovKfye(-f
z$eyw40c~yLRgS^|!GiTiekKktW8{d4@5y+=i&?WTo0k8y^)C@;Vyhgy7=hW-FaUM_
z2CV_mhObar#^qVx@K3fy5k5~r0kQ3z%hBK(SM`spqTmIhknBUwsg757u(r?Xp2lSE
z?p&u|t}|g|jEl_pW}<#^yImffuK&#1wmIVM8H6xPuGphSu)Q(I*5Fnn|5eB!5CVyu
zdQ9*_*Hw&)yud;_P*rXF4NyiLUbJ(i;IZm;3oL!C+QEF=X@I$V2bu>Z&G|21reBWh
zglikS$9z?7%hmwJMU<BpSn*h;>uVgqH^LM20>w0mDg9cVurEFZRb&)q-2@>W&7AFU
z)OYt?&z#As8PAhLLy%<q-Tvq2p{yDh!>E|{YZ~A<aVOX}9FO1C>yo2kcfb^stoH@}
zRLP59&=~#MHBStT@2>$b0<rr;4hpFnJ^t_iWY6oOxvv+k_zbgO06qbPV0^RB_U!)x
DUcDOF
new file mode 100644
--- /dev/null
+++ b/gfx/wr/wrench/reftests/transforms/raster-root-scaling-ref.yaml
@@ -0,0 +1,10 @@
+
+# Tests that surfaces created by raster roots are scaled based on the surface to parent transform.
+---
+root:
+  items:
+    - type: stacking-context
+      bounds: [0, 0, 0, 0]
+      items:
+        - image: checkerboard(2, 16, 16)
+          bounds: [0, 0, 260, 260]
new file mode 100644
--- /dev/null
+++ b/gfx/wr/wrench/reftests/transforms/raster-root-scaling.yaml
@@ -0,0 +1,16 @@
+# Tests that surfaces created by raster roots are scaled based on the surface to parent transform.
+---
+root:
+  items:
+    - type: stacking-context
+      bounds: [0, 0, 0, 0]
+      # Force WebRender to form a raster root
+      transform: perspective(1000)
+      items:
+      - type: stacking-context
+        bounds: [0, 0, 0, 0]
+        transform-style: preserve-3d
+        transform: scale(10,10)
+        items:
+          - image: checkerboard(2, 16, 16)
+            bounds: [0, 0, 26, 26]
--- a/gfx/wr/wrench/reftests/transforms/reftest.list
+++ b/gfx/wr/wrench/reftests/transforms/reftest.list
@@ -43,8 +43,9 @@ platform(linux,mac) fuzzy(1,74) == borde
 == strange-w.yaml strange-w-ref.yaml
 == big-axis-aligned-scale.yaml big-axis-aligned-scale-ref.yaml
 # Compare ~8K raster root (>MAX_SURFACE_SIZE) with ~2K raster root. fuzzy due to lerping on edges.
 skip_on(android) fuzzy-range(<=3,*3077,<=10,*133,<=93,*490) == raster_root_A_8192.yaml raster_root_A_ref.yaml
 # Same as large-raster-root.yaml but resulting in a 10302×100 raster root (= >4096) vs 4000x100 in ref:
 skip_on(android) fuzzy(60,917) == raster_root_B_8192.yaml raster_root_B_ref.yaml
 # Make sure we don't panic
 != raster-root-large-mask.yaml blank.yaml
+skip_on(android) == raster-root-scaling.yaml raster-root-scaling-ref.yaml