Bug 252648 - [GTK] GtkSnapshot contains overly large damage area
Summary: [GTK] GtkSnapshot contains overly large damage area
Status: NEW
Alias: None
Product: WebKit
Classification: Unclassified
Component: WebKitGTK (show other bugs)
Version: WebKit Nightly Build
Hardware: Unspecified Linux
: P2 Normal
Assignee: Nobody
URL:
Keywords:
Depends on:
Blocks: GTK4
  Show dependency treegraph
 
Reported: 2023-02-20 21:31 PST by Christian Hergert
Modified: 2023-02-21 06:39 PST (History)
3 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Christian Hergert 2023-02-20 21:31:08 PST
Hi!

I'm the author of a good portion of GTK 4's GL renderer. I wanted to chime in on some implementation details that might allow for improving snapshot performance of the GTK WebKitWebView when using EGL.

Currently, when using WebKit's accelerated rendering with the GTK 4 backend, an EGL texture is imported into GDK and snapshotted.

The unfortunate bit is that there is no damaged associated with the texture (as textures in GDK are considered "immutable"). What that means is when the GskRenderNode tree is snapshotted, it will perform a diff to the previous frame to determine damage. The single texture node currently added to the snapshot will be different, causing the damage rectangle to match the entire bounds of the texture area.

That means if you have a 16x16 GIF animating, you'll still redraw the entire browser window as far as the desktop compositor is concerned.

While I haven't looked to see what texture sharing mechanism is being used under the hood, I suspect it's a DMABUF attached to a GL texture? If so, one possible way to improve this is to keep 2 textures around (mapped to the same DMABUF). If you snapshot as tiles of textures (say 128x128) you only need to "flip" the tile which intersects the underlying damage. That is enough for "gsk_render_node_diff()" to see the damage.

I have some example code doing this in libmks https://gitlab.gnome.org/chergert/libmks/-/blob/main/lib/mks-dmabuf-paintable.c which could serve as an example.
Comment 1 Adrian Perez 2023-02-21 01:43:02 PST
(In reply to Christian Hergert from comment #0)
> Hi!
> 
> I'm the author of a good portion of GTK 4's GL renderer. I wanted to chime
> in on some implementation details that might allow for improving snapshot
> performance of the GTK WebKitWebView when using EGL.

Hello Christian! Always good to have your input, specially when it comes
to performance issues 👋️
 
> Currently, when using WebKit's accelerated rendering with the GTK 4 backend,
> an EGL texture is imported into GDK and snapshotted.

Indeed, that's how it works under Wayland.

Under X11 we are still using Cairo to paint the texture shared by the
WebProcess, although in theory it should be possible to import it when
backed by a DMA-BUF, or at least paint it on a textured quad to avoid
hitting the (slow) Cairo method. I haven't had the time to bring it into
WebKit, but here we do the textured quad method:

  https://github.com/Igalia/cog/blob/master/platform/x11/cog-platform-x11.c#L152-L177

> The unfortunate bit is that there is no damaged associated with the texture
> (as textures in GDK are considered "immutable"). What that means is when the
> GskRenderNode tree is snapshotted, it will perform a diff to the previous
> frame to determine damage. The single texture node currently added to the
> snapshot will be different, causing the damage rectangle to match the entire
> bounds of the texture area.
> 
> That means if you have a 16x16 GIF animating, you'll still redraw the entire
> browser window as far as the desktop compositor is concerned.
> 
> While I haven't looked to see what texture sharing mechanism is being used
> under the hood, I suspect it's a DMABUF attached to a GL texture? If so, one
> possible way to improve this is to keep 2 textures around (mapped to the
> same DMABUF). If you snapshot as tiles of textures (say 128x128) you only
> need to "flip" the tile which intersects the underlying damage. That is
> enough for "gsk_render_node_diff()" to see the damage.

There are some drivers which can do Wayland but don't necessarily expose
the needed EGL/GLX extensions to export and import DMA-BUFs, which is why
we have a nested Wayland compositor here--mostly a concern for non-Mesa
drivers. We have lately been adding more dependency on DMA-BUF machinery
(e.g. for WebGL2 + GPUProcess) so it may be possible to try and detect at
runtime whether to do something like you suggest =)

> I have some example code doing this in libmks
> https://gitlab.gnome.org/chergert/libmks/-/blob/main/lib/mks-dmabuf-
> paintable.c which could serve as an example.
Comment 2 Christian Hergert 2023-02-21 01:55:23 PST
(In reply to Adrian Perez from comment #1)
> There are some drivers which can do Wayland but don't necessarily expose
> the needed EGL/GLX extensions to export and import DMA-BUFs, which is why
> we have a nested Wayland compositor here--mostly a concern for non-Mesa
> drivers.

As long as you already have GL textures the tiling within GTK should work just fine, no need for DMABUF necessarily. (Assuming you're getting damage from the nested wayland compositor).