Diff
Modified: trunk/LayoutTests/ChangeLog (243355 => 243356)
--- trunk/LayoutTests/ChangeLog 2019-03-22 02:33:38 UTC (rev 243355)
+++ trunk/LayoutTests/ChangeLog 2019-03-22 02:47:35 UTC (rev 243356)
@@ -1,3 +1,17 @@
+2019-03-21 Devin Rousso <drou...@apple.com>
+
+ Web Inspector: Safari Canvas Inspector seems to show the canvas being rendered twice per frame.
+ https://bugs.webkit.org/show_bug.cgi?id=196082
+ <rdar://problem/49113496>
+
+ Reviewed by Dean Jackson.
+
+ * inspector/canvas/recording-2d.html:
+ * inspector/canvas/recording-bitmaprenderer.html:
+ * inspector/canvas/recording-html-2d.html:
+ * inspector/canvas/recording-webgl.html:
+ * inspector/canvas/setRecordingAutoCaptureFrameCount.html:
+
2019-03-21 Joseph Pecoraro <pecor...@apple.com>
Web Inspector: Timelines - Cannot export on about:blank - suggested filename containing a colon silently fails
Modified: trunk/LayoutTests/inspector/canvas/recording-2d.html (243355 => 243356)
--- trunk/LayoutTests/inspector/canvas/recording-2d.html 2019-03-22 02:33:38 UTC (rev 243355)
+++ trunk/LayoutTests/inspector/canvas/recording-2d.html 2019-03-22 02:47:35 UTC (rev 243356)
@@ -39,8 +39,6 @@
pattern = ctx.createPattern(image, "no-repeat");
bitmap = await createImageBitmap(image);
- document.body.appendChild(canvas);
-
ctx.save();
cancelActions();
@@ -53,7 +51,7 @@
} catch (e) { }
}
-let timeoutID = NaN;
+let requestAnimationFrameId = NaN;
let saveCount = 1;
function cancelActions() {
@@ -61,8 +59,8 @@
ctx.restore();
ctx.restore(); // Ensures the state is reset between test cases.
- clearTimeout(timeoutID);
- timeoutID = NaN;
+ cancelAnimationFrame(requestAnimationFrameId);
+ requestAnimationFrameId = NaN;
ctx.save(); // Ensures the state is reset between test cases.
ctx.save(); // This matches the `restore` call in `performActions`.
@@ -399,7 +397,7 @@
function executeFrameFunction() {
frames[index++]();
if (index < frames.length)
- timeoutID = setTimeout(executeFrameFunction, 0);
+ requestAnimationFrameId = requestAnimationFrame(executeFrameFunction);
};
executeFrameFunction();
}
Modified: trunk/LayoutTests/inspector/canvas/recording-bitmaprenderer.html (243355 => 243356)
--- trunk/LayoutTests/inspector/canvas/recording-bitmaprenderer.html 2019-03-22 02:33:38 UTC (rev 243355)
+++ trunk/LayoutTests/inspector/canvas/recording-bitmaprenderer.html 2019-03-22 02:47:35 UTC (rev 243356)
@@ -23,7 +23,7 @@
function load() {
ctx = canvas.getContext("bitmaprenderer");
- document.body.appendChild(canvas);
+ cancelActions();
runTest();
}
@@ -34,11 +34,11 @@
} catch (e) { }
}
-let timeoutID = NaN;
+let requestAnimationFrameId = NaN;
function cancelActions() {
- clearTimeout(timeoutID);
- timeoutID = NaN;
+ cancelAnimationFrame(requestAnimationFrameId);
+ requestAnimationFrameId = NaN;
createImageBitmap(transparentImage).then((transparentBitmap) => {
ctx.transferFromImageBitmap(transparentBitmap);
@@ -68,7 +68,7 @@
function executeFrameFunction() {
frames[index++]();
if (index < frames.length)
- timeoutID = setTimeout(executeFrameFunction, 0);
+ requestAnimationFrameId = requestAnimationFrame(executeFrameFunction);
};
executeFrameFunction();
}
Modified: trunk/LayoutTests/inspector/canvas/recording-html-2d.html (243355 => 243356)
--- trunk/LayoutTests/inspector/canvas/recording-html-2d.html 2019-03-22 02:33:38 UTC (rev 243355)
+++ trunk/LayoutTests/inspector/canvas/recording-html-2d.html 2019-03-22 02:47:35 UTC (rev 243356)
@@ -39,7 +39,7 @@
imageBitmap = await createImageBitmap(image);
- document.body.appendChild(canvas);
+ cancelActions();
context.strokeStyle = "red";
context.save();
@@ -56,7 +56,15 @@
} catch (e) { }
}
+let requestAnimationFrameId = NaN;
+
function cancelActions() {
+ cancelAnimationFrame(requestAnimationFrameId);
+ requestAnimationFrameId = NaN;
+
+ context.resetTransform();
+ context.beginPath();
+ context.clearRect(0, 0, context.canvas.width, context.canvas.height);
}
function performActions() {
@@ -97,7 +105,7 @@
function executeFrameFunction() {
frames[index++]();
if (index < frames.length)
- timeoutID = setTimeout(executeFrameFunction, 0);
+ requestAnimationFrameId = requestAnimationFrame(executeFrameFunction);
};
executeFrameFunction();
}
Modified: trunk/LayoutTests/inspector/canvas/recording-webgl.html (243355 => 243356)
--- trunk/LayoutTests/inspector/canvas/recording-webgl.html 2019-03-22 02:33:38 UTC (rev 243355)
+++ trunk/LayoutTests/inspector/canvas/recording-webgl.html 2019-03-22 02:47:35 UTC (rev 243356)
@@ -49,7 +49,7 @@
shader = context.createShader(context.VERTEX_SHADER);
texture = context.createTexture();
- document.body.appendChild(context.canvas);
+ cancelActions();
runTest();
}
@@ -60,11 +60,11 @@
} catch (e) { }
}
-let timeoutID = NaN;
+let requestAnimationFrameId = NaN;
function cancelActions() {
- clearTimeout(timeoutID);
- timeoutID = NaN;
+ cancelAnimationFrame(requestAnimationFrameId);
+ requestAnimationFrameId = NaN;
context.clearColor(0.0, 0.0, 0.0, 0.0);
context.clear(context.COLOR_BUFFER_BIT);
@@ -502,7 +502,7 @@
function executeFrameFunction() {
frames[index++]();
if (index < frames.length)
- timeoutID = setTimeout(executeFrameFunction, 0);
+ requestAnimationFrameId = requestAnimationFrame(executeFrameFunction);
};
executeFrameFunction();
}
Modified: trunk/LayoutTests/inspector/canvas/setRecordingAutoCaptureFrameCount.html (243355 => 243356)
--- trunk/LayoutTests/inspector/canvas/setRecordingAutoCaptureFrameCount.html 2019-03-22 02:33:38 UTC (rev 243355)
+++ trunk/LayoutTests/inspector/canvas/setRecordingAutoCaptureFrameCount.html 2019-03-22 02:47:35 UTC (rev 243356)
@@ -6,11 +6,11 @@
if (window.internals)
window.internals.settings.setWebGLErrorsToConsoleEnabled(false);
-let timeoutID = NaN;
+let requestAnimationFrameId = NaN;
function cancelActions() {
- clearTimeout(timeoutID);
- timeoutID = NaN;
+ cancelAnimationFrame(requestAnimationFrameId);
+ requestAnimationFrameId = NaN;
}
function performActions(frames) {
@@ -19,7 +19,7 @@
frames[index++]();
if (index < frames.length)
- timeoutID = setTimeout(executeFrameFunction, 0);
+ requestAnimationFrameId = requestAnimationFrame(executeFrameFunction);
else {
setTimeout(() => {
TestPage.dispatchEventToFrontend("LastFrame");
Modified: trunk/Source/WebCore/ChangeLog (243355 => 243356)
--- trunk/Source/WebCore/ChangeLog 2019-03-22 02:33:38 UTC (rev 243355)
+++ trunk/Source/WebCore/ChangeLog 2019-03-22 02:47:35 UTC (rev 243356)
@@ -1,3 +1,106 @@
+2019-03-21 Devin Rousso <drou...@apple.com>
+
+ Web Inspector: Safari Canvas Inspector seems to show the canvas being rendered twice per frame.
+ https://bugs.webkit.org/show_bug.cgi?id=196082
+ <rdar://problem/49113496>
+
+ Reviewed by Dean Jackson.
+
+ Tests: inspector/canvas/recording-2d.html
+ inspector/canvas/recording-bitmaprenderer.html
+ inspector/canvas/recording-html-2d.html
+ inspector/canvas/recording-webgl.html
+ inspector/canvas/setRecordingAutoCaptureFrameCount.html
+
+ WebGL `<canvas>` follow a different "rendering" path such that `HTMLCanvasElement::paint`
+ isn't called. Previously, there was a 0s timer that was started after the first action of a
+ frame was recorded (for the case that the `<canvas>` isn't attached to the DOM) that would
+ automatically stop the recording. It was possible that actions in two different "frame"s
+ were recorded as part of the same frame, because the WebGL `<canvas>` would instead fall
+ back to the timer to know when the "frame" had ended.
+
+ Now, there is additional instrumentation for the WebGL specific rendering path.
+ Additionally, replace the 0s timer with a microtask for more "immediate" calling.
+
+ * html/HTMLCanvasElement.cpp:
+ (WebCore::HTMLCanvasElement::paint):
+ Ensure that the `InspectorInstrumentation` call is last. This matches what we expect, as
+ before we were instrumenting right before is it about to paint.
+
+ * platform/graphics/GraphicsContext3D.h:
+ (WebCore::GraphicsContext3D::Client::~Client): Added.
+ (WebCore::GraphicsContext3D::addClient): Added.
+ (WebCore::GraphicsContext3D::removeClient): Added.
+ (WebCore::GraphicsContext3D::setWebGLContext): Deleted.
+ * platform/graphics/opengl/GraphicsContext3DOpenGLCommon.cpp:
+ (WebCore::GraphicsContext3D::markLayerComposited):
+ (WebCore::GraphicsContext3D::forceContextLost):
+ (WebCore::GraphicsContext3D::recycleContext):
+ (WebCore::GraphicsContext3D::dispatchContextChangedNotification):
+ * html/canvas/WebGLRenderingContextBase.h:
+ * html/canvas/WebGLRenderingContextBase.cpp:
+ (WebCore::WebGLRenderingContextBase::WebGLRenderingContextBase):
+ (WebCore::WebGLRenderingContextBase::destroyGraphicsContext3D):
+ (WebCore::WebGLRenderingContextBase::didComposite): Added.
+ (WebCore::WebGLRenderingContextBase::forceContextLost):
+ (WebCore::WebGLRenderingContextBase::recycleContext):
+ (WebCore::WebGLRenderingContextBase::dispatchContextChangedNotification): Added.
+ (WebCore::WebGLRenderingContextBase::dispatchContextChangedEvent): Deleted.
+ Introduce a `GraphicsContext3DClient` abstract class, rather than passing the
+ `WebGLRenderingContextBase` directly to the `GraphicsContext3D` (layering violation).
+ Notify the client whenever the `GraphicsContext3D` composites, which will in turn notify the
+ `InspectorCanvasAgent` so that it knows that the "frame" is over.
+
+ * inspector/agents/InspectorCanvasAgent.h:
+ * inspector/agents/InspectorCanvasAgent.cpp:
+ (WebCore::InspectorCanvasAgent::InspectorCanvasAgent):
+ (WebCore::InspectorCanvasAgent::requestNode):
+ (WebCore::InspectorCanvasAgent::requestContent):
+ (WebCore::InspectorCanvasAgent::requestCSSCanvasClientNodes):
+ (WebCore::InspectorCanvasAgent::resolveCanvasContext):
+ (WebCore::InspectorCanvasAgent::startRecording):
+ (WebCore::InspectorCanvasAgent::stopRecording):
+ (WebCore::InspectorCanvasAgent::requestShaderSource):
+ (WebCore::InspectorCanvasAgent::updateShader):
+ (WebCore::InspectorCanvasAgent::setShaderProgramDisabled):
+ (WebCore::InspectorCanvasAgent::setShaderProgramHighlighted):
+ (WebCore::InspectorCanvasAgent::didChangeCSSCanvasClientNodes):
+ (WebCore::InspectorCanvasAgent::didChangeCanvasMemory):
+ (WebCore::InspectorCanvasAgent::recordCanvasAction):
+ (WebCore::InspectorCanvasAgent::canvasDestroyed):
+ (WebCore::InspectorCanvasAgent::didFinishRecordingCanvasFrame):
+ (WebCore::InspectorCanvasAgent::consoleStartRecordingCanvas):
+ (WebCore::InspectorCanvasAgent::didEnableExtension):
+ (WebCore::InspectorCanvasAgent::didCreateProgram):
+ (WebCore::InspectorCanvasAgent::willDeleteProgram):
+ (WebCore::InspectorCanvasAgent::isShaderProgramDisabled):
+ (WebCore::InspectorCanvasAgent::isShaderProgramHighlighted):
+ (WebCore::InspectorCanvasAgent::clearCanvasData):
+ (WebCore::InspectorCanvasAgent::assertInspectorCanvas):
+ (WebCore::InspectorCanvasAgent::findInspectorCanvas):
+ (WebCore::InspectorCanvasAgent::assertInspectorProgram):
+ (WebCore::InspectorCanvasAgent::findInspectorProgram):
+ (WebCore::InspectorCanvasAgent::canvasRecordingTimerFired): Deleted.
+ Replace raw pointers with `RefPtr`s. This is primarily used so that the microtask (instead
+ of a timer) that is enqueued after the first action of each frame is recorded can access a
+ ref-counted instance of an `InspectorCanvas`, ensuring that it isn't destructed.
+
+ * inspector/InspectorCanvas.h:
+ * inspector/InspectorCanvas.cpp:
+ (WebCore::InspectorCanvas::canvasElement):
+ (WebCore::InspectorCanvas::recordAction):
+ (WebCore::InspectorCanvas::finalizeFrame):
+ (WebCore::InspectorCanvas::releaseObjectForRecording): Added.
+ (WebCore::InspectorCanvas::getCanvasContentAsDataURL):
+ (WebCore::InspectorCanvas::appendActionSnapshotIfNeeded):
+ (WebCore::InspectorCanvas::buildInitialState):
+ (WebCore::InspectorCanvas::releaseInitialState): Deleted.
+ (WebCore::InspectorCanvas::releaseFrames): Deleted.
+ (WebCore::InspectorCanvas::releaseData): Deleted.
+ Move the recording payload construction logic to `InspectorCanvas` so the actual data
+ doesn't need to leave that class.
+ Drive-by: unify the logic for getting the contents of a canvas from `InspectorCanvasAgent`.
+
2019-03-21 Tim Horton <timothy_hor...@apple.com>
Adopt UIWKDocumentContext
Modified: trunk/Source/WebCore/html/HTMLCanvasElement.cpp (243355 => 243356)
--- trunk/Source/WebCore/html/HTMLCanvasElement.cpp 2019-03-22 02:33:38 UTC (rev 243355)
+++ trunk/Source/WebCore/html/HTMLCanvasElement.cpp 2019-03-22 02:47:35 UTC (rev 243356)
@@ -668,38 +668,40 @@
void HTMLCanvasElement::paint(GraphicsContext& context, const LayoutRect& r)
{
- if (UNLIKELY(m_context && m_context->callTracingActive()))
- InspectorInstrumentation::didFinishRecordingCanvasFrame(*m_context);
-
// Clear the dirty rect
m_dirtyRect = FloatRect();
- if (context.paintingDisabled())
- return;
-
- if (m_context) {
- if (!paintsIntoCanvasBuffer() && !document().printing())
- return;
+ if (!context.paintingDisabled()) {
+ bool shouldPaint = true;
- m_context->paintRenderingResultsToCanvas();
- }
+ if (m_context) {
+ shouldPaint = paintsIntoCanvasBuffer() || document().printing();
+ if (shouldPaint)
+ m_context->paintRenderingResultsToCanvas();
+ }
- if (hasCreatedImageBuffer()) {
- ImageBuffer* imageBuffer = buffer();
- if (imageBuffer) {
- if (m_presentedImage) {
- ImageOrientationDescription orientationDescription;
+ if (shouldPaint) {
+ if (hasCreatedImageBuffer()) {
+ ImageBuffer* imageBuffer = buffer();
+ if (imageBuffer) {
+ if (m_presentedImage) {
+ ImageOrientationDescription orientationDescription;
#if ENABLE(CSS_IMAGE_ORIENTATION)
- orientationDescription.setImageOrientationEnum(renderer()->style().imageOrientation());
-#endif
- context.drawImage(*m_presentedImage, snappedIntRect(r), ImagePaintingOptions(orientationDescription));
- } else
- context.drawImageBuffer(*imageBuffer, snappedIntRect(r));
+ orientationDescription.setImageOrientationEnum(renderer()->style().imageOrientation());
+#endif
+ context.drawImage(*m_presentedImage, snappedIntRect(r), ImagePaintingOptions(orientationDescription));
+ } else
+ context.drawImageBuffer(*imageBuffer, snappedIntRect(r));
+ }
+ }
+
+ if (isGPUBased())
+ downcast<GPUBasedCanvasRenderingContext>(*m_context).markLayerComposited();
}
}
- if (isGPUBased())
- downcast<GPUBasedCanvasRenderingContext>(*m_context).markLayerComposited();
+ if (UNLIKELY(m_context && m_context->callTracingActive()))
+ InspectorInstrumentation::didFinishRecordingCanvasFrame(*m_context);
}
bool HTMLCanvasElement::isGPUBased() const
Modified: trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp (243355 => 243356)
--- trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp 2019-03-22 02:33:38 UTC (rev 243355)
+++ trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp 2019-03-22 02:47:35 UTC (rev 243356)
@@ -661,7 +661,7 @@
m_contextGroup = WebGLContextGroup::create();
m_contextGroup->addContext(*this);
- m_context->setWebGLContext(this);
+ m_context->addClient(*this);
m_context->getIntegerv(GraphicsContext3D::MAX_VIEWPORT_DIMS, m_maxViewportDims);
@@ -914,6 +914,7 @@
removeActivityStateChangeObserver();
if (m_context) {
+ m_context->removeClient(*this);
m_context->setContextLostCallback(nullptr);
m_context->setErrorMessageCallback(nullptr);
m_context = nullptr;
@@ -5042,15 +5043,6 @@
m_contextGroup->loseContextGroup(mode);
}
-void WebGLRenderingContextBase::recycleContext()
-{
- printToConsole(MessageLevel::Error, "There are too many active WebGL contexts on this page, the oldest context will be lost.");
- // Using SyntheticLostContext means the developer won't be able to force the restoration
- // of the context by calling preventDefault() in a "webglcontextlost" event handler.
- forceLostContext(SyntheticLostContext);
- destroyGraphicsContext3D();
-}
-
void WebGLRenderingContextBase::loseContextImpl(WebGLRenderingContextBase::LostContextMode mode)
{
if (isContextLost())
@@ -6225,15 +6217,6 @@
canvas->dispatchEvent(WebGLContextEvent::create(eventNames().webglcontextrestoredEvent, Event::CanBubble::No, Event::IsCancelable::Yes, emptyString()));
}
-void WebGLRenderingContextBase::dispatchContextChangedEvent()
-{
- auto* canvas = htmlCanvas();
- if (!canvas)
- return;
-
- canvas->dispatchEvent(WebGLContextEvent::create(eventNames().webglcontextchangedEvent, Event::CanBubble::No, Event::IsCancelable::Yes, emptyString()));
-}
-
void WebGLRenderingContextBase::simulateContextChanged()
{
if (m_context)
@@ -6513,6 +6496,36 @@
m_context->setFailNextGPUStatusCheck();
}
+void WebGLRenderingContextBase::didComposite()
+{
+ if (UNLIKELY(callTracingActive()))
+ InspectorInstrumentation::didFinishRecordingCanvasFrame(*this);
+}
+
+void WebGLRenderingContextBase::forceContextLost()
+{
+ forceLostContext(WebGLRenderingContextBase::RealLostContext);
+}
+
+void WebGLRenderingContextBase::recycleContext()
+{
+ printToConsole(MessageLevel::Error, "There are too many active WebGL contexts on this page, the oldest context will be lost.");
+ // Using SyntheticLostContext means the developer won't be able to force the restoration
+ // of the context by calling preventDefault() in a "webglcontextlost" event handler.
+ forceLostContext(SyntheticLostContext);
+ destroyGraphicsContext3D();
+}
+
+void WebGLRenderingContextBase::dispatchContextChangedNotification()
+{
+ auto* canvas = htmlCanvas();
+ if (!canvas)
+ return;
+
+ canvas->dispatchEvent(WebGLContextEvent::create(eventNames().webglcontextchangedEvent, Event::CanBubble::No, Event::IsCancelable::Yes, emptyString()));
+}
+
+
} // namespace WebCore
#endif // ENABLE(WEBGL)
Modified: trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.h (243355 => 243356)
--- trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.h 2019-03-22 02:33:38 UTC (rev 243355)
+++ trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.h 2019-03-22 02:47:35 UTC (rev 243356)
@@ -94,7 +94,7 @@
using WebGLCanvas = WTF::Variant<RefPtr<HTMLCanvasElement>, RefPtr<OffscreenCanvas>>;
-class WebGLRenderingContextBase : public GPUBasedCanvasRenderingContext, private ActivityStateChangeObserver {
+class WebGLRenderingContextBase : public GraphicsContext3D::Client, public GPUBasedCanvasRenderingContext, private ActivityStateChangeObserver {
public:
static std::unique_ptr<WebGLRenderingContextBase> create(CanvasBase&, WebGLContextAttributes&, const String&);
virtual ~WebGLRenderingContextBase();
@@ -330,10 +330,8 @@
SyntheticLostContext
};
void forceLostContext(LostContextMode);
- void recycleContext();
void forceRestoreContext();
void loseContextImpl(LostContextMode);
- void dispatchContextChangedEvent();
WEBCORE_EXPORT void simulateContextChanged();
GraphicsContext3D* graphicsContext3D() const { return m_context.get(); }
@@ -359,6 +357,12 @@
// Used for testing only, from Internals.
WEBCORE_EXPORT void setFailNextGPUStatusCheck();
+ // GraphicsContext3D::Client
+ void didComposite() override;
+ void forceContextLost() override;
+ void recycleContext() override;
+ void dispatchContextChangedNotification() override;
+
protected:
WebGLRenderingContextBase(CanvasBase&, WebGLContextAttributes);
WebGLRenderingContextBase(CanvasBase&, Ref<GraphicsContext3D>&&, WebGLContextAttributes);
Modified: trunk/Source/WebCore/inspector/InspectorCanvas.cpp (243355 => 243356)
--- trunk/Source/WebCore/inspector/InspectorCanvas.cpp 2019-03-22 02:33:38 UTC (rev 243355)
+++ trunk/Source/WebCore/inspector/InspectorCanvas.cpp 2019-03-22 02:47:35 UTC (rev 243356)
@@ -89,9 +89,8 @@
HTMLCanvasElement* InspectorCanvas::canvasElement()
{
- auto* canvasBase = &m_context.canvasBase();
- if (is<HTMLCanvasElement>(canvasBase))
- return downcast<HTMLCanvasElement>(canvasBase);
+ if (is<HTMLCanvasElement>(m_context.canvasBase()))
+ return &downcast<HTMLCanvasElement>(m_context.canvasBase());
return nullptr;
}
@@ -137,6 +136,9 @@
void InspectorCanvas::recordAction(const String& name, Vector<RecordCanvasActionVariant>&& parameters)
{
if (!m_initialState) {
+ // We should only construct the initial state for the first action of the recording.
+ ASSERT(!m_frames && !m_currentActions);
+
m_initialState = buildInitialState();
m_bufferUsed += m_initialState->memoryCost();
}
@@ -171,26 +173,10 @@
#endif
}
-RefPtr<Inspector::Protocol::Recording::InitialState>&& InspectorCanvas::releaseInitialState()
+void InspectorCanvas::finalizeFrame()
{
- return WTFMove(m_initialState);
-}
-
-RefPtr<JSON::ArrayOf<Inspector::Protocol::Recording::Frame>>&& InspectorCanvas::releaseFrames()
-{
appendActionSnapshotIfNeeded();
- return WTFMove(m_frames);
-}
-
-RefPtr<JSON::ArrayOf<JSON::Value>>&& InspectorCanvas::releaseData()
-{
- m_indexedDuplicateData.clear();
- return WTFMove(m_serializedDuplicateData);
-}
-
-void InspectorCanvas::finalizeFrame()
-{
if (m_frames && m_frames->length() && !std::isnan(m_currentFrameStartTime)) {
auto currentFrame = static_cast<Inspector::Protocol::Recording::Frame*>(m_frames->get(m_frames->length() - 1).get());
currentFrame->setDuration((MonotonicTime::now() - m_currentFrameStartTime).milliseconds());
@@ -311,22 +297,61 @@
return canvas;
}
-void InspectorCanvas::appendActionSnapshotIfNeeded()
+Ref<Inspector::Protocol::Recording::Recording> InspectorCanvas::releaseObjectForRecording()
{
- if (!m_actionNeedingSnapshot)
- return;
+ ASSERT(!m_currentActions);
+ ASSERT(!m_actionNeedingSnapshot);
+ ASSERT(!m_frames);
- m_actionNeedingSnapshot->addItem(indexForData(getCanvasContentAsDataURL()));
- m_actionNeedingSnapshot = nullptr;
+ // FIXME: <https://webkit.org/b/176008> Web Inspector: Record actions performed on WebGL2RenderingContext
+
+ Inspector::Protocol::Recording::Type type;
+ if (is<CanvasRenderingContext2D>(m_context))
+ type = Inspector::Protocol::Recording::Type::Canvas2D;
+ else if (is<ImageBitmapRenderingContext>(m_context))
+ type = Inspector::Protocol::Recording::Type::CanvasBitmapRenderer;
+#if ENABLE(WEBGL)
+ else if (is<WebGLRenderingContext>(m_context))
+ type = Inspector::Protocol::Recording::Type::CanvasWebGL;
+#endif
+ else {
+ ASSERT_NOT_REACHED();
+ type = Inspector::Protocol::Recording::Type::Canvas2D;
+ }
+
+ auto recording = Inspector::Protocol::Recording::Recording::create()
+ .setVersion(Inspector::Protocol::Recording::VERSION)
+ .setType(type)
+ .setInitialState(m_initialState.releaseNonNull())
+ .setData(m_serializedDuplicateData.releaseNonNull())
+ .release();
+
+ if (!m_recordingName.isEmpty())
+ recording->setName(m_recordingName);
+
+ resetRecordingData();
+
+ return recording;
}
-String InspectorCanvas::getCanvasContentAsDataURL()
+String InspectorCanvas::getCanvasContentAsDataURL(ErrorString& errorString)
{
+ // FIXME: <https://webkit.org/b/173621> Web Inspector: Support getting the content of WebMetal context;
+ if (!is<CanvasRenderingContext2D>(m_context)
+#if ENABLE(WEBGL)
+ && !is<WebGLRenderingContextBase>(m_context)
+#endif
+ && !is<ImageBitmapRenderingContext>(m_context)) {
+ errorString = "Unsupported canvas context type"_s;
+ return emptyString();
+ }
+
// FIXME: <https://webkit.org/b/180833> Web Inspector: support OffscreenCanvas for Canvas related operations
-
auto* node = canvasElement();
- if (!node)
- return String();
+ if (!node) {
+ errorString = "Context isn't related to an HTMLCanvasElement"_s;
+ return emptyString();
+ }
#if ENABLE(WEBGL)
if (is<WebGLRenderingContextBase>(m_context))
@@ -340,12 +365,29 @@
downcast<WebGLRenderingContextBase>(m_context).setPreventBufferClearForInspector(false);
#endif
- if (result.hasException())
- return String();
+ if (result.hasException()) {
+ errorString = result.releaseException().releaseMessage();
+ return emptyString();
+ }
return result.releaseReturnValue().string;
}
+void InspectorCanvas::appendActionSnapshotIfNeeded()
+{
+ if (!m_actionNeedingSnapshot)
+ return;
+
+ m_bufferUsed -= m_actionNeedingSnapshot->memoryCost();
+
+ ErrorString ignored;
+ m_actionNeedingSnapshot->addItem(indexForData(getCanvasContentAsDataURL(ignored)));
+
+ m_bufferUsed += m_actionNeedingSnapshot->memoryCost();
+
+ m_actionNeedingSnapshot = nullptr;
+}
+
int InspectorCanvas::indexForData(DuplicateDataVariant data)
{
size_t index = m_indexedDuplicateData.findMatching([&] (auto item) {
@@ -561,7 +603,8 @@
if (parametersPayload->length())
initialStatePayload->setParameters(WTFMove(parametersPayload));
- initialStatePayload->setContent(getCanvasContentAsDataURL());
+ ErrorString ignored;
+ initialStatePayload->setContent(getCanvasContentAsDataURL(ignored));
return initialStatePayload;
}
Modified: trunk/Source/WebCore/inspector/InspectorCanvas.h (243355 => 243356)
--- trunk/Source/WebCore/inspector/InspectorCanvas.h 2019-03-22 02:33:38 UTC (rev 243355)
+++ trunk/Source/WebCore/inspector/InspectorCanvas.h 2019-03-22 02:47:35 UTC (rev 243356)
@@ -44,6 +44,8 @@
class ImageBitmap;
class ImageData;
+typedef String ErrorString;
+
class InspectorCanvas final : public RefCounted<InspectorCanvas> {
public:
static Ref<InspectorCanvas> create(CanvasRenderingContext&);
@@ -58,14 +60,11 @@
bool currentFrameHasData() const;
void recordAction(const String&, Vector<RecordCanvasActionVariant>&& = { });
- RefPtr<Inspector::Protocol::Recording::InitialState>&& releaseInitialState();
- RefPtr<JSON::ArrayOf<Inspector::Protocol::Recording::Frame>>&& releaseFrames();
- RefPtr<JSON::ArrayOf<JSON::Value>>&& releaseData();
+ Ref<JSON::ArrayOf<Inspector::Protocol::Recording::Frame>> releaseFrames() { return m_frames.releaseNonNull(); }
void finalizeFrame();
void markCurrentFrameIncomplete();
- const String& recordingName() const { return m_recordingName; }
void setRecordingName(const String& name) { m_recordingName = name; }
void setBufferLimit(long);
@@ -76,11 +75,13 @@
bool overFrameCount() const;
Ref<Inspector::Protocol::Canvas::Canvas> buildObjectForCanvas(bool captureBacktrace);
+ Ref<Inspector::Protocol::Recording::Recording> releaseObjectForRecording();
+ String getCanvasContentAsDataURL(ErrorString&);
+
private:
InspectorCanvas(CanvasRenderingContext&);
void appendActionSnapshotIfNeeded();
- String getCanvasContentAsDataURL();
using DuplicateDataVariant = Variant<
RefPtr<CanvasGradient>,
Modified: trunk/Source/WebCore/inspector/agents/InspectorCanvasAgent.cpp (243355 => 243356)
--- trunk/Source/WebCore/inspector/agents/InspectorCanvasAgent.cpp 2019-03-22 02:33:38 UTC (rev 243355)
+++ trunk/Source/WebCore/inspector/agents/InspectorCanvasAgent.cpp 2019-03-22 02:47:35 UTC (rev 243356)
@@ -26,6 +26,7 @@
#include "config.h"
#include "InspectorCanvasAgent.h"
+#include "ActiveDOMCallbackMicrotask.h"
#include "CanvasRenderingContext.h"
#include "CanvasRenderingContext2D.h"
#include "Document.h"
@@ -37,6 +38,7 @@
#include "JSCanvasRenderingContext2D.h"
#include "JSExecState.h"
#include "JSImageBitmapRenderingContext.h"
+#include "Microtasks.h"
#include "OffscreenCanvas.h"
#include "ScriptState.h"
#include "StringAdaptors.h"
@@ -78,7 +80,6 @@
, m_injectedScriptManager(context.injectedScriptManager)
, m_inspectedPage(context.inspectedPage)
, m_canvasDestroyedTimer(*this, &InspectorCanvasAgent::canvasDestroyedTimerFired)
- , m_canvasRecordingTimer(*this, &InspectorCanvasAgent::canvasRecordingTimerFired)
{
}
@@ -147,7 +148,7 @@
void InspectorCanvasAgent::requestNode(ErrorString& errorString, const String& canvasId, int* nodeId)
{
- auto* inspectorCanvas = assertInspectorCanvas(errorString, canvasId);
+ auto inspectorCanvas = assertInspectorCanvas(errorString, canvasId);
if (!inspectorCanvas)
return;
@@ -168,48 +169,16 @@
void InspectorCanvasAgent::requestContent(ErrorString& errorString, const String& canvasId, String* content)
{
- auto* inspectorCanvas = assertInspectorCanvas(errorString, canvasId);
+ auto inspectorCanvas = assertInspectorCanvas(errorString, canvasId);
if (!inspectorCanvas)
return;
- // FIXME: <https://webkit.org/b/180833> Web Inspector: support OffscreenCanvas for Canvas related operations
-
- if (auto* node = inspectorCanvas->canvasElement()) {
- if (is<CanvasRenderingContext2D>(inspectorCanvas->context()) || is<ImageBitmapRenderingContext>(inspectorCanvas->context())) {
- auto result = node->toDataURL("image/png"_s);
- if (result.hasException()) {
- errorString = result.releaseException().releaseMessage();
- return;
- }
- *content = result.releaseReturnValue().string;
- return;
- }
-
-#if ENABLE(WEBGL)
- if (is<WebGLRenderingContextBase>(inspectorCanvas->context())) {
- WebGLRenderingContextBase& contextWebGLBase = downcast<WebGLRenderingContextBase>(inspectorCanvas->context());
-
- contextWebGLBase.setPreventBufferClearForInspector(true);
- auto result = node->toDataURL("image/png"_s);
- contextWebGLBase.setPreventBufferClearForInspector(false);
-
- if (result.hasException()) {
- errorString = result.releaseException().releaseMessage();
- return;
- }
- *content = result.releaseReturnValue().string;
- return;
- }
-#endif
- }
-
- // FIXME: <https://webkit.org/b/173621> Web Inspector: Support getting the content of WebMetal context;
- errorString = "Unsupported canvas context type"_s;
+ *content = inspectorCanvas->getCanvasContentAsDataURL(errorString);
}
void InspectorCanvasAgent::requestCSSCanvasClientNodes(ErrorString& errorString, const String& canvasId, RefPtr<JSON::ArrayOf<int>>& result)
{
- auto* inspectorCanvas = assertInspectorCanvas(errorString, canvasId);
+ auto inspectorCanvas = assertInspectorCanvas(errorString, canvasId);
if (!inspectorCanvas)
return;
@@ -250,7 +219,7 @@
void InspectorCanvasAgent::resolveCanvasContext(ErrorString& errorString, const String& canvasId, const String* objectGroup, RefPtr<Inspector::Protocol::Runtime::RemoteObject>& result)
{
- auto* inspectorCanvas = assertInspectorCanvas(errorString, canvasId);
+ auto inspectorCanvas = assertInspectorCanvas(errorString, canvasId);
if (!inspectorCanvas)
return;
@@ -279,7 +248,7 @@
void InspectorCanvasAgent::startRecording(ErrorString& errorString, const String& canvasId, const int* frameCount, const int* memoryLimit)
{
- auto* inspectorCanvas = assertInspectorCanvas(errorString, canvasId);
+ auto inspectorCanvas = assertInspectorCanvas(errorString, canvasId);
if (!inspectorCanvas)
return;
@@ -298,7 +267,7 @@
void InspectorCanvasAgent::stopRecording(ErrorString& errorString, const String& canvasId)
{
- auto* inspectorCanvas = assertInspectorCanvas(errorString, canvasId);
+ auto inspectorCanvas = assertInspectorCanvas(errorString, canvasId);
if (!inspectorCanvas)
return;
@@ -313,7 +282,7 @@
void InspectorCanvasAgent::requestShaderSource(ErrorString& errorString, const String& programId, const String& shaderType, String* content)
{
#if ENABLE(WEBGL)
- auto* inspectorProgram = assertInspectorProgram(errorString, programId);
+ auto inspectorProgram = assertInspectorProgram(errorString, programId);
if (!inspectorProgram)
return;
@@ -335,7 +304,7 @@
void InspectorCanvasAgent::updateShader(ErrorString& errorString, const String& programId, const String& shaderType, const String& source)
{
#if ENABLE(WEBGL)
- auto* inspectorProgram = assertInspectorProgram(errorString, programId);
+ auto inspectorProgram = assertInspectorProgram(errorString, programId);
if (!inspectorProgram)
return;
@@ -366,7 +335,7 @@
void InspectorCanvasAgent::setShaderProgramDisabled(ErrorString& errorString, const String& programId, bool disabled)
{
#if ENABLE(WEBGL)
- auto* inspectorProgram = assertInspectorProgram(errorString, programId);
+ auto inspectorProgram = assertInspectorProgram(errorString, programId);
if (!inspectorProgram)
return;
@@ -381,7 +350,7 @@
void InspectorCanvasAgent::setShaderProgramHighlighted(ErrorString& errorString, const String& programId, bool highlighted)
{
#if ENABLE(WEBGL)
- auto* inspectorProgram = assertInspectorProgram(errorString, programId);
+ auto inspectorProgram = assertInspectorProgram(errorString, programId);
if (!inspectorProgram)
return;
@@ -424,7 +393,7 @@
return;
}
- auto* inspectorCanvas = findInspectorCanvas(*context);
+ auto inspectorCanvas = findInspectorCanvas(*context);
ASSERT(inspectorCanvas);
if (!inspectorCanvas)
return;
@@ -450,7 +419,7 @@
void InspectorCanvasAgent::didChangeCanvasMemory(CanvasRenderingContext& context)
{
- auto* inspectorCanvas = findInspectorCanvas(context);
+ auto inspectorCanvas = findInspectorCanvas(context);
ASSERT(inspectorCanvas);
if (!inspectorCanvas)
return;
@@ -463,7 +432,7 @@
void InspectorCanvasAgent::recordCanvasAction(CanvasRenderingContext& canvasRenderingContext, const String& name, Vector<RecordCanvasActionVariant>&& parameters)
{
- auto* inspectorCanvas = findInspectorCanvas(canvasRenderingContext);
+ auto inspectorCanvas = findInspectorCanvas(canvasRenderingContext);
ASSERT(inspectorCanvas);
if (!inspectorCanvas)
return;
@@ -472,11 +441,25 @@
if (!canvasRenderingContext.callTracingActive())
return;
+ // Only enqueue a microtask for the first action of each frame. Any subsequent actions will be
+ // covered by the initial microtask until the next frame.
+ if (!inspectorCanvas->currentFrameHasData()) {
+ if (auto* scriptExecutionContext = inspectorCanvas->context().canvasBase().scriptExecutionContext()) {
+ auto& queue = MicrotaskQueue::mainThreadQueue();
+ queue.append(std::make_unique<ActiveDOMCallbackMicrotask>(queue, *scriptExecutionContext, [&, protectedInspectorCanvas = inspectorCanvas.copyRef()] {
+ if (auto* canvasElement = protectedInspectorCanvas->canvasElement()) {
+ if (canvasElement->isDescendantOf(canvasElement->document()))
+ return;
+ }
+
+ if (protectedInspectorCanvas->context().callTracingActive())
+ didFinishRecordingCanvasFrame(protectedInspectorCanvas->context());
+ }));
+ }
+ }
+
inspectorCanvas->recordAction(name, WTFMove(parameters));
- if (!m_canvasRecordingTimer.isActive())
- m_canvasRecordingTimer.startOneShot(0_s);
-
if (!inspectorCanvas->hasBufferSpace())
didFinishRecordingCanvasFrame(inspectorCanvas->context(), true);
}
@@ -487,7 +470,8 @@
if (!context)
return;
- auto* inspectorCanvas = findInspectorCanvas(*context);
+ auto inspectorCanvas = findInspectorCanvas(*context);
+ ASSERT(inspectorCanvas);
if (!inspectorCanvas)
return;
@@ -504,7 +488,7 @@
void InspectorCanvasAgent::didFinishRecordingCanvasFrame(CanvasRenderingContext& context, bool forceDispatch)
{
- auto* inspectorCanvas = findInspectorCanvas(context);
+ auto inspectorCanvas = findInspectorCanvas(context);
ASSERT(inspectorCanvas);
if (!inspectorCanvas)
return;
@@ -515,7 +499,6 @@
if (!inspectorCanvas->hasRecordingData()) {
if (forceDispatch) {
m_frontendDispatcher->recordingFinished(inspectorCanvas->identifier(), nullptr);
-
inspectorCanvas->resetRecordingData();
}
return;
@@ -531,41 +514,12 @@
if (!forceDispatch && !inspectorCanvas->overFrameCount())
return;
- // FIXME: <https://webkit.org/b/176008> Web Inspector: Record actions performed on WebGL2RenderingContext
-
- Inspector::Protocol::Recording::Type type;
- if (is<CanvasRenderingContext2D>(inspectorCanvas->context()))
- type = Inspector::Protocol::Recording::Type::Canvas2D;
- else if (is<ImageBitmapRenderingContext>(inspectorCanvas->context()))
- type = Inspector::Protocol::Recording::Type::CanvasBitmapRenderer;
-#if ENABLE(WEBGL)
- else if (is<WebGLRenderingContext>(inspectorCanvas->context()))
- type = Inspector::Protocol::Recording::Type::CanvasWebGL;
-#endif
- else {
- ASSERT_NOT_REACHED();
- type = Inspector::Protocol::Recording::Type::Canvas2D;
- }
-
- auto recording = Inspector::Protocol::Recording::Recording::create()
- .setVersion(Inspector::Protocol::Recording::VERSION)
- .setType(type)
- .setInitialState(inspectorCanvas->releaseInitialState())
- .setData(inspectorCanvas->releaseData())
- .release();
-
- const String& name = inspectorCanvas->recordingName();
- if (!name.isEmpty())
- recording->setName(name);
-
- m_frontendDispatcher->recordingFinished(inspectorCanvas->identifier(), WTFMove(recording));
-
- inspectorCanvas->resetRecordingData();
+ m_frontendDispatcher->recordingFinished(inspectorCanvas->identifier(), inspectorCanvas->releaseObjectForRecording());
}
void InspectorCanvasAgent::consoleStartRecordingCanvas(CanvasRenderingContext& context, JSC::ExecState& exec, JSC::JSObject* options)
{
- auto* inspectorCanvas = findInspectorCanvas(context);
+ auto inspectorCanvas = findInspectorCanvas(context);
ASSERT(inspectorCanvas);
if (!inspectorCanvas)
return;
@@ -587,7 +541,7 @@
#if ENABLE(WEBGL)
void InspectorCanvasAgent::didEnableExtension(WebGLRenderingContextBase& context, const String& extension)
{
- auto* inspectorCanvas = findInspectorCanvas(context);
+ auto inspectorCanvas = findInspectorCanvas(context);
ASSERT(inspectorCanvas);
if (!inspectorCanvas)
return;
@@ -597,7 +551,7 @@
void InspectorCanvasAgent::didCreateProgram(WebGLRenderingContextBase& context, WebGLProgram& program)
{
- auto* inspectorCanvas = findInspectorCanvas(context);
+ auto inspectorCanvas = findInspectorCanvas(context);
ASSERT(inspectorCanvas);
if (!inspectorCanvas)
return;
@@ -610,7 +564,7 @@
void InspectorCanvasAgent::willDeleteProgram(WebGLProgram& program)
{
- auto* inspectorProgram = findInspectorProgram(program);
+ auto inspectorProgram = findInspectorProgram(program);
if (!inspectorProgram)
return;
@@ -620,7 +574,8 @@
bool InspectorCanvasAgent::isShaderProgramDisabled(WebGLProgram& program)
{
- auto* inspectorProgram = findInspectorProgram(program);
+ auto inspectorProgram = findInspectorProgram(program);
+ ASSERT(inspectorProgram);
if (!inspectorProgram)
return false;
@@ -629,7 +584,8 @@
bool InspectorCanvasAgent::isShaderProgramHighlighted(WebGLProgram& program)
{
- auto* inspectorProgram = findInspectorProgram(program);
+ auto inspectorProgram = findInspectorProgram(program);
+ ASSERT(inspectorProgram);
if (!inspectorProgram)
return false;
@@ -674,16 +630,6 @@
m_removedCanvasIdentifiers.clear();
}
-void InspectorCanvasAgent::canvasRecordingTimerFired()
-{
- for (auto& inspectorCanvas : m_identifierToInspectorCanvas.values()) {
- if (!inspectorCanvas->context().callTracingActive())
- continue;
-
- didFinishRecordingCanvasFrame(inspectorCanvas->context());
- }
-}
-
void InspectorCanvasAgent::clearCanvasData()
{
for (auto& inspectorCanvas : m_identifierToInspectorCanvas.values())
@@ -690,14 +636,11 @@
inspectorCanvas->context().canvasBase().removeObserver(*this);
m_identifierToInspectorCanvas.clear();
- m_removedCanvasIdentifiers.clear();
#if ENABLE(WEBGL)
m_identifierToInspectorProgram.clear();
+ m_removedCanvasIdentifiers.clear();
#endif
- if (m_canvasRecordingTimer.isActive())
- m_canvasRecordingTimer.stop();
-
if (m_canvasDestroyedTimer.isActive())
m_canvasDestroyedTimer.stop();
}
@@ -745,22 +688,22 @@
return identifier;
}
-InspectorCanvas* InspectorCanvasAgent::assertInspectorCanvas(ErrorString& errorString, const String& identifier)
+RefPtr<InspectorCanvas> InspectorCanvasAgent::assertInspectorCanvas(ErrorString& errorString, const String& identifier)
{
- RefPtr<InspectorCanvas> inspectorCanvas = m_identifierToInspectorCanvas.get(identifier);
+ auto inspectorCanvas = m_identifierToInspectorCanvas.get(identifier);
if (!inspectorCanvas) {
errorString = "No canvas for given identifier."_s;
return nullptr;
}
- return inspectorCanvas.get();
+ return inspectorCanvas;
}
-InspectorCanvas* InspectorCanvasAgent::findInspectorCanvas(CanvasRenderingContext& context)
+RefPtr<InspectorCanvas> InspectorCanvasAgent::findInspectorCanvas(CanvasRenderingContext& context)
{
for (auto& inspectorCanvas : m_identifierToInspectorCanvas.values()) {
if (&inspectorCanvas->context() == &context)
- return inspectorCanvas.get();
+ return inspectorCanvas;
}
return nullptr;
@@ -775,22 +718,22 @@
return identifier;
}
-InspectorShaderProgram* InspectorCanvasAgent::assertInspectorProgram(ErrorString& errorString, const String& identifier)
+RefPtr<InspectorShaderProgram> InspectorCanvasAgent::assertInspectorProgram(ErrorString& errorString, const String& identifier)
{
- RefPtr<InspectorShaderProgram> inspectorProgram = m_identifierToInspectorProgram.get(identifier);
+ auto inspectorProgram = m_identifierToInspectorProgram.get(identifier);
if (!inspectorProgram) {
errorString = "No shader program for given identifier."_s;
return nullptr;
}
- return inspectorProgram.get();
+ return inspectorProgram;
}
-InspectorShaderProgram* InspectorCanvasAgent::findInspectorProgram(WebGLProgram& program)
+RefPtr<InspectorShaderProgram> InspectorCanvasAgent::findInspectorProgram(WebGLProgram& program)
{
for (auto& inspectorProgram : m_identifierToInspectorProgram.values()) {
if (&inspectorProgram->program() == &program)
- return inspectorProgram.get();
+ return inspectorProgram;
}
return nullptr;
Modified: trunk/Source/WebCore/inspector/agents/InspectorCanvasAgent.h (243355 => 243356)
--- trunk/Source/WebCore/inspector/agents/InspectorCanvasAgent.h 2019-03-22 02:33:38 UTC (rev 243355)
+++ trunk/Source/WebCore/inspector/agents/InspectorCanvasAgent.h 2019-03-22 02:47:35 UTC (rev 243356)
@@ -112,18 +112,15 @@
void startRecording(InspectorCanvas&, Inspector::Protocol::Recording::Initiator, RecordingOptions&& = { });
void canvasDestroyedTimerFired();
- void canvasRecordingTimerFired();
void clearCanvasData();
InspectorCanvas& bindCanvas(CanvasRenderingContext&, bool captureBacktrace);
String unbindCanvas(InspectorCanvas&);
- InspectorCanvas* assertInspectorCanvas(ErrorString&, const String& identifier);
- InspectorCanvas* findInspectorCanvas(CanvasRenderingContext&);
+ RefPtr<InspectorCanvas> assertInspectorCanvas(ErrorString&, const String& identifier);
+ RefPtr<InspectorCanvas> findInspectorCanvas(CanvasRenderingContext&);
#if ENABLE(WEBGL)
String unbindProgram(InspectorShaderProgram&);
- InspectorShaderProgram* assertInspectorProgram(ErrorString&, const String& identifier);
- InspectorShaderProgram* findInspectorProgram(WebGLProgram&);
-
- HashMap<String, RefPtr<InspectorShaderProgram>> m_identifierToInspectorProgram;
+ RefPtr<InspectorShaderProgram> assertInspectorProgram(ErrorString&, const String& identifier);
+ RefPtr<InspectorShaderProgram> findInspectorProgram(WebGLProgram&);
#endif
std::unique_ptr<Inspector::CanvasFrontendDispatcher> m_frontendDispatcher;
@@ -133,10 +130,14 @@
Page& m_inspectedPage;
HashMap<String, RefPtr<InspectorCanvas>> m_identifierToInspectorCanvas;
+#if ENABLE(WEBGL)
+ HashMap<String, RefPtr<InspectorShaderProgram>> m_identifierToInspectorProgram;
+#endif
Vector<String> m_removedCanvasIdentifiers;
+
Optional<size_t> m_recordingAutoCaptureFrameCount;
+
Timer m_canvasDestroyedTimer;
- Timer m_canvasRecordingTimer;
};
} // namespace WebCore
Modified: trunk/Source/WebCore/platform/graphics/GraphicsContext3D.h (243355 => 243356)
--- trunk/Source/WebCore/platform/graphics/GraphicsContext3D.h 2019-03-22 02:33:38 UTC (rev 243355)
+++ trunk/Source/WebCore/platform/graphics/GraphicsContext3D.h 2019-03-22 02:47:35 UTC (rev 243356)
@@ -120,6 +120,15 @@
class GraphicsContext3D : public RefCounted<GraphicsContext3D> {
public:
+ class Client {
+ public:
+ virtual ~Client() { }
+ virtual void didComposite() = 0;
+ virtual void forceContextLost() = 0;
+ virtual void recycleContext() = 0;
+ virtual void dispatchContextChangedNotification() = 0;
+ };
+
enum {
// WebGL 1 constants
DEPTH_BUFFER_BIT = 0x00000100,
@@ -764,8 +773,10 @@
#endif
bool makeContextCurrent();
- void setWebGLContext(WebGLRenderingContextBase* base) { m_webglContext = base; }
+ void addClient(Client& client) { m_clients.add(&client); }
+ void removeClient(Client& client) { m_clients.remove(&client); }
+
// With multisampling on, blit from multisampleFBO to regular FBO.
void prepareTexture();
@@ -1507,8 +1518,7 @@
std::unique_ptr<GraphicsContext3DPrivate> m_private;
#endif
- // FIXME: Layering violation.
- WebGLRenderingContextBase* m_webglContext { nullptr };
+ HashSet<Client*> m_clients;
bool m_isForWebGL2 { false };
bool m_usingCoreProfile { false };
Modified: trunk/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGLCommon.cpp (243355 => 243356)
--- trunk/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGLCommon.cpp 2019-03-22 02:33:38 UTC (rev 243355)
+++ trunk/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGLCommon.cpp 2019-03-22 02:47:35 UTC (rev 243356)
@@ -2016,6 +2016,9 @@
void GraphicsContext3D::markLayerComposited()
{
m_layerComposited = true;
+
+ for (auto* client : m_clients)
+ client->didComposite();
}
bool GraphicsContext3D::layerComposited() const
@@ -2025,26 +2028,20 @@
void GraphicsContext3D::forceContextLost()
{
-#if ENABLE(WEBGL)
- if (m_webglContext)
- m_webglContext->forceLostContext(WebGLRenderingContextBase::RealLostContext);
-#endif
+ for (auto* client : m_clients)
+ client->forceContextLost();
}
void GraphicsContext3D::recycleContext()
{
-#if ENABLE(WEBGL)
- if (m_webglContext)
- m_webglContext->recycleContext();
-#endif
+ for (auto* client : m_clients)
+ client->recycleContext();
}
void GraphicsContext3D::dispatchContextChangedNotification()
{
-#if ENABLE(WEBGL)
- if (m_webglContext)
- m_webglContext->dispatchContextChangedEvent();
-#endif
+ for (auto* client : m_clients)
+ client->dispatchContextChangedNotification();
}
void GraphicsContext3D::texImage2DDirect(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type, const void* pixels)