Bug 1171228 - Expose WEBGL_debug_renderer_info to Web Content #ifndef MOZ_RELEASE_BUILD. - r=kamidphish, sr=jst
--- a/dom/canvas/WebGLContextExtensions.cpp
+++ b/dom/canvas/WebGLContextExtensions.cpp
@@ -154,16 +154,30 @@ WebGLContext::IsExtensionSupported(WebGL
return gl->IsExtensionSupported(gl::GLContext::IMG_texture_compression_pvrtc);
case WebGLExtensionID::WEBGL_compressed_texture_s3tc:
if (gl->IsExtensionSupported(gl::GLContext::EXT_texture_compression_s3tc))
return true;
return gl->IsExtensionSupported(gl::GLContext::EXT_texture_compression_dxt1) &&
gl->IsExtensionSupported(gl::GLContext::ANGLE_texture_compression_dxt3) &&
gl->IsExtensionSupported(gl::GLContext::ANGLE_texture_compression_dxt5);
+
+ case WebGLExtensionID::WEBGL_debug_renderer_info:
+ {
+ bool isEnabled = true;
+
+#ifdef RELEASE_BUILD
+ // Keep this disabled on Release and Beta for now. (see bug 1171228)
+ isEnabled = false;
+#endif
+ if (Preferences::GetBool("webgl.disable-debug-renderer-info", false))
+ isEnabled = false;
+
+ return isEnabled;
+ }
case WebGLExtensionID::WEBGL_depth_texture:
// WEBGL_depth_texture supports DEPTH_STENCIL textures
if (!gl->IsSupported(gl::GLFeature::packed_depth_stencil))
return false;
return gl->IsSupported(gl::GLFeature::depth_texture) ||
gl->IsExtensionSupported(gl::GLContext::ANGLE_depth_texture);
case WebGLExtensionID::WEBGL_draw_buffers:
--- a/dom/canvas/WebGLContextState.cpp
+++ b/dom/canvas/WebGLContextState.cpp
@@ -1,24 +1,27 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* 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/. */
#include "WebGLContext.h"
+
+#include "GLContext.h"
+#include "mozilla/dom/ToJSValue.h"
+#include "mozilla/Preferences.h"
+#include "nsString.h"
+#include "WebGLBuffer.h"
#include "WebGLContextUtils.h"
-#include "WebGLBuffer.h"
+#include "WebGLFramebuffer.h"
+#include "WebGLProgram.h"
+#include "WebGLRenderbuffer.h"
#include "WebGLShader.h"
-#include "WebGLProgram.h"
-#include "WebGLFramebuffer.h"
-#include "WebGLRenderbuffer.h"
#include "WebGLTexture.h"
#include "WebGLVertexArray.h"
-#include "GLContext.h"
-#include "mozilla/dom/ToJSValue.h"
namespace mozilla {
void
WebGLContext::Disable(GLenum cap)
{
if (IsContextLost())
return;
@@ -52,16 +55,28 @@ WebGLContext::Enable(GLenum cap)
{
*trackingSlot = 1;
}
MakeContextCurrent();
gl->fEnable(cap);
}
+static JS::Value
+StringValue(JSContext* cx, const nsAString& str, ErrorResult& rv)
+{
+ JSString* jsStr = JS_NewUCStringCopyN(cx, str.BeginReading(), str.Length());
+ if (!jsStr) {
+ rv.Throw(NS_ERROR_OUT_OF_MEMORY);
+ return JS::NullValue();
+ }
+
+ return JS::StringValue(jsStr);
+}
+
bool
WebGLContext::GetStencilBits(GLint* out_stencilBits)
{
*out_stencilBits = 0;
if (mBoundDrawFramebuffer) {
if (mBoundDrawFramebuffer->HasDepthStencilConflict()) {
// Error, we don't know which stencil buffer's bits to use
ErrorInvalidFramebufferOperation("getParameter: framebuffer has two stencil buffers bound");
@@ -171,29 +186,57 @@ WebGLContext::GetParameter(JSContext* cx
realGLboolean disjoint = LOCAL_GL_FALSE;
if (gl->IsExtensionSupported(gl::GLContext::EXT_disjoint_timer_query)) {
gl->fGetBooleanv(pname, &disjoint);
}
return JS::BooleanValue(bool(disjoint));
}
}
- // Privileged string params exposed by WEBGL_debug_renderer_info:
+ // Privileged string params exposed by WEBGL_debug_renderer_info.
+ // The privilege check is done in WebGLContext::IsExtensionSupported.
+ // So here we just have to check that the extension is enabled.
if (IsExtensionEnabled(WebGLExtensionID::WEBGL_debug_renderer_info)) {
switch (pname) {
case UNMASKED_VENDOR_WEBGL:
case UNMASKED_RENDERER_WEBGL:
- GLenum glstringname = LOCAL_GL_NONE;
- if (pname == UNMASKED_VENDOR_WEBGL) {
- glstringname = LOCAL_GL_VENDOR;
- } else if (pname == UNMASKED_RENDERER_WEBGL) {
- glstringname = LOCAL_GL_RENDERER;
+ {
+ const char* overridePref = nullptr;
+ GLenum driverEnum = LOCAL_GL_NONE;
+
+ switch (pname) {
+ case UNMASKED_RENDERER_WEBGL:
+ overridePref = "webgl.renderer-string-override";
+ driverEnum = LOCAL_GL_RENDERER;
+ break;
+ case UNMASKED_VENDOR_WEBGL:
+ overridePref = "webgl.vendor-string-override";
+ driverEnum = LOCAL_GL_VENDOR;
+ break;
+ default:
+ MOZ_CRASH("bad `pname`");
+ }
+
+ bool hasRetVal = false;
+
+ nsAutoString ret;
+ if (overridePref) {
+ nsresult res = Preferences::GetString(overridePref, &ret);
+ if (NS_SUCCEEDED(res) && ret.Length() > 0)
+ hasRetVal = true;
+ }
+
+ if (!hasRetVal) {
+ const char* chars = reinterpret_cast<const char*>(gl->fGetString(driverEnum));
+ ret = NS_ConvertASCIItoUTF16(chars);
+ hasRetVal = true;
+ }
+
+ return StringValue(cx, ret, rv);
}
- const GLchar* string = (const GLchar*) gl->fGetString(glstringname);
- return StringValue(cx, string, rv);
}
}
if (IsExtensionEnabled(WebGLExtensionID::OES_standard_derivatives)) {
if (pname == LOCAL_GL_FRAGMENT_SHADER_DERIVATIVE_HINT) {
GLint i = 0;
gl->fGetIntegerv(pname, &i);
return JS::Int32Value(i);
--- a/dom/canvas/test/webgl-mochitest.ini
+++ b/dom/canvas/test/webgl-mochitest.ini
@@ -17,16 +17,17 @@ support-files = captureStream_common.js
[webgl-mochitest/test_hidden_alpha.html]
skip-if = (os == 'b2g') || buildapp == 'mulet' # Mulet - bug 1093639 (crashes in libLLVM-3.0.so)
[webgl-mochitest/test_implicit_color_buffer_float.html]
[webgl-mochitest/test_highp_fs.html]
[webgl-mochitest/test_no_arr_points.html]
skip-if = android_version == '10' || android_version == '18' #Android 2.3 and 4.3 aws only; bug 1030942
[webgl-mochitest/test_noprog_draw.html]
[webgl-mochitest/test_privileged_exts.html]
+[webgl-mochitest/test_renderer_strings.html]
[webgl-mochitest/test_texsubimage_float.html]
[webgl-mochitest/test_uninit_data.html]
[webgl-mochitest/test_webgl_available.html]
skip-if = toolkit == 'android' #bug 865443- seperate suite - the non_conf* tests pass except for one on armv6 tests
#[webgl-mochitest/test_webgl_color_buffer_float.html]
# We haven't cleaned up the Try results yet, but let's get this on the books first.
[webgl-mochitest/test_webgl_conformance.html]
skip-if = buildapp == 'mulet' || toolkit == 'android' #bug 865443- seperate suite - the non_conf* tests pass except for one on armv6 tests
--- a/dom/canvas/test/webgl-mochitest/test_privileged_exts.html
+++ b/dom/canvas/test/webgl-mochitest/test_privileged_exts.html
@@ -19,14 +19,14 @@ function TestExt(gl, name) {
(function() {
var gl = WebGLUtil.getWebGL('c');
if (!gl) {
todo(gl, 'Get GL working here first.');
return;
}
// Privileged extensions:
- TestExt(gl, 'WEBGL_debug_renderer_info');
+ TestExt(gl, 'WEBGL_debug_shaders');
})();
</script>
</body>
</html>
new file mode 100644
--- /dev/null
+++ b/dom/canvas/test/webgl-mochitest/test_renderer_strings.html
@@ -0,0 +1,98 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<script src="/tests/SimpleTest/SimpleTest.js"></script>
+<link rel="stylesheet" href="/tests/SimpleTest/test.css">
+</head>
+<body>
+<script>
+
+function AssertError(gl, expected, info) {
+ var actual = gl.getError();
+ while (gl.getError()) {}
+
+ ok(actual == expected,
+ 'For ' + info + ', expected 0x' + expected.toString(16) + ', got 0x'
+ + actual.toString(16));
+}
+
+var gl;
+
+var RENDERER_OVERRIDE = 'overridden renderer';
+var VENDOR_OVERRIDE = 'overridden vendor';
+
+function TestExt() {
+ var ext = gl.getExtension('WEBGL_debug_renderer_info');
+ ok(ext, 'Should have access to \'WEBGL_debug_renderer_info\'.');
+ AssertError(gl, 0, 'start of test');
+
+ var renderer = gl.getParameter(ext.UNMASKED_RENDERER_WEBGL);
+ AssertError(gl, 0, 'UNMASKED_RENDERER_WEBGL');
+ ok(renderer,
+ 'UNMASKED_RENDERER_WEBGL value should not be empty, was \'' + renderer + '\'');
+
+ var vendor = gl.getParameter(ext.UNMASKED_VENDOR_WEBGL);
+ AssertError(gl, 0, 'UNMASKED_VENDOR_WEBGL');
+ ok(vendor, 'UNMASKED_VENDOR_WEBGL value should not be empty, was \'' + vendor + '\'');
+
+ var prefArrArr = [
+ ['webgl.renderer-string-override', RENDERER_OVERRIDE],
+ ['webgl.vendor-string-override', VENDOR_OVERRIDE],
+ ];
+ var prefEnv = {'set': prefArrArr};
+ SpecialPowers.pushPrefEnv(prefEnv, TestOverrides);
+}
+
+function TestOverrides() {
+ var ext = gl.getExtension('WEBGL_debug_renderer_info');
+ ok(ext, 'Should have access to \'WEBGL_debug_renderer_info\'.');
+ AssertError(gl, 0, 'start of test');
+
+ var renderer = gl.getParameter(ext.UNMASKED_RENDERER_WEBGL);
+ AssertError(gl, 0, 'UNMASKED_RENDERER_WEBGL');
+ ok(renderer == RENDERER_OVERRIDE,
+ 'UNMASKED_RENDERER_WEBGL value should be \'' + RENDERER_OVERRIDE + '\', was \''
+ + renderer + '\'');
+
+ var vendor = gl.getParameter(ext.UNMASKED_VENDOR_WEBGL);
+ AssertError(gl, 0, 'UNMASKED_VENDOR_WEBGL');
+ ok(vendor == VENDOR_OVERRIDE,
+ 'UNMASKED_VENDOR_WEBGL value should be \'' + VENDOR_OVERRIDE + '\', was \'' + vendor
+ + '\'');
+
+ var prefArrArr = [
+ ['webgl.disable-debug-renderer-info', true],
+ ];
+ var prefEnv = {'set': prefArrArr};
+ SpecialPowers.pushPrefEnv(prefEnv, TestDisable);
+}
+
+function TestDisable() {
+ var ext = gl.getExtension('WEBGL_debug_renderer_info');
+ ok(!ext, 'Should not have access to \'WEBGL_debug_renderer_info\'.');
+
+ ok(true, 'Test complete.');
+ SimpleTest.finish();
+}
+
+(function() {
+ var canvas = document.createElement('canvas');
+ gl = canvas.getContext('experimental-webgl');
+ if (!gl) {
+ todo(gl, 'Get WebGL working here first.');
+ ok(true, 'Test complete.');
+ return;
+ }
+
+ SimpleTest.waitForExplicitFinish();
+
+ var prefArrArr = [
+ ['webgl.disable-debug-renderer-info', false],
+ ];
+ var prefEnv = {'set': prefArrArr};
+ SpecialPowers.pushPrefEnv(prefEnv, TestExt);
+})();
+
+</script>
+</body>
+</html>
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -4101,16 +4101,18 @@ pref("image.onload.decode.limit", 0);
// WebGL prefs
#ifdef ANDROID
// Disable MSAA on mobile.
pref("gl.msaa-level", 0);
#else
pref("gl.msaa-level", 2);
#endif
+pref("gl.require-hardware", false);
+
pref("webgl.force-enabled", false);
pref("webgl.disabled", false);
pref("webgl.disable-angle", false);
pref("webgl.min_capability_mode", false);
pref("webgl.disable-extensions", false);
pref("webgl.msaa-force", false);
pref("webgl.prefer-16bpp", false);
pref("webgl.default-no-alpha", false);
@@ -4119,17 +4121,19 @@ pref("webgl.lose-context-on-memory-press
pref("webgl.can-lose-context-in-foreground", true);
pref("webgl.restore-context-when-visible", true);
pref("webgl.max-warnings-per-context", 32);
pref("webgl.enable-draft-extensions", false);
pref("webgl.enable-privileged-extensions", false);
pref("webgl.bypass-shader-validation", false);
pref("webgl.enable-prototype-webgl2", false);
pref("webgl.disable-fail-if-major-performance-caveat", false);
-pref("gl.require-hardware", false);
+pref("webgl.disable-debug-renderer-info", false);
+pref("webgl.renderer-string-override", "");
+pref("webgl.vendor-string-override", "");
#ifdef XP_WIN
pref("webgl.angle.try-d3d11", true);
pref("webgl.angle.force-d3d11", false);
#endif
#ifdef MOZ_WIDGET_GONK
pref("gfx.gralloc.fence-with-readpixels", false);