Web Inspector: Record actions performed on WebGL2RenderingContext
authordrousso@apple.com <drousso@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 3 May 2019 16:36:17 +0000 (16:36 +0000)
committerdrousso@apple.com <drousso@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 3 May 2019 16:36:17 +0000 (16:36 +0000)
https://bugs.webkit.org/show_bug.cgi?id=176008
<rdar://problem/34213884>

Reviewed by Joseph Pecoraro.

Source/JavaScriptCore:

* inspector/protocol/Recording.json:
* inspector/scripts/codegen/generator.py:
Add `canvas-webgl2` as a `Type`.

Source/WebCore:

Tests: inspector/canvas/recording-webgl2.html
       inspector/canvas/recording-webgl2-snapshots.html

* html/canvas/WebGL2RenderingContext.idl:

* bindings/js/CallTracerTypes.h:
* inspector/RecordingSwizzleTypes.h:

* inspector/InspectorCanvas.h:
* inspector/InspectorCanvas.cpp:
(WebCore::InspectorCanvas::canvasChanged): Added.
(WebCore::InspectorCanvas::resetRecordingData):
(WebCore::shouldSnapshotWebGL2Action): Added.
(WebCore::InspectorCanvas::recordAction):
(WebCore::InspectorCanvas::releaseObjectForRecording):
(WebCore::InspectorCanvas::appendActionSnapshotIfNeeded):
(WebCore::InspectorCanvas::buildAction):
* inspector/agents/InspectorCanvasAgent.h:
* inspector/agents/InspectorCanvasAgent.cpp:
(WebCore::InspectorCanvasAgent::canvasChanged): Added.
(WebCore::InspectorCanvasAgent::startRecording):
Provide an actual implementation of `CanvasObserver::canvasChanged` since it can be used to
determine whether or not an action needs a snapshot.

* page/PageConsoleClient.cpp:
(WebCore::canvasRenderingContext):

Source/WebInspectorUI:

* UserInterface/Models/Recording.js:
(WI.Recording.fromPayload):
(WI.Recording.displayNameForSwizzleType):
(WI.Recording.prototype.async swizzle):
(WI.Recording.prototype.createContext):

* UserInterface/Models/RecordingAction.js:
(WI.RecordingAction.constantNameForParameter):
(WI.RecordingAction._prototypeForType):
(WI.RecordingAction.prototype.async swizzle):
Treat all actions with a snapshot as being a "visible" action.

* UserInterface/Views/CanvasTabContentView.css:
(.content-view.tab.canvas .navigation-bar > .item .canvas:matches(.webgl, .webgl2, .webgpu, .webmetal) .icon): Added.
(.content-view.tab.canvas .navigation-bar > .item .canvas.webgl): Deleted.
* UserInterface/Views/CanvasContentView.js:
(WI.CanvasContentView.prototype.initialLayout):
* UserInterface/Views/CanvasSidebarPanel.js:
(WI.CanvasSidebarPanel.prototype.shown):
(WI.CanvasSidebarPanel.prototype._canvasChanged):
(WI.CanvasSidebarPanel.prototype._updateRecordNavigationItem):

* UserInterface/Views/RecordingContentView.js:
(WI.RecordingContentView):
(WI.RecordingContentView.prototype.get navigationItems):
(WI.RecordingContentView.prototype.shown):
(WI.RecordingContentView.prototype.initialLayout):
* UserInterface/Views/RecordingActionTreeElement.js:
(WI.RecordingActionTreeElement._generateDOM.createParameterElement):

LayoutTests:

* inspector/canvas/recording-webgl2.html: Added.
* inspector/canvas/recording-webgl2-expected.txt: Added.
* inspector/canvas/recording-webgl2-snapshots.html: Added.
* inspector/canvas/recording-webgl2-snapshots-expected.txt: Added.

* TestExpectations:
* platform/gtk/TestExpectations:
* platform/mac/TestExpectations:
* platform/win/TestExpectations:
* platform/wincairo/TestExpectations:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@244908 268f45cc-cd09-0410-ab3c-d52691b4dbfc

30 files changed:
LayoutTests/ChangeLog
LayoutTests/TestExpectations
LayoutTests/inspector/canvas/recording-webgl2-expected.txt [new file with mode: 0644]
LayoutTests/inspector/canvas/recording-webgl2-snapshots-expected.txt [new file with mode: 0644]
LayoutTests/inspector/canvas/recording-webgl2-snapshots.html [new file with mode: 0644]
LayoutTests/inspector/canvas/recording-webgl2.html [new file with mode: 0644]
LayoutTests/platform/gtk/TestExpectations
LayoutTests/platform/mac/TestExpectations
LayoutTests/platform/win/TestExpectations
LayoutTests/platform/wincairo/TestExpectations
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/inspector/protocol/Recording.json
Source/JavaScriptCore/inspector/scripts/codegen/generator.py
Source/WebCore/ChangeLog
Source/WebCore/bindings/js/CallTracerTypes.h
Source/WebCore/html/canvas/WebGL2RenderingContext.idl
Source/WebCore/inspector/InspectorCanvas.cpp
Source/WebCore/inspector/InspectorCanvas.h
Source/WebCore/inspector/RecordingSwizzleTypes.h
Source/WebCore/inspector/agents/InspectorCanvasAgent.cpp
Source/WebCore/inspector/agents/InspectorCanvasAgent.h
Source/WebCore/page/PageConsoleClient.cpp
Source/WebInspectorUI/ChangeLog
Source/WebInspectorUI/UserInterface/Models/Recording.js
Source/WebInspectorUI/UserInterface/Models/RecordingAction.js
Source/WebInspectorUI/UserInterface/Views/CanvasContentView.js
Source/WebInspectorUI/UserInterface/Views/CanvasSidebarPanel.js
Source/WebInspectorUI/UserInterface/Views/CanvasTabContentView.css
Source/WebInspectorUI/UserInterface/Views/RecordingActionTreeElement.js
Source/WebInspectorUI/UserInterface/Views/RecordingContentView.js

index 242298f..b0b34d5 100644 (file)
@@ -1,3 +1,22 @@
+2019-05-03  Devin Rousso  <drousso@apple.com>
+
+        Web Inspector: Record actions performed on WebGL2RenderingContext
+        https://bugs.webkit.org/show_bug.cgi?id=176008
+        <rdar://problem/34213884>
+
+        Reviewed by Joseph Pecoraro.
+
+        * inspector/canvas/recording-webgl2.html: Added.
+        * inspector/canvas/recording-webgl2-expected.txt: Added.
+        * inspector/canvas/recording-webgl2-snapshots.html: Added.
+        * inspector/canvas/recording-webgl2-snapshots-expected.txt: Added.
+
+        * TestExpectations:
+        * platform/gtk/TestExpectations:
+        * platform/mac/TestExpectations:
+        * platform/win/TestExpectations:
+        * platform/wincairo/TestExpectations:
+
 2019-05-02  Ryosuke Niwa  <rniwa@webkit.org>
 
         Make focusing-element-with-tabindex-by-tap-or-click.html more robust on iOS
index 2c26f88..1014468 100644 (file)
@@ -534,6 +534,7 @@ webkit.org/b/142208 inspector/timeline/exception-in-injected-script-while-record
 [ Debug ] inspector/debugger/debugger-stack-overflow.html [ Skip ]
 [ Debug ] inspector/canvas/recording-2d.html [ Slow ]
 [ Debug ] inspector/canvas/recording-webgl.html [ Slow ]
+[ Debug ] inspector/canvas/recording-webgl2.html [ Slow ]
 
 # Debugger stepping tests can timeout if they run slowly due to a short timer scheduled in the frontend.
 webkit.org/b/161951 [ Debug ] inspector/debugger/paused-scopes.html [ Skip ]
diff --git a/LayoutTests/inspector/canvas/recording-webgl2-expected.txt b/LayoutTests/inspector/canvas/recording-webgl2-expected.txt
new file mode 100644 (file)
index 0000000..763c0d6
--- /dev/null
@@ -0,0 +1,1023 @@
+Test that CanvasManager is able to record actions made to WebGL2 canvas contexts.
+
+
+== Running test suite: Canvas.recordingWebGL2
+-- Running test case: Canvas.recordingWebGL2.singleFrame
+initialState:
+  attributes:
+    width: 2
+    height: 2
+  parameters:
+    0: {"alpha":true,"depth":true,"stencil":false,"antialias":false,"premultipliedAlpha":true,"preserveDrawingBuffer":false,"failIfMajorPerformanceCaveat":false}
+  content: <filtered>
+frames:
+  0: (duration)
+    0: activeTexture(1)
+      swizzleTypes: [Number]
+      trace:
+        0: activeTexture
+        1: (anonymous function)
+        2: executeFrameFunction
+        3: performActions
+        4: Global Code
+        5: evaluateWithScopeExtension
+        6: (anonymous function)
+        7: _wrapCall
+
+-- Running test case: Canvas.recordingWebGL2.multipleFrames
+initialState:
+  attributes:
+    width: 2
+    height: 2
+  parameters:
+    0: {"alpha":true,"depth":true,"stencil":false,"antialias":false,"premultipliedAlpha":true,"preserveDrawingBuffer":false,"failIfMajorPerformanceCaveat":false}
+  content: <filtered>
+frames:
+  0: (duration)
+    0: activeTexture(1)
+      swizzleTypes: [Number]
+      trace:
+        0: activeTexture
+        1: (anonymous function)
+        2: executeFrameFunction
+        3: performActions
+        4: Global Code
+        5: evaluateWithScopeExtension
+        6: (anonymous function)
+        7: _wrapCall
+  1: (duration)
+    0: attachShader(0, 0)
+      swizzleTypes: [WebGLProgram, WebGLShader]
+      trace:
+        0: attachShader
+        1: (anonymous function)
+        2: executeFrameFunction
+  2: (duration)
+    0: bindAttribLocation(0, 1, "test")
+      swizzleTypes: [WebGLProgram, Number, String]
+      trace:
+        0: bindAttribLocation
+        1: (anonymous function)
+        2: executeFrameFunction
+  3: (duration)
+    0: bindBuffer(1, 0)
+      swizzleTypes: [Number, WebGLBuffer]
+      trace:
+        0: bindBuffer
+        1: (anonymous function)
+        2: executeFrameFunction
+  4: (duration)
+    0: bindFramebuffer(1, 0)
+      swizzleTypes: [Number, WebGLFramebuffer]
+      trace:
+        0: bindFramebuffer
+        1: (anonymous function)
+        2: executeFrameFunction
+  5: (duration)
+    0: bindRenderbuffer(1, 0)
+      swizzleTypes: [Number, WebGLRenderbuffer]
+      trace:
+        0: bindRenderbuffer
+        1: (anonymous function)
+        2: executeFrameFunction
+  6: (duration)
+    0: bindTexture(1, 0)
+      swizzleTypes: [Number, WebGLTexture]
+      trace:
+        0: bindTexture
+        1: (anonymous function)
+        2: executeFrameFunction
+  7: (duration)
+    0: blendColor(1, 2, 3, 4)
+      swizzleTypes: [Number, Number, Number, Number]
+      trace:
+        0: blendColor
+        1: (anonymous function)
+        2: executeFrameFunction
+  8: (duration)
+    0: blendEquation(1)
+      swizzleTypes: [Number]
+      trace:
+        0: blendEquation
+        1: (anonymous function)
+        2: executeFrameFunction
+  9: (duration)
+    0: blendEquationSeparate(1, 2)
+      swizzleTypes: [Number, Number]
+      trace:
+        0: blendEquationSeparate
+        1: (anonymous function)
+        2: executeFrameFunction
+  10: (duration)
+    0: blendFunc(1, 2)
+      swizzleTypes: [Number, Number]
+      trace:
+        0: blendFunc
+        1: (anonymous function)
+        2: executeFrameFunction
+  11: (duration)
+    0: blendFuncSeparate(1, 2, 3, 4)
+      swizzleTypes: [Number, Number, Number, Number]
+      trace:
+        0: blendFuncSeparate
+        1: (anonymous function)
+        2: executeFrameFunction
+  12: (duration)
+    0: bufferData(1, 0, 2)
+      swizzleTypes: [Number, TypedArray, Number]
+      trace:
+        0: bufferData
+        1: (anonymous function)
+        2: executeFrameFunction
+    1: bufferData(3, 4, 5)
+      swizzleTypes: [Number, Number, Number]
+      trace:
+        0: bufferData
+        1: (anonymous function)
+        2: executeFrameFunction
+  13: (duration)
+    0: bufferSubData(1, 2, 0)
+      swizzleTypes: [Number, Number, TypedArray]
+      trace:
+        0: bufferSubData
+        1: (anonymous function)
+        2: executeFrameFunction
+  14: (duration)
+    0: checkFramebufferStatus(1)
+      swizzleTypes: [Number]
+      trace:
+        0: checkFramebufferStatus
+        1: (anonymous function)
+        2: executeFrameFunction
+  15: (duration)
+    0: clear(1)
+      swizzleTypes: [Number]
+      trace:
+        0: clear
+        1: (anonymous function)
+        2: executeFrameFunction
+      snapshot: <filtered>
+  16: (duration)
+    0: clearColor(1, 2, 3, 4)
+      swizzleTypes: [Number, Number, Number, Number]
+      trace:
+        0: clearColor
+        1: (anonymous function)
+        2: executeFrameFunction
+  17: (duration)
+    0: clearDepth(1)
+      swizzleTypes: [Number]
+      trace:
+        0: clearDepth
+        1: (anonymous function)
+        2: executeFrameFunction
+  18: (duration)
+    0: clearStencil(1)
+      swizzleTypes: [Number]
+      trace:
+        0: clearStencil
+        1: (anonymous function)
+        2: executeFrameFunction
+  19: (duration)
+    0: colorMask(true, false, true, false)
+      swizzleTypes: [Boolean, Boolean, Boolean, Boolean]
+      trace:
+        0: colorMask
+        1: (anonymous function)
+        2: executeFrameFunction
+  20: (duration)
+    0: compileShader(0)
+      swizzleTypes: [WebGLShader]
+      trace:
+        0: compileShader
+        1: (anonymous function)
+        2: executeFrameFunction
+  21: (duration)
+    0: compressedTexSubImage2D(1, 2, 3, 4, 5, 6, 7, 0)
+      swizzleTypes: [Number, Number, Number, Number, Number, Number, Number, TypedArray]
+      trace:
+        0: compressedTexSubImage2D
+        1: (anonymous function)
+        2: executeFrameFunction
+  22: (duration)
+    0: copyTexImage2D(1, 2, 3, 4, 5, 6, 7, 8)
+      swizzleTypes: [Number, Number, Number, Number, Number, Number, Number, Number]
+      trace:
+        0: copyTexImage2D
+        1: (anonymous function)
+        2: executeFrameFunction
+  23: (duration)
+    0: copyTexSubImage2D(1, 2, 3, 4, 5, 6, 7, 8)
+      swizzleTypes: [Number, Number, Number, Number, Number, Number, Number, Number]
+      trace:
+        0: copyTexSubImage2D
+        1: (anonymous function)
+        2: executeFrameFunction
+  24: (duration)
+    0: createBuffer()
+      trace:
+        0: createBuffer
+        1: (anonymous function)
+        2: executeFrameFunction
+  25: (duration)
+    0: createFramebuffer()
+      trace:
+        0: createFramebuffer
+        1: (anonymous function)
+        2: executeFrameFunction
+  26: (duration)
+    0: createProgram()
+      trace:
+        0: createProgram
+        1: (anonymous function)
+        2: executeFrameFunction
+  27: (duration)
+    0: createRenderbuffer()
+      trace:
+        0: createRenderbuffer
+        1: (anonymous function)
+        2: executeFrameFunction
+  28: (duration)
+    0: createShader(1)
+      swizzleTypes: [Number]
+      trace:
+        0: createShader
+        1: (anonymous function)
+        2: executeFrameFunction
+  29: (duration)
+    0: createTexture()
+      trace:
+        0: createTexture
+        1: (anonymous function)
+        2: executeFrameFunction
+  30: (duration)
+    0: cullFace(1)
+      swizzleTypes: [Number]
+      trace:
+        0: cullFace
+        1: (anonymous function)
+        2: executeFrameFunction
+  31: (duration)
+    0: deleteBuffer(0)
+      swizzleTypes: [WebGLBuffer]
+      trace:
+        0: deleteBuffer
+        1: (anonymous function)
+        2: executeFrameFunction
+  32: (duration)
+    0: deleteFramebuffer(0)
+      swizzleTypes: [WebGLFramebuffer]
+      trace:
+        0: deleteFramebuffer
+        1: (anonymous function)
+        2: executeFrameFunction
+  33: (duration)
+    0: deleteProgram(0)
+      swizzleTypes: [WebGLProgram]
+      trace:
+        0: deleteProgram
+        1: (anonymous function)
+        2: executeFrameFunction
+  34: (duration)
+    0: deleteRenderbuffer(0)
+      swizzleTypes: [WebGLRenderbuffer]
+      trace:
+        0: deleteRenderbuffer
+        1: (anonymous function)
+        2: executeFrameFunction
+  35: (duration)
+    0: deleteShader(0)
+      swizzleTypes: [WebGLShader]
+      trace:
+        0: deleteShader
+        1: (anonymous function)
+        2: executeFrameFunction
+  36: (duration)
+    0: deleteTexture(0)
+      swizzleTypes: [WebGLTexture]
+      trace:
+        0: deleteTexture
+        1: (anonymous function)
+        2: executeFrameFunction
+  37: (duration)
+    0: depthFunc(1)
+      swizzleTypes: [Number]
+      trace:
+        0: depthFunc
+        1: (anonymous function)
+        2: executeFrameFunction
+  38: (duration)
+    0: depthMask(true)
+      swizzleTypes: [Boolean]
+      trace:
+        0: depthMask
+        1: (anonymous function)
+        2: executeFrameFunction
+  39: (duration)
+    0: depthRange(1, 2)
+      swizzleTypes: [Number, Number]
+      trace:
+        0: depthRange
+        1: (anonymous function)
+        2: executeFrameFunction
+  40: (duration)
+    0: detachShader(0, 0)
+      swizzleTypes: [WebGLProgram, WebGLShader]
+      trace:
+        0: detachShader
+        1: (anonymous function)
+        2: executeFrameFunction
+  41: (duration)
+    0: disable(1)
+      swizzleTypes: [Number]
+      trace:
+        0: disable
+        1: (anonymous function)
+        2: executeFrameFunction
+  42: (duration)
+    0: disableVertexAttribArray(1)
+      swizzleTypes: [Number]
+      trace:
+        0: disableVertexAttribArray
+        1: (anonymous function)
+        2: executeFrameFunction
+  43: (duration)
+    0: drawArrays(1, 2, 3)
+      swizzleTypes: [Number, Number, Number]
+      trace:
+        0: drawArrays
+        1: (anonymous function)
+        2: executeFrameFunction
+      snapshot: <filtered>
+  44: (duration)
+    0: drawElements(1, 2, 3, 4)
+      swizzleTypes: [Number, Number, Number, Number]
+      trace:
+        0: drawElements
+        1: (anonymous function)
+        2: executeFrameFunction
+      snapshot: <filtered>
+  45: (duration)
+    0: enable(1)
+      swizzleTypes: [Number]
+      trace:
+        0: enable
+        1: (anonymous function)
+        2: executeFrameFunction
+  46: (duration)
+    0: enableVertexAttribArray(1)
+      swizzleTypes: [Number]
+      trace:
+        0: enableVertexAttribArray
+        1: (anonymous function)
+        2: executeFrameFunction
+  47: (duration)
+    0: finish()
+      trace:
+        0: finish
+        1: (anonymous function)
+        2: executeFrameFunction
+  48: (duration)
+    0: flush()
+      trace:
+        0: flush
+        1: (anonymous function)
+        2: executeFrameFunction
+  49: (duration)
+    0: framebufferRenderbuffer(1, 2, 3, 0)
+      swizzleTypes: [Number, Number, Number, WebGLRenderbuffer]
+      trace:
+        0: framebufferRenderbuffer
+        1: (anonymous function)
+        2: executeFrameFunction
+  50: (duration)
+    0: framebufferTexture2D(1, 2, 3, 0, 4)
+      swizzleTypes: [Number, Number, Number, WebGLTexture, Number]
+      trace:
+        0: framebufferTexture2D
+        1: (anonymous function)
+        2: executeFrameFunction
+  51: (duration)
+    0: frontFace(1)
+      swizzleTypes: [Number]
+      trace:
+        0: frontFace
+        1: (anonymous function)
+        2: executeFrameFunction
+  52: (duration)
+    0: generateMipmap(1)
+      swizzleTypes: [Number]
+      trace:
+        0: generateMipmap
+        1: (anonymous function)
+        2: executeFrameFunction
+  53: (duration)
+    0: getActiveAttrib(0, 1)
+      swizzleTypes: [WebGLProgram, Number]
+      trace:
+        0: getActiveAttrib
+        1: (anonymous function)
+        2: executeFrameFunction
+  54: (duration)
+    0: getActiveUniform(0, 1)
+      swizzleTypes: [WebGLProgram, Number]
+      trace:
+        0: getActiveUniform
+        1: (anonymous function)
+        2: executeFrameFunction
+  55: (duration)
+    0: getAttachedShaders(0)
+      swizzleTypes: [WebGLProgram]
+      trace:
+        0: getAttachedShaders
+        1: (anonymous function)
+        2: executeFrameFunction
+  56: (duration)
+    0: getAttribLocation(0, "test")
+      swizzleTypes: [WebGLProgram, String]
+      trace:
+        0: getAttribLocation
+        1: (anonymous function)
+        2: executeFrameFunction
+  57: (duration)
+    0: getBufferParameter(1, 2)
+      swizzleTypes: [Number, Number]
+      trace:
+        0: getBufferParameter
+        1: (anonymous function)
+        2: executeFrameFunction
+  58: (duration)
+    0: getContextAttributes()
+      trace:
+        0: getContextAttributes
+        1: (anonymous function)
+        2: executeFrameFunction
+  59: (duration)
+    0: getError()
+      trace:
+        0: getError
+        1: (anonymous function)
+        2: executeFrameFunction
+  60: (duration)
+    0: getExtension("test")
+      swizzleTypes: [String]
+      trace:
+        0: getExtension
+        1: (anonymous function)
+        2: executeFrameFunction
+  61: (duration)
+    0: getFramebufferAttachmentParameter(1, 2, 3)
+      swizzleTypes: [Number, Number, Number]
+      trace:
+        0: getFramebufferAttachmentParameter
+        1: (anonymous function)
+        2: executeFrameFunction
+  62: (duration)
+    0: getParameter(1)
+      swizzleTypes: [Number]
+      trace:
+        0: getParameter
+        1: (anonymous function)
+        2: executeFrameFunction
+  63: (duration)
+    0: getProgramInfoLog(0)
+      swizzleTypes: [WebGLProgram]
+      trace:
+        0: getProgramInfoLog
+        1: (anonymous function)
+        2: executeFrameFunction
+  64: (duration)
+    0: getProgramParameter(0, 1)
+      swizzleTypes: [WebGLProgram, Number]
+      trace:
+        0: getProgramParameter
+        1: (anonymous function)
+        2: executeFrameFunction
+  65: (duration)
+    0: getRenderbufferParameter(1, 2)
+      swizzleTypes: [Number, Number]
+      trace:
+        0: getRenderbufferParameter
+        1: (anonymous function)
+        2: executeFrameFunction
+  66: (duration)
+    0: getShaderInfoLog(0)
+      swizzleTypes: [WebGLShader]
+      trace:
+        0: getShaderInfoLog
+        1: (anonymous function)
+        2: executeFrameFunction
+  67: (duration)
+    0: getShaderParameter(0, 1)
+      swizzleTypes: [WebGLShader, Number]
+      trace:
+        0: getShaderParameter
+        1: (anonymous function)
+        2: executeFrameFunction
+  68: (duration)
+    0: getShaderPrecisionFormat(1, 2)
+      swizzleTypes: [Number, Number]
+      trace:
+        0: getShaderPrecisionFormat
+        1: (anonymous function)
+        2: executeFrameFunction
+  69: (duration)
+    0: getShaderSource(0)
+      swizzleTypes: [WebGLShader]
+      trace:
+        0: getShaderSource
+        1: (anonymous function)
+        2: executeFrameFunction
+  70: (duration)
+    0: getSupportedExtensions()
+      trace:
+        0: getSupportedExtensions
+        1: (anonymous function)
+        2: executeFrameFunction
+  71: (duration)
+    0: getTexParameter(1, 2)
+      swizzleTypes: [Number, Number]
+      trace:
+        0: getTexParameter
+        1: (anonymous function)
+        2: executeFrameFunction
+  72: (duration)
+    0: getUniform(0)
+      swizzleTypes: [WebGLProgram]
+      trace:
+        0: getUniform
+        1: (anonymous function)
+        2: executeFrameFunction
+  73: (duration)
+    0: getUniformLocation(0, "test")
+      swizzleTypes: [WebGLProgram, String]
+      trace:
+        0: getUniformLocation
+        1: (anonymous function)
+        2: executeFrameFunction
+  74: (duration)
+    0: getVertexAttrib(1, 2)
+      swizzleTypes: [Number, Number]
+      trace:
+        0: getVertexAttrib
+        1: (anonymous function)
+        2: executeFrameFunction
+  75: (duration)
+    0: getVertexAttribOffset(1, 2)
+      swizzleTypes: [Number, Number]
+      trace:
+        0: getVertexAttribOffset
+        1: (anonymous function)
+        2: executeFrameFunction
+  76: (duration)
+    0: hint(1, 2)
+      swizzleTypes: [Number, Number]
+      trace:
+        0: hint
+        1: (anonymous function)
+        2: executeFrameFunction
+  77: (duration)
+    0: isBuffer(0)
+      swizzleTypes: [WebGLBuffer]
+      trace:
+        0: isBuffer
+        1: (anonymous function)
+        2: executeFrameFunction
+  78: (duration)
+    0: isContextLost()
+      trace:
+        0: isContextLost
+        1: (anonymous function)
+        2: executeFrameFunction
+  79: (duration)
+    0: isEnabled(1)
+      swizzleTypes: [Number]
+      trace:
+        0: isEnabled
+        1: (anonymous function)
+        2: executeFrameFunction
+  80: (duration)
+    0: isFramebuffer(0)
+      swizzleTypes: [WebGLFramebuffer]
+      trace:
+        0: isFramebuffer
+        1: (anonymous function)
+        2: executeFrameFunction
+  81: (duration)
+    0: isProgram(0)
+      swizzleTypes: [WebGLProgram]
+      trace:
+        0: isProgram
+        1: (anonymous function)
+        2: executeFrameFunction
+  82: (duration)
+    0: isRenderbuffer(0)
+      swizzleTypes: [WebGLRenderbuffer]
+      trace:
+        0: isRenderbuffer
+        1: (anonymous function)
+        2: executeFrameFunction
+  83: (duration)
+    0: isShader(0)
+      swizzleTypes: [WebGLShader]
+      trace:
+        0: isShader
+        1: (anonymous function)
+        2: executeFrameFunction
+  84: (duration)
+    0: isTexture(0)
+      swizzleTypes: [WebGLTexture]
+      trace:
+        0: isTexture
+        1: (anonymous function)
+        2: executeFrameFunction
+  85: (duration)
+    0: lineWidth(1)
+      swizzleTypes: [Number]
+      trace:
+        0: lineWidth
+        1: (anonymous function)
+        2: executeFrameFunction
+  86: (duration)
+    0: linkProgram(0)
+      swizzleTypes: [WebGLProgram]
+      trace:
+        0: linkProgram
+        1: (anonymous function)
+        2: executeFrameFunction
+  87: (duration)
+    0: pixelStorei(1, 2)
+      swizzleTypes: [Number, Number]
+      trace:
+        0: pixelStorei
+        1: (anonymous function)
+        2: executeFrameFunction
+  88: (duration)
+    0: polygonOffset(1, 2)
+      swizzleTypes: [Number, Number]
+      trace:
+        0: polygonOffset
+        1: (anonymous function)
+        2: executeFrameFunction
+  89: (duration)
+    0: readPixels(1, 2, 3, 4, 5, 6, 0)
+      swizzleTypes: [Number, Number, Number, Number, Number, Number, TypedArray]
+      trace:
+        0: readPixels
+        1: (anonymous function)
+        2: executeFrameFunction
+  90: (duration)
+    0: releaseShaderCompiler()
+      trace:
+        0: releaseShaderCompiler
+        1: (anonymous function)
+        2: executeFrameFunction
+  91: (duration)
+    0: renderbufferStorage(1, 2, 3, 4)
+      swizzleTypes: [Number, Number, Number, Number]
+      trace:
+        0: renderbufferStorage
+        1: (anonymous function)
+        2: executeFrameFunction
+  92: (duration)
+    0: sampleCoverage(1, true)
+      swizzleTypes: [Number, Boolean]
+      trace:
+        0: sampleCoverage
+        1: (anonymous function)
+        2: executeFrameFunction
+  93: (duration)
+    0: scissor(1, 2, 3, 4)
+      swizzleTypes: [Number, Number, Number, Number]
+      trace:
+        0: scissor
+        1: (anonymous function)
+        2: executeFrameFunction
+  94: (duration)
+    0: shaderSource(0, "test")
+      swizzleTypes: [WebGLShader, String]
+      trace:
+        0: shaderSource
+        1: (anonymous function)
+        2: executeFrameFunction
+  95: (duration)
+    0: stencilFunc(1, 2, 3)
+      swizzleTypes: [Number, Number, Number]
+      trace:
+        0: stencilFunc
+        1: (anonymous function)
+        2: executeFrameFunction
+  96: (duration)
+    0: stencilFuncSeparate(1, 2, 3, 4)
+      swizzleTypes: [Number, Number, Number, Number]
+      trace:
+        0: stencilFuncSeparate
+        1: (anonymous function)
+        2: executeFrameFunction
+  97: (duration)
+    0: stencilMask(1)
+      swizzleTypes: [Number]
+      trace:
+        0: stencilMask
+        1: (anonymous function)
+        2: executeFrameFunction
+  98: (duration)
+    0: stencilMaskSeparate(1, 2)
+      swizzleTypes: [Number, Number]
+      trace:
+        0: stencilMaskSeparate
+        1: (anonymous function)
+        2: executeFrameFunction
+  99: (duration)
+    0: stencilOp(1, 2, 3)
+      swizzleTypes: [Number, Number, Number]
+      trace:
+        0: stencilOp
+        1: (anonymous function)
+        2: executeFrameFunction
+  100: (duration)
+    0: stencilOpSeparate(1, 2, 3, 4)
+      swizzleTypes: [Number, Number, Number, Number]
+      trace:
+        0: stencilOpSeparate
+        1: (anonymous function)
+        2: executeFrameFunction
+  101: (duration)
+    0: texParameterf(1, 2, 3)
+      swizzleTypes: [Number, Number, Number]
+      trace:
+        0: texParameterf
+        1: (anonymous function)
+        2: executeFrameFunction
+  102: (duration)
+    0: texParameteri(1, 2, 3)
+      swizzleTypes: [Number, Number, Number]
+      trace:
+        0: texParameteri
+        1: (anonymous function)
+        2: executeFrameFunction
+  103: (duration)
+    0: uniform1f(1)
+      swizzleTypes: [Number]
+      trace:
+        0: uniform1f
+        1: (anonymous function)
+        2: executeFrameFunction
+  104: (duration)
+    0: uniform1fv(0)
+      swizzleTypes: [TypedArray]
+      trace:
+        0: uniform1fv
+        1: (anonymous function)
+        2: executeFrameFunction
+  105: (duration)
+    0: uniform1i(1)
+      swizzleTypes: [Number]
+      trace:
+        0: uniform1i
+        1: (anonymous function)
+        2: executeFrameFunction
+  106: (duration)
+    0: uniform1iv(0)
+      swizzleTypes: [TypedArray]
+      trace:
+        0: uniform1iv
+        1: (anonymous function)
+        2: executeFrameFunction
+  107: (duration)
+    0: uniform2f(1, 2)
+      swizzleTypes: [Number, Number]
+      trace:
+        0: uniform2f
+        1: (anonymous function)
+        2: executeFrameFunction
+  108: (duration)
+    0: uniform2fv(0)
+      swizzleTypes: [TypedArray]
+      trace:
+        0: uniform2fv
+        1: (anonymous function)
+        2: executeFrameFunction
+  109: (duration)
+    0: uniform2i(1, 2)
+      swizzleTypes: [Number, Number]
+      trace:
+        0: uniform2i
+        1: (anonymous function)
+        2: executeFrameFunction
+  110: (duration)
+    0: uniform2iv(0)
+      swizzleTypes: [TypedArray]
+      trace:
+        0: uniform2iv
+        1: (anonymous function)
+        2: executeFrameFunction
+  111: (duration)
+    0: uniform3f(1, 2, 3)
+      swizzleTypes: [Number, Number, Number]
+      trace:
+        0: uniform3f
+        1: (anonymous function)
+        2: executeFrameFunction
+  112: (duration)
+    0: uniform3fv(0)
+      swizzleTypes: [TypedArray]
+      trace:
+        0: uniform3fv
+        1: (anonymous function)
+        2: executeFrameFunction
+  113: (duration)
+    0: uniform3i(1, 2, 3)
+      swizzleTypes: [Number, Number, Number]
+      trace:
+        0: uniform3i
+        1: (anonymous function)
+        2: executeFrameFunction
+  114: (duration)
+    0: uniform3iv(0)
+      swizzleTypes: [TypedArray]
+      trace:
+        0: uniform3iv
+        1: (anonymous function)
+        2: executeFrameFunction
+  115: (duration)
+    0: uniform4f(1, 2, 3, 4)
+      swizzleTypes: [Number, Number, Number, Number]
+      trace:
+        0: uniform4f
+        1: (anonymous function)
+        2: executeFrameFunction
+  116: (duration)
+    0: uniform4fv(0)
+      swizzleTypes: [TypedArray]
+      trace:
+        0: uniform4fv
+        1: (anonymous function)
+        2: executeFrameFunction
+  117: (duration)
+    0: uniform4i(1, 2, 3, 4)
+      swizzleTypes: [Number, Number, Number, Number]
+      trace:
+        0: uniform4i
+        1: (anonymous function)
+        2: executeFrameFunction
+  118: (duration)
+    0: uniform4iv(0)
+      swizzleTypes: [TypedArray]
+      trace:
+        0: uniform4iv
+        1: (anonymous function)
+        2: executeFrameFunction
+  119: (duration)
+    0: uniformMatrix2fv(true, 0)
+      swizzleTypes: [Boolean, TypedArray]
+      trace:
+        0: uniformMatrix2fv
+        1: (anonymous function)
+        2: executeFrameFunction
+  120: (duration)
+    0: uniformMatrix3fv(true, 0)
+      swizzleTypes: [Boolean, TypedArray]
+      trace:
+        0: uniformMatrix3fv
+        1: (anonymous function)
+        2: executeFrameFunction
+  121: (duration)
+    0: uniformMatrix4fv(true, 0)
+      swizzleTypes: [Boolean, TypedArray]
+      trace:
+        0: uniformMatrix4fv
+        1: (anonymous function)
+        2: executeFrameFunction
+  122: (duration)
+    0: useProgram(0)
+      swizzleTypes: [WebGLProgram]
+      trace:
+        0: useProgram
+        1: (anonymous function)
+        2: executeFrameFunction
+  123: (duration)
+    0: validateProgram(0)
+      swizzleTypes: [WebGLProgram]
+      trace:
+        0: validateProgram
+        1: (anonymous function)
+        2: executeFrameFunction
+  124: (duration)
+    0: vertexAttrib1f(1, 2)
+      swizzleTypes: [Number, Number]
+      trace:
+        0: vertexAttrib1f
+        1: (anonymous function)
+        2: executeFrameFunction
+  125: (duration)
+    0: vertexAttrib1fv(1, 0)
+      swizzleTypes: [Number, TypedArray]
+      trace:
+        0: vertexAttrib1fv
+        1: (anonymous function)
+        2: executeFrameFunction
+  126: (duration)
+    0: vertexAttrib2f(1, 2, 3)
+      swizzleTypes: [Number, Number, Number]
+      trace:
+        0: vertexAttrib2f
+        1: (anonymous function)
+        2: executeFrameFunction
+  127: (duration)
+    0: vertexAttrib2fv(1, 0)
+      swizzleTypes: [Number, TypedArray]
+      trace:
+        0: vertexAttrib2fv
+        1: (anonymous function)
+        2: executeFrameFunction
+  128: (duration)
+    0: vertexAttrib3f(1, 2, 3, 4)
+      swizzleTypes: [Number, Number, Number, Number]
+      trace:
+        0: vertexAttrib3f
+        1: (anonymous function)
+        2: executeFrameFunction
+  129: (duration)
+    0: vertexAttrib3fv(1, 0)
+      swizzleTypes: [Number, TypedArray]
+      trace:
+        0: vertexAttrib3fv
+        1: (anonymous function)
+        2: executeFrameFunction
+  130: (duration)
+    0: vertexAttrib4f(1, 2, 3, 4, 5)
+      swizzleTypes: [Number, Number, Number, Number, Number]
+      trace:
+        0: vertexAttrib4f
+        1: (anonymous function)
+        2: executeFrameFunction
+  131: (duration)
+    0: vertexAttrib4fv(1, 0)
+      swizzleTypes: [Number, TypedArray]
+      trace:
+        0: vertexAttrib4fv
+        1: (anonymous function)
+        2: executeFrameFunction
+  132: (duration)
+    0: vertexAttribPointer(1, 2, 3, true, 5, 6)
+      swizzleTypes: [Number, Number, Number, Boolean, Number, Number]
+      trace:
+        0: vertexAttribPointer
+        1: (anonymous function)
+        2: executeFrameFunction
+  133: (duration)
+    0: viewport(1, 2, 3, 4)
+      swizzleTypes: [Number, Number, Number, Number]
+      trace:
+        0: viewport
+        1: (anonymous function)
+        2: executeFrameFunction
+  134: (duration)
+    0: width
+      trace:
+        0: (anonymous function)
+        1: executeFrameFunction
+    1: width = 2
+      swizzleTypes: [Number]
+      trace:
+        0: (anonymous function)
+        1: executeFrameFunction
+  135: (duration)
+    0: height
+      trace:
+        0: (anonymous function)
+        1: executeFrameFunction
+    1: height = 2
+      swizzleTypes: [Number]
+      trace:
+        0: (anonymous function)
+        1: executeFrameFunction
+
+-- Running test case: Canvas.recordingWebGL2.memoryLimit
+initialState:
+  attributes:
+    width: 2
+    height: 2
+  parameters:
+    0: {"alpha":true,"depth":true,"stencil":false,"antialias":false,"premultipliedAlpha":true,"preserveDrawingBuffer":false,"failIfMajorPerformanceCaveat":false}
+  content: <filtered>
+frames:
+  0: (duration) (incomplete)
+    0: activeTexture(1)
+      swizzleTypes: [Number]
+      trace:
+        0: activeTexture
+        1: (anonymous function)
+        2: executeFrameFunction
+        3: performActions
+        4: Global Code
+        5: evaluateWithScopeExtension
+        6: (anonymous function)
+        7: _wrapCall
+
+-- Running test case: Canvas.recordingWebGL2.Console
+PASS: The recording should have the name "TEST".
+PASS: The recording should have one frame.
+PASS: The first frame should have one action.
+
diff --git a/LayoutTests/inspector/canvas/recording-webgl2-snapshots-expected.txt b/LayoutTests/inspector/canvas/recording-webgl2-snapshots-expected.txt
new file mode 100644 (file)
index 0000000..1e7b7f8
--- /dev/null
@@ -0,0 +1,139 @@
+Test that CanvasManager is able to record actions made to WebGL2 canvas contexts.
+
+
+== Running test suite: Canvas.recordingWebGL2
+-- Running test case: Canvas.recordingWebGL2.snapshots
+initialState:
+  attributes:
+    width: 300
+    height: 150
+  parameters:
+    0: {"alpha":true,"depth":true,"stencil":false,"antialias":false,"premultipliedAlpha":true,"preserveDrawingBuffer":false,"failIfMajorPerformanceCaveat":false}
+  content: <filtered>
+frames:
+  0: (duration)
+    0: useProgram(0)
+      swizzleTypes: [WebGLProgram]
+      trace:
+        0: useProgram
+        1: performActions
+        2: Global Code
+        3: evaluateWithScopeExtension
+        4: (anonymous function)
+        5: _wrapCall
+    1: clearColor(0, 0, 0, 1)
+      swizzleTypes: [Number, Number, Number, Number]
+      trace:
+        0: clearColor
+        1: clearContext
+        2: performActions
+        3: Global Code
+        4: evaluateWithScopeExtension
+        5: (anonymous function)
+        6: _wrapCall
+    2: clear(16384)
+      swizzleTypes: [Number]
+      trace:
+        0: clear
+        1: clearContext
+        2: performActions
+        3: Global Code
+        4: evaluateWithScopeExtension
+        5: (anonymous function)
+        6: _wrapCall
+      snapshot: <PASS: content changed>
+    3: bufferData(34962, 0, 35044)
+      swizzleTypes: [Number, TypedArray, Number]
+      trace:
+        0: bufferData
+        1: drawArrays
+        2: performActions
+        3: Global Code
+        4: evaluateWithScopeExtension
+        5: (anonymous function)
+        6: _wrapCall
+    4: drawArrays(4, 0, 3)
+      swizzleTypes: [Number, Number, Number]
+      trace:
+        0: drawArrays
+        1: drawArrays
+        2: performActions
+        3: Global Code
+        4: evaluateWithScopeExtension
+        5: (anonymous function)
+        6: _wrapCall
+      snapshot: <PASS: content changed>
+    5: clearColor(0, 0, 0, 1)
+      swizzleTypes: [Number, Number, Number, Number]
+      trace:
+        0: clearColor
+        1: clearContext
+        2: performActions
+        3: Global Code
+        4: evaluateWithScopeExtension
+        5: (anonymous function)
+        6: _wrapCall
+    6: clear(16384)
+      swizzleTypes: [Number]
+      trace:
+        0: clear
+        1: clearContext
+        2: performActions
+        3: Global Code
+        4: evaluateWithScopeExtension
+        5: (anonymous function)
+        6: _wrapCall
+      snapshot: <PASS: content changed>
+    7: bufferData(34962, 0, 35044)
+      swizzleTypes: [Number, TypedArray, Number]
+      trace:
+        0: bufferData
+        1: drawElements
+        2: performActions
+        3: Global Code
+        4: evaluateWithScopeExtension
+        5: (anonymous function)
+        6: _wrapCall
+    8: bufferData(34963, 0, 35044)
+      swizzleTypes: [Number, TypedArray, Number]
+      trace:
+        0: bufferData
+        1: drawElements
+        2: performActions
+        3: Global Code
+        4: evaluateWithScopeExtension
+        5: (anonymous function)
+        6: _wrapCall
+    9: drawElements(4, 3, 5123, 0)
+      swizzleTypes: [Number, Number, Number, Number]
+      trace:
+        0: drawElements
+        1: drawElements
+        2: performActions
+        3: Global Code
+        4: evaluateWithScopeExtension
+        5: (anonymous function)
+        6: _wrapCall
+      snapshot: <PASS: content changed>
+    10: clearColor(0, 0, 0, 1)
+      swizzleTypes: [Number, Number, Number, Number]
+      trace:
+        0: clearColor
+        1: clearContext
+        2: performActions
+        3: Global Code
+        4: evaluateWithScopeExtension
+        5: (anonymous function)
+        6: _wrapCall
+    11: clear(16384)
+      swizzleTypes: [Number]
+      trace:
+        0: clear
+        1: clearContext
+        2: performActions
+        3: Global Code
+        4: evaluateWithScopeExtension
+        5: (anonymous function)
+        6: _wrapCall
+      snapshot: <PASS: content changed>
+
diff --git a/LayoutTests/inspector/canvas/recording-webgl2-snapshots.html b/LayoutTests/inspector/canvas/recording-webgl2-snapshots.html
new file mode 100644 (file)
index 0000000..82f27c9
--- /dev/null
@@ -0,0 +1,117 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../../http/tests/inspector/resources/inspector-test.js"></script>
+<script src="resources/recording-utilities.js"></script>
+<script src="resources/shaderProgram-utilities.js"></script>
+<script id="vertex-shader" type="x-shader/x-vertex">
+    attribute vec3 position;
+    void main(void) {
+        gl_Position = vec4(position, 1.0);
+    }
+</script>
+<script id="fragment-shader" type="x-shader/x-fragment">
+    precision mediump float;
+
+    void main(void) {
+        gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
+    }
+</script>
+<script>
+if (window.internals) {
+    window.internals.settings.setWebGLErrorsToConsoleEnabled(false);
+    window.internals.settings.setWebGL2Enabled(true);
+}
+
+let vertexBuffer = null;
+let indexBuffer = null;
+let position = null;
+
+function load() {
+    createProgram("webgl2");
+    linkProgram("vertex-shader", "fragment-shader");
+    context.useProgram(program);
+
+    vertexBuffer = context.createBuffer();
+    context.bindBuffer(context.ARRAY_BUFFER, vertexBuffer);
+
+    indexBuffer = context.createBuffer();
+    context.bindBuffer(context.ELEMENT_ARRAY_BUFFER, indexBuffer);
+
+    position = context.getUniformLocation(program, "position");
+    context.vertexAttribPointer(position, 3, context.FLOAT, false, 0, 0); 
+    context.enableVertexAttribArray(position);
+
+    document.body.appendChild(context.canvas);
+
+    runTest();
+}
+
+function cancelActions() {
+    // This function is expected by "resources/recording-utilities.js".
+}
+
+function performActions() {
+    context.useProgram(program);
+
+    function clearContext() {
+        context.clearColor(0.0, 0.0, 0.0, 1.0);
+        context.clear(context.COLOR_BUFFER_BIT);
+    }
+
+    function drawArrays() {
+        let vertexes = [
+            -0.5,  0.5,  0.0,
+            -0.5, -0.5,  0.0,
+             0.5, -0.5,  0.0,
+        ];
+        context.bufferData(context.ARRAY_BUFFER, new Float32Array(vertexes), context.STATIC_DRAW);
+
+        context.drawArrays(context.TRIANGLES, 0, 3);
+    }
+
+    function drawElements() {
+        let vertexes = [
+             0.5,  0.5,  0.0,
+            -0.5, -0.5,  0.0,
+             0.5, -0.5,  0.0,
+        ];
+        context.bufferData(context.ARRAY_BUFFER, new Float32Array(vertexes), context.STATIC_DRAW);
+
+        let indexes = [0, 1, 2];
+        context.bufferData(context.ELEMENT_ARRAY_BUFFER, new Uint16Array(indexes), context.STATIC_DRAW);
+
+        context.drawElements(context.TRIANGLES, indexes.length, context.UNSIGNED_SHORT, 0);
+    }
+
+    clearContext();
+    drawArrays();
+    clearContext();
+    drawElements();
+    clearContext();
+
+    setTimeout(() => {
+        TestPage.dispatchEventToFrontend("LastFrame");
+    }, 0);
+}
+
+function test() {
+    let suite = InspectorTest.createAsyncSuite("Canvas.recordingWebGL2");
+
+    suite.addTestCase({
+        name: "Canvas.recordingWebGL2.snapshots",
+        description: "Check that the snapshot taken after each visual action is different.",
+        test(resolve, reject) {
+            startRecording(WI.Canvas.ContextType.WebGL2, resolve, reject, {frameCount: 1, checkForContentChange: true});
+        },
+        timeout: -1,
+    });
+
+    suite.runTestCasesAndFinish();
+}
+</script>
+</head>
+<body onload="load()">
+    <p>Test that CanvasManager is able to record actions made to WebGL2 canvas contexts.</p>
+</body>
+</html>
diff --git a/LayoutTests/inspector/canvas/recording-webgl2.html b/LayoutTests/inspector/canvas/recording-webgl2.html
new file mode 100644 (file)
index 0000000..e92a86f
--- /dev/null
@@ -0,0 +1,556 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../../http/tests/inspector/resources/inspector-test.js"></script>
+<script src="resources/recording-utilities.js"></script>
+<script src="resources/shaderProgram-utilities.js"></script>
+<script id="vertex-shader" type="x-shader/x-vertex">
+    attribute vec4 test;
+    void main(void) {
+        gl_Position = test;
+    }
+</script>
+<script id="fragment-shader" type="x-shader/x-fragment">
+    precision mediump float;
+
+    void main(void) {
+        gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
+    }
+</script>
+<script>
+if (window.internals) {
+    window.internals.settings.setWebGLErrorsToConsoleEnabled(false);
+    window.internals.settings.setWebGL2Enabled(true);
+}
+
+// 2x2 red square
+let image = document.createElement("img");
+image.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAYAAABytg0kAAAAAXNSR0IArs4c6QAAABNJREFUCB1j/M/AAEQMDEwgAgQAHxcCAmtAm/sAAAAASUVORK5CYII=";
+
+let float32Array = new Float32Array([0.1, 0.2]);
+let int32Array = new Int32Array([1, 2]);
+
+let buffer = null;
+let framebuffer = null;
+let uniformLocation = null;
+let renderbuffer = null;
+let shader = null;
+let texture = null;
+
+function load() {
+    createProgram("webgl2");
+    linkProgram("vertex-shader", "fragment-shader");
+
+    context.canvas.width = 2;
+    context.canvas.height = 2;
+
+    buffer = context.createBuffer();
+    framebuffer = context.createFramebuffer();
+    uniformLocation = context.getUniformLocation(program, "test");
+    renderbuffer = context.createRenderbuffer();
+    shader = context.createShader(context.VERTEX_SHADER);
+    texture = context.createTexture();
+
+    cancelActions();
+
+    runTest();
+}
+
+function ignoreException(func){
+    try {
+        func();
+    } catch (e) { }
+}
+
+let requestAnimationFrameId = NaN;
+
+function cancelActions() {
+    cancelAnimationFrame(requestAnimationFrameId);
+    requestAnimationFrameId = NaN;
+
+    context.clearColor(0.0, 0.0, 0.0, 0.0);
+    context.clear(context.COLOR_BUFFER_BIT);
+}
+
+function performActions() {
+    let frames = [
+        () => {
+            context.activeTexture(1);
+        },
+        () => {
+            context.attachShader(program, shader);
+        },
+        () => {
+            context.bindAttribLocation(program, 1, "test");
+        },
+        () => {
+            context.bindBuffer(1, buffer);
+        },
+        () => {
+            context.bindFramebuffer(1, framebuffer);
+        },
+        () => {
+            context.bindRenderbuffer(1, renderbuffer);
+        },
+        () => {
+            context.bindTexture(1, texture);
+        },
+        () => {
+            context.blendColor(1, 2, 3, 4);
+        },
+        () => {
+            context.blendEquation(1);
+        },
+        () => {
+            context.blendEquationSeparate(1, 2);
+        },
+        () => {
+            context.blendFunc(1, 2);
+        },
+        () => {
+            context.blendFuncSeparate(1, 2, 3, 4);
+        },
+        () => {
+            context.bufferData(1, float32Array, 2);
+            context.bufferData(3, 4, 5);
+        },
+        () => {
+            context.bufferSubData(1, 2, float32Array);
+        },
+        () => {
+            context.checkFramebufferStatus(1);
+        },
+        () => {
+            context.clear(1);
+        },
+        () => {
+            context.clearColor(1, 2, 3, 4);
+        },
+        () => {
+            context.clearDepth(1);
+        },
+        () => {
+            context.clearStencil(1);
+        },
+        () => {
+            context.colorMask(true, false, true, false);
+        },
+        () => {
+            context.compileShader(shader);
+        },
+        () => {
+            context.compressedTexSubImage2D(1, 2, 3, 4, 5, 6, 7, float32Array);
+        },
+        () => {
+            context.copyTexImage2D(1, 2, 3, 4, 5, 6, 7, 8);
+        },
+        () => {
+            context.copyTexSubImage2D(1, 2, 3, 4, 5, 6, 7, 8);
+        },
+        () => {
+            context.createBuffer();
+        },
+        () => {
+            context.createFramebuffer();
+        },
+        () => {
+            context.createProgram();
+        },
+        () => {
+            context.createRenderbuffer();
+        },
+        () => {
+            context.createShader(1);
+        },
+        () => {
+            context.createTexture();
+        },
+        () => {
+            context.cullFace(1);
+        },
+        () => {
+            context.deleteBuffer(buffer);
+        },
+        () => {
+            context.deleteFramebuffer(framebuffer);
+        },
+        () => {
+            context.deleteProgram(program);
+        },
+        () => {
+            context.deleteRenderbuffer(renderbuffer);
+        },
+        () => {
+            context.deleteShader(shader);
+        },
+        () => {
+            context.deleteTexture(texture);
+        },
+        () => {
+            context.depthFunc(1);
+        },
+        () => {
+            context.depthMask(true);
+        },
+        () => {
+            context.depthRange(1, 2);
+        },
+        () => {
+            context.detachShader(program, shader);
+        },
+        () => {
+            context.disable(1);
+        },
+        () => {
+            context.disableVertexAttribArray(1);
+        },
+        () => {
+            context.drawArrays(1, 2, 3);
+        },
+        () => {
+            context.drawElements(1, 2, 3, 4);
+        },
+        () => {
+            context.enable(1);
+        },
+        () => {
+            context.enableVertexAttribArray(1);
+        },
+        () => {
+            context.finish();
+        },
+        () => {
+            context.flush();
+        },
+        () => {
+            context.framebufferRenderbuffer(1, 2, 3, renderbuffer);
+        },
+        () => {
+            context.framebufferTexture2D(1, 2, 3, texture, 4);
+        },
+        () => {
+            context.frontFace(1);
+        },
+        () => {
+            context.generateMipmap(1);
+        },
+        () => {
+            context.getActiveAttrib(program, 1);
+        },
+        () => {
+            context.getActiveUniform(program, 1);
+        },
+        () => {
+            context.getAttachedShaders(program);
+        },
+        () => {
+            context.getAttribLocation(program, "test");
+        },
+        () => {
+            context.getBufferParameter(1, 2);
+        },
+        () => {
+            context.getContextAttributes();
+        },
+        () => {
+            context.getError();
+        },
+        () => {
+            context.getExtension("test");
+        },
+        () => {
+            context.getFramebufferAttachmentParameter(1, 2, 3);
+        },
+        () => {
+            context.getParameter(1);
+        },
+        () => {
+            context.getProgramInfoLog(program);
+        },
+        () => {
+            context.getProgramParameter(program, 1);
+        },
+        () => {
+            context.getRenderbufferParameter(1, 2);
+        },
+        () => {
+            context.getShaderInfoLog(shader);
+        },
+        () => {
+            context.getShaderParameter(shader, 1);
+        },
+        () => {
+            context.getShaderPrecisionFormat(1, 2);
+        },
+        () => {
+            context.getShaderSource(shader);
+        },
+        () => {
+            context.getSupportedExtensions();
+        },
+        () => {
+            context.getTexParameter(1, 2);
+        },
+        () => {
+            context.getUniform(program, uniformLocation);
+        },
+        () => {
+            context.getUniformLocation(program, "test");
+        },
+        () => {
+            context.getVertexAttrib(1, 2);
+        },
+        () => {
+            context.getVertexAttribOffset(1, 2);
+        },
+        () => {
+            context.hint(1, 2);
+        },
+        () => {
+            context.isBuffer(buffer);
+        },
+        () => {
+            context.isContextLost();
+        },
+        () => {
+            context.isEnabled(1);
+        },
+        () => {
+            context.isFramebuffer(framebuffer);
+        },
+        () => {
+            context.isProgram(program);
+        },
+        () => {
+            context.isRenderbuffer(renderbuffer);
+        },
+        () => {
+            context.isShader(shader);
+        },
+        () => {
+            context.isTexture(texture);
+        },
+        () => {
+            context.lineWidth(1);
+        },
+        () => {
+            context.linkProgram(program);
+        },
+        () => {
+            context.pixelStorei(1, 2);
+        },
+        () => {
+            context.polygonOffset(1, 2);
+        },
+        () => {
+            context.readPixels(1, 2, 3, 4, 5, 6, float32Array);
+        },
+        () => {
+            context.releaseShaderCompiler();
+        },
+        () => {
+            context.renderbufferStorage(1, 2, 3, 4);
+        },
+        () => {
+            context.sampleCoverage(1, true);
+        },
+        () => {
+            context.scissor(1, 2, 3, 4);
+        },
+        () => {
+            context.shaderSource(shader, "test");
+        },
+        () => {
+            context.stencilFunc(1, 2, 3);
+        },
+        () => {
+            context.stencilFuncSeparate(1, 2, 3, 4);
+        },
+        () => {
+            context.stencilMask(1);
+        },
+        () => {
+            context.stencilMaskSeparate(1, 2);
+        },
+        () => {
+            context.stencilOp(1, 2, 3);
+        },
+        () => {
+            context.stencilOpSeparate(1, 2, 3, 4);
+        },
+        () => {
+            context.texParameterf(1, 2, 3);
+        },
+        () => {
+            context.texParameteri(1, 2, 3);
+        },
+        () => {
+            context.uniform1f(uniformLocation, 1);
+        },
+        () => {
+            context.uniform1fv(uniformLocation, float32Array);
+        },
+        () => {
+            context.uniform1i(uniformLocation, 1);
+        },
+        () => {
+            context.uniform1iv(uniformLocation, int32Array);
+        },
+        () => {
+            context.uniform2f(uniformLocation, 1, 2);
+        },
+        () => {
+            context.uniform2fv(uniformLocation, float32Array);
+        },
+        () => {
+            context.uniform2i(uniformLocation, 1, 2);
+        },
+        () => {
+            context.uniform2iv(uniformLocation, int32Array);
+        },
+        () => {
+            context.uniform3f(uniformLocation, 1, 2, 3);
+        },
+        () => {
+            context.uniform3fv(uniformLocation, float32Array);
+        },
+        () => {
+            context.uniform3i(uniformLocation, 1, 2, 3);
+        },
+        () => {
+            context.uniform3iv(uniformLocation, int32Array);
+        },
+        () => {
+            context.uniform4f(uniformLocation, 1, 2, 3, 4);
+        },
+        () => {
+            context.uniform4fv(uniformLocation, float32Array);
+        },
+        () => {
+            context.uniform4i(uniformLocation, 1, 2, 3, 4);
+        },
+        () => {
+            context.uniform4iv(uniformLocation, int32Array);
+        },
+        () => {
+            context.uniformMatrix2fv(uniformLocation, true, float32Array);
+        },
+        () => {
+            context.uniformMatrix3fv(uniformLocation, true, float32Array);
+        },
+        () => {
+            context.uniformMatrix4fv(uniformLocation, true, float32Array);
+        },
+        () => {
+            context.useProgram(program);
+        },
+        () => {
+            context.validateProgram(program);
+        },
+        () => {
+            context.vertexAttrib1f(1, 2);
+        },
+        () => {
+            context.vertexAttrib1fv(1, float32Array);
+        },
+        () => {
+            context.vertexAttrib2f(1, 2, 3);
+        },
+        () => {
+            context.vertexAttrib2fv(1, float32Array);
+        },
+        () => {
+            context.vertexAttrib3f(1, 2, 3, 4);
+        },
+        () => {
+            context.vertexAttrib3fv(1, float32Array);
+        },
+        () => {
+            context.vertexAttrib4f(1, 2, 3, 4, 5);
+        },
+        () => {
+            context.vertexAttrib4fv(1, float32Array);
+        },
+        () => {
+            context.vertexAttribPointer(1, 2, 3, 4, 5, 6);
+        },
+        () => {
+            context.viewport(1, 2, 3, 4);
+        },
+        () => {
+            context.canvas.width;
+            context.canvas.width = 2;
+        },
+        () => {
+            context.canvas.height;
+            context.canvas.height = 2;
+        },
+        () => {
+            TestPage.dispatchEventToFrontend("LastFrame");
+        },
+    ];
+    let index = 0;
+    function executeFrameFunction() {
+        frames[index++]();
+        if (index < frames.length)
+            requestAnimationFrameId = requestAnimationFrame(executeFrameFunction);
+    };
+    executeFrameFunction();
+}
+
+function performConsoleActions() {
+    console.record(context, {name: "TEST"});
+
+    context.createTexture();
+
+    console.recordEnd(context);
+
+    context.createBuffer();
+}
+
+function test() {
+    let suite = InspectorTest.createAsyncSuite("Canvas.recordingWebGL2");
+
+    suite.addTestCase({
+        name: "Canvas.recordingWebGL2.singleFrame",
+        description: "Check that the recording is stopped after a single frame.",
+        test(resolve, reject) {
+            startRecording(WI.Canvas.ContextType.WebGL2, resolve, reject, {frameCount: 1});
+        },
+        timeout: -1,
+    });
+
+    suite.addTestCase({
+        name: "Canvas.recordingWebGL2.multipleFrames",
+        description: "Check that recording data is serialized correctly for multiple frames.",
+        test(resolve, reject) {
+            startRecording(WI.Canvas.ContextType.WebGL2, resolve, reject);
+        },
+        timeout: -1,
+    });
+
+    suite.addTestCase({
+        name: "Canvas.recordingWebGL2.memoryLimit",
+        description: "Check that the recording is stopped when it reaches the memory limit.",
+        test(resolve, reject) {
+            startRecording(WI.Canvas.ContextType.WebGL2, resolve, reject, {memoryLimit: 10});
+        },
+        timeout: -1,
+    });
+
+    suite.addTestCase({
+        name: "Canvas.recordingWebGL2.Console",
+        description: "Check that a recording can be triggered by console.record().",
+        test(resolve, reject) {
+            consoleRecord(WI.Canvas.ContextType.WebGL2, resolve, reject);
+        },
+    });
+
+    suite.runTestCasesAndFinish();
+}
+</script>
+</head>
+<body onload="load()">
+    <p>Test that CanvasManager is able to record actions made to WebGL2 canvas contexts.</p>
+</body>
+</html>
index 9e3c933..a394fcd 100644 (file)
@@ -543,6 +543,8 @@ webkit.org/b/166536 fast/canvas/webgl/webgl2-runtime-flag.html [ Skip ]
 webkit.org/b/166536 fast/canvas/webgl/webgl2-texStorage.html [ Skip ]
 webkit.org/b/166536 fast/canvas/webgl/webgl2-texture-upload-enums.html [ Skip ]
 webkit.org/b/166536 inspector/canvas/create-context-webgl2.html [ Skip ]
+webkit.org/b/166536 inspector/canvas/recording-webgl2.html [ Skip ]
+webkit.org/b/166536 inspector/canvas/recording-webgl2-snapshots.html [ Skip ]
 webkit.org/b/166536 inspector/canvas/requestContent-webgl2.html [ Skip ]
 webkit.org/b/166536 inspector/canvas/resolveCanvasContext-webgl2.html [ Skip ]
 webkit.org/b/166536 inspector/canvas/shaderProgram-add-remove-webgl2.html [ Skip ]
index 93b4fc5..aaef5be 100644 (file)
@@ -1032,6 +1032,8 @@ webkit.org/b/173931 inspector/canvas/context-attributes.html [ Pass Timeout ]
 webkit.org/b/178028 inspector/canvas/create-context-2d.html [ Pass Timeout ]
 webkit.org/b/174066 inspector/canvas/create-context-webgl2.html [ Pass Timeout ]
 webkit.org/b/174272 inspector/canvas/css-canvas-clients.html [ Pass Failure ]
+webkit.org/b/174066 inspector/canvas/recording-webgl2.html [ Pass Failure Timeout ]
+webkit.org/b/174066 inspector/canvas/recording-webgl2-snapshots.html [ Pass Failure Timeout ]
 webkit.org/b/174066 inspector/canvas/shaderProgram-add-remove-webgl2.html [ Pass Failure Timeout ]
 webkit.org/b/160048 [ Debug ] inspector/codemirror/prettyprinting-javascript.html [ Pass Timeout ]
 webkit.org/b/152025 [ Debug ] inspector/console/messagesCleared.html [ Pass Timeout ]
index d21dd0e..94c63fd 100644 (file)
@@ -1981,6 +1981,10 @@ http/tests/security/webgl-remote-read-remote-image-allowed-with-credentials.html
 http/tests/security/webgl-remote-read-remote-image-blocked-no-crossorigin.html [ Skip ]
 inspector/canvas/create-context-webgl.html [ Skip ]
 inspector/canvas/create-context-webgl2.html [ Skip ]
+inspector/canvas/recording-webgl.html [ Skip ]
+inspector/canvas/recording-webgl-snapshots.html [ Skip ]
+inspector/canvas/recording-webgl2.html [ Skip ]
+inspector/canvas/recording-webgl2-snapshots.html [ Skip ]
 inspector/canvas/requestContent-webgl.html [ Skip ]
 inspector/canvas/requestContent-webgl2.html [ Skip ]
 inspector/canvas/requestShaderSource.html [ Skip ]
index ec94087..3291973 100644 (file)
@@ -284,6 +284,8 @@ fast/canvas/webgl/webgl2-texStorage.html [ Skip ]
 fast/canvas/webgl/webgl2-texture-upload-enums.html [ Skip ]
 inspector/canvas/requestContent-webgl2.html [ Skip ]
 inspector/canvas/create-context-webgl2.html [ Skip ]
+inspector/canvas/recording-webgl2.html [ Skip ]
+inspector/canvas/recording-webgl2-snapshots.html [ Skip ]
 inspector/canvas/resolveCanvasContext-webgl2.html [ Skip ]
 inspector/canvas/shaderProgram-add-remove-webgl2.html [ Skip ]
 webgl/webgl2-rendering-context-defined.html [ Skip ]
index c05005e..bde32b8 100644 (file)
@@ -1,3 +1,15 @@
+2019-05-03  Devin Rousso  <drousso@apple.com>
+
+        Web Inspector: Record actions performed on WebGL2RenderingContext
+        https://bugs.webkit.org/show_bug.cgi?id=176008
+        <rdar://problem/34213884>
+
+        Reviewed by Joseph Pecoraro.
+
+        * inspector/protocol/Recording.json:
+        * inspector/scripts/codegen/generator.py:
+        Add `canvas-webgl2` as a `Type`.
+
 2019-05-03  Commit Queue  <commit-queue@webkit.org>
 
         Unreviewed, rolling out r244881.
index 8dfd70d..bc3ddf9 100644 (file)
@@ -7,7 +7,7 @@
         {
             "id": "Type",
             "type": "string",
-            "enum": ["canvas-2d", "canvas-bitmaprenderer", "canvas-webgl"],
+            "enum": ["canvas-2d", "canvas-bitmaprenderer", "canvas-webgl", "canvas-webgl2"],
             "description": "The type of the recording."
         },
         {
index 98536bc..f6f4e2c 100755 (executable)
@@ -48,6 +48,7 @@ _ALWAYS_SPECIALCASED_ENUM_VALUE_LOOKUP_TABLE = dict([(s.upper(), s) for s in _AL
 _ENUM_IDENTIFIER_RENAME_MAP = {
     'canvas-bitmaprenderer': 'CanvasBitmapRenderer',  # Recording.Type.canvas-bitmaprenderer
     'canvas-webgl': 'CanvasWebGL',  # Recording.Type.canvas-webgl
+    'canvas-webgl2': 'CanvasWebGL2',  # Recording.Type.canvas-webgl2
     'webgl': 'WebGL',  # Canvas.ContextType.webgl
     'webgl2': 'WebGL2',  # Canvas.ContextType.webgl2
     'webgpu': 'WebGPU',  # Canvas.ContextType.gpu
index 586dc3e..23acb3e 100644 (file)
@@ -1,3 +1,38 @@
+2019-05-03  Devin Rousso  <drousso@apple.com>
+
+        Web Inspector: Record actions performed on WebGL2RenderingContext
+        https://bugs.webkit.org/show_bug.cgi?id=176008
+        <rdar://problem/34213884>
+
+        Reviewed by Joseph Pecoraro.
+
+        Tests: inspector/canvas/recording-webgl2.html
+               inspector/canvas/recording-webgl2-snapshots.html
+
+        * html/canvas/WebGL2RenderingContext.idl:
+
+        * bindings/js/CallTracerTypes.h:
+        * inspector/RecordingSwizzleTypes.h:
+
+        * inspector/InspectorCanvas.h:
+        * inspector/InspectorCanvas.cpp:
+        (WebCore::InspectorCanvas::canvasChanged): Added.
+        (WebCore::InspectorCanvas::resetRecordingData):
+        (WebCore::shouldSnapshotWebGL2Action): Added.
+        (WebCore::InspectorCanvas::recordAction):
+        (WebCore::InspectorCanvas::releaseObjectForRecording):
+        (WebCore::InspectorCanvas::appendActionSnapshotIfNeeded):
+        (WebCore::InspectorCanvas::buildAction):
+        * inspector/agents/InspectorCanvasAgent.h:
+        * inspector/agents/InspectorCanvasAgent.cpp:
+        (WebCore::InspectorCanvasAgent::canvasChanged): Added.
+        (WebCore::InspectorCanvasAgent::startRecording):
+        Provide an actual implementation of `CanvasObserver::canvasChanged` since it can be used to
+        determine whether or not an action needs a snapshot.
+
+        * page/PageConsoleClient.cpp:
+        (WebCore::canvasRenderingContext):
+
 2019-05-03  Commit Queue  <commit-queue@webkit.org>
 
         Unreviewed, rolling out r244881.
index 95b4eea..7bc5406 100644 (file)
@@ -41,6 +41,7 @@
 #include <JavaScriptCore/ArrayBufferView.h>
 #include <JavaScriptCore/Float32Array.h>
 #include <JavaScriptCore/Int32Array.h>
+#include <JavaScriptCore/Uint32Array.h>
 #include <wtf/RefPtr.h>
 #include <wtf/Variant.h>
 #include <wtf/Vector.h>
 #include "WebGLBuffer.h"
 #include "WebGLFramebuffer.h"
 #include "WebGLProgram.h"
+#include "WebGLQuery.h"
 #include "WebGLRenderbuffer.h"
+#include "WebGLSampler.h"
 #include "WebGLShader.h"
+#include "WebGLSync.h"
 #include "WebGLTexture.h"
+#include "WebGLTransformFeedback.h"
 #include "WebGLUniformLocation.h"
+#include "WebGLVertexArrayObject.h"
 #endif
 
 namespace WebCore {
@@ -76,10 +82,15 @@ using RecordCanvasActionVariant = Variant<
     WebGLBuffer*,
     WebGLFramebuffer*,
     WebGLProgram*,
+    WebGLQuery*,
     WebGLRenderbuffer*,
+    WebGLSampler*,
     WebGLShader*,
+    WebGLSync*,
     WebGLTexture*,
+    WebGLTransformFeedback*,
     WebGLUniformLocation*,
+    WebGLVertexArrayObject*,
 #endif
     RefPtr<ArrayBuffer>,
     RefPtr<ArrayBufferView>,
@@ -97,11 +108,15 @@ using RecordCanvasActionVariant = Variant<
 #endif
     RefPtr<ImageData>,
     RefPtr<Int32Array>,
+    RefPtr<Uint32Array>,
+    Vector<String>,
     Vector<float>,
-    Vector<int>,
+    Vector<uint32_t>,
+    Vector<int32_t>,
     String,
     double,
     float,
+    uint64_t,
     int64_t,
     uint32_t,
     int32_t,
index 325bc44..866175a 100644 (file)
@@ -56,6 +56,7 @@ typedef (ImageBitmap or ImageData or HTMLImageElement or HTMLCanvasElement) TexI
     JSCustomMarkFunction,
     JSGenerateToJSObject,
     DoNotCheckConstants,
+    CallTracingCallback=recordCanvasAction,
 ] interface WebGL2RenderingContext {
     const GLenum READ_BUFFER                                   = 0x0C02;
     const GLenum UNPACK_ROW_LENGTH                             = 0x0CF2;
index f4e0fce..e38f2dc 100644 (file)
@@ -94,12 +94,23 @@ HTMLCanvasElement* InspectorCanvas::canvasElement()
     return nullptr;
 }
 
+void InspectorCanvas::canvasChanged()
+{
+    if (!m_context.callTracingActive())
+        return;
+
+    // Since 2D contexts are able to be fully reproduced in the frontend, we don't need snapshots.
+    if (is<CanvasRenderingContext2D>(m_context))
+        return;
+
+    m_contentChanged = true;
+}
+
 void InspectorCanvas::resetRecordingData()
 {
     m_initialState = nullptr;
     m_frames = nullptr;
     m_currentActions = nullptr;
-    m_actionNeedingSnapshot = nullptr;
     m_serializedDuplicateData = nullptr;
     m_indexedDuplicateData.clear();
     m_recordingName = { };
@@ -107,6 +118,7 @@ void InspectorCanvas::resetRecordingData()
     m_bufferUsed = 0;
     m_frameCount = WTF::nullopt;
     m_framesCaptured = 0;
+    m_contentChanged = false;
 
     m_context.setCallTracingActive(false);
 }
@@ -133,6 +145,15 @@ static bool shouldSnapshotWebGLAction(const String& name)
         || name == "drawElements";
 }
 
+static bool shouldSnapshotWebGL2Action(const String& name)
+{
+    return name == "clear"
+        || name == "drawArrays"
+        || name == "drawArraysInstanced"
+        || name == "drawElements"
+        || name == "drawElementsInstanced";
+}
+
 void InspectorCanvas::recordAction(const String& name, Vector<RecordCanvasActionVariant>&& parameters)
 {
     if (!m_initialState) {
@@ -161,15 +182,19 @@ void InspectorCanvas::recordAction(const String& name, Vector<RecordCanvasAction
 
     appendActionSnapshotIfNeeded();
 
-    auto action = buildAction(name, WTFMove(parameters));
-    m_bufferUsed += action->memoryCost();
-    m_currentActions->addItem(action.ptr());
+    m_lastRecordedAction = buildAction(name, WTFMove(parameters));
+    m_bufferUsed += m_lastRecordedAction->memoryCost();
+    m_currentActions->addItem(m_lastRecordedAction.get());
 
     if (is<ImageBitmapRenderingContext>(m_context) && shouldSnapshotBitmapRendererAction(name))
-        m_actionNeedingSnapshot = WTFMove(action);
+        m_contentChanged = true;
 #if ENABLE(WEBGL)
     else if (is<WebGLRenderingContext>(m_context) && shouldSnapshotWebGLAction(name))
-        m_actionNeedingSnapshot = WTFMove(action);
+        m_contentChanged = true;
+#endif
+#if ENABLE(WEBGL2)
+    else if (is<WebGL2RenderingContext>(m_context) && shouldSnapshotWebGL2Action(name))
+        m_contentChanged = true;
 #endif
 }
 
@@ -296,11 +321,9 @@ Ref<Inspector::Protocol::Canvas::Canvas> InspectorCanvas::buildObjectForCanvas(b
 Ref<Inspector::Protocol::Recording::Recording> InspectorCanvas::releaseObjectForRecording()
 {
     ASSERT(!m_currentActions);
-    ASSERT(!m_actionNeedingSnapshot);
+    ASSERT(!m_lastRecordedAction);
     ASSERT(!m_frames);
 
-    // 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;
@@ -310,6 +333,10 @@ Ref<Inspector::Protocol::Recording::Recording> InspectorCanvas::releaseObjectFor
     else if (is<WebGLRenderingContext>(m_context))
         type = Inspector::Protocol::Recording::Type::CanvasWebGL;
 #endif
+#if ENABLE(WEBGL2)
+    else if (is<WebGL2RenderingContext>(m_context))
+        type = Inspector::Protocol::Recording::Type::CanvasWebGL2;
+#endif
     else {
         ASSERT_NOT_REACHED();
         type = Inspector::Protocol::Recording::Type::Canvas2D;
@@ -371,17 +398,20 @@ String InspectorCanvas::getCanvasContentAsDataURL(ErrorString& errorString)
 
 void InspectorCanvas::appendActionSnapshotIfNeeded()
 {
-    if (!m_actionNeedingSnapshot)
+    if (!m_lastRecordedAction)
         return;
 
-    m_bufferUsed -= m_actionNeedingSnapshot->memoryCost();
+    if (m_contentChanged) {
+        m_bufferUsed -= m_lastRecordedAction->memoryCost();
 
-    ErrorString ignored;
-    m_actionNeedingSnapshot->addItem(indexForData(getCanvasContentAsDataURL(ignored)));
+        ErrorString ignored;
+        m_lastRecordedAction->addItem(indexForData(getCanvasContentAsDataURL(ignored)));
 
-    m_bufferUsed += m_actionNeedingSnapshot->memoryCost();
+        m_bufferUsed += m_lastRecordedAction->memoryCost();
+    }
 
-    m_actionNeedingSnapshot = nullptr;
+    m_lastRecordedAction = nullptr;
+    m_contentChanged = false;
 }
 
 int InspectorCanvas::indexForData(DuplicateDataVariant data)
@@ -667,10 +697,15 @@ Ref<JSON::ArrayOf<JSON::Value>> InspectorCanvas::buildAction(const String& name,
             [&] (const WebGLBuffer*) { addParameter(0, RecordingSwizzleTypes::WebGLBuffer); },
             [&] (const WebGLFramebuffer*) { addParameter(0, RecordingSwizzleTypes::WebGLFramebuffer); },
             [&] (const WebGLProgram*) { addParameter(0, RecordingSwizzleTypes::WebGLProgram); },
+            [&] (const WebGLQuery*) { addParameter(0, RecordingSwizzleTypes::WebGLQuery); },
             [&] (const WebGLRenderbuffer*) { addParameter(0, RecordingSwizzleTypes::WebGLRenderbuffer); },
+            [&] (const WebGLSampler*) { addParameter(0, RecordingSwizzleTypes::WebGLSampler); },
             [&] (const WebGLShader*) { addParameter(0, RecordingSwizzleTypes::WebGLShader); },
+            [&] (const WebGLSync*) { addParameter(0, RecordingSwizzleTypes::WebGLSync); },
             [&] (const WebGLTexture*) { addParameter(0, RecordingSwizzleTypes::WebGLTexture); },
+            [&] (const WebGLTransformFeedback*) { addParameter(0, RecordingSwizzleTypes::WebGLTransformFeedback); },
             [&] (const WebGLUniformLocation*) { addParameter(0, RecordingSwizzleTypes::WebGLUniformLocation); },
+            [&] (const WebGLVertexArrayObject*) { addParameter(0, RecordingSwizzleTypes::WebGLVertexArrayObject); },
 #endif
             [&] (const RefPtr<ArrayBuffer>&) { addParameter(0, RecordingSwizzleTypes::TypedArray); },
             [&] (const RefPtr<ArrayBufferView>&) { addParameter(0, RecordingSwizzleTypes::TypedArray); },
@@ -688,11 +723,25 @@ Ref<JSON::ArrayOf<JSON::Value>> InspectorCanvas::buildAction(const String& name,
             [&] (const RefPtr<ImageBitmap>& value) { addParameter(indexForData(value), RecordingSwizzleTypes::ImageBitmap); },
             [&] (const RefPtr<ImageData>& value) { addParameter(indexForData(value), RecordingSwizzleTypes::ImageData); },
             [&] (const RefPtr<Int32Array>&) { addParameter(0, RecordingSwizzleTypes::TypedArray); },
+            [&] (const RefPtr<Uint32Array>&) { addParameter(0, RecordingSwizzleTypes::TypedArray); },
+            [&] (const Vector<String>& value) {
+                auto deduplicated = value.map([&] (const String& item) {
+                    return indexForData(item);
+                });
+                addParameter(buildArrayForVector(deduplicated).ptr(), RecordingSwizzleTypes::Array);
+            },
             [&] (const Vector<float>& value) { addParameter(buildArrayForVector(value).ptr(), RecordingSwizzleTypes::Array); },
-            [&] (const Vector<int>& value) { addParameter(buildArrayForVector(value).ptr(), RecordingSwizzleTypes::Array); },
+            [&] (const Vector<uint32_t>& value) {
+                auto mapped = value.map([&] (uint32_t item) {
+                    return static_cast<double>(item);
+                });
+                addParameter(buildArrayForVector(mapped).ptr(), RecordingSwizzleTypes::Array);
+            },
+            [&] (const Vector<int32_t>& value) { addParameter(buildArrayForVector(value).ptr(), RecordingSwizzleTypes::Array); },
             [&] (const String& value) { addParameter(indexForData(value), RecordingSwizzleTypes::String); },
             [&] (double value) { addParameter(value, RecordingSwizzleTypes::Number); },
             [&] (float value) { addParameter(value, RecordingSwizzleTypes::Number); },
+            [&] (uint64_t value) { addParameter(static_cast<double>(value), RecordingSwizzleTypes::Number); },
             [&] (int64_t value) { addParameter(static_cast<double>(value), RecordingSwizzleTypes::Number); },
             [&] (uint32_t value) { addParameter(static_cast<double>(value), RecordingSwizzleTypes::Number); },
             [&] (int32_t value) { addParameter(value, RecordingSwizzleTypes::Number); },
index 45a43d4..6886e62 100644 (file)
@@ -58,6 +58,8 @@ public:
 
     HTMLCanvasElement* canvasElement();
 
+    void canvasChanged();
+
     void resetRecordingData();
     bool hasRecordingData() const;
     bool currentFrameHasData() const;
@@ -118,7 +120,7 @@ private:
     RefPtr<Inspector::Protocol::Recording::InitialState> m_initialState;
     RefPtr<JSON::ArrayOf<Inspector::Protocol::Recording::Frame>> m_frames;
     RefPtr<JSON::ArrayOf<JSON::Value>> m_currentActions;
-    RefPtr<JSON::ArrayOf<JSON::Value>> m_actionNeedingSnapshot;
+    RefPtr<JSON::ArrayOf<JSON::Value>> m_lastRecordedAction;
     RefPtr<JSON::ArrayOf<JSON::Value>> m_serializedDuplicateData;
     Vector<DuplicateDataVariant> m_indexedDuplicateData;
 
@@ -128,6 +130,7 @@ private:
     size_t m_bufferUsed { 0 };
     Optional<size_t> m_frameCount;
     size_t m_framesCaptured { 0 };
+    bool m_contentChanged { false };
 };
 
 } // namespace WebCore
index dd2e468..2745e84 100644 (file)
@@ -49,6 +49,11 @@ enum class RecordingSwizzleTypes : int {
     WebGLProgram = 17,
     WebGLUniformLocation = 18,
     ImageBitmap = 19,
+    WebGLQuery = 20,
+    WebGLSampler = 21,
+    WebGLSync = 22,
+    WebGLTransformFeedback = 23,
+    WebGLVertexArrayObject = 24,
 };
 
 } // namespace WebCore
index adc2e70..a33b603 100644 (file)
@@ -454,6 +454,20 @@ void InspectorCanvasAgent::recordCanvasAction(CanvasRenderingContext& canvasRend
         didFinishRecordingCanvasFrame(inspectorCanvas->context(), true);
 }
 
+void InspectorCanvasAgent::canvasChanged(CanvasBase& canvasBase, const FloatRect&)
+{
+    auto* context = canvasBase.renderingContext();
+    if (!context)
+        return;
+
+    auto inspectorCanvas = findInspectorCanvas(*context);
+    ASSERT(inspectorCanvas);
+    if (!inspectorCanvas)
+        return;
+
+    inspectorCanvas->canvasChanged();
+}
+
 void InspectorCanvasAgent::canvasDestroyed(CanvasBase& canvasBase)
 {
     auto* context = canvasBase.renderingContext();
@@ -591,6 +605,9 @@ void InspectorCanvasAgent::startRecording(InspectorCanvas& inspectorCanvas, Insp
 #if ENABLE(WEBGL)
         && !is<WebGLRenderingContext>(canvasRenderingContext)
 #endif
+#if ENABLE(WEBGL2)
+        && !is<WebGL2RenderingContext>(canvasRenderingContext)
+#endif
         && !is<ImageBitmapRenderingContext>(canvasRenderingContext))
         return;
 
index 7bc8d87..59a2250 100644 (file)
@@ -99,7 +99,7 @@ public:
 #endif
 
     // CanvasObserver
-    void canvasChanged(CanvasBase&, const FloatRect&) override { }
+    void canvasChanged(CanvasBase&, const FloatRect&) override;
     void canvasResized(CanvasBase&) override { }
     void canvasDestroyed(CanvasBase&) override;
 
index 75fd8ee..d8de7e2 100644 (file)
 #include "WebGLRenderingContext.h"
 #endif
 
+#if ENABLE(WEBGL2)
+#include "JSWebGL2RenderingContext.h"
+#include "WebGL2RenderingContext.h"
+#endif
 
 namespace WebCore {
 using namespace Inspector;
@@ -226,6 +230,10 @@ static CanvasRenderingContext* canvasRenderingContext(JSC::VM& vm, ScriptArgumen
     if (auto* context = JSWebGLRenderingContext::toWrapped(vm, target))
         return context;
 #endif
+#if ENABLE(WEBGL2)
+    if (auto* context = JSWebGL2RenderingContext::toWrapped(vm, target))
+        return context;
+#endif
     return nullptr;
 }
 
index 0461ae8..3af2c0c 100644 (file)
@@ -1,3 +1,41 @@
+2019-05-03  Devin Rousso  <drousso@apple.com>
+
+        Web Inspector: Record actions performed on WebGL2RenderingContext
+        https://bugs.webkit.org/show_bug.cgi?id=176008
+        <rdar://problem/34213884>
+
+        Reviewed by Joseph Pecoraro.
+
+        * UserInterface/Models/Recording.js:
+        (WI.Recording.fromPayload):
+        (WI.Recording.displayNameForSwizzleType):
+        (WI.Recording.prototype.async swizzle):
+        (WI.Recording.prototype.createContext):
+
+        * UserInterface/Models/RecordingAction.js:
+        (WI.RecordingAction.constantNameForParameter):
+        (WI.RecordingAction._prototypeForType):
+        (WI.RecordingAction.prototype.async swizzle):
+        Treat all actions with a snapshot as being a "visible" action.
+
+        * UserInterface/Views/CanvasTabContentView.css:
+        (.content-view.tab.canvas .navigation-bar > .item .canvas:matches(.webgl, .webgl2, .webgpu, .webmetal) .icon): Added.
+        (.content-view.tab.canvas .navigation-bar > .item .canvas.webgl): Deleted.
+        * UserInterface/Views/CanvasContentView.js:
+        (WI.CanvasContentView.prototype.initialLayout):
+        * UserInterface/Views/CanvasSidebarPanel.js:
+        (WI.CanvasSidebarPanel.prototype.shown):
+        (WI.CanvasSidebarPanel.prototype._canvasChanged):
+        (WI.CanvasSidebarPanel.prototype._updateRecordNavigationItem):
+
+        * UserInterface/Views/RecordingContentView.js:
+        (WI.RecordingContentView):
+        (WI.RecordingContentView.prototype.get navigationItems):
+        (WI.RecordingContentView.prototype.shown):
+        (WI.RecordingContentView.prototype.initialLayout):
+        * UserInterface/Views/RecordingActionTreeElement.js:
+        (WI.RecordingActionTreeElement._generateDOM.createParameterElement):
+
 2019-05-02  Nikita Vasilyev  <nvasilyev@apple.com>
 
         Web Inspector: Dark Mode: borders between section should be lighter than background
index 467f42d..c9b7434 100644 (file)
@@ -77,6 +77,9 @@ WI.Recording = class Recording extends WI.Object
         case RecordingAgent.Type.CanvasWebGL:
             type = WI.Recording.Type.CanvasWebGL;
             break;
+        case RecordingAgent.Type.CanvasWebGL2:
+            type = WI.Recording.Type.CanvasWebGL2;
+            break;
         default:
             WI.Recording.synthesizeWarning(WI.UIString("unknown %s \u0022%s\u0022").format(WI.unlocalizedString("type"), payload.type));
             type = String(payload.type);
@@ -188,6 +191,16 @@ WI.Recording = class Recording extends WI.Object
             return WI.unlocalizedString("WebGLUniformLocation");
         case WI.Recording.Swizzle.ImageBitmap:
             return WI.unlocalizedString("ImageBitmap");
+        case WI.Recording.Swizzle.WebGLQuery:
+            return WI.unlocalizedString("WebGLQuery");
+        case WI.Recording.Swizzle.WebGLSampler:
+            return WI.unlocalizedString("WebGLSampler");
+        case WI.Recording.Swizzle.WebGLSync:
+            return WI.unlocalizedString("WebGLSync");
+        case WI.Recording.Swizzle.WebGLTransformFeedback:
+            return WI.unlocalizedString("WebGLTransformFeedback");
+        case WI.Recording.Swizzle.WebGLVertexArrayObject:
+            return WI.unlocalizedString("WebGLVertexArrayObject");
         default:
             console.error("Unknown swizzle type", swizzleType);
             return null;
@@ -321,7 +334,12 @@ WI.Recording = class Recording extends WI.Object
             || type === WI.Recording.Swizzle.WebGLTexture
             || type === WI.Recording.Swizzle.WebGLShader
             || type === WI.Recording.Swizzle.WebGLProgram
-            || type === WI.Recording.Swizzle.WebGLUniformLocation) {
+            || type === WI.Recording.Swizzle.WebGLUniformLocation
+            || type === WI.Recording.Swizzle.WebGLQuery
+            || type === WI.Recording.Swizzle.WebGLSampler
+            || type === WI.Recording.Swizzle.WebGLSync
+            || type === WI.Recording.Swizzle.WebGLTransformFeedback
+            || type === WI.Recording.Swizzle.WebGLVertexArrayObject) {
             return index;
         }
 
@@ -457,6 +475,9 @@ WI.Recording = class Recording extends WI.Object
         if (this._type === WI.Recording.Type.CanvasWebGL)
             return createCanvasContext("webgl");
 
+        if (this._type === WI.Recording.Type.CanvasWebGL2)
+            return createCanvasContext("webgl2");
+
         console.error("Unknown recording type", this._type);
         return null;
     }
@@ -854,6 +875,7 @@ WI.Recording.Type = {
     Canvas2D: "canvas-2d",
     CanvasBitmapRenderer: "canvas-bitmaprenderer",
     CanvasWebGL: "canvas-webgl",
+    CanvasWebGL2: "canvas-webgl2",
 };
 
 // Keep this in sync with WebCore::RecordingSwizzleTypes.
@@ -878,6 +900,11 @@ WI.Recording.Swizzle = {
     WebGLProgram: 17,
     WebGLUniformLocation: 18,
     ImageBitmap: 19,
+    WebGLQuery: 20,
+    WebGLSampler: 21,
+    WebGLSync: 22,
+    WebGLTransformFeedback: 23,
+    WebGLVertexArrayObject: 24,
 
     // Special frontend-only swizzle types.
     CallStack: Symbol("CallStack"),
index 738bb28..f31cd33 100644 (file)
@@ -137,7 +137,7 @@ WI.RecordingAction = class RecordingAction extends WI.Object
                 return null;
         }
 
-        if (value === 0 && type === WI.Recording.Type.CanvasWebGL) {
+        if (value === 0 && (type === WI.Recording.Type.CanvasWebGL || type === WI.Recording.Type.CanvasWebGL2)) {
             if (name === "blendFunc" || name === "blendFuncSeparate")
                 return "ZERO";
             if (index === 0) {
@@ -149,10 +149,12 @@ WI.RecordingAction = class RecordingAction extends WI.Object
         }
 
         let prototype = WI.RecordingAction._prototypeForType(type);
-        for (let key in prototype) {
-            let descriptor = Object.getOwnPropertyDescriptor(prototype, key);
-            if (descriptor && descriptor.value === value)
-                return key;
+        if (prototype) {
+            for (let key in prototype) {
+                let descriptor = Object.getOwnPropertyDescriptor(prototype, key);
+                if (descriptor && descriptor.value === value)
+                    return key;
+            }
         }
 
         return null;
@@ -171,6 +173,10 @@ WI.RecordingAction = class RecordingAction extends WI.Object
             if (window.WebGLRenderingContext)
                 return WebGLRenderingContext.prototype;
             break;
+        case WI.Recording.Type.CanvasWebGL2:
+            if (window.WebGL2RenderingContext)
+                return WebGL2RenderingContext.prototype;
+            break;
         }
 
         WI.reportInternalError("Unknown recording type: " + type);
@@ -205,7 +211,7 @@ WI.RecordingAction = class RecordingAction extends WI.Object
 
         this._processed = true;
 
-        if (recording.type === WI.Recording.Type.CanvasWebGL) {
+        if (recording.type === WI.Recording.Type.CanvasWebGL || recording.type === WI.Recording.Type.CanvasWebGL2) {
             // We add each RecordingAction to the list of visualActionIndexes after it is processed.
             if (this._valid && this._isVisual) {
                 let contentBefore = recording.visualActionIndexes.length ? recording.actions[recording.visualActionIndexes.lastValue].snapshot : recording.initialState.content;
@@ -315,7 +321,7 @@ WI.RecordingAction = class RecordingAction extends WI.Object
         if (this._payloadSnapshot >= 0)
             this._snapshot = snapshot;
 
-        if (recording.type === WI.Recording.Type.Canvas2D || recording.type === WI.Recording.Type.CanvasBitmapRenderer || recording.type === WI.Recording.Type.CanvasWebGL) {
+        if (recording.type === WI.Recording.Type.Canvas2D || recording.type === WI.Recording.Type.CanvasBitmapRenderer || recording.type === WI.Recording.Type.CanvasWebGL || recording.type === WI.Recording.Type.CanvasWebGL2) {
             if (this._name === "width" || this._name === "height") {
                 this._contextReplacer = "canvas";
                 this._isFunction = false;
@@ -330,8 +336,12 @@ WI.RecordingAction = class RecordingAction extends WI.Object
             this._isFunction = WI.RecordingAction.isFunctionForType(recording.type, this._name);
             this._isGetter = !this._isFunction && !this._parameters.length;
 
-            let visualNames = WI.RecordingAction._visualNames[recording.type];
-            this._isVisual = visualNames ? visualNames.has(this._name) : false;
+            if (this._snapshot)
+                this._isVisual = true;
+            else {
+                let visualNames = WI.RecordingAction._visualNames[recording.type];
+                this._isVisual = visualNames ? visualNames.has(this._name) : false;
+            }
 
             if (this._valid) {
                 let prototype = WI.RecordingAction._prototypeForType(recording.type);
@@ -530,6 +540,113 @@ WI.RecordingAction._constantIndexes = {
         },
         "vertexAttribPointer": [2],
     },
+    [WI.Recording.Type.CanvasWebGL2]: {
+        "activeTexture": true,
+        "beginQuery": [0],
+        "beginTransformFeedback": true,
+        "bindBuffer": true,
+        "bindBufferBase": [0],
+        "bindBufferRange": [0],
+        "bindFramebuffer": true,
+        "bindRenderbuffer": true,
+        "bindTexture": true,
+        "bindTransformFeedback": [0],
+        "blendEquation": true,
+        "blendEquationSeparate": true,
+        "blendFunc": true,
+        "blendFuncSeparate": true,
+        "blitFramebuffer": [10],
+        "bufferData": [0, 2],
+        "bufferSubData": [0],
+        "checkFramebufferStatus": true,
+        "clearBufferfi": [0],
+        "clearBufferfv": [0],
+        "clearBufferiv": [0],
+        "clearBufferuiv": [0],
+        "compressedTexImage2D": [0, 2],
+        "compressedTexSubImage2D": [0],
+        "compressedTexSubImage3D": [0],
+        "copyBufferSubData": [0, 1],
+        "copyTexImage2D": [0, 2],
+        "copyTexSubImage2D": [0],
+        "copyTexSubImage3D": [0],
+        "createShader": true,
+        "cullFace": true,
+        "depthFunc": true,
+        "disable": true,
+        "drawArrays": [0],
+        "drawArraysInstanced": [0],
+        "drawBuffers": true,
+        "drawElements": [0, 2],
+        "drawElementsInstanced": [0, 2],
+        "drawRangeElements": [0, 4],
+        "enable": true,
+        "endQuery": true,
+        "fenceSync": [0],
+        "framebufferRenderbuffer": true,
+        "framebufferTexture2D": [0, 1, 2],
+        "framebufferTextureLayer": [0, 1],
+        "frontFace": true,
+        "generateMipmap": true,
+        "getActiveUniformBlockParameter": [2],
+        "getActiveUniforms": [2],
+        "getBufferParameter": true,
+        "getBufferSubData": [0],
+        "getFramebufferAttachmentParameter": true,
+        "getIndexedParameter": [0],
+        "getInternalformatParameter": true,
+        "getParameter": true,
+        "getProgramParameter": true,
+        "getQuery": true,
+        "getQueryParameter": [1],
+        "getRenderbufferParameter": true,
+        "getSamplerParameter": [1],
+        "getShaderParameter": true,
+        "getShaderPrecisionFormat": true,
+        "getSyncParameter": [1],
+        "getTexParameter": true,
+        "getVertexAttrib": [1],
+        "getVertexAttribOffset": [1],
+        "hint": true,
+        "invalidateFramebuffer": [0, 1],
+        "invalidateSubFramebuffer": [0, 1],
+        "isEnabled": true,
+        "pixelStorei": [0],
+        "readBuffer": true,
+        "readPixels": [4, 5],
+        "renderbufferStorage": [0, 1],
+        "renderbufferStorageMultisample": [0, 2],
+        "samplerParameterf": [1],
+        "samplerParameteri": [1],
+        "stencilFunc": [0],
+        "stencilFuncSeparate": [0, 1],
+        "stencilMaskSeparate": [0],
+        "stencilOp": true,
+        "stencilOpSeparate": true,
+        "texImage2D": {
+            5: [0, 2, 3, 4],
+            6: [0, 2, 3, 4],
+            8: [0, 2, 6, 7],
+            9: [0, 2, 6, 7],
+            10: [0, 2, 6, 7],
+            11: [0, 2, 7, 8],
+        },
+        "texParameterf": [0, 1],
+        "texParameteri": [0, 1],
+        "texStorage2D":[0, 2],
+        "texSubImage2D": {
+            6: [0, 4, 5],
+            7: [0, 4, 5],
+            8: [0, 6, 7],
+            9: [0, 6, 7],
+            10: [0, 6, 7],
+            11: [0, 8, 9],
+            12: [0, 8, 9],
+        },
+        "transformFeedbackVaryings": [2],
+        "vertexAttribIPointer": [2],
+        "vertexAttribPointer": [2],
+    },
 };
 
 WI.RecordingAction._visualNames = {
@@ -554,6 +671,13 @@ WI.RecordingAction._visualNames = {
         "drawArrays",
         "drawElements",
     ]),
+    [WI.Recording.Type.CanvasWebGL2]: new Set([
+        "clear",
+        "drawArrays",
+        "drawArraysInstanced",
+        "drawElements",
+        "drawElementsInstanced",
+    ]),
 };
 
 WI.RecordingAction._stateModifiers = {
index 004762c..8068840 100644 (file)
@@ -102,7 +102,7 @@ WI.CanvasContentView = class CanvasContentView extends WI.ContentView
 
             let navigationBar = new WI.NavigationBar;
 
-            if (this.representedObject.contextType === WI.Canvas.ContextType.Canvas2D || this.representedObject.contextType === WI.Canvas.ContextType.BitmapRenderer || this.representedObject.contextType === WI.Canvas.ContextType.WebGL) {
+            if (this.representedObject.contextType === WI.Canvas.ContextType.Canvas2D || this.representedObject.contextType === WI.Canvas.ContextType.BitmapRenderer || this.representedObject.contextType === WI.Canvas.ContextType.WebGL || this.representedObject.contextType === WI.Canvas.ContextType.WebGL2) {
                 const toolTip = WI.UIString("Start recording canvas actions.\nShift-click to record a single frame.");
                 const altToolTip = WI.UIString("Stop recording canvas actions");
                 this._recordButtonNavigationItem = new WI.ToggleButtonNavigationItem("record-start-stop", toolTip, altToolTip, "Images/Record.svg", "Images/Stop.svg", 13, 13);
index 00bc817..c294e22 100644 (file)
@@ -210,6 +210,18 @@ WI.CanvasSidebarPanel = class CanvasSidebarPanel extends WI.NavigationSidebarPan
 
         this.contentBrowser.addEventListener(WI.ContentBrowser.Event.CurrentRepresentedObjectsDidChange, this.updateRepresentedObjects, this);
         this.updateRepresentedObjects();
+
+        if (this._recording) {
+            this._recordingTreeOutline.updateVirtualizedElementsDebouncer.force();
+
+            let action = this._recording[WI.CanvasSidebarPanel.SelectedActionSymbol];
+            let treeElement = this._recordingTreeOutline.findTreeElement(action);
+            if (treeElement) {
+                const omitFocus = false;
+                const selectedByUser = false;
+                treeElement.revealAndSelect(omitFocus, selectedByUser);
+            }
+        }
     }
 
     hidden()
@@ -361,7 +373,7 @@ WI.CanvasSidebarPanel = class CanvasSidebarPanel extends WI.NavigationSidebarPan
         const selectedByUser = false;
         canvasTreeElement.revealAndSelect(omitFocus, selectedByUser);
 
-        if (WI.Canvas.ContextType.Canvas2D || this._canvas.contextType === WI.Canvas.ContextType.WebGL)
+        if (WI.Canvas.ContextType.Canvas2D || this._canvas.contextType === WI.Canvas.ContextType.WebGL || this._canvas.contextType === WI.Canvas.ContextType.WebGL2)
             this._recordButtonNavigationItem.enabled = true;
 
         this.recording = null;
@@ -460,7 +472,7 @@ WI.CanvasSidebarPanel = class CanvasSidebarPanel extends WI.NavigationSidebarPan
 
     _updateRecordNavigationItem()
     {
-        if (!this._canvas || !(this._canvas.contextType === WI.Canvas.ContextType.Canvas2D || this._canvas.contextType === WI.Canvas.ContextType.WebGL)) {
+        if (!this._canvas || !(this._canvas.contextType === WI.Canvas.ContextType.Canvas2D || this._canvas.contextType === WI.Canvas.ContextType.WebGL || this._canvas.contextType === WI.Canvas.ContextType.WebGL2)) {
             this._recordButtonNavigationItem.enabled = false;
             return;
         }
index a6a4125..6bae457 100644 (file)
@@ -31,7 +31,7 @@
     content: url(../Images/Canvas2D.svg);
 }
 
-.content-view.tab.canvas .navigation-bar > .item .canvas.webgl .icon {
+.content-view.tab.canvas .navigation-bar > .item .canvas:matches(.webgl, .webgl2, .webgpu, .webmetal) .icon {
     content: url(../Images/Canvas3D.svg);
 }
 
@@ -48,8 +48,7 @@
         filter: invert(88%);
     }
 
-    .content-view.tab.canvas .navigation-bar > .item .canvas.canvas-2d .icon,
-    .content-view.tab.canvas .navigation-bar > .item .canvas.webgl .icon,
+    .content-view.tab.canvas .navigation-bar > .item .canvas .icon,
     .content-view.tab.canvas .navigation-bar > .item .recording > .icon {
         filter: invert();
     }
index 8ec1829..c677ea4 100644 (file)
@@ -90,6 +90,11 @@ WI.RecordingActionTreeElement = class RecordingActionTreeElement extends WI.Gene
             case WI.Recording.Swizzle.WebGLShader:
             case WI.Recording.Swizzle.WebGLProgram:
             case WI.Recording.Swizzle.WebGLUniformLocation:
+            case WI.Recording.Swizzle.WebGLQuery:
+            case WI.Recording.Swizzle.WebGLSampler:
+            case WI.Recording.Swizzle.WebGLSync:
+            case WI.Recording.Swizzle.WebGLTransformFeedback:
+            case WI.Recording.Swizzle.WebGLVertexArrayObject:
                 parameterElement.classList.add("swizzled");
                 parameterElement.textContent = WI.Recording.displayNameForSwizzleType(swizzleType);
                 break;
index 7805268..41e8803 100644 (file)
@@ -31,23 +31,25 @@ WI.RecordingContentView = class RecordingContentView extends WI.ContentView
 
         super(representedObject);
 
+        let isCanvas2D = this.representedObject.type === WI.Recording.Type.Canvas2D;
+        let isCanvasBitmapRenderer = this.representedObject.type === WI.Recording.Type.CanvasBitmapRenderer;
+        let isCanvasWebGL = this.representedObject.type === WI.Recording.Type.CanvasWebGL;
+        let isCanvasWebGL2 = this.representedObject.type === WI.Recording.Type.CanvasWebGL2;
+
         this._index = NaN;
         this._action = null;
         this._snapshots = [];
         this._initialContent = null;
         this._generateContentThrottler = new Throttler(() => {
-            if (this.representedObject.type === WI.Recording.Type.Canvas2D)
+            if (isCanvas2D)
                 this._generateContentCanvas2D(this._index);
-            else if (this.representedObject.type === WI.Recording.Type.CanvasBitmapRenderer || this.representedObject.type === WI.Recording.Type.CanvasWebGL)
+            else if (isCanvasBitmapRenderer || isCanvasWebGL || isCanvasWebGL2)
                 this._generateContentFromSnapshot(this._index);
         }, 200);
 
         this.element.classList.add("recording", this.representedObject.type);
 
-        let isCanvas2D = this.representedObject.type === WI.Recording.Type.Canvas2D;
-        let isCanvasBitmapRenderer = this.representedObject.type === WI.Recording.Type.CanvasBitmapRenderer;
-        let isCanvasWebGL = this.representedObject.type === WI.Recording.Type.CanvasWebGL;
-        if (isCanvas2D || isCanvasBitmapRenderer || isCanvasWebGL) {
+        if (isCanvas2D || isCanvasBitmapRenderer || isCanvasWebGL || isCanvasWebGL2) {
             if (isCanvas2D && WI.ImageUtilities.supportsCanvasPathDebugging()) {
                 this._pathContext = null;
 
@@ -76,7 +78,8 @@ WI.RecordingContentView = class RecordingContentView extends WI.ContentView
         let isCanvas2D = this.representedObject.type === WI.Recording.Type.Canvas2D;
         let isCanvasBitmapRenderer = this.representedObject.type === WI.Recording.Type.CanvasBitmapRenderer;
         let isCanvasWebGL = this.representedObject.type === WI.Recording.Type.CanvasWebGL;
-        if (!isCanvas2D && !isCanvasBitmapRenderer && !isCanvasWebGL)
+        let isCanvasWebGL2 = this.representedObject.type === WI.Recording.Type.CanvasWebGL2;
+        if (!isCanvas2D && !isCanvasBitmapRenderer && !isCanvasWebGL && !isCanvasWebGL2)
             return [];
 
         let navigationItems = [this._exportButtonNavigationItem, new WI.DividerNavigationItem];
@@ -122,7 +125,8 @@ WI.RecordingContentView = class RecordingContentView extends WI.ContentView
         let isCanvas2D = this.representedObject.type === WI.Recording.Type.Canvas2D;
         let isCanvasBitmapRenderer = this.representedObject.type === WI.Recording.Type.CanvasBitmapRenderer;
         let isCanvasWebGL = this.representedObject.type === WI.Recording.Type.CanvasWebGL;
-        if (isCanvas2D || isCanvasBitmapRenderer || isCanvasWebGL) {
+        let isCanvasWebGL2 = this.representedObject.type === WI.Recording.Type.CanvasWebGL2;
+        if (isCanvas2D || isCanvasBitmapRenderer || isCanvasWebGL || isCanvasWebGL2) {
             if (isCanvas2D)
                 this._updateCanvasPath();
             this._updateImageGrid();
@@ -173,6 +177,8 @@ WI.RecordingContentView = class RecordingContentView extends WI.ContentView
             if (!this.representedObject.processing)
                 this.representedObject.startProcessing();
         }
+
+        this._updateSliderValue();
     }
 
     // Private