Skip to content

Commit

Permalink
Expose GraphicsClient through ScriptExecutionContext
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=261272
rdar://115108907

Reviewed by Matt Woodrow.

Expose GraphicsClient through ScriptExecutionContext

All DOM objects that construct graphics objects must do so via a
factory that is able to create graphics objects (either local or
remote). This factory interface is GraphicsClient.

The objects obtain the instance via ScriptExecutionContext, either:
- Document (via Chrome)
- WorkerGlobalScope (via WorkerClient)

Add ScriptExecutionContext::graphicsClient() to avoid doing various
error-prone downcasting sequences.

Make SerializedImageBuffer::sinkIntoImageBuffer() a similar function
to ImageBuffer::create(), where the polymorphism is added with
the GraphicsClient* and in-process variant is invoked if
the instance is nullptr.

* Source/WebCore/dom/Document.cpp:
(WebCore::Document::graphicsClient):
* Source/WebCore/dom/Document.h:
* Source/WebCore/dom/ScriptExecutionContext.h:
(WebCore::ScriptExecutionContext::graphicsClient):
* Source/WebCore/html/CanvasBase.cpp:
(WebCore::CanvasBase::allocateImageBuffer const):
(WebCore::CanvasBase::graphicsClient const): Deleted.
* Source/WebCore/html/CanvasBase.h:
* Source/WebCore/html/ImageBitmap.cpp:
(WebCore::ImageBitmap::createImageBuffer):
* Source/WebCore/html/ImageBitmapBacking.cpp:
(WebCore::ImageBitmapBacking::connect):
* Source/WebCore/html/OffscreenCanvas.cpp:
(WebCore::DetachedOffscreenCanvas::takeImageBuffer):
(WebCore::OffscreenCanvas::pushBufferToPlaceholder):
* Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp:
(WebCore::WebGLRenderingContextBase::create):
(WebCore::WebGLRenderingContextBase::maybeRestoreContext):
* Source/WebCore/platform/GraphicsClient.h:
* Source/WebCore/platform/graphics/ImageBuffer.cpp:
(WebCore::SerializedImageBuffer::sinkIntoImageBuffer):
* Source/WebCore/platform/graphics/ImageBuffer.h:
* Source/WebCore/workers/WorkerGlobalScope.cpp:
(WebCore::WorkerGlobalScope::graphicsClient):
* Source/WebCore/workers/WorkerGlobalScope.h:

Canonical link: https://commits.webkit.org/267938@main
  • Loading branch information
kkinnunen-apple committed Sep 13, 2023
1 parent 44bf0d7 commit a8f5521
Show file tree
Hide file tree
Showing 14 changed files with 40 additions and 52 deletions.
8 changes: 8 additions & 0 deletions Source/WebCore/dom/Document.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9510,6 +9510,14 @@ NotificationClient* Document::notificationClient()
#endif
}

GraphicsClient* Document::graphicsClient()
{
auto* page = this->page();
if (!page)
return nullptr;
return &page->chrome();
}

std::optional<PAL::SessionID> Document::sessionID() const
{
if (auto* page = this->page())
Expand Down
2 changes: 2 additions & 0 deletions Source/WebCore/dom/Document.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ class FormController;
class FrameSelection;
class FullscreenManager;
class GPUCanvasContext;
class GraphicsClient;
class HTMLAllCollection;
class HTMLAttachmentElement;
class HTMLBodyElement;
Expand Down Expand Up @@ -690,6 +691,7 @@ class Document
void suspendActiveDOMObjects(ReasonForSuspension) final;
void resumeActiveDOMObjects(ReasonForSuspension) final;
void stopActiveDOMObjects() final;
GraphicsClient* graphicsClient() final;

const Settings::Values& settingsValues() const final { return settings().values(); }

Expand Down
3 changes: 3 additions & 0 deletions Source/WebCore/dom/ScriptExecutionContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ class EventQueue;
class EventLoopTaskGroup;
class EventTarget;
class FontLoadRequest;
class GraphicsClient;
class MessagePort;
class NotificationClient;
class PublicURLManager;
Expand Down Expand Up @@ -129,6 +130,8 @@ class ScriptExecutionContext : public SecurityContext, public CanMakeCheckedPtr,

virtual SocketProvider* socketProvider() = 0;

virtual GraphicsClient* graphicsClient() { return nullptr; }

virtual std::optional<uint64_t> noiseInjectionHashSalt() const = 0;

virtual RefPtr<RTCDataChannelRemoteHandlerConnection> createRTCDataChannelRemoteHandlerConnection();
Expand Down
12 changes: 1 addition & 11 deletions Source/WebCore/html/CanvasBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -300,16 +300,6 @@ RefPtr<ImageBuffer> CanvasBase::setImageBuffer(RefPtr<ImageBuffer>&& buffer) con
return returnBuffer;
}

GraphicsClient* CanvasBase::graphicsClient() const
{
if (scriptExecutionContext()->isDocument() && downcast<Document>(scriptExecutionContext())->page())
return &downcast<Document>(scriptExecutionContext())->page()->chrome();
if (is<WorkerGlobalScope>(scriptExecutionContext()))
return downcast<WorkerGlobalScope>(scriptExecutionContext())->workerClient();

return nullptr;
}

bool CanvasBase::shouldAccelerate(const IntSize& size) const
{
auto checkedArea = size.area<RecordOverflow>();
Expand Down Expand Up @@ -358,7 +348,7 @@ RefPtr<ImageBuffer> CanvasBase::allocateImageBuffer() const
pixelFormat = context->pixelFormat();
}

return ImageBuffer::create(size(), RenderingPurpose::Canvas, 1, colorSpace, pixelFormat, bufferOptions, graphicsClient());
return ImageBuffer::create(size(), RenderingPurpose::Canvas, 1, colorSpace, pixelFormat, bufferOptions, scriptExecutionContext()->graphicsClient());
}

bool CanvasBase::shouldInjectNoiseBeforeReadback() const
Expand Down
3 changes: 0 additions & 3 deletions Source/WebCore/html/CanvasBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ class CanvasObserver;
class CanvasRenderingContext;
class Element;
class Event;
class GraphicsClient;
class GraphicsContext;
class GraphicsContextStateSaver;
class Image;
Expand Down Expand Up @@ -114,8 +113,6 @@ class CanvasBase {
virtual GraphicsContext* drawingContext() const;
virtual GraphicsContext* existingDrawingContext() const;

GraphicsClient* graphicsClient() const;

void didDraw(const std::optional<FloatRect>& rect) { return didDraw(rect, ShouldApplyPostProcessingToDirtyRect::Yes); }
virtual void didDraw(const std::optional<FloatRect>&, ShouldApplyPostProcessingToDirtyRect);

Expand Down
12 changes: 1 addition & 11 deletions Source/WebCore/html/ImageBitmap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,17 +96,7 @@ RefPtr<ImageBuffer> ImageBitmap::createImageBuffer(ScriptExecutionContext& scrip
}

auto bufferOptions = bufferOptionsForRendingMode(renderingMode);

GraphicsClient* client = nullptr;
if (scriptExecutionContext.isDocument()) {
auto& document = downcast<Document>(scriptExecutionContext);
if (document.view() && document.view()->root()) {
client = document.view()->root()->hostWindow();
}
} else if (scriptExecutionContext.isWorkerGlobalScope())
client = downcast<WorkerGlobalScope>(scriptExecutionContext).workerClient();

return ImageBuffer::create(size, RenderingPurpose::Canvas, resolutionScale, *imageBufferColorSpace, PixelFormat::BGRA8, bufferOptions, client);
return ImageBuffer::create(size, RenderingPurpose::Canvas, resolutionScale, *imageBufferColorSpace, PixelFormat::BGRA8, bufferOptions, scriptExecutionContext.graphicsClient());
}

void ImageBitmap::createCompletionHandler(ScriptExecutionContext& scriptExecutionContext, ImageBitmap::Source&& source, ImageBitmapOptions&& options, ImageBitmapCompletionHandler&& completionHandler)
Expand Down
10 changes: 1 addition & 9 deletions Source/WebCore/html/ImageBitmapBacking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,15 +88,7 @@ void ImageBitmapBacking::connect(ScriptExecutionContext& context)
ASSERT(!m_bitmapData);
if (!m_serializedBitmap)
return;

if (is<WorkerGlobalScope>(context) && downcast<WorkerGlobalScope>(context).workerClient()) {
auto* client = downcast<WorkerGlobalScope>(context).workerClient();
m_bitmapData = client->sinkIntoImageBuffer(WTFMove(m_serializedBitmap));
} else if (is<Document>(context)) {
ASSERT(downcast<Document>(context).page());
m_bitmapData = downcast<Document>(context).page()->chrome().sinkIntoImageBuffer(WTFMove(m_serializedBitmap));
} else
m_bitmapData = SerializedImageBuffer::sinkIntoImageBuffer(WTFMove(m_serializedBitmap));
m_bitmapData = SerializedImageBuffer::sinkIntoImageBuffer(WTFMove(m_serializedBitmap), context.graphicsClient());
}

} // namespace WebCore
16 changes: 3 additions & 13 deletions Source/WebCore/html/OffscreenCanvas.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,16 +68,7 @@ RefPtr<ImageBuffer> DetachedOffscreenCanvas::takeImageBuffer(ScriptExecutionCont
{
if (!m_buffer)
return nullptr;
GraphicsClient* client = nullptr;
if (is<WorkerGlobalScope>(context)) {
client = downcast<WorkerGlobalScope>(context).workerClient();
ASSERT(client);
} else if (is<Document>(context)) {
ASSERT(downcast<Document>(context).page());
client = &downcast<Document>(context).page()->chrome();
}
ASSERT(client);
return client->sinkIntoImageBuffer(WTFMove(m_buffer));
return SerializedImageBuffer::sinkIntoImageBuffer(WTFMove(m_buffer), context.graphicsClient());
}

WeakPtr<HTMLCanvasElement, WeakPtrImplWithEventTargetData> DetachedOffscreenCanvas::takePlaceholderCanvas()
Expand Down Expand Up @@ -493,9 +484,8 @@ void OffscreenCanvas::pushBufferToPlaceholder()
callOnMainThread([placeholderData = Ref { *m_placeholderData }] () mutable {
Locker locker { placeholderData->bufferLock };
if (RefPtr canvas = placeholderData->canvas.get()) {
if (canvas->document().page() && placeholderData->pendingCommitBuffer) {
GraphicsClient& client = canvas->document().page()->chrome();
auto imageBuffer = client.sinkIntoImageBuffer(WTFMove(placeholderData->pendingCommitBuffer));
if (placeholderData->pendingCommitBuffer) {
auto imageBuffer = SerializedImageBuffer::sinkIntoImageBuffer(WTFMove(placeholderData->pendingCommitBuffer), canvas->document().graphicsClient());
canvas->setImageBufferAndMarkDirty(WTFMove(imageBuffer));
}
}
Expand Down
4 changes: 2 additions & 2 deletions Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -573,7 +573,7 @@ std::unique_ptr<WebGLRenderingContextBase> WebGLRenderingContextBase::create(Can
if (!scriptExecutionContext)
return nullptr;

GraphicsClient* graphicsClient = canvas.graphicsClient();
GraphicsClient* graphicsClient = scriptExecutionContext->graphicsClient();

auto* canvasElement = dynamicDowncast<HTMLCanvasElement>(canvas);

Expand Down Expand Up @@ -5636,7 +5636,7 @@ void WebGLRenderingContextBase::maybeRestoreContext()
if (!scriptExecutionContext->settingsValues().webGLEnabled)
return;

GraphicsClient* graphicsClient = canvasBase().graphicsClient();
GraphicsClient* graphicsClient = scriptExecutionContext->graphicsClient();
if (!graphicsClient)
return;

Expand Down
9 changes: 8 additions & 1 deletion Source/WebCore/platform/GraphicsClient.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,19 @@ class GraphicsClient {

virtual PlatformDisplayID displayID() const = 0;

virtual RefPtr<ImageBuffer> createImageBuffer(const FloatSize&, RenderingMode, RenderingPurpose, float resolutionScale, const DestinationColorSpace&, PixelFormat, bool avoidBackendSizeCheck = false) const = 0;
#if ENABLE(WEBGL)
virtual RefPtr<GraphicsContextGL> createGraphicsContextGL(const GraphicsContextGLAttributes&) const = 0;
#endif

private:
// Called by passing GraphicsClient into ImageBuffer functions.
virtual RefPtr<ImageBuffer> createImageBuffer(const FloatSize&, RenderingMode, RenderingPurpose, float resolutionScale, const DestinationColorSpace&, PixelFormat, bool avoidBackendSizeCheck = false) const = 0;

// Called by passing GraphicsClient into SerializedImageBuffer functions.
virtual RefPtr<WebCore::ImageBuffer> sinkIntoImageBuffer(std::unique_ptr<WebCore::SerializedImageBuffer>) = 0;

friend class ImageBuffer;
friend class SerializedImageBuffer;
};

} // namespace WebCore
4 changes: 3 additions & 1 deletion Source/WebCore/platform/graphics/ImageBuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,10 @@ bool ImageBuffer::sizeNeedsClamping(const FloatSize& size)
return floorf(size.height()) * floorf(size.width()) > MaxClampedArea;
}

RefPtr<ImageBuffer> SerializedImageBuffer::sinkIntoImageBuffer(std::unique_ptr<SerializedImageBuffer> buffer)
RefPtr<ImageBuffer> SerializedImageBuffer::sinkIntoImageBuffer(std::unique_ptr<SerializedImageBuffer> buffer, GraphicsClient* graphicsClient)
{
if (graphicsClient)
return graphicsClient->sinkIntoImageBuffer(WTFMove(buffer));
return buffer->sinkIntoImageBuffer();
}

Expand Down
2 changes: 1 addition & 1 deletion Source/WebCore/platform/graphics/ImageBuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ class SerializedImageBuffer {

virtual size_t memoryCost() = 0;

WEBCORE_EXPORT static RefPtr<ImageBuffer> sinkIntoImageBuffer(std::unique_ptr<SerializedImageBuffer>);
WEBCORE_EXPORT static RefPtr<ImageBuffer> sinkIntoImageBuffer(std::unique_ptr<SerializedImageBuffer>, GraphicsClient* = nullptr);

virtual bool isRemoteSerializedImageBufferProxy() const { return false; }

Expand Down
5 changes: 5 additions & 0 deletions Source/WebCore/workers/WorkerGlobalScope.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,11 @@ IDBClient::IDBConnectionProxy* WorkerGlobalScope::idbConnectionProxy()
return m_connectionProxy.get();
}

GraphicsClient* WorkerGlobalScope::graphicsClient()
{
return workerClient();
}

void WorkerGlobalScope::stopIndexedDatabase()
{
if (m_connectionProxy)
Expand Down
2 changes: 2 additions & 0 deletions Source/WebCore/workers/WorkerGlobalScope.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ class WorkerGlobalScope : public Supplementable<WorkerGlobalScope>, public Base6
IDBClient::IDBConnectionProxy* idbConnectionProxy() final;
void suspend() final;
void resume() final;
GraphicsClient* graphicsClient() final;


using EventTarget::weakPtrFactory;
using EventTarget::WeakValueType;
Expand Down

0 comments on commit a8f5521

Please sign in to comment.