Diff
Modified: trunk/LayoutTests/ChangeLog (243382 => 243383)
--- trunk/LayoutTests/ChangeLog 2019-03-22 16:42:07 UTC (rev 243382)
+++ trunk/LayoutTests/ChangeLog 2019-03-22 16:54:54 UTC (rev 243383)
@@ -1,3 +1,17 @@
+2019-03-22 Ryan Haddad <ryanhad...@apple.com>
+
+ Unreviewed, rolling out r243356.
+
+ Causes assertion failures with WebGL layout tests on macOS and
+ iOS.
+
+ Reverted changeset:
+
+ "Web Inspector: Safari Canvas Inspector seems to show the
+ canvas being rendered twice per frame."
+ https://bugs.webkit.org/show_bug.cgi?id=196082
+ https://trac.webkit.org/changeset/243356
+
2019-03-22 Antti Koivisto <an...@apple.com>
Handle UI side hit testing for ScrollPositioningBehavior::Stationary positioned nodes
Modified: trunk/LayoutTests/inspector/canvas/recording-2d.html (243382 => 243383)
--- trunk/LayoutTests/inspector/canvas/recording-2d.html 2019-03-22 16:42:07 UTC (rev 243382)
+++ trunk/LayoutTests/inspector/canvas/recording-2d.html 2019-03-22 16:54:54 UTC (rev 243383)
@@ -39,6 +39,8 @@
pattern = ctx.createPattern(image, "no-repeat");
bitmap = await createImageBitmap(image);
+ document.body.appendChild(canvas);
+
ctx.save();
cancelActions();
@@ -51,7 +53,7 @@
} catch (e) { }
}
-let requestAnimationFrameId = NaN;
+let timeoutID = NaN;
let saveCount = 1;
function cancelActions() {
@@ -59,8 +61,8 @@
ctx.restore();
ctx.restore(); // Ensures the state is reset between test cases.
- cancelAnimationFrame(requestAnimationFrameId);
- requestAnimationFrameId = NaN;
+ clearTimeout(timeoutID);
+ timeoutID = NaN;
ctx.save(); // Ensures the state is reset between test cases.
ctx.save(); // This matches the `restore` call in `performActions`.
@@ -397,7 +399,7 @@
function executeFrameFunction() {
frames[index++]();
if (index < frames.length)
- requestAnimationFrameId = requestAnimationFrame(executeFrameFunction);
+ timeoutID = setTimeout(executeFrameFunction, 0);
};
executeFrameFunction();
}
Modified: trunk/LayoutTests/inspector/canvas/recording-bitmaprenderer.html (243382 => 243383)
--- trunk/LayoutTests/inspector/canvas/recording-bitmaprenderer.html 2019-03-22 16:42:07 UTC (rev 243382)
+++ trunk/LayoutTests/inspector/canvas/recording-bitmaprenderer.html 2019-03-22 16:54:54 UTC (rev 243383)
@@ -23,7 +23,7 @@
function load() {
ctx = canvas.getContext("bitmaprenderer");
- cancelActions();
+ document.body.appendChild(canvas);
runTest();
}
@@ -34,11 +34,11 @@
} catch (e) { }
}
-let requestAnimationFrameId = NaN;
+let timeoutID = NaN;
function cancelActions() {
- cancelAnimationFrame(requestAnimationFrameId);
- requestAnimationFrameId = NaN;
+ clearTimeout(timeoutID);
+ timeoutID = NaN;
createImageBitmap(transparentImage).then((transparentBitmap) => {
ctx.transferFromImageBitmap(transparentBitmap);
@@ -68,7 +68,7 @@
function executeFrameFunction() {
frames[index++]();
if (index < frames.length)
- requestAnimationFrameId = requestAnimationFrame(executeFrameFunction);
+ timeoutID = setTimeout(executeFrameFunction, 0);
};
executeFrameFunction();
}
Modified: trunk/LayoutTests/inspector/canvas/recording-html-2d.html (243382 => 243383)
--- trunk/LayoutTests/inspector/canvas/recording-html-2d.html 2019-03-22 16:42:07 UTC (rev 243382)
+++ trunk/LayoutTests/inspector/canvas/recording-html-2d.html 2019-03-22 16:54:54 UTC (rev 243383)
@@ -39,7 +39,7 @@
imageBitmap = await createImageBitmap(image);
- cancelActions();
+ document.body.appendChild(canvas);
context.strokeStyle = "red";
context.save();
@@ -56,15 +56,7 @@
} 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() {
@@ -105,7 +97,7 @@
function executeFrameFunction() {
frames[index++]();
if (index < frames.length)
- requestAnimationFrameId = requestAnimationFrame(executeFrameFunction);
+ timeoutID = setTimeout(executeFrameFunction, 0);
};
executeFrameFunction();
}
Modified: trunk/LayoutTests/inspector/canvas/recording-webgl.html (243382 => 243383)
--- trunk/LayoutTests/inspector/canvas/recording-webgl.html 2019-03-22 16:42:07 UTC (rev 243382)
+++ trunk/LayoutTests/inspector/canvas/recording-webgl.html 2019-03-22 16:54:54 UTC (rev 243383)
@@ -49,7 +49,7 @@
shader = context.createShader(context.VERTEX_SHADER);
texture = context.createTexture();
- cancelActions();
+ document.body.appendChild(context.canvas);
runTest();
}
@@ -60,11 +60,11 @@
} catch (e) { }
}
-let requestAnimationFrameId = NaN;
+let timeoutID = NaN;
function cancelActions() {
- cancelAnimationFrame(requestAnimationFrameId);
- requestAnimationFrameId = NaN;
+ clearTimeout(timeoutID);
+ timeoutID = 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)
- requestAnimationFrameId = requestAnimationFrame(executeFrameFunction);
+ timeoutID = setTimeout(executeFrameFunction, 0);
};
executeFrameFunction();
}
Modified: trunk/LayoutTests/inspector/canvas/setRecordingAutoCaptureFrameCount.html (243382 => 243383)
--- trunk/LayoutTests/inspector/canvas/setRecordingAutoCaptureFrameCount.html 2019-03-22 16:42:07 UTC (rev 243382)
+++ trunk/LayoutTests/inspector/canvas/setRecordingAutoCaptureFrameCount.html 2019-03-22 16:54:54 UTC (rev 243383)
@@ -6,11 +6,11 @@
if (window.internals)
window.internals.settings.setWebGLErrorsToConsoleEnabled(false);
-let requestAnimationFrameId = NaN;
+let timeoutID = NaN;
function cancelActions() {
- cancelAnimationFrame(requestAnimationFrameId);
- requestAnimationFrameId = NaN;
+ clearTimeout(timeoutID);
+ timeoutID = NaN;
}
function performActions(frames) {
@@ -19,7 +19,7 @@
frames[index++]();
if (index < frames.length)
- requestAnimationFrameId = requestAnimationFrame(executeFrameFunction);
+ timeoutID = setTimeout(executeFrameFunction, 0);
else {
setTimeout(() => {
TestPage.dispatchEventToFrontend("LastFrame");
Modified: trunk/Source/WebCore/ChangeLog (243382 => 243383)
--- trunk/Source/WebCore/ChangeLog 2019-03-22 16:42:07 UTC (rev 243382)
+++ trunk/Source/WebCore/ChangeLog 2019-03-22 16:54:54 UTC (rev 243383)
@@ -1,3 +1,17 @@
+2019-03-22 Ryan Haddad <ryanhad...@apple.com>
+
+ Unreviewed, rolling out r243356.
+
+ Causes assertion failures with WebGL layout tests on macOS and
+ iOS.
+
+ Reverted changeset:
+
+ "Web Inspector: Safari Canvas Inspector seems to show the
+ canvas being rendered twice per frame."
+ https://bugs.webkit.org/show_bug.cgi?id=196082
+ https://trac.webkit.org/changeset/243356
+
2019-03-22 Antti Koivisto <an...@apple.com>
Handle UI side hit testing for ScrollPositioningBehavior::Stationary positioned nodes
Modified: trunk/Source/WebCore/html/HTMLCanvasElement.cpp (243382 => 243383)
--- trunk/Source/WebCore/html/HTMLCanvasElement.cpp 2019-03-22 16:42:07 UTC (rev 243382)
+++ trunk/Source/WebCore/html/HTMLCanvasElement.cpp 2019-03-22 16:54:54 UTC (rev 243383)
@@ -668,40 +668,38 @@
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()) {
- bool shouldPaint = true;
+ if (context.paintingDisabled())
+ return;
+
+ if (m_context) {
+ if (!paintsIntoCanvasBuffer() && !document().printing())
+ return;
- if (m_context) {
- shouldPaint = paintsIntoCanvasBuffer() || document().printing();
- if (shouldPaint)
- m_context->paintRenderingResultsToCanvas();
- }
+ m_context->paintRenderingResultsToCanvas();
+ }
- if (shouldPaint) {
- if (hasCreatedImageBuffer()) {
- ImageBuffer* imageBuffer = buffer();
- if (imageBuffer) {
- if (m_presentedImage) {
- ImageOrientationDescription orientationDescription;
+ 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));
- }
- }
-
- if (isGPUBased())
- downcast<GPUBasedCanvasRenderingContext>(*m_context).markLayerComposited();
+ orientationDescription.setImageOrientationEnum(renderer()->style().imageOrientation());
+#endif
+ context.drawImage(*m_presentedImage, snappedIntRect(r), ImagePaintingOptions(orientationDescription));
+ } else
+ context.drawImageBuffer(*imageBuffer, snappedIntRect(r));
}
}
- if (UNLIKELY(m_context && m_context->callTracingActive()))
- InspectorInstrumentation::didFinishRecordingCanvasFrame(*m_context);
+ if (isGPUBased())
+ downcast<GPUBasedCanvasRenderingContext>(*m_context).markLayerComposited();
}
bool HTMLCanvasElement::isGPUBased() const
Modified: trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp (243382 => 243383)
--- trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp 2019-03-22 16:42:07 UTC (rev 243382)
+++ trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp 2019-03-22 16:54:54 UTC (rev 243383)
@@ -661,7 +661,7 @@
m_contextGroup = WebGLContextGroup::create();
m_contextGroup->addContext(*this);
- m_context->addClient(*this);
+ m_context->setWebGLContext(this);
m_context->getIntegerv(GraphicsContext3D::MAX_VIEWPORT_DIMS, m_maxViewportDims);
@@ -914,7 +914,6 @@
removeActivityStateChangeObserver();
if (m_context) {
- m_context->removeClient(*this);
m_context->setContextLostCallback(nullptr);
m_context->setErrorMessageCallback(nullptr);
m_context = nullptr;
@@ -5043,6 +5042,15 @@
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())
@@ -6217,6 +6225,15 @@
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)
@@ -6496,36 +6513,6 @@
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 (243382 => 243383)
--- trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.h 2019-03-22 16:42:07 UTC (rev 243382)
+++ trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.h 2019-03-22 16:54:54 UTC (rev 243383)
@@ -94,7 +94,7 @@
using WebGLCanvas = WTF::Variant<RefPtr<HTMLCanvasElement>, RefPtr<OffscreenCanvas>>;
-class WebGLRenderingContextBase : public GraphicsContext3D::Client, public GPUBasedCanvasRenderingContext, private ActivityStateChangeObserver {
+class WebGLRenderingContextBase : public GPUBasedCanvasRenderingContext, private ActivityStateChangeObserver {
public:
static std::unique_ptr<WebGLRenderingContextBase> create(CanvasBase&, WebGLContextAttributes&, const String&);
virtual ~WebGLRenderingContextBase();
@@ -330,8 +330,10 @@
SyntheticLostContext
};
void forceLostContext(LostContextMode);
+ void recycleContext();
void forceRestoreContext();
void loseContextImpl(LostContextMode);
+ void dispatchContextChangedEvent();
WEBCORE_EXPORT void simulateContextChanged();
GraphicsContext3D* graphicsContext3D() const { return m_context.get(); }
@@ -357,12 +359,6 @@
// 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 (243382 => 243383)
--- trunk/Source/WebCore/inspector/InspectorCanvas.cpp 2019-03-22 16:42:07 UTC (rev 243382)
+++ trunk/Source/WebCore/inspector/InspectorCanvas.cpp 2019-03-22 16:54:54 UTC (rev 243383)
@@ -89,8 +89,9 @@
HTMLCanvasElement* InspectorCanvas::canvasElement()
{
- if (is<HTMLCanvasElement>(m_context.canvasBase()))
- return &downcast<HTMLCanvasElement>(m_context.canvasBase());
+ auto* canvasBase = &m_context.canvasBase();
+ if (is<HTMLCanvasElement>(canvasBase))
+ return downcast<HTMLCanvasElement>(canvasBase);
return nullptr;
}
@@ -136,9 +137,6 @@
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();
}
@@ -173,10 +171,26 @@
#endif
}
-void InspectorCanvas::finalizeFrame()
+RefPtr<Inspector::Protocol::Recording::InitialState>&& InspectorCanvas::releaseInitialState()
{
+ 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());
@@ -297,61 +311,22 @@
return canvas;
}
-Ref<Inspector::Protocol::Recording::Recording> InspectorCanvas::releaseObjectForRecording()
+void InspectorCanvas::appendActionSnapshotIfNeeded()
{
- ASSERT(!m_currentActions);
- ASSERT(!m_actionNeedingSnapshot);
- ASSERT(!m_frames);
+ if (!m_actionNeedingSnapshot)
+ return;
- // 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;
+ m_actionNeedingSnapshot->addItem(indexForData(getCanvasContentAsDataURL()));
+ m_actionNeedingSnapshot = nullptr;
}
-String InspectorCanvas::getCanvasContentAsDataURL(ErrorString& errorString)
+String InspectorCanvas::getCanvasContentAsDataURL()
{
- // 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
- // FIXME: <https://webkit.org/b/180833> Web Inspector: support OffscreenCanvas for Canvas related operations
auto* node = canvasElement();
- if (!node) {
- errorString = "Context isn't related to an HTMLCanvasElement"_s;
- return emptyString();
- }
+ if (!node)
+ return String();
#if ENABLE(WEBGL)
if (is<WebGLRenderingContextBase>(m_context))
@@ -365,29 +340,12 @@
downcast<WebGLRenderingContextBase>(m_context).setPreventBufferClearForInspector(false);
#endif
- if (result.hasException()) {
- errorString = result.releaseException().releaseMessage();
- return emptyString();
- }
+ if (result.hasException())
+ return String();
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) {
@@ -603,8 +561,7 @@
if (parametersPayload->length())
initialStatePayload->setParameters(WTFMove(parametersPayload));
- ErrorString ignored;
- initialStatePayload->setContent(getCanvasContentAsDataURL(ignored));
+ initialStatePayload->setContent(getCanvasContentAsDataURL());
return initialStatePayload;
}
Modified: trunk/Source/WebCore/inspector/InspectorCanvas.h (243382 => 243383)
--- trunk/Source/WebCore/inspector/InspectorCanvas.h 2019-03-22 16:42:07 UTC (rev 243382)
+++ trunk/Source/WebCore/inspector/InspectorCanvas.h 2019-03-22 16:54:54 UTC (rev 243383)
@@ -44,8 +44,6 @@
class ImageBitmap;
class ImageData;
-typedef String ErrorString;
-
class InspectorCanvas final : public RefCounted<InspectorCanvas> {
public:
static Ref<InspectorCanvas> create(CanvasRenderingContext&);
@@ -60,11 +58,14 @@
bool currentFrameHasData() const;
void recordAction(const String&, Vector<RecordCanvasActionVariant>&& = { });
- Ref<JSON::ArrayOf<Inspector::Protocol::Recording::Frame>> releaseFrames() { return m_frames.releaseNonNull(); }
+ RefPtr<Inspector::Protocol::Recording::InitialState>&& releaseInitialState();
+ RefPtr<JSON::ArrayOf<Inspector::Protocol::Recording::Frame>>&& releaseFrames();
+ RefPtr<JSON::ArrayOf<JSON::Value>>&& releaseData();
void finalizeFrame();
void markCurrentFrameIncomplete();
+ const String& recordingName() const { return m_recordingName; }
void setRecordingName(const String& name) { m_recordingName = name; }
void setBufferLimit(long);
@@ -75,13 +76,11 @@
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 (243382 => 243383)
--- trunk/Source/WebCore/inspector/agents/InspectorCanvasAgent.cpp 2019-03-22 16:42:07 UTC (rev 243382)
+++ trunk/Source/WebCore/inspector/agents/InspectorCanvasAgent.cpp 2019-03-22 16:54:54 UTC (rev 243383)
@@ -26,7 +26,6 @@
#include "config.h"
#include "InspectorCanvasAgent.h"
-#include "ActiveDOMCallbackMicrotask.h"
#include "CanvasRenderingContext.h"
#include "CanvasRenderingContext2D.h"
#include "Document.h"
@@ -38,7 +37,6 @@
#include "JSCanvasRenderingContext2D.h"
#include "JSExecState.h"
#include "JSImageBitmapRenderingContext.h"
-#include "Microtasks.h"
#include "OffscreenCanvas.h"
#include "ScriptState.h"
#include "StringAdaptors.h"
@@ -80,6 +78,7 @@
, m_injectedScriptManager(context.injectedScriptManager)
, m_inspectedPage(context.inspectedPage)
, m_canvasDestroyedTimer(*this, &InspectorCanvasAgent::canvasDestroyedTimerFired)
+ , m_canvasRecordingTimer(*this, &InspectorCanvasAgent::canvasRecordingTimerFired)
{
}
@@ -148,7 +147,7 @@
void InspectorCanvasAgent::requestNode(ErrorString& errorString, const String& canvasId, int* nodeId)
{
- auto inspectorCanvas = assertInspectorCanvas(errorString, canvasId);
+ auto* inspectorCanvas = assertInspectorCanvas(errorString, canvasId);
if (!inspectorCanvas)
return;
@@ -169,16 +168,48 @@
void InspectorCanvasAgent::requestContent(ErrorString& errorString, const String& canvasId, String* content)
{
- auto inspectorCanvas = assertInspectorCanvas(errorString, canvasId);
+ auto* inspectorCanvas = assertInspectorCanvas(errorString, canvasId);
if (!inspectorCanvas)
return;
- *content = inspectorCanvas->getCanvasContentAsDataURL(errorString);
+ // 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;
}
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;
@@ -219,7 +250,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;
@@ -248,7 +279,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;
@@ -267,7 +298,7 @@
void InspectorCanvasAgent::stopRecording(ErrorString& errorString, const String& canvasId)
{
- auto inspectorCanvas = assertInspectorCanvas(errorString, canvasId);
+ auto* inspectorCanvas = assertInspectorCanvas(errorString, canvasId);
if (!inspectorCanvas)
return;
@@ -282,7 +313,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;
@@ -304,7 +335,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;
@@ -335,7 +366,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;
@@ -350,7 +381,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;
@@ -393,7 +424,7 @@
return;
}
- auto inspectorCanvas = findInspectorCanvas(*context);
+ auto* inspectorCanvas = findInspectorCanvas(*context);
ASSERT(inspectorCanvas);
if (!inspectorCanvas)
return;
@@ -419,7 +450,7 @@
void InspectorCanvasAgent::didChangeCanvasMemory(CanvasRenderingContext& context)
{
- auto inspectorCanvas = findInspectorCanvas(context);
+ auto* inspectorCanvas = findInspectorCanvas(context);
ASSERT(inspectorCanvas);
if (!inspectorCanvas)
return;
@@ -432,7 +463,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;
@@ -441,25 +472,11 @@
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;
- }
+ inspectorCanvas->recordAction(name, WTFMove(parameters));
- if (protectedInspectorCanvas->context().callTracingActive())
- didFinishRecordingCanvasFrame(protectedInspectorCanvas->context());
- }));
- }
- }
+ if (!m_canvasRecordingTimer.isActive())
+ m_canvasRecordingTimer.startOneShot(0_s);
- inspectorCanvas->recordAction(name, WTFMove(parameters));
-
if (!inspectorCanvas->hasBufferSpace())
didFinishRecordingCanvasFrame(inspectorCanvas->context(), true);
}
@@ -470,8 +487,7 @@
if (!context)
return;
- auto inspectorCanvas = findInspectorCanvas(*context);
- ASSERT(inspectorCanvas);
+ auto* inspectorCanvas = findInspectorCanvas(*context);
if (!inspectorCanvas)
return;
@@ -488,7 +504,7 @@
void InspectorCanvasAgent::didFinishRecordingCanvasFrame(CanvasRenderingContext& context, bool forceDispatch)
{
- auto inspectorCanvas = findInspectorCanvas(context);
+ auto* inspectorCanvas = findInspectorCanvas(context);
ASSERT(inspectorCanvas);
if (!inspectorCanvas)
return;
@@ -499,6 +515,7 @@
if (!inspectorCanvas->hasRecordingData()) {
if (forceDispatch) {
m_frontendDispatcher->recordingFinished(inspectorCanvas->identifier(), nullptr);
+
inspectorCanvas->resetRecordingData();
}
return;
@@ -514,12 +531,41 @@
if (!forceDispatch && !inspectorCanvas->overFrameCount())
return;
- m_frontendDispatcher->recordingFinished(inspectorCanvas->identifier(), inspectorCanvas->releaseObjectForRecording());
+ // 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();
}
void InspectorCanvasAgent::consoleStartRecordingCanvas(CanvasRenderingContext& context, JSC::ExecState& exec, JSC::JSObject* options)
{
- auto inspectorCanvas = findInspectorCanvas(context);
+ auto* inspectorCanvas = findInspectorCanvas(context);
ASSERT(inspectorCanvas);
if (!inspectorCanvas)
return;
@@ -541,7 +587,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;
@@ -551,7 +597,7 @@
void InspectorCanvasAgent::didCreateProgram(WebGLRenderingContextBase& context, WebGLProgram& program)
{
- auto inspectorCanvas = findInspectorCanvas(context);
+ auto* inspectorCanvas = findInspectorCanvas(context);
ASSERT(inspectorCanvas);
if (!inspectorCanvas)
return;
@@ -564,7 +610,7 @@
void InspectorCanvasAgent::willDeleteProgram(WebGLProgram& program)
{
- auto inspectorProgram = findInspectorProgram(program);
+ auto* inspectorProgram = findInspectorProgram(program);
if (!inspectorProgram)
return;
@@ -574,8 +620,7 @@
bool InspectorCanvasAgent::isShaderProgramDisabled(WebGLProgram& program)
{
- auto inspectorProgram = findInspectorProgram(program);
- ASSERT(inspectorProgram);
+ auto* inspectorProgram = findInspectorProgram(program);
if (!inspectorProgram)
return false;
@@ -584,8 +629,7 @@
bool InspectorCanvasAgent::isShaderProgramHighlighted(WebGLProgram& program)
{
- auto inspectorProgram = findInspectorProgram(program);
- ASSERT(inspectorProgram);
+ auto* inspectorProgram = findInspectorProgram(program);
if (!inspectorProgram)
return false;
@@ -630,6 +674,16 @@
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())
@@ -636,11 +690,14 @@
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();
}
@@ -688,22 +745,22 @@
return identifier;
}
-RefPtr<InspectorCanvas> InspectorCanvasAgent::assertInspectorCanvas(ErrorString& errorString, const String& identifier)
+InspectorCanvas* InspectorCanvasAgent::assertInspectorCanvas(ErrorString& errorString, const String& identifier)
{
- auto inspectorCanvas = m_identifierToInspectorCanvas.get(identifier);
+ RefPtr<InspectorCanvas> inspectorCanvas = m_identifierToInspectorCanvas.get(identifier);
if (!inspectorCanvas) {
errorString = "No canvas for given identifier."_s;
return nullptr;
}
- return inspectorCanvas;
+ return inspectorCanvas.get();
}
-RefPtr<InspectorCanvas> InspectorCanvasAgent::findInspectorCanvas(CanvasRenderingContext& context)
+InspectorCanvas* InspectorCanvasAgent::findInspectorCanvas(CanvasRenderingContext& context)
{
for (auto& inspectorCanvas : m_identifierToInspectorCanvas.values()) {
if (&inspectorCanvas->context() == &context)
- return inspectorCanvas;
+ return inspectorCanvas.get();
}
return nullptr;
@@ -718,22 +775,22 @@
return identifier;
}
-RefPtr<InspectorShaderProgram> InspectorCanvasAgent::assertInspectorProgram(ErrorString& errorString, const String& identifier)
+InspectorShaderProgram* InspectorCanvasAgent::assertInspectorProgram(ErrorString& errorString, const String& identifier)
{
- auto inspectorProgram = m_identifierToInspectorProgram.get(identifier);
+ RefPtr<InspectorShaderProgram> inspectorProgram = m_identifierToInspectorProgram.get(identifier);
if (!inspectorProgram) {
errorString = "No shader program for given identifier."_s;
return nullptr;
}
- return inspectorProgram;
+ return inspectorProgram.get();
}
-RefPtr<InspectorShaderProgram> InspectorCanvasAgent::findInspectorProgram(WebGLProgram& program)
+InspectorShaderProgram* InspectorCanvasAgent::findInspectorProgram(WebGLProgram& program)
{
for (auto& inspectorProgram : m_identifierToInspectorProgram.values()) {
if (&inspectorProgram->program() == &program)
- return inspectorProgram;
+ return inspectorProgram.get();
}
return nullptr;
Modified: trunk/Source/WebCore/inspector/agents/InspectorCanvasAgent.h (243382 => 243383)
--- trunk/Source/WebCore/inspector/agents/InspectorCanvasAgent.h 2019-03-22 16:42:07 UTC (rev 243382)
+++ trunk/Source/WebCore/inspector/agents/InspectorCanvasAgent.h 2019-03-22 16:54:54 UTC (rev 243383)
@@ -112,15 +112,18 @@
void startRecording(InspectorCanvas&, Inspector::Protocol::Recording::Initiator, RecordingOptions&& = { });
void canvasDestroyedTimerFired();
+ void canvasRecordingTimerFired();
void clearCanvasData();
InspectorCanvas& bindCanvas(CanvasRenderingContext&, bool captureBacktrace);
String unbindCanvas(InspectorCanvas&);
- RefPtr<InspectorCanvas> assertInspectorCanvas(ErrorString&, const String& identifier);
- RefPtr<InspectorCanvas> findInspectorCanvas(CanvasRenderingContext&);
+ InspectorCanvas* assertInspectorCanvas(ErrorString&, const String& identifier);
+ InspectorCanvas* findInspectorCanvas(CanvasRenderingContext&);
#if ENABLE(WEBGL)
String unbindProgram(InspectorShaderProgram&);
- RefPtr<InspectorShaderProgram> assertInspectorProgram(ErrorString&, const String& identifier);
- RefPtr<InspectorShaderProgram> findInspectorProgram(WebGLProgram&);
+ InspectorShaderProgram* assertInspectorProgram(ErrorString&, const String& identifier);
+ InspectorShaderProgram* findInspectorProgram(WebGLProgram&);
+
+ HashMap<String, RefPtr<InspectorShaderProgram>> m_identifierToInspectorProgram;
#endif
std::unique_ptr<Inspector::CanvasFrontendDispatcher> m_frontendDispatcher;
@@ -130,14 +133,10 @@
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 (243382 => 243383)
--- trunk/Source/WebCore/platform/graphics/GraphicsContext3D.h 2019-03-22 16:42:07 UTC (rev 243382)
+++ trunk/Source/WebCore/platform/graphics/GraphicsContext3D.h 2019-03-22 16:54:54 UTC (rev 243383)
@@ -120,15 +120,6 @@
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,
@@ -773,10 +764,8 @@
#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();
@@ -1518,7 +1507,8 @@
std::unique_ptr<GraphicsContext3DPrivate> m_private;
#endif
- HashSet<Client*> m_clients;
+ // FIXME: Layering violation.
+ WebGLRenderingContextBase* m_webglContext { nullptr };
bool m_isForWebGL2 { false };
bool m_usingCoreProfile { false };
Modified: trunk/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGLCommon.cpp (243382 => 243383)
--- trunk/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGLCommon.cpp 2019-03-22 16:42:07 UTC (rev 243382)
+++ trunk/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGLCommon.cpp 2019-03-22 16:54:54 UTC (rev 243383)
@@ -2016,9 +2016,6 @@
void GraphicsContext3D::markLayerComposited()
{
m_layerComposited = true;
-
- for (auto* client : m_clients)
- client->didComposite();
}
bool GraphicsContext3D::layerComposited() const
@@ -2028,20 +2025,26 @@
void GraphicsContext3D::forceContextLost()
{
- for (auto* client : m_clients)
- client->forceContextLost();
+#if ENABLE(WEBGL)
+ if (m_webglContext)
+ m_webglContext->forceLostContext(WebGLRenderingContextBase::RealLostContext);
+#endif
}
void GraphicsContext3D::recycleContext()
{
- for (auto* client : m_clients)
- client->recycleContext();
+#if ENABLE(WEBGL)
+ if (m_webglContext)
+ m_webglContext->recycleContext();
+#endif
}
void GraphicsContext3D::dispatchContextChangedNotification()
{
- for (auto* client : m_clients)
- client->dispatchContextChangedNotification();
+#if ENABLE(WEBGL)
+ if (m_webglContext)
+ m_webglContext->dispatchContextChangedEvent();
+#endif
}
void GraphicsContext3D::texImage2DDirect(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type, const void* pixels)