Skip to content

Commit 5abe8ab

Browse files
[GTK][WPE][Skia] Record all dirty tiles of a layer once, don't record each tile
https://bugs.webkit.org/show_bug.cgi?id=290614 Reviewed by Carlos Garcia Campos. For each layer, we currently record each dirty tile, then replay in a worker thread. We can do better and once record a SkPicture of the area spanning all dirty tiles, and then use the same SkPicture for replaying N times, for each dirty tile. Covered by existing tests. * Source/WebCore/platform/Skia.cmake: * Source/WebCore/platform/SourcesSkia.txt: * Source/WebCore/platform/graphics/skia/SkiaPaintingEngine.cpp: (WebCore::SkiaPaintingEngine::paint): (WebCore::SkiaPaintingEngine::record): (WebCore::SkiaPaintingEngine::replay): (WebCore::SkiaPaintingEngine::paintGraphicsLayerIntoBuffer const): Deleted. (WebCore::SkiaPaintingEngine::paintLayer): Deleted. (WebCore::SkiaPaintingEngine::postPaintingTask): Deleted. (WebCore::SkiaPaintingEngine::performPaintingTask): Deleted. * Source/WebCore/platform/graphics/skia/SkiaPaintingEngine.h: (WebCore::SkiaPaintingEngine::useThreadedRendering const): * Source/WebCore/platform/graphics/skia/SkiaRecordingResult.cpp: Added. (WebCore::SkiaRecordingResult::SkiaRecordingResult): (WebCore::SkiaRecordingResult::create): (WebCore::SkiaRecordingResult::hasFences): (WebCore::SkiaRecordingResult::waitForFenceIfNeeded): * Source/WebCore/platform/graphics/skia/SkiaRecordingResult.h: Added. * Source/WebCore/platform/graphics/skia/SkiaReplayCanvas.cpp: (WebCore::SkiaReplayCanvas::SkiaReplayCanvas): (WebCore::SkiaReplayCanvas::create): (WebCore::SkiaReplayCanvas::waitForRenderingCompletionAndRewrapImageIfNeeded): * Source/WebCore/platform/graphics/skia/SkiaReplayCanvas.h: * Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedBackingStoreProxy.cpp: (WebCore::CoordinatedBackingStoreProxy::updateIfNeeded): * Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedPlatformLayer.cpp: (WebCore::CoordinatedPlatformLayer::paint): (WebCore::CoordinatedPlatformLayer::record): (WebCore::CoordinatedPlatformLayer::replay): * Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedPlatformLayer.h: Canonical link: https://commits.webkit.org/292929@main
1 parent b12d8ef commit 5abe8ab

11 files changed

Lines changed: 251 additions & 97 deletions

‎Source/WebCore/platform/Skia.cmake‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ list(APPEND WebCore_PRIVATE_FRAMEWORK_HEADERS
1616
platform/graphics/skia/SkiaHarfBuzzFont.h
1717
platform/graphics/skia/SkiaHarfBuzzFontCache.h
1818
platform/graphics/skia/SkiaPaintingEngine.h
19+
platform/graphics/skia/SkiaRecordingResult.h
1920
platform/graphics/skia/SkiaReplayCanvas.h
2021
platform/graphics/skia/SkiaSpanExtras.h
2122
)

‎Source/WebCore/platform/SourcesSkia.txt‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ platform/graphics/skia/ShareableBitmapSkia.cpp
6161
platform/graphics/skia/SkiaHarfBuzzFont.cpp
6262
platform/graphics/skia/SkiaHarfBuzzFontCache.cpp
6363
platform/graphics/skia/SkiaPaintingEngine.cpp
64+
platform/graphics/skia/SkiaRecordingResult.cpp
6465
platform/graphics/skia/SkiaReplayCanvas.cpp
6566

6667
platform/skia/SharedBufferSkia.cpp

‎Source/WebCore/platform/graphics/skia/SkiaPaintingEngine.cpp‎

Lines changed: 48 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -30,19 +30,16 @@
3030
#include "BitmapTexturePool.h"
3131
#include "CoordinatedTileBuffer.h"
3232
#include "GLContext.h"
33-
#include "GLFence.h"
34-
#include "GraphicsContextSkia.h"
3533
#include "GraphicsLayer.h"
3634
#include "PlatformDisplay.h"
3735
#include "ProcessCapabilities.h"
3836
#include "RenderingMode.h"
37+
#include "SkiaRecordingResult.h"
3938
#include "SkiaReplayCanvas.h"
4039
WTF_IGNORE_WARNINGS_IN_THIRD_PARTY_CODE_BEGIN
41-
#include <skia/core/SkPicture.h>
4240
#include <skia/core/SkPictureRecorder.h>
4341
#include <skia/gpu/ganesh/GrBackendSurface.h>
4442
#include <skia/gpu/ganesh/SkImageGanesh.h>
45-
#include <skia/utils/SkNWayCanvas.h>
4643
WTF_IGNORE_WARNINGS_IN_THIRD_PARTY_CODE_END
4744
#include <wtf/NumberOfCores.h>
4845
#include <wtf/SystemTracing.h>
@@ -106,22 +103,6 @@ void SkiaPaintingEngine::paintIntoGraphicsContext(const GraphicsLayer& layer, Gr
106103
layer.paintGraphicsLayerContents(context, clipRect);
107104
}
108105

109-
bool SkiaPaintingEngine::paintGraphicsLayerIntoBuffer(Ref<CoordinatedTileBuffer>& buffer, const GraphicsLayer& layer, const IntRect& dirtyRect, bool contentsOpaque, float contentsScale) const
110-
{
111-
auto* canvas = buffer->canvas();
112-
if (!canvas)
113-
return false;
114-
115-
canvas->save();
116-
canvas->clear(SkColors::kTransparent);
117-
118-
GraphicsContextSkia context(*canvas, buffer->isBackedByOpenGL() ? RenderingMode::Accelerated : RenderingMode::Unaccelerated, RenderingPurpose::LayerBacking);
119-
paintIntoGraphicsContext(layer, context, dirtyRect, contentsOpaque, contentsScale);
120-
121-
canvas->restore();
122-
return true;
123-
}
124-
125106
bool SkiaPaintingEngine::isHybridMode() const
126107
{
127108
return m_cpuWorkerPool && m_gpuWorkerPool && canPerformAcceleratedRendering();
@@ -227,72 +208,89 @@ Ref<CoordinatedTileBuffer> SkiaPaintingEngine::createBuffer(RenderingMode render
227208
return CoordinatedUnacceleratedTileBuffer::create(size, contentsOpaque ? CoordinatedTileBuffer::NoFlags : CoordinatedTileBuffer::SupportsAlpha);
228209
}
229210

230-
Ref<CoordinatedTileBuffer> SkiaPaintingEngine::paintLayer(const GraphicsLayer& layer, const IntRect& dirtyRect, bool contentsOpaque, float contentsScale)
211+
Ref<CoordinatedTileBuffer> SkiaPaintingEngine::paint(const GraphicsLayer& layer, const IntRect& dirtyRect, bool contentsOpaque, float contentsScale)
231212
{
232213
// ### Synchronous rendering on main thread ###
233-
if (!m_cpuWorkerPool && !m_gpuWorkerPool) {
234-
auto renderingMode = canPerformAcceleratedRendering() ? RenderingMode::Accelerated : RenderingMode::Unaccelerated;
235-
return performPaintingTask(layer, renderingMode, dirtyRect, contentsOpaque, contentsScale);
236-
}
214+
ASSERT(!useThreadedRendering());
237215

238-
// ### Asynchronous rendering on worker threads ###
216+
auto renderingMode = canPerformAcceleratedRendering() ? RenderingMode::Accelerated : RenderingMode::Unaccelerated;
239217

240-
// ### Hybrid CPU/GPU mode ###
241-
if (isHybridMode()) {
242-
auto renderingMode = decideHybridRenderingMode(dirtyRect, contentsScale);
243-
return postPaintingTask(layer, renderingMode, dirtyRect, contentsOpaque, contentsScale);
244-
}
218+
auto buffer = createBuffer(renderingMode, dirtyRect.size(), contentsOpaque);
219+
buffer->beginPainting();
245220

246-
// ### CPU-only mode ###
247-
if (m_cpuWorkerPool)
248-
return postPaintingTask(layer, RenderingMode::Unaccelerated, dirtyRect, contentsOpaque, contentsScale);
221+
if (auto* canvas = buffer->canvas()) {
222+
WTFBeginSignpost(canvas, PaintTile, "Skia/%s, dirty region %ix%i+%i+%i", buffer->isBackedByOpenGL() ? "GPU" : "CPU", dirtyRect.x(), dirtyRect.y(), dirtyRect.width(), dirtyRect.height());
223+
canvas->save();
224+
canvas->clear(SkColors::kTransparent);
249225

250-
// ### GPU-only mode ###
251-
if (m_gpuWorkerPool && canPerformAcceleratedRendering())
252-
return postPaintingTask(layer, RenderingMode::Accelerated, dirtyRect, contentsOpaque, contentsScale);
226+
GraphicsContextSkia context(*canvas, renderingMode, RenderingPurpose::LayerBacking);
227+
paintIntoGraphicsContext(layer, context, dirtyRect, contentsOpaque, contentsScale);
253228

254-
ASSERT_NOT_REACHED();
255-
return performPaintingTask(layer, RenderingMode::Unaccelerated, dirtyRect, contentsOpaque, contentsScale);
229+
canvas->restore();
230+
WTFEndSignpost(canvas, PaintTile);
231+
}
232+
233+
buffer->completePainting();
234+
return buffer;
256235
}
257236

258-
Ref<CoordinatedTileBuffer> SkiaPaintingEngine::postPaintingTask(const GraphicsLayer& layer, RenderingMode renderingMode, const IntRect& dirtyRect, bool contentsOpaque, float contentsScale)
237+
Ref<SkiaRecordingResult> SkiaPaintingEngine::record(const GraphicsLayer& layer, const IntRect& recordRect, bool contentsOpaque, float contentsScale)
259238
{
260-
auto buffer = createBuffer(renderingMode, dirtyRect.size(), contentsOpaque);
261-
buffer->beginPainting();
239+
// ### Asynchronous rendering on worker threads ###
240+
ASSERT(useThreadedRendering());
241+
242+
auto renderingMode = canPerformAcceleratedRendering() ? RenderingMode::Accelerated : RenderingMode::Unaccelerated;
262243

263244
WTFBeginSignpost(this, RecordTile);
264245
SkPictureRecorder pictureRecorder;
265-
auto* recordingCanvas = pictureRecorder.beginRecording(dirtyRect.width(), dirtyRect.height());
246+
auto* recordingCanvas = pictureRecorder.beginRecording(recordRect.width(), recordRect.height());
266247
GraphicsContextSkia recordingContext(*recordingCanvas, renderingMode, RenderingPurpose::LayerBacking);
267248
recordingContext.beginRecording();
268-
paintIntoGraphicsContext(layer, recordingContext, dirtyRect, contentsOpaque, contentsScale);
249+
paintIntoGraphicsContext(layer, recordingContext, recordRect, contentsOpaque, contentsScale);
269250
auto imageToFenceMap = recordingContext.endRecording();
270251
auto picture = pictureRecorder.finishRecordingAsPicture();
271252
WTFEndSignpost(this, RecordTile);
272253

254+
return SkiaRecordingResult::create(WTFMove(picture), WTFMove(imageToFenceMap), recordRect, renderingMode, contentsOpaque, contentsScale);
255+
}
256+
257+
Ref<CoordinatedTileBuffer> SkiaPaintingEngine::replay(const RefPtr<SkiaRecordingResult>& recording, const IntRect& dirtyRect)
258+
{
259+
// ### Asynchronous rendering on worker threads ###
260+
ASSERT(useThreadedRendering());
261+
262+
auto renderingMode = recording->renderingMode();
263+
if (renderingMode == RenderingMode::Accelerated && !recording->hasFences() && isHybridMode())
264+
renderingMode = decideHybridRenderingMode(dirtyRect, recording->contentsScale());
265+
266+
auto buffer = createBuffer(renderingMode, dirtyRect.size(), recording->contentsOpaque());
267+
buffer->beginPainting();
268+
273269
auto& workerPool = renderingMode == RenderingMode::Accelerated ? *m_gpuWorkerPool.get() : *m_cpuWorkerPool.get();
274-
workerPool.postTask([buffer = Ref { buffer }, picture = sk_sp<SkPicture> { picture }, dirtyRect, imageToFenceMap = WTFMove(imageToFenceMap)]() mutable {
270+
workerPool.postTask([buffer = Ref { buffer }, dirtyRect, recording = RefPtr { recording }]() mutable {
275271
auto* canvas = buffer->canvas();
276272
if (!canvas) {
277273
buffer->completePainting();
278274
return;
279275
}
280276

281-
auto replayPicture = [&picture](SkCanvas* canvas) {
277+
auto replayPicture = [](const sk_sp<SkPicture>& picture, SkCanvas* canvas, const IntRect& recordRect, const IntRect& paintRect) {
282278
canvas->save();
283279
canvas->clear(SkColors::kTransparent);
280+
canvas->clipRect(SkRect::MakeXYWH(0, 0, paintRect.width(), paintRect.height()));
281+
canvas->translate(recordRect.x() - paintRect.x(), recordRect.y() - paintRect.y());
284282
picture->playback(canvas);
285283
canvas->restore();
286284
};
287285

288286
WTFBeginSignpost(canvas, PaintTile, "Skia/%s threaded, dirty region %ix%i+%i+%i", buffer->isBackedByOpenGL() ? "GPU" : "CPU", dirtyRect.x(), dirtyRect.y(), dirtyRect.width(), dirtyRect.height());
289-
if (!imageToFenceMap.isEmpty()) {
290-
auto replayCanvas = SkiaReplayCanvas::create(dirtyRect.size(), WTFMove(imageToFenceMap));
287+
if (recording->hasFences()) {
288+
auto replayCanvas = SkiaReplayCanvas::create(dirtyRect.size(), recording);
291289
replayCanvas->addCanvas(canvas);
292-
replayPicture(&replayCanvas.get());
290+
replayPicture(replayCanvas->picture(), &replayCanvas.get(), recording->recordRect(), dirtyRect);
293291
replayCanvas->removeCanvas(canvas);
294292
} else
295-
replayPicture(canvas);
293+
replayPicture(recording->picture(), canvas, recording->recordRect(), dirtyRect);
296294
WTFEndSignpost(canvas, PaintTile);
297295

298296
buffer->completePainting();
@@ -301,21 +299,6 @@ Ref<CoordinatedTileBuffer> SkiaPaintingEngine::postPaintingTask(const GraphicsLa
301299
return buffer;
302300
}
303301

304-
Ref<CoordinatedTileBuffer> SkiaPaintingEngine::performPaintingTask(const GraphicsLayer& layer, RenderingMode renderingMode, const IntRect& dirtyRect, bool contentsOpaque, float contentsScale)
305-
{
306-
auto buffer = createBuffer(renderingMode, dirtyRect.size(), contentsOpaque);
307-
buffer->beginPainting();
308-
309-
if (auto* canvas = buffer->canvas()) {
310-
WTFBeginSignpost(canvas, PaintTile, "Skia/%s, dirty region %ix%i+%i+%i", buffer->isBackedByOpenGL() ? "GPU" : "CPU", dirtyRect.x(), dirtyRect.y(), dirtyRect.width(), dirtyRect.height());
311-
paintGraphicsLayerIntoBuffer(buffer, layer, dirtyRect, contentsOpaque, contentsScale);
312-
WTFEndSignpost(canvas, PaintTile);
313-
}
314-
315-
buffer->completePainting();
316-
return buffer;
317-
}
318-
319302
unsigned SkiaPaintingEngine::numberOfCPUPaintingThreads()
320303
{
321304
static std::once_flag onceFlag;

‎Source/WebCore/platform/graphics/skia/SkiaPaintingEngine.h‎

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,6 @@
3030
#include <wtf/TZoneMalloc.h>
3131
#include <wtf/WorkerPool.h>
3232

33-
class SkImage;
34-
3533
namespace WebCore {
3634

3735
class BitmapTexturePool;
@@ -40,6 +38,7 @@ class GraphicsContext;
4038
class GraphicsLayer;
4139
class IntRect;
4240
class IntSize;
41+
class SkiaRecordingResult;
4342
enum class RenderingMode : uint8_t;
4443

4544
class SkiaPaintingEngine {
@@ -66,18 +65,15 @@ class SkiaPaintingEngine {
6665
static float minimumFractionOfTasksUsingGPUPainting();
6766
static HybridPaintingStrategy hybridPaintingStrategy();
6867

69-
Ref<CoordinatedTileBuffer> paintLayer(const GraphicsLayer&, const IntRect& dirtyRect, bool contentsOpaque, float contentsScale);
68+
bool useThreadedRendering() const { return m_cpuWorkerPool || m_gpuWorkerPool; }
69+
70+
Ref<CoordinatedTileBuffer> paint(const GraphicsLayer&, const IntRect& dirtyRect, bool contentsOpaque, float contentsScale);
71+
Ref<SkiaRecordingResult> record(const GraphicsLayer&, const IntRect& recordRect, bool contentsOpaque, float contentsScale);
72+
Ref<CoordinatedTileBuffer> replay(const RefPtr<SkiaRecordingResult>&, const IntRect& dirtyRect);
7073

7174
private:
7275
Ref<CoordinatedTileBuffer> createBuffer(RenderingMode, const IntSize&, bool contentsOpaque) const;
7376
void paintIntoGraphicsContext(const GraphicsLayer&, GraphicsContext&, const IntRect&, bool contentsOpaque, float contentsScale) const;
74-
bool paintGraphicsLayerIntoBuffer(Ref<CoordinatedTileBuffer>&, const GraphicsLayer&, const IntRect& dirtyRect, bool contentsOpaque, float contentsScale) const;
75-
76-
// Threaded rendering
77-
Ref<CoordinatedTileBuffer> postPaintingTask(const GraphicsLayer&, RenderingMode, const IntRect& dirtyRect, bool contentsOpaque, float contentsScale);
78-
79-
// Main thread rendering
80-
Ref<CoordinatedTileBuffer> performPaintingTask(const GraphicsLayer&, RenderingMode, const IntRect& dirtyRect, bool contentsOpaque, float contentsScale);
8177

8278
bool isHybridMode() const;
8379
RenderingMode decideHybridRenderingMode(const IntRect& dirtyRect, float contentsScale) const;
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/*
2+
* Copyright (C) 2025 Igalia S.L.
3+
*
4+
* Redistribution and use in source and binary forms, with or without
5+
* modification, are permitted provided that the following conditions
6+
* are met:
7+
* 1. Redistributions of source code must retain the above copyright
8+
* notice, this list of conditions and the following disclaimer.
9+
* 2. Redistributions in binary form must reproduce the above copyright
10+
* notice, this list of conditions and the following disclaimer in the
11+
* documentation and/or other materials provided with the distribution.
12+
*
13+
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14+
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16+
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17+
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18+
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19+
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20+
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21+
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24+
*/
25+
26+
#include "config.h"
27+
#include "SkiaRecordingResult.h"
28+
29+
#if USE(COORDINATED_GRAPHICS) && USE(SKIA)
30+
31+
namespace WebCore {
32+
33+
SkiaRecordingResult::SkiaRecordingResult(sk_sp<SkPicture>&& picture, SkiaImageToFenceMap&& imageToFenceMap, const IntRect& recordRect, RenderingMode renderingMode, bool contentsOpaque, float contentsScale)
34+
: m_picture(WTFMove(picture))
35+
, m_imageToFenceMap(WTFMove(imageToFenceMap))
36+
, m_recordRect(recordRect)
37+
, m_renderingMode(renderingMode)
38+
, m_contentsOpaque(contentsOpaque)
39+
, m_contentsScale(contentsScale)
40+
{
41+
}
42+
43+
SkiaRecordingResult::~SkiaRecordingResult() = default;
44+
45+
Ref<SkiaRecordingResult> SkiaRecordingResult::create(sk_sp<SkPicture>&& picture, SkiaImageToFenceMap&& imageToFenceMap, const IntRect& recordRect, RenderingMode renderingMode, bool contentsOpaque, float contentsScale)
46+
{
47+
return adoptRef(*new SkiaRecordingResult(WTFMove(picture), WTFMove(imageToFenceMap), recordRect, renderingMode, contentsOpaque, contentsScale));
48+
}
49+
50+
bool SkiaRecordingResult::hasFences()
51+
{
52+
Locker locker { m_imageToFenceMapLock };
53+
return !m_imageToFenceMap.isEmpty();
54+
}
55+
56+
void SkiaRecordingResult::waitForFenceIfNeeded(const SkImage& image)
57+
{
58+
Locker locker { m_imageToFenceMapLock };
59+
if (auto fence = m_imageToFenceMap.get(&image))
60+
fence->serverWait();
61+
}
62+
63+
} // namespace WebCore
64+
65+
#endif // USE(COORDINATED_GRAPHICS) && USE(SKIA)
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/*
2+
* Copyright (C) 2025 Igalia S.L.
3+
*
4+
* Redistribution and use in source and binary forms, with or without
5+
* modification, are permitted provided that the following conditions
6+
* are met:
7+
* 1. Redistributions of source code must retain the above copyright
8+
* notice, this list of conditions and the following disclaimer.
9+
* 2. Redistributions in binary form must reproduce the above copyright
10+
* notice, this list of conditions and the following disclaimer in the
11+
* documentation and/or other materials provided with the distribution.
12+
*
13+
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14+
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16+
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17+
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18+
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19+
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20+
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21+
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24+
*/
25+
26+
#pragma once
27+
28+
#if USE(COORDINATED_GRAPHICS) && USE(SKIA)
29+
#include "GraphicsContextSkia.h"
30+
31+
WTF_IGNORE_WARNINGS_IN_THIRD_PARTY_CODE_BEGIN
32+
#include <skia/core/SkPicture.h>
33+
WTF_IGNORE_WARNINGS_IN_THIRD_PARTY_CODE_END
34+
35+
#include <wtf/Lock.h>
36+
#include <wtf/ThreadSafeRefCounted.h>
37+
38+
class SkImage;
39+
40+
namespace WebCore {
41+
42+
class SkiaRecordingResult final : public ThreadSafeRefCounted<SkiaRecordingResult> {
43+
public:
44+
virtual ~SkiaRecordingResult();
45+
static Ref<SkiaRecordingResult> create(sk_sp<SkPicture>&&, SkiaImageToFenceMap&&, const IntRect& recordRect, RenderingMode, bool contentsOpaque, float contentsScale);
46+
47+
void waitForFenceIfNeeded(const SkImage&);
48+
bool hasFences();
49+
50+
const sk_sp<SkPicture>& picture() const { return m_picture; }
51+
const IntRect& recordRect() const { return m_recordRect; }
52+
RenderingMode renderingMode() const { return m_renderingMode; }
53+
bool contentsOpaque() const { return m_contentsOpaque; }
54+
float contentsScale() const { return m_contentsScale; }
55+
56+
private:
57+
SkiaRecordingResult(sk_sp<SkPicture>&&, SkiaImageToFenceMap&&, const IntRect& recordRect, RenderingMode, bool contentsOpaque, float contentsScale);
58+
59+
sk_sp<SkPicture> m_picture;
60+
SkiaImageToFenceMap m_imageToFenceMap WTF_GUARDED_BY_LOCK(m_imageToFenceMapLock);
61+
Lock m_imageToFenceMapLock;
62+
IntRect m_recordRect;
63+
RenderingMode m_renderingMode { RenderingMode::Unaccelerated };
64+
bool m_contentsOpaque : 1 { true };
65+
float m_contentsScale { 0 };
66+
};
67+
68+
} // namespace WebCore
69+
70+
#endif // USE(COORDINATED_GRAPHICS) && USE(SKIA)

0 commit comments

Comments
 (0)