Webrender: regression: low FPS on https://servo.org/bhtml-newtab/webrender-demos/moire.html

Created on 30 Apr 2018  路  4Comments  路  Source: servo/webrender

URL: https://servo.org/bhtml-newtab/webrender-demos/moire.html
Bugzilla: https://bugzilla.mozilla.org/show_bug.cgi?id=1457683

There are multiple regressions.
2018-02-01 ~60 fps
2018-03-01 ~45 fps
2018-04-27 ~28 fps

https://bugzilla.mozilla.org/show_bug.cgi?id=1457683#c6 summarized:

First regression:
Press F11. good = ~60 fps. bad = 34-56 fps
2018-02-20 https://github.com/servo/webrender/compare/4af31b8aa79d5a1f3c0242dea6be4876c71075c5...e8d2ffb404a85651fe08a6d09abbece9bd2b9182

Second regression:
Press F11. good = 34-56 fps. bad = unpleasant coil whine and 25-31 fps.
2018-04-09 https://github.com/servo/webrender/compare/a05186dc536d68efafcf832f38303162bf552897...df73569c5a9fba35a7c268d176a3eb0d6c52b249

performance bugzilled

All 4 comments

I looked at a GPU profile and was horrified by the amount of pixel shading work we do here:

  • the case features a variety of rounded cornered clips of different radiuses. We end up allocating 60 slices of the alpha target (2K by 2K each) just to fill them all in (every frame!).
  • those are then rendered as 3040 instances of one giant "B_Solid" call in the transparency pass (with blending, since the clip mask is used).

It does strike me as one of the cases where the general approach we take with WR shows it's weak side. However, we might be able to come with a few tricks to address it.

Here is one trick I can think of. When the rounded corner radius is the same for all 4 corners, we should be able to only have a single instance of that corner as the clip mask. The other corners can just re-use the same UV rect by mirroring the coordinates. E.g. if we hit the case, we render the top left corner into x0,y0 - x1,y1 region of the clip mask, and then the other corners can use:

  1. x1,y0 - x0,y1
  2. x1,y1 - x0,y0
  3. x0,y1 - x1,y0

Another thing that would help here is not rebuilding the clip masks each frame and instead cache them. This wouldn't help the general case where all the radiuses are animated.

@glennw if that sounds reasonable to you, I'll create the respective issues.

Yep, those sound good. I think the biggest win (which @pcwalton mentioned to me) is that we should tessellate the borders we are drawing when they have very big radii, to reduce overdraw. Once I have ported borders to brushes, I think it's fairly straightforward to use the segment infrastructure to break up very large border radii rects into small, tesselated segments.

Didn't want to add a new issue, so just commenting on this for now.

On Windows 10, Nvidia GTX 1070 and latest drivers (416.34):

  1. Moire demo is still seriously stuttering on color transitions (otherwise it's almost fluid).
    https://servo.org/bhtml-newtab/webrender-demos/moire.html
  2. The transparent-rects demo shows corruptions while initially loading it (image). It's strange that sometimes after refreshing, or keeping it open for some time, it displays them correctly:
    https://servo.org/bhtml-newtab/webrender-demos/transparent_rects.html
  3. Hard to explain, but the spheres demo is sometimes "jiggling" (left and right) on the X axis, instead of smoothly rotating counter-clockwise
    https://servo.org/bhtml-newtab/webrender-demos/spheres.html

On macOS Mojave, Macbook Pro 15" with Radeon 560X I'm not able to replicate the second problem, but the 1. and 3. remain (and performance is considerably worse)

Looking at the first case again - our behavior has changed (no clip masks, just cached images now), but in general we still suffer from the same thing: too much pixels to process. And the very same optimization (for symmetry) could apply.
There is probably other things we can do to help this, but I wouldn't call it high priority - the case is super artificial.

Was this page helpful?
0 / 5 - 0 ratings