WPE WebKit BlogNews related to WPE WebKit.2025-11-27T00:00:00Zhttps://wpewebkit.org/blog/Highlights of the WPE WebKit 2.50 release series2025-11-27T00:00:00Zhttps://wpewebkit.org/blog/2025-11-27-wpewebkit-2.50.html<p>This fall, the WPE WebKit team has released the 2.50 series of the Web engine after six months of hard work. Let’s have a deeper look at some of the most interesting changes in this release series!</p>
<h2 id="improved-rendering-performance" tabindex="-1">Improved rendering performance</h2>
<p>For this series, the threaded rendering implementation has been switched to use the Skia API. What has changed is the way we record the painting commands for each layer. Previously we used WebCore’s built-in mechanism (<code>DisplayList</code>) which is not thread-safe, and led to obscure rendering issues in release builds and/or sporadic assertions in debug builds when replaying the display lists in threads other than the main one. The <code>DisplayList</code> usage was replaced with <code>SkPictureRecorder</code>, Skia’s built-in facility, that provides similar functionality but in a thread-safe manner. Using the Skia API, we can leverage multithreading in a reliable way to replay recorded drawing commands in different worker threads, improving rendering performance.</p>
<p>An experimental hybrid rendering mode has also been added. In this mode, WPE WebKit will attempt to use GPU worker threads for rendering but, if these are busy, CPU worker threads will be used whenever possible. This rendering mode is still under investigation, as it is unclear whether the improvements are substantial enough to justify the extra complexity.</p>
<p>Damage propagation to the system compositor, which was added during the 2.48 cycle but remained disabled by default, has now been enabled. The system compositor may now leverage the damage information for further optimization.</p>
<p>Vertical writing-mode rendering has also received improvements for this release series.</p>
<h2 id="changes-in-multimedia-support" tabindex="-1">Changes in Multimedia support</h2>
<p>When available in the system, WebKit can now leverage the XDG desktop portal for accessing capture devices (like cameras) so that no specific sandbox exception is required. This provides secure access to capture devices in browser applications that use WPE WebKit.</p>
<p>Managed Media Source support has been enabled. This potentially improves multimedia playback, for example in mobile devices, by allowing the user agent to react to changes in memory and CPU availability.</p>
<p>Transcoding is now using the GStreamer built-in <code>uritranscodebin</code> element instead of GstTranscoder, which improves stability of the media recording that needs transcoding.</p>
<p>SVT-AV1 encoder support has been added to the media backend.</p>
<h2 id="webxr-support" tabindex="-1">WebXR support</h2>
<p>The <a href="https://developer.mozilla.org/en-US/docs/Web/API/WebXR_Device_API/Fundamentals">WebXR</a> implementation had been stagnating since it was first introduced, and had a number of shortcomings. This was removed in favor of a new implementation, also built using <a href="https://www.khronos.org/openxr/">OpenXR</a>, that better adapts to the multiprocess architecture of WebKit.</p>
<p>This feature is considered experimental in 2.50, and while it is complete enough to load and display a number of immersive experiences, a number of improvements and optional features continue to be actively developed. Therefore, WebXR support needs to be enabled at build time with the <code>ENABLE_WEBXR=ON</code> CMake option.</p>
<h2 id="android-support" tabindex="-1">Android support</h2>
<p>Support for Android targets has been greatly improved. It is now possible to build WPE WebKit without the need for additional patches when using the libwpe-based <a href="https://github.com/Igalia/WPEBackend-android">WPEBackend-android</a>. This was achieved by incorporating changes that make WebKit use more appropriate defaults (like disabling <code>MediaSession</code>) or using platform-specific features (like <a href="https://developer.android.com/ndk/reference/group/memory">ASharedMemory</a> and <a href="https://developer.android.com/ndk/reference/group/a-hardware-buffer">AHardwareBuffer</a>) when targeting Android.</p>
<p>The WebKit logging system has gained support to use <a href="https://wpewebkit.org/reference/2.50.0/wpe-webkit-2.0/android.html">the Android <code>logd</code> service</a>. This is particularly useful for both WebKit and application developers, allowing to configure logging channels at runtime in <em>any</em> WPE WebKit build. For example, the following commands may be used before launching an application to debug WebGL setup and multimedia playback errors:</p>
<pre class="language-sh"><code class="language-sh">adb setprop log.tag.WPEWebKit VERBOSE <span class="token comment"># Global logging filter</span>
adb setprop debug.WPEWebKit.log <span class="token string">'WebGL,Media=error'</span> <span class="token comment"># Channels</span>
adb logcat <span class="token parameter variable">-s</span> WPEWebKit <span class="token comment"># Follow log messages</span></code></pre>
<p>There is an ongoing effort to enable the WPEPlatform API on Android, and while it builds now, rendering is not yet working.</p>
<h2 id="web-platform-support" tabindex="-1">Web Platform support</h2>
<p>As usual, changes in this area are extensive as WebKit constantly adopts, improves, and supports new Web Platform features. However, some interesting additions in this release cycle include:</p>
<ul>
<li>The new <a href="https://developer.mozilla.org/en-US/docs/Web/API/CookieStore">CookieStore API</a>.</li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/API/ManagedMediaSource">ManagedMediaSource</a>.</li>
<li>CSS <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/container-progress">container-progress()</a>.</li>
<li>CSS <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/text-wrap-style">text-wrap-style: pretty</a>.</li>
<li>CSS <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/font-family">font-family: math</a>.</li>
<li>CSS Animation: support for the <a href="https://developer.mozilla.org/en-US/docs/Web/API/Animation/overallProgress">overallProgress property</a>.</li>
<li>HTML <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/details#creating_an_auto-expanding_details_element">auto-expanding <details></a>.</li>
<li>CSS <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/hidden">hidden=“until-found”</a>.</li>
</ul>
<h2 id="api-changes" tabindex="-1">API changes</h2>
<ul>
<li>The <a href="https://wpewebkit.org/reference/2.50.0/wpe-webkit-2.0/property.Settings.enable-hyperlink-auditing.html">WebKitSettings:enable-hyperlink-auditing</a> option has been deprecated. This feature is now always enabled.</li>
<li>The <a href="https://wpewebkit.org/reference/2.50.0/wpe-webkit-2.0/method.WebView.get_theme_color.html"><code>webkit_web_view_get_theme_color()</code></a> function has been added to allow querying the <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/meta/name/theme-color">theme color</a> declared by the content loaded in a web view. The corresponding <a href="https://wpewebkit.org/reference/2.50.0/wpe-webkit-2.0/property.WebView.theme-color.html">WebKitWebView:theme-color</a> property is available as well, which allows using the <a href="https://docs.gtk.org/gobject/vfunc.Object.notify.html"><code>notify</code> signal</a> to watch for theme color changes.</li>
</ul>
<h3 id="wpeplatform" tabindex="-1">WPEPlatform</h3>
<p>Work continues on the new WPEPlatform API, which is still shipped as a preview feature in the 2.50 and needs to be explicitly enabled at build time with the <code>ENABLE_WPE_PLATFORM=ON</code> CMake option. The API may still change and applications developed using WPEPlatform are likely to need changes with future WPE WebKit releases; but not for long: the current goal is to have it ready and enabled by default for the upcoming 2.52 series.</p>
<p>One of the main changes is that WPEPlatform now gets built into <code>libWPEWebKit</code>. The rationale for this change is avoiding shipping two copies of shared code from the Web Template Framework (WTF), which saves both disk and memory space usage. The <code>wpe-platform-2.0</code> pkg-config module is still shipped, which allows application developers to know whether WPEPlatform support has been built into WPE WebKit.</p>
<p>The abstract base class <code>WPEScreenSyncObserver</code> has been introduced, and allows platform implementations to notify on display synchronization, allowing WebKit to better pace rendering.</p>
<p>WPEPlatform has gained support for controllers like gamepads and joysticks through the new <code>WPEGamepadManager</code> and <code>WPEGamepad</code> classes. When building with the <code>ENABLE_MANETTE=ON</code> CMake option a built-in implementation based on <a href="https://gnome.pages.gitlab.gnome.org/libmanette/">libmanette</a> is used by default, if a custom one is not specified.</p>
<p>WPEPlatform now includes a new <code>WPEBufferAndroid</code> class, used to represent graphics buffers backed by <a href="https://developer.android.com/ndk/reference/group/a-hardware-buffer">AHardwareBuffer</a>. These buffers support being imported into an <code>EGLImage</code> using <code>wpe_buffer_import_to_egl_image()</code>.</p>
<p>As part of the work to improve Android support, the buffer rendering and release fences have been moved from <code>WPEBufferDMABuf</code> to the base class, <code>WPEBuffer</code>. This is leveraged by <code>WPEBufferAndroid</code>, and should be helpful if more buffer types are introduced in the future.</p>
<p>Other additions include clipboard support, <a href="https://www.w3.org/TR/mediaqueries-4/#mf-interaction">Interaction Media Features</a>, and an accessibility implementation using <a href="https://gitlab.gnome.org/Archive/atk">ATK</a>.</p>
<h2 id="what%E2%80%99s-new-for-webkit-developers%3F" tabindex="-1">What’s new for WebKit developers?</h2>
<p>WebKit now supports sending tracing marks and counters to <a href="https://gitlab.gnome.org/GNOME/sysprof/">Sysprof</a>. Marks indicate when certain events occur and their duration; while counters track variables over time. Together, these allow developers to find performance bottlenecks and monitor internal WebKit performance metrics like frame rates, memory usage, and more. This integration enables developers to analyze the performance of applications, including data for WebKit alongside system-level metrics, in a unified view. For more details see <a href="https://feaneron.com/2025/09/08/marks-and-counters-in-sysprof/">this article</a>, which also details how Sysprof was improved to handle the massive amounts of data produced by WebKit.</p>
<p>Finally, GCC 12.2 is now the minimum required version to build WPE WebKit. Increasing the minimum compiler version allows us to remove obsolete code and focus on improving code quality, while taking advantage of new C++ and compiler features.</p>
<h2 id="looking-forward-to-2.52" tabindex="-1">Looking forward to 2.52</h2>
<p>The 2.52 release series will bring even more improvements, and we expect it to be released during the spring of 2026. Until then!</p>
Success Story: Savant2025-05-22T00:00:00Zhttps://wpewebkit.org/blog/2025-success-savant.html<div class="success-top">
<img alt="Savant logo" align="center" src="https://wpewebkit.org/assets/img/logo-savant.png" srcset="https://wpewebkit.org/assets/img/[email protected] 2x" />
<img alt="WPE" align="center" src="https://wpewebkit.org/assets/img/logo-blue.svg" />
</div>
<p>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.</p>
<p>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.</p>
<p>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.</p>
WPE WebKit 2.48 highlights2025-04-11T00:00:00Zhttps://wpewebkit.org/blog/2025-04-11-wpewebkit-2.48.html<p>The WPE WebKit team has been working hard during the past six months and has recently released version 2.48 of the WPE port of WebKit. As is now tradition, here is an overview of the most important changes in this new stable release series.</p>
<h2 id="graphics-and-rendering" tabindex="-1">Graphics and Rendering</h2>
<p>The work on the graphics pipeline of WebKit continues, and a lot of improvements, refactorings, bug fixes, and optimizations have happened under the hood. These changes bring both performance and rendering improvements, and are too many to list individually. Nonetheless, there are a number of interesting changes.</p>
<h3 id="gpu-worker-threads" tabindex="-1">GPU Worker Threads</h3>
<p>When GPU rendering with Skia is in use, tiles will be rendered in worker threads, which has a positive impact on performance. Threads were already used when using the CPU for rendering. Note that GPU usage for rendering is not yet the default in the WPE port, but may be enabled setting <code>WEBKIT_SKIA_ENABLE_CPU_RENDERING=0</code> in the environment before running programs that use WPE WebKit.</p>
<h3 id="canvas-improvements" tabindex="-1">Canvas Improvements</h3>
<p>The <a href="https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D">CanvasRenderingContext2D</a> <code>putImageData()</code> and <code>getImageData()</code> methods have been optimized by preventing unnecessary buffer copies, resulting in improved performance and reduced memory usage.</p>
<h3 id="css-3d-transforms" tabindex="-1">CSS 3D Transforms</h3>
<p>There have been several improvements handling elements that use <code>preserve-3d</code> <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/transform">CSS transforms</a>. On top of a modest performance improvement, the changes fixed rendering issues, making the implementation compliant with the specification.</p>
<h3 id="damage-tracking" tabindex="-1">Damage Tracking</h3>
<p>This release gained experimental support for <a href="https://blogs.igalia.com/plampe/introduction-to-damage-propagation-in-wpe-and-gtk-webkit-ports/">collecting “damage” information</a>, which tracks which parts of Web content produce visual changes in the displayed output. This information is then taken into account to reuse existing graphics buffers and repaint only those parts that need to be modified. This results better performance and less resource usage.</p>
<p>Note that this feature is disabled by default and may be previewed toggling the <code>PropagateDamagingInformation</code> feature flag.</p>
<h3 id="gpu-process-beginnings" tabindex="-1">GPU Process Beginnings</h3>
<p>A new “GPU process” is now always built, but its usage is disabled by default at runtime. This is an experimental feature that can be toggled via the <code>UseGPUProcessForWebGL</code> feature flag, and as the name implies at the moment this new auxiliary process only supports handling WebGL content.</p>
<p>The GPU process is a new addition to WebKit’s multiprocess model, in which isolated processes are responsible for different tasks: the GPU process will eventually be in charge of most tasks that make use of the graphics processing unit, in order to improve security by separating graphics handling from Web content and data access. At the same time, graphics-intensive work does not interfere with Web content handling, which may bring potential performance improvements in the future.</p>
<h2 id="multimedia" tabindex="-1">Multimedia</h2>
<p>The <a href="https://developer.mozilla.org/en-US/docs/Web/API/MediaRecorder/MediaRecorder">MediaRecorder</a> backend gained support for the WebM format and audio bitrate configuration. WebM usage requires GStreamer 1.24.9 or newer.</p>
<p>Video handling using the <a href="https://developer.mozilla.org/en-US/docs/Web/API/WebCodecs_API">WebCodecs API</a> no longer ignores the <code>prefer-hardware</code> option. It is used as a hint to attempt using hardware-accelerated GStreamer components. If that fails, software based codecs will be used as fallback.</p>
<p>The <a href="https://developer.mozilla.org/en-US/docs/Web/API/Web_Speech_API">Web Speech API</a> gained a new synthesis backend, using <a href="https://project-spiel.org/">libspiel</a>. The existing <a href="http://www.festvox.org/flite/">FLite</a>-based backend is still chosen by default because the dependency is readily available in most distributions, but setting <code>USE_SPIEL=ON</code> at build time is recommended where <code>libspiel</code> may be available.</p>
<p>The GStreamer-GL sink can now handle DMA-BUF memory buffers, replacing the DMA-BUF sink in this way.</p>
<h2 id="api-changes" tabindex="-1">API Changes</h2>
<p>The JavaScriptCore GLib API has a new <a href="https://wpewebkit.org/reference/2.48.0/wpe-javascriptcore-2.0/ctor.Value.new_promise.html">jsc_value_new_promise()</a> function to create <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise">Promise</a> objects from native code.</p>
<h3 id="wpe-platform-library" tabindex="-1">WPE Platform library</h3>
<p>The WPEPlatform library is a completely new API which changes how WPE embedding API works. The aim is to make <em>both</em> developing WPE backends and user applications more approachable and idiomatic using GLib and GObject conventions. Inspiration has been drawn from the <a href="https://github.com/Igalia/cog">Cog</a> API. A preview version is shipped along in 2.48, and as such it needs to be explicitly enabled at build time with <code>ENABLE_WPE_PLATFORM=ON</code>. The API may still change and applications developed using WPEPlatform are likely to need changes with future WPE WebKit releases.</p>
<h2 id="web-platform" tabindex="-1">Web Platform</h2>
<p>The list of Web Platform features that are newly available in 2.48 is considerably long, and includes the following highlights:</p>
<ul>
<li>JavaScript <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_expressions#advanced_searching_with_flags">regular expression modifier flags</a>.</li>
<li>The <a href="https://developer.mozilla.org/en-US/docs/Web/API/Compression_Streams_API">Compression Streams API</a>.</li>
<li>The <a href="https://developer.mozilla.org/en-US/docs/Web/API/URLPattern/URLPattern">URLPattern API</a>.</li>
<li>Cross-document <a href="https://developer.mozilla.org/en-US/docs/Web/API/View_Transition_API">view transitions</a>, and many improvements overall to the View Transitions support.</li>
<li>The <a href="https://developer.mozilla.org/en-US/docs/Web/API/Web_components">Web Components API</a> gained support for <a href="https://developer.mozilla.org/en-US/docs/Web/API/CustomElementRegistry">CustomElementRegistry</a>.</li>
<li>The <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/basic-shape/shape">shape()</a> CSS function.</li>
<li>Support CSS <code>width</code> and <code>height</code> properties on MathML elements.</li>
<li>Support CSS <code>writing-mode: sideways-lr</code>.</li>
<li>Support scroll-to-<a href="https://developer.mozilla.org/en-US/docs/Web/URI/Fragment/Text_fragments">text-fragment</a>.</li>
</ul>
<p>Some new functionality may disabled by default, but testable after toggling the corresponding feature flag.</p>
<ul>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/API/FileSystemWritableFileStream">FileSystemWritableFileStream</a> is available behind the flag of the same name.</li>
<li>Support for CSS <code>progress()</code>, <code>media-progress()</code> and <code>container-progress()</code> functions—all part of the CSS, behind runtime flags <code>CSSMediaProgressFunction</code> and <code>CSSContainerProgressFunction</code>, respectively.</li>
</ul>
<h2 id="packaging" tabindex="-1">Packaging</h2>
<p>The Web Inspector resources are no longer built into a shared library, but as a <a href="https://docs.gtk.org/gio/struct.Resource.html">GResource</a> bundle file. This avoids usage of the dynamic linker and allows mapping the file in memory, which brings improved resource usage.</p>
<p>Packagers and distributors might need some adaptation of their build infrastructure in cases where the Web Inspector resources have some ad-hoc handling. Typical cases are avoiding installation in production builds for embedded devices, or as an optional component for development builds.</p>
<p>For example, using the default build configuration, the file with the resources inside the installation prefix will be <code>share/wpe-webkit-2.0/inspector.gresource</code>, instead of the old <code>lib/wpe-webkit-2.0/libWPEWebInspectorResources.so</code> library.</p>
<h2 id="other-noteworthy-changes" tabindex="-1">Other Noteworthy Changes</h2>
<ul>
<li>The minimum required ICU version is now 70.1.</li>
<li>Reading of Remote Web Inspector protocol messages was optimized, resulting in a considerable speed-up for large messages.</li>
</ul>
<p>The WPE WebKit team is already working on the 2.50 release, which is planned for September. In the meantime, you can expect stable updates for the 2.48 series through the usual channels.</p>
Success Story: GLANCR2025-04-04T00:00:00Zhttps://wpewebkit.org/blog/2025-success-glancr.html<div class="success-top">
<img alt="GLANCR: the smart mirror for your digital home" align="center" src="https://wpewebkit.org/assets/img/[email protected]" />
<img alt="WPE" align="center" src="https://wpewebkit.org/assets/img/logo-blue.svg" />
</div>
<p>From SmartTVs to light bulbs and cameras, smart devices are not hard to find in homes these days. <a href="https://glancr.net/">Glancr</a>’s smart mirror is a device that seamlessly integrates digital functionality into everyday life. Powered by its custom operating system <a href="https://gitlab.com/glancr/mirr-os">mirr.OS</a>, Glancr puts the Web at the forefront, allowing users to see all the information that matters to them in a customizable interface, right on a mirror. Besides being useful in smart home scenarios, Glancr can also expand the possibilities in other use cases in the industry, such as digital signage, point-of-sale devices, or even the healthcare industry.</p>
<p>WPE WebKit empowers mirr.OS to efficiently run and render interactive widgets and applications, ensuring a fluid and responsive user experience at the same time that enables mirr.OS to leverage the power of the Web Platform. This allows developers to create rich, web-based interfaces tailored to the smart mirror’s unique requirements, in order to deliver a seamless and visually compelling interaction layer for users at the same time it bridges the gap between digital functionality and aesthetic appeal.</p>
WPE WebKit 2.46 highlights2024-10-07T00:00:00Zhttps://wpewebkit.org/blog/2024-wpewebkit-2.46.html<p>A couple of weeks ago, the WPE WebKit team released version 2.46. This is an important milestone for the project as, for the first time in a stable series, the Skia backend takes over rendering. Skia brings significant improvements to the graphics stack, so we are very happy for this release. The list of changes goes beyond graphics, and it’s not short of awesome, so let’s have a look to what’s new!</p>
<h3 id="cairo-is-out%2C-skia-is-in" tabindex="-1">Cairo is out, Skia is in</h3>
<p>We <a href="https://blogs.igalia.com/carlosgc/2024/02/19/webkit-switching-to-skia-for-2d-graphics-rendering/">announced</a> some time ago that a new rendering backend with <a href="https://skia.org/">Skia</a> was on the works and that it would eventually replace Cairo. 2.46 the first release series where Skia is used, bringing important improvements in rendering and performance.</p>
<p>While Skia can use a GPU for rendering, our testing with common embedded SoCs has shown that the way WPE WebKit works may result in slightly worse performance in some cases than letting Skia use the CPU. Hence, for the 2.46 releases the latter is the default, while development continues to improve GPU usage on low-powered devices with the ultimate goal of making accelerated rendering the default choice in all cases.</p>
<p>The Cairo backend is still present and will be selected automatically at build time for big-endian architectures, where Skia is not yet supported. We plan to remove support for Cairo in the near future, and this approach allows us to ship the new renderer while solving the remaining issues. At any rate, the Cairo renderer is no longer receiving active development.</p>
<p>It is important to notice that it is recommended to build WPE with Clang instead of GCC. This comes from upstream Skia; see their <a href="https://skia.org/docs/user/build/#supported-and-preferred-compilers">supported and preferred compilers page</a> for details.</p>
<h3 id="graphics-stack-revamped" tabindex="-1">Graphics stack revamped</h3>
<p>Tha switch to Skia has made possible a significant number of changes and improvements in the WebKit graphics stack. These changes relate to accelerated canvas, accelerated CSS filters, color spaces, and more. <a href="https://blogs.igalia.com/carlosgc/2024/09/27/graphics-improvements-in-webkitgtk-and-wpewebkit-2-46/">Carlos García has written extensively about these changes</a> in his blog, we recommend reading his article for more details.</p>
<h3 id="trace-point-profiling-with-sysprof" tabindex="-1">Trace point profiling with sysprof</h3>
<p>Sysprof is a profiling and performance analysis tool for Linux. Thanks to integration with <code>libsysprof-capture</code>, it is now possible to use Sysprof to record trace points to do profiling and performance analysis of WebKit internals. This is a major improvement that will allow us to more effectively analyze the code paths that are more performance-sensitive and find ways to optimize them. It will also allow vendors to profile their specific hardware configurations and specific use-cases as well.</p>
<p>For a more in-depth presentation of the integration with Sysprof, please read <a href="https://feaneron.com/2024/07/12/profiling-a-web-engine/">Georges Stavacras’ blog post on the topic</a>.</p>
<h3 id="api-changes" tabindex="-1">API changes</h3>
<h4 id="additions" tabindex="-1">Additions</h4>
<ul>
<li><a href="https://webkitgtk.org/reference/webkitgtk/unstable/method.Settings.apply_from_key_file.html"><code>webkit_settings_apply_from_key_file()</code></a> allows applying WebKit settings directly from a key file</li>
<li>The console message API, which had been previously deprecated, has been brought to the current API</li>
<li><a href="https://webkitgtk.org/reference/webkitgtk/2.46.0/signal.AutomationSession.will-close.html"><code>WebKitAutomationSession::will-close</code></a> signal, which allows clients to perform cleanup tasks before an automation session is closed</li>
<li><a href="https://webkitgtk.org/reference/webkitgtk/2.46.0/property.Settings.enable-2d-canvas-acceleration.html"><code>enable-2d-canvas-acceleration</code></a> WebSetting can be used to control 2D-canvas acceleration in Skia-enabled builds</li>
<li><code>webkit_web_view_toggle_inspector()</code> shows or hides the web inspector for a given webview (only available with the WPE platform API)</li>
</ul>
<h4 id="deprecations" tabindex="-1">Deprecations</h4>
<ul>
<li><code>WebKitWebView::insecure-content-detected</code> signal.</li>
<li><code>WebKitWebContext:use-system-appearance-for-scrollbars</code> property.</li>
<li><code>webkit_web_context_set_use_system_appearance_for_scrollbars()</code> and <code>webkit_web_context_get_use_system_appearance_for_scrollbars()</code>.</li>
</ul>
<h3 id="gstreamer-customizations" tabindex="-1">GStreamer customizations</h3>
<p>Compile-time platform-specific GStreamer customizations are now done at runtime, using the <code>WEBKIT_GST_QUIRKS</code> and <code>WEBKIT_GST_HOLE_PUNCH_QUIRK</code> environment variables. Setting their value to <code>help</code> will return a help message with the possible values to <code>stderr</code>. A list of the removed CMake defines:</p>
<ul>
<li><code>USE_GSTREAMER_NATIVE_VIDEO</code></li>
<li><code>USE_GSTREAMER_NATIVE_AUDIO</code></li>
<li><code>USE_GSTREAMER_TEXT_SINK</code></li>
<li><code>USE_GSTREAMER_HOLEPUNCH</code></li>
<li><code>USE_WPEWEBKIT_PLATFORM_WESTEROS</code></li>
<li><code>USE_WPEWEBKIT_PLATFORM_BCM_NEXUS</code></li>
<li><code>USE_WPEWEBKIT_PLATFORM_AMLOGIC</code></li>
<li><code>USE_WPEWEBKIT_PLATFORM_RPI</code></li>
<li><code>USE_WPEWEBKIT_PLATFORM_BROADCOM</code></li>
<li><code>USE_WESTEROS_SINK</code></li>
</ul>
<h3 id="web-platform-changes" tabindex="-1">Web Platform changes</h3>
<p>The changes to supported Web Platform features between releases of WebKit are always substantial, and for that reason listing all of those changes here would be a major endeavour. The following is an incomplete list of some of the features that have been enabled, removed, and marked in preview state since 2.44, in no particular order:</p>
<ul>
<li>CSS Container/Style Queries</li>
<li>CSS <code>text-wrap-style</code></li>
<li>CSS <code>background-clip: border-area</code></li>
<li>CSS <code>text-underline-position: left|right</code></li>
<li>CSS <code>scrollbar-width</code></li>
<li>CSS View Transitions</li>
<li>CSS Grid Masonry layout (preview)</li>
<li>CSS <code>::target-text</code> pseudo element</li>
<li>WebCrypto X25519 algorithm (preview)</li>
<li>AppCache support has been removed</li>
<li>New <code>Promise.try()</code> method</li>
<li>New <code>Observable</code> methods, like <code>.map()</code> and <code>.filter()</code></li>
</ul>
<h3 id="other-noteworthy-changes" tabindex="-1">Other noteworthy changes</h3>
<ul>
<li>Suport for the WebP image format is now always enabled.</li>
<li>WebDriver clients may now connect to an already running process, instead of always needing to spawn a new one.</li>
<li>The <code>gst-libav</code> AAC decoders are now disabled due to outstanding bugs. Distributors are encouraged to use the GStreamer FDK AAC decoder (part of <code>gst-plugins-bad</code>) instead.</li>
</ul>
<h3 id="and-much-more!" tabindex="-1">And much more!</h3>
<p>WebKit evolves and changes a lot between major stable releases. Listing all changes would not be possible. There are countless bug fixes, performance improvements, new web features supported, and so on. We recommend checking the <a href="https://wpewebkit.org/release/">release notes</a> and the git log for more details.</p>
<p>The WPE WebKit team is already working on the 2.48 release, schedule for early next year. Until then!</p>
Update on the Layer Based SVG Engine (LBSE) in WebKit2024-05-21T00:00:00Zhttps://wpewebkit.org/blog/status-of-lbse-in-webkit.html<p>This blog entry gives an update on what we at <a href="https://www.igalia.com/">Igalia</a> have done on upstreaming and development of LBSE in WebKit in the last seven months. For an explanation of
what LBSE is and how it is related to WPE, see this <a href="https://wpewebkit.org/blog/05-new-svg-engine.html">previous entry</a> as a refresher.</p>
<div style="float: right">
<figure>
<a class="btn" href="https://www.igalia.com/" target="_blank"><img style="display: block; height: 100px;" src="https://wpewebkit.org/assets/svg/igalia-tagline.svg" alt="The Igalia logo" />
</a>
</figure>
<figure>
<a class="btn" href="https://wix.com/" target="_blank"><img style="display: block; height: 60px;" src="https://wpewebkit.org/assets/svg/wix-logo.svg" alt="The Wix logo" />
</a>
</figure>
</div>
<p>Thanks to generous funding by <a href="https://www.wix.com/" alt="Wix homepage"><b>Wix</b></a>, which extensively uses SVG in their products and has a broad
knowledge of the SVG peculiarities across browser engines, LBSE has made great progress in the past seven months. During this period, several advanced SVG painting
features were implemented (e.g. clip-paths, masks, gradients, patterns), along with important performance improvements that expanded the new engine’s capabilities
and stability. All this was possible thanks to Wix’s decision to address their problems by funding upstream work at the core of WebKit, instead of accepting
the status-quo and implementing case-by-case fixes and workarounds on their end. As a result, WebKit-based browsers now benefit from the results of this fruitful
collaboration, which we’ll try to explain in more detail in this blog post.</p>
<h2 id="project-kick-off-and-webkit-contributors-meeting" tabindex="-1">Project kick off and WebKit Contributors Meeting</h2>
<p>In <strong>October 2023</strong> we started the project mostly by thinking about the design and roadmap. We also did some general SVG bug fixing. For example, visual overflow computation for SVG renderers was <a href="https://commits.webkit.org/268981@main">corrected</a>, which fixed quite a few SVG pixel tests. Various visual bugs were also fixed, such as <a href="https://commits.webkit.org/269034@main">unnecessary repainting when <code>viewBox</code> is used on <svg> elements</a>, and <a href="https://commits.webkit.org/269360@main">incorrect clipping for outermost <svg> elements</a></p>
<p>Also in the same month, we attended the <a href="https://docs.webkit.org/Other/Contributor%20Meetings/ContributorMeeting2023.html">WebKit Contributors Meeting</a>, where we presented a talk on the LBSE (<a href="https://www.slideshare.net/igalia/integrating-the-new-layerbased-svg-engine">slides are available here</a>). The feedback on LBSE at the meeting was very positive. Giving the talk early on in the process actually helped us since we needed to have a good design in place.</p>
<h2 id="supporting-svg-resources" tabindex="-1">Supporting SVG resources</h2>
<p>The main focus in <strong>October 2023</strong> was introducing the SVG resource concept, as already outlined in the WebKit Contributors Meeting talk. Thus, we started with <a href="https://commits.webkit.org/269522@main">adding a base SVG resource class: <code>RenderSVGResourceContainer</code> </a>. This class was kept as simple as possible, with no support for resource invalidation or repainting logic. The main task of <code>RenderSVGResourceContainer</code> is to take care of registration so that the resource can be looked up by its clients.</p>
<p>For the first SVG resource to implement, we chose the SVG <clip-path> element, so we landed <a href="https://commits.webkit.org/269635@main"><code>RenderSVGResourceClipper</code></a>. To comply with the specification, the <code>RenderSVGResourceClipper</code> implementation produces 1-bit masks and uses a special rendering mode:</p>
<ul>
<li><code>fill-opacity</code>/<code>stroke-opacity</code>/<code>opacity</code> set to <code>1</code></li>
<li>masker/filter not applied when rendering the children</li>
<li><code>fill</code> set to solid black and <code>stroke</code> set to <code>none</code></li>
</ul>
<p>The initial implementation did not use caching of ImageBuffers for clipping, but relied on Porter-Duff DestinationIn/SourceOver compositing operations to achieve the same effect, but faster. By integrating <code>RenderSVGResourceClipper</code> properly into <code>RenderLayer</code>, it aligned SVG clipping with HTML/CSS clipping.</p>
<p>Finally, the implementation prefers a pure clipping solution internally, as in legacy rendering, but for more complicated clip-paths (for example when the clip-path involves text content), a fallback to a mask is done.</p>
<h2 id="resource-invalidation-handling" tabindex="-1">Resource invalidation handling</h2>
<p>After introducing the first SVG resource (<code>RenderSVGResourceClipper</code>), we noticed some issues with handling invalidations for it, such as adding to clip-path contents. In the legacy engine, invalidations have been handled through layouting. This caused various problems: for one, it could cause calling the <code>setNeedsLayout</code> method from within layout, which meant the invalidation chain depended on the DOM order.</p>
<p>In <strong>November 2023</strong>, <a href="https://commits.webkit.org/271017@main">an implementation landed</a> that avoided using layout for resource invalidation. Instead, on dynamic updates, the style system is used to determine the appropriate action:</p>
<ul>
<li>For non resources, changes that cause renderer geometry changes, like changing the <code>x</code> value of a <rect> element, still require a relayout. For visual changes not affecting geometry, like changing the fill color of a <rect>, a repaint action is enough.</li>
<li>For resources, the resource is invalidated/updated with the change and any of its clients are repainted using the new resource.</li>
</ul>
<h2 id="support-for-masks" tabindex="-1">Support for masks</h2>
<p>With improved support for SVG resource invalidation, in <strong>late November 2023</strong> we were ready to upstream support for the next SVG resource, <a href="https://commits.webkit.org/271153@main">RenderSVGResourceMasker</a>.</p>
<p>Like the support for clip-path, <code>RenderSVGResourceMasker</code> started out without caching image buffers and relied on creating temporary image buffers at rendering time. Mask content invalidations/changes were supported out of the box since we had improved resource invalidation handling (see above).</p>
<h2 id="support-for-gradients" tabindex="-1">Support for gradients</h2>
<p>In early <strong>January 2024</strong>, <a href="https://commits.webkit.org/272653@main">support for SVG gradients was upstreamed</a>. Gradients are a kind of SVG resource that is a bit different to the previously implemented clipping paths and masks because it is a <a href="https://www.w3.org/TR/SVG2/pservers.html">paint server</a>, so a helper class for that called <code>SVGPaintServerHandling</code> and a base class <code>RenderSVGResourcePaintServer</code> were introduced. The main difference is in invalidation: paint servers simply need a repaint of all its clients on invalidation, whereas clipping paths/masks may need to do more work; i.e., masks underlying image buffers need to be updated before its clients can be repainted.</p>
<h2 id="support-for-patterns-and-markers" tabindex="-1">Support for patterns and markers</h2>
<p>By the end of <strong>January 2024</strong>, <a href="https://commits.webkit.org/273757@main">support for SVG patterns was upstreamed</a>. In the first implementation, no image buffer caching was implemented in order to keep things clean and simple. This implementation is different from the legacy implementation because the pattern contents are being rendered through pattern content layers (see <a href="https://github.com/WebKit/WebKit/blob/main/Source/WebCore/rendering/RenderLayer.cpp#L2846"><code>RenderLayer::paintSVGResourceLayer</code></a>). To make this work, <code>RenderSVGResourcePattern</code> has to set up the graphics context matrix correctly before calling <code>paintSVGResourceLayer</code>.</p>
<p>Around that same time, we implemented the next to last SVG resource on our TODO list, namely <a href="https://commits.webkit.org/273820@main">SVG markers</a>.</p>
<h2 id="svg-filters" tabindex="-1">SVG filters</h2>
<p>In <strong>February 2024</strong>, Apple started work on <a href="https://github.com/WebKit/WebKit/pull/25087">supporting SVG filters</a> in LBSE. A first iteration managed to fix a lot of the official SVG filter tests, but it turned out a <a href="https://github.com/WebKit/WebKit/pull/25512">filter regression</a> had to be fixed first. Moreover, the initial work uncovered issues with the HTML/CSS filters implementation that need to be fixed in general. Finally, another reason why this support takes more time than some other features is that there is a strong requirement to make the support efficient in both memory usage and overall (re)painting speed. Still, the early results are very promising!</p>
<h2 id="cycle-detection" tabindex="-1">Cycle detection</h2>
<p>It is quite easy in SVG to cause direct circular references:</p>
<pre class="language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>svg</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>defs</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>pattern</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>p<span class="token punctuation">"</span></span> <span class="token attr-name"><span class="token namespace">xlink:</span>href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>#p<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>defs</span><span class="token punctuation">></span></span>
...
<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>svg</span><span class="token punctuation">></span></span></code></pre>
<p>It is also possible to cause indirect circular references:</p>
<pre class="language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>svg</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>defs</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>mask</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>z<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>rect</span> <span class="token attr-name">mask</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>url(#z)<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>mask</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>defs</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>ellipse</span> <span class="token attr-name">mask</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>url(#z)<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>svg</span><span class="token punctuation">></span></span></code></pre>
<p>The legacy engine solved this in an ad-hoc way in various places in the engine; it tried to break cycles before rendering, but still needed cycle protections in various places, since the solution was never unified or complete.</p>
<p>In <strong>February 2024</strong> we provided a unified solution for LBSE by introducing <code>SVGVisitedRendererTracking</code>; <a href="https://commits.webkit.org/274392@main">see this commit</a> for more. In the new approach, we don’t attempt to remove cycles, but detect them everywhere upon usage and stop processing in well-defined ways, all centralized in <code>SVGVisitedRendererTracking</code>.</p>
<h2 id="nested-mask%2Fpattern-slowness" tabindex="-1">Nested mask/pattern slowness</h2>
<p>In <strong>April 2024</strong>, we addressed the slowness problems with nested masks/patterns. As an example, consider this for nested masks:</p>
<pre class="language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>svg</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>defs</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>mask</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>z<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>rect</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>1<span class="token punctuation">"</span></span> <span class="token attr-name">mask</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>url(#y)<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>rect</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>2<span class="token punctuation">"</span></span> <span class="token attr-name">mask</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>url(#y)<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span>
...
<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>mask</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>mask</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>y<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>rect</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>1<span class="token punctuation">"</span></span> <span class="token attr-name">mask</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>url(#x)<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>rect</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>2<span class="token punctuation">"</span></span> <span class="token attr-name">mask</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>url(#x)<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span>
...
<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>mask</span><span class="token punctuation">></span></span>
...
<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>defs</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>ellipse</span> <span class="token attr-name">mask</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>url(#z)<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>svg</span><span class="token punctuation">></span></span></code></pre>
<p>For this example, the complexity can be increased at will by adding more masks and contents per mask.</p>
<p>The solution was twofold:</p>
<ul>
<li>For masks, we realized bounding box calculations for a mask were not affected by masks used in the mask contents, so we could cut off bounding box calculations for nested masks.</li>
<li>For both masks and patterns, we added caching of image buffers per resource client so nested masks/patterns that are already encountered can reuse the image buffer cache.</li>
</ul>
<p>See optimizations here for nested <a href="https://commits.webkit.org/273820@main">masks</a> and <a href="https://commits.webkit.org/277306@main">patterns</a>.</p>
<h2 id="next-steps" tabindex="-1">Next steps</h2>
<p>For the short and mid-term, the plan is to make LBSE at least as good as legacy in regards to test coverage; i.e., all tests that pass in legacy should pass in LBSE. We have made a lot of progress over the
last seven months just because of the amount of SVG resources that were implemented, but for example ,we will need to have SVG filters in place to pass this goal.</p>
<p>Another goal is to make sure LBSE passes all security requirements, as failing that would be a blocker to replacing the current engine. Fortunately, we are already taking this into account in several ways, such as adopting a lot of good <a href="https://github.com/WebKit/WebKit/wiki/Smart-Pointer-Usage-Guidelines">smart pointer practices</a>.</p>
<p>Finally, a big goal will be for LBSE to perform well on certain benchmarks like <a href="https://browserbench.org/MotionMark1.2/">MotionMark</a>, since WebKit has a golden rule to never ship a performance regression. So far there has not been an explicit focus
on performance, and we know there are likely optimizations possible in <code>RenderLayer</code> usage, both in reducing the number of <code>RenderLayer</code> objects we create in certain situations as well as a possible reduction in complexity of <code>RenderLayer</code> for LBSE usage.</p>
<p>All in all, we are very pleased with the results and the progress we made in the last seven months. We at <a href="https://www.igalia.com/">Igalia</a> look forward to finishing the work to get the new engine in a shippable state in the near future!</p>