diff --git a/dom/canvas/WebGLContext.cpp b/dom/canvas/WebGLContext.cpp index 684e61c6a869..b7358d67ffae 100644 --- a/dom/canvas/WebGLContext.cpp +++ b/dom/canvas/WebGLContext.cpp @@ -194,6 +194,7 @@ WebGLContextOptions::WebGLContextOptions() , premultipliedAlpha(true) , antialias(true) , preserveDrawingBuffer(false) + , failIfMajorPerformanceCaveat(false) { // Set default alpha state based on preference. if (Preferences::GetBool("webgl.default-no-alpha", false)) @@ -431,6 +432,7 @@ WebGLContext::SetContextOptions(JSContext* cx, JS::Handle options) newOpts.premultipliedAlpha = attributes.mPremultipliedAlpha; newOpts.antialias = attributes.mAntialias; newOpts.preserveDrawingBuffer = attributes.mPreserveDrawingBuffer; + newOpts.failIfMajorPerformanceCaveat = attributes.mFailIfMajorPerformanceCaveat; if (attributes.mAlpha.WasPassed()) newOpts.alpha = attributes.mAlpha.Value(); @@ -500,6 +502,30 @@ IsFeatureInBlacklist(const nsCOMPtr& gfxInfo, int32_t feature) return status != nsIGfxInfo::FEATURE_STATUS_OK; } +static bool +HasAcceleratedLayers(const nsCOMPtr& gfxInfo) +{ + int32_t status; + + gfxInfo->GetFeatureStatus(nsIGfxInfo::FEATURE_DIRECT3D_9_LAYERS, &status); + if (status) + return true; + gfxInfo->GetFeatureStatus(nsIGfxInfo::FEATURE_DIRECT3D_10_LAYERS, &status); + if (status) + return true; + gfxInfo->GetFeatureStatus(nsIGfxInfo::FEATURE_DIRECT3D_10_1_LAYERS, &status); + if (status) + return true; + gfxInfo->GetFeatureStatus(nsIGfxInfo::FEATURE_DIRECT3D_11_LAYERS, &status); + if (status) + return true; + gfxInfo->GetFeatureStatus(nsIGfxInfo::FEATURE_OPENGL_LAYERS, &status); + if (status) + return true; + + return false; +} + static already_AddRefed CreateHeadlessNativeGL(bool forceEnabled, const nsCOMPtr& gfxInfo, bool requireCompatProfile, WebGLContext* webgl) @@ -569,7 +595,6 @@ CreateHeadlessEGL(bool forceEnabled, bool requireCompatProfile, return gl.forget(); } - static already_AddRefed CreateHeadlessGL(bool forceEnabled, const nsCOMPtr& gfxInfo, WebGLContext* webgl) @@ -873,6 +898,18 @@ WebGLContext::SetDimensions(int32_t signedWidth, int32_t signedHeight) return NS_ERROR_FAILURE; } + nsCOMPtr gfxInfo = do_GetService("@mozilla.org/gfx/info;1"); + bool failIfMajorPerformanceCaveat = + !gfxPrefs::WebGLDisableFailIfMajorPerformanceCaveat() && + !HasAcceleratedLayers(gfxInfo); + if (failIfMajorPerformanceCaveat) { + Nullable contextAttributes; + this->GetContextAttributes(contextAttributes); + if (contextAttributes.Value().mFailIfMajorPerformanceCaveat) { + return NS_ERROR_FAILURE; + } + } + // Alright, now let's start trying. bool forceEnabled = Preferences::GetBool("webgl.force-enabled", false); ScopedGfxFeatureReporter reporter("WebGL", forceEnabled); @@ -1255,6 +1292,7 @@ WebGLContext::GetContextAttributes(Nullable& retval result.mAntialias = mOptions.antialias; result.mPremultipliedAlpha = mOptions.premultipliedAlpha; result.mPreserveDrawingBuffer = mOptions.preserveDrawingBuffer; + result.mFailIfMajorPerformanceCaveat = mOptions.failIfMajorPerformanceCaveat; } /* [noscript] DOMString mozGetUnderlyingParamString(in GLenum pname); */ diff --git a/dom/canvas/WebGLContext.h b/dom/canvas/WebGLContext.h index 0b0c41922b1d..e4dbf73b2866 100644 --- a/dom/canvas/WebGLContext.h +++ b/dom/canvas/WebGLContext.h @@ -128,6 +128,7 @@ struct WebGLContextOptions bool premultipliedAlpha; bool antialias; bool preserveDrawingBuffer; + bool failIfMajorPerformanceCaveat; }; // From WebGLContextUtils diff --git a/dom/webidl/WebGLRenderingContext.webidl b/dom/webidl/WebGLRenderingContext.webidl index 7321528edf54..043e65e645cd 100644 --- a/dom/webidl/WebGLRenderingContext.webidl +++ b/dom/webidl/WebGLRenderingContext.webidl @@ -41,6 +41,7 @@ dictionary WebGLContextAttributes { boolean antialias = true; boolean premultipliedAlpha = true; boolean preserveDrawingBuffer = false; + boolean failIfMajorPerformanceCaveat = false; }; interface WebGLBuffer { diff --git a/gfx/thebes/gfxPrefs.h b/gfx/thebes/gfxPrefs.h index 8e3622c688ec..26d1e0460217 100644 --- a/gfx/thebes/gfxPrefs.h +++ b/gfx/thebes/gfxPrefs.h @@ -368,6 +368,8 @@ private: DECL_GFX_PREF(Live, "ui.click_hold_context_menus.delay", UiClickHoldContextMenusDelay, int32_t, 500); DECL_GFX_PREF(Once, "webgl.angle.force-d3d11", WebGLANGLEForceD3D11, bool, false); DECL_GFX_PREF(Once, "webgl.angle.try-d3d11", WebGLANGLETryD3D11, bool, false); + DECL_GFX_PREF(Live, "webgl.disable-fail-if-major-performance-caveat", + WebGLDisableFailIfMajorPerformanceCaveat, bool, false); DECL_GFX_PREF(Once, "webgl.force-layers-readback", WebGLForceLayersReadback, bool, false); // WARNING: diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index a226bbebfdcb..f233561c8f9e 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -4001,6 +4001,7 @@ 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); #ifdef XP_WIN