Web Inspector: Instrument WebGLProgram created/deleted
authormattbaker@apple.com <mattbaker@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 3 Aug 2017 22:31:44 +0000 (22:31 +0000)
committermattbaker@apple.com <mattbaker@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 3 Aug 2017 22:31:44 +0000 (22:31 +0000)
https://bugs.webkit.org/show_bug.cgi?id=175059

Reviewed by Devin Rousso.

Source/JavaScriptCore:

Extend the Canvas protocol with types/events for tracking WebGLPrograms.

* inspector/protocol/Canvas.json:

Source/WebCore:

Tests: inspector/canvas/shaderProgram-add-remove-webgl.html
       inspector/canvas/shaderProgram-add-remove-webgl2.html

This patch adds instrumentation to WebGLRenderingContextBase for tracking
WebGLPrograms. A new helper class, InspectorShaderProgram, is used by
the CanvasAgent to hold related data.

* CMakeLists.txt:
* WebCore.xcodeproj/project.pbxproj:

* html/canvas/WebGLRenderingContextBase.cpp:
(WebCore::WebGLRenderingContextBase::createProgram):
(WebCore::WebGLRenderingContextBase::deleteProgram):

* inspector/InspectorCanvasAgent.cpp:
(WebCore::InspectorCanvasAgent::enable):
(WebCore::InspectorCanvasAgent::frameNavigated):
(WebCore::InspectorCanvasAgent::didCreateProgram):
(WebCore::InspectorCanvasAgent::willDeleteProgram):
(WebCore::InspectorCanvasAgent::clearCanvasData):
(WebCore::InspectorCanvasAgent::unbindCanvas):
(WebCore::InspectorCanvasAgent::unbindProgram):
(WebCore::InspectorCanvasAgent::assertInspectorProgram):
(WebCore::InspectorCanvasAgent::findInspectorProgram):
* inspector/InspectorCanvasAgent.h:

* inspector/InspectorInstrumentation.cpp:
(WebCore::InspectorInstrumentation::didCreateCSSCanvasImpl):
(WebCore::InspectorInstrumentation::didChangeCSSCanvasClientNodesImpl):
(WebCore::InspectorInstrumentation::didCreateCanvasRenderingContextImpl):
(WebCore::InspectorInstrumentation::didChangeCanvasMemoryImpl):
(WebCore::InspectorInstrumentation::recordCanvasActionImpl):
(WebCore::InspectorInstrumentation::didFinishRecordingCanvasFrameImpl):
(WebCore::InspectorInstrumentation::didCreateProgramImpl):
(WebCore::InspectorInstrumentation::willDeleteProgramImpl):

* inspector/InspectorInstrumentation.h:
(WebCore::InspectorInstrumentation::recordCanvasActionImpl):
(WebCore::InspectorInstrumentation::didCreateCSSCanvas):
(WebCore::InspectorInstrumentation::didChangeCSSCanvasClientNodes):
(WebCore::InspectorInstrumentation::didCreateCanvasRenderingContext):
(WebCore::InspectorInstrumentation::didChangeCanvasMemory):
(WebCore::InspectorInstrumentation::recordCanvasAction):
(WebCore::InspectorInstrumentation::didFinishRecordingCanvasFrame):
(WebCore::InspectorInstrumentation::didCreateProgram):
(WebCore::InspectorInstrumentation::willDeleteProgram):

* inspector/InspectorShaderProgram.cpp: Added.
(WebCore::InspectorShaderProgram::create):
(WebCore::InspectorShaderProgram::InspectorShaderProgram):
(WebCore::InspectorShaderProgram::context const):
* inspector/InspectorShaderProgram.h: Added.

Source/WebInspectorUI:

This patch adds frontend support for shader program instrumentation.
The frontend creates a ShaderProgram model object for each WebGLProgram.
Since only canvases with a WebGL context have programs, the Canvas model
object does not contain any logic specific to programs. CanvasManager
dispatches program added/removed events, and the parent Canvas can be
accessed from ShaderProgram but not the other way around.

* UserInterface/Controllers/CanvasManager.js:
(WI.CanvasManager):
(WI.CanvasManager.prototype.get shaderPrograms):
(WI.CanvasManager.prototype.canvasRemoved):
(WI.CanvasManager.prototype.programCreated):
(WI.CanvasManager.prototype.programDeleted):
(WI.CanvasManager.prototype._mainResourceDidChange):
(WI.CanvasManager.prototype._dispatchShaderProgramRemoved):

* UserInterface/Main.html:

* UserInterface/Models/Canvas.js:
(WI.Canvas.prototype.nextShaderProgramDisplayNumber):
(WI.Canvas):

* UserInterface/Models/ShaderProgram.js: Added.
(WI.ShaderProgram):
(WI.ShaderProgram.prototype.get identifier):
(WI.ShaderProgram.prototype.get canvas):
(WI.ShaderProgram.prototype.get displayName):

* UserInterface/Protocol/CanvasObserver.js:
(WI.CanvasObserver.prototype.programCreated):
(WI.CanvasObserver.prototype.programDeleted):
(WI.CanvasObserver):

* UserInterface/Test.html:

LayoutTests:

Add tests for CanvasManager shader program events and ShaderProgram model object.
WebGL and WebGL2 contexts are tested separately based on platform support.

* inspector/canvas/resources/shaderProgram-utilities.js: Added.
(createProgram):
(deleteProgram):
(deleteContext):
(TestPage.registerInitializer.awaitProgramAdded):
(TestPage.registerInitializer):
(TestPage.registerInitializer.window.initializeTestSuite):
(TestPage.registerInitializer.window.addSimpleTestCase):
(TestPage.registerInitializer.window.addParentCanvasRemovedTestCase):

* inspector/canvas/shaderProgram-add-remove-webgl-expected.txt: Added.
* inspector/canvas/shaderProgram-add-remove-webgl.html: Added.
* inspector/canvas/shaderProgram-add-remove-webgl2-expected.txt: Added.
* inspector/canvas/shaderProgram-add-remove-webgl2.html: Added.

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

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

28 files changed:
LayoutTests/ChangeLog
LayoutTests/inspector/canvas/resources/shaderProgram-utilities.js [new file with mode: 0644]
LayoutTests/inspector/canvas/shaderProgram-add-remove-webgl-expected.txt [new file with mode: 0644]
LayoutTests/inspector/canvas/shaderProgram-add-remove-webgl.html [new file with mode: 0644]
LayoutTests/inspector/canvas/shaderProgram-add-remove-webgl2-expected.txt [new file with mode: 0644]
LayoutTests/inspector/canvas/shaderProgram-add-remove-webgl2.html [new file with mode: 0644]
LayoutTests/platform/gtk/TestExpectations
LayoutTests/platform/mac/TestExpectations
LayoutTests/platform/win/TestExpectations
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/inspector/protocol/Canvas.json
Source/WebCore/CMakeLists.txt
Source/WebCore/ChangeLog
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp
Source/WebCore/inspector/InspectorCanvasAgent.cpp
Source/WebCore/inspector/InspectorCanvasAgent.h
Source/WebCore/inspector/InspectorInstrumentation.cpp
Source/WebCore/inspector/InspectorInstrumentation.h
Source/WebCore/inspector/InspectorShaderProgram.cpp [new file with mode: 0644]
Source/WebCore/inspector/InspectorShaderProgram.h [new file with mode: 0644]
Source/WebInspectorUI/ChangeLog
Source/WebInspectorUI/UserInterface/Controllers/CanvasManager.js
Source/WebInspectorUI/UserInterface/Main.html
Source/WebInspectorUI/UserInterface/Models/Canvas.js
Source/WebInspectorUI/UserInterface/Models/ShaderProgram.js [new file with mode: 0644]
Source/WebInspectorUI/UserInterface/Protocol/CanvasObserver.js
Source/WebInspectorUI/UserInterface/Test.html

index c6e5068..03bb572 100644 (file)
@@ -1,3 +1,32 @@
+2017-08-03  Matt Baker  <mattbaker@apple.com>
+
+        Web Inspector: Instrument WebGLProgram created/deleted
+        https://bugs.webkit.org/show_bug.cgi?id=175059
+
+        Reviewed by Devin Rousso.
+
+        Add tests for CanvasManager shader program events and ShaderProgram model object.
+        WebGL and WebGL2 contexts are tested separately based on platform support.
+
+        * inspector/canvas/resources/shaderProgram-utilities.js: Added.
+        (createProgram):
+        (deleteProgram):
+        (deleteContext):
+        (TestPage.registerInitializer.awaitProgramAdded):
+        (TestPage.registerInitializer):
+        (TestPage.registerInitializer.window.initializeTestSuite):
+        (TestPage.registerInitializer.window.addSimpleTestCase):
+        (TestPage.registerInitializer.window.addParentCanvasRemovedTestCase):
+
+        * inspector/canvas/shaderProgram-add-remove-webgl-expected.txt: Added.
+        * inspector/canvas/shaderProgram-add-remove-webgl.html: Added.
+        * inspector/canvas/shaderProgram-add-remove-webgl2-expected.txt: Added.
+        * inspector/canvas/shaderProgram-add-remove-webgl2.html: Added.
+
+        * platform/gtk/TestExpectations:
+        * platform/mac/TestExpectations:
+        * platform/win/TestExpectations:
+
 2017-08-03  Youenn Fablet  <youenn@apple.com>
 
         Import WPT service worker tests
diff --git a/LayoutTests/inspector/canvas/resources/shaderProgram-utilities.js b/LayoutTests/inspector/canvas/resources/shaderProgram-utilities.js
new file mode 100644 (file)
index 0000000..b5ae46f
--- /dev/null
@@ -0,0 +1,102 @@
+let context;
+let program;
+
+function createProgram(contextType) {
+    context = document.createElement("canvas").getContext(contextType);
+    program = context.createProgram();
+}
+
+function deleteProgram() {
+    context.deleteProgram(program);
+    program = null;
+}
+
+function deleteContext() {
+    context = null;
+    // Force GC to make sure the canvas element is destroyed, otherwise the frontend
+    // does not receive WI.CanvasManager.Event.CanvasWasRemoved events.
+    setTimeout(() => { GCController.collect(); }, 0);
+}
+
+TestPage.registerInitializer(() => {
+    let suite = null;
+
+    function awaitProgramAdded() {
+        return WI.canvasManager.awaitEvent(WI.CanvasManager.Event.ShaderProgramAdded)
+        .then((event) => {
+            let program = event.data.program;
+            InspectorTest.expectThat(program instanceof WI.ShaderProgram, "Added ShaderProgram.");
+            InspectorTest.expectThat(program.canvas instanceof WI.Canvas, "ShaderProgram should have a parent Canvas.");
+            return program;
+        });
+    }
+
+    function awaitProgramRemoved() {
+        return WI.canvasManager.awaitEvent(WI.CanvasManager.Event.ShaderProgramRemoved)
+        .then((event) => {
+            let program = event.data.program;
+            InspectorTest.expectThat(program instanceof WI.ShaderProgram, "Removed ShaderProgram.");
+            InspectorTest.expectThat(program.canvas instanceof WI.Canvas, "ShaderProgram should have a parent Canvas.");
+            return program;
+        });
+    }
+
+    window.initializeTestSuite = function(contextType) {
+        suite = InspectorTest.createAsyncSuite(`Canvas.ShaderProgram.${contextType}`);
+
+        suite.addTestCase({
+            name: `${suite.name}.reloadPage`,
+            description: "Check that ShaderProgramAdded is sent for a program created before CanvasAgent is enabled.",
+            test(resolve, reject) {
+                awaitProgramAdded().then(resolve, reject);
+
+                InspectorTest.reloadPage();
+            }
+        });
+
+        return suite;
+    }
+
+     window.addSimpleTestCase = function(contextType) {
+        suite.addTestCase({
+            name: `${suite.name}.ShaderProgramAdded`,
+            description: "Check that added/removed events are sent.",
+            test(resolve, reject) {
+                awaitProgramAdded()
+                .then((addedProgram) => {
+                    awaitProgramRemoved()
+                    .then((removedProgram) => {
+                        InspectorTest.expectEqual(removedProgram, addedProgram, "Removed the previously added ShaderProgram.");
+                    })
+                    .then(resolve, reject);
+
+                    InspectorTest.evaluateInPage(`deleteProgram()`);
+                });
+
+                InspectorTest.evaluateInPage(`createProgram("${contextType}")`);
+            }
+        });
+    }
+
+    window.addParentCanvasRemovedTestCase = function(contextType) {
+        suite.addTestCase({
+            name: `${suite.name}.ParentCanvasRemoved`,
+            description: "Check that the ShaderProgram is removed before it's parent Canvas.",
+            test(resolve, reject) {
+                Promise.race([
+                    awaitProgramRemoved()
+                    .then(() => {
+                        InspectorTest.pass("Removed ShaderProgram before Canvas.");
+                        resolve();
+                    }),
+                    WI.canvasManager.awaitEvent(WI.CanvasManager.Event.CanvasWasRemoved)
+                    .then(reject)
+                ])
+                .catch(() => { InspectorTest.fail("Removed Canvas before ShaderProgram."); });
+
+                InspectorTest.evaluateInPage(`createProgram("${contextType}")`);
+                InspectorTest.evaluateInPage(`deleteContext()`);
+            }
+        });
+    }
+});
diff --git a/LayoutTests/inspector/canvas/shaderProgram-add-remove-webgl-expected.txt b/LayoutTests/inspector/canvas/shaderProgram-add-remove-webgl-expected.txt
new file mode 100644 (file)
index 0000000..cdeb985
--- /dev/null
@@ -0,0 +1,20 @@
+Test that CanvasManager tracks creation and destruction of WebGL shader programs.
+
+
+== Running test suite: Canvas.ShaderProgram.webgl
+-- Running test case: Canvas.ShaderProgram.webgl.reloadPage
+PASS: Added ShaderProgram.
+PASS: ShaderProgram should have a parent Canvas.
+
+-- Running test case: Canvas.ShaderProgram.webgl.ShaderProgramAdded
+PASS: Added ShaderProgram.
+PASS: ShaderProgram should have a parent Canvas.
+PASS: Removed ShaderProgram.
+PASS: ShaderProgram should have a parent Canvas.
+PASS: Removed the previously added ShaderProgram.
+
+-- Running test case: Canvas.ShaderProgram.webgl.ParentCanvasRemoved
+PASS: Removed ShaderProgram.
+PASS: ShaderProgram should have a parent Canvas.
+PASS: Removed ShaderProgram before Canvas.
+
diff --git a/LayoutTests/inspector/canvas/shaderProgram-add-remove-webgl.html b/LayoutTests/inspector/canvas/shaderProgram-add-remove-webgl.html
new file mode 100644 (file)
index 0000000..2ce79f2
--- /dev/null
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../../http/tests/inspector/resources/inspector-test.js"></script>
+<script src="resources/shaderProgram-utilities.js"></script>
+<script>
+function test() {
+    let suite = initializeTestSuite("webgl");
+
+    addSimpleTestCase("webgl");
+    addParentCanvasRemovedTestCase("webgl");
+
+    suite.runTestCasesAndFinish();
+}
+</script>
+</head>
+<body onload="runTest()">
+    <p>Test that CanvasManager tracks creation and destruction of WebGL shader programs.</p>
+</body>
+<script>
+    createProgram("webgl");
+</script>
+</html>
diff --git a/LayoutTests/inspector/canvas/shaderProgram-add-remove-webgl2-expected.txt b/LayoutTests/inspector/canvas/shaderProgram-add-remove-webgl2-expected.txt
new file mode 100644 (file)
index 0000000..4b9d291
--- /dev/null
@@ -0,0 +1,20 @@
+Test that CanvasManager tracks creation and destruction of WebGL2 shader programs.
+
+
+== Running test suite: Canvas.ShaderProgram.webgl2
+-- Running test case: Canvas.ShaderProgram.webgl2.reloadPage
+PASS: Added ShaderProgram.
+PASS: ShaderProgram should have a parent Canvas.
+
+-- Running test case: Canvas.ShaderProgram.webgl2.ShaderProgramAdded
+PASS: Added ShaderProgram.
+PASS: ShaderProgram should have a parent Canvas.
+PASS: Removed ShaderProgram.
+PASS: ShaderProgram should have a parent Canvas.
+PASS: Removed the previously added ShaderProgram.
+
+-- Running test case: Canvas.ShaderProgram.webgl2.ParentCanvasRemoved
+PASS: Removed ShaderProgram.
+PASS: ShaderProgram should have a parent Canvas.
+PASS: Removed ShaderProgram before Canvas.
+
diff --git a/LayoutTests/inspector/canvas/shaderProgram-add-remove-webgl2.html b/LayoutTests/inspector/canvas/shaderProgram-add-remove-webgl2.html
new file mode 100644 (file)
index 0000000..263ffca
--- /dev/null
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../../http/tests/inspector/resources/inspector-test.js"></script>
+<script src="resources/shaderProgram-utilities.js"></script>
+<script>
+if (window.internals)
+    internals.settings.setWebGL2Enabled(true);
+
+function test() {
+    let suite = initializeTestSuite("webgl2");
+
+    addSimpleTestCase("webgl2");
+    addParentCanvasRemovedTestCase("webgl2");
+
+    suite.runTestCasesAndFinish();
+}
+</script>
+</head>
+<body onload="runTest()">
+    <p>Test that CanvasManager tracks creation and destruction of WebGL2 shader programs.</p>
+</body>
+<script>
+    createProgram("webgl2");
+</script>
+</html>
index cc43221..62655ab 100644 (file)
@@ -591,6 +591,7 @@ 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/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 ]
 
 # These tests reference specific fonts on Mac port.
 Bug(GTK) fast/text/font-weights.html [ WontFix ]
index f8101f3..4fc3a66 100644 (file)
@@ -1138,6 +1138,7 @@ webkit.org/b/148119 [ Yosemite ] fast/text/trak-optimizeLegibility.html [ Failur
 webkit.org/b/174066 inspector/canvas/create-context-webgl2.html [ Pass Timeout ]
 webkit.org/b/174066 inspector/canvas/create-context-webgpu.html [ Pass Timeout ]
 webkit.org/b/174272 inspector/canvas/css-canvas-clients.html [ Pass Timeout ]
+webkit.org/b/174066 inspector/canvas/shaderProgram-add-remove-webgl2.html [ Pass Timeout ]
 webkit.org/b/170615 inspector/codemirror/prettyprinting-css.html [ Pass Timeout ]
 webkit.org/b/153460 inspector/codemirror/prettyprinting-css-rules.html [ Pass Timeout ]
 webkit.org/b/160048 [ Debug ] inspector/codemirror/prettyprinting-javascript.html [ Pass Timeout ]
index 4dc94f5..30b80fb 100644 (file)
@@ -1913,6 +1913,8 @@ inspector/canvas/requestContent-webgl.html [ Skip ]
 inspector/canvas/requestContent-webgl2.html [ Skip ]
 inspector/canvas/resolveCanvasContext-webgl.html [ Skip ]
 inspector/canvas/resolveCanvasContext-webgl2.html [ Skip ]
+inspector/canvas/shaderProgram-add-remove-webgl.html [ Skip ]
+inspector/canvas/shaderProgram-add-remove-webgl2.html [ Skip ]
 ################################################################################
 #################          End WebGL Issues              #######################
 ################################################################################
index fce0b7e..a09f76e 100644 (file)
@@ -1,3 +1,14 @@
+2017-08-03  Matt Baker  <mattbaker@apple.com>
+
+        Web Inspector: Instrument WebGLProgram created/deleted
+        https://bugs.webkit.org/show_bug.cgi?id=175059
+
+        Reviewed by Devin Rousso.
+
+        Extend the Canvas protocol with types/events for tracking WebGLPrograms.
+
+        * inspector/protocol/Canvas.json:
+
 2017-08-03  Brady Eidson  <beidson@apple.com>
 
         Add SW IDLs and stub out basic functionality.
index 85e19f4..3858719 100644 (file)
@@ -9,6 +9,11 @@
             "description": "Unique canvas identifier."
         },
         {
+            "id": "ProgramId",
+            "type": "string",
+            "description": "Unique shader program identifier."
+        },
+        {
             "id": "ContextType",
             "type": "string",
             "enum": ["canvas-2d", "webgl", "webgl2", "webgpu"],
                 { "name": "canvasId", "$ref": "CanvasId" },
                 { "name": "recording", "$ref": "Recording.Recording" }
             ]
+        },
+        {
+            "name": "programCreated",
+            "parameters": [
+                { "name": "canvasId", "$ref": "CanvasId", "description": "Canvas identifier." },
+                { "name": "programId", "$ref": "ProgramId", "description": "Program identifier." }
+            ]
+        },
+        {
+            "name": "programDeleted",
+            "parameters": [
+                { "name": "programId", "$ref": "ProgramId", "description": "Program identifier." }
+            ]
         }
     ]
 }
index 3371feb..5fdbd66 100644 (file)
@@ -3246,6 +3246,8 @@ if (ENABLE_WEBGL)
         html/canvas/WebGLVertexArrayObject.cpp
         html/canvas/WebGLVertexArrayObjectBase.cpp
         html/canvas/WebGLVertexArrayObjectOES.cpp
+
+        inspector/InspectorShaderProgram.cpp
     )
     list(APPEND WebCore_IDL_FILES
         html/canvas/ANGLEInstancedArrays.idl
index 54d21f0..e30ec97 100644 (file)
@@ -1,3 +1,63 @@
+2017-08-03  Matt Baker  <mattbaker@apple.com>
+
+        Web Inspector: Instrument WebGLProgram created/deleted
+        https://bugs.webkit.org/show_bug.cgi?id=175059
+
+        Reviewed by Devin Rousso.
+
+        Tests: inspector/canvas/shaderProgram-add-remove-webgl.html
+               inspector/canvas/shaderProgram-add-remove-webgl2.html
+
+        This patch adds instrumentation to WebGLRenderingContextBase for tracking
+        WebGLPrograms. A new helper class, InspectorShaderProgram, is used by
+        the CanvasAgent to hold related data.
+
+        * CMakeLists.txt:
+        * WebCore.xcodeproj/project.pbxproj:
+
+        * html/canvas/WebGLRenderingContextBase.cpp:
+        (WebCore::WebGLRenderingContextBase::createProgram):
+        (WebCore::WebGLRenderingContextBase::deleteProgram):
+
+        * inspector/InspectorCanvasAgent.cpp:
+        (WebCore::InspectorCanvasAgent::enable):
+        (WebCore::InspectorCanvasAgent::frameNavigated):
+        (WebCore::InspectorCanvasAgent::didCreateProgram):
+        (WebCore::InspectorCanvasAgent::willDeleteProgram):
+        (WebCore::InspectorCanvasAgent::clearCanvasData):
+        (WebCore::InspectorCanvasAgent::unbindCanvas):
+        (WebCore::InspectorCanvasAgent::unbindProgram):
+        (WebCore::InspectorCanvasAgent::assertInspectorProgram):
+        (WebCore::InspectorCanvasAgent::findInspectorProgram):
+        * inspector/InspectorCanvasAgent.h:
+
+        * inspector/InspectorInstrumentation.cpp:
+        (WebCore::InspectorInstrumentation::didCreateCSSCanvasImpl):
+        (WebCore::InspectorInstrumentation::didChangeCSSCanvasClientNodesImpl):
+        (WebCore::InspectorInstrumentation::didCreateCanvasRenderingContextImpl):
+        (WebCore::InspectorInstrumentation::didChangeCanvasMemoryImpl):
+        (WebCore::InspectorInstrumentation::recordCanvasActionImpl):
+        (WebCore::InspectorInstrumentation::didFinishRecordingCanvasFrameImpl):
+        (WebCore::InspectorInstrumentation::didCreateProgramImpl):
+        (WebCore::InspectorInstrumentation::willDeleteProgramImpl):
+
+        * inspector/InspectorInstrumentation.h:
+        (WebCore::InspectorInstrumentation::recordCanvasActionImpl):
+        (WebCore::InspectorInstrumentation::didCreateCSSCanvas):
+        (WebCore::InspectorInstrumentation::didChangeCSSCanvasClientNodes):
+        (WebCore::InspectorInstrumentation::didCreateCanvasRenderingContext):
+        (WebCore::InspectorInstrumentation::didChangeCanvasMemory):
+        (WebCore::InspectorInstrumentation::recordCanvasAction):
+        (WebCore::InspectorInstrumentation::didFinishRecordingCanvasFrame):
+        (WebCore::InspectorInstrumentation::didCreateProgram):
+        (WebCore::InspectorInstrumentation::willDeleteProgram):
+
+        * inspector/InspectorShaderProgram.cpp: Added.
+        (WebCore::InspectorShaderProgram::create):
+        (WebCore::InspectorShaderProgram::InspectorShaderProgram):
+        (WebCore::InspectorShaderProgram::context const):
+        * inspector/InspectorShaderProgram.h: Added.
+
 2017-08-03  Matt Lewis  <jlewis3@apple.com>
 
         Unreviewed, rolling out r220209.
index 8992360..d82e555 100644 (file)
                6A22E8731F1042C400F546C3 /* InspectorCanvas.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6A22E8721F1042C400F546C3 /* InspectorCanvas.cpp */; };
                6A32D7CE1A16D8C000412F0B /* InspectorCanvasAgent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6A4B6D6619D225D8006F11D3 /* InspectorCanvasAgent.cpp */; };
                6A4B6D6519D22519006F11D3 /* InspectorCanvasAgent.h in Headers */ = {isa = PBXBuildFile; fileRef = 6A4B6D6419D22519006F11D3 /* InspectorCanvasAgent.h */; };
+               6A72798B1F16C29C003F39B8 /* InspectorShaderProgram.h in Headers */ = {isa = PBXBuildFile; fileRef = 6A7279881F16C29B003F39B8 /* InspectorShaderProgram.h */; };
+               6A72798C1F16C29C003F39B8 /* InspectorShaderProgram.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6A7279891F16C29B003F39B8 /* InspectorShaderProgram.cpp */; };
                6B3480940EEF50D400AC1B41 /* NativeImage.h in Headers */ = {isa = PBXBuildFile; fileRef = 6B3480920EEF50D400AC1B41 /* NativeImage.h */; settings = {ATTRIBUTES = (Private, ); }; };
                6B693A2E1C51A82E00B03BEF /* ResourceLoadObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = 6B693A2D1C51A82E00B03BEF /* ResourceLoadObserver.h */; settings = {ATTRIBUTES = (Private, ); }; };
                6B693A341C51A95D00B03BEF /* ResourceLoadObserver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6B693A331C51A95D00B03BEF /* ResourceLoadObserver.cpp */; };
                6A22E8721F1042C400F546C3 /* InspectorCanvas.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = InspectorCanvas.cpp; sourceTree = "<group>"; };
                6A4B6D6419D22519006F11D3 /* InspectorCanvasAgent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorCanvasAgent.h; sourceTree = "<group>"; };
                6A4B6D6619D225D8006F11D3 /* InspectorCanvasAgent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InspectorCanvasAgent.cpp; sourceTree = "<group>"; };
+               6A7279881F16C29B003F39B8 /* InspectorShaderProgram.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorShaderProgram.h; sourceTree = "<group>"; };
+               6A7279891F16C29B003F39B8 /* InspectorShaderProgram.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InspectorShaderProgram.cpp; sourceTree = "<group>"; };
                6B3480920EEF50D400AC1B41 /* NativeImage.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = NativeImage.h; sourceTree = "<group>"; };
                6B693A2D1C51A82E00B03BEF /* ResourceLoadObserver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ResourceLoadObserver.h; sourceTree = "<group>"; };
                6B693A331C51A95D00B03BEF /* ResourceLoadObserver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ResourceLoadObserver.cpp; sourceTree = "<group>"; };
                                A518225517E2A0D400A9BA1D /* InspectorOverlayPage.js */,
                                4F6FDD621341DEDD001F8EE3 /* InspectorPageAgent.cpp */,
                                4F6FDD631341DEDD001F8EE3 /* InspectorPageAgent.h */,
+                               6A7279891F16C29B003F39B8 /* InspectorShaderProgram.cpp */,
+                               6A7279881F16C29B003F39B8 /* InspectorShaderProgram.h */,
                                82AB176F125C826700C5069D /* InspectorStyleSheet.cpp */,
                                82AB1770125C826700C5069D /* InspectorStyleSheet.h */,
                                754133A9102E00F400075D00 /* InspectorTimelineAgent.cpp */,
                                504AACCE1834455900E3D9BC /* InspectorNodeFinder.h in Headers */,
                                0F03C0751884805500A5F8CA /* InspectorOverlay.h in Headers */,
                                4F6FDD651341DEDD001F8EE3 /* InspectorPageAgent.h in Headers */,
+                               6A72798B1F16C29C003F39B8 /* InspectorShaderProgram.h in Headers */,
                                82AB1774125C826700C5069D /* InspectorStyleSheet.h in Headers */,
                                754133A8102E00E800075D00 /* InspectorTimelineAgent.h in Headers */,
                                A593CF8B1840535200BFCE27 /* InspectorWebAgentBase.h in Headers */,
                                504AACCD1834455900E3D9BC /* InspectorNodeFinder.cpp in Sources */,
                                7C522D4B15B477E8009B7C95 /* InspectorOverlay.cpp in Sources */,
                                4F6FDD641341DEDD001F8EE3 /* InspectorPageAgent.cpp in Sources */,
+                               6A72798C1F16C29C003F39B8 /* InspectorShaderProgram.cpp in Sources */,
                                82AB1773125C826700C5069D /* InspectorStyleSheet.cpp in Sources */,
                                754133AA102E00F400075D00 /* InspectorTimelineAgent.cpp in Sources */,
                                A54A0C5D1DB6D9C00017A90B /* InspectorWorkerAgent.cpp in Sources */,
index 1a8873a..31d05d1 100644 (file)
@@ -1502,6 +1502,9 @@ RefPtr<WebGLProgram> WebGLRenderingContextBase::createProgram()
         return nullptr;
     auto program = WebGLProgram::create(*this);
     addSharedObject(program.get());
+
+    InspectorInstrumentation::didCreateProgram(*this, program.get());
+
     return WTFMove(program);
 }
 
@@ -1572,6 +1575,9 @@ void WebGLRenderingContextBase::deleteFramebuffer(WebGLFramebuffer* framebuffer)
 
 void WebGLRenderingContextBase::deleteProgram(WebGLProgram* program)
 {
+    ASSERT(program);
+    InspectorInstrumentation::willDeleteProgram(*this, *program);
+
     deleteObject(program);
     // We don't reset m_currentProgram to 0 here because the deletion of the
     // current program is delayed.
index 664a8eb..8bba20d 100644 (file)
@@ -46,6 +46,7 @@
 
 #if ENABLE(WEBGL)
 #include "JSWebGLRenderingContext.h"
+#include "WebGLProgram.h"
 #endif
 
 #if ENABLE(WEBGL2)
@@ -94,6 +95,13 @@ void InspectorCanvasAgent::enable(ErrorString&)
 
     for (auto& inspectorCanvas : m_identifierToInspectorCanvas.values())
         m_frontendDispatcher->canvasAdded(inspectorCanvas->buildObjectForCanvas(m_instrumentingAgents));
+
+#if ENABLE(WEBGL)
+    for (auto& inspectorProgram : m_identifierToInspectorProgram.values()) {
+        auto& inspectorCanvas = inspectorProgram->canvas();
+        m_frontendDispatcher->programCreated(inspectorCanvas.identifier(), inspectorProgram->identifier());
+    }
+#endif
 }
 
 void InspectorCanvasAgent::disable(ErrorString&)
@@ -270,7 +278,7 @@ void InspectorCanvasAgent::frameNavigated(Frame& frame)
     }
 
     Vector<InspectorCanvas*> inspectorCanvases;
-    for (RefPtr<InspectorCanvas>& inspectorCanvas : m_identifierToInspectorCanvas.values()) {
+    for (auto& inspectorCanvas : m_identifierToInspectorCanvas.values()) {
         if (inspectorCanvas->canvas().document().frame() == &frame)
             inspectorCanvases.append(inspectorCanvas.get());
     }
@@ -417,6 +425,34 @@ void InspectorCanvasAgent::didFinishRecordingCanvasFrame(HTMLCanvasElement& canv
     inspectorCanvas->resetRecordingData();
 }
 
+#if ENABLE(WEBGL)
+void InspectorCanvasAgent::didCreateProgram(WebGLRenderingContextBase& context, WebGLProgram& program)
+{
+    auto* inspectorCanvas = findInspectorCanvas(context.canvas());
+    ASSERT(inspectorCanvas);
+    if (!inspectorCanvas)
+        return;
+
+    auto inspectorProgram = InspectorShaderProgram::create(program, *inspectorCanvas);
+    String programIdentifier = inspectorProgram->identifier();
+    m_identifierToInspectorProgram.set(programIdentifier, WTFMove(inspectorProgram));
+
+    if (m_enabled)
+        m_frontendDispatcher->programCreated(inspectorCanvas->identifier(), programIdentifier);
+}
+
+void InspectorCanvasAgent::willDeleteProgram(WebGLProgram& program)
+{
+    auto* inspectorProgram = findInspectorProgram(program);
+    if (!inspectorProgram)
+        return;
+
+    String identifier = unbindProgram(*inspectorProgram);
+    if (m_enabled)
+        m_frontendDispatcher->programDeleted(identifier);
+}
+#endif
+
 void InspectorCanvasAgent::canvasDestroyedTimerFired()
 {
     if (!m_removedCanvasIdentifiers.size())
@@ -448,6 +484,9 @@ void InspectorCanvasAgent::clearCanvasData()
     m_identifierToInspectorCanvas.clear();
     m_canvasToCSSCanvasName.clear();
     m_removedCanvasIdentifiers.clear();
+#if ENABLE(WEBGL)
+    m_identifierToInspectorProgram.clear();
+#endif
 
     if (m_canvasRecordingTimer.isActive())
         m_canvasRecordingTimer.stop();
@@ -460,6 +499,17 @@ String InspectorCanvasAgent::unbindCanvas(InspectorCanvas& inspectorCanvas)
 {
     ASSERT(!m_canvasToCSSCanvasName.contains(&inspectorCanvas.canvas()));
 
+#if ENABLE(WEBGL)
+    Vector<InspectorShaderProgram*> programsToRemove;
+    for (auto& inspectorProgram : m_identifierToInspectorProgram.values()) {
+        if (&inspectorProgram->canvas() == &inspectorCanvas)
+            programsToRemove.append(inspectorProgram.get());
+    }
+
+    for (auto* inspectorProgram : programsToRemove)
+        unbindProgram(*inspectorProgram);
+#endif
+
     String identifier = inspectorCanvas.identifier();
     m_identifierToInspectorCanvas.remove(identifier);
 
@@ -487,4 +537,37 @@ InspectorCanvas* InspectorCanvasAgent::findInspectorCanvas(HTMLCanvasElement& ca
     return nullptr;
 }
 
+#if ENABLE(WEBGL)
+String InspectorCanvasAgent::unbindProgram(InspectorShaderProgram& inspectorProgram)
+{
+    ASSERT(inspectorProgram.context());
+
+    String identifier = inspectorProgram.identifier();
+    m_identifierToInspectorProgram.remove(identifier);
+
+    return identifier;
+}
+
+InspectorShaderProgram* InspectorCanvasAgent::assertInspectorProgram(ErrorString& errorString, const String& identifier)
+{
+    RefPtr<InspectorShaderProgram> inspectorProgram = m_identifierToInspectorProgram.get(identifier);
+    if (!inspectorProgram) {
+        errorString = ASCIILiteral("No shader program for given identifier.");
+        return nullptr;
+    }
+
+    return inspectorProgram.get();
+}
+
+InspectorShaderProgram* InspectorCanvasAgent::findInspectorProgram(WebGLProgram& program)
+{
+    for (auto& inspectorProgram : m_identifierToInspectorProgram.values()) {
+        if (&inspectorProgram->program() == &program)
+            return inspectorProgram.get();
+    }
+
+    return nullptr;
+}
+#endif
+
 } // namespace WebCore
index d88c2fa..2df7bce 100644 (file)
 #include <wtf/Vector.h>
 #include <wtf/text/WTFString.h>
 
+#if ENABLE(WEBGL)
+#include "InspectorShaderProgram.h"
+#endif
+
 namespace Inspector {
 class InjectedScriptManager;
 }
@@ -44,7 +48,10 @@ class InjectedScriptManager;
 namespace WebCore {
 
 class CanvasRenderingContext;
+#if ENABLE(WEBGL)
+class WebGLProgram;
 class WebGLRenderingContextBase;
+#endif
 
 typedef String ErrorString;
 
@@ -77,6 +84,10 @@ public:
     void didChangeCanvasMemory(HTMLCanvasElement&);
     void recordCanvasAction(CanvasRenderingContext&, const String&, Vector<RecordCanvasActionVariant>&& = { });
     void didFinishRecordingCanvasFrame(HTMLCanvasElement&, bool forceDispatch = false);
+#if ENABLE(WEBGL)
+    void didCreateProgram(WebGLRenderingContextBase&, WebGLProgram&);
+    void willDeleteProgram(WebGLProgram&);
+#endif
 
     // CanvasObserver
     void canvasChanged(HTMLCanvasElement&, const FloatRect&) override { }
@@ -88,13 +99,19 @@ private:
     void canvasRecordingTimerFired();
     void clearCanvasData();
     String unbindCanvas(InspectorCanvas&);
-    InspectorCanvas* assertInspectorCanvas(ErrorString&, const String&);
+    InspectorCanvas* assertInspectorCanvas(ErrorString&, const String& identifier);
     InspectorCanvas* findInspectorCanvas(HTMLCanvasElement&);
+#if ENABLE(WEBGL)
+    String unbindProgram(InspectorShaderProgram&);
+    InspectorShaderProgram* assertInspectorProgram(ErrorString&, const String& identifier);
+    InspectorShaderProgram* findInspectorProgram(WebGLProgram&);
+
+    HashMap<String, RefPtr<InspectorShaderProgram>> m_identifierToInspectorProgram;
+#endif
 
     std::unique_ptr<Inspector::CanvasFrontendDispatcher> m_frontendDispatcher;
     RefPtr<Inspector::CanvasBackendDispatcher> m_backendDispatcher;
     Inspector::InjectedScriptManager& m_injectedScriptManager;
-
     HashMap<String, RefPtr<InspectorCanvas>> m_identifierToInspectorCanvas;
     HashMap<HTMLCanvasElement*, String> m_canvasToCSSCanvasName;
     Vector<String> m_removedCanvasIdentifiers;
index c7492c9..4ae8a37 100644 (file)
@@ -978,42 +978,56 @@ void InspectorInstrumentation::didSendWebSocketFrameImpl(InstrumentingAgents& in
 }
 #endif
 
-void InspectorInstrumentation::didCreateCSSCanvasImpl(InstrumentingAgents* instrumentingAgents, HTMLCanvasElement& canvasElement, const String& name)
+void InspectorInstrumentation::didCreateCSSCanvasImpl(InstrumentingAgents& instrumentingAgents, HTMLCanvasElement& canvasElement, const String& name)
 {
-    if (InspectorCanvasAgent* canvasAgent = instrumentingAgents->inspectorCanvasAgent())
+    if (InspectorCanvasAgent* canvasAgent = instrumentingAgents.inspectorCanvasAgent())
         canvasAgent->didCreateCSSCanvas(canvasElement, name);
 }
 
-void InspectorInstrumentation::didChangeCSSCanvasClientNodesImpl(InstrumentingAgents* instrumentingAgents, HTMLCanvasElement& canvasElement)
+void InspectorInstrumentation::didChangeCSSCanvasClientNodesImpl(InstrumentingAgents& instrumentingAgents, HTMLCanvasElement& canvasElement)
 {
-    if (InspectorCanvasAgent* canvasAgent = instrumentingAgents->inspectorCanvasAgent())
+    if (InspectorCanvasAgent* canvasAgent = instrumentingAgents.inspectorCanvasAgent())
         canvasAgent->didChangeCSSCanvasClientNodes(canvasElement);
 }
 
-void InspectorInstrumentation::didCreateCanvasRenderingContextImpl(InstrumentingAgents* instrumentingAgents, HTMLCanvasElement& canvasElement)
+void InspectorInstrumentation::didCreateCanvasRenderingContextImpl(InstrumentingAgents& instrumentingAgents, HTMLCanvasElement& canvasElement)
 {
-    if (InspectorCanvasAgent* canvasAgent = instrumentingAgents->inspectorCanvasAgent())
+    if (InspectorCanvasAgent* canvasAgent = instrumentingAgents.inspectorCanvasAgent())
         canvasAgent->didCreateCanvasRenderingContext(canvasElement);
 }
 
-void InspectorInstrumentation::didChangeCanvasMemoryImpl(InstrumentingAgents* instrumentingAgents, HTMLCanvasElement& canvasElement)
+void InspectorInstrumentation::didChangeCanvasMemoryImpl(InstrumentingAgents& instrumentingAgents, HTMLCanvasElement& canvasElement)
 {
-    if (InspectorCanvasAgent* canvasAgent = instrumentingAgents->inspectorCanvasAgent())
+    if (InspectorCanvasAgent* canvasAgent = instrumentingAgents.inspectorCanvasAgent())
         canvasAgent->didChangeCanvasMemory(canvasElement);
 }
 
-void InspectorInstrumentation::recordCanvasActionImpl(InstrumentingAgents* instrumentingAgents, CanvasRenderingContext& canvasRenderingContext, const String& name, Vector<RecordCanvasActionVariant>&& parameters)
+void InspectorInstrumentation::recordCanvasActionImpl(InstrumentingAgents& instrumentingAgents, CanvasRenderingContext& canvasRenderingContext, const String& name, Vector<RecordCanvasActionVariant>&& parameters)
 {
-    if (InspectorCanvasAgent* canvasAgent = instrumentingAgents->inspectorCanvasAgent())
+    if (InspectorCanvasAgent* canvasAgent = instrumentingAgents.inspectorCanvasAgent())
         canvasAgent->recordCanvasAction(canvasRenderingContext, name, WTFMove(parameters));
 }
 
-void InspectorInstrumentation::didFinishRecordingCanvasFrameImpl(InstrumentingAgents* instrumentingAgents, HTMLCanvasElement& canvasElement, bool forceDispatch)
+void InspectorInstrumentation::didFinishRecordingCanvasFrameImpl(InstrumentingAgents& instrumentingAgents, HTMLCanvasElement& canvasElement, bool forceDispatch)
 {
-    if (InspectorCanvasAgent* canvasAgent = instrumentingAgents->inspectorCanvasAgent())
+    if (InspectorCanvasAgent* canvasAgent = instrumentingAgents.inspectorCanvasAgent())
         canvasAgent->didFinishRecordingCanvasFrame(canvasElement, forceDispatch);
 }
 
+#if ENABLE(WEBGL)
+void InspectorInstrumentation::didCreateProgramImpl(InstrumentingAgents& instrumentingAgents, WebGLRenderingContextBase& context, WebGLProgram& program)
+{
+    if (InspectorCanvasAgent* canvasAgent = instrumentingAgents.inspectorCanvasAgent())
+        canvasAgent->didCreateProgram(context, program);
+}
+
+void InspectorInstrumentation::willDeleteProgramImpl(InstrumentingAgents& instrumentingAgents, WebGLProgram& program)
+{
+    if (InspectorCanvasAgent* canvasAgent = instrumentingAgents.inspectorCanvasAgent())
+        canvasAgent->willDeleteProgram(program);
+}
+#endif
+
 #if ENABLE(RESOURCE_USAGE)
 void InspectorInstrumentation::didHandleMemoryPressureImpl(InstrumentingAgents& instrumentingAgents, Critical critical)
 {
index 88dd931..bf77b6b 100644 (file)
 #include <wtf/MemoryPressureHandler.h>
 #include <wtf/RefPtr.h>
 
+#if ENABLE(WEBGL)
+#include "WebGLRenderingContextBase.h"
+#endif
+
 namespace Inspector {
 class ConsoleMessage;
 class ScriptArguments;
@@ -82,7 +86,9 @@ class ScriptExecutionContext;
 class SecurityOrigin;
 class ShadowRoot;
 class URL;
-class WebGLRenderingContextBase;
+#if ENABLE(WEBGL)
+class WebGLProgram;
+#endif
 class WebKitNamedFlow;
 class WorkerInspectorProxy;
 
@@ -235,6 +241,11 @@ public:
     static void recordCanvasAction(CanvasRenderingContext&, const String&, Vector<RecordCanvasActionVariant>&& = { });
     static void didFinishRecordingCanvasFrame(HTMLCanvasElement&, bool forceDispatch = false);
 
+#if ENABLE(WEBGL)
+    static void didCreateProgram(WebGLRenderingContextBase&, WebGLProgram&);
+    static void willDeleteProgram(WebGLRenderingContextBase&, WebGLProgram&);
+#endif
+
     static void networkStateChanged(Page&);
     static void updateApplicationCacheStatus(Frame*);
 
@@ -390,12 +401,16 @@ private:
     static void networkStateChangedImpl(InstrumentingAgents&);
     static void updateApplicationCacheStatusImpl(InstrumentingAgents&, Frame&);
 
-    static void didCreateCSSCanvasImpl(InstrumentingAgents*, HTMLCanvasElement&, const String&);
-    static void didChangeCSSCanvasClientNodesImpl(InstrumentingAgents*, HTMLCanvasElement&);
-    static void didCreateCanvasRenderingContextImpl(InstrumentingAgents*, HTMLCanvasElement&);
-    static void didChangeCanvasMemoryImpl(InstrumentingAgents*, HTMLCanvasElement&);
-    static void recordCanvasActionImpl(InstrumentingAgents*, CanvasRenderingContext&, const String&, Vector<RecordCanvasActionVariant>&& = { });
-    static void didFinishRecordingCanvasFrameImpl(InstrumentingAgents*, HTMLCanvasElement&, bool forceDispatch = false);
+    static void didCreateCSSCanvasImpl(InstrumentingAgents&, HTMLCanvasElement&, const String&);
+    static void didChangeCSSCanvasClientNodesImpl(InstrumentingAgents&, HTMLCanvasElement&);
+    static void didCreateCanvasRenderingContextImpl(InstrumentingAgents&, HTMLCanvasElement&);
+    static void didChangeCanvasMemoryImpl(InstrumentingAgents&, HTMLCanvasElement&);
+    static void recordCanvasActionImpl(InstrumentingAgents&, CanvasRenderingContext&, const String&, Vector<RecordCanvasActionVariant>&& = { });
+    static void didFinishRecordingCanvasFrameImpl(InstrumentingAgents&, HTMLCanvasElement&, bool forceDispatch = false);
+#if ENABLE(WEBGL)
+    static void didCreateProgramImpl(InstrumentingAgents&, WebGLRenderingContextBase&, WebGLProgram&);
+    static void willDeleteProgramImpl(InstrumentingAgents&, WebGLProgram&);
+#endif
 
     static void layerTreeDidChangeImpl(InstrumentingAgents&);
     static void renderLayerDestroyedImpl(InstrumentingAgents&, const RenderLayer&);
@@ -1099,43 +1114,57 @@ inline void InspectorInstrumentation::didHandleMemoryPressure(Page& page, Critic
 inline void InspectorInstrumentation::didCreateCSSCanvas(HTMLCanvasElement& canvasElement, const String& name)
 {
     if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForDocument(&canvasElement.document()))
-        didCreateCSSCanvasImpl(instrumentingAgents, canvasElement, name);
+        didCreateCSSCanvasImpl(*instrumentingAgents, canvasElement, name);
 }
 
 inline void InspectorInstrumentation::didChangeCSSCanvasClientNodes(HTMLCanvasElement& canvasElement)
 {
     FAST_RETURN_IF_NO_FRONTENDS(void());
     if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForDocument(&canvasElement.document()))
-        didChangeCSSCanvasClientNodesImpl(instrumentingAgents, canvasElement);
+        didChangeCSSCanvasClientNodesImpl(*instrumentingAgents, canvasElement);
 }
 
 inline void InspectorInstrumentation::didCreateCanvasRenderingContext(HTMLCanvasElement& canvasElement)
 {
     if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForDocument(&canvasElement.document()))
-        didCreateCanvasRenderingContextImpl(instrumentingAgents, canvasElement);
+        didCreateCanvasRenderingContextImpl(*instrumentingAgents, canvasElement);
 }
 
 inline void InspectorInstrumentation::didChangeCanvasMemory(HTMLCanvasElement& canvasElement)
 {
     FAST_RETURN_IF_NO_FRONTENDS(void());
     if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForDocument(&canvasElement.document()))
-        didChangeCanvasMemoryImpl(instrumentingAgents, canvasElement);
+        didChangeCanvasMemoryImpl(*instrumentingAgents, canvasElement);
 }
 
 inline void InspectorInstrumentation::recordCanvasAction(CanvasRenderingContext& canvasRenderingContext, const String& name, Vector<RecordCanvasActionVariant>&& parameters)
 {
     FAST_RETURN_IF_NO_FRONTENDS(void());
     if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForDocument(&canvasRenderingContext.canvas().document()))
-        recordCanvasActionImpl(instrumentingAgents, canvasRenderingContext, name, WTFMove(parameters));
+        recordCanvasActionImpl(*instrumentingAgents, canvasRenderingContext, name, WTFMove(parameters));
 }
 
 inline void InspectorInstrumentation::didFinishRecordingCanvasFrame(HTMLCanvasElement& canvasElement, bool forceDispatch)
 {
     FAST_RETURN_IF_NO_FRONTENDS(void());
     if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForDocument(&canvasElement.document()))
-        didFinishRecordingCanvasFrameImpl(instrumentingAgents, canvasElement, forceDispatch);
+        didFinishRecordingCanvasFrameImpl(*instrumentingAgents, canvasElement, forceDispatch);
 }
 
+#if ENABLE(WEBGL)
+inline void InspectorInstrumentation::didCreateProgram(WebGLRenderingContextBase& context, WebGLProgram& program)
+{
+    if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForDocument(context.canvas().document()))
+        didCreateProgramImpl(*instrumentingAgents, context, program);
+}
+
+inline void InspectorInstrumentation::willDeleteProgram(WebGLRenderingContextBase& context, WebGLProgram& program)
+{
+    if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForDocument(context.canvas().document()))
+        willDeleteProgramImpl(*instrumentingAgents, program);
+}
+#endif
+
 inline void InspectorInstrumentation::networkStateChanged(Page& page)
 {
     FAST_RETURN_IF_NO_FRONTENDS(void());
diff --git a/Source/WebCore/inspector/InspectorShaderProgram.cpp b/Source/WebCore/inspector/InspectorShaderProgram.cpp
new file mode 100644 (file)
index 0000000..dd4dbbe
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2017 Apple Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "InspectorShaderProgram.h"
+
+#include "HTMLCanvasElement.h"
+#include "InspectorCanvas.h"
+#include "WebGLProgram.h"
+#include "WebGLRenderingContextBase.h"
+#include <inspector/IdentifiersFactory.h>
+
+using namespace Inspector;
+
+namespace WebCore {
+
+Ref<InspectorShaderProgram> InspectorShaderProgram::create(WebGLProgram& program, InspectorCanvas& inspectorCanvas)
+{
+    return adoptRef(*new InspectorShaderProgram(program, inspectorCanvas));
+}
+
+InspectorShaderProgram::InspectorShaderProgram(WebGLProgram& program, InspectorCanvas& inspectorCanvas)
+    : m_identifier("program:" + IdentifiersFactory::createIdentifier())
+    , m_program(program)
+    , m_canvas(inspectorCanvas)
+{
+}
+
+WebGLRenderingContextBase* InspectorShaderProgram::context() const
+{
+    auto* context = m_canvas.canvas().renderingContext();
+    ASSERT(context && is<WebGLRenderingContextBase>(context));
+    return downcast<WebGLRenderingContextBase>(context);
+}
+
+} // namespace WebCore
+
diff --git a/Source/WebCore/inspector/InspectorShaderProgram.h b/Source/WebCore/inspector/InspectorShaderProgram.h
new file mode 100644 (file)
index 0000000..b9ddd44
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2017 Apple Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include <inspector/InspectorProtocolObjects.h>
+#include <inspector/InspectorValues.h>
+
+namespace WebCore {
+
+class InspectorCanvas;
+class WebGLProgram;
+class WebGLRenderingContextBase;
+
+typedef String ErrorString;
+
+class InspectorShaderProgram final : public RefCounted<InspectorShaderProgram> {
+public:
+    static Ref<InspectorShaderProgram> create(WebGLProgram&, InspectorCanvas&);
+
+    const String& identifier() const { return m_identifier; }
+    InspectorCanvas& canvas() const { return m_canvas; }
+    WebGLRenderingContextBase* context() const;
+    WebGLProgram& program() const { return m_program; }
+
+    ~InspectorShaderProgram() { }
+
+private:
+    InspectorShaderProgram(WebGLProgram&, InspectorCanvas&);
+
+    String m_identifier;
+    WebGLProgram& m_program;
+    InspectorCanvas& m_canvas;
+};
+
+} // namespace WebCore
index 2b487b8..4bf75c2 100644 (file)
@@ -1,3 +1,45 @@
+2017-08-03  Matt Baker  <mattbaker@apple.com>
+
+        Web Inspector: Instrument WebGLProgram created/deleted
+        https://bugs.webkit.org/show_bug.cgi?id=175059
+
+        Reviewed by Devin Rousso.
+
+        This patch adds frontend support for shader program instrumentation.
+        The frontend creates a ShaderProgram model object for each WebGLProgram.
+        Since only canvases with a WebGL context have programs, the Canvas model
+        object does not contain any logic specific to programs. CanvasManager
+        dispatches program added/removed events, and the parent Canvas can be
+        accessed from ShaderProgram but not the other way around.
+
+        * UserInterface/Controllers/CanvasManager.js:
+        (WI.CanvasManager):
+        (WI.CanvasManager.prototype.get shaderPrograms):
+        (WI.CanvasManager.prototype.canvasRemoved):
+        (WI.CanvasManager.prototype.programCreated):
+        (WI.CanvasManager.prototype.programDeleted):
+        (WI.CanvasManager.prototype._mainResourceDidChange):
+        (WI.CanvasManager.prototype._dispatchShaderProgramRemoved):
+
+        * UserInterface/Main.html:
+
+        * UserInterface/Models/Canvas.js:
+        (WI.Canvas.prototype.nextShaderProgramDisplayNumber):
+        (WI.Canvas):
+
+        * UserInterface/Models/ShaderProgram.js: Added.
+        (WI.ShaderProgram):
+        (WI.ShaderProgram.prototype.get identifier):
+        (WI.ShaderProgram.prototype.get canvas):
+        (WI.ShaderProgram.prototype.get displayName):
+
+        * UserInterface/Protocol/CanvasObserver.js:
+        (WI.CanvasObserver.prototype.programCreated):
+        (WI.CanvasObserver.prototype.programDeleted):
+        (WI.CanvasObserver):
+
+        * UserInterface/Test.html:
+
 2017-08-03  Joseph Pecoraro  <pecoraro@apple.com>
 
         JSContext Inspector: Recording tab should not be available in New Tab picker
index cc5d0a5..25cd346 100644 (file)
@@ -32,6 +32,8 @@ WI.CanvasManager = class CanvasManager extends WI.Object
         WI.Frame.addEventListener(WI.Frame.Event.MainResourceDidChange, this._mainResourceDidChange, this);
 
         this._canvasIdentifierMap = new Map;
+        this._shaderProgramIdentifierMap = new Map;
+        this._canvasShaderProgramMap = new Map;
 
         if (window.CanvasAgent)
             CanvasAgent.enable();
@@ -44,6 +46,11 @@ WI.CanvasManager = class CanvasManager extends WI.Object
         return [...this._canvasIdentifierMap.values()];
     }
 
+    get shaderPrograms()
+    {
+        return [...this._shaderProgramIdentifierMap.values()];
+    }
+
     canvasAdded(canvasPayload)
     {
         // Called from WI.CanvasObserver.
@@ -67,6 +74,14 @@ WI.CanvasManager = class CanvasManager extends WI.Object
         if (!canvas)
             return;
 
+        let programs = this._canvasShaderProgramMap.take(canvas);
+        if (programs) {
+            for (let program of programs) {
+                this._shaderProgramIdentifierMap.delete(program.identifier);
+                this._dispatchShaderProgramRemoved(program);
+            }
+        }
+
         canvas.frame.canvasCollection.remove(canvas);
 
         this.dispatchEventToListeners(WI.CanvasManager.Event.CanvasWasRemoved, {canvas});
@@ -111,6 +126,50 @@ WI.CanvasManager = class CanvasManager extends WI.Object
         this.dispatchEventToListeners(WI.CanvasManager.Event.RecordingFinished, {canvas, recording});
     }
 
+    programCreated(canvasIdentifier, programIdentifier)
+    {
+        // Called from WI.CanvasObserver.
+
+        let canvas = this._canvasIdentifierMap.get(canvasIdentifier);
+        console.assert(canvas);
+        if (!canvas)
+            return;
+
+        console.assert(!this._shaderProgramIdentifierMap.has(programIdentifier), `ShaderProgram already exists with id ${programIdentifier}.`);
+
+        let program = new WI.ShaderProgram(programIdentifier, canvas);
+        this._shaderProgramIdentifierMap.set(program.identifier, program);
+
+        let programs = this._canvasShaderProgramMap.get(canvas);
+        if (!programs) {
+            programs = [];
+            this._canvasShaderProgramMap.set(canvas, programs);
+        }
+
+        programs.push(program);
+
+        this.dispatchEventToListeners(WI.CanvasManager.Event.ShaderProgramAdded, {program});
+    }
+
+    programDeleted(programIdentifier)
+    {
+        // Called from WI.CanvasObserver.
+
+        let program = this._shaderProgramIdentifierMap.take(programIdentifier);
+        console.assert(program);
+        if (!program)
+            return;
+
+        let programs = this._canvasShaderProgramMap.get(program.canvas);
+
+        programs.remove(program);
+
+        if (!programs.length)
+            this._canvasShaderProgramMap.delete(program.canvas);
+
+        this._dispatchShaderProgramRemoved(program);
+    }
+
     // Private
 
     _mainResourceDidChange(event)
@@ -121,11 +180,19 @@ WI.CanvasManager = class CanvasManager extends WI.Object
 
         WI.Canvas.resetUniqueDisplayNameNumbers();
 
+        this._shaderProgramIdentifierMap.clear();
+        this._canvasShaderProgramMap.clear();
+
         if (this._canvasIdentifierMap.size) {
             this._canvasIdentifierMap.clear();
             this.dispatchEventToListeners(WI.CanvasManager.Event.Cleared);
         }
     }
+
+    _dispatchShaderProgramRemoved(program)
+    {
+        this.dispatchEventToListeners(WI.CanvasManager.Event.ShaderProgramRemoved, {program});
+    }
 };
 
 WI.CanvasManager.Event = {
@@ -133,4 +200,6 @@ WI.CanvasManager.Event = {
     CanvasWasAdded: "canvas-manager-canvas-was-added",
     CanvasWasRemoved: "canvas-manager-canvas-was-removed",
     RecordingFinished: "canvas-managger-recording-finished",
+    ShaderProgramAdded: "canvas-manager-shader-program-added",
+    ShaderProgramRemoved: "canvas-manager-shader-program-removed",
 };
index 3cc46de..c0ce67c 100644 (file)
     <script src="Models/ScriptInstrument.js"></script>
     <script src="Models/ScriptSyntaxTree.js"></script>
     <script src="Models/ScriptTimelineRecord.js"></script>
+    <script src="Models/ShaderProgram.js"></script>
     <script src="Models/SourceCodePosition.js"></script>
     <script src="Models/SourceCodeRevision.js"></script>
     <script src="Models/SourceCodeSearchMatchObject.js"></script>
index d547a2f..d676f4f 100644 (file)
@@ -42,6 +42,8 @@ WI.Canvas = class Canvas extends WI.Object
         this._memoryCost = memoryCost || NaN;
 
         this._cssCanvasClientNodes = null;
+
+        this._nextShaderProgramDisplayNumber = 1;
     }
 
     // Static
@@ -224,6 +226,13 @@ WI.Canvas = class Canvas extends WI.Object
 
         this.dispatchEventToListeners(WI.Canvas.Event.CSSCanvasClientNodesChanged);
     }
+
+    nextShaderProgramDisplayNumber()
+    {
+        // Called from WI.ShaderProgram.
+
+        return this._nextShaderProgramDisplayNumber++;
+    }
 };
 
 WI.Canvas._nextUniqueDisplayNameNumber = 1;
diff --git a/Source/WebInspectorUI/UserInterface/Models/ShaderProgram.js b/Source/WebInspectorUI/UserInterface/Models/ShaderProgram.js
new file mode 100644 (file)
index 0000000..71cb42a
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+WI.ShaderProgram = class ShaderProgram extends WI.Object
+{
+    constructor(identifier, canvas)
+    {
+        super();
+
+        console.assert(identifier);
+        console.assert(canvas instanceof WI.Canvas);
+
+        this._identifier = identifier;
+        this._canvas = canvas;
+        this._uniqueDisplayNumber = canvas.nextShaderProgramDisplayNumber();
+    }
+
+    // Public
+
+    get identifier() { return this._identifier; }
+    get canvas() { return this._canvas; }
+
+    get displayName()
+    {
+        return WI.UIString("Program %d").format(this._uniqueDisplayNumber);
+    }
+};
+
+WI.ShaderProgram.Event = {
+    ProgramLinked: "shader-program-program-linked",
+    ShaderCompiled: "shader-program-shader-compiled",
+};
index b7c5f2f..ded281f 100644 (file)
@@ -51,4 +51,14 @@ WI.CanvasObserver = class CanvasObserver
     {
         WI.canvasManager.recordingFinished(canvasId, recording);
     }
+
+    programCreated(canvasId, programId)
+    {
+        WI.canvasManager.programCreated(canvasId, programId);
+    }
+
+    programDeleted(programId)
+    {
+        WI.canvasManager.programDeleted(programId);
+    }
 };
index 6a31845..641a0e7 100644 (file)
     <script src="Models/ScriptInstrument.js"></script>
     <script src="Models/ScriptSyntaxTree.js"></script>
     <script src="Models/ScriptTimelineRecord.js"></script>
+    <script src="Models/ShaderProgram.js"></script>
     <script src="Models/SourceCodeRevision.js"></script>
     <script src="Models/SourceCodeTimeline.js"></script>
     <script src="Models/SourceMapResource.js"></script>