Gecko:OffMainThreadPainting: Difference between revisions

m
No edit summary
 
(3 intermediate revisions by one other user not shown)
Line 2: Line 2:


Painting is slow. On complex, dynamic pages, we spend a large amount of CPU time rasterizing the page which blocks the main thread from being responsive. Ongoing work to reduce the amount of painting done (DLBI), and improve the speed of painting are helping with this, but being able to offload the entirety of this work to another thread will be a significant gain.
Painting is slow. On complex, dynamic pages, we spend a large amount of CPU time rasterizing the page which blocks the main thread from being responsive. Ongoing work to reduce the amount of painting done (DLBI), and improve the speed of painting are helping with this, but being able to offload the entirety of this work to another thread will be a significant gain.
Also, on platforms where we have asynchronous scrolling (Android and B2G currently), the scrolling is limited to within a prerendered viewport area. When scrolling goes outside of this area, the main-thread is required to draw the new content. If this takes too long, we are forced to checkerboard until the content is available. Being able to render newly scrolled in content, without accessing the main thread, would reduce the chance of users seeing checkerboarding.


=Goals=
=Goals=
Line 7: Line 9:
* Improve painting throughput performance (increase frames per second drawn to the screen)
* Improve painting throughput performance (increase frames per second drawn to the screen)
* Reduce the load on the main thread to improve responsiveness and reduce jank.
* Reduce the load on the main thread to improve responsiveness and reduce jank.
* Reduce redraw latency when scrolling


=Proposed solution=
=Proposed solution=


Modify our current display item list items to be entirely self contained, such that they only access main-thread data during construction (or an explicit finalization pass). We can then pass the entire tree across to the painting thread to do all visibility analysis, layer building and ThebesLayer painting. This would require that ownership and access to FrameLayerBuilder and Layers become painting-thread only, instead of main-thread only as they currently. Compositing then happens on yet another thread via off-main-thread compositing (OMTC - Bug 598873).
Modify our current display item list items to be entirely self contained, such that they only access main-thread data during construction (or an explicit finalization pass). We can then pass the entire tree across to the painting thread to do all visibility analysis, layer building and ThebesLayer painting. This would require that ownership and access to FrameLayerBuilder and Layers become painting-thread only, instead of main-thread only as they currently. Compositing then happens on yet another thread via off-main-thread compositing (OMTC - Bug 598873).
The painting thread could use worker threads for the actual rasterization pass, so that we can have multiple paints being done in parallel.
We can also start retaining the display item list on the painting thread. This, once it is integrated with async scrolling (APZC) would let us rasterize new content during content without accessing the main-thread. We could build a layer tree for the entire page, but only rasterize content that falls within the prerendered viewport. When async scrolling attempts to scroll outside of the prerendered area, we would notify the painting thread of the new desired prerendered area and rasterize it.


=Alternatives=
=Alternatives=


Chrome's proposed solution to the same problem (https://sites.google.com/a/chromium.org/dev/developers/design-documents/impl-side-painting) is lower level. Rather than using high-level drawable objects (display items), they plan to serialize a stream of skia drawing commands. This lets them store the entirety of a layer's content (within reason), not just restricted to areas that are currently visible. They can then rasterize newly exposed content during scrolling without accessing the main thread, and without the large memory trade-off of pre-rendering areas that are expected to be scrolled into view. They can also dynamically re-rasterize areas of layers at a new resolution or quality setting without requiring main thread access.
Chrome's proposed solution to the same problem (https://sites.google.com/a/chromium.org/dev/developers/design-documents/impl-side-painting) is lower level. Rather than using high-level drawable objects (display items), they plan to serialize a stream of skia drawing commands. This lets them store the entirety of a layer's content (within reason), not just restricted to areas that are currently visible. They can then rasterize newly exposed content during scrolling without accessing the main thread, and without the large memory trade-off of pre-rendering areas that are expected to be scrolled into view. They can also dynamically re-rasterize areas of layers at a new resolution or quality setting without requiring main thread access.
This solution probably will give better results (less checkerboarding and/or jank) when fling scrolling a static page, but doesn't benefit as much for dynamic pages that require modifications to the drawing stream.


=Plan=
=Plan=
Line 25: Line 30:
* Start porting the remainder of the display item types to not require main-thread access
* Start porting the remainder of the display item types to not require main-thread access
** Each display item should be a fairly self contained chunk of work, so we can parallelize this stage well
** Each display item should be a fairly self contained chunk of work, so we can parallelize this stage well
* Add display item caching for fully asynchronous scrolling
* Investigate having multiple rendering threads


=Prerequisites=
=Prerequisites=
Line 71: Line 78:


-moz-element
-moz-element
=Further Work=
Retaining the display list on the painting thread, and adding interactions with the asynchronous scrolling code. This would let us render new content as we scroll (without interacting with the main thread) and give us parity with Chrome's approach during scrolling.
Confirmed users
586

edits