Branch: refs/heads/main
  Home:   https://github.com/WebKit/WebKit
  Commit: 48bf47fef51c61baf918a618ab851081493bf1ca
      
https://github.com/WebKit/WebKit/commit/48bf47fef51c61baf918a618ab851081493bf1ca
  Author: Nikolas Zimmermann <[email protected]>
  Date:   2026-03-02 (Mon, 02 Mar 2026)

  Changed paths:
    M Source/WebCore/platform/Skia.cmake
    M Source/WebCore/platform/SourcesSkia.txt
    M Source/WebCore/platform/graphics/NativeImage.h
    M Source/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp
    M Source/WebCore/platform/graphics/skia/NativeImageSkia.cpp
    A Source/WebCore/platform/graphics/skia/SkiaGPUAtlas.cpp
    A Source/WebCore/platform/graphics/skia/SkiaGPUAtlas.h
    M Source/WebCore/platform/graphics/skia/SkiaPaintingEngine.cpp
    M Source/WebCore/platform/graphics/skia/SkiaPaintingEngine.h
    M Source/WebCore/platform/graphics/skia/SkiaRecordingResult.cpp
    M Source/WebCore/platform/graphics/skia/SkiaRecordingResult.h
    A Source/WebCore/platform/graphics/skia/SkiaReplayAtlas.cpp
    A Source/WebCore/platform/graphics/skia/SkiaReplayAtlas.h
    M Source/WebCore/platform/graphics/skia/SkiaReplayCanvas.cpp
    M Source/WebCore/platform/graphics/skia/SkiaReplayCanvas.h
    M Source/WebCore/platform/graphics/texmap/BitmapTexture.cpp

  Log Message:
  -----------
  [GTK][WPE] Implement GPU atlas creation and replay substitution for batched 
raster image uploads
https://bugs.webkit.org/show_bug.cgi?id=308166

Reviewed by Carlos Garcia Campos.

This builds on the previous atlas layout computation to complete
the texture atlas pipeline for batching raster image uploads in
the Skia painting engine.

During the recording phase, raster images are collected and packed
into atlas layouts. After recording, SkiaPaintingEngine now creates
GPU atlases on the main thread by acquiring BitmapTextures from the
texture pool and composing the raster image pixels into them. Two
composition paths are supported: a DMA-buf path that memory-maps
the GPU buffer for direct pixel writes (optimized - dispatched to a
dedicated composition worker thread), and a GL fallback path that
uses BitmapTexture::updateContents() synchronously. A single GL
fence is inserted after all atlas uploads to allow worker threads
to wait for completion before using the textures.

The DMA-buf atlas composition path is enabled by default on
platforms supporting GBM. It can be disabled at runtime by setting
the WEBKIT_DISABLE_DMABUF_ATLAS environment variable to 1.

Async DMA-buf atlas composition is synchronized using an
AtlasCompositionFence countdown latch (Lock + Condition). A single
fence is shared across all atlas compositions for a given recording,
with addPending()/signal() counting dispatched work and wait()
blocking replay workers until all compositions complete.

On the replay side, SkiaReplayCanvas now creates per-worker
SkiaReplayAtlas wrappers that rewrap the pre-uploaded GPU textures
for each worker thread's GrDirectContext. During picture playback,
onDrawImage2() and onDrawImageRect2() intercept raster image draws
and substitute them with atlas texture draws, mapping source
coordinates into atlas space.

All atlas draw paths use kStrict_SrcRectConstraint to prevent
texture bleeding artifacts. When drawing from a standalone image,
kFast_SrcRectConstraint is safe because sampling beyond the source
rect just clamps to the image's own edge pixels. However, when
drawing a sub-region from an atlas texture, sampling beyond the
source rect would read pixels from adjacent images in the atlas,
producing visible edge artifacts. kStrict_SrcRectConstraint tells
Skia to clamp texture sampling strictly within the source rect.

Images with non-sRGB color spaces (e.g. linear RGB from SVG filter
results rendered with color-interpolation-filters: linearRGB) are
converted to sRGB during atlas composition. The atlas texture is
always tagged sRGB, so without conversion the raw pixel data would
be misinterpreted, causing visible color shifts (darker colors).
The conversion uses Skia's built-in readPixels() with an sRGB
target SkImageInfo. sRGB and untagged images use a zero-copy
peekPixels() fast path.

Covered by existing tests.

* Source/WebCore/platform/Skia.cmake:
* Source/WebCore/platform/SourcesSkia.txt:
* Source/WebCore/platform/graphics/NativeImage.h:
* Source/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp:
(WebCore::GraphicsContextSkia::drawNativeImage):
(WebCore::GraphicsContextSkia::beginRecording):
(WebCore::GraphicsContextSkia::endRecording):
* Source/WebCore/platform/graphics/skia/NativeImageSkia.cpp:
(WebCore::NativeImage::uniqueID const):
* Source/WebCore/platform/graphics/skia/SkiaGPUAtlas.cpp: Added.
(WebCore::SkiaGPUAtlas::SkiaGPUAtlas):
(WebCore::SkiaGPUAtlas::create):
(WebCore::SkiaGPUAtlas::uploadImages):
* Source/WebCore/platform/graphics/skia/SkiaGPUAtlas.h: Added.
(WebCore::SkiaGPUAtlas::backendTexture const):
(WebCore::SkiaGPUAtlas::imageToRect const):
(WebCore::SkiaGPUAtlas::size const):
(WebCore::SkiaGPUAtlas::atlasTexture const):
* Source/WebCore/platform/graphics/skia/SkiaPaintingEngine.cpp:
(WebCore::SkiaPaintingEngine::SkiaPaintingEngine):
(WebCore::SkiaPaintingEngine::createAtlas):
(WebCore::SkiaPaintingEngine::record):
(WebCore::SkiaPaintingEngine::replay):
(WebCore::SkiaPaintingEngine::shouldUseDMABufAtlasTextures):
* Source/WebCore/platform/graphics/skia/SkiaPaintingEngine.h:
(WebCore::SkiaPaintingEngine::useThreadedRendering const):
* Source/WebCore/platform/graphics/skia/SkiaRecordingResult.cpp:
(WebCore::SkiaRecordingResult::waitForUploadFence):
(WebCore::SkiaRecordingResult::waitForUploadCondition):
* Source/WebCore/platform/graphics/skia/SkiaRecordingResult.h:
(WebCore::AtlasUploadCondition::create):
(WebCore::AtlasUploadCondition::addPending):
(WebCore::AtlasUploadCondition::signal):
(WebCore::AtlasUploadCondition::wait):
(WebCore::AtlasUploadCondition::WTF_GUARDED_BY_LOCK):
* Source/WebCore/platform/graphics/skia/SkiaReplayAtlas.cpp: Added.
(WebCore::SkiaReplayAtlas::SkiaReplayAtlas):
(WebCore::SkiaReplayAtlas::create):
(WebCore::SkiaReplayAtlas::rectForImage const):
* Source/WebCore/platform/graphics/skia/SkiaReplayAtlas.h: Copied from 
Source/WebCore/platform/graphics/skia/SkiaRecordingResult.cpp.
(WebCore::SkiaReplayAtlas::atlasTexture const):
* Source/WebCore/platform/graphics/skia/SkiaReplayCanvas.cpp:
(WebCore::SkiaReplayCanvas::SkiaReplayCanvas):
(WebCore::SkiaReplayCanvas::create):
(WebCore::SkiaReplayCanvas::onDrawImage2):
(WebCore::SkiaReplayCanvas::onDrawImageRect2):
* Source/WebCore/platform/graphics/skia/SkiaReplayCanvas.h:
* Source/WebCore/platform/graphics/texmap/BitmapTexture.cpp:
(WebCore::BitmapTexture::BitmapTexture):
(WebCore::BitmapTexture::reset):
Fix a problem with the untested code path, pixelFormat was wrong
when using the BGRALayout flag

Canonical link: https://commits.webkit.org/308458@main



To unsubscribe from these emails, change your notification settings at 
https://github.com/WebKit/WebKit/settings/notifications

Reply via email to