WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
NEW
311103
REGRESSION(
308458@main
): [GTK] white noise images
https://bugs.webkit.org/show_bug.cgi?id=311103
Summary
REGRESSION(308458@main): [GTK] white noise images
Fujii Hironori
Reported
2026-03-30 05:52:09 PDT
After
308458@main
, images sometimes have white noise on my laptop. However, no such problem on my desktop.
Attachments
screenshot
(1.16 MB, image/png)
2026-03-30 18:09 PDT
,
Fujii Hironori
no flags
Details
View All
Add attachment
proposed patch, testcase, etc.
Fujii Hironori
Comment 1
2026-03-30 18:09:52 PDT
Created
attachment 478852
[details]
screenshot
Fujii Hironori
Comment 2
2026-04-12 18:54:35 PDT
Adding sleep can work around the issue. However, it becomes slow. diff --git a/Source/WebCore/platform/graphics/skia/SkiaReplayCanvas.cpp b/Source/WebCore/platform/graphics/skia/SkiaReplayCanvas.cpp index 482ac8d7f28e..86dc824bc8c9 100644 --- a/Source/WebCore/platform/graphics/skia/SkiaReplayCanvas.cpp +++ b/Source/WebCore/platform/graphics/skia/SkiaReplayCanvas.cpp @@ -47,6 +47,7 @@ SkiaReplayCanvas::SkiaReplayCanvas(const IntSize& size, const RefPtr<SkiaRecordi m_recording->waitForUploadCondition(); m_recording->waitForUploadFence(); + sleep(500_ms); const auto& gpuAtlases = m_recording->gpuAtlases(); m_atlases.reserveInitialCapacity(gpuAtlases.size());
Fujii Hironori
Comment 3
2026-04-12 20:21:09 PDT
No. It still happens with the patch. Lower probability.
Fujii Hironori
Comment 4
2026-04-12 21:15:44 PDT
Setting WEBKIT_DISABLE_DMABUF_ATLAS=1 can work around the issue.
Nikolas Zimmermann
Comment 5
2026-04-13 02:30:52 PDT
I guess the problem is related to updating the dma-buf from another thread: ``` // DMA-buf path: create atlas without uploading, dispatch pixel writes to worker. if (!m_uploadWorkQueue) m_uploadWorkQueue = WorkQueue::create("AtlasUpload"_s); uploadCondition.addPending(); m_uploadWorkQueue->dispatch([atlas = Ref { *atlas }, condition = Ref { uploadCondition }]() mutable { atlas->uploadImages(); condition->signal(); }); return atlas; ```
Nikolas Zimmermann
Comment 6
2026-04-13 02:33:55 PDT
Maybe it is related to sharing the same write scope for multiple disjoint writes -- which should work in theory, but maybe there's a driver dependent issue. Can you create the writeScope inside the inner for loop instead of outside? ``` bool SkiaGPUAtlas::uploadImages() { ... #if USE(GBM) if (auto* gpuBuffer = m_atlasTexture->memoryMappedGPUBuffer()) { if (gpuBuffer->isLinear() || gpuBuffer->isVivanteSuperTiled()) { for (const auto& entry : m_layout->entries()) { auto writeScope = makeGPUBufferWriteScope(*gpuBuffer); if (!writeScope) return false; if (auto pixels = pixelDataInSRGB(entry.rasterImage)) gpuBuffer->updateContents(*writeScope, pixels->first, entry.atlasRect, pixels->second); } return true; } } #endif ```
Fujii Hironori
Comment 7
2026-04-13 03:41:08 PDT
Unfortunately, it has no effect. diff --git a/Source/WebCore/platform/graphics/skia/SkiaGPUAtlas.cpp b/Source/WebCore/platform/graphics/skia/SkiaGPUAtlas.cpp index 4d5a36f96e60..bb8375c96661 100644 --- a/Source/WebCore/platform/graphics/skia/SkiaGPUAtlas.cpp +++ b/Source/WebCore/platform/graphics/skia/SkiaGPUAtlas.cpp @@ -101,11 +101,10 @@ bool SkiaGPUAtlas::uploadImages() #if USE(GBM) if (auto* gpuBuffer = m_atlasTexture->memoryMappedGPUBuffer()) { if (gpuBuffer->isLinear() || gpuBuffer->isVivanteSuperTiled()) { - auto writeScope = makeGPUBufferWriteScope(*gpuBuffer); - if (!writeScope) - return false; - for (const auto& entry : m_layout->entries()) { + auto writeScope = makeGPUBufferWriteScope(*gpuBuffer); + if (!writeScope) + return false; if (auto pixels = pixelDataInSRGB(entry.rasterImage)) gpuBuffer->updateContents(*writeScope, pixels->first, entry.atlasRect, pixels->second); }
Nikolas Zimmermann
Comment 8
2026-04-13 04:04:44 PDT
Ok, one things less to check. Please test instead: Changing: ``` // DMA-buf path: create atlas without uploading, dispatch pixel writes to worker. if (!m_uploadWorkQueue) m_uploadWorkQueue = WorkQueue::create("AtlasUpload"_s); uploadCondition.addPending(); m_uploadWorkQueue->dispatch([atlas = Ref { *atlas }, condition = Ref { uploadCondition }]() mutable { atlas->uploadImages(); condition->signal(); }); return atlas; ``` To: ``` // DMA-buf path: create atlas without uploading, dispatch pixel writes to worker. atlas->uploadImages(); uploadCondition->signal(); return atlas; ``` That does the uploads on the main thread instead of a worker thread.
Nikolas Zimmermann
Comment 9
2026-04-13 04:05:23 PDT
(Not fully correct, you need the addPending()... - but you get the idea, just remove the work queue out of the condition)
Note
You need to
log in
before you can comment on or make changes to this bug.
Top of Page
Format For Printing
XML
Clone This Bug