Bug 1342237 - remove Shader Editor Panel; r=vporof

Differential Revision: https://phabricator.services.mozilla.com/D14732

--HG--
extra : moz-landing-system : lando
This commit is contained in:
yulia 2019-03-13 16:47:10 +00:00
parent 83e3a56687
commit 8c86559f59
60 changed files with 0 additions and 4033 deletions

View File

@ -107,9 +107,6 @@ module.exports = {
}
}, {
"files": [
// Note: Bug 1342237 may be removing shadereditor, check before
// doing more work on enabling these rules.
"client/shadereditor/**",
// Note: Bug 1403944 may be removing webaudioeditor, check before
// doing more work on enabling these rules.
"client/webaudioeditor/**",

View File

@ -6,7 +6,6 @@
const Services = require("Services");
const osString = Services.appinfo.OS;
const { Cu } = require("chrome");
// Panels
loader.lazyGetter(this, "OptionsPanel", () => require("devtools/client/framework/toolbox-options").OptionsPanel);
@ -176,33 +175,6 @@ Tools.styleEditor = {
},
};
Tools.shaderEditor = {
id: "shadereditor",
deprecated: true,
deprecationURL: DEPRECATION_URL,
ordinal: 5,
visibilityswitch: "devtools.shadereditor.enabled",
icon: "chrome://devtools/skin/images/tool-shadereditor.svg",
url: "chrome://devtools/content/shadereditor/index.xul",
label: l10n("ToolboxShaderEditor.label"),
panelLabel: l10n("ToolboxShaderEditor.panelLabel"),
tooltip: l10n("ToolboxShaderEditor.tooltip"),
isTargetSupported: function(target) {
return target.hasActor("webgl") && !target.chrome;
},
build: function(iframeWindow, toolbox) {
const { BrowserLoader } = Cu.import("resource://devtools/client/shared/browser-loader.js", {});
const browserRequire = BrowserLoader({
baseURI: "resource://devtools/client/shadereditor/",
window: iframeWindow,
}).require;
const { ShaderEditorPanel } = browserRequire("devtools/client/shadereditor/panel");
return new ShaderEditorPanel(toolbox);
},
};
Tools.performance = {
id: "performance",
ordinal: 7,
@ -442,7 +414,6 @@ var defaultTools = [
Tools.inspector,
Tools.jsdebugger,
Tools.styleEditor,
Tools.shaderEditor,
Tools.webAudioEditor,
Tools.performance,
Tools.netMonitor,

View File

@ -26,7 +26,6 @@ devtools.jar:
content/shared/sourceeditor/codemirror/mozilla.css (shared/sourceeditor/codemirror/mozilla.css)
content/shared/sourceeditor/codemirror/cmiframe.html (shared/sourceeditor/codemirror/cmiframe.html)
content/debugger/new/index.html (debugger/new/index.html)
content/shadereditor/index.xul (shadereditor/index.xul)
content/webaudioeditor/index.xul (webaudioeditor/index.xul)
content/webaudioeditor/includes.js (webaudioeditor/includes.js)
content/webaudioeditor/models.js (webaudioeditor/models.js)
@ -137,7 +136,6 @@ devtools.jar:
skin/performance.css (themes/performance.css)
skin/memory.css (themes/memory.css)
skin/scratchpad.css (themes/scratchpad.css)
skin/shadereditor.css (themes/shadereditor.css)
skin/storage.css (themes/storage.css)
skin/splitview.css (themes/splitview.css)
skin/styleeditor.css (themes/styleeditor.css)
@ -183,7 +181,6 @@ devtools.jar:
skin/images/tool-webconsole.svg (themes/images/tool-webconsole.svg)
skin/images/tool-debugger.svg (themes/images/tool-debugger.svg)
skin/images/tool-inspector.svg (themes/images/tool-inspector.svg)
skin/images/tool-shadereditor.svg (themes/images/tool-shadereditor.svg)
skin/images/tool-styleeditor.svg (themes/images/tool-styleeditor.svg)
skin/images/tool-storage.svg (themes/images/tool-storage.svg)
skin/images/tool-profiler.svg (themes/images/tool-profiler.svg)

View File

@ -1,32 +0,0 @@
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<!-- LOCALIZATION NOTE : FILE This file contains the Debugger strings -->
<!-- LOCALIZATION NOTE : FILE Do not translate commandkey -->
<!-- LOCALIZATION NOTE : FILE The correct localization of this file might be to
- keep it in English, or another language commonly spoken among web developers.
- You want to make that choice consistent across the developer tools.
- A good criteria is the language in which you'd find the best
- documentation on web development on the web. -->
<!-- LOCALIZATION NOTE (shaderEditorUI.vertexShader): This is the label for
- the pane that displays a vertex shader's source. -->
<!ENTITY shaderEditorUI.vertexShader "Vertex Shader">
<!-- LOCALIZATION NOTE (shaderEditorUI.fragmentShader): This is the label for
- the pane that displays a fragment shader's source. -->
<!ENTITY shaderEditorUI.fragmentShader "Fragment Shader">
<!-- LOCALIZATION NOTE (shaderEditorUI.reloadNotice1): This is the label shown
- on the button that triggers a page refresh. -->
<!ENTITY shaderEditorUI.reloadNotice1 "Reload">
<!-- LOCALIZATION NOTE (shaderEditorUI.reloadNotice2): This is the label shown
- along with the button that triggers a page refresh. -->
<!ENTITY shaderEditorUI.reloadNotice2 "the page to be able to edit GLSL code.">
<!-- LOCALIZATION NOTE (shaderEditorUI.emptyNotice): This is the label shown
- while the page is refreshing and the tool waits for a WebGL context. -->
<!ENTITY shaderEditorUI.emptyNotice "Waiting for a WebGL context to be created…">

View File

@ -1,22 +0,0 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
# LOCALIZATION NOTE These strings are used inside the Debugger
# which is available from the Web Developer sub-menu -> 'Debugger'.
# The correct localization of this file might be to keep it in
# English, or another language commonly spoken among web developers.
# You want to make that choice consistent across the developer tools.
# A good criteria is the language in which you'd find the best
# documentation on web development on the web.
# LOCALIZATION NOTE (shadersList.programLabel):
# This string is displayed in the programs list of the Shader Editor,
# identifying a set of linked GLSL shaders.
shadersList.programLabel=Program %S
# LOCALIZATION NOTE (shadersList.blackboxLabel):
# This string is displayed in the programs list of the Shader Editor, while
# the user hovers over the checkbox used to toggle blackboxing of a program's
# associated fragment shader.
shadersList.blackboxLabel=Toggle geometry visibility

View File

@ -98,20 +98,6 @@ ToolboxStyleEditor.tooltip3=Stylesheet Editor (CSS) (%S)
# editor.
open.accesskey=l
# LOCALIZATION NOTE (ToolboxShaderEditor.label):
# This string is displayed in the title of the tab when the Shader Editor is
# displayed inside the developer tools window and in the Developer Tools Menu.
ToolboxShaderEditor.label=Shader Editor
# LOCALIZATION NOTE (ToolboxShaderEditor.panelLabel):
# This is used as the label for the toolbox panel.
ToolboxShaderEditor.panelLabel=Shader Editor Panel
# LOCALIZATION NOTE (ToolboxShaderEditor.tooltip):
# This string is displayed in the tooltip of the tab when the Shader Editor is
# displayed inside the developer tools window.
ToolboxShaderEditor.tooltip=Live GLSL shader language editor for WebGL
# LOCALIZATION NOTE (ToolboxWebAudioEditor1.label):
# This string is displayed in the title of the tab when the Web Audio Editor
# is displayed inside the developer tools window and in the Developer Tools Menu.

View File

@ -24,7 +24,6 @@ DIRS += [
'preferences',
'responsive.html',
'scratchpad',
'shadereditor',
'shared',
'storage',
'styleeditor',

View File

@ -229,9 +229,6 @@ pref("devtools.styleeditor.transitions", true);
pref("devtools.screenshot.clipboard.enabled", false);
pref("devtools.screenshot.audio.enabled", true);
// Enable the Shader Editor.
pref("devtools.shadereditor.enabled", false);
// Enable the Web Audio Editor
pref("devtools.webaudioeditor.enabled", false);

View File

@ -1,68 +0,0 @@
<?xml version="1.0"?>
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<?xml-stylesheet href="chrome://devtools/skin/widgets.css" type="text/css"?>
<?xml-stylesheet href="chrome://devtools/skin/shadereditor.css" type="text/css"?>
<?xml-stylesheet href="chrome://devtools/content/shared/widgets/widgets.css" type="text/css"?>
<!DOCTYPE window [
<!ENTITY % debuggerDTD SYSTEM "chrome://devtools/locale/shadereditor.dtd">
%debuggerDTD;
]>
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script type="application/javascript"
src="chrome://devtools/content/shared/theme-switching.js"/>
<vbox class="theme-body" flex="1">
<hbox id="reload-notice"
class="notice-container"
align="center"
pack="center"
flex="1">
<button id="requests-menu-reload-notice-button"
class="devtools-toolbarbutton"
standalone="true"
label="&shaderEditorUI.reloadNotice1;"/>
<label id="requests-menu-reload-notice-label"
class="plain"
value="&shaderEditorUI.reloadNotice2;"/>
</hbox>
<hbox id="waiting-notice"
class="notice-container devtools-throbber"
align="center"
pack="center"
flex="1"
hidden="true">
<label id="requests-menu-waiting-notice-label"
class="plain"
value="&shaderEditorUI.emptyNotice;"/>
</hbox>
<box id="content"
class="devtools-responsive-container"
flex="1"
hidden="true">
<vbox id="shaders-pane"/>
<splitter class="devtools-side-splitter"/>
<box id="shaders-editors" class="devtools-responsive-container" flex="1">
<vbox flex="1">
<vbox id="vs-editor" flex="1"/>
<label id="vs-editor-label"
class="plain editor-label"
value="&shaderEditorUI.vertexShader;"/>
</vbox>
<splitter id="editors-splitter" class="devtools-side-splitter"/>
<vbox flex="1">
<vbox id="fs-editor" flex="1"/>
<label id="fs-editor-label"
class="plain editor-label"
value="&shaderEditorUI.fragmentShader;"/>
</vbox>
</box>
</box>
</vbox>
</window>

View File

@ -1,14 +0,0 @@
# vim: set filetype=python:
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
DevToolsModules(
'panel.js',
'shadereditor.js'
)
BROWSER_CHROME_MANIFESTS += ['test/browser.ini']
with Files('**'):
BUG_COMPONENT = ('DevTools', 'WebGL Shader Editor')

View File

@ -1,71 +0,0 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const EventEmitter = require("devtools/shared/event-emitter");
const { EventsHandler, ShadersListView, ShadersEditorsView, EVENTS, $, L10N } =
require("./shadereditor");
function ShaderEditorPanel(toolbox) {
this._toolbox = toolbox;
this._destroyer = null;
this.panelWin = window;
EventEmitter.decorate(this);
}
exports.ShaderEditorPanel = ShaderEditorPanel;
ShaderEditorPanel.prototype = {
// Expose symbols for tests:
EVENTS,
$,
L10N,
/**
* Open is effectively an asynchronous constructor.
*
* @return object
* A promise that is resolved when the Shader Editor completes opening.
*/
async open() {
this.front = await this.target.getFront("webgl");
this.shadersListView = new ShadersListView();
this.eventsHandler = new EventsHandler();
this.shadersEditorsView = new ShadersEditorsView();
await this.shadersListView.initialize(this._toolbox, this.shadersEditorsView);
await this.eventsHandler.initialize(this, this._toolbox, this.target, this.front,
this.shadersListView);
await this.shadersEditorsView.initialize(this, this.shadersListView);
this.isReady = true;
this.emit("ready");
return this;
},
// DevToolPanel API
get target() {
return this._toolbox.target;
},
destroy() {
// Make sure this panel is not already destroyed.
if (this._destroyer) {
return this._destroyer;
}
return (this._destroyer = (async () => {
await this.shadersListView.destroy();
await this.eventsHandler.destroy();
await this.shadersEditorsView.destroy();
// Destroy front to ensure packet handler is removed from client
this.front.destroy();
this.emit("destroyed");
})());
},
};

View File

@ -1,625 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const {XPCOMUtils} = require("resource://gre/modules/XPCOMUtils.jsm");
const {SideMenuWidget} = require("devtools/client/shared/widgets/SideMenuWidget.jsm");
const promise = require("promise");
const {Task} = require("devtools/shared/task");
const EventEmitter = require("devtools/shared/event-emitter");
const { HTMLTooltip } = require("devtools/client/shared/widgets/tooltip/HTMLTooltip");
const Editor = require("devtools/client/shared/sourceeditor/editor");
const {LocalizationHelper} = require("devtools/shared/l10n");
const {extend} = require("devtools/shared/extend");
const {WidgetMethods, setNamedTimeout} =
require("devtools/client/shared/widgets/view-helpers");
// The panel's window global is an EventEmitter firing the following events:
const EVENTS = {
// When new programs are received from the server.
NEW_PROGRAM: "ShaderEditor:NewProgram",
PROGRAMS_ADDED: "ShaderEditor:ProgramsAdded",
// When the vertex and fragment sources were shown in the editor.
SOURCES_SHOWN: "ShaderEditor:SourcesShown",
// When a shader's source was edited and compiled via the editor.
SHADER_COMPILED: "ShaderEditor:ShaderCompiled",
// When the UI is reset from tab navigation
UI_RESET: "ShaderEditor:UIReset",
// When the editor's error markers are all removed
EDITOR_ERROR_MARKERS_REMOVED: "ShaderEditor:EditorCleaned",
};
exports.EVENTS = EVENTS;
const XHTML_NS = "http://www.w3.org/1999/xhtml";
const STRINGS_URI = "devtools/client/locales/shadereditor.properties";
const HIGHLIGHT_TINT = [1, 0, 0.25, 1]; // rgba
const TYPING_MAX_DELAY = 500; // ms
const SHADERS_AUTOGROW_ITEMS = 4;
const GUTTER_ERROR_PANEL_OFFSET_X = 7; // px
const GUTTER_ERROR_PANEL_DELAY = 100; // ms
const DEFAULT_EDITOR_CONFIG = {
gutters: ["errors"],
lineNumbers: true,
showAnnotationRuler: true,
};
/**
* Functions handling target-related lifetime events.
*/
class EventsHandler {
/**
* Listen for events emitted by the current tab target.
*/
initialize(panel, toolbox, target, front, shadersListView) {
this.panel = panel;
this.toolbox = toolbox;
this.target = target;
this.front = front;
this.shadersListView = shadersListView;
this._onHostChanged = this._onHostChanged.bind(this);
this._onTabNavigated = this._onTabNavigated.bind(this);
this._onTabWillNavigate = this._onTabWillNavigate.bind(this);
this._onProgramLinked = this._onProgramLinked.bind(this);
this._onProgramsAdded = this._onProgramsAdded.bind(this);
this.toolbox.on("host-changed", this._onHostChanged);
this.target.on("will-navigate", this._onTabWillNavigate);
this.target.on("navigate", this._onTabNavigated);
this.front.on("program-linked", this._onProgramLinked);
this.reloadButton = $("#requests-menu-reload-notice-button");
this._onReloadCommand = this._onReloadCommand.bind(this);
this.reloadButton.addEventListener("command", this._onReloadCommand);
}
/**
* Remove events emitted by the current tab target.
*/
destroy() {
this.toolbox.off("host-changed", this._onHostChanged);
this.target.off("will-navigate", this._onTabWillNavigate);
this.target.off("navigate", this._onTabNavigated);
this.front.off("program-linked", this._onProgramLinked);
this.reloadButton.removeEventListener("command", this._onReloadCommand);
}
/**
* Handles a command event on reload button
*/
_onReloadCommand() {
this.front.setup({ reload: true });
}
/**
* Handles a host change event on the parent toolbox.
*/
_onHostChanged() {
if (this.toolbox.hostType == "right" || this.toolbox.hostType == "left") {
$("#shaders-pane").removeAttribute("height");
}
}
_onTabWillNavigate({isFrameSwitching}) {
// Make sure the backend is prepared to handle WebGL contexts.
if (!isFrameSwitching) {
this.front.setup({ reload: false });
}
// Reset UI.
this.shadersListView.empty();
// When switching to an iframe, ensure displaying the reload button.
// As the document has already been loaded without being hooked.
if (isFrameSwitching) {
$("#reload-notice").hidden = false;
$("#waiting-notice").hidden = true;
} else {
$("#reload-notice").hidden = true;
$("#waiting-notice").hidden = false;
}
$("#content").hidden = true;
this.panel.emit(EVENTS.UI_RESET);
}
/**
* Called for each location change in the debugged tab.
*/
_onTabNavigated() {
// Manually retrieve the list of program actors known to the server,
// because the backend won't emit "program-linked" notifications
// in the case of a bfcache navigation (since no new programs are
// actually linked).
this.front.getPrograms().then(this._onProgramsAdded);
}
/**
* Called every time a program was linked in the debugged tab.
*/
_onProgramLinked(programActor) {
this._addProgram(programActor);
this.panel.emit(EVENTS.NEW_PROGRAM);
}
/**
* Callback for the front's getPrograms() method.
*/
_onProgramsAdded(programActors) {
programActors.forEach(this._addProgram.bind(this));
this.panel.emit(EVENTS.PROGRAMS_ADDED);
}
/**
* Adds a program to the shaders list and unhides any modal notices.
*/
_addProgram(programActor) {
$("#waiting-notice").hidden = true;
$("#reload-notice").hidden = true;
$("#content").hidden = false;
this.shadersListView.addProgram(programActor);
}
}
exports.EventsHandler = EventsHandler;
/**
* Functions handling the sources UI.
*/
function WidgetMethodsClass() {
}
WidgetMethodsClass.prototype = WidgetMethods;
class ShadersListView extends WidgetMethodsClass {
/**
* Initialization function, called when the tool is started.
*/
initialize(toolbox, shadersEditorsView) {
this.toolbox = toolbox;
this.shadersEditorsView = shadersEditorsView;
this.widget = new SideMenuWidget(this._pane = $("#shaders-pane"), {
showArrows: true,
showItemCheckboxes: true,
});
this._onProgramSelect = this._onProgramSelect.bind(this);
this._onProgramCheck = this._onProgramCheck.bind(this);
this._onProgramMouseOver = this._onProgramMouseOver.bind(this);
this._onProgramMouseOut = this._onProgramMouseOut.bind(this);
this.widget.addEventListener("select", this._onProgramSelect);
this.widget.addEventListener("check", this._onProgramCheck);
this.widget.addEventListener("mouseover", this._onProgramMouseOver, true);
this.widget.addEventListener("mouseout", this._onProgramMouseOut, true);
}
/**
* Destruction function, called when the tool is closed.
*/
destroy() {
this.widget.removeEventListener("select", this._onProgramSelect);
this.widget.removeEventListener("check", this._onProgramCheck);
this.widget.removeEventListener("mouseover", this._onProgramMouseOver, true);
this.widget.removeEventListener("mouseout", this._onProgramMouseOut, true);
}
/**
* Adds a program to this programs container.
*
* @param object programActor
* The program actor coming from the active thread.
*/
addProgram(programActor) {
if (this.hasProgram(programActor)) {
return;
}
// Currently, there's no good way of differentiating between programs
// in a way that helps humans. It will be a good idea to implement a
// standard of allowing debuggees to add some identifiable metadata to their
// program sources or instances.
const label = L10N.getFormatStr("shadersList.programLabel", this.itemCount);
const contents = document.createElement("label");
contents.className = "plain program-item";
contents.setAttribute("value", label);
contents.setAttribute("crop", "start");
contents.setAttribute("flex", "1");
// Append a program item to this container.
this.push([contents], {
index: -1, /* specifies on which position should the item be appended */
attachment: {
label: label,
programActor: programActor,
checkboxState: true,
checkboxTooltip: L10N.getStr("shadersList.blackboxLabel"),
},
});
// Make sure there's always a selected item available.
if (!this.selectedItem) {
this.selectedIndex = 0;
}
// Prevent this container from growing indefinitely in height when the
// toolbox is docked to the side.
if ((this.toolbox.hostType == "left" || this.toolbox.hostType == "right") &&
this.itemCount == SHADERS_AUTOGROW_ITEMS) {
this._pane.setAttribute("height", this._pane.getBoundingClientRect().height);
}
}
/**
* Returns whether a program was already added to this programs container.
*
* @param object programActor
* The program actor coming from the active thread.
* @param boolean
* True if the program was added, false otherwise.
*/
hasProgram(programActor) {
return !!this.attachments.filter(e => e.programActor == programActor).length;
}
/**
* The select listener for the programs container.
*/
_onProgramSelect({ detail: sourceItem }) {
if (!sourceItem) {
return;
}
// The container is not empty and an actual item was selected.
const attachment = sourceItem.attachment;
function getShaders() {
return promise.all([
attachment.vs || (attachment.vs = attachment.programActor.getVertexShader()),
attachment.fs || (attachment.fs = attachment.programActor.getFragmentShader()),
]);
}
function getSources([vertexShaderActor, fragmentShaderActor]) {
return promise.all([
vertexShaderActor.getText(),
fragmentShaderActor.getText(),
]);
}
const showSources = ([vertexShaderText, fragmentShaderText]) => {
return this.shadersEditorsView.setText({
vs: vertexShaderText,
fs: fragmentShaderText,
});
};
getShaders()
.then(getSources)
.then(showSources)
.catch(console.error);
}
/**
* The check listener for the programs container.
*/
_onProgramCheck({ detail: { checked }, target }) {
const sourceItem = this.getItemForElement(target);
const attachment = sourceItem.attachment;
attachment.isBlackBoxed = !checked;
attachment.programActor[checked ? "unblackbox" : "blackbox"]();
}
/**
* The mouseover listener for the programs container.
*/
_onProgramMouseOver(e) {
const sourceItem = this.getItemForElement(e.target, { noSiblings: true });
if (sourceItem && !sourceItem.attachment.isBlackBoxed) {
sourceItem.attachment.programActor.highlight(HIGHLIGHT_TINT);
if (e instanceof Event) {
e.preventDefault();
e.stopPropagation();
}
}
}
/**
* The mouseout listener for the programs container.
*/
_onProgramMouseOut(e) {
const sourceItem = this.getItemForElement(e.target, { noSiblings: true });
if (sourceItem && !sourceItem.attachment.isBlackBoxed) {
sourceItem.attachment.programActor.unhighlight();
if (e instanceof Event) {
e.preventDefault();
e.stopPropagation();
}
}
}
}
exports.ShadersListView = ShadersListView;
/**
* Functions handling the editors displaying the vertex and fragment shaders.
*/
class ShadersEditorsView {
/**
* Initialization function, called when the tool is started.
*/
initialize(panel, shadersListView) {
this.panel = panel;
this.shadersListView = shadersListView;
XPCOMUtils.defineLazyGetter(this, "_editorPromises", () => new Map());
this._vsFocused = this._onFocused.bind(this, "vs", "fs");
this._fsFocused = this._onFocused.bind(this, "fs", "vs");
this._vsChanged = this._onChanged.bind(this, "vs");
this._fsChanged = this._onChanged.bind(this, "fs");
this._errors = {
vs: [],
fs: [],
};
}
/**
* Destruction function, called when the tool is closed.
*/
async destroy() {
this._destroyed = true;
await this._toggleListeners("off");
for (const p of this._editorPromises.values()) {
const editor = await p;
editor.destroy();
}
}
/**
* Sets the text displayed in the vertex and fragment shader editors.
*
* @param object sources
* An object containing the following properties
* - vs: the vertex shader source code
* - fs: the fragment shader source code
* @return object
* A promise resolving upon completion of text setting.
*/
setText(sources) {
const view = this;
function setTextAndClearHistory(editor, text) {
editor.setText(text);
editor.clearHistory();
}
return (async function() {
await view._toggleListeners("off");
await promise.all([
view._getEditor("vs").then(e => setTextAndClearHistory(e, sources.vs)),
view._getEditor("fs").then(e => setTextAndClearHistory(e, sources.fs)),
]);
await view._toggleListeners("on");
})().then(() => this.panel.emit(EVENTS.SOURCES_SHOWN, sources));
}
/**
* Lazily initializes and returns a promise for an Editor instance.
*
* @param string type
* Specifies for which shader type should an editor be retrieved,
* either are "vs" for a vertex, or "fs" for a fragment shader.
* @return object
* Returns a promise that resolves to an editor instance
*/
_getEditor(type) {
if (this._editorPromises.has(type)) {
return this._editorPromises.get(type);
}
const promise = new Promise(resolve =>{
// Initialize the source editor and store the newly created instance
// in the ether of a resolved promise's value.
const parent = $("#" + type + "-editor");
const editor = new Editor(DEFAULT_EDITOR_CONFIG);
editor.config.mode = Editor.modes[type];
if (this._destroyed) {
resolve(editor);
} else {
editor.appendTo(parent).then(() => resolve(editor));
}
});
this._editorPromises.set(type, promise);
return promise;
}
/**
* Toggles all the event listeners for the editors either on or off.
*
* @param string flag
* Either "on" to enable the event listeners, "off" to disable them.
* @return object
* A promise resolving upon completion of toggling the listeners.
*/
_toggleListeners(flag) {
return promise.all(["vs", "fs"].map(type => {
return this._getEditor(type).then(editor => {
editor[flag]("focus", this["_" + type + "Focused"]);
editor[flag]("change", this["_" + type + "Changed"]);
});
}));
}
/**
* The focus listener for a source editor.
*
* @param string focused
* The corresponding shader type for the focused editor (e.g. "vs").
* @param string focused
* The corresponding shader type for the other editor (e.g. "fs").
*/
_onFocused(focused, unfocused) {
$("#" + focused + "-editor-label").setAttribute("selected", "");
$("#" + unfocused + "-editor-label").removeAttribute("selected");
}
/**
* The change listener for a source editor.
*
* @param string type
* The corresponding shader type for the focused editor (e.g. "vs").
*/
_onChanged(type) {
setNamedTimeout("gl-typed", TYPING_MAX_DELAY, () => this._doCompile(type));
// Remove all the gutter markers and line classes from the editor.
this._cleanEditor(type);
}
/**
* Recompiles the source code for the shader being edited.
* This function is fired at a certain delay after the user stops typing.
*
* @param string type
* The corresponding shader type for the focused editor (e.g. "vs").
*/
_doCompile(type) {
(async function() {
const editor = await this._getEditor(type);
const shaderActor = await this.shadersListView.selectedAttachment[type];
try {
await shaderActor.compile(editor.getText());
this._onSuccessfulCompilation();
} catch (e) {
this._onFailedCompilation(type, editor, e);
}
}.bind(this))();
}
/**
* Called uppon a successful shader compilation.
*/
_onSuccessfulCompilation() {
// Signal that the shader was compiled successfully.
this.panel.emit(EVENTS.SHADER_COMPILED, null);
}
/**
* Called uppon an unsuccessful shader compilation.
*/
_onFailedCompilation(type, editor, errors) {
const lineCount = editor.lineCount();
const currentLine = editor.getCursor().line;
const listeners = { mouseover: this._onMarkerMouseOver };
function matchLinesAndMessages(string) {
return {
// First number that is not equal to 0.
lineMatch: string.match(/\d{2,}|[1-9]/),
// The string after all the numbers, semicolons and spaces.
textMatch: string.match(/[^\s\d:][^\r\n|]*/),
};
}
function discardInvalidMatches(e) {
// Discard empty line and text matches.
return e.lineMatch && e.textMatch;
}
function sanitizeValidMatches(e) {
return {
// Drivers might yield confusing line numbers under some obscure
// circumstances. Don't throw the errors away in those cases,
// just display them on the currently edited line.
line: e.lineMatch[0] > lineCount ? currentLine : e.lineMatch[0] - 1,
// Trim whitespace from the beginning and the end of the message,
// and replace all other occurences of double spaces to a single space.
text: e.textMatch[0].trim().replace(/\s{2,}/g, " "),
};
}
function sortByLine(first, second) {
// Sort all the errors ascending by their corresponding line number.
return first.line > second.line ? 1 : -1;
}
function groupSameLineMessages(accumulator, current) {
// Group errors corresponding to the same line number to a single object.
const previous = accumulator[accumulator.length - 1];
if (!previous || previous.line != current.line) {
return [...accumulator, {
line: current.line,
messages: [current.text],
}];
}
previous.messages.push(current.text);
return accumulator;
}
function displayErrors({ line, messages }) {
// Add gutter markers and line classes for every error in the source.
editor.addMarker(line, "errors", "error");
editor.setMarkerListeners(line, "errors", "error", listeners, messages);
editor.addLineClass(line, "error-line");
}
(this._errors[type] = errors.link
.split("ERROR")
.map(matchLinesAndMessages)
.filter(discardInvalidMatches)
.map(sanitizeValidMatches)
.sort(sortByLine)
.reduce(groupSameLineMessages, []))
.forEach(displayErrors);
// Signal that the shader wasn't compiled successfully.
this.panel.emit(EVENTS.SHADER_COMPILED, errors);
}
/**
* Event listener for the 'mouseover' event on a marker in the editor gutter.
*/
_onMarkerMouseOver(line, node, messages) {
if (node._markerErrorsTooltip) {
return;
}
const tooltip = node._markerErrorsTooltip = new HTMLTooltip(document, {
type: "arrow",
useXulWrapper: true,
});
const div = document.createElementNS(XHTML_NS, "div");
div.className = "devtools-shader-tooltip-container";
for (const message of messages) {
const messageDiv = document.createElementNS(XHTML_NS, "div");
messageDiv.className = "devtools-tooltip-simple-text";
messageDiv.textContent = message;
div.appendChild(messageDiv);
}
tooltip.panel.appendChild(div);
tooltip.startTogglingOnHover(node, () => true, {
toggleDelay: GUTTER_ERROR_PANEL_DELAY,
});
}
/**
* Removes all the gutter markers and line classes from the editor.
*/
_cleanEditor(type) {
this._getEditor(type).then(editor => {
editor.removeAllMarkers("errors");
this._errors[type].forEach(e => editor.removeLineClass(e.line));
this._errors[type].length = 0;
this.panel.emit(EVENTS.EDITOR_ERROR_MARKERS_REMOVED);
});
}
}
exports.ShadersEditorsView = ShadersEditorsView;
/**
* Localization convenience methods.
*/
var L10N = new LocalizationHelper(STRINGS_URI);
exports.L10N = L10N;
/**
* DOM query helper.
*/
var $ = (selector, target = document) => target.querySelector(selector);
exports.$ = $;

View File

@ -1,6 +0,0 @@
"use strict";
module.exports = {
// Extend from the shared list of defined globals for mochitests.
"extends": "../../../.eslintrc.mochitests.js"
};

View File

@ -1,59 +0,0 @@
[DEFAULT]
tags = devtools
subsuite = devtools
support-files =
doc_blended-geometry.html
doc_multiple-contexts.html
doc_overlapping-geometry.html
doc_shader-order.html
doc_simple-canvas.html
head.js
!/devtools/client/shared/test/frame-script-utils.js
!/devtools/client/shared/test/shared-head.js
!/devtools/client/shared/test/telemetry-test-helpers.js
[browser_se_aaa_run_first_leaktest.js]
[browser_se_bfcache.js]
skip-if = true # Bug 942473, caused by Bug 940541
[browser_se_editors-contents.js]
skip-if = (verify && (os == 'win'))
[browser_se_editors-error-gutter.js]
skip-if = (verify && !debug && (os == 'win'))
[browser_se_editors-error-tooltip.js]
skip-if = (verify && (os == 'win' || os == 'linux'))
[browser_se_editors-lazy-init.js]
[browser_se_first-run.js]
[browser_se_navigation.js]
[browser_se_programs-blackbox-01.js]
[browser_se_programs-blackbox-02.js]
[browser_se_programs-cache.js]
[browser_se_programs-highlight-01.js]
skip-if = (verify && debug && (os == 'win'))
[browser_se_programs-highlight-02.js]
[browser_se_programs-list.js]
[browser_se_shaders-edit-01.js]
[browser_se_shaders-edit-02.js]
[browser_se_shaders-edit-03.js]
skip-if = (verify && (os == 'win'))
[browser_webgl-actor-test-01.js]
[browser_webgl-actor-test-02.js]
[browser_webgl-actor-test-03.js]
[browser_webgl-actor-test-04.js]
[browser_webgl-actor-test-05.js]
skip-if = (verify && !debug && (os == 'linux'))
[browser_webgl-actor-test-06.js]
skip-if = (verify && (os == 'linux'))
[browser_webgl-actor-test-07.js]
[browser_webgl-actor-test-08.js]
skip-if = (verify && debug && (os == 'win'))
[browser_webgl-actor-test-09.js]
[browser_webgl-actor-test-10.js]
[browser_webgl-actor-test-11.js]
[browser_webgl-actor-test-12.js]
[browser_webgl-actor-test-13.js]
[browser_webgl-actor-test-14.js]
[browser_webgl-actor-test-15.js]
[browser_webgl-actor-test-16.js]
[browser_webgl-actor-test-17.js]
skip-if = (verify && debug && (os == 'win'))
[browser_webgl-actor-test-18.js]

View File

@ -1,17 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests if the shader editor leaks on initialization and sudden destruction.
* You can also use this initialization format as a template for other tests.
*/
async function ifWebGLSupported() {
const { target, panel } = await initShaderEditor(SIMPLE_CANVAS_URL);
ok(target, "Should have a target available.");
ok(panel, "Should have a panel available.");
await teardown(panel);
finish();
}

View File

@ -1,60 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests if the shader editor works with bfcache.
*/
async function ifWebGLSupported() {
const { target, panel } = await initShaderEditor(SIMPLE_CANVAS_URL);
const { front, $, EVENTS, shadersListView, shadersEditorsView } = panel;
// Attach frame scripts if in e10s to perform
// history navigation via the content
loadFrameScripts();
const reloaded = reload(target);
const firstProgram = await once(front, "program-linked");
await reloaded;
const navigated = navigate(target, MULTIPLE_CONTEXTS_URL);
const [secondProgram, thirdProgram] = await getPrograms(front, 2);
await navigated;
const vsEditor = await shadersEditorsView._getEditor("vs");
const fsEditor = await shadersEditorsView._getEditor("fs");
await navigateInHistory(target, "back", "will-navigate");
await once(panel, EVENTS.PROGRAMS_ADDED);
await once(panel, EVENTS.SOURCES_SHOWN);
is($("#content").hidden, false,
"The tool's content should not be hidden.");
is(shadersListView.itemCount, 1,
"The shaders list contains one entry after navigating back.");
is(shadersListView.selectedIndex, 0,
"The shaders list has a correct selection after navigating back.");
is(vsEditor.getText().indexOf("gl_Position"), 170,
"The vertex shader editor contains the correct text.");
is(fsEditor.getText().indexOf("gl_FragColor"), 97,
"The fragment shader editor contains the correct text.");
await navigateInHistory(target, "forward", "will-navigate");
await once(panel, EVENTS.PROGRAMS_ADDED);
await once(panel, EVENTS.SOURCES_SHOWN);
is($("#content").hidden, false,
"The tool's content should not be hidden.");
is(shadersListView.itemCount, 2,
"The shaders list contains two entries after navigating forward.");
is(shadersListView.selectedIndex, 0,
"The shaders list has a correct selection after navigating forward.");
is(vsEditor.getText().indexOf("gl_Position"), 100,
"The vertex shader editor contains the correct text.");
is(fsEditor.getText().indexOf("gl_FragColor"), 89,
"The fragment shader editor contains the correct text.");
await teardown(panel);
finish();
}

View File

@ -1,29 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests if the editors contain the correct text when a program
* becomes available.
*/
async function ifWebGLSupported() {
const { target, panel } = await initShaderEditor(SIMPLE_CANVAS_URL);
const { front, shadersEditorsView, EVENTS } = panel;
reload(target);
await promise.all([
once(front, "program-linked"),
once(panel, EVENTS.SOURCES_SHOWN),
]);
const vsEditor = await shadersEditorsView._getEditor("vs");
const fsEditor = await shadersEditorsView._getEditor("fs");
is(vsEditor.getText().indexOf("gl_Position"), 170,
"The vertex shader editor contains the correct text.");
is(fsEditor.getText().indexOf("gl_FragColor"), 97,
"The fragment shader editor contains the correct text.");
await teardown(panel);
finish();
}

View File

@ -1,160 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests if error indicators are shown in the editor's gutter and text area
* when there's a shader compilation error.
*/
async function ifWebGLSupported() {
const { target, panel } = await initShaderEditor(SIMPLE_CANVAS_URL);
const { front, EVENTS, shadersEditorsView } = panel;
reload(target);
await promise.all([
once(front, "program-linked"),
once(panel, EVENTS.SOURCES_SHOWN),
]);
const vsEditor = await shadersEditorsView._getEditor("vs");
const fsEditor = await shadersEditorsView._getEditor("fs");
vsEditor.replaceText("vec3", { line: 7, ch: 22 }, { line: 7, ch: 26 });
let vertError = await panel.once(EVENTS.SHADER_COMPILED);
checkHasVertFirstError(true, vertError);
checkHasVertSecondError(false, vertError);
info("Error marks added in the vertex shader editor.");
vsEditor.insertText(" ", { line: 1, ch: 0 });
await panel.once(EVENTS.EDITOR_ERROR_MARKERS_REMOVED);
is(vsEditor.getText(1), " precision lowp float;", "Typed space.");
checkHasVertFirstError(false, vertError);
checkHasVertSecondError(false, vertError);
info("Error marks removed while typing in the vertex shader editor.");
vertError = await panel.once(EVENTS.SHADER_COMPILED);
checkHasVertFirstError(true, vertError);
checkHasVertSecondError(false, vertError);
info("Error marks were re-added after recompiling the vertex shader.");
fsEditor.replaceText("vec4", { line: 2, ch: 14 }, { line: 2, ch: 18 });
let fragError = await panel.once(EVENTS.SHADER_COMPILED);
checkHasVertFirstError(true, vertError);
checkHasVertSecondError(false, vertError);
checkHasFragError(true, fragError);
info("Error marks added in the fragment shader editor.");
fsEditor.insertText(" ", { line: 1, ch: 0 });
await panel.once(EVENTS.EDITOR_ERROR_MARKERS_REMOVED);
is(fsEditor.getText(1), " precision lowp float;", "Typed space.");
checkHasVertFirstError(true, vertError);
checkHasVertSecondError(false, vertError);
checkHasFragError(false, fragError);
info("Error marks removed while typing in the fragment shader editor.");
fragError = await panel.once(EVENTS.SHADER_COMPILED);
checkHasVertFirstError(true, vertError);
checkHasVertSecondError(false, vertError);
checkHasFragError(true, fragError);
info("Error marks were re-added after recompiling the fragment shader.");
vsEditor.replaceText("2", { line: 3, ch: 19 }, { line: 3, ch: 20 });
await panel.once(EVENTS.EDITOR_ERROR_MARKERS_REMOVED);
checkHasVertFirstError(false, vertError);
checkHasVertSecondError(false, vertError);
checkHasFragError(true, fragError);
info("Error marks removed while typing in the vertex shader editor again.");
vertError = await panel.once(EVENTS.SHADER_COMPILED);
checkHasVertFirstError(true, vertError);
checkHasVertSecondError(true, vertError);
checkHasFragError(true, fragError);
info("Error marks were re-added after recompiling the fragment shader again.");
await teardown(panel);
finish();
function checkHasVertFirstError(bool, error) {
ok(error, "Vertex shader compiled with errors.");
isnot(error.link, "", "The linkage status should not be empty.");
const line = 7;
info("Checking first vertex shader error on line " + line + "...");
is(vsEditor.hasMarker(line, "errors", "error"), bool,
"Error is " + (bool ? "" : "not ") + "shown in the editor's gutter.");
is(vsEditor.hasLineClass(line, "error-line"), bool,
"Error style is " + (bool ? "" : "not ") + "applied to the faulty line.");
const parsed = shadersEditorsView._errors.vs;
is(parsed.length >= 1, bool,
"There's " + (bool ? ">= 1" : "< 1") + " parsed vertex shader error(s).");
if (bool) {
is(parsed[0].line, line,
"The correct line was parsed.");
is(parsed[0].messages.length, 3,
"There are 3 parsed messages.");
ok(parsed[0].messages[0].includes("'constructor' : too many arguments"),
"The correct first message was parsed.");
ok(parsed[0].messages[1].includes("'=' : dimension mismatch"),
"The correct second message was parsed.");
ok(parsed[0].messages[2].includes("'assign' : cannot convert from"),
"The correct third message was parsed.");
}
}
function checkHasVertSecondError(bool, error) {
ok(error, "Vertex shader compiled with errors.");
isnot(error.link, "", "The linkage status should not be empty.");
const line = 8;
info("Checking second vertex shader error on line " + line + "...");
is(vsEditor.hasMarker(line, "errors", "error"), bool,
"Error is " + (bool ? "" : "not ") + "shown in the editor's gutter.");
is(vsEditor.hasLineClass(line, "error-line"), bool,
"Error style is " + (bool ? "" : "not ") + "applied to the faulty line.");
const parsed = shadersEditorsView._errors.vs;
is(parsed.length >= 2, bool,
"There's " + (bool ? ">= 2" : "< 2") + " parsed vertex shader error(s).");
if (bool) {
is(parsed[1].line, line,
"The correct line was parsed.");
is(parsed[1].messages.length, 2,
"There is 2 parsed messages.");
ok(parsed[1].messages[0].includes("'=' : dimension mismatch"),
"The correct first message was parsed.");
ok(parsed[1].messages[1].includes("'assign' : cannot convert from"),
"The correct second message was parsed.");
}
}
function checkHasFragError(bool, error) {
ok(error, "Fragment shader compiled with errors.");
isnot(error.link, "", "The linkage status should not be empty.");
const line = 5;
info("Checking first vertex shader error on line " + line + "...");
is(fsEditor.hasMarker(line, "errors", "error"), bool,
"Error is " + (bool ? "" : "not ") + "shown in the editor's gutter.");
is(fsEditor.hasLineClass(line, "error-line"), bool,
"Error style is " + (bool ? "" : "not ") + "applied to the faulty line.");
const parsed = shadersEditorsView._errors.fs;
is(parsed.length >= 1, bool,
"There's " + (bool ? ">= 2" : "< 1") + " parsed fragment shader error(s).");
if (bool) {
is(parsed[0].line, line,
"The correct line was parsed.");
is(parsed[0].messages.length, 1,
"There is 1 parsed message.");
ok(parsed[0].messages[0].includes("'constructor' : too many arguments"),
"The correct message was parsed.");
}
}
}

View File

@ -1,58 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests if error tooltips can be opened from the editor's gutter when there's
* a shader compilation error.
*/
async function ifWebGLSupported() {
const { target, panel } = await initShaderEditor(SIMPLE_CANVAS_URL);
const { front, EVENTS, shadersEditorsView } = panel;
reload(target);
await promise.all([
once(front, "program-linked"),
once(panel, EVENTS.SOURCES_SHOWN),
]);
const vsEditor = await shadersEditorsView._getEditor("vs");
const fsEditor = await shadersEditorsView._getEditor("fs");
vsEditor.replaceText("vec3", { line: 7, ch: 22 }, { line: 7, ch: 26 });
await once(panel, EVENTS.SHADER_COMPILED);
// Synthesizing 'mouseover' events doesn't work, hack around this by
// manually calling the event listener with the expected arguments.
const editorDocument = vsEditor.container.contentDocument;
const marker = editorDocument.querySelector(".error");
const parsed = shadersEditorsView._errors.vs[0].messages;
shadersEditorsView._onMarkerMouseOver(7, marker, parsed);
const tooltip = marker._markerErrorsTooltip;
ok(tooltip, "A tooltip was created successfully.");
const containerClass = ".devtools-shader-tooltip-container";
const container = tooltip.panel.querySelector(containerClass);
ok(container, "The tooltip's content container was created correctly.");
const messages = container.childNodes;
is(messages.length, 3,
"There are three messages displayed in the tooltip.");
ok(messages[0].className.includes("devtools-tooltip-simple-text"),
"The first message was created correctly.");
ok(messages[1].className.includes("devtools-tooltip-simple-text"),
"The second message was created correctly.");
ok(messages[2].className.includes("devtools-tooltip-simple-text"),
"The third message was created correctly.");
ok(messages[0].textContent.includes("'constructor' : too many arguments"),
"The first message contains the correct text.");
ok(messages[1].textContent.includes("'=' : dimension mismatch"),
"The second message contains the correct text.");
ok(messages[2].textContent.includes("'assign' : cannot convert"),
"The third message contains the correct text.");
await teardown(panel);
finish();
}

View File

@ -1,34 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests if source editors are lazily initialized.
*/
async function ifWebGLSupported() {
const { target, panel } = await initShaderEditor(SIMPLE_CANVAS_URL);
const { front, shadersEditorsView } = panel;
reload(target);
await once(front, "program-linked");
const vsEditor = await shadersEditorsView._getEditor("vs");
const fsEditor = await shadersEditorsView._getEditor("fs");
ok(vsEditor, "A vertex shader editor was initialized.");
ok(fsEditor, "A fragment shader editor was initialized.");
isnot(vsEditor, fsEditor,
"The vertex shader editor is distinct from the fragment shader editor.");
const vsEditor2 = await shadersEditorsView._getEditor("vs");
const fsEditor2 = await shadersEditorsView._getEditor("fs");
is(vsEditor, vsEditor2,
"The vertex shader editor instances are cached.");
is(fsEditor, fsEditor2,
"The fragment shader editor instances are cached.");
await teardown(panel);
finish();
}

View File

@ -1,43 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests if the shader editor shows the appropriate UI when opened.
*/
async function ifWebGLSupported() {
const { target, panel } = await initShaderEditor(SIMPLE_CANVAS_URL);
const { front, $ } = panel;
is($("#reload-notice").hidden, false,
"The 'reload this page' notice should initially be visible.");
is($("#waiting-notice").hidden, true,
"The 'waiting for a WebGL context' notice should initially be hidden.");
is($("#content").hidden, true,
"The tool's content should initially be hidden.");
const navigating = once(target, "will-navigate");
const linked = once(front, "program-linked");
reload(target);
await navigating;
is($("#reload-notice").hidden, true,
"The 'reload this page' notice should be hidden when navigating.");
is($("#waiting-notice").hidden, false,
"The 'waiting for a WebGL context' notice should be visible when navigating.");
is($("#content").hidden, true,
"The tool's content should still be hidden.");
await linked;
is($("#reload-notice").hidden, true,
"The 'reload this page' notice should be hidden after linking.");
is($("#waiting-notice").hidden, true,
"The 'waiting for a WebGL context' notice should be hidden after linking.");
is($("#content").hidden, false,
"The tool's content should not be hidden anymore.");
await teardown(panel);
finish();
}

View File

@ -1,71 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests target navigations are handled correctly in the UI.
*/
async function ifWebGLSupported() {
const { target, panel } = await initShaderEditor(SIMPLE_CANVAS_URL);
const { front, $, EVENTS, shadersListView, shadersEditorsView } = panel;
reload(target);
await promise.all([
once(front, "program-linked"),
once(panel, EVENTS.SOURCES_SHOWN),
]);
is($("#reload-notice").hidden, true,
"The 'reload this page' notice should be hidden after linking.");
is($("#waiting-notice").hidden, true,
"The 'waiting for a WebGL context' notice should be visible after linking.");
is($("#content").hidden, false,
"The tool's content should not be hidden anymore.");
is(shadersListView.itemCount, 1,
"The shaders list contains one entry.");
is(shadersListView.selectedItem, shadersListView.items[0],
"The shaders list has a correct item selected.");
is(shadersListView.selectedIndex, 0,
"The shaders list has a correct index selected.");
const vsEditor = await shadersEditorsView._getEditor("vs");
const fsEditor = await shadersEditorsView._getEditor("fs");
is(vsEditor.getText().indexOf("gl_Position"), 170,
"The vertex shader editor contains the correct text.");
is(fsEditor.getText().indexOf("gl_FragColor"), 97,
"The fragment shader editor contains the correct text.");
const navigating = once(target, "will-navigate");
const navigated = once(target, "will-navigate");
navigate(target, "about:blank");
await promise.all([navigating, once(panel, EVENTS.UI_RESET) ]);
is($("#reload-notice").hidden, true,
"The 'reload this page' notice should be hidden while navigating.");
is($("#waiting-notice").hidden, false,
"The 'waiting for a WebGL context' notice should be visible while navigating.");
is($("#content").hidden, true,
"The tool's content should be hidden now that there's no WebGL content.");
is(shadersListView.itemCount, 0,
"The shaders list should be empty.");
is(shadersListView.selectedItem, null,
"The shaders list has no correct item.");
is(shadersListView.selectedIndex, -1,
"The shaders list has a negative index.");
await navigated;
is($("#reload-notice").hidden, true,
"The 'reload this page' notice should still be hidden after navigating.");
is($("#waiting-notice").hidden, false,
"The 'waiting for a WebGL context' notice should still be visible after navigating.");
is($("#content").hidden, true,
"The tool's content should be still hidden since there's no WebGL content.");
await teardown(panel);
finish();
}

View File

@ -1,163 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests if blackboxing a program works properly.
*/
async function ifWebGLSupported() {
const { target, debuggee, panel } = await initShaderEditor(MULTIPLE_CONTEXTS_URL);
const { front, EVENTS, shadersListView, shadersEditorsView } = panel;
once(panel, EVENTS.SHADER_COMPILED).then(() => {
ok(false, "No shaders should be publicly compiled during this test.");
});
reload(target);
const [[firstProgramActor, secondProgramActor]] = await promise.all([
getPrograms(front, 2),
once(panel, EVENTS.SOURCES_SHOWN),
]);
const vsEditor = await shadersEditorsView._getEditor("vs");
const fsEditor = await shadersEditorsView._getEditor("fs");
vsEditor.once("change", () => {
ok(false, "The vertex shader source was unexpectedly changed.");
});
fsEditor.once("change", () => {
ok(false, "The fragment shader source was unexpectedly changed.");
});
once(panel, EVENTS.SOURCES_SHOWN).then(() => {
ok(false, "No sources should be changed form this point onward.");
});
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 255, g: 255, b: 0, a: 255 }, true, "#canvas1");
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 0, g: 255, b: 255, a: 255 }, true, "#canvas2");
await ensurePixelIs(front, { x: 127, y: 127 }, { r: 255, g: 255, b: 0, a: 255 }, true, "#canvas1");
await ensurePixelIs(front, { x: 127, y: 127 }, { r: 0, g: 255, b: 255, a: 255 }, true, "#canvas2");
ok(!shadersListView.selectedAttachment.isBlackBoxed,
"The first program should not be blackboxed yet.");
is(getBlackBoxCheckbox(panel, 0).checked, true,
"The first blackbox checkbox should be initially checked.");
ok(!shadersListView.attachments[1].isBlackBoxed,
"The second program should not be blackboxed yet.");
is(getBlackBoxCheckbox(panel, 1).checked, true,
"The second blackbox checkbox should be initially checked.");
getBlackBoxCheckbox(panel, 0).click();
ok(shadersListView.selectedAttachment.isBlackBoxed,
"The first program should now be blackboxed.");
is(getBlackBoxCheckbox(panel, 0).checked, false,
"The first blackbox checkbox should now be unchecked.");
ok(!shadersListView.attachments[1].isBlackBoxed,
"The second program should still not be blackboxed.");
is(getBlackBoxCheckbox(panel, 1).checked, true,
"The second blackbox checkbox should still be checked.");
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 0, g: 0, b: 0, a: 255 }, true, "#canvas1");
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 0, g: 255, b: 255, a: 255 }, true, "#canvas2");
await ensurePixelIs(front, { x: 127, y: 127 }, { r: 0, g: 0, b: 0, a: 255 }, true, "#canvas1");
await ensurePixelIs(front, { x: 127, y: 127 }, { r: 0, g: 255, b: 255, a: 255 }, true, "#canvas2");
ok(true, "The first program was correctly blackboxed.");
getBlackBoxCheckbox(panel, 1).click();
ok(shadersListView.selectedAttachment.isBlackBoxed,
"The first program should still be blackboxed.");
is(getBlackBoxCheckbox(panel, 0).checked, false,
"The first blackbox checkbox should still be unchecked.");
ok(shadersListView.attachments[1].isBlackBoxed,
"The second program should now be blackboxed.");
is(getBlackBoxCheckbox(panel, 1).checked, false,
"The second blackbox checkbox should now be unchecked.");
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 0, g: 0, b: 0, a: 255 }, true, "#canvas1");
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 0, g: 0, b: 0, a: 255 }, true, "#canvas2");
await ensurePixelIs(front, { x: 127, y: 127 }, { r: 0, g: 0, b: 0, a: 255 }, true, "#canvas1");
await ensurePixelIs(front, { x: 127, y: 127 }, { r: 0, g: 0, b: 0, a: 255 }, true, "#canvas2");
ok(true, "The second program was correctly blackboxed.");
shadersListView._onProgramMouseOver({ target: getItemLabel(panel, 0) });
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 0, g: 0, b: 0, a: 255 }, true, "#canvas1");
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 0, g: 0, b: 0, a: 255 }, true, "#canvas2");
await ensurePixelIs(front, { x: 127, y: 127 }, { r: 0, g: 0, b: 0, a: 255 }, true, "#canvas1");
await ensurePixelIs(front, { x: 127, y: 127 }, { r: 0, g: 0, b: 0, a: 255 }, true, "#canvas2");
ok(true, "Highlighting shouldn't work while blackboxed (1).");
shadersListView._onProgramMouseOut({ target: getItemLabel(panel, 0) });
shadersListView._onProgramMouseOver({ target: getItemLabel(panel, 1) });
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 0, g: 0, b: 0, a: 255 }, true, "#canvas1");
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 0, g: 0, b: 0, a: 255 }, true, "#canvas2");
await ensurePixelIs(front, { x: 127, y: 127 }, { r: 0, g: 0, b: 0, a: 255 }, true, "#canvas1");
await ensurePixelIs(front, { x: 127, y: 127 }, { r: 0, g: 0, b: 0, a: 255 }, true, "#canvas2");
ok(true, "Highlighting shouldn't work while blackboxed (2).");
shadersListView._onProgramMouseOut({ target: getItemLabel(panel, 1) });
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 0, g: 0, b: 0, a: 255 }, true, "#canvas1");
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 0, g: 0, b: 0, a: 255 }, true, "#canvas2");
await ensurePixelIs(front, { x: 127, y: 127 }, { r: 0, g: 0, b: 0, a: 255 }, true, "#canvas1");
await ensurePixelIs(front, { x: 127, y: 127 }, { r: 0, g: 0, b: 0, a: 255 }, true, "#canvas2");
ok(true, "Highlighting shouldn't work while blackboxed (3).");
getBlackBoxCheckbox(panel, 0).click();
getBlackBoxCheckbox(panel, 1).click();
ok(!shadersListView.selectedAttachment.isBlackBoxed,
"The first program should now be unblackboxed.");
is(getBlackBoxCheckbox(panel, 0).checked, true,
"The first blackbox checkbox should now be rechecked.");
ok(!shadersListView.attachments[1].isBlackBoxed,
"The second program should now be unblackboxed.");
is(getBlackBoxCheckbox(panel, 1).checked, true,
"The second blackbox checkbox should now be rechecked.");
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 255, g: 255, b: 0, a: 255 }, true, "#canvas1");
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 0, g: 255, b: 255, a: 255 }, true, "#canvas2");
await ensurePixelIs(front, { x: 127, y: 127 }, { r: 255, g: 255, b: 0, a: 255 }, true, "#canvas1");
await ensurePixelIs(front, { x: 127, y: 127 }, { r: 0, g: 255, b: 255, a: 255 }, true, "#canvas2");
ok(true, "The two programs were correctly unblackboxed.");
shadersListView._onProgramMouseOver({ target: getItemLabel(panel, 0) });
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 255, g: 0, b: 0, a: 255 }, true, "#canvas1");
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 0, g: 255, b: 255, a: 255 }, true, "#canvas2");
await ensurePixelIs(front, { x: 127, y: 127 }, { r: 255, g: 0, b: 0, a: 255 }, true, "#canvas1");
await ensurePixelIs(front, { x: 127, y: 127 }, { r: 0, g: 255, b: 255, a: 255 }, true, "#canvas2");
ok(true, "The first program was correctly highlighted.");
shadersListView._onProgramMouseOut({ target: getItemLabel(panel, 0) });
shadersListView._onProgramMouseOver({ target: getItemLabel(panel, 1) });
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 255, g: 255, b: 0, a: 255 }, true, "#canvas1");
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 0, g: 0, b: 64, a: 255 }, true, "#canvas2");
await ensurePixelIs(front, { x: 127, y: 127 }, { r: 255, g: 255, b: 0, a: 255 }, true, "#canvas1");
await ensurePixelIs(front, { x: 127, y: 127 }, { r: 0, g: 0, b: 64, a: 255 }, true, "#canvas2");
ok(true, "The second program was correctly highlighted.");
shadersListView._onProgramMouseOut({ target: getItemLabel(panel, 1) });
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 255, g: 255, b: 0, a: 255 }, true, "#canvas1");
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 0, g: 255, b: 255, a: 255 }, true, "#canvas2");
await ensurePixelIs(front, { x: 127, y: 127 }, { r: 255, g: 255, b: 0, a: 255 }, true, "#canvas1");
await ensurePixelIs(front, { x: 127, y: 127 }, { r: 0, g: 255, b: 255, a: 255 }, true, "#canvas2");
ok(true, "The two programs were correctly unhighlighted.");
await teardown(panel);
finish();
}
function getItemLabel(aPanel, aIndex) {
return aPanel.panelWin.document.querySelectorAll(
".side-menu-widget-item-contents")[aIndex];
}
function getBlackBoxCheckbox(aPanel, aIndex) {
return aPanel.panelWin.document.querySelectorAll(
".side-menu-widget-item-checkbox")[aIndex];
}

View File

@ -1,63 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests if blackboxing a program works properly in tandem with blended
* overlapping geometry.
*/
async function ifWebGLSupported() {
const { target, debuggee, panel } = await initShaderEditor(BLENDED_GEOMETRY_CANVAS_URL);
const { front, EVENTS } = panel;
reload(target);
const [[firstProgramActor, secondProgramActor]] = await promise.all([
getPrograms(front, 2),
once(panel, EVENTS.SOURCES_SHOWN),
]);
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 127, g: 127, b: 127, a: 255 }, true);
await ensurePixelIs(front, { x: 64, y: 64 }, { r: 0, g: 127, b: 127, a: 127 }, true);
ok(true, "The canvas was correctly drawn.");
getBlackBoxCheckbox(panel, 0).click();
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 0, g: 0, b: 0, a: 255 }, true);
await ensurePixelIs(front, { x: 64, y: 64 }, { r: 0, g: 0, b: 0, a: 127 }, true);
ok(true, "The first program was correctly blackboxed.");
getBlackBoxCheckbox(panel, 0).click();
getBlackBoxCheckbox(panel, 1).click();
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 127, g: 127, b: 127, a: 255 }, true);
await ensurePixelIs(front, { x: 64, y: 64 }, { r: 127, g: 127, b: 127, a: 255 }, true);
ok(true, "The second program was correctly blackboxed.");
getBlackBoxCheckbox(panel, 1).click();
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 127, g: 127, b: 127, a: 255 }, true);
await ensurePixelIs(front, { x: 64, y: 64 }, { r: 0, g: 127, b: 127, a: 127 }, true);
ok(true, "The two programs were correctly unblackboxed.");
getBlackBoxCheckbox(panel, 0).click();
getBlackBoxCheckbox(panel, 1).click();
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 0, g: 0, b: 0, a: 255 }, true);
await ensurePixelIs(front, { x: 64, y: 64 }, { r: 0, g: 0, b: 0, a: 255 }, true);
ok(true, "The two programs were correctly blackboxed again.");
getBlackBoxCheckbox(panel, 0).click();
getBlackBoxCheckbox(panel, 1).click();
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 127, g: 127, b: 127, a: 255 }, true);
await ensurePixelIs(front, { x: 64, y: 64 }, { r: 0, g: 127, b: 127, a: 127 }, true);
ok(true, "The two programs were correctly unblackboxed again.");
await teardown(panel);
finish();
}
function getBlackBoxCheckbox(aPanel, aIndex) {
return aPanel.panelWin.document.querySelectorAll(
".side-menu-widget-item-checkbox")[aIndex];
}

View File

@ -1,41 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests that program and shader actors are cached in the frontend.
*/
async function ifWebGLSupported() {
const { target, debuggee, panel } = await initShaderEditor(MULTIPLE_CONTEXTS_URL);
const { EVENTS, front, shadersListView, shadersEditorsView } = panel;
reload(target);
const [[programActor]] = await promise.all([
getPrograms(front, 1),
once(panel, EVENTS.SOURCES_SHOWN),
]);
const programItem = shadersListView.selectedItem;
is(programItem.attachment.programActor, programActor,
"The correct program actor is cached for the selected item.");
is((await programActor.getVertexShader()),
(await programItem.attachment.vs),
"The cached vertex shader promise returns the correct actor.");
is((await programActor.getFragmentShader()),
(await programItem.attachment.fs),
"The cached fragment shader promise returns the correct actor.");
is((await (await programActor.getVertexShader()).getText()),
(await (await shadersEditorsView._getEditor("vs")).getText()),
"The cached vertex shader promise returns the correct text.");
is((await (await programActor.getFragmentShader()).getText()),
(await (await shadersEditorsView._getEditor("fs")).getText()),
"The cached fragment shader promise returns the correct text.");
await teardown(panel);
finish();
}

View File

@ -1,93 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests if highlighting a program works properly.
*/
async function ifWebGLSupported() {
const { target, panel } = await initShaderEditor(MULTIPLE_CONTEXTS_URL);
const { front, EVENTS, shadersListView, shadersEditorsView } = panel;
once(panel, EVENTS.SHADER_COMPILED).then(() => {
ok(false, "No shaders should be publicly compiled during this test.");
});
reload(target);
const [[firstProgramActor, secondProgramActor]] = await promise.all([
getPrograms(front, 2),
once(panel, EVENTS.SOURCES_SHOWN),
]);
const vsEditor = await shadersEditorsView._getEditor("vs");
const fsEditor = await shadersEditorsView._getEditor("fs");
vsEditor.once("change", () => {
ok(false, "The vertex shader source was unexpectedly changed.");
});
fsEditor.once("change", () => {
ok(false, "The fragment shader source was unexpectedly changed.");
});
once(panel, EVENTS.SOURCES_SHOWN).then(() => {
ok(false, "No sources should be changed form this point onward.");
});
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 255, g: 255, b: 0, a: 255 }, true, "#canvas1");
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 0, g: 255, b: 255, a: 255 }, true, "#canvas2");
await ensurePixelIs(front, { x: 127, y: 127 }, { r: 255, g: 255, b: 0, a: 255 }, true, "#canvas1");
await ensurePixelIs(front, { x: 127, y: 127 }, { r: 0, g: 255, b: 255, a: 255 }, true, "#canvas2");
shadersListView._onProgramMouseOver({ target: getItemLabel(panel, 0) });
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 255, g: 0, b: 0, a: 255 }, true, "#canvas1");
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 0, g: 255, b: 255, a: 255 }, true, "#canvas2");
await ensurePixelIs(front, { x: 127, y: 127 }, { r: 255, g: 0, b: 0, a: 255 }, true, "#canvas1");
await ensurePixelIs(front, { x: 127, y: 127 }, { r: 0, g: 255, b: 255, a: 255 }, true, "#canvas2");
ok(true, "The first program was correctly highlighted.");
shadersListView._onProgramMouseOut({ target: getItemLabel(panel, 0) });
shadersListView._onProgramMouseOver({ target: getItemLabel(panel, 1) });
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 255, g: 255, b: 0, a: 255 }, true, "#canvas1");
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 0, g: 0, b: 64, a: 255 }, true, "#canvas2");
await ensurePixelIs(front, { x: 127, y: 127 }, { r: 255, g: 255, b: 0, a: 255 }, true, "#canvas1");
await ensurePixelIs(front, { x: 127, y: 127 }, { r: 0, g: 0, b: 64, a: 255 }, true, "#canvas2");
ok(true, "The second program was correctly highlighted.");
shadersListView._onProgramMouseOut({ target: getItemLabel(panel, 1) });
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 255, g: 255, b: 0, a: 255 }, true, "#canvas1");
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 0, g: 255, b: 255, a: 255 }, true, "#canvas2");
await ensurePixelIs(front, { x: 127, y: 127 }, { r: 255, g: 255, b: 0, a: 255 }, true, "#canvas1");
await ensurePixelIs(front, { x: 127, y: 127 }, { r: 0, g: 255, b: 255, a: 255 }, true, "#canvas2");
ok(true, "The two programs were correctly unhighlighted.");
shadersListView._onProgramMouseOver({ target: getBlackBoxCheckbox(panel, 0) });
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 255, g: 255, b: 0, a: 255 }, true, "#canvas1");
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 0, g: 255, b: 255, a: 255 }, true, "#canvas2");
await ensurePixelIs(front, { x: 127, y: 127 }, { r: 255, g: 255, b: 0, a: 255 }, true, "#canvas1");
await ensurePixelIs(front, { x: 127, y: 127 }, { r: 0, g: 255, b: 255, a: 255 }, true, "#canvas2");
ok(true, "The two programs were left unchanged after hovering a blackbox checkbox.");
shadersListView._onProgramMouseOut({ target: getBlackBoxCheckbox(panel, 0) });
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 255, g: 255, b: 0, a: 255 }, true, "#canvas1");
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 0, g: 255, b: 255, a: 255 }, true, "#canvas2");
await ensurePixelIs(front, { x: 127, y: 127 }, { r: 255, g: 255, b: 0, a: 255 }, true, "#canvas1");
await ensurePixelIs(front, { x: 127, y: 127 }, { r: 0, g: 255, b: 255, a: 255 }, true, "#canvas2");
ok(true, "The two programs were left unchanged after unhovering a blackbox checkbox.");
await teardown(panel);
finish();
}
function getItemLabel(aPanel, aIndex) {
return aPanel.panelWin.document.querySelectorAll(
".side-menu-widget-item-contents")[aIndex];
}
function getBlackBoxCheckbox(aPanel, aIndex) {
return aPanel.panelWin.document.querySelectorAll(
".side-menu-widget-item-checkbox")[aIndex];
}

View File

@ -1,49 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests if highlighting a program works properly in tandem with blended
* overlapping geometry.
*/
async function ifWebGLSupported() {
const { target, debuggee, panel } = await initShaderEditor(BLENDED_GEOMETRY_CANVAS_URL);
const { front, EVENTS, shadersListView, shadersEditorsView } = panel;
reload(target);
const [[firstProgramActor, secondProgramActor]] = await promise.all([
getPrograms(front, 2),
once(panel, EVENTS.SOURCES_SHOWN),
]);
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 127, g: 127, b: 127, a: 255 }, true);
await ensurePixelIs(front, { x: 64, y: 64 }, { r: 0, g: 127, b: 127, a: 127 }, true);
ok(true, "The canvas was correctly drawn.");
shadersListView._onProgramMouseOver({ target: getItemLabel(panel, 0) });
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 127, g: 0, b: 32, a: 255 }, true);
await ensurePixelIs(front, { x: 64, y: 64 }, { r: 0, g: 0, b: 32, a: 127 }, true);
ok(true, "The first program was correctly highlighted.");
shadersListView._onProgramMouseOut({ target: getItemLabel(panel, 0) });
shadersListView._onProgramMouseOver({ target: getItemLabel(panel, 1) });
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 127, g: 127, b: 127, a: 255 }, true);
await ensurePixelIs(front, { x: 64, y: 64 }, { r: 255, g: 0, b: 64, a: 255 }, true);
ok(true, "The second program was correctly highlighted.");
shadersListView._onProgramMouseOut({ target: getItemLabel(panel, 1) });
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 127, g: 127, b: 127, a: 255 }, true);
await ensurePixelIs(front, { x: 64, y: 64 }, { r: 0, g: 127, b: 127, a: 127 }, true);
ok(true, "The two programs were correctly unhighlighted.");
await teardown(panel);
finish();
}
function getItemLabel(aPanel, aIndex) {
return aPanel.panelWin.document.querySelectorAll(
".side-menu-widget-item-contents")[aIndex];
}

View File

@ -1,89 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests if the programs list contains an entry after vertex and fragment
* shaders are linked.
*/
async function ifWebGLSupported() {
const { target, panel } = await initShaderEditor(MULTIPLE_CONTEXTS_URL);
const { front, EVENTS, L10N, shadersListView, shadersEditorsView } = panel;
is(shadersListView.itemCount, 0,
"The shaders list should initially be empty.");
is(shadersListView.selectedItem, null,
"The shaders list has no selected item.");
is(shadersListView.selectedIndex, -1,
"The shaders list has a negative index.");
reload(target);
const [firstProgramActor, secondProgramActor] = await promise.all([
getPrograms(front, 2, (actors) => {
// Fired upon each actor addition, we want to check only
// after the first actor has been added so we can test state
if (actors.length === 1) {
checkFirstProgram();
}
if (actors.length === 2) {
checkSecondProgram();
}
}),
once(panel, EVENTS.SOURCES_SHOWN),
]).then(([programs ]) => programs);
is(shadersListView.attachments[0].label, L10N.getFormatStr("shadersList.programLabel", 0),
"The correct first label is shown in the shaders list.");
is(shadersListView.attachments[1].label, L10N.getFormatStr("shadersList.programLabel", 1),
"The correct second label is shown in the shaders list.");
const vertexShader = await firstProgramActor.getVertexShader();
const fragmentShader = await firstProgramActor.getFragmentShader();
const vertSource = await vertexShader.getText();
const fragSource = await fragmentShader.getText();
const vsEditor = await shadersEditorsView._getEditor("vs");
const fsEditor = await shadersEditorsView._getEditor("fs");
is(vertSource, vsEditor.getText(),
"The vertex shader editor contains the correct text.");
is(fragSource, fsEditor.getText(),
"The vertex shader editor contains the correct text.");
const compiled = once(panel, EVENTS.SHADER_COMPILED).then(() => {
ok(false, "Selecting a different program shouldn't recompile its shaders.");
});
const shown = once(panel, EVENTS.SOURCES_SHOWN).then(() => {
ok(true, "The vertex and fragment sources have changed in the editors.");
});
EventUtils.sendMouseEvent({ type: "mousedown" }, shadersListView.items[1].target);
await shown;
is(shadersListView.selectedItem, shadersListView.items[1],
"The shaders list has a correct item selected.");
is(shadersListView.selectedIndex, 1,
"The shaders list has a correct index selected.");
await teardown(panel);
finish();
function checkFirstProgram() {
is(shadersListView.itemCount, 1,
"The shaders list contains one entry.");
is(shadersListView.selectedItem, shadersListView.items[0],
"The shaders list has a correct item selected.");
is(shadersListView.selectedIndex, 0,
"The shaders list has a correct index selected.");
}
function checkSecondProgram() {
is(shadersListView.itemCount, 2,
"The shaders list contains two entries.");
is(shadersListView.selectedItem, shadersListView.items[0],
"The shaders list has a correct item selected.");
is(shadersListView.selectedIndex, 0,
"The shaders list has a correct index selected.");
}
}

View File

@ -1,73 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests if editing a vertex and a fragment shader works properly.
*/
async function ifWebGLSupported() {
const { target, panel } = await initShaderEditor(SIMPLE_CANVAS_URL);
const { front, $, EVENTS, shadersEditorsView } = panel;
reload(target);
await promise.all([
once(front, "program-linked"),
once(panel, EVENTS.SOURCES_SHOWN),
]);
const vsEditor = await shadersEditorsView._getEditor("vs");
const fsEditor = await shadersEditorsView._getEditor("fs");
is(vsEditor.getText().indexOf("gl_Position"), 170,
"The vertex shader editor contains the correct text.");
is(fsEditor.getText().indexOf("gl_FragColor"), 97,
"The fragment shader editor contains the correct text.");
is($("#vs-editor-label").hasAttribute("selected"), false,
"The vertex shader editor shouldn't be initially selected.");
is($("#fs-editor-label").hasAttribute("selected"), false,
"The vertex shader editor shouldn't be initially selected.");
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 255, g: 0, b: 0, a: 255 }, true);
await ensurePixelIs(front, { x: 128, y: 128 }, { r: 191, g: 64, b: 0, a: 255 }, true);
await ensurePixelIs(front, { x: 511, y: 511 }, { r: 0, g: 255, b: 0, a: 255 }, true);
vsEditor.focus();
is($("#vs-editor-label").hasAttribute("selected"), true,
"The vertex shader editor should now be selected.");
is($("#fs-editor-label").hasAttribute("selected"), false,
"The vertex shader editor shouldn't still not be selected.");
vsEditor.replaceText("2.0", { line: 7, ch: 44 }, { line: 7, ch: 47 });
await once(panel, EVENTS.SHADER_COMPILED);
ok(true, "Vertex shader was changed.");
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 0, g: 0, b: 0, a: 255 }, true);
await ensurePixelIs(front, { x: 128, y: 128 }, { r: 255, g: 0, b: 0, a: 255 }, true);
await ensurePixelIs(front, { x: 511, y: 511 }, { r: 0, g: 0, b: 0, a: 255 }, true);
ok(true, "The vertex shader was recompiled successfully.");
fsEditor.focus();
is($("#vs-editor-label").hasAttribute("selected"), false,
"The vertex shader editor should now be deselected.");
is($("#fs-editor-label").hasAttribute("selected"), true,
"The vertex shader editor should now be selected.");
fsEditor.replaceText("0.5", { line: 5, ch: 44 }, { line: 5, ch: 47 });
await once(panel, EVENTS.SHADER_COMPILED);
ok(true, "Fragment shader was changed.");
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 0, g: 0, b: 0, a: 255 }, true);
await ensurePixelIs(front, { x: 128, y: 128 }, { r: 255, g: 0, b: 0, a: 127 }, true);
await ensurePixelIs(front, { x: 511, y: 511 }, { r: 0, g: 0, b: 0, a: 255 }, true);
ok(true, "The fragment shader was recompiled successfully.");
await teardown(panel);
finish();
}

View File

@ -1,73 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests if compile or linkage errors are emitted when a shader source
* gets malformed after being edited.
*/
async function ifWebGLSupported() {
const { target, panel } = await initShaderEditor(SIMPLE_CANVAS_URL);
const { front, EVENTS, shadersEditorsView } = panel;
reload(target);
await promise.all([
once(front, "program-linked"),
once(panel, EVENTS.SOURCES_SHOWN),
]);
const vsEditor = await shadersEditorsView._getEditor("vs");
const fsEditor = await shadersEditorsView._getEditor("fs");
vsEditor.replaceText("vec3", { line: 7, ch: 22 }, { line: 7, ch: 26 });
let error = await panel.once(EVENTS.SHADER_COMPILED);
ok(error,
"The new vertex shader source was compiled with errors.");
// The implementation has the choice to defer all compile-time errors to link time.
let infoLog = (error.compile != "") ? error.compile : error.link;
isnot(infoLog, "",
"The one of the compile or link info logs should not be empty.");
is(infoLog.split("ERROR").length - 1, 3,
"The info log status contains three errors.");
ok(infoLog.includes("ERROR: 0:8: 'constructor'"),
"A constructor error is contained in the info log.");
ok(infoLog.includes("ERROR: 0:8: '='"),
"A dimension error is contained in the info log.");
ok(infoLog.includes("ERROR: 0:8: 'assign'"),
"An assignment error is contained in the info log.");
fsEditor.replaceText("vec4", { line: 2, ch: 14 }, { line: 2, ch: 18 });
error = await panel.once(EVENTS.SHADER_COMPILED);
ok(error,
"The new fragment shader source was compiled with errors.");
infoLog = (error.compile != "") ? error.compile : error.link;
isnot(infoLog, "",
"The one of the compile or link info logs should not be empty.");
is(infoLog.split("ERROR").length - 1, 1,
"The info log contains one error.");
ok(infoLog.includes("ERROR: 0:6: 'constructor'"),
"A constructor error is contained in the info log.");
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 255, g: 0, b: 0, a: 255 }, true);
await ensurePixelIs(front, { x: 511, y: 511 }, { r: 0, g: 255, b: 0, a: 255 }, true);
vsEditor.replaceText("vec4", { line: 7, ch: 22 }, { line: 7, ch: 26 });
error = await panel.once(EVENTS.SHADER_COMPILED);
ok(!error, "The new vertex shader source was compiled successfully.");
fsEditor.replaceText("vec3", { line: 2, ch: 14 }, { line: 2, ch: 18 });
error = await panel.once(EVENTS.SHADER_COMPILED);
ok(!error, "The new fragment shader source was compiled successfully.");
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 255, g: 0, b: 0, a: 255 }, true);
await ensurePixelIs(front, { x: 511, y: 511 }, { r: 0, g: 255, b: 0, a: 255 }, true);
await teardown(panel);
finish();
}

View File

@ -1,85 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests if editing a vertex and a fragment shader would permanently store
* their new source on the backend and reshow it in the frontend when required.
*/
async function ifWebGLSupported() {
const { target, panel } = await initShaderEditor(MULTIPLE_CONTEXTS_URL);
const { front, EVENTS, shadersListView, shadersEditorsView } = panel;
reload(target);
await promise.all([
once(front, "program-linked"),
once(front, "program-linked"),
]);
await once(panel, EVENTS.SOURCES_SHOWN);
const vsEditor = await shadersEditorsView._getEditor("vs");
const fsEditor = await shadersEditorsView._getEditor("fs");
is(shadersListView.selectedIndex, 0,
"The first program is currently selected.");
is(vsEditor.getText().indexOf("1);"), 136,
"The vertex shader editor contains the correct initial text (1).");
is(fsEditor.getText().indexOf("1);"), 117,
"The fragment shader editor contains the correct initial text (1).");
is(vsEditor.getText().indexOf("2.);"), -1,
"The vertex shader editor contains the correct initial text (2).");
is(fsEditor.getText().indexOf(".0);"), -1,
"The fragment shader editor contains the correct initial text (2).");
vsEditor.replaceText("2.", { line: 5, ch: 44 }, { line: 5, ch: 45 });
await once(panel, EVENTS.SHADER_COMPILED);
fsEditor.replaceText(".0", { line: 5, ch: 35 }, { line: 5, ch: 37 });
await once(panel, EVENTS.SHADER_COMPILED);
ok(true, "Vertex and fragment shaders were changed.");
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 0, g: 0, b: 0, a: 255 }, true, "#canvas1");
await ensurePixelIs(front, { x: 32, y: 32 }, { r: 255, g: 255, b: 0, a: 0 }, true, "#canvas1");
await ensurePixelIs(front, { x: 64, y: 64 }, { r: 255, g: 255, b: 0, a: 0 }, true, "#canvas1");
await ensurePixelIs(front, { x: 127, y: 127 }, { r: 0, g: 0, b: 0, a: 255 }, true, "#canvas1");
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 0, g: 255, b: 255, a: 255 }, true, "#canvas2");
await ensurePixelIs(front, { x: 32, y: 32 }, { r: 0, g: 255, b: 255, a: 255 }, true, "#canvas2");
await ensurePixelIs(front, { x: 64, y: 64 }, { r: 0, g: 255, b: 255, a: 255 }, true, "#canvas2");
await ensurePixelIs(front, { x: 127, y: 127 }, { r: 0, g: 255, b: 255, a: 255 }, true, "#canvas2");
ok(true, "The vertex and fragment shaders were recompiled successfully.");
EventUtils.sendMouseEvent({ type: "mousedown" }, shadersListView.items[1].target);
await once(panel, EVENTS.SOURCES_SHOWN);
is(shadersListView.selectedIndex, 1,
"The second program is currently selected.");
is(vsEditor.getText().indexOf("1);"), 136,
"The vertex shader editor contains the correct text (1).");
is(fsEditor.getText().indexOf("1);"), 117,
"The fragment shader editor contains the correct text (1).");
is(vsEditor.getText().indexOf("2.);"), -1,
"The vertex shader editor contains the correct text (2).");
is(fsEditor.getText().indexOf(".0);"), -1,
"The fragment shader editor contains the correct text (2).");
EventUtils.sendMouseEvent({ type: "mousedown" }, shadersListView.items[0].target);
await once(panel, EVENTS.SOURCES_SHOWN);
is(shadersListView.selectedIndex, 0,
"The first program is currently selected again.");
is(vsEditor.getText().indexOf("1);"), -1,
"The vertex shader editor contains the correct text (3).");
is(fsEditor.getText().indexOf("1);"), -1,
"The fragment shader editor contains the correct text (3).");
is(vsEditor.getText().indexOf("2.);"), 136,
"The vertex shader editor contains the correct text (4).");
is(fsEditor.getText().indexOf(".0);"), 116,
"The fragment shader editor contains the correct text (4).");
await teardown(panel);
finish();
}

View File

@ -1,16 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests if a WebGL front can be created for a remote tab target.
*/
async function ifWebGLSupported() {
const { target, front } = await initBackend(SIMPLE_CANVAS_URL);
ok(target, "Should have a target available.");
ok(front, "Should have a protocol front available.");
await removeTab(target.tab);
finish();
}

View File

@ -1,21 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests if notifications about WebGL programs being linked are not sent
* if the front wasn't set up first.
*/
async function ifWebGLSupported() {
const { target, front } = await initBackend(SIMPLE_CANVAS_URL);
once(front, "program-linked").then(() => {
ok(false, "A 'program-linked' notification shouldn't have been sent!");
});
ok(true, "Each test requires at least one pass, fail or todo so here is a pass.");
await reload(target);
await removeTab(target.tab);
finish();
}

View File

@ -1,26 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests if notifications about WebGL programs being linked are sent
* after a target navigation.
*/
async function ifWebGLSupported() {
const { target, front } = await initBackend(SIMPLE_CANVAS_URL);
const navigated = once(target, "navigate");
const linked = once(front, "program-linked");
await front.setup({ reload: true });
ok(true, "The front was setup up successfully.");
await navigated;
ok(true, "Target automatically navigated when the front was set up.");
await linked;
ok(true, "A 'program-linked' notification was sent after reloading.");
await removeTab(target.tab);
finish();
}

View File

@ -1,27 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests if a program actor is sent when WebGL programs are linked,
* and that the corresponding vertex and fragment actors can be retrieved.
*/
async function ifWebGLSupported() {
const { target, front } = await initBackend(SIMPLE_CANVAS_URL);
front.setup({ reload: true });
const programActor = await once(front, "program-linked");
ok(programActor,
"A program actor was sent along with the 'program-linked' notification.");
const vertexShader = await programActor.getVertexShader();
ok(programActor,
"A vertex shader actor was retrieved from the program actor.");
const fragmentShader = await programActor.getFragmentShader();
ok(programActor,
"A fragment shader actor was retrieved from the program actor.");
await removeTab(target.tab);
finish();
}

View File

@ -1,27 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests that the source contents can be retrieved from the vertex and fragment
* shader actors.
*/
async function ifWebGLSupported() {
const { target, front } = await initBackend(SIMPLE_CANVAS_URL);
front.setup({ reload: true });
const programActor = await once(front, "program-linked");
const vertexShader = await programActor.getVertexShader();
const fragmentShader = await programActor.getFragmentShader();
const vertSource = await vertexShader.getText();
ok(vertSource.includes("gl_Position"),
"The correct vertex shader source was retrieved.");
const fragSource = await fragmentShader.getText();
ok(fragSource.includes("gl_FragColor"),
"The correct fragment shader source was retrieved.");
await removeTab(target.tab);
finish();
}

View File

@ -1,64 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests that the highlight/unhighlight and blackbox/unblackbox operations on
* program actors work as expected.
*/
async function ifWebGLSupported() {
const { target, front } = await initBackend(SIMPLE_CANVAS_URL);
front.setup({ reload: true });
const programActor = await once(front, "program-linked");
const vertexShader = await programActor.getVertexShader();
const fragmentShader = await programActor.getFragmentShader();
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 255, g: 0, b: 0, a: 255 }, true);
await ensurePixelIs(front, { x: 511, y: 511 }, { r: 0, g: 255, b: 0, a: 255 }, true);
await checkShaderSource("The shader sources are correct before highlighting.");
ok(true, "The corner pixel colors are correct before highlighting.");
await programActor.highlight([0, 1, 0, 1]);
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 0, g: 0, b: 0, a: 255 }, true);
await ensurePixelIs(front, { x: 511, y: 511 }, { r: 0, g: 255, b: 0, a: 255 }, true);
await checkShaderSource("The shader sources are preserved after highlighting.");
ok(true, "The corner pixel colors are correct after highlighting.");
await programActor.unhighlight();
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 255, g: 0, b: 0, a: 255 }, true);
await ensurePixelIs(front, { x: 511, y: 511 }, { r: 0, g: 255, b: 0, a: 255 }, true);
await checkShaderSource("The shader sources are correct after unhighlighting.");
ok(true, "The corner pixel colors are correct after unhighlighting.");
await programActor.blackbox();
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 0, g: 0, b: 0, a: 255 }, true);
await ensurePixelIs(front, { x: 511, y: 511 }, { r: 0, g: 0, b: 0, a: 255 }, true);
await checkShaderSource("The shader sources are preserved after blackboxing.");
ok(true, "The corner pixel colors are correct after blackboxing.");
await programActor.unblackbox();
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 255, g: 0, b: 0, a: 255 }, true);
await ensurePixelIs(front, { x: 511, y: 511 }, { r: 0, g: 255, b: 0, a: 255 }, true);
await checkShaderSource("The shader sources are correct after unblackboxing.");
ok(true, "The corner pixel colors are correct after unblackboxing.");
function checkShaderSource(aMessage) {
return (async function() {
const newVertexShader = await programActor.getVertexShader();
const newFragmentShader = await programActor.getFragmentShader();
is(vertexShader, newVertexShader,
"The same vertex shader actor was retrieved.");
is(fragmentShader, newFragmentShader,
"The same fragment shader actor was retrieved.");
const vertSource = await newVertexShader.getText();
const fragSource = await newFragmentShader.getText();
ok(vertSource.includes("I'm special!") &&
fragSource.includes("I'm also special!"), aMessage);
})();
}
await removeTab(target.tab);
finish();
}

View File

@ -1,61 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests that vertex and fragment shader sources can be changed.
*/
async function ifWebGLSupported() {
const { target, front } = await initBackend(SIMPLE_CANVAS_URL);
front.setup({ reload: true });
const programActor = await once(front, "program-linked");
const vertexShader = await programActor.getVertexShader();
const fragmentShader = await programActor.getFragmentShader();
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 255, g: 0, b: 0, a: 255 }, true);
await ensurePixelIs(front, { x: 128, y: 128 }, { r: 191, g: 64, b: 0, a: 255 }, true);
await ensurePixelIs(front, { x: 511, y: 511 }, { r: 0, g: 255, b: 0, a: 255 }, true);
let vertSource = await vertexShader.getText();
let fragSource = await fragmentShader.getText();
ok(!vertSource.includes("2.0"),
"The vertex shader source is correct before changing it.");
ok(!fragSource.includes("0.5"),
"The fragment shader source is correct before changing it.");
const newVertSource = vertSource.replace("1.0", "2.0");
let status = await vertexShader.compile(newVertSource);
ok(!status,
"The new vertex shader source was compiled without errors.");
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 0, g: 0, b: 0, a: 255 }, true);
await ensurePixelIs(front, { x: 128, y: 128 }, { r: 255, g: 0, b: 0, a: 255 }, true);
await ensurePixelIs(front, { x: 511, y: 511 }, { r: 0, g: 0, b: 0, a: 255 }, true);
vertSource = await vertexShader.getText();
fragSource = await fragmentShader.getText();
ok(vertSource.includes("2.0"),
"The vertex shader source is correct after changing it.");
ok(!fragSource.includes("0.5"),
"The fragment shader source is correct after changing the vertex shader.");
const newFragSource = fragSource.replace("1.0", "0.5");
status = await fragmentShader.compile(newFragSource);
ok(!status,
"The new fragment shader source was compiled without errors.");
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 0, g: 0, b: 0, a: 255 }, true);
await ensurePixelIs(front, { x: 128, y: 128 }, { r: 255, g: 0, b: 0, a: 127 }, true);
await ensurePixelIs(front, { x: 511, y: 511 }, { r: 0, g: 0, b: 0, a: 255 }, true);
vertSource = await vertexShader.getText();
fragSource = await fragmentShader.getText();
ok(vertSource.includes("2.0"),
"The vertex shader source is correct after changing the fragment shader.");
ok(fragSource.includes("0.5"),
"The fragment shader source is correct after changing it.");
await removeTab(target.tab);
finish();
}

View File

@ -1,37 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests that the rendering is updated when a varying variable is
* changed in one shader.
*/
async function ifWebGLSupported() {
const { target, front } = await initBackend(SIMPLE_CANVAS_URL);
front.setup({ reload: true });
const programActor = await once(front, "program-linked");
const vertexShader = await programActor.getVertexShader();
const fragmentShader = await programActor.getFragmentShader();
const oldVertSource = await vertexShader.getText();
const newVertSource = oldVertSource.replace("= aVertexColor", "= vec3(0, 0, 1)");
const status = await vertexShader.compile(newVertSource);
ok(!status,
"The new vertex shader source was compiled without errors.");
await front.waitForFrame();
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 0, g: 0, b: 255, a: 255 }, true);
await ensurePixelIs(front, { x: 128, y: 128 }, { r: 0, g: 0, b: 255, a: 255 }, true);
await ensurePixelIs(front, { x: 511, y: 511 }, { r: 0, g: 0, b: 255, a: 255 }, true);
const vertSource = await vertexShader.getText();
const fragSource = await fragmentShader.getText();
ok(vertSource.includes("vFragmentColor = vec3(0, 0, 1);"),
"The vertex shader source is correct after changing it.");
ok(fragSource.includes("gl_FragColor = vec4(vFragmentColor, 1.0);"),
"The fragment shader source is correct after changing the vertex shader.");
await removeTab(target.tab);
finish();
}

View File

@ -1,91 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests that errors are properly handled when trying to compile a
* defective shader source.
*/
async function ifWebGLSupported() {
const { target, front } = await initBackend(SIMPLE_CANVAS_URL);
front.setup({ reload: true });
const programActor = await once(front, "program-linked");
const vertexShader = await programActor.getVertexShader();
const fragmentShader = await programActor.getFragmentShader();
const oldVertSource = await vertexShader.getText();
const newVertSource = oldVertSource.replace("vec4", "vec3");
try {
await vertexShader.compile(newVertSource);
ok(false, "Vertex shader was compiled with a defective source!");
} catch (error) {
ok(error,
"The new vertex shader source was compiled with errors.");
// The implementation has the choice to defer all compile-time errors to link time.
const infoLog = (error.compile != "") ? error.compile : error.link;
isnot(infoLog, "",
"The one of the compile or link info logs should not be empty.");
is(infoLog.split("ERROR").length - 1, 3,
"The info log status contains three errors.");
ok(infoLog.includes("ERROR: 0:8: 'constructor'"),
"A constructor error is contained in the info log.");
ok(infoLog.includes("ERROR: 0:8: '='"),
"A dimension error is contained in the info log.");
ok(infoLog.includes("ERROR: 0:8: 'assign'"),
"An assignment error is contained in the info log.");
}
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 255, g: 0, b: 0, a: 255 }, true);
await ensurePixelIs(front, { x: 511, y: 511 }, { r: 0, g: 255, b: 0, a: 255 }, true);
ok(true, "The shader was reverted to the old source.");
const vertSource = await vertexShader.getText();
ok(vertSource.includes("vec4(aVertexPosition, 1.0);"),
"The previous correct vertex shader source was preserved.");
const oldFragSource = await fragmentShader.getText();
const newFragSource = oldFragSource.replace("vec3", "vec4");
try {
await fragmentShader.compile(newFragSource);
ok(false, "Fragment shader was compiled with a defective source!");
} catch (error) {
ok(error,
"The new fragment shader source was compiled with errors.");
// The implementation has the choice to defer all compile-time errors to link time.
const infoLog = (error.compile != "") ? error.compile : error.link;
isnot(infoLog, "",
"The one of the compile or link info logs should not be empty.");
is(infoLog.split("ERROR").length - 1, 1,
"The info log contains one error.");
ok(infoLog.includes("ERROR: 0:6: 'constructor'"),
"A constructor error is contained in the info log.");
}
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 255, g: 0, b: 0, a: 255 }, true);
await ensurePixelIs(front, { x: 511, y: 511 }, { r: 0, g: 255, b: 0, a: 255 }, true);
ok(true, "The shader was reverted to the old source.");
const fragSource = await fragmentShader.getText();
ok(fragSource.includes("vec3 vFragmentColor;"),
"The previous correct fragment shader source was preserved.");
await programActor.highlight([0, 1, 0, 1]);
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 0, g: 0, b: 0, a: 255 }, true);
await ensurePixelIs(front, { x: 511, y: 511 }, { r: 0, g: 255, b: 0, a: 255 }, true);
ok(true, "Highlighting worked after setting a defective fragment source.");
await programActor.unhighlight();
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 255, g: 0, b: 0, a: 255 }, true);
await ensurePixelIs(front, { x: 511, y: 511 }, { r: 0, g: 255, b: 0, a: 255 }, true);
ok(true, "Unhighlighting worked after setting a defective vertex source.");
await removeTab(target.tab);
finish();
}

View File

@ -1,44 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests if the WebGL context is correctly instrumented every time the
* target navigates.
*/
async function ifWebGLSupported() {
const { target, front } = await initBackend(SIMPLE_CANVAS_URL);
front.setup({ reload: true });
await testHighlighting((await once(front, "program-linked")));
ok(true, "Canvas was correctly instrumented on the first navigation.");
reload(target);
await testHighlighting((await once(front, "program-linked")));
ok(true, "Canvas was correctly instrumented on the second navigation.");
reload(target);
await testHighlighting((await once(front, "program-linked")));
ok(true, "Canvas was correctly instrumented on the third navigation.");
await removeTab(target.tab);
finish();
function testHighlighting(programActor) {
return (async function() {
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 255, g: 0, b: 0, a: 255 }, true);
await ensurePixelIs(front, { x: 511, y: 511 }, { r: 0, g: 255, b: 0, a: 255 }, true);
ok(true, "The corner pixel colors are correct before highlighting.");
await programActor.highlight([0, 1, 0, 1]);
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 0, g: 0, b: 0, a: 255 }, true);
await ensurePixelIs(front, { x: 511, y: 511 }, { r: 0, g: 255, b: 0, a: 255 }, true);
ok(true, "The corner pixel colors are correct after highlighting.");
await programActor.unhighlight();
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 255, g: 0, b: 0, a: 255 }, true);
await ensurePixelIs(front, { x: 511, y: 511 }, { r: 0, g: 255, b: 0, a: 255 }, true);
ok(true, "The corner pixel colors are correct after unhighlighting.");
})();
}
}

View File

@ -1,25 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests if the WebGL context is never instrumented anymore after the
* finalize method is called.
*/
async function ifWebGLSupported() {
const { target, front } = await initBackend(SIMPLE_CANVAS_URL);
const linked = once(front, "program-linked");
front.setup({ reload: true });
await linked;
ok(true, "Canvas was correctly instrumented on the first navigation.");
once(front, "program-linked").then(() => {
ok(false, "A 'program-linked' notification shouldn't have been sent!");
});
await front.finalize();
await reload(target);
await removeTab(target.tab);
finish();
}

View File

@ -1,27 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests that the correct vertex and fragment shader sources are retrieved
* regardless of the order in which they were compiled and attached.
*/
async function ifWebGLSupported() {
const { target, front } = await initBackend(SHADER_ORDER_URL);
front.setup({ reload: true });
const programActor = await once(front, "program-linked");
const vertexShader = await programActor.getVertexShader();
const fragmentShader = await programActor.getFragmentShader();
const vertSource = await vertexShader.getText();
const fragSource = await fragmentShader.getText();
ok(vertSource.includes("I'm a vertex shader!"),
"The correct vertex shader text was retrieved.");
ok(fragSource.includes("I'm a fragment shader!"),
"The correct fragment shader text was retrieved.");
await removeTab(target.tab);
finish();
}

View File

@ -1,67 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests if multiple WebGL contexts are correctly handled.
*/
async function ifWebGLSupported() {
const { target, front } = await initBackend(MULTIPLE_CONTEXTS_URL);
front.setup({ reload: true });
const [firstProgramActor, secondProgramActor] = await getPrograms(front, 2);
isnot(firstProgramActor, secondProgramActor,
"Two distinct program actors were recevide from two separate contexts.");
const firstVertexShader = await firstProgramActor.getVertexShader();
const firstFragmentShader = await firstProgramActor.getFragmentShader();
const secondVertexShader = await secondProgramActor.getVertexShader();
const secondFragmentShader = await secondProgramActor.getFragmentShader();
isnot(firstVertexShader, secondVertexShader,
"The two programs should have distinct vertex shaders.");
isnot(firstFragmentShader, secondFragmentShader,
"The two programs should have distinct fragment shaders.");
const firstVertSource = await firstVertexShader.getText();
const firstFragSource = await firstFragmentShader.getText();
const secondVertSource = await secondVertexShader.getText();
const secondFragSource = await secondFragmentShader.getText();
is(firstVertSource, secondVertSource,
"The vertex shaders should have identical sources.");
is(firstFragSource, secondFragSource,
"The vertex shaders should have identical sources.");
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 255, g: 255, b: 0, a: 255 }, true, "#canvas1");
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 0, g: 255, b: 255, a: 255 }, true, "#canvas2");
await ensurePixelIs(front, { x: 127, y: 127 }, { r: 255, g: 255, b: 0, a: 255 }, true, "#canvas1");
await ensurePixelIs(front, { x: 127, y: 127 }, { r: 0, g: 255, b: 255, a: 255 }, true, "#canvas2");
ok(true, "The two canvases are correctly drawn.");
await firstProgramActor.highlight([1, 0, 0, 1]);
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 255, g: 0, b: 0, a: 255 }, true, "#canvas1");
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 0, g: 255, b: 255, a: 255 }, true, "#canvas2");
await ensurePixelIs(front, { x: 127, y: 127 }, { r: 255, g: 0, b: 0, a: 255 }, true, "#canvas1");
await ensurePixelIs(front, { x: 127, y: 127 }, { r: 0, g: 255, b: 255, a: 255 }, true, "#canvas2");
ok(true, "The first canvas was correctly filled after highlighting.");
await secondProgramActor.highlight([0, 1, 0, 1]);
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 255, g: 0, b: 0, a: 255 }, true, "#canvas1");
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 0, g: 255, b: 0, a: 255 }, true, "#canvas2");
await ensurePixelIs(front, { x: 127, y: 127 }, { r: 255, g: 0, b: 0, a: 255 }, true, "#canvas1");
await ensurePixelIs(front, { x: 127, y: 127 }, { r: 0, g: 255, b: 0, a: 255 }, true, "#canvas2");
ok(true, "The second canvas was correctly filled after highlighting.");
await firstProgramActor.unhighlight();
await secondProgramActor.unhighlight();
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 255, g: 255, b: 0, a: 255 }, true, "#canvas1");
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 0, g: 255, b: 255, a: 255 }, true, "#canvas2");
await ensurePixelIs(front, { x: 127, y: 127 }, { r: 255, g: 255, b: 0, a: 255 }, true, "#canvas1");
await ensurePixelIs(front, { x: 127, y: 127 }, { r: 0, g: 255, b: 255, a: 255 }, true, "#canvas2");
ok(true, "The two canvases were correctly filled after unhighlighting.");
await removeTab(target.tab);
finish();
}

View File

@ -1,46 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests that the rendering is updated when a uniform variable is
* changed in one shader of a page with multiple WebGL contexts.
*/
async function ifWebGLSupported() {
const { target, front } = await initBackend(MULTIPLE_CONTEXTS_URL);
front.setup({ reload: true });
const [firstProgramActor, secondProgramActor] = await getPrograms(front, 2);
const firstFragmentShader = await firstProgramActor.getFragmentShader();
const secondFragmentShader = await secondProgramActor.getFragmentShader();
let oldFragSource = await firstFragmentShader.getText();
let newFragSource = oldFragSource.replace("vec4(uColor", "vec4(0.25, 0.25, 0.25");
let status = await firstFragmentShader.compile(newFragSource);
ok(!status,
"The first new fragment shader source was compiled without errors.");
await front.waitForFrame();
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 64, g: 64, b: 64, a: 255 }, true, "#canvas1");
await ensurePixelIs(front, { x: 127, y: 127 }, { r: 64, g: 64, b: 64, a: 255 }, true, "#canvas1");
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 0, g: 255, b: 255, a: 255 }, true, "#canvas2");
await ensurePixelIs(front, { x: 127, y: 127 }, { r: 0, g: 255, b: 255, a: 255 }, true, "#canvas2");
ok(true, "The first fragment shader was changed.");
oldFragSource = await secondFragmentShader.getText();
newFragSource = oldFragSource.replace("vec4(uColor", "vec4(0.75, 0.75, 0.75");
status = await secondFragmentShader.compile(newFragSource);
ok(!status,
"The second new fragment shader source was compiled without errors.");
await front.waitForFrame();
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 64, g: 64, b: 64, a: 255 }, true, "#canvas1");
await ensurePixelIs(front, { x: 127, y: 127 }, { r: 64, g: 64, b: 64, a: 255 }, true, "#canvas1");
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 191, g: 191, b: 191, a: 255 }, true, "#canvas2");
await ensurePixelIs(front, { x: 127, y: 127 }, { r: 191, g: 191, b: 191, a: 255 }, true, "#canvas2");
ok(true, "The second fragment shader was changed.");
await removeTab(target.tab);
finish();
}

View File

@ -1,133 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests if program actors are cached when navigating in the bfcache.
*/
async function ifWebGLSupported() {
const { target, front } = await initBackend(SIMPLE_CANVAS_URL);
front.setup({ reload: false });
// Attach frame scripts if in e10s to perform
// history navigation via the content
loadFrameScripts();
reload(target);
const firstProgram = await once(front, "program-linked");
await checkFirstCachedPrograms(firstProgram);
await checkHighlightingInTheFirstPage(firstProgram);
ok(true, "The cached programs behave correctly before the navigation.");
navigate(target, MULTIPLE_CONTEXTS_URL);
const [secondProgram, thirdProgram] = await getPrograms(front, 2);
await checkSecondCachedPrograms(firstProgram, [secondProgram, thirdProgram]);
await checkHighlightingInTheSecondPage(secondProgram, thirdProgram);
ok(true, "The cached programs behave correctly after the navigation.");
once(front, "program-linked").then(() => {
ok(false, "Shouldn't have received any more program-linked notifications.");
});
await navigateInHistory(target, "back");
await checkFirstCachedPrograms(firstProgram);
await checkHighlightingInTheFirstPage(firstProgram);
ok(true, "The cached programs behave correctly after navigating back.");
await navigateInHistory(target, "forward");
await checkSecondCachedPrograms(firstProgram, [secondProgram, thirdProgram]);
await checkHighlightingInTheSecondPage(secondProgram, thirdProgram);
ok(true, "The cached programs behave correctly after navigating forward.");
await navigateInHistory(target, "back");
await checkFirstCachedPrograms(firstProgram);
await checkHighlightingInTheFirstPage(firstProgram);
ok(true, "The cached programs behave correctly after navigating back again.");
await navigateInHistory(target, "forward");
await checkSecondCachedPrograms(firstProgram, [secondProgram, thirdProgram]);
await checkHighlightingInTheSecondPage(secondProgram, thirdProgram);
ok(true, "The cached programs behave correctly after navigating forward again.");
await removeTab(target.tab);
finish();
function checkFirstCachedPrograms(programActor) {
return (async function() {
const programs = await front.getPrograms();
is(programs.length, 1,
"There should be 1 cached program actor.");
is(programs[0], programActor,
"The cached program actor was the expected one.");
})();
}
function checkSecondCachedPrograms(oldProgramActor, newProgramActors) {
return (async function() {
const programs = await front.getPrograms();
is(programs.length, 2,
"There should be 2 cached program actors after the navigation.");
is(programs[0], newProgramActors[0],
"The first cached program actor was the expected one after the navigation.");
is(programs[1], newProgramActors[1],
"The second cached program actor was the expected one after the navigation.");
isnot(newProgramActors[0], oldProgramActor,
"The old program actor is not equal to the new first program actor.");
isnot(newProgramActors[1], oldProgramActor,
"The old program actor is not equal to the new second program actor.");
})();
}
function checkHighlightingInTheFirstPage(programActor) {
return (async function() {
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 255, g: 0, b: 0, a: 255 }, true);
await ensurePixelIs(front, { x: 511, y: 511 }, { r: 0, g: 255, b: 0, a: 255 }, true);
ok(true, "The corner pixel colors are correct before highlighting.");
await programActor.highlight([0, 1, 0, 1]);
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 0, g: 0, b: 0, a: 255 }, true);
await ensurePixelIs(front, { x: 511, y: 511 }, { r: 0, g: 255, b: 0, a: 255 }, true);
ok(true, "The corner pixel colors are correct after highlighting.");
await programActor.unhighlight();
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 255, g: 0, b: 0, a: 255 }, true);
await ensurePixelIs(front, { x: 511, y: 511 }, { r: 0, g: 255, b: 0, a: 255 }, true);
ok(true, "The corner pixel colors are correct after unhighlighting.");
})();
}
function checkHighlightingInTheSecondPage(firstProgramActor, secondProgramActor) {
return (async function() {
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 255, g: 255, b: 0, a: 255 }, true, "#canvas1");
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 0, g: 255, b: 255, a: 255 }, true, "#canvas2");
await ensurePixelIs(front, { x: 127, y: 127 }, { r: 255, g: 255, b: 0, a: 255 }, true, "#canvas1");
await ensurePixelIs(front, { x: 127, y: 127 }, { r: 0, g: 255, b: 255, a: 255 }, true, "#canvas2");
ok(true, "The two canvases are correctly drawn before highlighting.");
await firstProgramActor.highlight([1, 0, 0, 1]);
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 255, g: 0, b: 0, a: 255 }, true, "#canvas1");
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 0, g: 255, b: 255, a: 255 }, true, "#canvas2");
await ensurePixelIs(front, { x: 127, y: 127 }, { r: 255, g: 0, b: 0, a: 255 }, true, "#canvas1");
await ensurePixelIs(front, { x: 127, y: 127 }, { r: 0, g: 255, b: 255, a: 255 }, true, "#canvas2");
ok(true, "The first canvas was correctly filled after highlighting.");
await secondProgramActor.highlight([0, 1, 0, 1]);
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 255, g: 0, b: 0, a: 255 }, true, "#canvas1");
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 0, g: 255, b: 0, a: 255 }, true, "#canvas2");
await ensurePixelIs(front, { x: 127, y: 127 }, { r: 255, g: 0, b: 0, a: 255 }, true, "#canvas1");
await ensurePixelIs(front, { x: 127, y: 127 }, { r: 0, g: 255, b: 0, a: 255 }, true, "#canvas2");
ok(true, "The second canvas was correctly filled after highlighting.");
await firstProgramActor.unhighlight();
await secondProgramActor.unhighlight();
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 255, g: 255, b: 0, a: 255 }, true, "#canvas1");
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 0, g: 255, b: 255, a: 255 }, true, "#canvas2");
await ensurePixelIs(front, { x: 127, y: 127 }, { r: 255, g: 255, b: 0, a: 255 }, true, "#canvas1");
await ensurePixelIs(front, { x: 127, y: 127 }, { r: 0, g: 255, b: 255, a: 255 }, true, "#canvas2");
ok(true, "The two canvases were correctly filled after unhighlighting.");
})();
}
}

View File

@ -1,141 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests if program actors are invalidated from the cache when a window is
* removed from the bfcache.
*/
async function ifWebGLSupported() {
const { target, front } = await initBackend(SIMPLE_CANVAS_URL);
front.setup({ reload: false });
// Attach frame scripts if in e10s to perform
// history navigation via the content
loadFrameScripts();
// 0. Perform the initial reload.
reload(target);
const firstProgram = await once(front, "program-linked");
let programs = await front.getPrograms();
is(programs.length, 1,
"The first program should be returned by a call to getPrograms().");
is(programs[0], firstProgram,
"The first programs was correctly retrieved from the cache.");
let allPrograms = await front._getAllPrograms();
is(allPrograms.length, 1,
"Should be only one program in cache.");
// 1. Perform a simple navigation.
navigate(target, MULTIPLE_CONTEXTS_URL);
const [secondProgram, thirdProgram] = await getPrograms(front, 2);
programs = await front.getPrograms();
is(programs.length, 2,
"The second and third programs should be returned by a call to getPrograms().");
is(programs[0], secondProgram,
"The second programs was correctly retrieved from the cache.");
is(programs[1], thirdProgram,
"The third programs was correctly retrieved from the cache.");
allPrograms = await front._getAllPrograms();
is(allPrograms.length, 3,
"Should be three programs in cache.");
// 2. Perform a bfcache navigation.
await navigateInHistory(target, "back");
let globalDestroyed = once(front, "global-created");
let globalCreated = once(front, "global-destroyed");
let programsLinked = once(front, "program-linked");
reload(target);
await promise.all([programsLinked, globalDestroyed, globalCreated]);
allPrograms = await front._getAllPrograms();
is(allPrograms.length, 3,
"Should be 3 programs total in cache.");
programs = await front.getPrograms();
is(programs.length, 1,
"There should be 1 cached program actor now.");
await checkHighlightingInTheFirstPage(programs[0]);
ok(true, "The cached programs behave correctly after navigating back and reloading.");
// 3. Perform a bfcache navigation and a page reload.
await navigateInHistory(target, "forward");
globalDestroyed = once(front, "global-created");
globalCreated = once(front, "global-destroyed");
programsLinked = getPrograms(front, 2);
reload(target);
await promise.all([programsLinked, globalDestroyed, globalCreated]);
allPrograms = await front._getAllPrograms();
is(allPrograms.length, 3,
"Should be 3 programs total in cache.");
programs = await front.getPrograms();
is(programs.length, 2,
"There should be 2 cached program actors now.");
await checkHighlightingInTheSecondPage(programs[0], programs[1]);
ok(true, "The cached programs behave correctly after navigating forward and reloading.");
await removeTab(target.tab);
finish();
function checkHighlightingInTheFirstPage(programActor) {
return (async function() {
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 255, g: 0, b: 0, a: 255 }, true);
await ensurePixelIs(front, { x: 511, y: 511 }, { r: 0, g: 255, b: 0, a: 255 }, true);
ok(true, "The corner pixel colors are correct before highlighting.");
await programActor.highlight([0, 1, 0, 1]);
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 0, g: 0, b: 0, a: 255 }, true);
await ensurePixelIs(front, { x: 511, y: 511 }, { r: 0, g: 255, b: 0, a: 255 }, true);
ok(true, "The corner pixel colors are correct after highlighting.");
await programActor.unhighlight();
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 255, g: 0, b: 0, a: 255 }, true);
await ensurePixelIs(front, { x: 511, y: 511 }, { r: 0, g: 255, b: 0, a: 255 }, true);
ok(true, "The corner pixel colors are correct after unhighlighting.");
})();
}
function checkHighlightingInTheSecondPage(firstProgramActor, secondProgramActor) {
return (async function() {
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 255, g: 255, b: 0, a: 255 }, true, "#canvas1");
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 0, g: 255, b: 255, a: 255 }, true, "#canvas2");
await ensurePixelIs(front, { x: 127, y: 127 }, { r: 255, g: 255, b: 0, a: 255 }, true, "#canvas1");
await ensurePixelIs(front, { x: 127, y: 127 }, { r: 0, g: 255, b: 255, a: 255 }, true, "#canvas2");
ok(true, "The two canvases are correctly drawn before highlighting.");
await firstProgramActor.highlight([1, 0, 0, 1]);
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 255, g: 0, b: 0, a: 255 }, true, "#canvas1");
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 0, g: 255, b: 255, a: 255 }, true, "#canvas2");
await ensurePixelIs(front, { x: 127, y: 127 }, { r: 255, g: 0, b: 0, a: 255 }, true, "#canvas1");
await ensurePixelIs(front, { x: 127, y: 127 }, { r: 0, g: 255, b: 255, a: 255 }, true, "#canvas2");
ok(true, "The first canvas was correctly filled after highlighting.");
await secondProgramActor.highlight([0, 1, 0, 1]);
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 255, g: 0, b: 0, a: 255 }, true, "#canvas1");
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 0, g: 255, b: 0, a: 255 }, true, "#canvas2");
await ensurePixelIs(front, { x: 127, y: 127 }, { r: 255, g: 0, b: 0, a: 255 }, true, "#canvas1");
await ensurePixelIs(front, { x: 127, y: 127 }, { r: 0, g: 255, b: 0, a: 255 }, true, "#canvas2");
ok(true, "The second canvas was correctly filled after highlighting.");
await firstProgramActor.unhighlight();
await secondProgramActor.unhighlight();
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 255, g: 255, b: 0, a: 255 }, true, "#canvas1");
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 0, g: 255, b: 255, a: 255 }, true, "#canvas2");
await ensurePixelIs(front, { x: 127, y: 127 }, { r: 255, g: 255, b: 0, a: 255 }, true, "#canvas1");
await ensurePixelIs(front, { x: 127, y: 127 }, { r: 0, g: 255, b: 255, a: 255 }, true, "#canvas2");
ok(true, "The two canvases were correctly filled after unhighlighting.");
})();
}
}

View File

@ -1,46 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests that the blackbox/unblackbox operations work as expected with
* overlapping geometry.
*/
async function ifWebGLSupported() {
const { target, front } = await initBackend(OVERLAPPING_GEOMETRY_CANVAS_URL);
front.setup({ reload: true });
const [firstProgramActor, secondProgramActor] = await getPrograms(front, 2);
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 255, g: 255, b: 0, a: 255 }, true);
await ensurePixelIs(front, { x: 64, y: 64 }, { r: 0, g: 255, b: 255, a: 255 }, true);
await ensurePixelIs(front, { x: 127, y: 127 }, { r: 255, g: 255, b: 0, a: 255 }, true);
ok(true, "The corner vs. center pixel colors are correct before blackboxing.");
await firstProgramActor.blackbox();
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 0, g: 0, b: 0, a: 255 }, true);
await ensurePixelIs(front, { x: 64, y: 64 }, { r: 0, g: 255, b: 255, a: 255 }, true);
await ensurePixelIs(front, { x: 127, y: 127 }, { r: 0, g: 0, b: 0, a: 255 }, true);
ok(true, "The corner vs. center pixel colors are correct after blackboxing (1).");
await firstProgramActor.unblackbox();
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 255, g: 255, b: 0, a: 255 }, true);
await ensurePixelIs(front, { x: 64, y: 64 }, { r: 0, g: 255, b: 255, a: 255 }, true);
await ensurePixelIs(front, { x: 127, y: 127 }, { r: 255, g: 255, b: 0, a: 255 }, true);
ok(true, "The corner vs. center pixel colors are correct after unblackboxing (1).");
await secondProgramActor.blackbox();
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 255, g: 255, b: 0, a: 255 }, true);
await ensurePixelIs(front, { x: 64, y: 64 }, { r: 255, g: 255, b: 0, a: 255 }, true);
await ensurePixelIs(front, { x: 127, y: 127 }, { r: 255, g: 255, b: 0, a: 255 }, true);
ok(true, "The corner vs. center pixel colors are correct after blackboxing (2).");
await secondProgramActor.unblackbox();
await ensurePixelIs(front, { x: 0, y: 0 }, { r: 255, g: 255, b: 0, a: 255 }, true);
await ensurePixelIs(front, { x: 64, y: 64 }, { r: 0, g: 255, b: 255, a: 255 }, true);
await ensurePixelIs(front, { x: 127, y: 127 }, { r: 255, g: 255, b: 0, a: 255 }, true);
ok(true, "The corner vs. center pixel colors are correct after unblackboxing (2).");
await removeTab(target.tab);
finish();
}

View File

@ -1,31 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests the `getPixel` actor method works across threads.
*/
async function ifWebGLSupported() {
const { target, front } = await initBackend(MULTIPLE_CONTEXTS_URL);
front.setup({ reload: true });
await getPrograms(front, 2);
// Wait a frame to ensure rendering
await front.waitForFrame();
let pixel = await front.getPixel({ selector: "#canvas1", position: { x: 0, y: 0 }});
is(pixel.r, 255, "correct `r` value for first canvas.");
is(pixel.g, 255, "correct `g` value for first canvas.");
is(pixel.b, 0, "correct `b` value for first canvas.");
is(pixel.a, 255, "correct `a` value for first canvas.");
pixel = await front.getPixel({ selector: "#canvas2", position: { x: 0, y: 0 }});
is(pixel.r, 0, "correct `r` value for second canvas.");
is(pixel.g, 255, "correct `g` value for second canvas.");
is(pixel.b, 255, "correct `b` value for second canvas.");
is(pixel.a, 255, "correct `a` value for second canvas.");
await removeTab(target.tab);
finish();
}

View File

@ -1,135 +0,0 @@
<!-- Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ -->
<!doctype html>
<html>
<head>
<meta charset="utf-8"/>
<title>WebGL editor test page</title>
<script id="shader-vs" type="x-shader/x-vertex">
precision lowp float;
attribute vec3 aVertexPosition;
uniform float uDepth;
void main(void) {
gl_Position = vec4(aVertexPosition, uDepth);
}
</script>
<script id="shader-fs-0" type="x-shader/x-fragment">
precision lowp float;
void main(void) {
gl_FragColor = vec4(0.5, 0.5, 0.5, 1.0);
}
</script>
<script id="shader-fs-1" type="x-shader/x-fragment">
precision lowp float;
void main(void) {
gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
}
</script>
</head>
<body>
<canvas id="canvas" width="128" height="128"></canvas>
<script type="text/javascript">
"use strict";
let canvas, gl;
const program = [];
let squareVerticesPositionBuffer;
const vertexPositionAttribute = [];
const depthUniform = [];
window.onload = function() {
canvas = document.querySelector("canvas");
gl = canvas.getContext("webgl", { preserveDrawingBuffer: true });
gl.clearColor(0.0, 0.0, 0.0, 1.0);
initProgram(0);
initProgram(1);
initBuffers();
drawScene();
};
function initProgram(i) {
const vertexShader = getShader("shader-vs");
const fragmentShader = getShader("shader-fs-" + i);
program[i] = gl.createProgram();
gl.attachShader(program[i], vertexShader);
gl.attachShader(program[i], fragmentShader);
gl.linkProgram(program[i]);
vertexPositionAttribute[i] = gl.getAttribLocation(program[i], "aVertexPosition");
gl.enableVertexAttribArray(vertexPositionAttribute[i]);
depthUniform[i] = gl.getUniformLocation(program[i], "uDepth");
}
function getShader(id) {
const script = document.getElementById(id);
const source = script.textContent;
let shader;
if (script.type == "x-shader/x-fragment") {
shader = gl.createShader(gl.FRAGMENT_SHADER);
} else if (script.type == "x-shader/x-vertex") {
shader = gl.createShader(gl.VERTEX_SHADER);
}
gl.shaderSource(shader, source);
gl.compileShader(shader);
return shader;
}
function initBuffers() {
squareVerticesPositionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, squareVerticesPositionBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
1.0, 1.0, 0.0,
-1.0, 1.0, 0.0,
1.0, -1.0, 0.0,
-1.0, -1.0, 0.0,
]), gl.STATIC_DRAW);
}
function drawScene() {
gl.clear(gl.COLOR_BUFFER_BIT);
for (let i = 0; i < 2; i++) {
gl.bindBuffer(gl.ARRAY_BUFFER, squareVerticesPositionBuffer);
gl.vertexAttribPointer(vertexPositionAttribute[i], 3, gl.FLOAT, false, 0, 0);
gl.useProgram(program[i]);
gl.uniform1f(depthUniform[i], i + 1);
blend(i);
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
}
window.requestAnimationFrame(drawScene);
}
function blend(i) {
if (i == 0) {
gl.disable(gl.BLEND);
} else if (i == 1) {
gl.enable(gl.BLEND);
gl.blendColor(0.5, 0, 0, 0.25);
gl.blendEquationSeparate(
gl.FUNC_REVERSE_SUBTRACT, gl.FUNC_SUBTRACT);
gl.blendFuncSeparate(
gl.CONSTANT_COLOR, gl.ONE_MINUS_CONSTANT_COLOR,
gl.ONE_MINUS_CONSTANT_COLOR, gl.CONSTANT_COLOR);
}
}
</script>
</body>
</html>

View File

@ -1,112 +0,0 @@
<!-- Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ -->
<!doctype html>
<html>
<head>
<meta charset="utf-8"/>
<title>WebGL editor test page</title>
<script id="shader-vs" type="x-shader/x-vertex">
precision lowp float;
attribute vec3 aVertexPosition;
void main(void) {
gl_Position = vec4(aVertexPosition, 1);
}
</script>
<script id="shader-fs" type="x-shader/x-fragment">
precision lowp float;
uniform vec3 uColor;
void main(void) {
gl_FragColor = vec4(uColor, 1);
}
</script>
</head>
<body>
<canvas id="canvas1" width="128" height="128"></canvas>
<canvas id="canvas2" width="128" height="128"></canvas>
<script type="text/javascript">
"use strict";
const canvas = [], gl = [];
const program = [];
const squareVerticesPositionBuffer = [];
const vertexPositionAttribute = [];
const colorUniform = [];
window.onload = function() {
for (let i = 0; i < 2; i++) {
canvas[i] = document.querySelector("#canvas" + (i + 1));
gl[i] = canvas[i].getContext("webgl", { preserveDrawingBuffer: true });
gl[i].clearColor(0.0, 0.0, 0.0, 1.0);
initProgram(i);
initBuffers(i);
drawScene(i);
}
};
function initProgram(i) {
const vertexShader = getShader(gl[i], "shader-vs");
const fragmentShader = getShader(gl[i], "shader-fs");
program[i] = gl[i].createProgram();
gl[i].attachShader(program[i], vertexShader);
gl[i].attachShader(program[i], fragmentShader);
gl[i].linkProgram(program[i]);
vertexPositionAttribute[i] = gl[i].getAttribLocation(program[i], "aVertexPosition");
gl[i].enableVertexAttribArray(vertexPositionAttribute[i]);
colorUniform[i] = gl[i].getUniformLocation(program[i], "uColor");
}
function getShader(gl, id) {
const script = document.getElementById(id);
const source = script.textContent;
let shader;
if (script.type == "x-shader/x-fragment") {
shader = gl.createShader(gl.FRAGMENT_SHADER);
} else if (script.type == "x-shader/x-vertex") {
shader = gl.createShader(gl.VERTEX_SHADER);
}
gl.shaderSource(shader, source);
gl.compileShader(shader);
return shader;
}
function initBuffers(i) {
squareVerticesPositionBuffer[i] = gl[i].createBuffer();
gl[i].bindBuffer(gl[i].ARRAY_BUFFER, squareVerticesPositionBuffer[i]);
gl[i].bufferData(gl[i].ARRAY_BUFFER, new Float32Array([
1.0, 1.0, 0.0,
-1.0, 1.0, 0.0,
1.0, -1.0, 0.0,
-1.0, -1.0, 0.0,
]), gl[i].STATIC_DRAW);
}
function drawScene(i) {
gl[i].clear(gl[i].COLOR_BUFFER_BIT);
gl[i].bindBuffer(gl[i].ARRAY_BUFFER, squareVerticesPositionBuffer[i]);
gl[i].vertexAttribPointer(vertexPositionAttribute[i], 3, gl[i].FLOAT, false, 0, 0);
gl[i].useProgram(program[i]);
gl[i].uniform3fv(colorUniform[i], i == 0 ? [1, 1, 0] : [0, 1, 1]);
gl[i].drawArrays(gl[i].TRIANGLE_STRIP, 0, 4);
window.requestAnimationFrame(() => drawScene(i));
}
</script>
</body>
</html>

View File

@ -1,120 +0,0 @@
<!-- Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ -->
<!doctype html>
<html>
<head>
<meta charset="utf-8"/>
<title>WebGL editor test page</title>
<script id="shader-vs" type="x-shader/x-vertex">
precision lowp float;
attribute vec3 aVertexPosition;
uniform float uDepth;
void main(void) {
gl_Position = vec4(aVertexPosition, uDepth);
}
</script>
<script id="shader-fs-0" type="x-shader/x-fragment">
precision lowp float;
void main(void) {
gl_FragColor = vec4(1.0, 1.0, 0.0, 1.0);
}
</script>
<script id="shader-fs-1" type="x-shader/x-fragment">
precision lowp float;
void main(void) {
gl_FragColor = vec4(0.0, 1.0, 1.0, 1.0);
}
</script>
</head>
<body>
<canvas id="canvas" width="128" height="128"></canvas>
<script type="text/javascript">
"use strict";
let canvas, gl;
const program = [];
let squareVerticesPositionBuffer;
const vertexPositionAttribute = [];
const depthUniform = [];
window.onload = function() {
canvas = document.querySelector("canvas");
gl = canvas.getContext("webgl", { preserveDrawingBuffer: true });
gl.clearColor(0.0, 0.0, 0.0, 1.0);
initProgram(0);
initProgram(1);
initBuffers();
drawScene();
};
function initProgram(i) {
const vertexShader = getShader("shader-vs");
const fragmentShader = getShader("shader-fs-" + i);
program[i] = gl.createProgram();
gl.attachShader(program[i], vertexShader);
gl.attachShader(program[i], fragmentShader);
gl.linkProgram(program[i]);
vertexPositionAttribute[i] = gl.getAttribLocation(program[i], "aVertexPosition");
gl.enableVertexAttribArray(vertexPositionAttribute[i]);
depthUniform[i] = gl.getUniformLocation(program[i], "uDepth");
}
function getShader(id) {
const script = document.getElementById(id);
const source = script.textContent;
let shader;
if (script.type == "x-shader/x-fragment") {
shader = gl.createShader(gl.FRAGMENT_SHADER);
} else if (script.type == "x-shader/x-vertex") {
shader = gl.createShader(gl.VERTEX_SHADER);
}
gl.shaderSource(shader, source);
gl.compileShader(shader);
return shader;
}
function initBuffers() {
squareVerticesPositionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, squareVerticesPositionBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
1.0, 1.0, 0.0,
-1.0, 1.0, 0.0,
1.0, -1.0, 0.0,
-1.0, -1.0, 0.0,
]), gl.STATIC_DRAW);
}
function drawScene() {
gl.clear(gl.COLOR_BUFFER_BIT);
for (let i = 0; i < 2; i++) {
gl.bindBuffer(gl.ARRAY_BUFFER, squareVerticesPositionBuffer);
gl.vertexAttribPointer(vertexPositionAttribute[i], 3, gl.FLOAT, false, 0, 0);
gl.useProgram(program[i]);
gl.uniform1f(depthUniform[i], i + 1);
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
}
window.requestAnimationFrame(drawScene);
}
</script>
</body>
</html>

View File

@ -1,83 +0,0 @@
<!-- Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ -->
<!doctype html>
<html>
<head>
<meta charset="utf-8"/>
<title>WebGL editor test page</title>
<script id="shader-vs" type="x-shader/x-vertex">
precision lowp float;
void main(void) {
gl_Position = vec4(0, 0, 0, 1); // I'm a vertex shader!
}
</script>
<script id="shader-fs" type="x-shader/x-fragment">
precision lowp float;
varying vec3 vFragmentColor;
void main(void) {
gl_FragColor = vec4(1, 0, 0, 1); // I'm a fragment shader!
}
</script>
</head>
<body>
<canvas width="512" height="512"></canvas>
<script type="text/javascript">
"use strict";
let canvas, gl;
window.onload = function() {
canvas = document.querySelector("canvas");
gl = canvas.getContext("webgl", { preserveDrawingBuffer: true });
const shaderProgram = gl.createProgram();
let vertexShader, fragmentShader;
// Compile and attach the shaders in a random order. The test will
// ensure that the correct vertex and fragment source is retrieved
// regardless of this crazyness.
if (Math.random() > 0.5) {
vertexShader = getShader(gl, "shader-vs");
fragmentShader = getShader(gl, "shader-fs");
} else {
fragmentShader = getShader(gl, "shader-fs");
vertexShader = getShader(gl, "shader-vs");
}
if (Math.random() > 0.5) {
gl.attachShader(shaderProgram, vertexShader);
gl.attachShader(shaderProgram, fragmentShader);
} else {
gl.attachShader(shaderProgram, fragmentShader);
gl.attachShader(shaderProgram, vertexShader);
}
gl.linkProgram(shaderProgram);
};
function getShader(gl, id) {
const script = document.getElementById(id);
const source = script.textContent;
let shader;
if (script.type == "x-shader/x-fragment") {
shader = gl.createShader(gl.FRAGMENT_SHADER);
} else if (script.type == "x-shader/x-vertex") {
shader = gl.createShader(gl.VERTEX_SHADER);
}
gl.shaderSource(shader, source);
gl.compileShader(shader);
return shader;
}
</script>
</body>
</html>

View File

@ -1,125 +0,0 @@
<!-- Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ -->
<!doctype html>
<html>
<head>
<meta charset="utf-8"/>
<title>WebGL editor test page</title>
<script id="shader-vs" type="x-shader/x-vertex">
precision lowp float;
attribute vec3 aVertexPosition;
attribute vec3 aVertexColor;
varying vec3 vFragmentColor;
void main(void) {
gl_Position = vec4(aVertexPosition, 1.0);
vFragmentColor = aVertexColor; // I'm special!
}
</script>
<script id="shader-fs" type="x-shader/x-fragment">
precision lowp float;
varying vec3 vFragmentColor;
void main(void) {
gl_FragColor = vec4(vFragmentColor, 1.0); // I'm also special!
}
</script>
</head>
<body>
<canvas width="512" height="512"></canvas>
<script type="text/javascript">
"use strict";
let canvas, gl;
let program;
let squareVerticesPositionBuffer;
let squareVerticesColorBuffer;
let vertexPositionAttribute;
let vertexColorAttribute;
window.onload = function() {
canvas = document.querySelector("canvas");
gl = canvas.getContext("webgl", { preserveDrawingBuffer: true });
gl.clearColor(0.0, 0.0, 0.0, 1.0);
initProgram();
initBuffers();
drawScene();
};
function initProgram() {
const vertexShader = getShader(gl, "shader-vs");
const fragmentShader = getShader(gl, "shader-fs");
program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
vertexPositionAttribute = gl.getAttribLocation(program, "aVertexPosition");
gl.enableVertexAttribArray(vertexPositionAttribute);
vertexColorAttribute = gl.getAttribLocation(program, "aVertexColor");
gl.enableVertexAttribArray(vertexColorAttribute);
}
function getShader(gl, id) {
const script = document.getElementById(id);
const source = script.textContent;
let shader;
if (script.type == "x-shader/x-fragment") {
shader = gl.createShader(gl.FRAGMENT_SHADER);
} else if (script.type == "x-shader/x-vertex") {
shader = gl.createShader(gl.VERTEX_SHADER);
}
gl.shaderSource(shader, source);
gl.compileShader(shader);
return shader;
}
function initBuffers() {
squareVerticesPositionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, squareVerticesPositionBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
1.0, 1.0, 0.0,
-1.0, 1.0, 0.0,
1.0, -1.0, 0.0,
-1.0, -1.0, 0.0,
]), gl.STATIC_DRAW);
squareVerticesColorBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, squareVerticesColorBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
1.0, 1.0, 1.0, 1.0,
1.0, 0.0, 0.0, 1.0,
0.0, 1.0, 0.0, 1.0,
0.0, 0.0, 1.0, 1.0,
]), gl.STATIC_DRAW);
}
function drawScene() {
gl.clear(gl.COLOR_BUFFER_BIT);
gl.bindBuffer(gl.ARRAY_BUFFER, squareVerticesPositionBuffer);
gl.vertexAttribPointer(vertexPositionAttribute, 3, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ARRAY_BUFFER, squareVerticesColorBuffer);
gl.vertexAttribPointer(vertexColorAttribute, 4, gl.FLOAT, false, 0, 0);
gl.useProgram(program);
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
window.requestAnimationFrame(drawScene);
}
</script>
</body>
</html>

View File

@ -1,208 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/* eslint no-unused-vars: [2, {"vars": "local"}] */
/* import-globals-from ../../shared/test/shared-head.js */
"use strict";
// Load the shared-head file first.
Services.scriptloader.loadSubScript(
"chrome://mochitests/content/browser/devtools/client/shared/test/shared-head.js",
this);
var { DebuggerClient } = require("devtools/shared/client/debugger-client");
var { DebuggerServer } = require("devtools/server/main");
var { Toolbox } = require("devtools/client/framework/toolbox");
var { isWebGLSupported } = require("devtools/client/shared/webgl-utils");
const EXAMPLE_URL = "http://example.com/browser/devtools/client/shadereditor/test/";
const SIMPLE_CANVAS_URL = EXAMPLE_URL + "doc_simple-canvas.html";
const SHADER_ORDER_URL = EXAMPLE_URL + "doc_shader-order.html";
const MULTIPLE_CONTEXTS_URL = EXAMPLE_URL + "doc_multiple-contexts.html";
const OVERLAPPING_GEOMETRY_CANVAS_URL = EXAMPLE_URL + "doc_overlapping-geometry.html";
const BLENDED_GEOMETRY_CANVAS_URL = EXAMPLE_URL + "doc_blended-geometry.html";
var gEnableLogging = Services.prefs.getBoolPref("devtools.debugger.log");
// To enable logging for try runs, just set the pref to true.
Services.prefs.setBoolPref("devtools.debugger.log", false);
var gToolEnabled = Services.prefs.getBoolPref("devtools.shadereditor.enabled");
registerCleanupFunction(() => {
Services.prefs.setBoolPref("devtools.debugger.log", gEnableLogging);
Services.prefs.setBoolPref("devtools.shadereditor.enabled", gToolEnabled);
// These tests use a lot of memory due to GL contexts, so force a GC to help
// fragmentation.
info("Forcing GC after shadereditor test.");
Cu.forceGC();
});
/**
* Call manually in tests that use frame script utils after initializing
* the shader editor. Must be called after initializing so we can detect
* whether or not `content` is a CPOW or not. Call after init but before navigating
* to different pages, as bfcache and thus shader caching gets really strange if
* frame script attached in the middle of the test.
*/
function loadFrameScripts() {
if (!content) {
loadFrameScriptUtils();
}
}
function handleError(aError) {
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
finish();
}
function ifWebGLSupported() {
ok(false, "You need to define a 'ifWebGLSupported' function.");
finish();
}
function ifWebGLUnsupported() {
todo(false, "Skipping test because WebGL isn't supported.");
finish();
}
async function test() {
const generator = isWebGLSupported(document) ? ifWebGLSupported : ifWebGLUnsupported;
try {
await generator();
} catch (e) {
handleError(e);
}
}
function createCanvas() {
return document.createElementNS("http://www.w3.org/1999/xhtml", "canvas");
}
function observe(aNotificationName, aOwnsWeak = false) {
info("Waiting for observer notification: '" + aNotificationName + ".");
return new Promise(resolve =>{
Services.obs.addObserver(function onNotification(...aArgs) {
Services.obs.removeObserver(onNotification, aNotificationName);
resolve.apply(deferred, aArgs);
}, aNotificationName, aOwnsWeak);
});
}
function isApprox(aFirst, aSecond, aMargin = 1) {
return Math.abs(aFirst - aSecond) <= aMargin;
}
function isApproxColor(aFirst, aSecond, aMargin) {
return isApprox(aFirst.r, aSecond.r, aMargin) &&
isApprox(aFirst.g, aSecond.g, aMargin) &&
isApprox(aFirst.b, aSecond.b, aMargin) &&
isApprox(aFirst.a, aSecond.a, aMargin);
}
function ensurePixelIs(aFront, aPosition, aColor, aWaitFlag = false, aSelector = "canvas") {
return (async function() {
const pixel = await aFront.getPixel({ selector: aSelector, position: aPosition });
if (isApproxColor(pixel, aColor)) {
ok(true, "Expected pixel is shown at: " + aPosition.toSource());
return;
}
if (aWaitFlag) {
await aFront.waitForFrame();
await ensurePixelIs(aFront, aPosition, aColor, aWaitFlag, aSelector);
return;
}
ok(false, "Expected pixel was not already shown at: " + aPosition.toSource());
throw new Error("Expected pixel was not already shown at: " + aPosition.toSource());
})();
}
function navigateInHistory(aTarget, aDirection, aWaitForTargetEvent = "navigate") {
if (!content) {
const mm = gBrowser.selectedBrowser.messageManager;
mm.sendAsyncMessage("devtools:test:history", { direction: aDirection });
} else {
executeSoon(() => content.history[aDirection]());
}
return once(aTarget, aWaitForTargetEvent);
}
function navigate(aTarget, aUrl, aWaitForTargetEvent = "navigate") {
executeSoon(() => aTarget.navigateTo({ url: aUrl }));
return once(aTarget, aWaitForTargetEvent);
}
async function reload(aTarget, aWaitForTargetEvent = "navigate") {
const onTargetEvent = once(aTarget, aWaitForTargetEvent);
await aTarget.reload();
return onTargetEvent;
}
function initBackend(aUrl) {
info("Initializing a shader editor front.");
DebuggerServer.init();
DebuggerServer.registerAllActors();
return (async function() {
const tab = await addTab(aUrl);
const target = await TargetFactory.forTab(tab);
await target.attach();
const front = await target.getFront("webgl");
return { target, front };
})();
}
function initShaderEditor(aUrl) {
info("Initializing a shader editor pane.");
return (async function() {
const tab = await addTab(aUrl);
const target = await TargetFactory.forTab(tab);
Services.prefs.setBoolPref("devtools.shadereditor.enabled", true);
const toolbox = await gDevTools.showToolbox(target, "shadereditor");
const panel = toolbox.getCurrentPanel();
return { target, panel };
})();
}
function teardown(aPanel) {
info("Destroying the specified shader editor.");
return promise.all([
once(aPanel, "destroyed"),
removeTab(aPanel.target.tab),
]);
}
// Due to `program-linked` events firing synchronously, we cannot
// just yield/chain them together, as then we miss all actors after the
// first event since they're fired consecutively. This allows us to capture
// all actors and returns an array containing them.
//
// Takes a `front` object that is an event emitter, the number of
// programs that should be listened to and waited on, and an optional
// `onAdd` function that calls with the entire actors array on program link
function getPrograms(front, count, onAdd) {
return new Promise(resolve => {
const actors = [];
front.on("program-linked", function onLink(actor) {
if (actors.length !== count) {
actors.push(actor);
if (typeof onAdd === "function") {
onAdd(actors);
}
}
if (actors.length === count) {
front.off("program-linked", onLink);
resolve(actors);
}
});
});
}

View File

@ -703,7 +703,6 @@ function getChartsFromToolId(id) {
case "PAINTFLASHING":
case "RESPONSIVE":
case "SCRATCHPAD":
case "SHADEREDITOR":
case "STORAGE":
case "STYLEEDITOR":
case "TOOLBOX":

View File

@ -220,7 +220,6 @@ skip-if = !e10s || os == "win" # RDM only works for remote tabs, Win: bug 140419
[browser_telemetry_toolboxtabs_jsprofiler.js]
[browser_telemetry_toolboxtabs_netmonitor.js]
[browser_telemetry_toolboxtabs_options.js]
[browser_telemetry_toolboxtabs_shadereditor.js]
[browser_telemetry_toolboxtabs_storage.js]
[browser_telemetry_toolboxtabs_styleeditor.js]
[browser_telemetry_toolboxtabs_webaudioeditor.js]

View File

@ -1,36 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
const TEST_URI = "data:text/html;charset=utf-8," +
"<p>browser_telemetry_toolboxtabs_shadereditor.js</p>";
// Because we need to gather stats for the period of time that a tool has been
// opened we make use of setTimeout() to create tool active times.
const TOOL_DELAY = 200;
const TOOL_PREF = "devtools.shadereditor.enabled";
add_task(async function() {
info("Active the sharer editor");
const originalPref = Services.prefs.getBoolPref(TOOL_PREF);
Services.prefs.setBoolPref(TOOL_PREF, true);
await addTab(TEST_URI);
startTelemetry();
await openAndCloseToolbox(2, TOOL_DELAY, "shadereditor");
checkResults();
gBrowser.removeCurrentTab();
info("De-activate the sharer editor");
Services.prefs.setBoolPref(TOOL_PREF, originalPref);
});
function checkResults() {
// For help generating these tests use generateTelemetryTests("DEVTOOLS_SHADEREDITOR_")
// here.
checkTelemetry("DEVTOOLS_SHADEREDITOR_OPENED_COUNT", "", {0: 2, 1: 0}, "array");
checkTelemetry("DEVTOOLS_SHADEREDITOR_TIME_ACTIVE_SECONDS", "", null, "hasentries");
}

View File

@ -1,12 +0,0 @@
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="context-fill #0c0c0d">
<path d="M2 4v8h12V4H2zm0-1h12a1 1 0 0 1 1 1v8a1 1 0 0 1-1 1H2a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1z"/>
<circle cx="1" cy="3" r="1"/>
<circle cx="1" cy="13" r="1"/>
<circle cx="15" cy="13" r="1"/>
<circle cx="15" cy="3" r="1"/>
<path d="M1.215 3.911l13 9 .411.285.57-.822-.411-.285-13-9-.411-.285-.57.822z"/>
<path fill-opacity=".3" d="M8 5h2v2H8zM8 8h2v2L9 8.711zM5 5.962V5h2v2h-.828l-.729-.368zM11 5h2v2h-2zM11 8h2v2h-2z"/>
</svg>

Before

Width:  |  Height:  |  Size: 764 B

View File

@ -1,119 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
/* Reload and waiting notices */
.notice-container {
margin-top: -50vh;
color: var(--theme-body-color-alt);
}
#reload-notice {
font-size: 120%;
}
#waiting-notice {
font-size: 110%;
}
/* Shaders pane */
#shaders-pane {
min-width: 150px;
}
.program-item {
padding: 2px 0px;
}
.side-menu-widget-item-checkbox {
-moz-appearance: none;
opacity: 0;
transition: opacity .15s ease-out 0s;
}
/* Only show the checkbox when the source is hovered over, is selected, or if it
* is not checked. */
.side-menu-widget-item:hover > .side-menu-widget-item-checkbox,
.side-menu-widget-item.selected > .side-menu-widget-item-checkbox,
.side-menu-widget-item-checkbox:not([checked]) {
opacity: 1;
transition: opacity .15s ease-out 0s;
}
.side-menu-widget-item-checkbox .checkbox-check {
-moz-appearance: none;
background-image: url(images/item-toggle.svg);
background-color: transparent;
width: 16px;
height: 16px;
border: 0;
-moz-context-properties: fill;
}
.side-menu-widget-item-checkbox:not([checked]) .checkbox-check,
.side-menu-widget-item-checkbox:not([checked]) + vbox {
opacity: 0.3;
}
.side-menu-widget-item:not(.selected) .checkbox-check {
fill: var(--theme-icon-color);
}
/* Make sure icon is white when the item is selected */
.side-menu-widget-item.selected .checkbox-check {
fill: var(--theme-selection-color);
}
/* Shader source editors */
.editor-label {
padding: 1px 12px;
border-top: 1px solid;
}
.editor-label {
background: var(--theme-toolbar-background);
border-color: var(--theme-splitter-color);
color: var(--theme-body-color-alt);
}
.editor-label[selected] {
background-color: var(--theme-selection-background);
color: var(--theme-selection-color);
}
.devtools-shader-tooltip-container .devtools-tooltip-simple-text {
color: var(--theme-content-color1);
border-bottom: 1px solid var(--theme-splitter-color);
}
.devtools-shader-tooltip-container .devtools-tooltip-simple-text:last-child {
border-bottom: 0;
}
/* Responsive sidebar */
@media (max-width: 700px) {
#shaders-pane {
max-height: 60vh;
}
#editors-splitter {
border-color: transparent;
}
.side-menu-widget-container {
box-shadow: none !important;
}
.side-menu-widget-item-arrow {
background-image: none !important;
}
.editor-label {
-moz-box-ordinal-group: 0;
border-bottom: 1px solid;
}
}