Skip to content

Commit

Permalink
OffscreenCanvas uses CanvasBase::buffer() directly
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=275563
rdar://problem/129989623

Reviewed by Matt Woodrow.

OffscreenCanvas would use CanvasBase::buffer() to transfer the
offscreen canvas rendering to placeholder canvas.
The transfer is a draw operation from offscreen canvas and it changes
conceptually the placeholder *context*, not the placeholder canvas.

Implement this by adding PlaceholderRenderingContext::setPlaceholderBuffer().

Remove redundant ImageBufferPipe and OffscreenCanvasPlaceholderData
classes. PlaceholderRenderingContextSource is the thread-safe refcounted
interface to submit the placeholder buffer.

This is work towards making the rendering contexts be able to manage the
drawing and display buffers, by eventually removing the buffers from
CanvasBase.

* Source/WebCore/platform/graphics/nicosia/NicosiaPlaceholderRenderingContextSource.cpp: Renamed from Source/WebCore/platform/graphics/nicosia/NicosiaImageBufferPipe.cpp.
(Nicosia::NicosiaPlaceholderRenderingContextSource::NicosiaPlaceholderRenderingContextSource):
(Nicosia::NicosiaPlaceholderRenderingContextSource::~NicosiaPlaceholderRenderingContextSource):
(Nicosia::NicosiaPlaceholderRenderingContextSource::setPlaceholderBuffer):
(Nicosia::NicosiaPlaceholderRenderingContextSource::swapBuffersIfNeeded):
(Nicosia::NicosiaPlaceholderRenderingContextSource::setContentsToLayer):
(WebCore::PlaceholderRenderingContextSource::create):
* Source/WebCore/Headers.cmake:
* Source/WebCore/SmartPointerExpectations/UncountedCallArgsCheckerExpectations:
* Source/WebCore/Sources.txt:
* Source/WebCore/WebCore.xcodeproj/project.pbxproj:
* Source/WebCore/html/HTMLCanvasElement.cpp:
(WebCore::HTMLCanvasElement::transferControlToOffscreen):
* Source/WebCore/html/HTMLCanvasElement.h:
* Source/WebCore/html/OffscreenCanvas.cpp:
(WebCore::DetachedOffscreenCanvas::DetachedOffscreenCanvas):
(WebCore::DetachedOffscreenCanvas::takePlaceholderSource):
(WebCore::OffscreenCanvas::create):
(WebCore::OffscreenCanvas::OffscreenCanvas):
(WebCore::OffscreenCanvas::detach):
(WebCore::OffscreenCanvas::commitToPlaceholderCanvas):
(WebCore::OffscreenCanvas::scheduleCommitToPlaceholderCanvas):
(WebCore::OffscreenCanvasPlaceholderData::create): Deleted.
(WebCore::OffscreenCanvasPlaceholderData::placeholder const): Deleted.
(WebCore::OffscreenCanvasPlaceholderData::pipeSource const): Deleted.
(WebCore::OffscreenCanvasPlaceholderData::OffscreenCanvasPlaceholderData): Deleted.
(WebCore::DetachedOffscreenCanvas::takePlaceholderData): Deleted.
* Source/WebCore/html/OffscreenCanvas.h:
* Source/WebCore/html/canvas/PlaceholderRenderingContext.cpp:
(WebCore::PlaceholderRenderingContextSource::create):
(WebCore::PlaceholderRenderingContextSource::PlaceholderRenderingContextSource):
(WebCore::PlaceholderRenderingContextSource::setPlaceholderBuffer):
(WebCore::PlaceholderRenderingContext::create):
(WebCore::PlaceholderRenderingContext::PlaceholderRenderingContext):
(WebCore::PlaceholderRenderingContext::canvas const):
(WebCore::PlaceholderRenderingContext::size const):
(WebCore::PlaceholderRenderingContext::setContentsToLayer):
(WebCore::PlaceholderRenderingContext::setPlaceholderBuffer):
* Source/WebCore/html/canvas/PlaceholderRenderingContext.h:
* Source/WebCore/platform/SourcesNicosia.txt:
* Source/WebCore/platform/graphics/ImageBufferPipe.cpp: Removed.
* Source/WebCore/platform/graphics/ImageBufferPipe.h: Removed.
* Source/WebCore/platform/graphics/nicosia/NicosiaImageBufferPipe.h: Removed.

Canonical link: https://commits.webkit.org/280115@main
  • Loading branch information
kkinnunen-apple committed Jun 18, 2024
1 parent 15ad704 commit 035c61a
Show file tree
Hide file tree
Showing 16 changed files with 194 additions and 342 deletions.
1 change: 0 additions & 1 deletion Source/WebCore/Headers.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -1979,7 +1979,6 @@ set(WebCore_PRIVATE_FRAMEWORK_HEADERS
platform/graphics/ImageBufferAllocator.h
platform/graphics/ImageBufferBackend.h
platform/graphics/ImageBufferBackendParameters.h
platform/graphics/ImageBufferPipe.h
platform/graphics/ImageBufferPixelFormat.h
platform/graphics/ImageBufferPlatformBackend.h
platform/graphics/ImageDecoder.h
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1560,7 +1560,6 @@ platform/graphics/GraphicsLayer.cpp
platform/graphics/GraphicsLayer.h
platform/graphics/ImageAdapter.cpp
platform/graphics/ImageBackingStore.h
platform/graphics/ImageBufferPipe.cpp
platform/graphics/ImageFrame.cpp
platform/graphics/ImageFrameAnimator.cpp
platform/graphics/ImageFrameWorkQueue.cpp
Expand Down
1 change: 0 additions & 1 deletion Source/WebCore/Sources.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2353,7 +2353,6 @@ platform/graphics/ImageAdapter.cpp
platform/graphics/ImageBuffer.cpp
platform/graphics/ImageBufferAllocator.cpp
platform/graphics/ImageBufferBackend.cpp
platform/graphics/ImageBufferPipe.cpp
platform/graphics/ImageDecoder.cpp
platform/graphics/ImageFrame.cpp
platform/graphics/ImageFrameAnimator.cpp
Expand Down
6 changes: 0 additions & 6 deletions Source/WebCore/WebCore.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -4559,7 +4559,6 @@
B2A015A90AF6CD53006BCE0E /* GraphicsContext.h in Headers */ = {isa = PBXBuildFile; fileRef = B2A015930AF6CD53006BCE0E /* GraphicsContext.h */; settings = {ATTRIBUTES = (Private, ); }; };
B2A015AB0AF6CD53006BCE0E /* GraphicsTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = B2A015950AF6CD53006BCE0E /* GraphicsTypes.h */; settings = {ATTRIBUTES = (Private, ); }; };
B2A10B920B3818BD00099AA4 /* ImageBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = B2A10B910B3818BD00099AA4 /* ImageBuffer.h */; settings = {ATTRIBUTES = (Private, ); }; };
B2A10D910B3818BD00099AA4 /* ImageBufferPipe.h in Headers */ = {isa = PBXBuildFile; fileRef = B2A10C910B3818BD00099AA4 /* ImageBufferPipe.h */; settings = {ATTRIBUTES = (Private, ); }; };
B2A1F2AB0CEF0ABF00442F6A /* SVGFontElement.h in Headers */ = {isa = PBXBuildFile; fileRef = B2A1F2A20CEF0ABF00442F6A /* SVGFontElement.h */; };
B2A1F2AE0CEF0ABF00442F6A /* SVGGlyphElement.h in Headers */ = {isa = PBXBuildFile; fileRef = B2A1F2A50CEF0ABF00442F6A /* SVGGlyphElement.h */; };
B2A1F2B10CEF0ABF00442F6A /* SVGMissingGlyphElement.h in Headers */ = {isa = PBXBuildFile; fileRef = B2A1F2A80CEF0ABF00442F6A /* SVGMissingGlyphElement.h */; };
Expand Down Expand Up @@ -10474,7 +10473,6 @@
43C092BA12D9E4EE00A989C3 /* RenderSVGForeignObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderSVGForeignObject.h; sourceTree = "<group>"; };
43C092BA24AAE36500A889C3 /* LegacyRenderSVGForeignObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LegacyRenderSVGForeignObject.h; sourceTree = "<group>"; };
43D2597613C816F400608559 /* ImageBuffer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ImageBuffer.cpp; sourceTree = "<group>"; };
43D2598613C816F400608559 /* ImageBufferPipe.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ImageBufferPipe.cpp; sourceTree = "<group>"; };
43E47B642ABB7B7E0155527C /* RenderSVGResourcePaintServer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderSVGResourcePaintServer.cpp; sourceTree = "<group>"; };
43E632862AC43FB61174B113 /* RenderSVGResourceRadialGradient.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderSVGResourceRadialGradient.cpp; sourceTree = "<group>"; };
43E632872AC43FB71174B113 /* RenderSVGResourceRadialGradient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderSVGResourceRadialGradient.h; sourceTree = "<group>"; };
Expand Down Expand Up @@ -17042,7 +17040,6 @@
B2A015940AF6CD53006BCE0E /* GraphicsTypes.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = GraphicsTypes.cpp; sourceTree = "<group>"; };
B2A015950AF6CD53006BCE0E /* GraphicsTypes.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = GraphicsTypes.h; sourceTree = "<group>"; };
B2A10B910B3818BD00099AA4 /* ImageBuffer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ImageBuffer.h; sourceTree = "<group>"; };
B2A10C910B3818BD00099AA4 /* ImageBufferPipe.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ImageBufferPipe.h; sourceTree = "<group>"; };
B2A1F2A10CEF0ABF00442F6A /* SVGFontElement.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = SVGFontElement.cpp; sourceTree = "<group>"; };
B2A1F2A20CEF0ABF00442F6A /* SVGFontElement.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SVGFontElement.h; sourceTree = "<group>"; };
B2A1F2A40CEF0ABF00442F6A /* SVGGlyphElement.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = SVGGlyphElement.cpp; sourceTree = "<group>"; };
Expand Down Expand Up @@ -32981,8 +32978,6 @@
72BAC3A423E17327008D741C /* ImageBufferBackend.cpp */,
72BAC3A523E17328008D741C /* ImageBufferBackend.h */,
86BBA9EF2987EBF100A78986 /* ImageBufferBackendParameters.h */,
43D2598613C816F400608559 /* ImageBufferPipe.cpp */,
B2A10C910B3818BD00099AA4 /* ImageBufferPipe.h */,
3D0F80C52BCA014D006C8023 /* ImageBufferPixelFormat.h */,
72BAC3A623E17328008D741C /* ImageBufferPlatformBackend.h */,
CD19FEA71F573972000C42FB /* ImageDecoder.cpp */,
Expand Down Expand Up @@ -39869,7 +39864,6 @@
550640B02407587E00AAE045 /* ImageBufferCGBackend.h in Headers */,
2D7705C925528D34001D0C94 /* ImageBufferCGBitmapBackend.h in Headers */,
727A7F3A24078B84004D2931 /* ImageBufferIOSurfaceBackend.h in Headers */,
B2A10D910B3818BD00099AA4 /* ImageBufferPipe.h in Headers */,
3DFAB6FE2BCDA7AB00EDC3C4 /* ImageBufferPixelFormat.h in Headers */,
2D7705C7255276CD001D0C94 /* ImageBufferPlatformBackend.h in Headers */,
CD3E21DD2183444A00E66F55 /* ImageBufferUtilitiesCG.h in Headers */,
Expand Down
7 changes: 4 additions & 3 deletions Source/WebCore/html/HTMLCanvasElement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -761,11 +761,12 @@ ExceptionOr<Ref<OffscreenCanvas>> HTMLCanvasElement::transferControlToOffscreen(
if (m_context)
return Exception { ExceptionCode::InvalidStateError };

m_context = makeUniqueWithoutRefCountedCheck<PlaceholderRenderingContext>(*this);
std::unique_ptr placeholderContext = PlaceholderRenderingContext::create(*this);
Ref offscreen = OffscreenCanvas::create(document(), *placeholderContext);
m_context = WTFMove(placeholderContext);
if (m_context->delegatesDisplay())
invalidateStyleAndLayerComposition();

return OffscreenCanvas::create(document(), *this);
return offscreen;
}
#endif

Expand Down
2 changes: 2 additions & 0 deletions Source/WebCore/html/HTMLCanvasElement.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,8 @@ class HTMLCanvasElement final : public HTMLElement, public CanvasBase, public Ac
void ref() const final { HTMLElement::ref(); }
void deref() const final { HTMLElement::deref(); }

using HTMLElement::scriptExecutionContext;

private:
HTMLCanvasElement(const QualifiedName&, Document&);

Expand Down
71 changes: 14 additions & 57 deletions Source/WebCore/html/OffscreenCanvas.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,44 +67,18 @@ namespace WebCore {

WTF_MAKE_ISO_ALLOCATED_IMPL(OffscreenCanvas);

class OffscreenCanvasPlaceholderData : public ThreadSafeRefCounted<OffscreenCanvasPlaceholderData, WTF::DestructionThread::Main> {
WTF_MAKE_NONCOPYABLE(OffscreenCanvasPlaceholderData);
WTF_MAKE_FAST_ALLOCATED;
public:
static Ref<OffscreenCanvasPlaceholderData> create(HTMLCanvasElement& placeholder)
{
RefPtr<ImageBufferPipe::Source> pipeSource;
RefPtr placeholderContext = downcast<PlaceholderRenderingContext>(placeholder.renderingContext());
if (auto& pipe = placeholderContext->imageBufferPipe())
pipeSource = pipe->source();
return adoptRef(*new OffscreenCanvasPlaceholderData { placeholder, WTFMove(pipeSource) });
}
RefPtr<HTMLCanvasElement> placeholder() const { return m_placeholder.get(); }
RefPtr<ImageBufferPipe::Source> pipeSource() const { return m_pipeSource; }

private:
OffscreenCanvasPlaceholderData(HTMLCanvasElement& placeholder, RefPtr<ImageBufferPipe::Source> pipeSource)
: m_placeholder(placeholder)
, m_pipeSource(WTFMove(pipeSource))
{
}

WeakPtr<HTMLCanvasElement, WeakPtrImplWithEventTargetData> m_placeholder;
RefPtr<ImageBufferPipe::Source> m_pipeSource;
};

DetachedOffscreenCanvas::DetachedOffscreenCanvas(const IntSize& size, bool originClean, RefPtr<OffscreenCanvasPlaceholderData> placeholderData)
: m_placeholderData(WTFMove(placeholderData))
DetachedOffscreenCanvas::DetachedOffscreenCanvas(const IntSize& size, bool originClean, RefPtr<PlaceholderRenderingContextSource>&& placeholderSource)
: m_placeholderSource(WTFMove(placeholderSource))
, m_size(size)
, m_originClean(originClean)
{
}

DetachedOffscreenCanvas::~DetachedOffscreenCanvas() = default;

RefPtr<OffscreenCanvasPlaceholderData> DetachedOffscreenCanvas::takePlaceholderData()
RefPtr<PlaceholderRenderingContextSource> DetachedOffscreenCanvas::takePlaceholderSource()
{
return WTFMove(m_placeholderData);
return WTFMove(m_placeholderSource);
}

bool OffscreenCanvas::enabledForContext(ScriptExecutionContext& context)
Expand All @@ -129,24 +103,24 @@ Ref<OffscreenCanvas> OffscreenCanvas::create(ScriptExecutionContext& scriptExecu

Ref<OffscreenCanvas> OffscreenCanvas::create(ScriptExecutionContext& scriptExecutionContext, std::unique_ptr<DetachedOffscreenCanvas>&& detachedCanvas)
{
Ref<OffscreenCanvas> clone = adoptRef(*new OffscreenCanvas(scriptExecutionContext, detachedCanvas->size(), detachedCanvas->takePlaceholderData()));
Ref<OffscreenCanvas> clone = adoptRef(*new OffscreenCanvas(scriptExecutionContext, detachedCanvas->size(), detachedCanvas->takePlaceholderSource()));
if (!detachedCanvas->originClean())
clone->setOriginTainted();
clone->suspendIfNeeded();
return clone;
}

Ref<OffscreenCanvas> OffscreenCanvas::create(ScriptExecutionContext& scriptExecutionContext, HTMLCanvasElement& placeholder)
Ref<OffscreenCanvas> OffscreenCanvas::create(ScriptExecutionContext& scriptExecutionContext, PlaceholderRenderingContext& placeholder)
{
auto offscreen = adoptRef(*new OffscreenCanvas(scriptExecutionContext, placeholder.size(), OffscreenCanvasPlaceholderData::create(placeholder)));
auto offscreen = adoptRef(*new OffscreenCanvas(scriptExecutionContext, placeholder.size(), placeholder.source().ptr()));
offscreen->suspendIfNeeded();
return offscreen;
}

OffscreenCanvas::OffscreenCanvas(ScriptExecutionContext& scriptExecutionContext, IntSize size, RefPtr<OffscreenCanvasPlaceholderData> placeholderData)
OffscreenCanvas::OffscreenCanvas(ScriptExecutionContext& scriptExecutionContext, IntSize size, RefPtr<PlaceholderRenderingContextSource>&& placeholderSource)
: ActiveDOMObject(&scriptExecutionContext)
, CanvasBase(WTFMove(size), scriptExecutionContext.noiseInjectionHashSalt())
, m_placeholderData(WTFMove(placeholderData))
, m_placeholderSource(WTFMove(placeholderSource))
{
}

Expand Down Expand Up @@ -409,14 +383,14 @@ std::unique_ptr<DetachedOffscreenCanvas> OffscreenCanvas::detach()

m_detached = true;

auto detached = makeUnique<DetachedOffscreenCanvas>(size(), originClean(), WTFMove(m_placeholderData));
auto detached = makeUnique<DetachedOffscreenCanvas>(size(), originClean(), WTFMove(m_placeholderSource));
setSize(IntSize(0, 0));
return detached;
}

void OffscreenCanvas::commitToPlaceholderCanvas()
{
if (!m_placeholderData)
if (!m_placeholderSource)
return;
if (!m_context)
return;
Expand All @@ -425,29 +399,12 @@ void OffscreenCanvas::commitToPlaceholderCanvas()
RefPtr imageBuffer = m_context->surfaceBufferToImageBuffer(CanvasRenderingContext::SurfaceBuffer::DisplayBuffer);
if (!imageBuffer)
return;
if (auto pipeSource = m_placeholderData->pipeSource())
pipeSource->handle(*imageBuffer);

auto clone = imageBuffer->clone();
if (!clone)
return;
auto serializedClone = ImageBuffer::sinkIntoSerializedImageBuffer(WTFMove(clone));
if (!serializedClone)
return;
callOnMainThread([placeholderData = Ref { *m_placeholderData }, buffer = WTFMove(serializedClone)] () mutable {
RefPtr canvas = placeholderData->placeholder();
if (!canvas)
return;
RefPtr imageBuffer = SerializedImageBuffer::sinkIntoImageBuffer(WTFMove(buffer), canvas->document().graphicsClient());
if (!imageBuffer)
return;
canvas->setImageBufferAndMarkDirty(WTFMove(imageBuffer));
});
}
m_placeholderSource->setPlaceholderBuffer(*imageBuffer);
}

void OffscreenCanvas::scheduleCommitToPlaceholderCanvas()
{
if (!m_hasScheduledCommit && m_placeholderData) {
if (!m_hasScheduledCommit && m_placeholderSource) {
auto& scriptContext = *scriptExecutionContext();
m_hasScheduledCommit = true;
scriptContext.postTask([protectedThis = Ref { *this }, this] (ScriptExecutionContext&) {
Expand Down
16 changes: 8 additions & 8 deletions Source/WebCore/html/OffscreenCanvas.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@
#include "ExceptionOr.h"
#include "IDLTypes.h"
#include "ImageBuffer.h"
#include "ImageBufferPipe.h"
#include "IntSize.h"
#include "ScriptWrappable.h"
#include <wtf/FixedVector.h>
Expand Down Expand Up @@ -74,22 +73,23 @@ using OffscreenRenderingContext = std::variant<
RefPtr<OffscreenCanvasRenderingContext2D>
>;

class OffscreenCanvasPlaceholderData;
class PlaceholderRenderingContext;
class PlaceholderRenderingContextSource;

class DetachedOffscreenCanvas {
WTF_MAKE_NONCOPYABLE(DetachedOffscreenCanvas);
WTF_MAKE_FAST_ALLOCATED;
friend class OffscreenCanvas;

public:
DetachedOffscreenCanvas(const IntSize&, bool originClean, RefPtr<OffscreenCanvasPlaceholderData>);
DetachedOffscreenCanvas(const IntSize&, bool originClean, RefPtr<PlaceholderRenderingContextSource>&&);
WEBCORE_EXPORT ~DetachedOffscreenCanvas();
const IntSize& size() const { return m_size; }
bool originClean() const { return m_originClean; }
RefPtr<OffscreenCanvasPlaceholderData> takePlaceholderData();
RefPtr<PlaceholderRenderingContextSource> takePlaceholderSource();

private:
RefPtr<OffscreenCanvasPlaceholderData> m_placeholderData;
RefPtr<PlaceholderRenderingContextSource> m_placeholderSource;
IntSize m_size;
bool m_originClean;
};
Expand All @@ -115,7 +115,7 @@ class OffscreenCanvas final : public ActiveDOMObject, public RefCounted<Offscree

static Ref<OffscreenCanvas> create(ScriptExecutionContext&, unsigned width, unsigned height);
static Ref<OffscreenCanvas> create(ScriptExecutionContext&, std::unique_ptr<DetachedOffscreenCanvas>&&);
static Ref<OffscreenCanvas> create(ScriptExecutionContext&, HTMLCanvasElement& placeholder);
static Ref<OffscreenCanvas> create(ScriptExecutionContext&, PlaceholderRenderingContext&);
WEBCORE_EXPORT virtual ~OffscreenCanvas();

void setWidth(unsigned);
Expand Down Expand Up @@ -154,7 +154,7 @@ class OffscreenCanvas final : public ActiveDOMObject, public RefCounted<Offscree
void deref() const final { RefCounted::deref(); }

private:
OffscreenCanvas(ScriptExecutionContext&, IntSize, RefPtr<OffscreenCanvasPlaceholderData>);
OffscreenCanvas(ScriptExecutionContext&, IntSize, RefPtr<PlaceholderRenderingContextSource>&&);

bool isOffscreenCanvas() const final { return true; }

Expand All @@ -176,7 +176,7 @@ class OffscreenCanvas final : public ActiveDOMObject, public RefCounted<Offscree
void scheduleCommitToPlaceholderCanvas();

std::unique_ptr<CanvasRenderingContext> m_context;
RefPtr<OffscreenCanvasPlaceholderData> m_placeholderData;
RefPtr<PlaceholderRenderingContextSource> m_placeholderSource;
mutable RefPtr<Image> m_copiedImage;
// m_hasCreatedImageBuffer means we tried to malloc the buffer. We didn't necessarily get it.
mutable bool m_hasCreatedImageBuffer { false };
Expand Down
92 changes: 82 additions & 10 deletions Source/WebCore/html/canvas/PlaceholderRenderingContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,33 +30,105 @@

#include "GraphicsLayerContentsDisplayDelegate.h"
#include "HTMLCanvasElement.h"
#include "ImageBufferPipe.h"
#include "OffscreenCanvas.h"
#include <wtf/IsoMallocInlines.h>

namespace WebCore {

#if !USE(NICOSIA)
namespace {
// FIXME: Once NICOSIA PlaceholderRenderingContextSource is reimplemented with delegated display compositor interface,
// move these to PlaceholderRenderingContextSource.
class DelegatedDisplayPlaceholderRenderingContextSource final : public PlaceholderRenderingContextSource {
public:
void setPlaceholderBuffer(ImageBuffer& image) final
{
RefPtr<GraphicsLayerAsyncContentsDisplayDelegate> delegate;
{
Locker locker { m_lock };
if (m_delegate)
m_delegate->tryCopyToLayer(image);
}
PlaceholderRenderingContextSource::setPlaceholderBuffer(image);
}

void setContentsToLayer(GraphicsLayer& layer) final
{
Locker locker { m_lock };
m_delegate = layer.createAsyncContentsDisplayDelegate(m_delegate.get());
}

private:
using PlaceholderRenderingContextSource::PlaceholderRenderingContextSource;
Lock m_lock;
RefPtr<GraphicsLayerAsyncContentsDisplayDelegate> m_delegate WTF_GUARDED_BY_LOCK(m_lock);
friend Ref<PlaceholderRenderingContextSource> PlaceholderRenderingContextSource::create(PlaceholderRenderingContext&);
};

}

Ref<PlaceholderRenderingContextSource> PlaceholderRenderingContextSource::create(PlaceholderRenderingContext& context)
{
return adoptRef(*new DelegatedDisplayPlaceholderRenderingContextSource(context));
}

#endif

PlaceholderRenderingContextSource::PlaceholderRenderingContextSource(PlaceholderRenderingContext& placeholder)
: m_placeholder(placeholder)
{
}

void PlaceholderRenderingContextSource::setPlaceholderBuffer(ImageBuffer& imageBuffer)
{
RefPtr clone = imageBuffer.clone();
if (!clone)
return;
std::unique_ptr serializedClone = ImageBuffer::sinkIntoSerializedImageBuffer(WTFMove(clone));
if (!serializedClone)
return;
callOnMainThread([weakPlaceholder = m_placeholder, buffer = WTFMove(serializedClone)] () mutable {
RefPtr placeholder = weakPlaceholder.get();
if (!placeholder)
return;
RefPtr imageBuffer = SerializedImageBuffer::sinkIntoImageBuffer(WTFMove(buffer), placeholder->canvas().scriptExecutionContext()->graphicsClient());
if (!imageBuffer)
return;
placeholder->setPlaceholderBuffer(imageBuffer.releaseNonNull());
});
}

WTF_MAKE_ISO_ALLOCATED_IMPL(PlaceholderRenderingContext);

PlaceholderRenderingContext::PlaceholderRenderingContext(CanvasBase& canvas)
std::unique_ptr<PlaceholderRenderingContext> PlaceholderRenderingContext::create(HTMLCanvasElement& element)
{
return std::unique_ptr<PlaceholderRenderingContext> { new PlaceholderRenderingContext(element) };
}

PlaceholderRenderingContext::PlaceholderRenderingContext(HTMLCanvasElement& canvas)
: CanvasRenderingContext(canvas)
, m_source(PlaceholderRenderingContextSource::create(*this))
{
m_imageBufferPipe = ImageBufferPipe::create();
}

HTMLCanvasElement* PlaceholderRenderingContext::canvas() const
HTMLCanvasElement& PlaceholderRenderingContext::canvas() const
{
return dynamicDowncast<HTMLCanvasElement>(canvasBase());
return static_cast<HTMLCanvasElement&>(canvasBase());
}

IntSize PlaceholderRenderingContext::size() const
{
return canvas().size();
}

void PlaceholderRenderingContext::setContentsToLayer(GraphicsLayer& layer)
{
if (m_imageBufferPipe) {
m_imageBufferPipe->setContentsToLayer(layer);
return;
}
m_source->setContentsToLayer(layer);
}

return CanvasRenderingContext::setContentsToLayer(layer);
void PlaceholderRenderingContext::setPlaceholderBuffer(Ref<ImageBuffer>&& buffer)
{
canvasBase().setImageBufferAndMarkDirty(WTFMove(buffer));
}

}
Expand Down
Loading

0 comments on commit 035c61a

Please sign in to comment.