https://bugs.webkit.org/show_bug.cgi?id=175400
Reviewed by Matt Baker.
Source/JavaScriptCore:
* inspector/protocol/Canvas.json:
Add `setShaderProgramDisabled` command that sets the `disabled` flag on the given shader
program to the supplied boolean value. If this value is true, calls to `drawArrays` and
`drawElements` when that program is in use will have no effect.
Source/WebCore:
Test: inspector/canvas/setShaderProgramDisabled.html
* inspector/InspectorShaderProgram.h:
(WebCore::InspectorShaderProgram::disabled):
(WebCore::InspectorShaderProgram::setDisabled):
* html/canvas/WebGLRenderingContextBase.cpp:
(WebCore::WebGLRenderingContextBase::drawArrays):
(WebCore::WebGLRenderingContextBase::drawElements):
If the current program is disabled, return early. This will prevent the current shader
program from drawing anything to the canvas.
* inspector/InspectorCanvasAgent.h:
* inspector/InspectorCanvasAgent.cpp:
(WebCore::InspectorCanvasAgent::setShaderProgramDisabled):
(WebCore::InspectorCanvasAgent::isShaderProgramDisabled):
* inspector/InspectorInstrumentation.h:
* inspector/InspectorInstrumentation.cpp:
(WebCore::InspectorInstrumentation::isShaderProgramDisabled):
(WebCore::InspectorInstrumentation::isShaderProgramDisabledImpl):
Source/WebInspectorUI:
Adds a status element to ShaderProgramTreeElement that, when clicked, will toggle the
disabled state of the corresponding ShaderProgram. Disabled shader programs will not draw
anything to the context.
* Localizations/en.lproj/localizedStrings.js:
* UserInterface/Main.html:
* UserInterface/Models/ShaderProgram.js:
(WI.ShaderProgram):
(WI.ShaderProgram.prototype.get disabled):
(WI.ShaderProgram.prototype.toggleDisabled):
* UserInterface/Views/ShaderProgramTreeElement.js:
(WI.ShaderProgramTreeElement):
(WI.ShaderProgramTreeElement.prototype.selectOnMouseDown):
(WI.ShaderProgramTreeElement.prototype._disabledImageElementClicked):
* UserInterface/Views/ShaderProgramTreeElement.css: Added.
(.item.shader-program .status > img):
(.item.shader-program:not(:hover, .selected, .disabled) .status > img):
(.tree-outline:matches(:focus, .force-focus) .item.shader-program.selected .status > img):
(.item.shader-program.disabled > *):
LayoutTests:
* inspector/canvas/setShaderProgramDisabled-expected.txt: Added.
* inspector/canvas/setShaderProgramDisabled.html: Added.
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@221025
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2017-08-22 Devin Rousso <webkit@devinrousso.com>
+
+ Web Inspector: provide way for ShaderPrograms to be enabled/disabled
+ https://bugs.webkit.org/show_bug.cgi?id=175400
+
+ Reviewed by Matt Baker.
+
+ * inspector/canvas/setShaderProgramDisabled-expected.txt: Added.
+ * inspector/canvas/setShaderProgramDisabled.html: Added.
+
2017-08-22 Youenn Fablet <youenn@apple.com>
[Cache API] Add support for overwriting responses with put on an existing record
--- /dev/null
+Test disabling and re-enabling of shader programs.
+
+
+== Running test suite: Canvas.setShaderProgramDisabled
+-- Running test case: Canvas.setShaderProgramDisabled.disabledDrawArrays
+PASS: Disabling a shader program should prevent it from drawing.
+
+-- Running test case: Canvas.setShaderProgramDisabled.disabledDrawElements
+PASS: Disabling a shader program should prevent it from drawing.
+
+-- Running test case: Canvas.setShaderProgramDisabled.reenabledDrawArrays
+PASS: Re-enabling a shader program should allow it to draw.
+
+-- Running test case: Canvas.setShaderProgramDisabled.reenabledDrawElements
+PASS: Re-enabling a shader program should allow it to draw.
+
+-- Running test case: Canvas.setShaderProgramDisabled.invalidProgramId
+PASS: Should produce an error.
+Error: No shader program for given identifier.
+
--- /dev/null
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../../http/tests/inspector/resources/inspector-test.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>
+function load() {
+ createProgram("webgl");
+ linkProgram("vertex-shader", "fragment-shader");
+ context.useProgram(program);
+
+ clearContext();
+
+ runTest();
+}
+
+function clearContext() {
+ context.clearColor(0.0, 0.0, 0.0, 1.0);
+ context.clear(context.COLOR_BUFFER_BIT);
+}
+
+function drawArrays() {
+ clearContext();
+
+ let vertexes = [
+ -0.5, 0.5, 0.0,
+ -0.5, -0.5, 0.0,
+ 0.5, -0.5, 0.0,
+ ];
+ let vertexBuffer = context.createBuffer();
+ context.bindBuffer(context.ARRAY_BUFFER, vertexBuffer);
+ context.bufferData(context.ARRAY_BUFFER, new Float32Array(vertexes), context.STATIC_DRAW);
+
+ let position = context.getAttribLocation(program, "position");
+ context.vertexAttribPointer(position, 3, context.FLOAT, false, 0, 0);
+ context.enableVertexAttribArray(position);
+
+ context.drawArrays(context.TRIANGLES, 0, 3);
+}
+
+function drawElements() {
+ clearContext();
+
+ let vertexes = [
+ 0.5, 0.5, 0.0,
+ -0.5, -0.5, 0.0,
+ 0.5, -0.5, 0.0,
+ ];
+ let vertexBuffer = context.createBuffer();
+ context.bindBuffer(context.ARRAY_BUFFER, vertexBuffer);
+ context.bufferData(context.ARRAY_BUFFER, new Float32Array(vertexes), context.STATIC_DRAW);
+
+ let indexes = [0, 1, 2];
+ let indexBuffer = context.createBuffer();
+ context.bindBuffer(context.ELEMENT_ARRAY_BUFFER, indexBuffer);
+ context.bufferData(context.ELEMENT_ARRAY_BUFFER, new Uint16Array(indexes), context.STATIC_DRAW);
+
+ let position = context.getAttribLocation(program, "position");
+ context.vertexAttribPointer(position, 3, context.FLOAT, false, 0, 0);
+ context.enableVertexAttribArray(position);
+
+ context.drawElements(context.TRIANGLES, indexes.length, context.UNSIGNED_SHORT, 0);
+}
+
+function test() {
+ let suite = InspectorTest.createAsyncSuite("Canvas.setShaderProgramDisabled");
+
+ let shaderProgram = WI.canvasManager.shaderPrograms[0];
+ let originalContent = null;
+
+ function validTest({name, disabled, evaluateString}) {
+ suite.addTestCase({
+ name,
+ test(resolve, reject) {
+ CanvasAgent.setShaderProgramDisabled(shaderProgram.identifier, disabled, (error) => {
+ if (error) {
+ reject(error);
+ return;
+ }
+
+ InspectorTest.evaluateInPage(evaluateString, (error) => {
+ if (error) {
+ reject(error);
+ return;
+ }
+
+ CanvasAgent.requestContent(shaderProgram.canvas.identifier)
+ .then(({content}) => {
+ if (disabled)
+ InspectorTest.expectEqual(content, originalContent, "Disabling a shader program should prevent it from drawing.");
+ else
+ InspectorTest.expectNotEqual(content, originalContent, "Re-enabling a shader program should allow it to draw.");
+ })
+ .then(resolve, reject);
+ });
+ });
+ }
+ });
+ }
+
+ validTest({
+ name: "Canvas.setShaderProgramDisabled.disabledDrawArrays",
+ disabled: true,
+ evaluateString: `drawArrays()`,
+ });
+
+ validTest({
+ name: "Canvas.setShaderProgramDisabled.disabledDrawElements",
+ disabled: true,
+ evaluateString: `drawElements()`,
+ });
+
+ validTest({
+ name: "Canvas.setShaderProgramDisabled.reenabledDrawArrays",
+ disabled: false,
+ evaluateString: `drawArrays()`,
+ });
+
+ validTest({
+ name: "Canvas.setShaderProgramDisabled.reenabledDrawElements",
+ disabled: false,
+ evaluateString: `drawElements()`,
+ });
+
+ suite.addTestCase({
+ name: "Canvas.setShaderProgramDisabled.invalidProgramId",
+ description: "Invalid program identifiers should cause an error.",
+ test(resolve, reject) {
+ const programId = "INVALID_PROGRAM_ID";
+ const disabled = false;
+ CanvasAgent.setShaderProgramDisabled(programId, disabled, (error) => {
+ InspectorTest.expectThat(error, "Should produce an error.");
+ InspectorTest.log("Error: " + error);
+ resolve();
+ });
+ }
+ });
+
+ CanvasAgent.requestContent(shaderProgram.canvas.identifier, (error, content) => {
+ originalContent = content;
+
+ suite.runTestCasesAndFinish();
+ });
+}
+</script>
+</head>
+<body onload="load()">
+ <p>Test disabling and re-enabling of shader programs.</p>
+</body>
+</html>
+2017-08-22 Devin Rousso <webkit@devinrousso.com>
+
+ Web Inspector: provide way for ShaderPrograms to be enabled/disabled
+ https://bugs.webkit.org/show_bug.cgi?id=175400
+
+ Reviewed by Matt Baker.
+
+ * inspector/protocol/Canvas.json:
+ Add `setShaderProgramDisabled` command that sets the `disabled` flag on the given shader
+ program to the supplied boolean value. If this value is true, calls to `drawArrays` and
+ `drawElements` when that program is in use will have no effect.
+
2017-08-22 Keith Miller <keith_miller@apple.com>
Unriviewed, fix windows build... for realz.
{ "name": "shaderType", "$ref": "ShaderType" },
{ "name": "source", "type": "string" }
]
+ },
+ {
+ "name": "setShaderProgramDisabled",
+ "description": "Enable/disable the visibility of the given shader program.",
+ "parameters": [
+ { "name": "programId", "$ref": "ProgramId" },
+ { "name": "disabled", "type": "boolean" }
+ ]
}
],
"events": [
+2017-08-22 Devin Rousso <webkit@devinrousso.com>
+
+ Web Inspector: provide way for ShaderPrograms to be enabled/disabled
+ https://bugs.webkit.org/show_bug.cgi?id=175400
+
+ Reviewed by Matt Baker.
+
+ Test: inspector/canvas/setShaderProgramDisabled.html
+
+ * inspector/InspectorShaderProgram.h:
+ (WebCore::InspectorShaderProgram::disabled):
+ (WebCore::InspectorShaderProgram::setDisabled):
+
+ * html/canvas/WebGLRenderingContextBase.cpp:
+ (WebCore::WebGLRenderingContextBase::drawArrays):
+ (WebCore::WebGLRenderingContextBase::drawElements):
+ If the current program is disabled, return early. This will prevent the current shader
+ program from drawing anything to the canvas.
+
+ * inspector/InspectorCanvasAgent.h:
+ * inspector/InspectorCanvasAgent.cpp:
+ (WebCore::InspectorCanvasAgent::setShaderProgramDisabled):
+ (WebCore::InspectorCanvasAgent::isShaderProgramDisabled):
+ * inspector/InspectorInstrumentation.h:
+ * inspector/InspectorInstrumentation.cpp:
+ (WebCore::InspectorInstrumentation::isShaderProgramDisabled):
+ (WebCore::InspectorInstrumentation::isShaderProgramDisabledImpl):
+
2017-08-22 Youenn Fablet <youenn@apple.com>
[Cache API] Add support for overwriting responses with put on an existing record
if (!validateDrawArrays("drawArrays", mode, first, count, 0))
return;
+ if (m_currentProgram && InspectorInstrumentation::isShaderProgramDisabled(*this, *m_currentProgram))
+ return;
+
clearIfComposited();
bool vertexAttrib0Simulated = false;
if (!validateDrawElements("drawElements", mode, count, type, offset, numElements, 0))
return;
+ if (m_currentProgram && InspectorInstrumentation::isShaderProgramDisabled(*this, *m_currentProgram))
+ return;
+
clearIfComposited();
bool vertexAttrib0Simulated = false;
#endif
}
+void InspectorCanvasAgent::setShaderProgramDisabled(ErrorString& errorString, const String& programId, bool disabled)
+{
+#if ENABLE(WEBGL)
+ auto* inspectorProgram = assertInspectorProgram(errorString, programId);
+ if (!inspectorProgram)
+ return;
+
+ inspectorProgram->setDisabled(disabled);
+#else
+ UNUSED_PARAM(programId);
+ UNUSED_PARAM(disabled);
+ errorString = ASCIILiteral("WebGL is not supported.");
+#endif
+}
+
void InspectorCanvasAgent::frameNavigated(Frame& frame)
{
if (frame.isMainFrame()) {
if (m_enabled)
m_frontendDispatcher->programDeleted(identifier);
}
+
+bool InspectorCanvasAgent::isShaderProgramDisabled(WebGLProgram& program)
+{
+ auto* inspectorProgram = findInspectorProgram(program);
+ if (!inspectorProgram)
+ return false;
+
+ return inspectorProgram->disabled();
+}
#endif
void InspectorCanvasAgent::canvasDestroyedTimerFired()
void cancelRecording(ErrorString&, const String& canvasId) override;
void requestShaderSource(ErrorString&, const String& programId, const String& shaderType, String*) override;
void updateShader(ErrorString&, const String& programId, const String& shaderType, const String& source) override;
+ void setShaderProgramDisabled(ErrorString&, const String& programId, bool disabled) override;
// InspectorInstrumentation
void frameNavigated(Frame&);
#if ENABLE(WEBGL)
void didCreateProgram(WebGLRenderingContextBase&, WebGLProgram&);
void willDeleteProgram(WebGLProgram&);
+ bool isShaderProgramDisabled(WebGLProgram&);
#endif
// CanvasObserver
if (InspectorCanvasAgent* canvasAgent = instrumentingAgents.inspectorCanvasAgent())
canvasAgent->willDeleteProgram(program);
}
+
+bool InspectorInstrumentation::isShaderProgramDisabledImpl(InstrumentingAgents& instrumentingAgents, WebGLProgram& program)
+{
+ if (InspectorCanvasAgent* canvasAgent = instrumentingAgents.inspectorCanvasAgent())
+ return canvasAgent->isShaderProgramDisabled(program);
+ return false;
+}
#endif
#if ENABLE(RESOURCE_USAGE)
#if ENABLE(WEBGL)
static void didCreateProgram(WebGLRenderingContextBase&, WebGLProgram&);
static void willDeleteProgram(WebGLRenderingContextBase&, WebGLProgram&);
+ static bool isShaderProgramDisabled(WebGLRenderingContextBase&, WebGLProgram&);
#endif
static void networkStateChanged(Page&);
#if ENABLE(WEBGL)
static void didCreateProgramImpl(InstrumentingAgents&, WebGLRenderingContextBase&, WebGLProgram&);
static void willDeleteProgramImpl(InstrumentingAgents&, WebGLProgram&);
+ static bool isShaderProgramDisabledImpl(InstrumentingAgents&, WebGLProgram&);
#endif
static void layerTreeDidChangeImpl(InstrumentingAgents&);
if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForDocument(context.canvas().document()))
willDeleteProgramImpl(*instrumentingAgents, program);
}
+
+inline bool InspectorInstrumentation::isShaderProgramDisabled(WebGLRenderingContextBase& context, WebGLProgram& program)
+{
+ FAST_RETURN_IF_NO_FRONTENDS(false);
+ if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForDocument(context.canvas().document()))
+ return isShaderProgramDisabledImpl(*instrumentingAgents, program);
+ return false;
+}
#endif
inline void InspectorInstrumentation::networkStateChanged(Page& page)
WebGLProgram& program() const { return m_program; }
WebGLShader* shaderForType(const String&);
+ bool disabled() const { return m_disabled; }
+ void setDisabled(bool disabled) { m_disabled = disabled; }
+
~InspectorShaderProgram() { }
private:
String m_identifier;
WebGLProgram& m_program;
InspectorCanvas& m_canvas;
+
+ bool m_disabled { false };
};
} // namespace WebCore
+2017-08-22 Devin Rousso <webkit@devinrousso.com>
+
+ Web Inspector: provide way for ShaderPrograms to be enabled/disabled
+ https://bugs.webkit.org/show_bug.cgi?id=175400
+
+ Reviewed by Matt Baker.
+
+ Adds a status element to ShaderProgramTreeElement that, when clicked, will toggle the
+ disabled state of the corresponding ShaderProgram. Disabled shader programs will not draw
+ anything to the context.
+
+ * Localizations/en.lproj/localizedStrings.js:
+ * UserInterface/Main.html:
+
+ * UserInterface/Models/ShaderProgram.js:
+ (WI.ShaderProgram):
+ (WI.ShaderProgram.prototype.get disabled):
+ (WI.ShaderProgram.prototype.toggleDisabled):
+
+ * UserInterface/Views/ShaderProgramTreeElement.js:
+ (WI.ShaderProgramTreeElement):
+ (WI.ShaderProgramTreeElement.prototype.selectOnMouseDown):
+ (WI.ShaderProgramTreeElement.prototype._disabledImageElementClicked):
+ * UserInterface/Views/ShaderProgramTreeElement.css: Added.
+ (.item.shader-program .status > img):
+ (.item.shader-program:not(:hover, .selected, .disabled) .status > img):
+ (.tree-outline:matches(:focus, .force-focus) .item.shader-program.selected .status > img):
+ (.item.shader-program.disabled > *):
+
2017-08-21 Devin Rousso <webkit@devinrousso.com>
Web Inspector: Can't copy text from "View variable value" popover in Styles sidebar
localizedStrings["Direction"] = "Direction";
localizedStrings["Disable Breakpoint"] = "Disable Breakpoint";
localizedStrings["Disable Breakpoints"] = "Disable Breakpoints";
+localizedStrings["Disable Program"] = "Disable Program";
localizedStrings["Disable all breakpoints (%s)"] = "Disable all breakpoints (%s)";
localizedStrings["Disable paint flashing"] = "Disable paint flashing";
localizedStrings["Disabled"] = "Disabled";
localizedStrings["Elements"] = "Elements";
localizedStrings["Enable Breakpoint"] = "Enable Breakpoint";
localizedStrings["Enable Breakpoints"] = "Enable Breakpoints";
+localizedStrings["Enable Program"] = "Enable Program";
localizedStrings["Enable all breakpoints (%s)"] = "Enable all breakpoints (%s)";
localizedStrings["Enable breakpoints"] = "Enable breakpoints";
localizedStrings["Enable paint flashing"] = "Enable paint flashing";
<link rel="stylesheet" href="Views/SearchSidebarPanel.css">
<link rel="stylesheet" href="Views/SettingsTabContentView.css">
<link rel="stylesheet" href="Views/ShaderProgramContentView.css">
+ <link rel="stylesheet" href="Views/ShaderProgramTreeElement.css">
<link rel="stylesheet" href="Views/Sidebar.css">
<link rel="stylesheet" href="Views/SidebarPanel.css">
<link rel="stylesheet" href="Views/Slider.css">
* THE POSSIBILITY OF SUCH DAMAGE.
*/
-WI.ShaderProgram = class ShaderProgram extends WI.Object
+WI.ShaderProgram = class ShaderProgram
{
constructor(identifier, canvas)
{
- super();
-
console.assert(identifier);
console.assert(canvas instanceof WI.Canvas);
this._identifier = identifier;
this._canvas = canvas;
this._uniqueDisplayNumber = canvas.nextShaderProgramDisplayNumber();
+ this._disabled = false;
}
// Public
get identifier() { return this._identifier; }
get canvas() { return this._canvas; }
+ get disabled() { return this._disabled; }
get displayName()
{
this._updateShader(CanvasAgent.ShaderType.Fragment, source);
}
+ toggleDisabled(callback)
+ {
+ CanvasAgent.setShaderProgramDisabled(this._identifier, !this._disabled, (error) => {
+ console.assert(!error, error);
+ if (error)
+ return;
+
+ this._disabled = !this._disabled;
+ callback();
+ });
+ }
+
// Private
_requestShaderSource(shaderType, callback)
Fragment: "shader-type-fragment",
Vertex: "shader-type-vertex",
};
-
-WI.ShaderProgram.Event = {
- ProgramLinked: "shader-program-program-linked",
- ShaderCompiled: "shader-program-shader-compiled",
-};
--- /dev/null
+/*
+ * 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.
+ */
+
+.item.shader-program .status > img {
+ width: 18px;
+ margin-top: 2px;
+ content: url(../Images/Eye.svg);
+}
+
+.item.shader-program:not(:hover, .selected, .disabled) .status > img {
+ display: none;
+}
+
+.tree-outline:matches(:focus, .force-focus) .item.shader-program.selected .status > img {
+ filter: invert();
+}
+
+.item.shader-program.disabled > * {
+ opacity: 0.5;
+}
const subtitle = null;
super("shader-program", shaderProgram.displayName, subtitle, shaderProgram);
+
+ this._disabledImageElement = document.createElement("img");
+ this._disabledImageElement.title = WI.UIString("Disable Program");
+ this._disabledImageElement.addEventListener("click", this._disabledImageElementClicked.bind(this));
+ this.status = this._disabledImageElement;
+ }
+
+ // Protected
+
+ selectOnMouseDown(event)
+ {
+ if (event.target.isSelfOrDescendant(this._statusElement))
+ return;
+
+ super.selectOnMouseDown(event);
+ }
+
+ // Private
+
+ _disabledImageElementClicked(event)
+ {
+ this.representedObject.toggleDisabled(() => {
+ this._listItemNode.classList.toggle("disabled", !!this.representedObject.disabled);
+ this._disabledImageElement.title = this.representedObject.disabled ? WI.UIString("Enable Program") : WI.UIString("Disable Program");
+ });
}
};