Title: [225193] trunk
Revision
225193
Author
[email protected]
Date
2017-11-27 14:12:46 -0800 (Mon, 27 Nov 2017)

Log Message

Implement OffscreenCanvas.getContext("webgl")
https://bugs.webkit.org/show_bug.cgi?id=180050
<rdar://problem/35705473>

Reviewed by Sam Weinig.

Source/WebCore:

Implement enough of getContext("webgl") to actually return an
active WebGLRenderingContext, even though it isn't actually
hooked up to draw.

Introduce a new type, WebGLCanvas, which is a variant of HTMLCanvasElement
and OffscreenCanvas, so that it can be exposed by the 'canvas' attribute
on WebGLRenderingContext.

At the moment we still assume that all uses of WebGLRenderingContext come
from HTMLCanvasElement, so add a bunch of logic to detect that case.

Updated the existing (proposed) WPT.

* html/OffscreenCanvas.cpp:
(WebCore::OffscreenCanvas::getContext): Implement enough of getContext to
return a WebGLRenderingContext.
* html/OffscreenCanvas.h: Use the new OffscreenRenderingContext type, even
though it's just a WebGLRenderingContext at the moment.

* html/canvas/WebGLRenderingContextBase.cpp:
(WebCore::WebGLRenderingContextBase::canvas): Now returns a WebGLCanvas.
(WebCore::WebGLRenderingContextBase::htmlCanvas): Helper to get the HTMLCanvasElement if it exists.
(WebCore::WebGLRenderingContextBase::offscreenCanvas): Ditto for OffscreenCanvas.
(WebCore::WebGLRenderingContextBase::checkForContextLossHandling): Guard for htmlCanvas().
(WebCore::WebGLRenderingContextBase::registerWithWebGLStateTracker):
(WebCore::WebGLRenderingContextBase::setupFlags):
(WebCore::WebGLRenderingContextBase::addActivityStateChangeObserverIfNecessary):
(WebCore::WebGLRenderingContextBase::removeActivityStateChangeObserver):
(WebCore::WebGLRenderingContextBase::markContextChanged):
(WebCore::WebGLRenderingContextBase::markContextChangedAndNotifyCanvasObserver):
(WebCore::WebGLRenderingContextBase::paintRenderingResultsToCanvas):
(WebCore::WebGLRenderingContextBase::reshape):
(WebCore::WebGLRenderingContextBase::compileShader):
(WebCore::WebGLRenderingContextBase::isContextLostOrPending):
(WebCore::WebGLRenderingContextBase::readPixels):
(WebCore::WebGLRenderingContextBase::loseContextImpl):
(WebCore::WebGLRenderingContextBase::printToConsole):
(WebCore::WebGLRenderingContextBase::dispatchContextLostEvent):
(WebCore::WebGLRenderingContextBase::maybeRestoreContext):
(WebCore::WebGLRenderingContextBase::dispatchContextChangedEvent):
(WebCore::WebGLRenderingContextBase::clampedCanvasSize):
* html/canvas/WebGLRenderingContextBase.h: Define WebGLCanvas.
* html/canvas/WebGLRenderingContextBase.idl:

* inspector/InspectorInstrumentation.h: Handle the variant options, although leave OffscreenCanvas
unimplemented for the moment.
(WebCore::InspectorInstrumentation::didEnableExtension):
(WebCore::InspectorInstrumentation::didCreateProgram):
(WebCore::InspectorInstrumentation::willDeleteProgram):
(WebCore::InspectorInstrumentation::isShaderProgramDisabled):
* inspector/agents/InspectorCanvasAgent.cpp:
(WebCore::InspectorCanvasAgent::didEnableExtension):
(WebCore::InspectorCanvasAgent::didCreateProgram):

LayoutTests:

Update expected results.

* http/wpt/offscreen-canvas/getContext-webgl.html:

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (225192 => 225193)


--- trunk/LayoutTests/ChangeLog	2017-11-27 21:21:43 UTC (rev 225192)
+++ trunk/LayoutTests/ChangeLog	2017-11-27 22:12:46 UTC (rev 225193)
@@ -1,3 +1,15 @@
+2017-11-27  Dean Jackson  <[email protected]>
+
+        Implement OffscreenCanvas.getContext("webgl")
+        https://bugs.webkit.org/show_bug.cgi?id=180050
+        <rdar://problem/35705473>
+
+        Reviewed by Sam Weinig.
+
+        Update expected results.
+
+        * http/wpt/offscreen-canvas/getContext-webgl.html:
+
 2017-11-27  Matt Lewis  <[email protected]>
 
         Fixed incorrectly marked test expectations.

Modified: trunk/LayoutTests/http/wpt/offscreen-canvas/getContext-webgl.html (225192 => 225193)


--- trunk/LayoutTests/http/wpt/offscreen-canvas/getContext-webgl.html	2017-11-27 21:21:43 UTC (rev 225192)
+++ trunk/LayoutTests/http/wpt/offscreen-canvas/getContext-webgl.html	2017-11-27 22:12:46 UTC (rev 225193)
@@ -8,7 +8,8 @@
 test(function() {
     let offscreenCanvas = new OffscreenCanvas(100, 100);
     let gl = offscreenCanvas.getContext("webgl");
-    assert_equals(gl, null);
+    assert_true(gl instanceof WebGLRenderingContext);
+    assert_equals(gl.canvas, offscreenCanvas);
 }, "Test getContext('webgl').");
 
 </script>

Modified: trunk/Source/WebCore/ChangeLog (225192 => 225193)


--- trunk/Source/WebCore/ChangeLog	2017-11-27 21:21:43 UTC (rev 225192)
+++ trunk/Source/WebCore/ChangeLog	2017-11-27 22:12:46 UTC (rev 225193)
@@ -1,3 +1,65 @@
+2017-11-27  Dean Jackson  <[email protected]>
+
+        Implement OffscreenCanvas.getContext("webgl")
+        https://bugs.webkit.org/show_bug.cgi?id=180050
+        <rdar://problem/35705473>
+
+        Reviewed by Sam Weinig.
+
+        Implement enough of getContext("webgl") to actually return an
+        active WebGLRenderingContext, even though it isn't actually
+        hooked up to draw.
+
+        Introduce a new type, WebGLCanvas, which is a variant of HTMLCanvasElement
+        and OffscreenCanvas, so that it can be exposed by the 'canvas' attribute
+        on WebGLRenderingContext.
+
+        At the moment we still assume that all uses of WebGLRenderingContext come
+        from HTMLCanvasElement, so add a bunch of logic to detect that case.
+
+        Updated the existing (proposed) WPT.
+
+        * html/OffscreenCanvas.cpp:
+        (WebCore::OffscreenCanvas::getContext): Implement enough of getContext to
+        return a WebGLRenderingContext.
+        * html/OffscreenCanvas.h: Use the new OffscreenRenderingContext type, even
+        though it's just a WebGLRenderingContext at the moment.
+
+        * html/canvas/WebGLRenderingContextBase.cpp:
+        (WebCore::WebGLRenderingContextBase::canvas): Now returns a WebGLCanvas.
+        (WebCore::WebGLRenderingContextBase::htmlCanvas): Helper to get the HTMLCanvasElement if it exists.
+        (WebCore::WebGLRenderingContextBase::offscreenCanvas): Ditto for OffscreenCanvas.
+        (WebCore::WebGLRenderingContextBase::checkForContextLossHandling): Guard for htmlCanvas().
+        (WebCore::WebGLRenderingContextBase::registerWithWebGLStateTracker):
+        (WebCore::WebGLRenderingContextBase::setupFlags):
+        (WebCore::WebGLRenderingContextBase::addActivityStateChangeObserverIfNecessary):
+        (WebCore::WebGLRenderingContextBase::removeActivityStateChangeObserver):
+        (WebCore::WebGLRenderingContextBase::markContextChanged):
+        (WebCore::WebGLRenderingContextBase::markContextChangedAndNotifyCanvasObserver):
+        (WebCore::WebGLRenderingContextBase::paintRenderingResultsToCanvas):
+        (WebCore::WebGLRenderingContextBase::reshape):
+        (WebCore::WebGLRenderingContextBase::compileShader):
+        (WebCore::WebGLRenderingContextBase::isContextLostOrPending):
+        (WebCore::WebGLRenderingContextBase::readPixels):
+        (WebCore::WebGLRenderingContextBase::loseContextImpl):
+        (WebCore::WebGLRenderingContextBase::printToConsole):
+        (WebCore::WebGLRenderingContextBase::dispatchContextLostEvent):
+        (WebCore::WebGLRenderingContextBase::maybeRestoreContext):
+        (WebCore::WebGLRenderingContextBase::dispatchContextChangedEvent):
+        (WebCore::WebGLRenderingContextBase::clampedCanvasSize):
+        * html/canvas/WebGLRenderingContextBase.h: Define WebGLCanvas.
+        * html/canvas/WebGLRenderingContextBase.idl:
+
+        * inspector/InspectorInstrumentation.h: Handle the variant options, although leave OffscreenCanvas
+        unimplemented for the moment.
+        (WebCore::InspectorInstrumentation::didEnableExtension):
+        (WebCore::InspectorInstrumentation::didCreateProgram):
+        (WebCore::InspectorInstrumentation::willDeleteProgram):
+        (WebCore::InspectorInstrumentation::isShaderProgramDisabled):
+        * inspector/agents/InspectorCanvasAgent.cpp:
+        (WebCore::InspectorCanvasAgent::didEnableExtension):
+        (WebCore::InspectorCanvasAgent::didCreateProgram):
+
 2017-11-27  Michael Catanzaro  <[email protected]>
 
         Unreviewed, fix an improper #include

Modified: trunk/Source/WebCore/html/OffscreenCanvas.cpp (225192 => 225193)


--- trunk/Source/WebCore/html/OffscreenCanvas.cpp	2017-11-27 21:21:43 UTC (rev 225192)
+++ trunk/Source/WebCore/html/OffscreenCanvas.cpp	2017-11-27 22:12:46 UTC (rev 225193)
@@ -75,10 +75,23 @@
 }
 
 #if ENABLE(WEBGL)
-ExceptionOr<RefPtr<WebGLRenderingContext>> OffscreenCanvas::getContext(JSC::ExecState&, RenderingContextType contextType, Vector<JSC::Strong<JSC::Unknown>>&& arguments)
+ExceptionOr<OffscreenRenderingContext> OffscreenCanvas::getContext(JSC::ExecState& state, RenderingContextType contextType, Vector<JSC::Strong<JSC::Unknown>>&& arguments)
 {
-    UNUSED_PARAM(contextType);
-    UNUSED_PARAM(arguments);
+    if (m_context && contextType == RenderingContextType::Webgl)
+        return { RefPtr<WebGLRenderingContext> { &downcast<WebGLRenderingContext>(*m_context) } };
+
+    if (contextType == RenderingContextType::Webgl) {
+        auto scope = DECLARE_THROW_SCOPE(state.vm());
+        auto attributes = convert<IDLDictionary<WebGLContextAttributes>>(state, !arguments.isEmpty() ? arguments[0].get() : JSC::jsUndefined());
+        RETURN_IF_EXCEPTION(scope, Exception { ExistingExceptionError });
+
+        m_context = WebGLRenderingContextBase::create(*this, attributes, "webgl");
+        if (!m_context)
+            return { nullptr };
+
+        return { RefPtr<WebGLRenderingContext> { &downcast<WebGLRenderingContext>(*m_context) } };
+    }
+
     return { nullptr };
 }
 #endif

Modified: trunk/Source/WebCore/html/OffscreenCanvas.h (225192 => 225193)


--- trunk/Source/WebCore/html/OffscreenCanvas.h	2017-11-27 21:21:43 UTC (rev 225192)
+++ trunk/Source/WebCore/html/OffscreenCanvas.h	2017-11-27 22:12:46 UTC (rev 225193)
@@ -37,15 +37,13 @@
 
 namespace WebCore {
 
+class CanvasRenderingContext;
 class ImageBitmap;
 class WebGLRenderingContext;
 
-// using OffscreenRenderingContext = Variant<
-// #if ENABLE(WEBGL)
-// RefPtr<WebGLRenderingContext>,
-// #endif
-// RefPtr<OffscreenCanvasRenderingContext2D>
-// >;
+#if ENABLE(WEBGL)
+using OffscreenRenderingContext = RefPtr<WebGLRenderingContext>;
+#endif
 
 class OffscreenCanvas final : public RefCounted<OffscreenCanvas>, public CanvasBase, public EventTargetWithInlineData {
     WTF_MAKE_FAST_ALLOCATED;
@@ -73,8 +71,7 @@
     void setSize(const IntSize&) final;
 
 #if ENABLE(WEBGL)
-    // FIXME: Should be optional<OffscreenRenderingContext> from above.
-    ExceptionOr<RefPtr<WebGLRenderingContext>> getContext(JSC::ExecState&, RenderingContextType, Vector<JSC::Strong<JSC::Unknown>>&& arguments);
+    ExceptionOr<OffscreenRenderingContext> getContext(JSC::ExecState&, RenderingContextType, Vector<JSC::Strong<JSC::Unknown>>&& arguments);
 #endif
     RefPtr<ImageBitmap> transferToImageBitmap();
     // void convertToBlob(ImageEncodeOptions options);
@@ -98,6 +95,7 @@
     void derefCanvasBase() final { deref(); }
 
     IntSize m_size;
+    std::unique_ptr<CanvasRenderingContext> m_context;
 };
 
 }

Modified: trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp (225192 => 225193)


--- trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp	2017-11-27 21:21:43 UTC (rev 225192)
+++ trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp	2017-11-27 22:12:46 UTC (rev 225193)
@@ -64,6 +64,7 @@
 #include "OESTextureHalfFloat.h"
 #include "OESTextureHalfFloatLinear.h"
 #include "OESVertexArrayObject.h"
+#include "OffscreenCanvas.h"
 #include "Page.h"
 #include "RenderBox.h"
 #include "RuntimeEnabledFeatures.h"
@@ -513,32 +514,56 @@
     addActivityStateChangeObserverIfNecessary();
 }
 
-HTMLCanvasElement* WebGLRenderingContextBase::canvas()
+WebGLCanvas WebGLRenderingContextBase::canvas()
 {
     auto& base = canvasBase();
+    if (is<OffscreenCanvas>(base))
+        return &downcast<OffscreenCanvas>(base);
+    return &downcast<HTMLCanvasElement>(base);
+}
+
+HTMLCanvasElement* WebGLRenderingContextBase::htmlCanvas()
+{
+    auto& base = canvasBase();
     if (!is<HTMLCanvasElement>(base))
         return nullptr;
     return &downcast<HTMLCanvasElement>(base);
 }
 
+OffscreenCanvas* WebGLRenderingContextBase::offscreenCanvas()
+{
+    auto& base = canvasBase();
+    if (!is<OffscreenCanvas>(base))
+        return nullptr;
+    return &downcast<OffscreenCanvas>(base);
+}
+
 // We check for context loss handling after a few seconds to give the JS a chance to register the event listeners
 // and to discard temporary GL contexts (e.g. feature detection).
 void WebGLRenderingContextBase::checkForContextLossHandling()
 {
-    if (!canvas()->renderer())
+    auto canvas = htmlCanvas();
+    if (!canvas)
         return;
 
-    auto* page = canvas()->document().page();
+    if (!canvas->renderer())
+        return;
+
+    auto* page = canvas->document().page();
     if (!page)
         return;
 
-    bool handlesContextLoss = canvas()->hasEventListeners(eventNames().webglcontextlostEvent) && canvas()->hasEventListeners(eventNames().webglcontextrestoredEvent);
+    bool handlesContextLoss = canvas->hasEventListeners(eventNames().webglcontextlostEvent) && canvas->hasEventListeners(eventNames().webglcontextrestoredEvent);
     page->diagnosticLoggingClient().logDiagnosticMessage(DiagnosticLoggingKeys::pageHandlesWebGLContextLossKey(), handlesContextLoss ? DiagnosticLoggingKeys::yesKey() : DiagnosticLoggingKeys::noKey(), ShouldSample::No);
 }
 
 void WebGLRenderingContextBase::registerWithWebGLStateTracker()
 {
-    auto* page = canvas()->document().page();
+    auto canvas = htmlCanvas();
+    if (!canvas)
+        return;
+
+    auto* page = canvas->document().page();
     if (!page)
         return;
 
@@ -627,8 +652,11 @@
 {
     ASSERT(m_context);
 
-    if (Page* page = canvas()->document().page())
-        m_synthesizedErrorsToConsole = page->settings().webGLErrorsToConsoleEnabled();
+    auto canvas = htmlCanvas();
+    if (canvas) {
+        if (Page* page = canvas->document().page())
+            m_synthesizedErrorsToConsole = page->settings().webGLErrorsToConsoleEnabled();
+    }
 
     m_isGLES2Compliant = m_context->isGLES2Compliant();
     if (m_isGLES2Compliant) {
@@ -654,7 +682,11 @@
     if (!isHighPerformanceContext(m_context))
         return;
 
-    auto* page = canvas()->document().page();
+    auto* canvas = htmlCanvas();
+    if (!canvas)
+        return;
+
+    auto* page = canvas->document().page();
     if (!page)
         return;
 
@@ -668,8 +700,11 @@
 
 void WebGLRenderingContextBase::removeActivityStateChangeObserver()
 {
-    if (auto* page = canvas()->document().page())
-        page->removeActivityStateChangeObserver(*this);
+    auto* canvas = htmlCanvas();
+    if (canvas) {
+        if (auto* page = canvas->document().page())
+            page->removeActivityStateChangeObserver(*this);
+    }
 }
 
 WebGLRenderingContextBase::~WebGLRenderingContextBase()
@@ -721,15 +756,20 @@
     m_context->markContextChanged();
 
     m_layerCleared = false;
-    RenderBox* renderBox = canvas()->renderBox();
+
+    auto* canvas = htmlCanvas();
+    if (!canvas)
+        return;
+
+    RenderBox* renderBox = canvas->renderBox();
     if (isAccelerated() && renderBox && renderBox->hasAcceleratedCompositing()) {
         m_markedCanvasDirty = true;
-        canvas()->clearCopiedImage();
+        htmlCanvas()->clearCopiedImage();
         renderBox->contentChanged(CanvasChanged);
     } else {
         if (!m_markedCanvasDirty) {
             m_markedCanvasDirty = true;
-            canvas()->didDraw(FloatRect(FloatPoint(0, 0), clampedCanvasSize()));
+            canvas->didDraw(FloatRect(FloatPoint(0, 0), clampedCanvasSize()));
         }
     }
 }
@@ -739,10 +779,14 @@
     markContextChanged();
     if (!isAccelerated())
         return;
-    
-    RenderBox* renderBox = canvas()->renderBox();
+
+    auto* canvas = htmlCanvas();
+    if (!canvas)
+        return;
+
+    RenderBox* renderBox = canvas->renderBox();
     if (renderBox && renderBox->hasAcceleratedCompositing())
-        canvas()->notifyObserversCanvasChanged(FloatRect(FloatPoint(0, 0), clampedCanvasSize()));
+        canvas->notifyObserversCanvasChanged(FloatRect(FloatPoint(0, 0), clampedCanvasSize()));
 }
 
 bool WebGLRenderingContextBase::clearIfComposited(GC3Dbitfield mask)
@@ -824,26 +868,30 @@
     if (isContextLostOrPending())
         return;
 
-    if (canvas()->document().printing())
-        canvas()->clearPresentationCopy();
+    auto* canvas = htmlCanvas();
+    if (!canvas)
+        return;
 
+    if (canvas->document().printing())
+        canvas->clearPresentationCopy();
+
     // Until the canvas is written to by the application, the clear that
     // happened after it was composited should be ignored by the compositor.
     if (m_context->layerComposited() && !m_attributes.preserveDrawingBuffer) {
-        m_context->paintCompositedResultsToCanvas(canvas()->buffer());
+        m_context->paintCompositedResultsToCanvas(canvas->buffer());
 
-        canvas()->makePresentationCopy();
+        canvas->makePresentationCopy();
     } else
-        canvas()->clearPresentationCopy();
+        canvas->clearPresentationCopy();
     clearIfComposited();
 
     if (!m_markedCanvasDirty && !m_layerCleared)
         return;
 
-    canvas()->clearCopiedImage();
+    canvas->clearCopiedImage();
     m_markedCanvasDirty = false;
 
-    m_context->paintRenderingResultsToCanvas(canvas()->buffer());
+    m_context->paintRenderingResultsToCanvas(canvas->buffer());
 }
 
 RefPtr<ImageData> WebGLRenderingContextBase::paintRenderingResultsToImageData()
@@ -873,9 +921,12 @@
     height = clamp(height, 1, maxHeight);
 
     if (m_needsUpdate) {
-        RenderBox* renderBox = canvas()->renderBox();
-        if (renderBox && renderBox->hasAcceleratedCompositing())
-            renderBox->contentChanged(CanvasChanged);
+        auto* canvas = htmlCanvas();
+        if (canvas) {
+            RenderBox* renderBox = htmlCanvas()->renderBox();
+            if (renderBox && renderBox->hasAcceleratedCompositing())
+                renderBox->contentChanged(CanvasChanged);
+        }
         m_needsUpdate = false;
     }
 
@@ -1327,13 +1378,15 @@
     m_context->getShaderiv(objectOrZero(shader), GraphicsContext3D::COMPILE_STATUS, &value);
     shader->setValid(value);
 
-    if (m_synthesizedErrorsToConsole && !value) {
+    auto* canvas = htmlCanvas();
+
+    if (canvas && m_synthesizedErrorsToConsole && !value) {
         Ref<Inspector::ScriptCallStack> stackTrace = Inspector::createScriptCallStack(JSMainThreadExecState::currentState());
 
         Vector<String> errors;
         getShaderInfoLog(shader).split("\n", errors);
         for (String& error : errors)
-            canvas()->document().addConsoleMessage(std::make_unique<Inspector::ConsoleMessage>(MessageSource::Rendering, MessageType::Log, MessageLevel::Error, "WebGL: " + error, stackTrace.copyRef()));
+            canvas->document().addConsoleMessage(std::make_unique<Inspector::ConsoleMessage>(MessageSource::Rendering, MessageType::Log, MessageLevel::Error, "WebGL: " + error, stackTrace.copyRef()));
     }
 }
 
@@ -2810,14 +2863,17 @@
 {
     if (m_isPendingPolicyResolution && !m_hasRequestedPolicyResolution) {
         LOG(WebGL, "Context is being used. Attempt to resolve the policy.");
-        Document& document = canvas()->document().topDocument();
-        Page* page = document.page();
-        if (page && !document.url().isLocalFile())
-            page->mainFrame().loader().client().resolveWebGLPolicyForURL(document.url());
-        // FIXME: We don't currently do anything with the result from resolution. A more
-        // complete implementation might try to construct a real context, etc and proceed
-        // with normal operation.
-        // https://bugs.webkit.org/show_bug.cgi?id=129122
+        auto* canvas = htmlCanvas();
+        if (canvas) {
+            Document& document = canvas->document().topDocument();
+            Page* page = document.page();
+            if (page && !document.url().isLocalFile())
+                page->mainFrame().loader().client().resolveWebGLPolicyForURL(document.url());
+            // FIXME: We don't currently do anything with the result from resolution. A more
+            // complete implementation might try to construct a real context, etc and proceed
+            // with normal operation.
+            // https://bugs.webkit.org/show_bug.cgi?id=129122
+        }
         m_hasRequestedPolicyResolution = true;
     }
 
@@ -3135,7 +3191,7 @@
         return;
     // Due to WebGL's same-origin restrictions, it is not possible to
     // taint the origin using the WebGL API.
-    ASSERT(canvas()->originClean());
+    ASSERT(canvasBase().originClean());
 
     GC3Denum internalFormat = 0;
     if (m_framebufferBinding) {
@@ -4709,8 +4765,11 @@
     if (mode == RealLostContext) {
         // Inform the embedder that a lost context was received. In response, the embedder might
         // decide to take action such as asking the user for permission to use WebGL again.
-        if (RefPtr<Frame> frame = canvas()->document().frame())
-            frame->loader().client().didLoseWebGLContext(m_context->getExtensions().getGraphicsResetStatusARB());
+        auto* canvas = htmlCanvas();
+        if (canvas) {
+            if (RefPtr<Frame> frame = canvas->document().frame())
+                frame->loader().client().didLoseWebGLContext(m_context->getExtensions().getGraphicsResetStatusARB());
+        }
     }
 
     detachAndRemoveAllObjects();
@@ -5333,7 +5392,9 @@
     } else
         consoleMessage = std::make_unique<Inspector::ConsoleMessage>(MessageSource::Rendering, MessageType::Log, level, message);
 
-    canvas()->document().addConsoleMessage(WTFMove(consoleMessage));
+    auto* canvas = htmlCanvas();
+    if (canvas)
+        canvas->document().addConsoleMessage(WTFMove(consoleMessage));
 
     --m_numGLErrorsToConsoleAllowed;
     if (!m_numGLErrorsToConsoleAllowed)
@@ -5678,8 +5739,12 @@
 
 void WebGLRenderingContextBase::dispatchContextLostEvent()
 {
+    auto* canvas = htmlCanvas();
+    if (!canvas)
+        return;
+
     Ref<WebGLContextEvent> event = WebGLContextEvent::create(eventNames().webglcontextlostEvent, false, true, emptyString());
-    canvas()->dispatchEvent(event);
+    canvas->dispatchEvent(event);
     m_restoreAllowed = event->defaultPrevented();
     if (m_contextLostMode == RealLostContext && m_restoreAllowed)
         m_restoreTimer.startOneShot(0_s);
@@ -5727,7 +5792,11 @@
         break;
     }
 
-    RefPtr<Frame> frame = canvas()->document().frame();
+    auto* canvas = htmlCanvas();
+    if (!canvas)
+        return;
+
+    RefPtr<Frame> frame = canvas->document().frame();
     if (!frame)
         return;
 
@@ -5760,12 +5829,16 @@
     setupFlags();
     initializeNewContext();
     initializeVertexArrayObjects();
-    canvas()->dispatchEvent(WebGLContextEvent::create(eventNames().webglcontextrestoredEvent, false, true, emptyString()));
+    canvas->dispatchEvent(WebGLContextEvent::create(eventNames().webglcontextrestoredEvent, false, true, emptyString()));
 }
 
 void WebGLRenderingContextBase::dispatchContextChangedEvent()
 {
-    canvas()->dispatchEvent(WebGLContextEvent::create(eventNames().webglcontextchangedEvent, false, true, emptyString()));
+    auto* canvas = htmlCanvas();
+    if (!canvas)
+        return;
+
+    canvas->dispatchEvent(WebGLContextEvent::create(eventNames().webglcontextchangedEvent, false, true, emptyString()));
 }
 
 void WebGLRenderingContextBase::simulateContextChanged()
@@ -5875,8 +5948,8 @@
 
 IntSize WebGLRenderingContextBase::clampedCanvasSize()
 {
-    return IntSize(clamp(canvas()->width(), 1, m_maxViewportDims[0]),
-        clamp(canvas()->height(), 1, m_maxViewportDims[1]));
+    return IntSize(clamp(canvasBase().width(), 1, m_maxViewportDims[0]),
+        clamp(canvasBase().height(), 1, m_maxViewportDims[1]));
 }
 
 GC3Dint WebGLRenderingContextBase::getMaxDrawBuffers()

Modified: trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.h (225192 => 225193)


--- trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.h	2017-11-27 21:21:43 UTC (rev 225192)
+++ trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.h	2017-11-27 22:12:46 UTC (rev 225193)
@@ -65,6 +65,7 @@
 class OESTextureHalfFloatLinear;
 class OESVertexArrayObject;
 class OESElementIndexUint;
+class OffscreenCanvas;
 class WebGLActiveInfo;
 class WebGLContextGroup;
 class WebGLContextObject;
@@ -112,12 +113,14 @@
     return (*clippedX != x || *clippedY != y || *clippedWidth != width || *clippedHeight != height);
 }
 
+using WebGLCanvas = WTF::Variant<RefPtr<HTMLCanvasElement>, RefPtr<OffscreenCanvas>>;
+
 class WebGLRenderingContextBase : public GPUBasedCanvasRenderingContext, private ActivityStateChangeObserver {
 public:
     static std::unique_ptr<WebGLRenderingContextBase> create(CanvasBase&, WebGLContextAttributes&, const String&);
     virtual ~WebGLRenderingContextBase();
 
-    HTMLCanvasElement* canvas();
+    WebGLCanvas canvas();
 
     int drawingBufferWidth() const;
     int drawingBufferHeight() const;
@@ -846,6 +849,9 @@
     // Check if EXT_draw_buffers extension is supported and if it satisfies the WebGL requirements.
     bool supportsDrawBuffers();
 
+    HTMLCanvasElement* htmlCanvas();
+    OffscreenCanvas* offscreenCanvas();
+
 private:
     bool validateArrayBufferType(const char* functionName, GC3Denum type, std::optional<JSC::TypedArrayType>);
     void registerWithWebGLStateTracker();

Modified: trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.idl (225192 => 225193)


--- trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.idl	2017-11-27 21:21:43 UTC (rev 225192)
+++ trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.idl	2017-11-27 22:12:46 UTC (rev 225193)
@@ -48,6 +48,8 @@
 typedef (ImageData or HTMLImageElement or HTMLCanvasElement) TexImageSource;
 #endif
 
+typedef (HTMLCanvasElement or OffscreenCanvas) WebGLCanvas;
+
 [
     Conditional=WEBGL,
     CustomIsReachable,
@@ -58,7 +60,7 @@
     ExportMacro=WEBCORE_EXPORT,
 ] interface WebGLRenderingContextBase {
 
-    readonly attribute HTMLCanvasElement canvas;
+    readonly attribute WebGLCanvas canvas;
 
     /* ClearBufferMask */
     const GLenum DEPTH_BUFFER_BIT = 0x00000100;

Modified: trunk/Source/WebCore/inspector/InspectorInstrumentation.h (225192 => 225193)


--- trunk/Source/WebCore/inspector/InspectorInstrumentation.h	2017-11-27 21:21:43 UTC (rev 225192)
+++ trunk/Source/WebCore/inspector/InspectorInstrumentation.h	2017-11-27 22:12:46 UTC (rev 225193)
@@ -43,6 +43,7 @@
 #include "HitTestResult.h"
 #include "InspectorController.h"
 #include "InspectorInstrumentationCookie.h"
+#include "OffscreenCanvas.h"
 #include "Page.h"
 #include "StorageArea.h"
 #include "WorkerGlobalScope.h"
@@ -1255,37 +1256,57 @@
 inline void InspectorInstrumentation::didEnableExtension(WebGLRenderingContextBase& context, const String& extension)
 {
     FAST_RETURN_IF_NO_FRONTENDS(void());
-
-    if (auto* canvasElement = context.canvas()) {
-        if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForDocument(canvasElement->document()))
-            didEnableExtensionImpl(*instrumentingAgents, context, extension);
-    }
+    auto canvas = context.canvas();
+    WTF::switchOn(canvas,
+        [&] (const RefPtr<HTMLCanvasElement>& htmlCanvasElement) {
+            if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForDocument(htmlCanvasElement->document()))
+                didEnableExtensionImpl(*instrumentingAgents, context, extension);
+        },
+        [&] (const RefPtr<OffscreenCanvas>&) {
+        }
+    );
 }
 
 inline void InspectorInstrumentation::didCreateProgram(WebGLRenderingContextBase& context, WebGLProgram& program)
 {
-    if (auto* canvasElement = context.canvas()) {
-        if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForDocument(canvasElement->document()))
-            didCreateProgramImpl(*instrumentingAgents, context, program);
-    }
+    auto canvas = context.canvas();
+    WTF::switchOn(canvas,
+        [&] (const RefPtr<HTMLCanvasElement>& htmlCanvasElement) {
+            if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForDocument(htmlCanvasElement->document()))
+                didCreateProgramImpl(*instrumentingAgents, context, program);
+        },
+        [&] (const RefPtr<OffscreenCanvas>&) {
+        }
+    );
 }
 
 inline void InspectorInstrumentation::willDeleteProgram(WebGLRenderingContextBase& context, WebGLProgram& program)
 {
-    if (auto* canvasElement = context.canvas()) {
-        if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForDocument(canvasElement->document()))
-            willDeleteProgramImpl(*instrumentingAgents, program);
-    }
+    auto canvas = context.canvas();
+    WTF::switchOn(canvas,
+        [&] (const RefPtr<HTMLCanvasElement>& htmlCanvasElement) {
+            if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForDocument(htmlCanvasElement->document()))
+                willDeleteProgramImpl(*instrumentingAgents, program);
+        },
+        [&] (const RefPtr<OffscreenCanvas>&) {
+        }
+    );
 }
 
 inline bool InspectorInstrumentation::isShaderProgramDisabled(WebGLRenderingContextBase& context, WebGLProgram& program)
 {
     FAST_RETURN_IF_NO_FRONTENDS(false);
-    if (auto* canvasElement = context.canvas()) {
-        if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForDocument(canvasElement->document()))
-            return isShaderProgramDisabledImpl(*instrumentingAgents, program);
-    }
-    return false;
+    auto canvas = context.canvas();
+    return WTF::switchOn(canvas,
+        [&] (const RefPtr<HTMLCanvasElement>& htmlCanvasElement) {
+            if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForDocument(htmlCanvasElement->document()))
+                return isShaderProgramDisabledImpl(*instrumentingAgents, program);
+            return false;
+        },
+        [&] (const RefPtr<OffscreenCanvas>&) {
+            return false;
+        }
+    );
 }
 #endif
 

Modified: trunk/Source/WebCore/inspector/agents/InspectorCanvasAgent.cpp (225192 => 225193)


--- trunk/Source/WebCore/inspector/agents/InspectorCanvasAgent.cpp	2017-11-27 21:21:43 UTC (rev 225192)
+++ trunk/Source/WebCore/inspector/agents/InspectorCanvasAgent.cpp	2017-11-27 22:12:46 UTC (rev 225193)
@@ -36,6 +36,7 @@
 #include "JSCanvasRenderingContext2D.h"
 #include "JSMainThreadExecState.h"
 #include "MainFrame.h"
+#include "OffscreenCanvas.h"
 #include "ScriptState.h"
 #include "StringAdaptors.h"
 #include <inspector/IdentifiersFactory.h>
@@ -528,26 +529,32 @@
 #if ENABLE(WEBGL)
 void InspectorCanvasAgent::didEnableExtension(WebGLRenderingContextBase& context, const String& extension)
 {
-    auto* inspectorCanvas = findInspectorCanvas(*context.canvas());
-    if (!inspectorCanvas)
-        return;
+    auto canvas = context.canvas();
+    if (WTF::holds_alternative<RefPtr<HTMLCanvasElement>>(canvas)) {
+        auto* inspectorCanvas = findInspectorCanvas(*WTF::get<RefPtr<HTMLCanvasElement>>(canvas));
+        if (!inspectorCanvas)
+            return;
 
-    m_frontendDispatcher->extensionEnabled(inspectorCanvas->identifier(), extension);
+        m_frontendDispatcher->extensionEnabled(inspectorCanvas->identifier(), extension);
+    }
 }
 
 void InspectorCanvasAgent::didCreateProgram(WebGLRenderingContextBase& context, WebGLProgram& program)
 {
-    auto* inspectorCanvas = findInspectorCanvas(*context.canvas());
-    ASSERT(inspectorCanvas);
-    if (!inspectorCanvas)
-        return;
+    auto canvas = context.canvas();
+    if (WTF::holds_alternative<RefPtr<HTMLCanvasElement>>(canvas)) {
+        auto* inspectorCanvas = findInspectorCanvas(*WTF::get<RefPtr<HTMLCanvasElement>>(canvas));
+        ASSERT(inspectorCanvas);
+        if (!inspectorCanvas)
+            return;
 
-    auto inspectorProgram = InspectorShaderProgram::create(program, *inspectorCanvas);
-    String programIdentifier = inspectorProgram->identifier();
-    m_identifierToInspectorProgram.set(programIdentifier, WTFMove(inspectorProgram));
+        auto inspectorProgram = InspectorShaderProgram::create(program, *inspectorCanvas);
+        String programIdentifier = inspectorProgram->identifier();
+        m_identifierToInspectorProgram.set(programIdentifier, WTFMove(inspectorProgram));
 
-    if (m_enabled)
-        m_frontendDispatcher->programCreated(inspectorCanvas->identifier(), programIdentifier);
+        if (m_enabled)
+            m_frontendDispatcher->programCreated(inspectorCanvas->identifier(), programIdentifier);
+    }
 }
 
 void InspectorCanvasAgent::willDeleteProgram(WebGLProgram& program)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to