Skip to content

Commit cfc4f80

Browse files
committed
Add support for creating accelerated WebGL contexts in a worker
https://bugs.webkit.org/show_bug.cgi?id=247103 Reviewed by Dean Jackson. * Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp: (WebCore::getGraphicsClient): (WebCore::WebGLRenderingContextBase::create): (WebCore::WebGLRenderingContextBase::maybeRestoreContext): * Source/WebCore/platform/GraphicsClient.h: * Source/WebCore/platform/HostWindow.h: * Source/WebKit/WebProcess/WebCoreSupport/WebWorkerClient.cpp: (WebKit::WebWorkerClient::createGraphicsContextGL const): * Source/WebKit/WebProcess/WebCoreSupport/WebWorkerClient.h: Canonical link: https://commits.webkit.org/257541@main
1 parent 3c4cf6c commit cfc4f80

File tree

5 files changed

+87
-47
lines changed

5 files changed

+87
-47
lines changed

Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp

Lines changed: 49 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,8 @@
115115
#include "WebGLVertexArrayObject.h"
116116
#include "WebGLVertexArrayObjectOES.h"
117117
#include "WebXRSystem.h"
118+
#include "WorkerClient.h"
119+
#include "WorkerGlobalScope.h"
118120
#include <JavaScriptCore/ConsoleMessage.h>
119121
#include <JavaScriptCore/JSCInlines.h>
120122
#include <JavaScriptCore/ScriptCallStack.h>
@@ -482,6 +484,22 @@ static void removeActiveContext(WebGLRenderingContextBase& context)
482484
ASSERT_UNUSED(didContain, didContain);
483485
}
484486

487+
static GraphicsClient* getGraphicsClient(CanvasBase& canvas)
488+
{
489+
if (auto* canvasElement = dynamicDowncast<HTMLCanvasElement>(canvas)) {
490+
Document& document = canvasElement->document();
491+
RefPtr<Frame> frame = document.frame();
492+
if (!frame)
493+
return nullptr;
494+
495+
return document.view()->root()->hostWindow();
496+
}
497+
if (is<WorkerGlobalScope>(canvas.scriptExecutionContext()))
498+
return downcast<WorkerGlobalScope>(canvas.scriptExecutionContext())->workerClient();
499+
500+
return nullptr;
501+
}
502+
485503
std::unique_ptr<WebGLRenderingContextBase> WebGLRenderingContextBase::create(CanvasBase& canvas, WebGLContextAttributes& attributes, WebGLVersion type)
486504
{
487505
auto scriptExecutionContext = canvas.scriptExecutionContext();
@@ -496,54 +514,53 @@ std::unique_ptr<WebGLRenderingContextBase> WebGLRenderingContextBase::create(Can
496514
UNUSED_PARAM(type);
497515
#endif
498516

499-
HostWindow* hostWindow = nullptr;
517+
GraphicsClient* graphicsClient = getGraphicsClient(canvas);
500518

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

521+
if (!scriptExecutionContext->settingsValues().webGLEnabled) {
522+
canvasElement->dispatchEvent(WebGLContextEvent::create(eventNames().webglcontextcreationerrorEvent,
523+
Event::CanBubble::No, Event::IsCancelable::Yes, "Web page was not allowed to create a WebGL context."_s));
524+
return nullptr;
525+
}
526+
527+
if (scriptExecutionContext->settingsValues().forceWebGLUsesLowPower) {
528+
if (attributes.powerPreference == GraphicsContextGLPowerPreference::HighPerformance)
529+
LOG(WebGL, "Overriding powerPreference from high-performance to low-power.");
530+
attributes.powerPreference = GraphicsContextGLPowerPreference::LowPower;
531+
}
532+
503533
if (canvasElement) {
504534
Document& document = canvasElement->document();
505535
RefPtr<Frame> frame = document.frame();
506536
if (!frame)
507537
return nullptr;
508538

509-
if (!frame->settings().webGLEnabled()) {
510-
canvasElement->dispatchEvent(WebGLContextEvent::create(eventNames().webglcontextcreationerrorEvent,
511-
Event::CanBubble::No, Event::IsCancelable::Yes, "Web page was not allowed to create a WebGL context."_s));
512-
return nullptr;
513-
}
514-
515539
Document& topDocument = document.topDocument();
516540
Page* page = topDocument.page();
517-
if (frame->settings().forceWebGLUsesLowPower()) {
518-
if (attributes.powerPreference == GraphicsContextGLPowerPreference::HighPerformance)
519-
LOG(WebGL, "Overriding powerPreference from high-performance to low-power.");
520-
attributes.powerPreference = GraphicsContextGLPowerPreference::LowPower;
521-
}
522-
523541
if (page)
524542
attributes.devicePixelRatio = page->deviceScaleFactor();
525-
526-
hostWindow = document.view()->root()->hostWindow();
527543
}
528544

545+
// FIXME: Should we try get the devicePixelRatio for workers for the page that created
546+
// the worker? What if it's a shared worker, and there's multiple answers?
547+
529548
attributes.noExtensions = true;
530549
attributes.shareResources = false;
531550
attributes.initialPowerPreference = attributes.powerPreference;
532551
attributes.webGLVersion = type;
533552
#if PLATFORM(MAC)
534553
// FIXME: Add MACCATALYST support for gpuIDForDisplay.
535-
if (hostWindow)
536-
attributes.windowGPUID = gpuIDForDisplay(hostWindow->displayID());
554+
if (graphicsClient)
555+
attributes.windowGPUID = gpuIDForDisplay(graphicsClient->displayID());
537556
#endif
538557
#if PLATFORM(COCOA)
539558
attributes.useMetal = scriptExecutionContext->settingsValues().webGLUsingMetal;
540559
#endif
541560

542561
RefPtr<GraphicsContextGL> context;
543-
if (hostWindow)
544-
context = hostWindow->createGraphicsContextGL(attributes);
545-
// FIXME: OffscreenCanvas does not support GPU process and ANGLE does not support
546-
// multi-threaded access so offscreen canvas is disabled.
562+
if (graphicsClient)
563+
context = graphicsClient->createGraphicsContextGL(attributes);
547564
if (!context) {
548565
if (canvasElement) {
549566
canvasElement->dispatchEvent(WebGLContextEvent::create(eventNames().webglcontextcreationerrorEvent,
@@ -5506,28 +5523,18 @@ void WebGLRenderingContextBase::maybeRestoreContext()
55065523
return;
55075524
}
55085525

5509-
auto* canvas = htmlCanvas();
5510-
if (!canvas)
5511-
return;
5512-
5513-
RefPtr<Frame> frame = canvas->document().frame();
5514-
if (!frame)
5526+
auto scriptExecutionContext = canvasBase().scriptExecutionContext();
5527+
if (!scriptExecutionContext)
55155528
return;
55165529

5517-
if (!frame->settings().webGLEnabled())
5530+
if (!scriptExecutionContext->settingsValues().webGLEnabled)
55185531
return;
55195532

5520-
RefPtr<FrameView> view = frame->view();
5521-
if (!view)
5522-
return;
5523-
RefPtr<ScrollView> root = view->root();
5524-
if (!root)
5525-
return;
5526-
HostWindow* hostWindow = root->hostWindow();
5527-
if (!hostWindow)
5533+
GraphicsClient* graphicsClient = getGraphicsClient(canvasBase());
5534+
if (!graphicsClient)
55285535
return;
55295536

5530-
RefPtr<GraphicsContextGL> context = hostWindow->createGraphicsContextGL(m_attributes);
5537+
RefPtr<GraphicsContextGL> context = graphicsClient->createGraphicsContextGL(m_attributes);
55315538
if (!context) {
55325539
if (m_contextLostState->mode == RealLostContext)
55335540
m_restoreTimer.startOneShot(secondsBetweenRestoreAttempts);
@@ -5541,6 +5548,11 @@ void WebGLRenderingContextBase::maybeRestoreContext()
55415548
m_contextLostState = std::nullopt;
55425549
setupFlags();
55435550
initializeNewContext();
5551+
5552+
auto* canvas = htmlCanvas();
5553+
if (!canvas)
5554+
return;
5555+
55445556
if (!isContextLost())
55455557
canvas->dispatchEvent(WebGLContextEvent::create(eventNames().webglcontextrestoredEvent, Event::CanBubble::No, Event::IsCancelable::Yes, emptyString()));
55465558
}

Source/WebCore/platform/GraphicsClient.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,11 @@
3030
namespace WebCore {
3131

3232
class DestinationColorSpace;
33+
class GraphicsContextGL;
3334
class ImageBuffer;
3435

36+
struct GraphicsContextGLAttributes;
37+
3538
enum class PixelFormat : uint8_t;
3639
enum class RenderingMode : bool;
3740
enum class RenderingPurpose : uint8_t;
@@ -45,6 +48,10 @@ class GraphicsClient {
4548
virtual PlatformDisplayID displayID() const = 0;
4649

4750
virtual RefPtr<ImageBuffer> createImageBuffer(const FloatSize&, RenderingMode, RenderingPurpose, float resolutionScale, const DestinationColorSpace&, PixelFormat, bool avoidBackendSizeCheck = false) const = 0;
51+
#if ENABLE(WEBGL)
52+
virtual RefPtr<GraphicsContextGL> createGraphicsContextGL(const GraphicsContextGLAttributes&) const = 0;
53+
#endif
54+
4855
};
4956

5057
} // namespace WebCore

Source/WebCore/platform/HostWindow.h

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,6 @@
3131
namespace WebCore {
3232

3333
class Cursor;
34-
class GraphicsContextGL;
35-
36-
struct GraphicsContextGLAttributes;
3734

3835
using FramesPerSecond = unsigned;
3936

@@ -61,10 +58,6 @@ class HostWindow : public GraphicsClient {
6158
virtual IntPoint accessibilityScreenToRootView(const IntPoint&) const = 0;
6259
virtual IntRect rootViewToAccessibilityScreen(const IntRect&) const = 0;
6360

64-
#if ENABLE(WEBGL)
65-
virtual RefPtr<GraphicsContextGL> createGraphicsContextGL(const GraphicsContextGLAttributes&) const = 0;
66-
#endif
67-
6861
// Method for retrieving the native client of the page.
6962
virtual PlatformPageClient platformPageClient() const = 0;
7063

Source/WebKit/WebProcess/WebCoreSupport/WebWorkerClient.cpp

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,22 @@
3030
#include "RemoteImageBufferProxy.h"
3131
#include "RemoteRenderingBackendProxy.h"
3232

33+
#if ENABLE(WEBGL) && ENABLE(GPU_PROCESS)
34+
#include "RemoteGraphicsContextGLProxy.h"
35+
#endif
36+
37+
#if ENABLE(WEBGL)
38+
#include <WebCore/GraphicsContextGL.h>
39+
#endif
40+
3341
namespace WebKit {
3442
using namespace WebCore;
3543

3644
WebWorkerClient::WebWorkerClient(WebPage* page, SerialFunctionDispatcher& dispatcher)
3745
: m_dispatcher(dispatcher)
46+
#if ENABLE(GPU_PROCESS)
47+
, m_connection(WebProcess::singleton().ensureGPUProcessConnection().connection())
48+
#endif
3849
{
3950
ASSERT(isMainRunLoop());
4051
#if ENABLE(GPU_PROCESS)
@@ -46,8 +57,9 @@ WebWorkerClient::WebWorkerClient(WebPage* page, SerialFunctionDispatcher& dispat
4657
}
4758

4859
#if ENABLE(GPU_PROCESS)
49-
WebWorkerClient::WebWorkerClient(SerialFunctionDispatcher& dispatcher, RemoteRenderingBackendCreationParameters& creationParameters, WebCore::PlatformDisplayID& displayID)
60+
WebWorkerClient::WebWorkerClient(IPC::Connection& connection, SerialFunctionDispatcher& dispatcher, RemoteRenderingBackendCreationParameters& creationParameters, WebCore::PlatformDisplayID& displayID)
5061
: m_dispatcher(dispatcher)
62+
, m_connection(connection)
5163
, m_creationParameters(creationParameters)
5264
, m_displayID(displayID)
5365
{ }
@@ -72,7 +84,7 @@ std::unique_ptr<WorkerClient> WebWorkerClient::clone(SerialFunctionDispatcher& d
7284
{
7385
assertIsCurrent(m_dispatcher);
7486
#if ENABLE(GPU_PROCESS)
75-
return makeUnique<WebWorkerClient>(dispatcher, m_creationParameters, m_displayID);
87+
return makeUnique<WebWorkerClient>(m_connection, dispatcher, m_creationParameters, m_displayID);
7688
#else
7789
return makeUnique<WebWorkerClient>(dispatcher, m_displayID);
7890
#endif
@@ -94,5 +106,16 @@ RefPtr<ImageBuffer> WebWorkerClient::createImageBuffer(const FloatSize& size, Re
94106
return nullptr;
95107
}
96108

109+
#if ENABLE(WEBGL)
110+
RefPtr<GraphicsContextGL> WebWorkerClient::createGraphicsContextGL(const GraphicsContextGLAttributes& attributes) const
111+
{
112+
#if ENABLE(GPU_PROCESS)
113+
if (WebProcess::singleton().shouldUseRemoteRenderingForWebGL())
114+
return RemoteGraphicsContextGLProxy::create(m_connection, attributes, ensureRenderingBackend());
115+
#endif
116+
return WebCore::createWebProcessGraphicsContextGL(attributes);
117+
}
118+
#endif
119+
97120
}
98121

Source/WebKit/WebProcess/WebCoreSupport/WebWorkerClient.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525

2626
#pragma once
2727

28+
#include "Connection.h"
2829
#include "RemoteRenderingBackendCreationParameters.h"
2930
#include <WebCore/WorkerClient.h>
3031

@@ -47,7 +48,7 @@ class WebWorkerClient : public WebCore::WorkerClient {
4748
// worker thread of the outer worker, and then transferred to the
4849
// nested worker.
4950
#if ENABLE(GPU_PROCESS)
50-
WebWorkerClient(SerialFunctionDispatcher&, RemoteRenderingBackendCreationParameters&, WebCore::PlatformDisplayID&);
51+
WebWorkerClient(IPC::Connection&, SerialFunctionDispatcher&, RemoteRenderingBackendCreationParameters&, WebCore::PlatformDisplayID&);
5152
#else
5253
WebWorkerClient(SerialFunctionDispatcher&, WebCore::PlatformDisplayID&);
5354
#endif
@@ -57,6 +58,9 @@ class WebWorkerClient : public WebCore::WorkerClient {
5758
WebCore::PlatformDisplayID displayID() const final;
5859

5960
RefPtr<WebCore::ImageBuffer> createImageBuffer(const WebCore::FloatSize&, WebCore::RenderingMode, WebCore::RenderingPurpose, float resolutionScale, const WebCore::DestinationColorSpace&, WebCore::PixelFormat, bool avoidBackendSizeCheck = false) const final;
61+
#if ENABLE(WEBGL)
62+
RefPtr<WebCore::GraphicsContextGL> createGraphicsContextGL(const WebCore::GraphicsContextGLAttributes&) const final;
63+
#endif
6064

6165
private:
6266
#if ENABLE(GPU_PROCESS)
@@ -65,6 +69,7 @@ class WebWorkerClient : public WebCore::WorkerClient {
6569

6670
SerialFunctionDispatcher& m_dispatcher;
6771
#if ENABLE(GPU_PROCESS)
72+
Ref<IPC::Connection> m_connection;
6873
mutable std::unique_ptr<RemoteRenderingBackendProxy> m_remoteRenderingBackendProxy;
6974
RemoteRenderingBackendCreationParameters m_creationParameters;
7075
#endif

0 commit comments

Comments
 (0)