WebGL flat interpolation memory issue

123 views
Skip to first unread message

Cristi

unread,
Feb 12, 2024, 9:46:47 AM2/12/24
to skia-discuss
Hi,
While investigating a memory usage issue with our web app, WebGL2 + Skia 118, on Safari/Webkit, I've found out that Angle, used by Webkit for WebGL to platform graphics translation, was allocating a lot of buffers (20k each 65KiB) for drawElements to handle difference of provoking vertex between GL and Metal. Angle code `ProvokingVertexHelper::preconditionIndexBuffer`.

To workaround this issue I was looking at 2 possible options:
  1. Use WEBGL_provoking_vertex extension to switch to first vertex
  2. Patch Skia and expose fPreferFlatInterpolation in GrOptions to allow to override GrShaderCaps. Skia already sets this to false if it detects GL Angle with D3D or Metal backend but for WebGL it defaults to true.
For 1. does Skia depend on last vertex being used or is there a way to tell Skia that first vertex is used for flat interpolation? Is there any performance caveats? I didn't see any at glance
For 2. Is this something that Skia might allow to override via options? or maybe Skia can detect WebGL with non GL backend and disfavor interpolation.

John Stiles

unread,
Feb 12, 2024, 9:53:39 AM2/12/24
to skia-d...@googlegroups.com
A patch that sets `fPreferFlatInterpolation` to true sounds like something that we would be happy to accept, if it doesn't lead to regressions somewhere else. If we are accidentally hitting a slow path in WebGL that we can easily avoid, we should change it.

--
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 view this discussion on the web visit https://groups.google.com/d/msgid/skia-discuss/5fc29aaa-f539-4198-af0f-ed84eeb05b59n%40googlegroups.com.

Cristi Alex

unread,
Feb 13, 2024, 8:37:57 AM2/13/24
to skia-d...@googlegroups.com
I think there is a misunderstanding.
The issue is that `fPreferFlatInterpolation` is true already for WebGL and my suggestion was expose in Skia the option to override that via GrOptions or have Skia default to false for WebGL (or only if it can detect that non GL backend is used). I think defaulting to false is the best option here for now since Skia already defaults to false for GL Angle renderer with Metal/D3D backend. For Angle VK I assume Angle changes VK provoking vertex to match GL
Changing the provoking vertex in WebGL to first will be preferred where possible but couldn't find how to tell Skia that WebGL uses first instead of last vertex and don't know if Skia depends on last vertex being used in its vertex shaders.

Here are results of Safari GPU memory usage from our web app. At most 125 drawElements, YUV SkImage, calls per frame at 60FPS for 3+ seconds
With prefer flat interpolation true, default from Skia. Start 200MB End 950MB
SafariGPUMemoryIncreaseWithFlatInterpolation.png
With prefer flat interpolation false, Start 100MB End 200MB
SafariGPUMemoryWithoutFlatInterpolation.png
With WebGL provoking verte changed to first.  Start 110MB End ~200MB
 SafariGPUMemoryWithWebGLFirstVertexChange.png
And Chrome with prefer flat interpolation. Start 100MB End 340MB
ChromeGPUMemoryIncreaseWithFlatInterpolation.png.png
On Chrome there are only 120 buffers allocated even though it also uses Angle with Metal backend. We are still investigating why there is such a difference and think it's related to when the command buffer completes and allows Angle to reuse the buffers. On Safari it ends up allocating 20k before it tries to release, for reuse, the buffers.

You received this message because you are subscribed to a topic in the Google Groups "skia-discuss" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/skia-discuss/52QazX8pNC0/unsubscribe.
To unsubscribe from this group and all its topics, send an email to skia-discuss...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/skia-discuss/CANBPXuBmPXtX8Gua81BtMjCHvqO0AUrGJ%3DWw5mxpNat99WeSbQ%40mail.gmail.com.

Greg Daniel

unread,
Feb 13, 2024, 9:19:46 AM2/13/24
to skia-d...@googlegroups.com
Exposing the flag in GrContextOptions seems fine to me.

On a meta level, this is a very interesting problem that I hadn't thought about with the layering of Angle for things like WebGL. AFAIK Skia has no idea that Angle is being used under the hood and thus doesn't know the real things it is sitting on top of. I wouldn't be surprised if there aren't other use cases besides flat where we will now make very unoptimized decisions.

Greg Daniel

unread,
Feb 13, 2024, 9:46:05 AM2/13/24
to skia-d...@googlegroups.com
So after some more investigation the situation is a little intriguing as to what is expressed by the GL strings with WebGL on Mac.

Chrome:
Unmasked Vendor:
Google Inc. (Apple)
Unmasked Renderer:
ANGLE (Apple, ANGLE Metal Renderer: Apple M2 Max, Unspecified Version)

Safari:
Unmasked Vendor:
Apple Inc.
Unmasked Renderer:
Apple GPU

So webkit is not exposing the fact that the Renderer is using Angle under the hood. Some various options:
1) In an ideal world I think we file a bug with Webkit to say expose this like Chrome, but my guess is that this is intentional (possibly because they have either additional layers or a modified Angle and they consider it an implementation detail).
2) If we can figure out if the "Apple GPU" string is only used as the Renderer when going through WebGL/Angle we could use that as a flag to know Angle is being used and thus set all our Caps correctly.
3) In this specific case, flat interpolation is probably providing pretty minimal benefit even when it works correctly in WebGL. We could just disable the use of it entirely in WebGL
4) Expose a GrContextOption to have a client disable flat interpolation. This approach is less appealing the more I think about it because it requires the client to need to know underlying implementation details of both Skia and how the drivers are implemented under the hood.

IMO I think 2) is an interesting thing to investigate if someone has time to figure out all the Renderer flags Apple uses for various implementations. Otherwise 3) is a more client friendly option with very minimal performance impact when things were working correctly.

Greg

Cristi

unread,
Feb 13, 2024, 10:36:59 AM2/13/24
to skia-discuss
Webkit intentionally masks Renderer/Vendor/Shader Lang even for debug_renderer_info. It is an internal setting `maskWebGLStringsEnabled` which is enabled by default and used an all platforms except iOS where it always masks.
Similarly there is a setting in Webkit for using metal backend in Angle,  `webGLUsingMetal` ("Use the Metal backend for ANGLE") which is enabled by default if `WEBGL_COMPATIBLE_METAL` build flag is enabled which it is by default. Metal is used only on Cocoa platform (i.e. I think it includes most if not all OS from Apple). For other platforms if who is integrating Webkit doesn't change `maskWebGLStringsEnabled` then it seems it could return "Apple Inc." and "Apple GPU".  
Webkit commit that introduced masking: https://commits.webkit.org/220765@main 

Greg Is there a way to tell Skia that WebGL is using provoking vertex first if the extension for that is available and the app is using it? From what I saw the extension is only available if the web platform thinks it helps
https://registry.khronos.org/webgl/extensions/WEBGL_provoking_vertex/ 

Greg Daniel

unread,
Feb 13, 2024, 1:01:05 PM2/13/24
to skia-d...@googlegroups.com
We certainly could add support for the provoking vertex extension. However, it does involve a little bit of work to make sure it is always used safely and correctly. Additionally we're not doing much updates to our GL backend in Ganesh anymore.  So I think I'm more inclined to just disable flat interpolation on WebG given the minimal gains, if any, from using it.

Reply all
Reply to author
Forward
0 new messages