Bug 1694059 - Use WebRender to render most non-native-theme widgets when possible. r=mstange

We basically use a couple primitives to draw these
(PaintRoundedRectWithRadius, FillRect), so making the code a bit generic
implementing stuff with WebRender seems straight-forward.

I've kept using the fallback codepath for the bits that draw complex
paths like arrows and such, but the rest of the things should work with
this patch.

A thing I'm not too happy about is the scrollbar painting setup (requires a lot
of boilerplate), but modulo template hacks make nsNativeBasicTheme a template
that receives its super class as a parameter or something) it seems hard to do
better.

Differential Revision: https://phabricator.services.mozilla.com/D105931
This commit is contained in:
Emilio Cobos Álvarez 2021-02-23 01:10:22 +00:00
Родитель ca8338163c
Коммит cb286403d0
18 изменённых файлов: 743 добавлений и 310 удалений

Просмотреть файл

@ -3,12 +3,12 @@
# First make sure that we are actually drawing scrollbars
skip-if(!asyncPan) pref(apz.allow_zooming,true) != async-scrollbar-1-v.html about:blank
skip-if(!asyncPan) pref(apz.allow_zooming,true) != async-scrollbar-1-v-ref.html about:blank
fuzzy-if(Android,0-1,0-2) fuzzy-if(webrender&&gtkWidget&&!swgl,7-8,24-32) fuzzy-if(webrender&&cocoaWidget,22-22,44-44) skip-if(!asyncPan) pref(apz.allow_zooming,true) == async-scrollbar-1-v.html async-scrollbar-1-v-ref.html
fuzzy-if(Android,0-4,0-5) fuzzy-if(webrender&&gtkWidget,28-30,28-32) fuzzy-if(webrender&&cocoaWidget,22-22,44-44) skip-if(!asyncPan) pref(apz.allow_zooming,true) == async-scrollbar-1-h.html async-scrollbar-1-h-ref.html
fuzzy-if(Android,0-7,0-6) fuzzy-if(webrender&&gtkWidget&&!swgl,2-2,19-20) fuzzy-if(webrender&&cocoaWidget,17-17,88-88) skip-if(!asyncPan) pref(apz.allow_zooming,true) == async-scrollbar-1-vh.html async-scrollbar-1-vh-ref.html
fuzzy-if(Android,0-1,0-2) fuzzy-if(webrender&&gtkWidget&&!swgl,7-8,24-32) fuzzy-if(webrender&&cocoaWidget,22-22,44-44) skip-if(!asyncPan) pref(apz.allow_zooming,true) == async-scrollbar-1-v-rtl.html async-scrollbar-1-v-rtl-ref.html
fuzzy-if(Android,0-14,0-5) fuzzy-if(webrender&&gtkWidget,28-30,28-32) fuzzy-if(webrender&&cocoaWidget,22-22,44-44) skip-if(!asyncPan) pref(apz.allow_zooming,true) == async-scrollbar-1-h-rtl.html async-scrollbar-1-h-rtl-ref.html
fuzzy-if(Android,0-8,0-8) fuzzy-if(webrender&&gtkWidget,13-14,27-32) fuzzy-if(webrender&&cocoaWidget,17-17,50-54) skip-if(!asyncPan) pref(apz.allow_zooming,true) == async-scrollbar-1-vh-rtl.html async-scrollbar-1-vh-rtl-ref.html
fuzzy-if(Android,0-1,0-2) fuzzy-if(webrender&&gtkWidget,1-8,8-32) fuzzy-if(webrender&&cocoaWidget,22-22,44-44) skip-if(!asyncPan) pref(apz.allow_zooming,true) == async-scrollbar-1-v.html async-scrollbar-1-v-ref.html
fuzzy-if(Android,0-4,0-5) fuzzy-if(webrender&&gtkWidget,1-30,4-32) fuzzy-if(webrender&&cocoaWidget,22-22,44-44) skip-if(!asyncPan) pref(apz.allow_zooming,true) == async-scrollbar-1-h.html async-scrollbar-1-h-ref.html
fuzzy-if(Android,0-7,0-6) fuzzy-if(webrender&&gtkWidget,1-2,8-20) fuzzy-if(webrender&&cocoaWidget,17-17,88-88) skip-if(!asyncPan) pref(apz.allow_zooming,true) == async-scrollbar-1-vh.html async-scrollbar-1-vh-ref.html
fuzzy-if(Android,0-1,0-2) fuzzy-if(webrender&&gtkWidget,1-8,8-32) fuzzy-if(webrender&&cocoaWidget,22-22,44-44) skip-if(!asyncPan) pref(apz.allow_zooming,true) == async-scrollbar-1-v-rtl.html async-scrollbar-1-v-rtl-ref.html
fuzzy-if(Android,0-14,0-5) fuzzy-if(webrender&&gtkWidget,1-30,12-32) fuzzy-if(webrender&&cocoaWidget,22-22,44-44) skip-if(!asyncPan) pref(apz.allow_zooming,true) == async-scrollbar-1-h-rtl.html async-scrollbar-1-h-rtl-ref.html
fuzzy-if(Android,0-8,0-8) fuzzy-if(webrender&&gtkWidget,8-14,12-32) fuzzy-if(webrender&&cocoaWidget,17-17,50-54) skip-if(!asyncPan) pref(apz.allow_zooming,true) == async-scrollbar-1-vh-rtl.html async-scrollbar-1-vh-rtl-ref.html
# Different async zoom levels. Since the scrollthumb gets async-scaled in the
# compositor, the border-radius ends of the scrollthumb are going to be a little

Просмотреть файл

@ -468,10 +468,8 @@ static inline wr::BorderRadius EmptyBorderRadius() {
}
static inline wr::BorderRadius ToBorderRadius(
const mozilla::LayoutDeviceSize& topLeft,
const mozilla::LayoutDeviceSize& topRight,
const mozilla::LayoutDeviceSize& bottomLeft,
const mozilla::LayoutDeviceSize& bottomRight) {
const LayoutDeviceSize& topLeft, const LayoutDeviceSize& topRight,
const LayoutDeviceSize& bottomLeft, const LayoutDeviceSize& bottomRight) {
wr::BorderRadius br;
br.top_left = ToLayoutSize(topLeft);
br.top_right = ToLayoutSize(topRight);
@ -480,6 +478,14 @@ static inline wr::BorderRadius ToBorderRadius(
return br;
}
static inline wr::BorderRadius ToBorderRadius(
const gfx::RectCornerRadii& aRadii) {
return ToBorderRadius(LayoutDeviceSize::FromUnknownSize(aRadii[0]),
LayoutDeviceSize::FromUnknownSize(aRadii[1]),
LayoutDeviceSize::FromUnknownSize(aRadii[3]),
LayoutDeviceSize::FromUnknownSize(aRadii[2]));
}
static inline wr::ComplexClipRegion ToComplexClipRegion(
const nsRect& aRect, const nscoord* aRadii, int32_t aAppUnitsPerDevPixel) {
wr::ComplexClipRegion ret;

Просмотреть файл

@ -141,15 +141,11 @@ bool nsDisplayButtonBoxShadowOuter::CreateWebRenderCommands(
wr::BorderRadius borderRadius =
wr::ToBorderRadius(zeroSize, zeroSize, zeroSize, zeroSize);
if (hasBorderRadius) {
mozilla::gfx::RectCornerRadii borderRadii;
gfx::RectCornerRadii borderRadii;
hasBorderRadius = nsCSSRendering::GetBorderRadii(shadowRect, shadowRect,
mFrame, borderRadii);
if (hasBorderRadius) {
borderRadius = wr::ToBorderRadius(
LayoutDeviceSize::FromUnknownSize(borderRadii.TopLeft()),
LayoutDeviceSize::FromUnknownSize(borderRadii.TopRight()),
LayoutDeviceSize::FromUnknownSize(borderRadii.BottomLeft()),
LayoutDeviceSize::FromUnknownSize(borderRadii.BottomRight()));
borderRadius = wr::ToBorderRadius(borderRadii);
}
}

Просмотреть файл

@ -3342,11 +3342,7 @@ void nsCSSBorderRenderer::CreateWebRenderCommands(
wr::ToBorderSide(ToDeviceColor(mBorderColors[i]), mBorderStyles[i]);
}
wr::BorderRadius borderRadius =
wr::ToBorderRadius(LayoutDeviceSize::FromUnknownSize(mBorderRadii[0]),
LayoutDeviceSize::FromUnknownSize(mBorderRadii[1]),
LayoutDeviceSize::FromUnknownSize(mBorderRadii[3]),
LayoutDeviceSize::FromUnknownSize(mBorderRadii[2]));
wr::BorderRadius borderRadius = wr::ToBorderRadius(mBorderRadii);
if (mLocalClip) {
LayoutDeviceRect localClip =

Просмотреть файл

@ -24,7 +24,7 @@ fuzzy-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu),0-1,0-3120) skip-if(!asyncPa
skip-if(!asyncPan) == position-fixed-cover-1.html position-fixed-cover-1-ref.html
skip-if(!asyncPan) == position-fixed-cover-2.html position-fixed-cover-2-ref.html
skip-if(!asyncPan) == position-fixed-cover-3.html position-fixed-cover-3-ref.html
fuzzy-if(Android,0-8,0-4) fuzzy-if(webrender&&gtkWidget,32-33,28-32) fuzzy-if(webrender&&cocoaWidget,21-21,44-44) skip-if(!asyncPan) == position-fixed-transformed-1.html position-fixed-transformed-1-ref.html # Bug 1604338
fuzzy-if(Android,0-8,0-4) fuzzy-if(webrender&&gtkWidget,20-33,14-32) fuzzy-if(webrender&&cocoaWidget,21-21,44-44) skip-if(!asyncPan) == position-fixed-transformed-1.html position-fixed-transformed-1-ref.html # Bug 1604338
skip-if(!asyncPan) == split-layers-1.html split-layers-1-ref.html
skip-if(!asyncPan) == split-layers-multi-scrolling-1.html split-layers-multi-scrolling-1-ref.html
fuzzy-if(skiaContent,0-2,0-240000) fuzzy-if(browserIsRemote&&!skiaContent&&(cocoaWidget||winWidget),0-1,0-240000) skip-if(!asyncPan) == split-opacity-layers-1.html split-opacity-layers-1-ref.html
@ -49,33 +49,33 @@ skip-if(!asyncPan) fails-if(!webrender) == sticky-inside-transform-1.html sticky
fuzzy(0-1,0-60000) skip-if(!asyncPan) == group-opacity-surface-size-1.html group-opacity-surface-size-1-ref.html
fuzzy-if(Android,0-1,0-197) fuzzy-if(webrender,0-9,0-99) skip-if(!asyncPan) == position-sticky-transformed.html position-sticky-transformed-ref.html
skip-if(!asyncPan) fuzzy-if(webrender&&cocoaWidget,1-1,396-396) fuzzy-if(webrender&&winWidget,0-1,0-396) == offscreen-prerendered-active-opacity.html offscreen-prerendered-active-opacity-ref.html
fuzzy-if(Android,0-6,0-4) fuzzy-if(skiaContent&&!Android,0-1,0-34) fuzzy-if(webrender&&gtkWidget,34-35,28-32) fuzzy-if(webrender&&cocoaWidget,7-7,38-39) skip-if(!asyncPan) == offscreen-clipped-blendmode-1.html offscreen-clipped-blendmode-ref.html # Bug 1604338
fuzzy-if(Android,0-6,0-4) fuzzy-if(webrender&&gtkWidget,34-35,28-32) fuzzy-if(webrender&&cocoaWidget,7-7,38-39) skip-if(!asyncPan) == offscreen-clipped-blendmode-2.html offscreen-clipped-blendmode-ref.html # Bug 1604338
fuzzy-if(Android,0-6,0-4) fuzzy-if(skiaContent&&!Android,0-1,0-34) fuzzy-if(webrender&&gtkWidget,22-74,20-32) fuzzy-if(webrender&&cocoaWidget,7-7,38-39) skip-if(!asyncPan) == offscreen-clipped-blendmode-1.html offscreen-clipped-blendmode-ref.html # Bug 1604338
fuzzy-if(Android,0-6,0-4) fuzzy-if(webrender&&gtkWidget,22-74,28-32) fuzzy-if(webrender&&cocoaWidget,7-7,20-39) skip-if(!asyncPan) == offscreen-clipped-blendmode-2.html offscreen-clipped-blendmode-ref.html # Bug 1604338
fuzzy-if(Android,0-6,0-4) skip == offscreen-clipped-blendmode-3.html offscreen-clipped-blendmode-ref.html # bug 1251588 - wrong AGR on mix-blend-mode item
fuzzy-if(Android,0-6,0-4) fuzzy-if(webrender&&gtkWidget,34-35,28-32) fuzzy-if(webrender&&cocoaWidget,7-7,38-39) skip-if(!asyncPan) == offscreen-clipped-blendmode-4.html offscreen-clipped-blendmode-ref.html # Bug 1604338
fuzzy-if(Android,0-7,0-1680) fuzzy-if(webrender&&gtkWidget&&!swgl,1-1,10-20) fuzzy-if(webrender&&cocoaWidget,1-2,16-18) skip-if(!asyncPan) == perspective-scrolling-1.html perspective-scrolling-1-ref.html # Bug 1604338
fuzzy-if(Android,0-6,0-4) fuzzy-if(webrender&&gtkWidget,22-74,20-32) fuzzy-if(webrender&&cocoaWidget,7-7,38-39) skip-if(!asyncPan) == offscreen-clipped-blendmode-4.html offscreen-clipped-blendmode-ref.html # Bug 1604338
fuzzy-if(Android,0-7,0-1680) fuzzy-if(webrender&&gtkWidget,1-1,2-20) fuzzy-if(webrender&&cocoaWidget,1-2,16-18) skip-if(!asyncPan) == perspective-scrolling-1.html perspective-scrolling-1-ref.html # Bug 1604338
fuzzy-if(Android,0-7,0-4) skip-if(!asyncPan) == perspective-scrolling-2.html perspective-scrolling-2-ref.html
fuzzy-if(Android,0-19,0-4) fuzzy-if(webrender&&gtkWidget,13-13,28-32) fuzzy-if(webrender&&cocoaWidget,13-13,44-44) skip-if(!asyncPan) == perspective-scrolling-3.html perspective-scrolling-3-ref.html # Bug 1604338
fuzzy-if(Android,0-7,0-4) fuzzy-if(webrender&&gtkWidget,29-30,28-32) fuzzy-if(webrender&&cocoaWidget,19-20,44-44) skip-if(!asyncPan) == perspective-scrolling-4.html perspective-scrolling-4-ref.html # Bug 1604338
fuzzy-if(Android,0-19,0-4) fuzzy-if(webrender&&gtkWidget,8-13,12-32) fuzzy-if(webrender&&cocoaWidget,13-13,44-44) skip-if(!asyncPan) == perspective-scrolling-3.html perspective-scrolling-3-ref.html # Bug 1604338
fuzzy-if(Android,0-7,0-4) fuzzy-if(webrender&&gtkWidget,18-30,14-32) fuzzy-if(webrender&&cocoaWidget,19-20,44-44) skip-if(!asyncPan) == perspective-scrolling-4.html perspective-scrolling-4-ref.html # Bug 1604338
skip-if(!asyncPan) == perspective-scrolling-5.html perspective-scrolling-5-ref.html
pref(apz.disable_for_scroll_linked_effects,true) skip-if(!asyncPan) == disable-apz-for-sle-pages.html disable-apz-for-sle-pages-ref.html
fuzzy-if(browserIsRemote&&d2d,0-1,0-22) skip-if(!asyncPan) fuzzy-if(geckoview,2-2,242-242) skip-if(geckoview&&debug) fuzzy-if(webrender&&swgl,0-255,0-11) == background-blend-mode-1.html background-blend-mode-1-ref.html # bug 1558286 for GV
skip-if(Android||!asyncPan) != opaque-fractional-displayport-1.html about:blank
skip-if(Android||!asyncPan) != opaque-fractional-displayport-2.html about:blank
fuzzy-if(Android,0-19,0-4) fuzzy-if(webrender&&gtkWidget,19-19,28-32) fuzzy-if(webrender&&cocoaWidget,21-21,44-44) skip-if(!asyncPan) == fixed-pos-scrolled-clip-1.html fixed-pos-scrolled-clip-1-ref.html # Bug 1604338
fuzzy-if(Android,0-44,0-10) fuzzy-if(webrender&&gtkWidget,26-26,56-64) fuzzy-if(webrender&&cocoaWidget,13-13,81-82) fuzzy-if(winWidget&&!nativeThemePref,0-4,0-36) skip-if(!asyncPan) == fixed-pos-scrolled-clip-2.html fixed-pos-scrolled-clip-2-ref.html # Bug 1604338
fuzzy-if(Android,0-6,0-8) fuzzy-if(webrender&&gtkWidget,28-28,30-60) fuzzy-if(swgl&&gtkWidget&&!nativeThemePref,29-29,30-30) fuzzy-if(webrender&&cocoaWidget,18-19,70-75) skip-if(!asyncPan) == fixed-pos-scrolled-clip-3.html fixed-pos-scrolled-clip-3-ref.html # Bug 1604338
fuzzy-if(Android,0-6,0-8) fuzzy-if(webrender&&gtkWidget,28-29,30-60) fuzzy-if(webrender&&cocoaWidget,18-19,70-75) skip-if(!asyncPan) == fixed-pos-scrolled-clip-4.html fixed-pos-scrolled-clip-4-ref.html # Bug 1604338
fuzzy-if(Android,0-19,0-4) fuzzy-if(webrender&&gtkWidget,12-19,12-32) fuzzy-if(webrender&&cocoaWidget,21-21,44-44) skip-if(!asyncPan) == fixed-pos-scrolled-clip-1.html fixed-pos-scrolled-clip-1-ref.html # Bug 1604338
fuzzy-if(Android,0-44,0-10) fuzzy-if(webrender&&gtkWidget,16-26,26-64) fuzzy-if(webrender&&cocoaWidget,13-13,81-82) fuzzy-if(winWidget&&!nativeThemePref,0-4,0-36) skip-if(!asyncPan) == fixed-pos-scrolled-clip-2.html fixed-pos-scrolled-clip-2-ref.html # Bug 1604338
fuzzy-if(Android,0-6,0-8) fuzzy-if(webrender&&gtkWidget,17-28,24-60) fuzzy-if(webrender&&cocoaWidget,18-19,70-75) skip-if(!asyncPan) == fixed-pos-scrolled-clip-3.html fixed-pos-scrolled-clip-3-ref.html # Bug 1604338
fuzzy-if(Android,0-6,0-8) fuzzy-if(webrender&&gtkWidget,17-29,24-60) fuzzy-if(webrender&&cocoaWidget,18-19,70-75) skip-if(!asyncPan) == fixed-pos-scrolled-clip-4.html fixed-pos-scrolled-clip-4-ref.html # Bug 1604338
skip-if(!asyncPan) == fixed-pos-scrolled-clip-5.html fixed-pos-scrolled-clip-5-ref.html
skip-if(!asyncPan) == position-sticky-bug1434250.html position-sticky-bug1434250-ref.html
fuzzy-if(Android,0-8,0-4) fuzzy-if(webrender&&gtkWidget,25-25,28-32) fuzzy-if(webrender&&cocoaWidget,16-16,44-44) skip-if(!asyncPan) == position-sticky-scrolled-clip-1.html position-sticky-scrolled-clip-1-ref.html # Bug 1604338
fuzzy-if(Android,0-8,0-4) fuzzy-if(webrender&&gtkWidget,16-25,12-32) fuzzy-if(webrender&&cocoaWidget,16-16,44-44) skip-if(!asyncPan) == position-sticky-scrolled-clip-1.html position-sticky-scrolled-clip-1-ref.html # Bug 1604338
fuzzy-if(Android,0-6,0-4) skip == position-sticky-scrolled-clip-2.html position-sticky-scrolled-clip-2-ref.html # bug ?????? - incorrectly applying clip to sticky contents
fuzzy-if(Android,0-8,0-27) fuzzy-if(webrender&&cocoaWidget,10-11,44-44) skip-if(!asyncPan) == curtain-effect-1.html curtain-effect-1-ref.html
fuzzy-if(Android,0-6,0-4) fuzzy-if(webrender&&gtkWidget,15-15,28-32) fuzzy-if(webrender&&cocoaWidget,8-8,38-42) skip-if(!asyncPan) == transformed-1.html transformed-1-ref.html # Bug 1604338
fuzzy-if(Android&&!webrender,2-2,4-4) fuzzy-if(Android&&webrender,7-7,4-4) fuzzy-if(webrender&&gtkWidget&&!swgl,4-5,26-28) fuzzy-if(webrender&&cocoaWidget,6-6,37-38) skip-if(!asyncPan) == position-sticky-transformed-in-scrollframe-1.html position-sticky-transformed-in-scrollframe-1-ref.html # Bug 1604338
fuzzy-if(Android&&!webrender,3-3,4-4) fuzzy-if(Android&&webrender,10-10,4-4) fuzzy-if(webrender&&gtkWidget,20-20,28-32) fuzzy-if(webrender&&cocoaWidget,15-16,44-44) skip-if(!asyncPan) == position-sticky-transformed-in-scrollframe-2.html position-sticky-transformed-in-scrollframe-2-ref.html # Bug 1604338
fuzzy-if(Android&&!webrender,3-3,4-4) fuzzy-if(Android&&webrender,13-13,4-4) fuzzy-if(webrender&&gtkWidget,26-27,28-32) fuzzy-if(webrender&&cocoaWidget,16-16,44-44) skip-if(!asyncPan) == position-sticky-in-transformed-scrollframe-1.html position-sticky-in-transformed-scrollframe-ref.html # Bug 1604338
fuzzy-if(Android&&!webrender,3-3,4-4) fuzzy-if(Android&&webrender,13-13,4-4) fuzzy-if(webrender&&gtkWidget,26-27,28-32) fuzzy-if(webrender&&cocoaWidget,16-16,44-44) skip-if(!asyncPan) == position-sticky-in-transformed-scrollframe-2.html position-sticky-in-transformed-scrollframe-ref.html # Bug 1604338
fuzzy-if(Android,0-6,0-4) fuzzy-if(webrender&&gtkWidget,10-15,12-32) fuzzy-if(webrender&&cocoaWidget,8-8,38-42) skip-if(!asyncPan) == transformed-1.html transformed-1-ref.html # Bug 1604338
fuzzy-if(Android&&!webrender,2-2,4-4) fuzzy-if(Android&&webrender,7-7,4-4) fuzzy-if(webrender&&gtkWidget,3-5,12-28) fuzzy-if(webrender&&cocoaWidget,6-6,37-38) skip-if(!asyncPan) == position-sticky-transformed-in-scrollframe-1.html position-sticky-transformed-in-scrollframe-1-ref.html # Bug 1604338
fuzzy-if(Android&&!webrender,3-3,4-4) fuzzy-if(Android&&webrender,10-10,4-4) fuzzy-if(webrender&&gtkWidget,13-20,12-32) fuzzy-if(webrender&&cocoaWidget,15-16,44-44) skip-if(!asyncPan) == position-sticky-transformed-in-scrollframe-2.html position-sticky-transformed-in-scrollframe-2-ref.html # Bug 1604338
fuzzy-if(Android&&!webrender,3-3,4-4) fuzzy-if(Android&&webrender,13-13,4-4) fuzzy-if(webrender&&gtkWidget,16-27,14-32) fuzzy-if(webrender&&cocoaWidget,16-16,44-44) skip-if(!asyncPan) == position-sticky-in-transformed-scrollframe-1.html position-sticky-in-transformed-scrollframe-ref.html # Bug 1604338
fuzzy-if(Android&&!webrender,3-3,4-4) fuzzy-if(Android&&webrender,13-13,4-4) fuzzy-if(webrender&&gtkWidget,16-27,14-32) fuzzy-if(webrender&&cocoaWidget,16-16,44-44) skip-if(!asyncPan) == position-sticky-in-transformed-scrollframe-2.html position-sticky-in-transformed-scrollframe-ref.html # Bug 1604338
# for the following tests, we want to disable the low-precision buffer
# as it will expand the displayport beyond what the test specifies in

Просмотреть файл

@ -1383,8 +1383,8 @@ fuzzy-if(Android,0-5,0-1656) fuzzy-if(skiaContent,0-1,0-1200) == 512410.html 512
== 512631-1.html 512631-1-ref.html
fuzzy-if(Android,0-1,0-2) fuzzy-if(!nativeThemePref,0-1,0-4) == 513153-1a.html 513153-1-ref.html
fuzzy-if(Android,0-1,0-2) fuzzy-if(!nativeThemePref,0-1,0-4) == 513153-1b.html 513153-1-ref.html
fails-if((winWidget||cocoaWidget)&&!nativeThemePref&&webrender) fuzzy-if(winWidget&&nativeThemePref&&webrender,82-82,84-84) == 513153-2a.html 513153-2-ref.html
fails-if(cocoaWidget&&!nativeThemePref&&webrender) fuzzy-if(cocoaWidget&&nativeThemePref&&webrender,46-46,116-116) == 513153-2b.html 513153-2-ref.html
fuzzy-if(winWidget&&nativeThemePref&&webrender,82-82,84-84) == 513153-2a.html 513153-2-ref.html
fuzzy-if(cocoaWidget&&nativeThemePref&&webrender,46-46,116-116) == 513153-2b.html 513153-2-ref.html
== chrome://reftest/content/bugs/513318-1.xhtml chrome://reftest/content/bugs/513318-1-ref.xhtml
fails-if(Android&&(!asyncPan)) != chrome://reftest/content/bugs/513318-2.xhtml chrome://reftest/content/bugs/513318-2-ref.xhtml
== 514917-1.html 514917-1-ref.html

Просмотреть файл

@ -5,7 +5,7 @@ fuzzy-if(gtkWidget||webrender,0-1,0-10) == background.html chrome://reftest/cont
fuzzy-if(gtkWidget,0-1,0-10) == style.html chrome://reftest/content/forms/input/file/style-ref.xhtml
!= width-clip.html width-clip-ref.html
== color-inherit.html color-inherit-ref.html
fuzzy-if(Android,0-2,0-2) fuzzy-if(!nativeThemePref,0-1,0-5) fuzzy-if(OSX,0-46,0-134) fails-if(webrender&&!(cocoaWidget||geckoview)) == dynamic-max-width.html dynamic-max-width-ref.html # bug 1496542 for webrender.
fuzzy-if(Android,0-2,0-2) fuzzy-if(!nativeThemePref,0-1,0-5) fuzzy-if(OSX,0-46,0-134) fails-if(webrender&&nativeThemePref&&!(cocoaWidget||geckoView)) == dynamic-max-width.html dynamic-max-width-ref.html # bug 1496542 for webrender.
== label-min-inline-size.html label-min-inline-size-ref.html
== css-overflow.html css-overflow-ref.html
== css-display.html css-display-ref.html

Просмотреть файл

@ -17,7 +17,11 @@ fuzzy-if(d2d&&/^Windows\x20NT\x206\.1/.test(http.oscpu),0-16,0-90) == element-pa
== element-paint-background-size-02.html element-paint-background-size-02-ref.html
fuzzy-if(skiaContent,0-255,0-4) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == element-paint-transform-repeated.html element-paint-transform-repeated-ref.html # Bug 1475907
fuzzy-if(d2d,0-255,0-24) fuzzy-if(webrender,255-255,56-72) == element-paint-transform-03.html element-paint-transform-03-ref.html
fuzzy-if(asyncPan,0-2,0-140) fuzzy-if(skiaContent,0-3,0-106) fuzzy-if(webrender&&winWidget,134-222,1197-1588) fuzzy-if(geckoview&&webrender,0-7,0-1321) == element-paint-native-widget.html element-paint-native-widget-ref.html # in -ref the scrollframe is active and layerized differently with APZ
# For !nativeThemePref: element() uses fallback / skia in WebRender, which antialiases differently from WR.
# For the rest: -ref the scrollframe is active and layerized differently with APZ.
fuzzy-if(asyncPan,0-2,0-140) fuzzy-if(skiaContent,0-3,0-106) fuzzy-if(webrender&&winWidget,134-222,1197-1588) fuzzy-if(webrender&&!nativeThemePref,48-48,50-68) fuzzy-if(geckoview&&webrender,0-7,0-1321) == element-paint-native-widget.html element-paint-native-widget-ref.html
fails-if(usesRepeatResampling&&!(webrender&&winWidget)) == element-paint-subimage-sampling-restriction.html about:blank
== element-paint-clippath.html element-paint-clippath-ref.html
fuzzy-if(webrender,36-39,704-738) == element-paint-sharpness-01a.html element-paint-sharpness-01b.html

Просмотреть файл

@ -50,6 +50,6 @@ fuzzy-if(Android,0-8,0-630) fuzzy-if(OSX,0-1,0-11) fuzzy-if(skiaContent,0-1,0-22
== block-in-inline-continuations.html block-in-inline-continuations-ref.html
== iframe-1.html iframe-1-ref.html
== transformed-1.html transformed-1-ref.html
fuzzy-if(Android,0-4,0-4) fuzzy-if(webrender&&gtkWidget,16-17,28-32) fuzzy-if(webrender&&cocoaWidget,8-8,38-42) skip-if(!asyncPan) == transformed-2.html transformed-2-ref.html # Bug 1604644
skip-if(!asyncPan) fuzzy-if(Android,0-10,0-4) fuzzy-if(webrender&&gtkWidget,29-30,28-32) fuzzy-if(webrender&&cocoaWidget,15-16,44-44) == nested-sticky-1.html nested-sticky-1-ref.html # Bug 1604644
skip-if(!asyncPan) fuzzy-if(Android,0-10,0-4) fuzzy-if(webrender&&gtkWidget,29-30,28-32) fuzzy-if(webrender&&cocoaWidget,15-16,44-44) fuzzy-if(/^Windows\x20NT\x206\.1/.test(http.oscpu),0-4,0-104) == nested-sticky-2.html nested-sticky-2-ref.html # Bug 1604644
fuzzy-if(Android,0-4,0-4) fuzzy-if(webrender&&gtkWidget,10-17,12-32) fuzzy-if(webrender&&cocoaWidget,8-8,38-42) skip-if(!asyncPan) == transformed-2.html transformed-2-ref.html # Bug 1604644
skip-if(!asyncPan) fuzzy-if(Android,0-10,0-4) fuzzy-if(webrender&&gtkWidget,19-30,12-32) fuzzy-if(webrender&&cocoaWidget,15-16,44-44) == nested-sticky-1.html nested-sticky-1-ref.html # Bug 1604644
skip-if(!asyncPan) fuzzy-if(Android,0-10,0-4) fuzzy-if(webrender&&gtkWidget,19-30,12-32) fuzzy-if(webrender&&cocoaWidget,15-16,44-44) fuzzy-if(/^Windows\x20NT\x206\.1/.test(http.oscpu),0-4,0-104) == nested-sticky-2.html nested-sticky-2-ref.html # Bug 1604644

Просмотреть файл

@ -3,8 +3,8 @@
== chrome://reftest/content/xul/menuitem-key.xhtml chrome://reftest/content/xul/menuitem-key-ref.xhtml
# these random-if(Android) are due to differences between Android Native & Xul, see bug 732569
random-if(Android) == chrome://reftest/content/xul/menulist-shrinkwrap-1.xhtml chrome://reftest/content/xul/menulist-shrinkwrap-1-ref.xhtml
random-if(Android) == chrome://reftest/content/xul/menulist-shrinkwrap-2.xhtml chrome://reftest/content/xul/menulist-shrinkwrap-2-ref.xhtml
random-if(Android) fuzzy-if(webrender&&!nativeThemePref,0-1,0-4) == chrome://reftest/content/xul/menulist-shrinkwrap-1.xhtml chrome://reftest/content/xul/menulist-shrinkwrap-1-ref.xhtml
random-if(Android) fuzzy-if(webrender&&!nativeThemePref,0-1,0-4) == chrome://reftest/content/xul/menulist-shrinkwrap-2.xhtml chrome://reftest/content/xul/menulist-shrinkwrap-2-ref.xhtml
== chrome://reftest/content/xul/textbox-overflow-1.xhtml chrome://reftest/content/xul/textbox-overflow-1-ref.xhtml # for bug 749658
# accesskeys are not normally displayed on Mac, so set a pref to enable them
pref(ui.key.menuAccessKey,18) == chrome://reftest/content/xul/accesskey.xhtml chrome://reftest/content/xul/accesskey-ref.xhtml

Просмотреть файл

@ -10557,6 +10557,12 @@
#endif
mirror: always
# Whether we should try to use WebRender to render widgets.
- name: widget.non-native-theme.webrender
type: bool
value: true
mirror: always
# Preference to disable dark scrollbar implementation.
# This is mainly for testing because dark scrollbars have to be semi-
# transparent, but many reftests expect scrollbars to look identical

Просмотреть файл

@ -43,7 +43,7 @@ auto nsNativeBasicThemeCocoa::GetScrollbarSizes(nsPresContext* aPresContext,
return {size, size};
}
void nsNativeBasicThemeCocoa::PaintScrollbarThumb(
bool nsNativeBasicThemeCocoa::PaintScrollbarThumb(
DrawTarget& aDrawTarget, const LayoutDeviceRect& aRect, bool aHorizontal,
nsIFrame* aFrame, const ComputedStyle& aStyle,
const EventStates& aElementState, const EventStates& aDocumentState,
@ -59,9 +59,10 @@ void nsNativeBasicThemeCocoa::PaintScrollbarThumb(
} else {
ScrollbarDrawingMac::DrawScrollbarThumb(aDrawTarget, rect, params);
}
return true;
}
void nsNativeBasicThemeCocoa::PaintScrollbarTrack(
bool nsNativeBasicThemeCocoa::PaintScrollbarTrack(
DrawTarget& aDrawTarget, const LayoutDeviceRect& aRect, bool aHorizontal,
nsIFrame* aFrame, const ComputedStyle& aStyle,
const EventStates& aDocumentState, DPIRatio aDpiRatio) {
@ -76,18 +77,10 @@ void nsNativeBasicThemeCocoa::PaintScrollbarTrack(
} else {
ScrollbarDrawingMac::DrawScrollbarTrack(aDrawTarget, rect, params);
}
return true;
}
void nsNativeBasicThemeCocoa::PaintScrollbar(DrawTarget& aDrawTarget,
const LayoutDeviceRect& aRect,
bool aHorizontal, nsIFrame* aFrame,
const ComputedStyle& aStyle,
const EventStates& aDocumentState,
DPIRatio aDpiRatio) {
// Draw nothing; the scrollbar track is drawn in PaintScrollbarTrack.
}
void nsNativeBasicThemeCocoa::PaintScrollCorner(
bool nsNativeBasicThemeCocoa::PaintScrollCorner(
DrawTarget& aDrawTarget, const LayoutDeviceRect& aRect, nsIFrame* aFrame,
const ComputedStyle& aStyle, const EventStates& aDocumentState,
DPIRatio aDpiRatio) {
@ -103,4 +96,5 @@ void nsNativeBasicThemeCocoa::PaintScrollCorner(
auto rect = aRect.ToUnknownRect();
ScrollbarDrawingMac::DrawScrollCorner(aDrawTarget, rect, params);
}
return true;
}

Просмотреть файл

@ -26,26 +26,64 @@ class nsNativeBasicThemeCocoa : public nsNativeBasicTheme {
ScrollbarSizes GetScrollbarSizes(nsPresContext*, StyleScrollbarWidth,
Overlay) override;
void PaintScrollbarThumb(DrawTarget&,
const LayoutDeviceRect& aRect, bool aHorizontal,
nsIFrame* aFrame, const ComputedStyle& aStyle,
bool PaintScrollbarThumb(DrawTarget&, const LayoutDeviceRect& aRect,
bool aHorizontal, nsIFrame* aFrame,
const ComputedStyle& aStyle,
const EventStates& aElementState,
const EventStates& aDocumentState,
DPIRatio aDpiRatio) override;
void PaintScrollbarTrack(DrawTarget&,
const LayoutDeviceRect& aRect, bool aHorizontal,
nsIFrame* aFrame, const ComputedStyle& aStyle,
bool PaintScrollbarThumb(WebRenderBackendData&, const LayoutDeviceRect& aRect,
bool aHorizontal, nsIFrame* aFrame,
const ComputedStyle& aStyle,
const EventStates& aElementState,
const EventStates& aDocumentState,
DPIRatio aDpiRatio) override {
// TODO: Seems this should be relatively straight-forward.
return false;
}
bool PaintScrollbarTrack(DrawTarget&, const LayoutDeviceRect& aRect,
bool aHorizontal, nsIFrame* aFrame,
const ComputedStyle& aStyle,
const EventStates& aDocumentState,
DPIRatio aDpiRatio) override;
void PaintScrollbar(DrawTarget&, const LayoutDeviceRect& aRect,
bool PaintScrollbarTrack(WebRenderBackendData&, const LayoutDeviceRect& aRect,
bool aHorizontal, nsIFrame* aFrame,
const ComputedStyle& aStyle,
const EventStates& aDocumentState,
DPIRatio aDpiRatio) override {
// TODO: Seems this should be relatively straight-forward.
return false;
}
bool PaintScrollbar(DrawTarget&, const LayoutDeviceRect& aRect,
bool aHorizontal, nsIFrame* aFrame,
const ComputedStyle& aStyle,
const EventStates& aDocumentState,
DPIRatio aDpiRatio) override;
void PaintScrollCorner(DrawTarget&, const LayoutDeviceRect& aRect,
DPIRatio aDpiRatio) override {
// Draw nothing; the scrollbar track is drawn in PaintScrollbarTrack.
return true;
}
bool PaintScrollbar(WebRenderBackendData&, const LayoutDeviceRect& aRect,
bool aHorizontal, nsIFrame* aFrame,
const ComputedStyle& aStyle,
const EventStates& aDocumentState,
DPIRatio aDpiRatio) override {
// Draw nothing; the scrollbar track is drawn in PaintScrollbarTrack.
return true;
}
bool PaintScrollCorner(DrawTarget&, const LayoutDeviceRect& aRect,
nsIFrame* aFrame, const ComputedStyle& aStyle,
const EventStates& aDocumentState,
DPIRatio aDpiRatio) override;
bool PaintScrollCorner(WebRenderBackendData&, const LayoutDeviceRect& aRect,
nsIFrame* aFrame, const ComputedStyle& aStyle,
const EventStates& aDocumentState,
DPIRatio aDpiRatio) override {
// TODO: Seems this should be relatively straight-forward.
return false;
}
protected:
virtual ~nsNativeBasicThemeCocoa() = default;

Просмотреть файл

@ -124,9 +124,10 @@ nsNativeBasicThemeGTK::GetMinimumWidgetSize(nsPresContext* aPresContext,
return NS_OK;
}
void nsNativeBasicThemeGTK::PaintScrollbarThumb(
DrawTarget& aDrawTarget, const LayoutDeviceRect& aRect, bool aHorizontal,
nsIFrame* aFrame, const ComputedStyle& aStyle,
template <typename PaintBackendData>
bool nsNativeBasicThemeGTK::DoPaintScrollbarThumb(
PaintBackendData& aPaintData, const LayoutDeviceRect& aRect,
bool aHorizontal, nsIFrame* aFrame, const ComputedStyle& aStyle,
const EventStates& aElementState, const EventStates& aDocumentState,
DPIRatio aDpiRatio) {
sRGBColor thumbColor =
@ -146,32 +147,91 @@ void nsNativeBasicThemeGTK::PaintScrollbarThumb(
? (aHorizontal ? thumbRect.height : thumbRect.width) / 2.0f
: 0.0f;
PaintRoundedRectWithRadius(aDrawTarget, thumbRect, thumbColor, sRGBColor(), 0,
PaintRoundedRectWithRadius(aPaintData, thumbRect, thumbColor, sRGBColor(), 0,
radius / aDpiRatio, aDpiRatio);
return true;
}
void nsNativeBasicThemeGTK::PaintScrollbar(DrawTarget& aDrawTarget,
bool nsNativeBasicThemeGTK::PaintScrollbarThumb(
DrawTarget& aDrawTarget, const LayoutDeviceRect& aRect, bool aHorizontal,
nsIFrame* aFrame, const ComputedStyle& aStyle,
const EventStates& aElementState, const EventStates& aDocumentState,
DPIRatio aDpiRatio) {
return DoPaintScrollbarThumb(aDrawTarget, aRect, aHorizontal, aFrame, aStyle,
aElementState, aDocumentState, aDpiRatio);
}
bool nsNativeBasicThemeGTK::PaintScrollbarThumb(
WebRenderBackendData& aWrData, const LayoutDeviceRect& aRect,
bool aHorizontal, nsIFrame* aFrame, const ComputedStyle& aStyle,
const EventStates& aElementState, const EventStates& aDocumentState,
DPIRatio aDpiRatio) {
return DoPaintScrollbarThumb(aWrData, aRect, aHorizontal, aFrame, aStyle,
aElementState, aDocumentState, aDpiRatio);
}
template <typename PaintBackendData>
bool nsNativeBasicThemeGTK::DoPaintScrollbar(PaintBackendData& aPaintData,
const LayoutDeviceRect& aRect,
bool aHorizontal, nsIFrame* aFrame,
const ComputedStyle& aStyle,
const EventStates& aDocumentState,
DPIRatio aDpiRatio) {
auto [trackColor, borderColor] =
ComputeScrollbarColors(aFrame, aStyle, aDocumentState);
Unused << borderColor;
FillRect(aPaintData, aRect, trackColor);
return true;
}
bool nsNativeBasicThemeGTK::PaintScrollbar(DrawTarget& aDrawTarget,
const LayoutDeviceRect& aRect,
bool aHorizontal, nsIFrame* aFrame,
const ComputedStyle& aStyle,
const EventStates& aDocumentState,
DPIRatio aDpiRatio) {
return DoPaintScrollbar(aDrawTarget, aRect, aHorizontal, aFrame, aStyle,
aDocumentState, aDpiRatio);
}
bool nsNativeBasicThemeGTK::PaintScrollbar(WebRenderBackendData& aWrData,
const LayoutDeviceRect& aRect,
bool aHorizontal, nsIFrame* aFrame,
const ComputedStyle& aStyle,
const EventStates& aDocumentState,
DPIRatio aDpiRatio) {
return DoPaintScrollbar(aWrData, aRect, aHorizontal, aFrame, aStyle,
aDocumentState, aDpiRatio);
}
template <typename PaintBackendData>
bool nsNativeBasicThemeGTK::DoPaintScrollCorner(
PaintBackendData& aPaintData, const LayoutDeviceRect& aRect,
nsIFrame* aFrame, const ComputedStyle& aStyle,
const EventStates& aDocumentState, DPIRatio aDpiRatio) {
auto [trackColor, borderColor] =
ComputeScrollbarColors(aFrame, aStyle, aDocumentState);
Unused << borderColor;
aDrawTarget.FillRect(aRect.ToUnknownRect(),
gfx::ColorPattern(ToDeviceColor(trackColor)));
FillRect(aPaintData, aRect, trackColor);
return true;
}
void nsNativeBasicThemeGTK::PaintScrollCorner(DrawTarget& aDrawTarget,
bool nsNativeBasicThemeGTK::PaintScrollCorner(DrawTarget& aDrawTarget,
const LayoutDeviceRect& aRect,
nsIFrame* aFrame,
const ComputedStyle& aStyle,
const EventStates& aDocumentState,
DPIRatio aDpiRatio) {
auto [trackColor, borderColor] =
ComputeScrollbarColors(aFrame, aStyle, aDocumentState);
Unused << borderColor;
aDrawTarget.FillRect(aRect.ToUnknownRect(),
gfx::ColorPattern(ToDeviceColor(trackColor)));
return DoPaintScrollCorner(aDrawTarget, aRect, aFrame, aStyle, aDocumentState,
aDpiRatio);
}
bool nsNativeBasicThemeGTK::PaintScrollCorner(WebRenderBackendData& aWrData,
const LayoutDeviceRect& aRect,
nsIFrame* aFrame,
const ComputedStyle& aStyle,
const EventStates& aDocumentState,
DPIRatio aDpiRatio) {
return DoPaintScrollCorner(aWrData, aRect, aFrame, aStyle, aDocumentState,
aDpiRatio);
}

Просмотреть файл

@ -20,21 +20,56 @@ class nsNativeBasicThemeGTK : public nsNativeBasicTheme {
nsITheme::Transparency GetWidgetTransparency(
nsIFrame* aFrame, StyleAppearance aAppearance) override;
void PaintScrollbarThumb(DrawTarget&,
const LayoutDeviceRect& aRect, bool aHorizontal,
nsIFrame* aFrame, const ComputedStyle& aStyle,
bool PaintScrollbarThumb(DrawTarget&, const LayoutDeviceRect& aRect,
bool aHorizontal, nsIFrame* aFrame,
const ComputedStyle& aStyle,
const EventStates& aElementState,
const EventStates& aDocumentState,
DPIRatio aDpiRatio) override;
void PaintScrollbar(DrawTarget&, const LayoutDeviceRect& aRect,
bool PaintScrollbarThumb(WebRenderBackendData&, const LayoutDeviceRect& aRect,
bool aHorizontal, nsIFrame* aFrame,
const ComputedStyle& aStyle,
const EventStates& aElementState,
const EventStates& aDocumentState,
DPIRatio aDpiRatio) override;
template <typename PaintBackendData>
bool DoPaintScrollbarThumb(PaintBackendData&, const LayoutDeviceRect& aRect,
bool aHorizontal, nsIFrame* aFrame,
const ComputedStyle& aStyle,
const EventStates& aElementState,
const EventStates& aDocumentState,
DPIRatio aDpiRatio);
bool PaintScrollbar(DrawTarget&, const LayoutDeviceRect& aRect,
bool aHorizontal, nsIFrame* aFrame,
const ComputedStyle& aStyle,
const EventStates& aDocumentState,
DPIRatio aDpiRatio) override;
void PaintScrollCorner(DrawTarget&, const LayoutDeviceRect& aRect,
bool PaintScrollbar(WebRenderBackendData&, const LayoutDeviceRect& aRect,
bool aHorizontal, nsIFrame* aFrame,
const ComputedStyle& aStyle,
const EventStates& aDocumentState,
DPIRatio aDpiRatio) override;
template <typename PaintBackendData>
bool DoPaintScrollbar(PaintBackendData&, const LayoutDeviceRect& aRect,
bool aHorizontal, nsIFrame* aFrame,
const ComputedStyle& aStyle,
const EventStates& aDocumentState, DPIRatio aDpiRatio);
bool PaintScrollCorner(DrawTarget&, const LayoutDeviceRect& aRect,
nsIFrame* aFrame, const ComputedStyle& aStyle,
const EventStates& aDocumentState,
DPIRatio aDpiRatio) override;
bool PaintScrollCorner(WebRenderBackendData&, const LayoutDeviceRect& aRect,
nsIFrame* aFrame, const ComputedStyle& aStyle,
const EventStates& aDocumentState,
DPIRatio aDpiRatio) override;
template <typename PaintBackendData>
bool DoPaintScrollCorner(PaintBackendData&, const LayoutDeviceRect& aRect,
nsIFrame* aFrame, const ComputedStyle& aStyle,
const EventStates& aDocumentState,
DPIRatio aDpiRatio);
bool ThemeSupportsScrollbarButtons() override;
sRGBColor ComputeScrollbarThumbColor(
nsIFrame*, const ComputedStyle&, const EventStates& aElementState,

Просмотреть файл

@ -13,6 +13,7 @@
#include "mozilla/gfx/Filters.h"
#include "mozilla/RelativeLuminanceUtils.h"
#include "mozilla/StaticPrefs_widget.h"
#include "mozilla/webrender/WebRenderAPI.h"
#include "nsCSSColorUtils.h"
#include "nsCSSRendering.h"
#include "nsLayoutUtils.h"
@ -549,24 +550,10 @@ std::array<sRGBColor, 3> nsNativeBasicTheme::ComputeScrollbarButtonColors(
return {buttonColor, arrowColor, sScrollbarBorderColor};
}
static already_AddRefed<Path> GetFocusStrokePath(
DrawTarget& aDrawTarget, LayoutDeviceRect& aFocusRect,
LayoutDeviceCoord aOffset, const LayoutDeviceCoord aRadius,
LayoutDeviceCoord aFocusWidth) {
RectCornerRadii radii(aRadius, aRadius, aRadius, aRadius);
aFocusRect.Inflate(aOffset);
LayoutDeviceRect focusRect(aFocusRect);
// Deflate the rect by half the border width, so that the middle of the
// stroke fills exactly the area we want to fill and not more.
focusRect.Deflate(aFocusWidth * 0.5f);
return MakePathForRoundedRect(aDrawTarget, focusRect.ToUnknownRect(), radii);
}
static const CSSCoord kInnerFocusOutlineWidth = 2.0f;
void nsNativeBasicTheme::PaintRoundedFocusRect(DrawTarget& aDrawTarget,
template <typename PaintBackendData>
void nsNativeBasicTheme::PaintRoundedFocusRect(PaintBackendData& aBackendData,
const LayoutDeviceRect& aRect,
DPIRatio aDpiRatio,
CSSCoord aRadius,
@ -574,6 +561,7 @@ void nsNativeBasicTheme::PaintRoundedFocusRect(DrawTarget& aDrawTarget,
// NOTE(emilio): If the widths or offsets here change, make sure to tweak
// the GetWidgetOverflow path for FocusOutline.
auto [innerColor, middleColor, outerColor] = ComputeFocusRectColors();
const sRGBColor kTransparent = sRGBColor::White(0.0);
LayoutDeviceRect focusRect(aRect);
@ -584,38 +572,109 @@ void nsNativeBasicTheme::PaintRoundedFocusRect(DrawTarget& aDrawTarget,
//
// But some controls might provide a negative offset to cover the border, if
// necessary.
LayoutDeviceCoord offset = aOffset * aDpiRatio;
LayoutDeviceCoord strokeWidth = kInnerFocusOutlineWidth * aDpiRatio;
focusRect.Inflate(strokeWidth);
CSSCoord strokeWidth = kInnerFocusOutlineWidth;
CSSCoord strokeRadius = aRadius;
focusRect.Inflate(aOffset * aDpiRatio + strokeWidth * aDpiRatio);
LayoutDeviceCoord strokeRadius = aRadius * aDpiRatio;
RefPtr<Path> roundedRect = GetFocusStrokePath(aDrawTarget, focusRect, offset,
strokeRadius, strokeWidth);
aDrawTarget.Stroke(roundedRect, ColorPattern(ToDeviceColor(innerColor)),
StrokeOptions(strokeWidth));
PaintRoundedRectWithRadius(aBackendData, focusRect, kTransparent, innerColor,
strokeWidth, strokeRadius, aDpiRatio);
offset = CSSCoord(1.0f) * aDpiRatio;
strokeRadius += offset;
strokeWidth = CSSCoord(1.0f) * aDpiRatio;
roundedRect = GetFocusStrokePath(aDrawTarget, focusRect, offset, strokeRadius,
strokeWidth);
aDrawTarget.Stroke(roundedRect, ColorPattern(ToDeviceColor(middleColor)),
StrokeOptions(strokeWidth));
strokeWidth = CSSCoord(1.0f);
strokeRadius += strokeWidth;
focusRect.Inflate(strokeWidth * aDpiRatio);
offset = CSSCoord(2.0f) * aDpiRatio;
strokeRadius += offset;
strokeWidth = CSSCoord(2.0f) * aDpiRatio;
roundedRect = GetFocusStrokePath(aDrawTarget, focusRect, offset, strokeRadius,
strokeWidth);
aDrawTarget.Stroke(roundedRect, ColorPattern(ToDeviceColor(outerColor)),
StrokeOptions(strokeWidth));
PaintRoundedRectWithRadius(aBackendData, focusRect, kTransparent, middleColor,
strokeWidth, strokeRadius, aDpiRatio);
strokeWidth = CSSCoord(2.0f);
strokeRadius += strokeWidth;
focusRect.Inflate(strokeWidth * aDpiRatio);
PaintRoundedRectWithRadius(aBackendData, focusRect, kTransparent, outerColor,
strokeWidth, strokeRadius, aDpiRatio);
}
void nsNativeBasicTheme::PaintRoundedRectWithRadius(
WebRenderBackendData& aWrData, const LayoutDeviceRect& aRect,
const LayoutDeviceRect& aClipRect, const sRGBColor& aBackgroundColor,
const sRGBColor& aBorderColor, CSSCoord aBorderWidth, CSSCoord aRadius,
DPIRatio aDpiRatio) {
const bool kBackfaceIsVisible = true;
const LayoutDeviceCoord borderWidth(SnapBorderWidth(aBorderWidth, aDpiRatio));
const LayoutDeviceCoord radius(aRadius * aDpiRatio);
const wr::LayoutRect dest = wr::ToLayoutRect(aRect);
const wr::LayoutRect clip = wr::ToLayoutRect(aClipRect);
// Push the background.
if (aBackgroundColor.a) {
auto backgroundColor = wr::ToColorF(ToDeviceColor(aBackgroundColor));
wr::LayoutRect backgroundRect = [&] {
LayoutDeviceRect bg = aRect;
bg.Deflate(borderWidth);
return wr::ToLayoutRect(bg);
}();
if (!radius) {
aWrData.mBuilder.PushRect(backgroundRect, clip, kBackfaceIsVisible,
backgroundColor);
} else {
// NOTE(emilio): This follows DisplayListBuilder::PushRoundedRect and
// draws the rounded fill as an extra thick rounded border instead of a
// rectangle that's clipped to a rounded clip. Refer to that method for a
// justification. See bug 1694269.
LayoutDeviceCoord backgroundRadius =
std::max(0.0f, float(radius) - float(borderWidth));
wr::BorderSide side = {backgroundColor, wr::BorderStyle::Solid};
const wr::BorderSide sides[4] = {side, side, side, side};
float h = backgroundRect.size.width * 0.6f;
float v = backgroundRect.size.height * 0.6f;
wr::LayoutSideOffsets widths = {v, h, v, h};
wr::BorderRadius radii = {{backgroundRadius, backgroundRadius},
{backgroundRadius, backgroundRadius},
{backgroundRadius, backgroundRadius},
{backgroundRadius, backgroundRadius}};
aWrData.mBuilder.PushBorder(backgroundRect, clip, kBackfaceIsVisible,
widths, {sides, 4}, radii);
}
}
// Push the border.
const auto borderColor = ToDeviceColor(aBorderColor);
const auto side = wr::ToBorderSide(borderColor, StyleBorderStyle::Solid);
const wr::BorderSide sides[4] = {side, side, side, side};
const LayoutDeviceSize sideRadius(radius, radius);
const auto widths =
wr::ToBorderWidths(borderWidth, borderWidth, borderWidth, borderWidth);
const auto wrRadius =
wr::ToBorderRadius(sideRadius, sideRadius, sideRadius, sideRadius);
aWrData.mBuilder.PushBorder(dest, clip, kBackfaceIsVisible, widths,
{sides, 4}, wrRadius);
}
void nsNativeBasicTheme::FillRect(DrawTarget& aDt,
const LayoutDeviceRect& aRect,
const sRGBColor& aColor) {
aDt.FillRect(aRect.ToUnknownRect(), ColorPattern(ToDeviceColor(aColor)));
}
void nsNativeBasicTheme::FillRect(WebRenderBackendData& aWrData,
const LayoutDeviceRect& aRect,
const sRGBColor& aColor) {
const bool kBackfaceIsVisible = true;
auto dest = wr::ToLayoutRect(aRect);
aWrData.mBuilder.PushRect(dest, dest, kBackfaceIsVisible,
wr::ToColorF(ToDeviceColor(aColor)));
}
void nsNativeBasicTheme::PaintRoundedRectWithRadius(
DrawTarget& aDrawTarget, const LayoutDeviceRect& aRect,
const sRGBColor& aBackgroundColor, const sRGBColor& aBorderColor,
CSSCoord aBorderWidth, CSSCoord aRadius, DPIRatio aDpiRatio) {
const LayoutDeviceRect& aClipRect, const sRGBColor& aBackgroundColor,
const sRGBColor& aBorderColor, CSSCoord aBorderWidth, CSSCoord aRadius,
DPIRatio aDpiRatio) {
const LayoutDeviceCoord borderWidth(SnapBorderWidth(aBorderWidth, aDpiRatio));
const bool needsClip = !(aRect == aClipRect);
if (needsClip) {
aDrawTarget.PushClipRect(aClipRect.ToUnknownRect());
}
LayoutDeviceRect rect(aRect);
// Deflate the rect by half the border width, so that the middle of the
@ -631,13 +690,31 @@ void nsNativeBasicTheme::PaintRoundedRectWithRadius(
}
}
RectCornerRadii radii(radius, radius, radius, radius);
RefPtr<Path> roundedRect =
MakePathForRoundedRect(aDrawTarget, rect.ToUnknownRect(), radii);
Maybe<ColorPattern> backgroundPattern;
if (aBackgroundColor.a) {
backgroundPattern.emplace(ToDeviceColor(aBackgroundColor));
}
ColorPattern borderPattern(ToDeviceColor(aBorderColor));
if (radius) {
RectCornerRadii radii(radius, radius, radius, radius);
RefPtr<Path> roundedRect =
MakePathForRoundedRect(aDrawTarget, rect.ToUnknownRect(), radii);
aDrawTarget.Fill(roundedRect, ColorPattern(ToDeviceColor(aBackgroundColor)));
aDrawTarget.Stroke(roundedRect, ColorPattern(ToDeviceColor(aBorderColor)),
StrokeOptions(borderWidth));
if (backgroundPattern) {
aDrawTarget.Fill(roundedRect, *backgroundPattern);
}
aDrawTarget.Stroke(roundedRect, borderPattern, StrokeOptions(borderWidth));
} else {
if (backgroundPattern) {
aDrawTarget.FillRect(rect.ToUnknownRect(), *backgroundPattern);
}
aDrawTarget.StrokeRect(rect.ToUnknownRect(), borderPattern,
StrokeOptions(borderWidth));
}
if (needsClip) {
aDrawTarget.PopClip();
}
}
void nsNativeBasicTheme::PaintCheckboxControl(DrawTarget& aDrawTarget,
@ -800,7 +877,8 @@ void nsNativeBasicTheme::PaintRadioCheckmark(DrawTarget& aDrawTarget,
borderWidth, aDpiRatio);
}
void nsNativeBasicTheme::PaintTextField(DrawTarget& aDrawTarget,
template <typename PaintBackendData>
void nsNativeBasicTheme::PaintTextField(PaintBackendData& aPaintData,
const LayoutDeviceRect& aRect,
const EventStates& aState,
DPIRatio aDpiRatio) {
@ -808,32 +886,34 @@ void nsNativeBasicTheme::PaintTextField(DrawTarget& aDrawTarget,
const CSSCoord radius = 2.0f;
PaintRoundedRectWithRadius(aDrawTarget, aRect, backgroundColor, borderColor,
PaintRoundedRectWithRadius(aPaintData, aRect, backgroundColor, borderColor,
kTextFieldBorderWidth, radius, aDpiRatio);
if (aState.HasState(NS_EVENT_STATE_FOCUSRING)) {
PaintRoundedFocusRect(aDrawTarget, aRect, aDpiRatio, radius,
PaintRoundedFocusRect(aPaintData, aRect, aDpiRatio, radius,
-kTextFieldBorderWidth);
}
}
void nsNativeBasicTheme::PaintListbox(DrawTarget& aDrawTarget,
template <typename PaintBackendData>
void nsNativeBasicTheme::PaintListbox(PaintBackendData& aPaintData,
const LayoutDeviceRect& aRect,
const EventStates& aState,
DPIRatio aDpiRatio) {
const CSSCoord radius = 2.0f;
auto [backgroundColor, borderColor] = ComputeTextfieldColors(aState);
PaintRoundedRectWithRadius(aDrawTarget, aRect, backgroundColor, borderColor,
PaintRoundedRectWithRadius(aPaintData, aRect, backgroundColor, borderColor,
kMenulistBorderWidth, radius, aDpiRatio);
if (aState.HasState(NS_EVENT_STATE_FOCUSRING)) {
PaintRoundedFocusRect(aDrawTarget, aRect, aDpiRatio, radius,
PaintRoundedFocusRect(aPaintData, aRect, aDpiRatio, radius,
-kMenulistBorderWidth);
}
}
void nsNativeBasicTheme::PaintMenulist(DrawTarget& aDrawTarget,
template <typename PaintBackendData>
void nsNativeBasicTheme::PaintMenulist(PaintBackendData& aDrawTarget,
const LayoutDeviceRect& aRect,
const EventStates& aState,
DPIRatio aDpiRatio) {
@ -1017,9 +1097,13 @@ void nsNativeBasicTheme::PaintRange(nsIFrame* aFrame, DrawTarget& aDrawTarget,
}
// TODO: Indeterminate state.
void nsNativeBasicTheme::PaintProgress(
nsIFrame* aFrame, DrawTarget& aDrawTarget, const LayoutDeviceRect& aRect,
const EventStates& aState, DPIRatio aDpiRatio, bool aIsMeter, bool aBar) {
template <typename PaintBackendData>
void nsNativeBasicTheme::PaintProgress(nsIFrame* aFrame,
PaintBackendData& aPaintData,
const LayoutDeviceRect& aRect,
const EventStates& aState,
DPIRatio aDpiRatio, bool aIsMeter,
bool aBar) {
auto [backgroundColor, borderColor] = [&] {
if (aIsMeter) {
return aBar ? ComputeMeterTrackColors() : ComputeMeterchunkColors(aState);
@ -1046,6 +1130,7 @@ void nsNativeBasicTheme::PaintProgress(
}
// This is the progress chunk, clip it to the right amount.
LayoutDeviceRect clipRect = rect;
if (!aBar) {
double position = [&] {
if (aIsMeter) {
@ -1061,7 +1146,6 @@ void nsNativeBasicTheme::PaintProgress(
}
return progress->Value() / progress->Max();
}();
LayoutDeviceRect clipRect = rect;
if (isHorizontal) {
double clipWidth = rect.width * position;
clipRect.width = clipWidth;
@ -1073,94 +1157,141 @@ void nsNativeBasicTheme::PaintProgress(
clipRect.height = clipHeight;
clipRect.y += rect.height - clipHeight;
}
aDrawTarget.PushClipRect(clipRect.ToUnknownRect());
}
PaintRoundedRectWithRadius(aDrawTarget, rect, backgroundColor, borderColor,
borderWidth, radius, aDpiRatio);
if (!aBar) {
aDrawTarget.PopClip();
}
PaintRoundedRectWithRadius(aPaintData, rect, clipRect, backgroundColor,
borderColor, borderWidth, radius, aDpiRatio);
}
void nsNativeBasicTheme::PaintButton(nsIFrame* aFrame, DrawTarget& aDrawTarget,
template <typename PaintBackendData>
void nsNativeBasicTheme::PaintButton(nsIFrame* aFrame,
PaintBackendData& aPaintData,
const LayoutDeviceRect& aRect,
const EventStates& aState,
DPIRatio aDpiRatio) {
const CSSCoord radius = 4.0f;
auto [backgroundColor, borderColor] = ComputeButtonColors(aState, aFrame);
PaintRoundedRectWithRadius(aDrawTarget, aRect, backgroundColor, borderColor,
PaintRoundedRectWithRadius(aPaintData, aRect, backgroundColor, borderColor,
kButtonBorderWidth, radius, aDpiRatio);
if (aState.HasState(NS_EVENT_STATE_FOCUSRING)) {
PaintRoundedFocusRect(aDrawTarget, aRect, aDpiRatio, radius,
PaintRoundedFocusRect(aPaintData, aRect, aDpiRatio, radius,
-kButtonBorderWidth);
}
}
void nsNativeBasicTheme::PaintScrollbarThumb(DrawTarget& aDrawTarget,
template <typename PaintBackendData>
bool nsNativeBasicTheme::DoPaintDefaultScrollbarThumb(
PaintBackendData& aPaintData, const LayoutDeviceRect& aRect,
bool aHorizontal, nsIFrame* aFrame, const ComputedStyle& aStyle,
const EventStates& aElementState, const EventStates& aDocumentState,
DPIRatio aDpiRatio) {
sRGBColor thumbColor =
ComputeScrollbarThumbColor(aFrame, aStyle, aElementState, aDocumentState);
FillRect(aPaintData, aRect, thumbColor);
return true;
}
bool nsNativeBasicTheme::PaintScrollbarThumb(DrawTarget& aDrawTarget,
const LayoutDeviceRect& aRect,
bool aHorizontal, nsIFrame* aFrame,
const ComputedStyle& aStyle,
const EventStates& aElementState,
const EventStates& aDocumentState,
DPIRatio aDpiRatio) {
sRGBColor thumbColor =
ComputeScrollbarThumbColor(aFrame, aStyle, aElementState, aDocumentState);
aDrawTarget.FillRect(aRect.ToUnknownRect(),
ColorPattern(ToDeviceColor(thumbColor)));
return DoPaintDefaultScrollbarThumb(aDrawTarget, aRect, aHorizontal, aFrame,
aStyle, aElementState, aDocumentState,
aDpiRatio);
}
void nsNativeBasicTheme::PaintScrollbarTrack(DrawTarget& aDrawTarget,
bool nsNativeBasicTheme::PaintScrollbarThumb(WebRenderBackendData& aWrData,
const LayoutDeviceRect& aRect,
bool aHorizontal, nsIFrame* aFrame,
const ComputedStyle& aStyle,
const EventStates& aElementState,
const EventStates& aDocumentState,
DPIRatio aDpiRatio) {
// Draw nothing by default. Subclasses can override this.
return DoPaintDefaultScrollbarThumb(aWrData, aRect, aHorizontal, aFrame,
aStyle, aElementState, aDocumentState,
aDpiRatio);
}
void nsNativeBasicTheme::PaintScrollbar(DrawTarget& aDrawTarget,
template <typename PaintBackendData>
bool nsNativeBasicTheme::DoPaintDefaultScrollbar(
PaintBackendData& aPaintData, const LayoutDeviceRect& aRect,
bool aHorizontal, nsIFrame* aFrame, const ComputedStyle& aStyle,
const EventStates& aDocumentState, DPIRatio aDpiRatio) {
auto [scrollbarColor, borderColor] =
ComputeScrollbarColors(aFrame, aStyle, aDocumentState);
FillRect(aPaintData, aRect, scrollbarColor);
// FIXME(heycam): We should probably derive the border color when custom
// scrollbar colors are in use too. But for now, just skip painting it,
// to avoid ugliness.
if (aStyle.StyleUI()->mScrollbarColor.IsAuto()) {
// Draw a 1px-wide line in the top / left of the scrollbar.
LayoutDeviceRect borderRect(aRect);
LayoutDeviceCoord onePx = CSSCoord(1.0f) * aDpiRatio;
if (aHorizontal) {
borderRect.height = onePx;
} else {
borderRect.width = onePx;
}
FillRect(aPaintData, borderRect, borderColor);
}
return true;
}
bool nsNativeBasicTheme::PaintScrollbar(DrawTarget& aDrawTarget,
const LayoutDeviceRect& aRect,
bool aHorizontal, nsIFrame* aFrame,
const ComputedStyle& aStyle,
const EventStates& aDocumentState,
DPIRatio aDpiRatio) {
auto [scrollbarColor, borderColor] =
ComputeScrollbarColors(aFrame, aStyle, aDocumentState);
aDrawTarget.FillRect(aRect.ToUnknownRect(),
ColorPattern(ToDeviceColor(scrollbarColor)));
// FIXME(heycam): We should probably derive the border color when custom
// scrollbar colors are in use too. But for now, just skip painting it,
// to avoid ugliness.
if (aStyle.StyleUI()->mScrollbarColor.IsAuto()) {
RefPtr<PathBuilder> builder = aDrawTarget.CreatePathBuilder();
LayoutDeviceRect strokeRect(aRect);
strokeRect.Deflate(CSSCoord(0.5f) * aDpiRatio);
builder->MoveTo(strokeRect.TopLeft().ToUnknownPoint());
builder->LineTo(
(aHorizontal ? strokeRect.TopRight() : strokeRect.BottomLeft())
.ToUnknownPoint());
RefPtr<Path> path = builder->Finish();
aDrawTarget.Stroke(path, ColorPattern(ToDeviceColor(borderColor)),
StrokeOptions(CSSCoord(1.0f) * aDpiRatio));
}
return DoPaintDefaultScrollbar(aDrawTarget, aRect, aHorizontal, aFrame,
aStyle, aDocumentState, aDpiRatio);
}
void nsNativeBasicTheme::PaintScrollCorner(DrawTarget& aDrawTarget,
bool nsNativeBasicTheme::PaintScrollbar(WebRenderBackendData& aWrData,
const LayoutDeviceRect& aRect,
bool aHorizontal, nsIFrame* aFrame,
const ComputedStyle& aStyle,
const EventStates& aDocumentState,
DPIRatio aDpiRatio) {
return DoPaintDefaultScrollbar(aWrData, aRect, aHorizontal, aFrame, aStyle,
aDocumentState, aDpiRatio);
}
template <typename PaintBackendData>
bool nsNativeBasicTheme::DoPaintDefaultScrollCorner(
PaintBackendData& aPaintData, const LayoutDeviceRect& aRect,
nsIFrame* aFrame, const ComputedStyle& aStyle,
const EventStates& aDocumentState, DPIRatio aDpiRatio) {
auto [scrollbarColor, borderColor] =
ComputeScrollbarColors(aFrame, aStyle, aDocumentState);
Unused << borderColor;
FillRect(aPaintData, aRect, scrollbarColor);
return true;
}
bool nsNativeBasicTheme::PaintScrollCorner(DrawTarget& aDrawTarget,
const LayoutDeviceRect& aRect,
nsIFrame* aFrame,
const ComputedStyle& aStyle,
const EventStates& aDocumentState,
DPIRatio aDpiRatio) {
auto [scrollbarColor, borderColor] =
ComputeScrollbarColors(aFrame, aStyle, aDocumentState);
Unused << borderColor;
aDrawTarget.FillRect(aRect.ToUnknownRect(),
ColorPattern(ToDeviceColor(scrollbarColor)));
return DoPaintDefaultScrollCorner(aDrawTarget, aRect, aFrame, aStyle,
aDocumentState, aDpiRatio);
}
bool nsNativeBasicTheme::PaintScrollCorner(WebRenderBackendData& aWrData,
const LayoutDeviceRect& aRect,
nsIFrame* aFrame,
const ComputedStyle& aStyle,
const EventStates& aDocumentState,
DPIRatio aDpiRatio) {
return DoPaintDefaultScrollCorner(aWrData, aRect, aFrame, aStyle,
aDocumentState, aDpiRatio);
}
void nsNativeBasicTheme::PaintScrollbarButton(
@ -1231,13 +1362,53 @@ nsNativeBasicTheme::DrawWidgetBackground(gfxContext* aContext, nsIFrame* aFrame,
StyleAppearance aAppearance,
const nsRect& aRect,
const nsRect& /* aDirtyRect */) {
DrawTarget& dt = *aContext->GetDrawTarget();
const nscoord twipsPerPixel = aFrame->PresContext()->AppUnitsPerDevPixel();
EventStates eventState = GetContentState(aFrame, aAppearance);
EventStates docState = aFrame->PresContext()->Document()->GetDocumentState();
auto devPxRect = LayoutDeviceRect::FromUnknownRect(
NSRectToSnappedRect(aRect, twipsPerPixel, dt));
if (!DoDrawWidgetBackground(*aContext->GetDrawTarget(), aFrame, aAppearance,
aRect)) {
return NS_ERROR_NOT_IMPLEMENTED;
}
return NS_OK;
}
bool nsNativeBasicTheme::CreateWebRenderCommandsForWidget(
mozilla::wr::DisplayListBuilder& aBuilder,
mozilla::wr::IpcResourceUpdateQueue& aResources,
const mozilla::layers::StackingContextHelper& aSc,
mozilla::layers::RenderRootStateManager* aManager, nsIFrame* aFrame,
StyleAppearance aAppearance, const nsRect& aRect) {
if (!StaticPrefs::widget_non_native_theme_webrender()) {
return false;
}
WebRenderBackendData data{aBuilder, aResources, aSc, aManager};
return DoDrawWidgetBackground(data, aFrame, aAppearance, aRect);
}
static LayoutDeviceRect ToSnappedRect(const nsRect& aRect,
nscoord aTwipsPerPixel, DrawTarget& aDt) {
return LayoutDeviceRect::FromUnknownRect(
NSRectToSnappedRect(aRect, aTwipsPerPixel, aDt));
}
static LayoutDeviceRect ToSnappedRect(
const nsRect& aRect, nscoord aTwipsPerPixel,
nsNativeBasicTheme::WebRenderBackendData& aDt) {
// TODO: Do we need to do any more snapping here?
return LayoutDeviceRect::FromAppUnits(aRect, aTwipsPerPixel);
}
template <typename PaintBackendData>
bool nsNativeBasicTheme::DoDrawWidgetBackground(PaintBackendData& aPaintData,
nsIFrame* aFrame,
StyleAppearance aAppearance,
const nsRect& aRect) {
static_assert(std::is_same_v<PaintBackendData, DrawTarget> ||
std::is_same_v<PaintBackendData, WebRenderBackendData>);
const nsPresContext* pc = aFrame->PresContext();
const nscoord twipsPerPixel = pc->AppUnitsPerDevPixel();
const auto devPxRect = ToSnappedRect(aRect, twipsPerPixel, aPaintData);
const EventStates docState = pc->Document()->GetDocumentState();
EventStates eventState = GetContentState(aFrame, aAppearance);
if (aAppearance == StyleAppearance::MozMenulistArrowButton) {
bool isHTML = IsHTMLContent(aFrame);
nsIFrame* parentFrame = aFrame->GetParent();
@ -1253,127 +1424,157 @@ nsNativeBasicTheme::DrawWidgetBackground(gfxContext* aContext, nsIFrame* aFrame,
// Hack to avoid skia fuzziness: Add a dummy clip if the widget doesn't
// overflow devPxRect.
Maybe<AutoClipRect> maybeClipRect;
if (aAppearance != StyleAppearance::FocusOutline &&
aAppearance != StyleAppearance::Range &&
!eventState.HasState(NS_EVENT_STATE_FOCUSRING)) {
maybeClipRect.emplace(dt, devPxRect);
if constexpr (std::is_same_v<PaintBackendData, DrawTarget>) {
if (aAppearance != StyleAppearance::FocusOutline &&
aAppearance != StyleAppearance::Range &&
!eventState.HasState(NS_EVENT_STATE_FOCUSRING)) {
maybeClipRect.emplace(aPaintData, devPxRect);
}
}
DPIRatio dpiRatio = GetDPIRatio(aFrame, aAppearance);
switch (aAppearance) {
case StyleAppearance::Radio: {
auto rect = FixAspectRatio(devPxRect);
PaintRadioControl(dt, rect, eventState, dpiRatio);
if (IsSelected(aFrame)) {
PaintRadioCheckmark(dt, rect, eventState, dpiRatio);
if constexpr (std::is_same_v<PaintBackendData, WebRenderBackendData>) {
// TODO: Need to figure out how to best draw this using WR.
return false;
} else {
auto rect = FixAspectRatio(devPxRect);
PaintRadioControl(aPaintData, rect, eventState, dpiRatio);
if (IsSelected(aFrame)) {
PaintRadioCheckmark(aPaintData, rect, eventState, dpiRatio);
}
}
break;
}
case StyleAppearance::Checkbox: {
auto rect = FixAspectRatio(devPxRect);
PaintCheckboxControl(dt, rect, eventState, dpiRatio);
if (GetIndeterminate(aFrame)) {
PaintIndeterminateMark(dt, rect, eventState);
} else if (IsChecked(aFrame)) {
PaintCheckMark(dt, rect, eventState);
if constexpr (std::is_same_v<PaintBackendData, WebRenderBackendData>) {
// TODO: Need to figure out how to best draw this using WR.
return false;
} else {
auto rect = FixAspectRatio(devPxRect);
PaintCheckboxControl(aPaintData, rect, eventState, dpiRatio);
if (GetIndeterminate(aFrame)) {
PaintIndeterminateMark(aPaintData, rect, eventState);
} else if (IsChecked(aFrame)) {
PaintCheckMark(aPaintData, rect, eventState);
}
}
break;
}
case StyleAppearance::Textarea:
case StyleAppearance::Textfield:
case StyleAppearance::NumberInput:
PaintTextField(dt, devPxRect, eventState, dpiRatio);
PaintTextField(aPaintData, devPxRect, eventState, dpiRatio);
break;
case StyleAppearance::Listbox:
PaintListbox(dt, devPxRect, eventState, dpiRatio);
PaintListbox(aPaintData, devPxRect, eventState, dpiRatio);
break;
case StyleAppearance::MenulistButton:
case StyleAppearance::Menulist:
PaintMenulist(dt, devPxRect, eventState, dpiRatio);
PaintMenulist(aPaintData, devPxRect, eventState, dpiRatio);
break;
case StyleAppearance::MozMenulistArrowButton:
PaintMenulistArrowButton(aFrame, dt, devPxRect, eventState);
if constexpr (std::is_same_v<PaintBackendData, WebRenderBackendData>) {
// TODO: Need to figure out how to best draw this using WR.
return false;
} else {
PaintMenulistArrowButton(aFrame, aPaintData, devPxRect, eventState);
}
break;
case StyleAppearance::SpinnerUpbutton:
case StyleAppearance::SpinnerDownbutton:
PaintSpinnerButton(aFrame, dt, devPxRect, eventState, aAppearance,
dpiRatio);
if constexpr (std::is_same_v<PaintBackendData, WebRenderBackendData>) {
// TODO: Need to figure out how to best draw this using WR.
return false;
} else {
PaintSpinnerButton(aFrame, aPaintData, devPxRect, eventState,
aAppearance, dpiRatio);
}
break;
case StyleAppearance::Range:
PaintRange(aFrame, dt, devPxRect, eventState, dpiRatio,
IsRangeHorizontal(aFrame));
if constexpr (std::is_same_v<PaintBackendData, WebRenderBackendData>) {
// TODO: Need to figure out how to best draw this using WR.
return false;
} else {
PaintRange(aFrame, aPaintData, devPxRect, eventState, dpiRatio,
IsRangeHorizontal(aFrame));
}
break;
case StyleAppearance::RangeThumb:
// Painted as part of StyleAppearance::Range.
break;
case StyleAppearance::ProgressBar:
PaintProgress(aFrame, dt, devPxRect, eventState, dpiRatio,
/* aMeter = */ false, /* aBar = */ true);
PaintProgress(aFrame, aPaintData, devPxRect, eventState, dpiRatio,
/* aIsMeter = */ false, /* aBar = */ true);
break;
case StyleAppearance::Progresschunk:
if (nsProgressFrame* f = do_QueryFrame(aFrame->GetParent())) {
PaintProgress(f, dt, devPxRect, f->GetContent()->AsElement()->State(),
dpiRatio, /* aMeter = */ false, /* aBar = */ false);
PaintProgress(f, aPaintData, devPxRect,
f->GetContent()->AsElement()->State(), dpiRatio,
/* aIsMeter = */ false, /* aBar = */ false);
}
break;
case StyleAppearance::Meter:
PaintProgress(aFrame, dt, devPxRect, eventState, dpiRatio,
/* aMeter = */ true, /* aBar = */ true);
PaintProgress(aFrame, aPaintData, devPxRect, eventState, dpiRatio,
/* aIsMeter = */ true, /* aBar = */ true);
break;
case StyleAppearance::Meterchunk:
if (nsMeterFrame* f = do_QueryFrame(aFrame->GetParent())) {
PaintProgress(f, dt, devPxRect, f->GetContent()->AsElement()->State(),
dpiRatio, /* aMeter = */ true, /* aBar = */ false);
PaintProgress(f, aPaintData, devPxRect,
f->GetContent()->AsElement()->State(), dpiRatio,
/* aIsMeter = */ true, /* aBar = */ false);
}
break;
case StyleAppearance::ScrollbarthumbHorizontal:
case StyleAppearance::ScrollbarthumbVertical: {
bool isHorizontal =
aAppearance == StyleAppearance::ScrollbarthumbHorizontal;
PaintScrollbarThumb(dt, devPxRect, isHorizontal, aFrame,
*nsLayoutUtils::StyleForScrollbar(aFrame), eventState,
docState, dpiRatio);
break;
return PaintScrollbarThumb(aPaintData, devPxRect, isHorizontal, aFrame,
*nsLayoutUtils::StyleForScrollbar(aFrame),
eventState, docState, dpiRatio);
}
case StyleAppearance::ScrollbartrackHorizontal:
case StyleAppearance::ScrollbartrackVertical: {
bool isHorizontal =
aAppearance == StyleAppearance::ScrollbartrackHorizontal;
PaintScrollbarTrack(dt, devPxRect, isHorizontal, aFrame,
*nsLayoutUtils::StyleForScrollbar(aFrame), docState,
dpiRatio);
break;
return PaintScrollbarTrack(aPaintData, devPxRect, isHorizontal, aFrame,
*nsLayoutUtils::StyleForScrollbar(aFrame),
docState, dpiRatio);
}
case StyleAppearance::ScrollbarHorizontal:
case StyleAppearance::ScrollbarVertical: {
bool isHorizontal = aAppearance == StyleAppearance::ScrollbarHorizontal;
PaintScrollbar(dt, devPxRect, isHorizontal, aFrame,
*nsLayoutUtils::StyleForScrollbar(aFrame), docState,
dpiRatio);
break;
return PaintScrollbar(aPaintData, devPxRect, isHorizontal, aFrame,
*nsLayoutUtils::StyleForScrollbar(aFrame), docState,
dpiRatio);
}
case StyleAppearance::Scrollcorner:
PaintScrollCorner(dt, devPxRect, aFrame,
*nsLayoutUtils::StyleForScrollbar(aFrame), docState,
dpiRatio);
break;
return PaintScrollCorner(aPaintData, devPxRect, aFrame,
*nsLayoutUtils::StyleForScrollbar(aFrame),
docState, dpiRatio);
case StyleAppearance::ScrollbarbuttonUp:
case StyleAppearance::ScrollbarbuttonDown:
case StyleAppearance::ScrollbarbuttonLeft:
case StyleAppearance::ScrollbarbuttonRight:
// For scrollbar-width:thin, we don't display the buttons.
if (!IsScrollbarWidthThin(aFrame)) {
PaintScrollbarButton(dt, aAppearance, devPxRect, aFrame,
*nsLayoutUtils::StyleForScrollbar(aFrame),
eventState, docState, dpiRatio);
if constexpr (std::is_same_v<PaintBackendData, WebRenderBackendData>) {
// TODO: Need to figure out how to best draw this using WR.
return false;
} else {
PaintScrollbarButton(aPaintData, aAppearance, devPxRect, aFrame,
*nsLayoutUtils::StyleForScrollbar(aFrame),
eventState, docState, dpiRatio);
}
}
break;
case StyleAppearance::Button:
PaintButton(aFrame, dt, devPxRect, eventState, dpiRatio);
PaintButton(aFrame, aPaintData, devPxRect, eventState, dpiRatio);
break;
case StyleAppearance::FocusOutline:
PaintAutoStyleOutline(aFrame, dt, devPxRect, dpiRatio);
PaintAutoStyleOutline(aFrame, aPaintData, devPxRect, dpiRatio);
break;
default:
// Various appearance values are used for XUL elements. Normally these
@ -1381,33 +1582,30 @@ nsNativeBasicTheme::DrawWidgetBackground(gfxContext* aContext, nsIFrame* aFrame,
// processes where the native basic theme can be used), but tests are
// run with the remote XUL pref enabled and so we can get in here. So
// we just return an error rather than assert.
return NS_ERROR_NOT_IMPLEMENTED;
return false;
}
return NS_OK;
return true;
}
template <typename PaintBackendData>
void nsNativeBasicTheme::PaintAutoStyleOutline(nsIFrame* aFrame,
DrawTarget& aDt,
PaintBackendData& aPaintData,
const LayoutDeviceRect& aRect,
DPIRatio aDpiRatio) {
auto [innerColor, middleColor, outerColor] = ComputeFocusRectColors();
Unused << middleColor;
Unused << outerColor;
const LayoutDeviceCoord width = kInnerFocusOutlineWidth * aDpiRatio;
const LayoutDeviceCoord halfWidth = width * 0.5f;
LayoutDeviceRect rect(aRect);
// This is equivalent to Inflate(width), to paint the outline outside of
// aRect, then Deflate(width * 0.5), to stroke at the right place.
rect.Inflate(halfWidth);
const LayoutDeviceCoord width = kInnerFocusOutlineWidth * aDpiRatio;
rect.Inflate(width);
nscoord cssRadii[8];
if (!aFrame->GetBorderRadii(cssRadii)) {
return aDt.StrokeRect(rect.ToUnknownRect(),
ColorPattern(ToDeviceColor(innerColor)),
StrokeOptions(width));
return PaintRoundedRectWithRadius(aPaintData, aRect, sRGBColor::White(0.0f),
innerColor, kInnerFocusOutlineWidth,
/* aRadius = */ 0.0f, aDpiRatio);
}
nsPresContext* pc = aFrame->PresContext();
@ -1418,25 +1616,35 @@ void nsNativeBasicTheme::PaintAutoStyleOutline(nsIFrame* aFrame,
nsCSSRendering::ComputePixelRadii(cssRadii, pc->AppUnitsPerDevPixel(),
&innerRadii);
const auto borderColor = ToDeviceColor(innerColor);
// NOTE(emilio): This doesn't use PaintRoundedRectWithRadius because we need
// to support arbitrary radii.
RectCornerRadii outerRadii;
const Float widths[4] = {
halfWidth + devPixelOffset, halfWidth + devPixelOffset,
halfWidth + devPixelOffset, halfWidth + devPixelOffset};
nsCSSBorderRenderer::ComputeOuterRadii(innerRadii, widths, &outerRadii);
RefPtr<Path> path =
MakePathForRoundedRect(aDt, rect.ToUnknownRect(), outerRadii);
aDt.Stroke(path, ColorPattern(ToDeviceColor(innerColor)),
StrokeOptions(width));
}
if constexpr (std::is_same_v<PaintBackendData, WebRenderBackendData>) {
const Float widths[4] = {devPixelOffset, devPixelOffset, devPixelOffset,
devPixelOffset};
nsCSSBorderRenderer::ComputeOuterRadii(innerRadii, widths, &outerRadii);
/*bool
nsNativeBasicTheme::CreateWebRenderCommandsForWidget(mozilla::wr::DisplayListBuilder&
aBuilder, mozilla::wr::IpcResourceUpdateQueue& aResources, const
mozilla::layers::StackingContextHelper& aSc,
mozilla::layers::RenderRootStateManager*
aManager, nsIFrame* aFrame, StyleAppearance aAppearance, const nsRect& aRect)
{
}*/
const auto dest = wr::ToLayoutRect(rect);
const auto side = wr::ToBorderSide(borderColor, StyleBorderStyle::Solid);
const wr::BorderSide sides[4] = {side, side, side, side};
const bool kBackfaceIsVisible = true;
const auto wrWidths = wr::ToBorderWidths(width, width, width, width);
const auto wrRadius = wr::ToBorderRadius(outerRadii);
aPaintData.mBuilder.PushBorder(dest, dest, kBackfaceIsVisible, wrWidths,
{sides, 4}, wrRadius);
} else {
const LayoutDeviceCoord halfWidth = width * 0.5f;
rect.Deflate(halfWidth);
const Float widths[4] = {
halfWidth + devPixelOffset, halfWidth + devPixelOffset,
halfWidth + devPixelOffset, halfWidth + devPixelOffset};
nsCSSBorderRenderer::ComputeOuterRadii(innerRadii, widths, &outerRadii);
RefPtr<Path> path =
MakePathForRoundedRect(aPaintData, rect.ToUnknownRect(), outerRadii);
aPaintData.Stroke(path, ColorPattern(borderColor), StrokeOptions(width));
}
}
LayoutDeviceIntMargin nsNativeBasicTheme::GetWidgetBorder(
nsDeviceContext* aContext, nsIFrame* aFrame, StyleAppearance aAppearance) {

Просмотреть файл

@ -133,12 +133,29 @@ class nsNativeBasicTheme : protected nsNativeTheme, public nsITheme {
NS_IMETHOD DrawWidgetBackground(gfxContext* aContext, nsIFrame*,
StyleAppearance, const nsRect& aRect,
const nsRect& aDirtyRect) override;
/*bool CreateWebRenderCommandsForWidget(mozilla::wr::DisplayListBuilder&
aBuilder, mozilla::wr::IpcResourceUpdateQueue& aResources, const
mozilla::layers::StackingContextHelper& aSc,
mozilla::layers::RenderRootStateManager*
aManager, nsIFrame* aFrame, StyleAppearance aAppearance, const nsRect&
aRect) override;*/
struct WebRenderBackendData {
mozilla::wr::DisplayListBuilder& mBuilder;
mozilla::wr::IpcResourceUpdateQueue& mResources;
const mozilla::layers::StackingContextHelper& mSc;
mozilla::layers::RenderRootStateManager* mManager;
};
bool CreateWebRenderCommandsForWidget(
mozilla::wr::DisplayListBuilder& aBuilder,
mozilla::wr::IpcResourceUpdateQueue& aResources,
const mozilla::layers::StackingContextHelper& aSc,
mozilla::layers::RenderRootStateManager* aManager, nsIFrame*,
StyleAppearance, const nsRect& aRect) override;
// PaintBackendData will be either a DrawTarget, or a WebRenderBackendData.
//
// The return value represents whether the widget could be painted with the
// given back-end.
template <typename PaintBackendData>
bool DoDrawWidgetBackground(PaintBackendData&, nsIFrame*, StyleAppearance,
const nsRect& aRect);
[[nodiscard]] LayoutDeviceIntMargin GetWidgetBorder(nsDeviceContext* aContext,
nsIFrame*,
StyleAppearance) override;
@ -215,16 +232,42 @@ class nsNativeBasicTheme : protected nsNativeTheme, public nsITheme {
nsIFrame*, StyleAppearance, const ComputedStyle&,
const EventStates& aElementState, const EventStates& aDocumentState);
void PaintRoundedFocusRect(DrawTarget&, const LayoutDeviceRect&, DPIRatio,
CSSCoord aRadius, CSSCoord aOffset);
void PaintAutoStyleOutline(nsIFrame*, DrawTarget&, const LayoutDeviceRect&,
DPIRatio);
void PaintRoundedRectWithRadius(DrawTarget& aDrawTarget,
const LayoutDeviceRect&,
const sRGBColor& aBackgroundColor,
const sRGBColor& aBorderColor,
CSSCoord aBorderWidth, CSSCoord aRadius,
DPIRatio);
template <typename PaintBackendData>
void PaintRoundedFocusRect(PaintBackendData&, const LayoutDeviceRect&,
DPIRatio, CSSCoord aRadius, CSSCoord aOffset);
template <typename PaintBackendData>
void PaintAutoStyleOutline(nsIFrame*, PaintBackendData&,
const LayoutDeviceRect&, DPIRatio);
static void PaintRoundedRectWithRadius(DrawTarget&,
const LayoutDeviceRect& aRect,
const LayoutDeviceRect& aClipRect,
const sRGBColor& aBackgroundColor,
const sRGBColor& aBorderColor,
CSSCoord aBorderWidth,
CSSCoord aRadius, DPIRatio);
static void PaintRoundedRectWithRadius(WebRenderBackendData&,
const LayoutDeviceRect& aRect,
const LayoutDeviceRect& aClipRect,
const sRGBColor& aBackgroundColor,
const sRGBColor& aBorderColor,
CSSCoord aBorderWidth,
CSSCoord aRadius, DPIRatio);
template <typename PaintBackendData>
static void PaintRoundedRectWithRadius(PaintBackendData& aData,
const LayoutDeviceRect& aRect,
const sRGBColor& aBackgroundColor,
const sRGBColor& aBorderColor,
CSSCoord aBorderWidth,
CSSCoord aRadius, DPIRatio aDpiRatio) {
PaintRoundedRectWithRadius(aData, aRect, aRect, aBackgroundColor,
aBorderColor, aBorderWidth, aRadius, aDpiRatio);
}
static void FillRect(DrawTarget&, const LayoutDeviceRect&, const sRGBColor&);
static void FillRect(WebRenderBackendData&, const LayoutDeviceRect&,
const sRGBColor&);
void PaintCheckboxControl(DrawTarget& aDrawTarget, const LayoutDeviceRect&,
const EventStates&, DPIRatio);
void PaintCheckMark(DrawTarget&, const LayoutDeviceRect&, const EventStates&);
@ -241,12 +284,15 @@ class nsNativeBasicTheme : protected nsNativeTheme, public nsITheme {
const EventStates&, DPIRatio);
void PaintRadioCheckmark(DrawTarget&, const LayoutDeviceRect&,
const EventStates&, DPIRatio);
void PaintTextField(DrawTarget&, const LayoutDeviceRect&, const EventStates&,
DPIRatio);
void PaintListbox(DrawTarget&, const LayoutDeviceRect&, const EventStates&,
DPIRatio);
void PaintMenulist(DrawTarget&, const LayoutDeviceRect&, const EventStates&,
DPIRatio);
template <typename PaintBackendData>
void PaintTextField(PaintBackendData&, const LayoutDeviceRect&,
const EventStates&, DPIRatio);
template <typename PaintBackendData>
void PaintListbox(PaintBackendData&, const LayoutDeviceRect&,
const EventStates&, DPIRatio);
template <typename PaintBackendData>
void PaintMenulist(PaintBackendData&, const LayoutDeviceRect&,
const EventStates&, DPIRatio);
void PaintArrow(DrawTarget&, const LayoutDeviceRect&,
const float aArrowPolygonX[], const float aArrowPolygonY[],
const int32_t aArrowNumPoints, const sRGBColor aFillColor);
@ -256,33 +302,77 @@ class nsNativeBasicTheme : protected nsNativeTheme, public nsITheme {
const EventStates&, StyleAppearance, DPIRatio);
void PaintRange(nsIFrame*, DrawTarget&, const LayoutDeviceRect&,
const EventStates&, DPIRatio, bool aHorizontal);
void PaintProgress(nsIFrame*, DrawTarget&, const LayoutDeviceRect&,
template <typename PaintBackendData>
void PaintProgress(nsIFrame*, PaintBackendData&, const LayoutDeviceRect&,
const EventStates&, DPIRatio, bool aIsMeter, bool aBar);
void PaintButton(nsIFrame*, DrawTarget&, const LayoutDeviceRect&,
template <typename PaintBackendData>
void PaintButton(nsIFrame*, PaintBackendData&, const LayoutDeviceRect&,
const EventStates&, DPIRatio);
virtual void PaintScrollbarThumb(DrawTarget&, const LayoutDeviceRect&,
void PaintScrollbarButton(DrawTarget&, StyleAppearance,
const LayoutDeviceRect&, nsIFrame*,
const ComputedStyle&,
const EventStates& aElementState,
const EventStates& aDocumentState, DPIRatio);
virtual bool PaintScrollbarThumb(DrawTarget&, const LayoutDeviceRect&,
bool aHorizontal, nsIFrame*,
const ComputedStyle&,
const EventStates& aElementState,
const EventStates& aDocumentState, DPIRatio);
virtual void PaintScrollbar(DrawTarget&, const LayoutDeviceRect&,
bool aHorizontal, nsIFrame*, const ComputedStyle&,
const EventStates& aDocumentState, DPIRatio);
virtual void PaintScrollbarTrack(DrawTarget&, const LayoutDeviceRect&,
bool aHorizontal, nsIFrame*,
const ComputedStyle&,
virtual bool PaintScrollbarThumb(WebRenderBackendData&,
const LayoutDeviceRect&, bool aHorizontal,
nsIFrame*, const ComputedStyle&,
const EventStates& aElementState,
const EventStates& aDocumentState, DPIRatio);
virtual void PaintScrollCorner(DrawTarget&, const LayoutDeviceRect&,
nsIFrame*, const ComputedStyle&,
const EventStates& aDocumentState, DPIRatio);
virtual void PaintScrollbarButton(DrawTarget&, StyleAppearance,
const LayoutDeviceRect&, nsIFrame*,
template <typename PaintBackendData>
bool DoPaintDefaultScrollbarThumb(PaintBackendData&, const LayoutDeviceRect&,
bool aHorizontal, nsIFrame*,
const ComputedStyle&,
const EventStates& aElementState,
const EventStates& aDocumentState,
DPIRatio);
virtual bool PaintScrollbar(DrawTarget&, const LayoutDeviceRect&,
bool aHorizontal, nsIFrame*, const ComputedStyle&,
const EventStates& aDocumentState, DPIRatio);
virtual bool PaintScrollbar(WebRenderBackendData&, const LayoutDeviceRect&,
bool aHorizontal, nsIFrame*, const ComputedStyle&,
const EventStates& aDocumentState, DPIRatio);
template <typename PaintBackendData>
bool DoPaintDefaultScrollbar(PaintBackendData&, const LayoutDeviceRect&,
bool aHorizontal, nsIFrame*,
const ComputedStyle&,
const EventStates& aDocumentState, DPIRatio);
virtual bool PaintScrollbarTrack(DrawTarget&, const LayoutDeviceRect&,
bool aHorizontal, nsIFrame*,
const ComputedStyle&,
const EventStates& aDocumentState,
DPIRatio) {
// Draw nothing by default. Subclasses can override this.
return true;
}
virtual bool PaintScrollbarTrack(WebRenderBackendData&,
const LayoutDeviceRect&, bool aHorizontal,
nsIFrame*, const ComputedStyle&,
const EventStates& aDocumentState,
DPIRatio) {
// Draw nothing by default. Subclasses can override this.
return true;
}
virtual bool PaintScrollCorner(DrawTarget&, const LayoutDeviceRect&,
nsIFrame*, const ComputedStyle&,
const EventStates& aDocumentState, DPIRatio);
virtual bool PaintScrollCorner(WebRenderBackendData&, const LayoutDeviceRect&,
nsIFrame*, const ComputedStyle&,
const EventStates& aDocumentState, DPIRatio);
template <typename PaintBackendData>
bool DoPaintDefaultScrollCorner(PaintBackendData&, const LayoutDeviceRect&,
nsIFrame*, const ComputedStyle&,
const EventStates& aDocumentState, DPIRatio);
static sRGBColor sAccentColor;
static sRGBColor sAccentColorForeground;

Просмотреть файл

@ -1,6 +1,6 @@
== progressbar-fallback-default-style.html progressbar-fallback-default-style-ref.html
fuzzy-if(Android,0-17,0-1120) fuzzy-if(webrender,0-8,0-480) fuzzy-if(!nativeThemePref,0-30,0-67) == meter-native-style.html meter-native-style-ref.html
skip-if(!cocoaWidget&&nativeThemePref) fuzzy-if(webrender&&!nativeThemePref,0-11,0-310) fuzzy-if(!webrender&&!nativeThemePref,0-4,0-131) == meter-vertical-native-style.html meter-vertical-native-style-ref.html # dithering
skip-if(!cocoaWidget&&nativeThemePref) fuzzy-if(webrender&&!nativeThemePref,0-11,0-310) fuzzy-if(!webrender&&!nativeThemePref,0-4,0-174) == meter-vertical-native-style.html meter-vertical-native-style-ref.html # dithering
== meter-fallback-default-style.html meter-fallback-default-style-ref.html
load 664925.xhtml
pref(apz.allow_zooming,true) pref(ui.useOverlayScrollbars,0) skip-if(!cocoaWidget) != scaled-scrollbar.html about:blank