Planet Igalia WebKit

August 11, 2025

Igalia WebKit Team

WebKit Igalia Periodical #33

Update on what happened in WebKit in the week from July 29 to August 11.

This update covers two weeks, including a deluge of releases and graphics work.

Cross-Port 🐱

Graphics 🖼️

CSS animations with a cubic-bezier timing function are now correctly rendered

The rewrite of the WebXR support continued making steady progress, and is getting closer to being able to render content again.

WPE WebKit 📟

The WPE port gained basic undo support in text inputs.

WPE Android 🤖

Adaptation of WPE WebKit targeting the Android operating system.

WPE-Android has been updated to use WebKit 2.48.5. This update particular interest for development on Android is the support for using the system logd service, which can be configured using system properties. For example, the following will enable logging all warnings:

adb shell setprop debug.log.WPEWebKit all
adb shell setprop log.tag.WPEWebKit WARN

Updated prebuilt packages are also available in the Central repository.

Releases 📦️

Stable releases of WebKitGTK 2.48.5 and WPE WebKit 2.48.5 are now available. These include the fixes and improvements from the corresponding 2.48.4 ones, and additionally solve a number of security issues. Advisory WSA-2025-0005 (GTK, WPE) covers the included security patches.

WebKitGTK 2.49.3 and WPE WebKit 2.49.4 have been released, intended to test out upcoming features and improvements. As usual, issue reports are welcome in Bugzilla, and are particularly important now to stabilize the newly created branch for the upcoming 2.50.x series.

Ruby was re-added to the GNOME SDK, thanks to Michael Catanzaro and Jordan Petridis. So we're happy to report that the WebKitGTK nightly builds for GNOME Web Canary are now fixed and Canary updates were resumed.

That’s all for this week!

by Igalia WebKit Team at August 11, 2025 09:07 PM

July 28, 2025

Igalia WebKit Team

WebKit Igalia Periodical #32

Update on what happened in WebKit in the week from July 21 to July 28.

This week the trickle of improvements to the graphics stack continues with more font handling improvements and tuning of damage information; plus the WPEPlatform Wayland backend gets server-side decorations with some compositors.

Cross-Port 🐱

Graphics 🖼️

The font-variant-emoji CSS property is now enabled by default in the GTK and WPE ports.

Font synthesis properties (synthetic bold/italic) are now correctly handled, so that fonts are rendered bold or italic even when the font itself does not provide these variants.

A few minor improvements to the damage propagation feature have landed.

The screen device scaling factor in use is now shown in the webkit://gpu internal information page.

WPE WebKit 📟

WPE Platform API 🧩

New, modern platform API that supersedes usage of libwpe and WPE backends.

The Wayland backend included with WPEPlatform has been taught how to request server-side decorations using the XDG Decoration protocol. This means that compositors that support the protocol will provide window frames and title bars for WPEToplevel instances. While this is a welcome quality of life improvement in many cases, window decorations will not be shown on Weston and Mutter (used by GNOME Shell among others), as they do not support the protocol at the moment.

WPE MiniBrowser, showing server-side decorations with the Labwc compositor

That’s all for this week!

by Igalia WebKit Team at July 28, 2025 09:04 PM

July 21, 2025

Igalia WebKit Team

WebKit Igalia Periodical #31

Update on what happened in WebKit in the week from July 14 to July 21.

In this week we had a fix for the libsoup-based resource loader on platforms without the shared-mime-info package installed, a fix for SQLite usage in WebKit, ongoing work on the GStreamer-based WebRTC implementation including better encryption for its default DTLS certificate and removal of a dependency, and an update on the status of GNOME Web Canary version.

Cross-Port 🐱

ResourceLoader delegates local resource loading (e.g. gresources) to ResourceLoaderSoup, which in turn uses g_content_type_guess to identify their content type. In platforms where shared-mime-info is not available, this fails silently and reports "text/plain", breaking things such as PDFjs.

A patch was submitted to use MIMETypeRegistry to get the MIME type of these local resources, falling back to g_content_type_guess when that fails, making internal resource loading more resilient.

Fixed "PRAGMA incrementalVacuum" for SQLite, which is used to reclaim freed filesystem space.

Multimedia 🎥

GStreamer-based multimedia support for WebKit, including (but not limited to) playback, capture, WebAudio, WebCodecs, and WebRTC.

Most web engines migrated from a default DTLS certificate signed with a RSA key to a ECDSA p-256 key, almost a decade ago. GstWebRTC is now also signing its default DTLS certificate with that private key format. This improves compatibility with various SFUs, the Jitsi Video Bridge among them.

Work is on-going in GStreamer, adding support for getting the currently selected ICE candidates pair and a new webrtcbin signal to close the connection.

The WebKit GStreamer MediaRecorder backend no longer depends on GstTranscoder

WPE WebKit 📟

WPE Android 🤖

Adaptation of WPE WebKit targeting the Android operating system.

Changed libpsl to include built-in public-suffix data when building WPE for Android. Among other duties, having this working correctly is important for site isolation, resource loading, and cookie handling.

Releases 📦️

The GNOME Web Canary build has been stale for several weeks, since the GNOME nightly SDK was updated to freedesktop SDK 25.08beta which no longer ships one of the WebKitGTK build dependencies (Ruby). We will do our best to get the builds back to a working state, soon hopefully.

That’s all for this week!

by Igalia WebKit Team at July 21, 2025 07:24 PM

July 14, 2025

Igalia WebKit Team

WebKit Igalia Periodical #30

Update on what happened in WebKit in the week from July 7 to July 14.

This week saw a fix for IPv6 scope-ids in DNS responses, frame pointers re-enabled in JSC developer builds, and a significant improvement to emoji fonts selection.

Cross-Port 🐱

Fixed support for IPv6 scope-ids in DNS responses.

JavaScriptCore 🐟

The built-in JavaScript/ECMAScript engine for WebKit, also known as JSC or SquirrelFish.

Developer builds of JSC now default to having frame pointers, to allow for more useful backtraces.

Graphics 🖼️

Improved the selection of emoji fonts to follow the spec more closely, and ensure the choice is honored while iterating over fallback fonts.

This work has been done in preparation to enable the support for the new font-variant-emoji CSS property down the line.

That’s all for this week!

by Igalia WebKit Team at July 14, 2025 08:01 PM

July 07, 2025

Igalia WebKit Team

WebKit Igalia Periodical #29

Update on what happened in WebKit in the week from June 30 to July 7.

Improvements to Sysprof and related dependencies, WebKit's usage of std::variant replaced by mpark::variant, major WebXR overhauling, and support for the logd service on Android, are all part of this week's bundle of updates.

Cross-Port 🐱

The WebXR support in the GTK and WPE WebKit ports has been ripped off in preparation for an overhaul that will make it better fit WebKit's multi-process architecture.

The new implementation, still based on OpenXR is being re-added piecewise, starting with the foundational support code to coordinate XR content inside the Web engine. Next starting and stopping immersive sessions was brought back, and a basic render loop.

Note these are the first steps on this effort, and there is still plenty to do before WebXR experiences work again.

Changed usage of std::variant in favor of an alternative implementation based on mpark::variant, which reduces the size of the built WebKit library—currently saves slightly over a megabyte for release builds.

WPE WebKit 📟

WPE Android 🤖

Adaptation of WPE WebKit targeting the Android operating system.

Logging support is being improved to submit entries to the logd service on Android, and also to configure logging using a system property. This makes debugging and troubleshooting issues on Android more manageable, and is particularly welcome to develop WebKit itself.

While working on this feature, the definition of logging channels was simplified, too.

Community & Events 🤝

WebKit on Linux integrates with Sysprof and reports a plethora of marks. As we report more information to Sysprof, we eventually pushed Sysprof internals to its limit! To help with that, we're adding a new feature to Sysprof: hiding marks from view.

This required diving a little deeper into the stack, and add a new feature to a dependency as well.

That’s all for this week!

by Igalia WebKit Team at July 07, 2025 08:49 PM

July 01, 2025

Igalia WebKit Team

WebKit Igalia Periodical #28

Update on what happened in WebKit in the week from June 24 to July 1.

This was a slow week, where the main highlight are new development releases of WPE WebKit and WebKitGTK.

Cross-Port 🐱

JavaScriptCore 🐟

The built-in JavaScript/ECMAScript engine for WebKit, also known as JSC or SquirrelFish.

Made some further progress bringing the 32-bit version of OMG closer to the 64-bit one

Releases 📦️

WebKitGTK 2.49.3 and WPE WebKit 2.49.3 have been released. These are development snapshots intended to allow those interested to test the new features and improvement which will be part of the next stable release series. As usual, bug reports are welcome in the WebKit Bugzilla.

Community & Events 🤝

The video recording for the talk “Jumping Over the Garden Wall - WPE WebKit on Android” from this year's Web Engines Hackfest is now available for watching.

That’s all for this week!

by Igalia WebKit Team at July 01, 2025 01:29 PM

June 23, 2025

Igalia WebKit Team

WebKit Igalia Periodical #27

Update on what happened in WebKit in the week from June 16 to June 23.

This week saw a variety of fixes on multimedia, including GStreamer, a fix for JSC, and the addition of analog gamepad buttons support for WPE.

Cross-Port 🐱

Multimedia 🎥

GStreamer-based multimedia support for WebKit, including (but not limited to) playback, capture, WebAudio, WebCodecs, and WebRTC.

WebRTC DTMF support was recently implemented in our GstWebRTC backend.

The WebCodecs VideoFrame copyTo() function now correctly handles odd-sized frames.

Multiple MediaRecorder-related improvements landed in main recently (1, 2, 3, 4), and also in GStreamer.

JavaScriptCore 🐟

The built-in JavaScript/ECMAScript engine for WebKit, also known as JSC or SquirrelFish.

JSC saw some fixes in i31 reference types when using Wasm GC.

WPE WebKit 📟

WPE now has support for analog gamepad buttons when using libwpe. Since version 1.16.2 libwpe has the capability to handle analog gamepad button events, but the support on the WPE side was missing. It has now been added, and will be enabled when the appropriate versions of libwpe are used.

That’s all for this week!

by Igalia WebKit Team at June 23, 2025 07:58 PM

June 16, 2025

Igalia WebKit Team

WebKit Igalia Periodical #26

Update on what happened in WebKit in the week from May 27 to June 16.

After a short hiatus coinciding with this year's edition of the Web Engines Hackfest, this issue covers a mixed bag of new API features, releases, multimedia, and graphics work.

Cross-Port 🐱

A new WebKitWebView::theme-color property has been added to the public API, along with a corresponding webkit_web_view_get_theme_color() getter. Its value follows that of the theme-color metadata attribute declared by pages loaded in the web view. Although applications may use the theme color in any way they see fit, the expectation is that it will be used to adapt their user interface (as in this example) to complement the Web content being displayed.

Multimedia 🎥

GStreamer-based multimedia support for WebKit, including (but not limited to) playback, capture, WebAudio, WebCodecs, and WebRTC.

The video capture pipeline has gained the ability to optionally rotate the input before encoding.

WebKitGTK 🖥️

Damage propagation has been toggled for the GTK port: for now only a single rectangle is passed to the UI process, which then is used to let GTK know which part of a WebKitWebView has received changes since the last repaint. This is a first step to get damage tracking code widely tested, with further improvements to be enabled later when considered appropriate.

WPE WebKit 📟

WPE Android 🤖

Adaptation of WPE WebKit targeting the Android operating system.

WPE-Android 0.2.0 has been released. The main change in this version is the update to WPE WebKit 2.48.3, which is the first that can be built for Android out of the box, without needing any additional patching. Thanks to this, we expect that the WPE WebKit version used will receive more frequent updates going forward. The prebuilt packages available at the Maven Central repository have been updated accordingly.

Releases 📦️

WebKitGTK 2.49.2 and WPE WebKit 2.49.2 have been released. These are development snapshots and are intended to let those interested test out upcoming features and improvements, and as usual issue reports are welcome in Bugzilla.

Community & Events 🤝

This year's Web Engines Hackfest had two WebKit-related sessions, and the slides are available already for the WPE-Android talk and the Multimedia in WebKit session. Video recordings will be available later on.

That’s all for this week!

by Igalia WebKit Team at June 16, 2025 09:44 PM

May 30, 2025

Igalia WebKit Team

WebKit at the Web Engines Hackfest 2025

The Web Engines Hackfest 2025 is kicking off next Monday in A Coruña and among all the interesting talks and sessions about different engines, there are a few that can be interesting to people involved one way or another with WebKitGTK and WPE:

All talks will be live streamed and a Jitsi Meet link will be available for those interested in participating remotely. You can find all the details at webengineshackfest.org.

by Igalia WebKit Team at May 30, 2025 04:21 PM

May 26, 2025

Igalia WebKit Team

WebKit Igalia Periodical #25

Update on what happened in WebKit in the week from May 19 to May 26.

This week saw updates on the Android version of WPE, the introduction of a new mechanism to support memory-mappable buffers which can lead to better performance, a new gamepad API to WPE, and other improvements.

Cross-Port 🐱

Implemented support for the new 'request-close' command for dialog elements.

JavaScriptCore 🐟

The built-in JavaScript/ECMAScript engine for WebKit, also known as JSC or SquirrelFish.

Added support for using the GDB JIT API when dynamically generating code in JSC.

Graphics 🖼️

Added support for memory-mappable GPU buffers. This mechanism allows to allocate linear textures that can be used from OpenGL, and memory-mapped into CPU-accessible memory. This allows to update the pixel data directly, bypassing the usual glCopyTexSubImage2D logic that may introduce implicit synchronization / perform staging copies / etc. (driver-dependant).

WPE WebKit 📟

WPE Platform API 🧩

New, modern platform API that supersedes usage of libwpe and WPE backends.

Landed a patch to add a gamepads API to WPE Platform with an optional default implementation using libmanette.

WPE Android 🤖

Adaptation of WPE WebKit targeting the Android operating system.

WPE-Android has been updated to use WebKit 2.48.2. Updated packages will be available in the Central repository in the coming days.

The WPE-Android MiniBrowser no longer crashes when opening the “Settings” activity when the system-wide dark user interface mode is enabled.

That’s all for this week!

by Igalia WebKit Team at May 26, 2025 07:38 PM

May 22, 2025

WPE WebKit Blog

Success Story: Savant

Savant logo WPE

Igalia worked with Savant Systems to bring a seamless, high-performance music experience to its smart home ecosystem. By enhancing WPE WebKit with critical backported patches, developing a custom Widevine CDM, and engineering a JavaScript D-Bus bridge, WPE WebKit was adapted to ensure robust and secure media playback directly within Savant’s platform.

Delivering a tightly integrated music experience in a smart home environment required overcoming significant technical challenges. To achieve this, WPE WebKit’s capabilities were streamlined to enable a fluid interface and reliable communication between the browser and the music process that powers a third-party music integration.

With deep expertise in browser technology and embedded systems, Igalia was able to help Savant implement a tailored WPE WebKit integration, optimizing performance while maintaining security and responsiveness. The result is a cutting-edge solution that enhances user experience and supports Savant’s commitment to innovation in smart home entertainment.

May 22, 2025 12:00 AM

May 19, 2025

Igalia WebKit Team

WebKit Igalia Periodical #24

Update on what happened in WebKit in the week from May 12 to May 19.

This week focused on infrastructure improvements, new releases that include security fixes, and featured external projects that use the GTK and WPE ports.

Cross-Port 🐱

Multimedia 🎥

GStreamer-based multimedia support for WebKit, including (but not limited to) playback, capture, WebAudio, WebCodecs, and WebRTC.

Fixed a reference cycle in the mediastreamsrc element, which prevented its disposal.

JavaScriptCore 🐟

The built-in JavaScript/ECMAScript engine for WebKit, also known as JSC or SquirrelFish.

Added an internal class that will be used to represent Temporal Duration objects in a way that allows for more precise calculations. This is not a user-visible change, but will enable future PRs to advance Temporal support in JSC towards completion.

WPE WebKit 📟

WPE Platform API 🧩

New, modern platform API that supersedes usage of libwpe and WPE backends.

Added an initial demo application to the GTK4 WPEPlatform implementation.

Screenshot of a Web browser application using a WPEPlatform backend based on GTK4

Releases 📦️

WebKitGTK 2.48.2 and WPE WebKit 2.48.2 have been released. These are paired with a security advisory (WSA-2025-0004: GTK, WPE), and therefore it is advised to update.

On top of security fixes, these release also include correctness fixes, and support for CSS Overscroll Behaviour is now enabled by default.

Community & Events 🤝

GNOME Web has gained a preferences page that allows toggling WebKit features at run-time. Tech Preview builds of the browser will show the settings page by default, while in regular releases it is hidden and may be enabled with the following command:

gsettings set org.gnome.Epiphany.ui webkit-features-page true

This should allow frontend developers to test upcoming features more easily. Note that the settings for WebKit features are not persistent, and they will be reset to their default state on every launch.

Features page in the GNOME Web preferences dialog Features page in the GNOME Web preferences dialog

Infrastructure 🏗️

Landed an improvement to error reporting in the script within WebKit that runs test262 JavaScript tests.

The WebKit Test Runner (WKTR) will no longer crash if invalid UTF-8 sequences are written to the standard error stream, (e.g. from 3rd party libraries' debugging options.

Experimentation is ongoing to un-inline String::find(), which saves ~50 KiB in the resulting binary size worth of repeated implementations of SIMD “find character in UTF-16” and “find character in UTF-32” algorithms. Notably, the algorithm for “find character in ASCII string” was not even part of the inlining.

Added the LLVM repository to the WebKit container SDK. Now it is possible to easily install Clang 20.x with wkdev-setup-default-clang --version=20.

Figured out that a performance bug related to jump threading optimization in Clang 18 resulted in a bottleneck adding up to five minutes of build time in the container SDK. This may be fixed by updating to Clang 20.x.

That’s all for this week!

by Igalia WebKit Team at May 19, 2025 09:10 PM

May 12, 2025

Igalia WebKit Team

WebKit Igalia Periodical #23

Update on what happened in WebKit in the week from May 5 to May 12.

This week saw one more feature enabled by default, additional support to track memory allocations, continued work on multimedia and WebAssembly.

Cross-Port 🐱

The Media Capabilities API is now enabled by default. It was previously available as a run-time option in the WPE/WebKitGTK API (WebKitSettings:enable-media-capabilities), so this is just a default tweak.

Landed a change that integrates malloc heap breakdown functionality with non-Apple ports. It works similarly to Apple's one yet in case of non-Apple ports the per-heap memory allocation statistics are printed to stdout periodically for now. In the future this functionality will be integrated with Sysprof.

Multimedia 🎥

GStreamer-based multimedia support for WebKit, including (but not limited to) playback, capture, WebAudio, WebCodecs, and WebRTC.

Support for WebRTC RTP header extensions was improved, a RTP header extension for video orientation metadata handling was introduced and several simulcast tests are now passing

Progress is ongoing on resumable player suspension, which will eventually allow us to handle websites with lots of simultaneous media elements better in the GStreamer ports, but this is a complex task.

JavaScriptCore 🐟

The built-in JavaScript/ECMAScript engine for WebKit, also known as JSC or SquirrelFish.

The in-place Wasm interpreter (IPInt) port to 32-bits has seen some more work.

Fixed a bug in OMG caused by divergence with the 64-bit version. Further syncing is underway.

Releases 📦️

Michael Catanzaro has published a writeup on his blog about how the WebKitGTK API versions have changed over time.

Infrastructure 🏗️

Landed some improvements in the WebKit container SDK for Linux, particularly in error handling.

That’s all for this week!

by Igalia WebKit Team at May 12, 2025 07:29 PM

May 06, 2025

Igalia WebKit Team

WebKit Igalia Periodical #22

Update on what happened in WebKit in the week from April 15 to May 6.

WPEPlatform continued closing the feature gap with libwpe-based WPE backends, WPE got improved clipboard support, and JSC gets assorted improvements.

Cross-Port 🐱

Multimedia 🎥

GStreamer-based multimedia support for WebKit, including (but not limited to) playback, capture, WebAudio, WebCodecs, and WebRTC.

The GstWPE2 GStreamer plugin landed in GStreamer main, it makes use of the WPEPlatform API. It will ship in GStreamer 1.28. Compared to GstWPE1 it provides the same features, but improved support for NVIDIA GPUs. The main regression is lack of audio support, which is work-in-progress, both on the WPE and GStreamer sides.

JavaScriptCore 🐟

The built-in JavaScript/ECMAScript engine for WebKit, also known as JSC or SquirrelFish.

Work on enabling the in-place Wasm interpreter (IPInt) on 32-bits has progressed nicely

The JSC tests runner can now guard against a pathological failure mode.

In JavaScriptCore's implementation of Temporal, Tim Chevalier fixed the parsing of RFC 9557 annotations in date strings to work according to the standard. So now syntactically valid but unknown annotations [foo=bar] are correctly ignored, and the ! flag in an annotation is handled correctly. Philip Chimento expanded the test suite around this feature and fixed a couple of crashes in Temporal.

Math.hypot(x, y, z) received a fix for a corner case.

WPE WebKit 📟

WPE now uses the new pasteboard API, aligning it with the GTK port, and enabling features that were previously disabled. Note that the new features work only with WPEPlatform, because libwpe-based backends are limited to access clipboard text items.

WPE Platform API 🧩

New, modern platform API that supersedes usage of libwpe and WPE backends.

A new interface for handling clipboard requests was added, with a generic implementation that only operated within WebKit.

Platform backends may add their own clipboard handling, with the Wayland one being the first one to, using wl_data_device_manager.

This continues the effort to close the feature gap between the “traditional” libwpe-based WPE backends and the new WPEPlatform ones.

Community & Events 🤝

Carlos García has published a blog post about the optimizations introduced in the WPE and GTK WebKit ports since the introduction of Skia replacing Cairo for 2D rendering. Plus, there are some hints about what is coming next.

That’s all for this week!

by Igalia WebKit Team at May 06, 2025 01:27 PM

April 21, 2025

Carlos García Campos

Graphics improvements in WebKitGTK and WPEWebKit after the switch to Skia

In my previous post, when I introduced the switch to Skia for 2D rendering, I explained that we replaced Cairo with Skia keeping mostly the same architecture. This alone was an important improvement in performance, but still the graphics implementation was designed for Cairo and CPU rendering. Once we considered the switch to Skia as stable, we started to work on changes to take more advantage of Skia and GPU rendering to improve the performance even more. In this post I’m going to present some of those improvements and other not directly related to Skia and GPU rendering.

Explicit fence support

This is related to the DMA-BUF renderer used by the GTK port and WPE when using the new API. The composited buffer is shared as a DMA-BUF between the web and UI processes. Once the web process finished the composition we created a fence and waited for it, to make sure that when the UI process was notified that the composition was done the buffer was actually ready. This approach was safe, but slow. In 281640@main we introduced support for explicit fencing to the WPE port. When possible, an exportable fence is created, so that instead of waiting for it immediately, we export it as a file descriptor that is sent to the UI process as part of the message that notifies that a new frame has been composited. This unblocks the web process as soon as composition is done. When supported by the platform, for example in WPE under Wayland when the zwp_linux_explicit_synchronization_v1 protocol is available, the fence file descriptor is passed to the platform implementation. Otherwise, the UI process asynchronously waits for the fence by polling the file descriptor before passing the buffer to the platform. This is what we always do in the GTK port since 281744@main. This change improved the score of all MotionMark tests, see for example multiply.

Enable MSAA when available

In 282223@main we enabled the support for MSAA when possible in the WPE port only, because this is more important for embedded devices where we use 4 samples providing good enough quality with a better performance. This change improved the Motion Mark tests that use 2D canvas like canvas arcs, paths and canvas lines. You can see here the change in paths when run in a RaspberryPi 4 with WPE 64 bits.

Avoid textures copies in accelerated 2D canvas

As I also explained in the previous post, when 2D canvas is accelerated we now use a dedicated layer that renders into a texture that is copied to be passed to the compositor. In 283460@main we changed the implementation to use a CoordinatedPlatformLayerBufferNativeImage to handle the canvas texture and avoid the copy, directly passing the texture to the compositor. This improved the MotionMark tests that use 2D canvas. See canvas arcs, for example.

Introduce threaded GPU painting mode

In the initial implementation of the GPU rendering mode, layers were painted in the main thread. In 287060@main we moved the rendering task to a dedicated thread when using the GPU, with the same threaded rendering architecture we have always used for CPU rendering, but limited to 1 worker thread. This improved the performance of several MotionMark tests like images, suits and multiply. See images.

Update default GPU thread settings

Parallelization is not so important for GPU rendering compared to CPU, but still we realized that we got better results by increasing a bit the amount of worker threads when doing GPU rendering. In 290781@main we increased the limit of GPU worker threads to 2 for systems with at least 4 CPU cores. This improved mainly images and suits in MotionMark. See suits.

Hybrid threaded CPU+GPU rendering mode

We had either GPU or CPU worker threads for layer rendering. In systems with 4 CPU cores or more we now have 2 GPU worker threads. When those 2 threads are busy rendering, why not using the CPU to render other pending tiles? And the same applies when doing CPU rendering, when all workers are busy, could we use the GPU to render other pending tasks? We tried and turned out to be a good idea, especially in embedded devices. In 291106@main we introduced the hybrid mode, giving priority to GPU or CPU workers depending on the default rendering mode, and also taking into account special cases like on HiDPI, where we are always scaling, and we always prefer the GPU. This improved multiply, images and suits. See images.

Use Skia API for display list implementation

When rendering with Cairo and threaded rendering enabled we use our own implementation of display lists specific to Cairo. When switching to Skia we thought it was a good idea to use the WebCore display list implementation instead, since it’s cross-platform implementation shared with other ports. But we realized this implementation is not yet ready to support multiple threads, because it holds references to WebCore objects that are not thread safe. Main thread might change those objects before they have been processed by painting threads. So, we decided to try to use the Skia API (SkPicture) that supports recording in the main thread and replaying from worker threads. In 292639@main we replaced the WebCore display list usage by SkPicture. This was expected to be a neutral change in terms of performance but it surprisingly improved several MotionMark tests like leaves, multiply and suits. See leaves.

Use Damage to track the dirty region of GraphicsLayer

Every time there’s a change in a GraphicsLayer and it needs to be repainted, it’s notified and the area that changed is included so that we only render the parts of the layer that changed. That’s what we call the layer dirty region. It can happen that when there are many small updates in a layer we end up with lots of dirty regions on every layer flush. We used to have a limit of 32 dirty regions per layer, so that when more than 32 are added we just united them into the first dirty area. This limit was removed because we always unite the dirty areas for the same tiles when processing the updates to prepare the rendering tasks. However, we also tried to avoid handling the same dirty region twice, so every time a new dirty region was added we iterated the existing regions to check if it was already present. Without the 32 regions limit that means we ended up iterating a potentially very long list on every dirty region addition. The damage propagation feature uses a Damage class to efficiently handle dirty regions, so we thought we could reuse it to track the layer dirty region, bringing back the limit but uniting in a more efficient way than using always the first dirty area of the list. It also allowed to remove check for duplicated area in the list. This change was added in 292747@main and improved the performance of MotionMark leaves and multiply tests. See leaves.

Record all dirty tiles of a layer once

After the switch to use SkPicture for the display list implementation, we realized that this API would also allow to record the graphics layer once, using the bounding box of the dirty region, and then replay multiple times on worker threads for every dirty tile. Recording can be a very heavy operation, specially when there are shadows or filters, and it was always done for every tile due to the limitations of the previous display list implementation. In 292929@main we introduced the change with improvements in MotionMark leaves and multiply tests. See multiply.

MotionMark results

I’ve shown here the improvements of these changes in some of the MotionMark tests. I have to say that some of those changes also introduced small regressions in other tests, but the global improvement is still noticeable. Here is a table with the scores of all tests before these improvements and current main branch run by WPE MiniBrowser in a RaspberryPi 4 (64bit).

TestScore July 2024Score April 2025
Multiply501.17684.23
Canvas arcs140.24828.05
Canvas lines1613.933086.60
Paths375.524255.65
Leaves319.31470.78
Images162.69267.78
Suits232.91445.80
Design33.7964.06

What’s next?

There’s still quite a lot of room for improvement, so we are already working on other features and exploring ideas to continue improving the performance. Some of those are:

  • Damage tracking: this feature is already present, but disabled by default because it’s still work in progress. We currently use the damage information to only paint the areas of every layer that changed. But then we always compose a whole frame inside WebKit that is passed to the UI process to be presented on screen. It’s possible to use the damage information to improve both, the composition inside WebKit and the presentation of the composited frame on the screen. For more details about this feature read Pawel’s awesome blog post about it.
  • Use DMA-BUF for tile textures to improve pixel transfer operations: We currently use DMA-BUF buffers to share the composited frame between the web and UI process. We are now exploring the idea of using DMA-BUF also for the textures used by the WebKit compositor to generate the frame. This would allow to improve the performance of pixel transfer operations, for example when doing CPU rendering we need to upload the dirty regions from main memory to a compositor texture on every composition. With DMA-BUF backed textures we can map the buffer into main memory and paint with the CPU directly into the mapped buffer.
  • Compositor synchronization: We plan to try to improve the synchronization of the WebKit compositor with the system vblank and the different sources of composition (painted layers, video layers, CSS animations, WebGL, etc.)

 

by carlos garcia campos at April 21, 2025 08:27 AM