are svg rendering instructions cached in Chrome?

65 views
Skip to first unread message

sha...@infograph.com

unread,
Nov 24, 2018, 12:47:22 AM11/24/18
to skia-discuss

I know you guys are not in charge of this stuff, but you probably know the answer.  Can you verify or debunk the following text?:


I bet browsers implement svg as a series of rendering instructions stored on the video adapter, under the covers. Graphics APIs provide ways of doing this.  OpenGL calls it a display list. Skia calls it an SkPicture.  When asked to render, if nothing has changed, the browser can just call a command that says “draw display list 52 using this [matrix]”.  Instead of parsing the svg data every time it generates a render for a canvas or div. Then the browser probably listens for when the svg data is altered. If that happens, then it re-parses the svg data and re-creates the display list.  I bet they even keep those display lists around, if the svg is destroyed.  In case it comes back a few seconds later because the user scrolled back.  Then they could just say “oh I have that right here. Display list 52.”  If the svg is not loaded in a certain amount of time, or if they are running low on memory, they might flush out those unused display lists they were caching.

Hal Canary

unread,
Nov 24, 2018, 12:15:03 PM11/24/18
to skia-d...@googlegroups.com
Kind of. 

To be clear, the GPU driver knows nothing about the SkPicture or other display list data structures. What may be cached on the GPU are textures, vertex arrays, and shader programs. A program might cache the output of a display list in a texture. 

Browsers and similar programs usually create an intermediate data structure called the DOM (document object model) which can be modified in place (e.g. by javascript or some animation system). The browser might cache the SkPicture associated with a particular node in the DOM and only recreate it when the node or any of its decendants changes. Or it could cache a texture in the GPU instead. Or it could render the entire document into tiles and refresh only the tiles associated with changing nodes.

I actually don't know how Skia's GPU backend caches objects (I don't work on that part of Skia) or how browsers work these days. I do know that Chromium has a bunch of documentation, some of which might be outdated. See https://www.chromium.org/developers/the-rendering-critical-path for example.

On Sat, Nov 24, 2018, 12:47 AM <sha...@infograph.com wrote:

I know you guys are not in charge of this stuff, but you probably know the answer.  Can you verify or debunk the following text?:


I bet browsers implement svg as a series of rendering instructions stored on the video adapter, under the covers. Graphics APIs provide ways of doing this.  OpenGL calls it a display list. Skia calls it an SkPicture.  When asked to render, if nothing has changed, the browser can just call a command that says “draw display list 52 using this [matrix]”.  Instead of parsing the svg data every time it generates a render for a canvas or div. Then the browser probably listens for when the svg data is altered. If that happens, then it re-parses the svg data and re-creates the display list.  I bet they even keep those display lists around, if the svg is destroyed.  In case it comes back a few seconds later because the user scrolled back.  Then they could just say “oh I have that right here. Display list 52.”  If the svg is not loaded in a certain amount of time, or if they are running low on memory, they might flush out those unused display lists they were caching.

--
You received this message because you are subscribed to the Google Groups "skia-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to skia-discuss...@googlegroups.com.
To post to this group, send email to skia-d...@googlegroups.com.
Visit this group at https://groups.google.com/group/skia-discuss.
For more options, visit https://groups.google.com/d/optout.

sha...@infograph.com

unread,
Nov 24, 2018, 3:47:30 PM11/24/18
to skia-discuss
Thanks for the link.  Very interesting.   What do you think about the caching of things discarded, in case they come back?

Florin Malita

unread,
Nov 24, 2018, 5:51:52 PM11/24/18
to skia-d...@googlegroups.com
On Sat, Nov 24, 2018 at 3:47 PM <sha...@infograph.com> wrote:
Thanks for the link.  Very interesting.   What do you think about the caching of things discarded, in case they come back?

(speaking about Chromium here, but other browsers share this architecture to various extents)

It's easier to conceptualize, but there is nothing special about SVG content vs. regular web content.  You can think of the whole rendering pipeline as a multi-level cache:

HTML/CSS/resources -> DOM tree -> layout tree -> display lists + property trees -> [Skia] -> rasterized tiles

Each stage is caching data derived from previous stages, and gets (minimally) invalidated when upstream content changes.  The display list mechanism you are referencing comes into play when passing draw commands from Blink's layout tree to the Chrome Compositor (CC).  As Hal mentioned, it's a private in-RAM representation and not something we pass further down to the GPU -- instead, these display lists (paint_op_buffers in the current "Slimming Paint" incarnation -- see [1]) are converted to Skia draw commands on the fly, when they need to be rasterized.

Other than the resource cache (which essentially caches web resources indefinitely/on a budget), there is very little speculative retention going on: all cached entries are strongly owned by upstream objects and get purged when the owning object goes away.  So when an SVG/HTML DOM node goes away, all the derived display lists are also discarded.

To your example, in order to know if display list 52 is suitable for a newly added layout tree object, we would have to actually invoke the object's display list builder and then compare its display list to display list 52 -- which defeats any benefit to keeping DL52 around (since it resides in RAM and not in GPU memory).  One can imagine ways to hash layout objects and key the cached DLs, but building them when needed is not particularly expensive, and it is unclear whether the pattern of re-creating identical nodes is common in practice.   The pipeline is currently optimized for long-lived nodes with potentially dynamic/animated properties (which yield different DLs on each invalidation).

There's some form of speculative caching going on with rasterized tiles: CC caches tiles beyond the immediately visible viewport (also tries to predict scrolling and attempts to pre-rasterize as needed).  But it's prolly more correct to describe the tile cache as a cache with entries strongly-owned by an extended viewport rather than a speculative/keep-around-in-case-we-need-it-later cache.


Shawn Riordan

unread,
Nov 24, 2018, 6:58:12 PM11/24/18
to skia-discuss
Thanks!  That was very informative.

The reason I ask these questions is:  We are converting our document viewer html app from using SVG files for each page, to using skia as a webassembly module. Which would draw each page.  (Ideally using a SkPicture)  In the React - DOM, each page is a react component with a canvas.  The data for a page can be anything.  Text, vector art, raster art. It could be sparse or it could be dense with stuff.  Potentially heavyweight resources.

I was arguing to my team that we should cache each page's SkPicture and the data that built it.  So that if you scroll down to page 3 and the page 2 react component is unmounted and destroyed, we would be able to be back in business really quickly if the user scrolled back up to view page 2 again.  The new component would not need to download or build anything for page 2.  

Others on my dev team want to not cache everything.  Preferring a more stateless model.  (even though we are already caching font glyphs and some images and therefore cannot be purely stateless)

I am a native (C/C++) programmer, so it kind of goes against my instincts to think that way.  It sounds like it would be janky and wasteful.
Reply all
Reply to author
Forward
0 new messages