diff --git a/dom/canvas/WebGL2Context.cpp b/dom/canvas/WebGL2Context.cpp index f842bf97b6cd..5f273e44acd6 100644 --- a/dom/canvas/WebGL2Context.cpp +++ b/dom/canvas/WebGL2Context.cpp @@ -97,7 +97,7 @@ static const gl::GLFeature kRequiredFeatures[] = { }; bool -WebGLContext::InitWebGL2(nsACString* const out_failReason, nsACString* const out_failureId) +WebGLContext::InitWebGL2(FailureReason* const out_failReason) { MOZ_ASSERT(IsWebGL2(), "WebGLContext is not a WebGL 2 context!"); @@ -107,8 +107,8 @@ WebGLContext::InitWebGL2(nsACString* const out_failReason, nsACString* const out { // On desktop, we fake occlusion_query_boolean with occlusion_query if // necessary. (See WebGL2ContextQueries.cpp) - *out_failureId = "FEATURE_FAILURE_WEBGL2_OCCL"; - out_failReason->AssignASCII("WebGL 2 requires occlusion query support."); + *out_failReason = FailureReason("FEATURE_FAILURE_WEBGL2_OCCL", + "WebGL 2 requires occlusion query support."); return false; } @@ -136,11 +136,10 @@ WebGLContext::InitWebGL2(nsACString* const out_failReason, nsACString* const out exts.Append(gl::GLContext::GetFeatureName(*itr)); } - *out_failureId = "FEATURE_FAILURE_WEBGL2_FEATURE"; const nsPrintfCString reason("WebGL 2 requires support for the following" " features: %s", exts.BeginReading()); - out_failReason->Assign(reason); + *out_failReason = FailureReason("FEATURE_FAILURE_WEBGL2_OCCL", reason); return false; } diff --git a/dom/canvas/WebGLContext.cpp b/dom/canvas/WebGLContext.cpp index f53fa3bf6d52..eaf844f36268 100644 --- a/dom/canvas/WebGLContext.cpp +++ b/dom/canvas/WebGLContext.cpp @@ -588,7 +588,8 @@ BaseCaps(const WebGLContextOptions& options, WebGLContext* webgl) static already_AddRefed CreateGLWithEGL(const gl::SurfaceCaps& caps, gl::CreateContextFlags flags, - WebGLContext* webgl, std::vector* const out_failReasons) + WebGLContext* webgl, + std::vector* const out_failReasons) { const gfx::IntSize dummySize(16, 16); RefPtr gl = gl::GLContextProviderEGL::CreateOffscreen(dummySize, caps, @@ -598,8 +599,10 @@ CreateGLWithEGL(const gl::SurfaceCaps& caps, gl::CreateContextFlags flags, } if (!gl) { - out_failReasons->push_back({ "FEATURE_FAILURE_WEBGL_EGL_INIT", - "Error during EGL OpenGL init." }); + out_failReasons->push_back(WebGLContext::FailureReason( + "FEATURE_FAILURE_WEBGL_EGL_INIT", + "Error during EGL OpenGL init." + )); return nullptr; } @@ -608,7 +611,8 @@ CreateGLWithEGL(const gl::SurfaceCaps& caps, gl::CreateContextFlags flags, static already_AddRefed CreateGLWithANGLE(const gl::SurfaceCaps& caps, gl::CreateContextFlags flags, - WebGLContext* webgl, std::vector* const out_failReasons) + WebGLContext* webgl, + std::vector* const out_failReasons) { const gfx::IntSize dummySize(16, 16); RefPtr gl = gl::GLContextProviderEGL::CreateOffscreen(dummySize, caps, @@ -618,8 +622,10 @@ CreateGLWithANGLE(const gl::SurfaceCaps& caps, gl::CreateContextFlags flags, } if (!gl) { - out_failReasons->push_back({ "FEATURE_FAILURE_WEBGL_ANGLE_INIT", - "Error during ANGLE OpenGL init." }); + out_failReasons->push_back(WebGLContext::FailureReason( + "FEATURE_FAILURE_WEBGL_ANGLE_INIT", + "Error during ANGLE OpenGL init." + )); return nullptr; } @@ -629,7 +635,7 @@ CreateGLWithANGLE(const gl::SurfaceCaps& caps, gl::CreateContextFlags flags, static already_AddRefed CreateGLWithDefault(const gl::SurfaceCaps& caps, gl::CreateContextFlags flags, WebGLContext* webgl, - std::vector* const out_failReasons) + std::vector* const out_failReasons) { const gfx::IntSize dummySize(16, 16); RefPtr gl = gl::GLContextProvider::CreateOffscreen(dummySize, caps, @@ -640,8 +646,10 @@ CreateGLWithDefault(const gl::SurfaceCaps& caps, gl::CreateContextFlags flags, } if (!gl) { - out_failReasons->push_back({ "FEATURE_FAILURE_WEBGL_DEFAULT_INIT", - "Error during native OpenGL init." }); + out_failReasons->push_back(WebGLContext::FailureReason( + "FEATURE_FAILURE_WEBGL_DEFAULT_INIT", + "Error during native OpenGL init." + )); return nullptr; } @@ -673,7 +681,7 @@ WebGLContext::CreateAndInitGLWith(FnCreateGL_T fnCreateGL, return false; FailureReason reason; - if (!InitAndValidateGL(&reason.info, &reason.key)) { + if (!InitAndValidateGL(&reason)) { // The fail reason here should be specific enough for now. gl = nullptr; out_failReasons->push_back(reason); @@ -699,11 +707,11 @@ WebGLContext::CreateAndInitGL(bool forceEnabled, reason.info = "Refused to create native OpenGL context because of blacklist" " entry: "; - reason.info.Append(blacklistId); + reason.info.Append(reason.key); out_failReasons->push_back(reason); - GenerateWarning(text.BeginReading()); + GenerateWarning(reason.info.BeginReading()); } } @@ -751,7 +759,8 @@ WebGLContext::CreateAndInitGL(bool forceEnabled, ////// - out_failReasons->push_back(nsLiteralCString("Exhausted GL driver options.")); + out_failReasons->push_back(FailureReason("FEATURE_FAILURE_WEBGL_EXHAUSTED_DRIVERS", + "Exhausted GL driver options.")); return false; } diff --git a/dom/canvas/WebGLContext.h b/dom/canvas/WebGLContext.h index d8f054e645d4..1f089466b3ac 100644 --- a/dom/canvas/WebGLContext.h +++ b/dom/canvas/WebGLContext.h @@ -1201,13 +1201,21 @@ protected: public: virtual bool IsWebGL2() const = 0; -protected: - bool InitWebGL2(nsACString* const out_failReason, nsACString* const out_failureId); - struct FailureReason { nsCString key; // For reporting. nsCString info; + + FailureReason() { } + + template + FailureReason(const A& _key, const B& _info) + : key(nsCString(_key)) + , info(nsCString(_info)) + { } }; +protected: + bool InitWebGL2(FailureReason* const out_failReason); + bool CreateAndInitGL(bool forceEnabled, std::vector* const out_failReasons); @@ -1226,7 +1234,8 @@ protected: // ------------------------------------------------------------------------- // Validation functions (implemented in WebGLContextValidate.cpp) - bool InitAndValidateGL(nsACString* const out_failReason, nsACString* const out_failureId); + bool InitAndValidateGL(FailureReason* const out_failReason); + bool ValidateBlendEquationEnum(GLenum cap, const char* info); bool ValidateBlendFuncDstEnum(GLenum mode, const char* info); bool ValidateBlendFuncSrcEnum(GLenum mode, const char* info); diff --git a/dom/canvas/WebGLContextValidate.cpp b/dom/canvas/WebGLContextValidate.cpp index cb24442e03c5..4a67ac0789c9 100644 --- a/dom/canvas/WebGLContextValidate.cpp +++ b/dom/canvas/WebGLContextValidate.cpp @@ -648,7 +648,7 @@ FloorPOT(int32_t x) } bool -WebGLContext::InitAndValidateGL(nsACString* const out_failReason, nsACString* const out_failureId) +WebGLContext::InitAndValidateGL(FailureReason* const out_failReason) { MOZ_RELEASE_ASSERT(gl, "GFX: GL not initialized"); @@ -657,18 +657,17 @@ WebGLContext::InitAndValidateGL(nsACString* const out_failReason, nsACString* co // formats back into the authority. mFormatUsage = CreateFormatUsage(gl); if (!mFormatUsage) { - *out_failureId = "FEATURE_FAILURE_WEBGL_FORMAT"; - out_failReason->AssignLiteral("Failed to create mFormatUsage."); + *out_failReason = { "FEATURE_FAILURE_WEBGL_FORMAT", + "Failed to create mFormatUsage." }; return false; } GLenum error = gl->fGetError(); if (error != LOCAL_GL_NO_ERROR) { - *out_failureId = "FEATURE_FAILURE_WEBGL_GLERR_1"; const nsPrintfCString reason("GL error 0x%x occurred during OpenGL context" " initialization, before WebGL initialization!", error); - out_failReason->Assign(reason); + *out_failReason = { "FEATURE_FAILURE_WEBGL_GLERR_1", reason }; return false; } @@ -757,10 +756,9 @@ WebGLContext::InitAndValidateGL(nsACString* const out_failReason, nsACString* co gl->fGetIntegerv(LOCAL_GL_MAX_VERTEX_ATTRIBS, &mGLMaxVertexAttribs); if (mGLMaxVertexAttribs < 8) { - *out_failureId = "FEATURE_FAILURE_WEBGL_V_ATRB"; const nsPrintfCString reason("GL_MAX_VERTEX_ATTRIBS: %d is < 8!", mGLMaxVertexAttribs); - out_failReason->Assign(reason); + *out_failReason = { "FEATURE_FAILURE_WEBGL_V_ATRB", reason }; return false; } @@ -773,10 +771,9 @@ WebGLContext::InitAndValidateGL(nsACString* const out_failReason, nsACString* co gl->fGetIntegerv(LOCAL_GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &mGLMaxTextureUnits); if (mGLMaxTextureUnits < 8) { - *out_failureId = "FEATURE_FAILURE_WEBGL_T_UNIT"; const nsPrintfCString reason("GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: %d is < 8!", mGLMaxTextureUnits); - out_failReason->Assign(reason); + *out_failReason = { "FEATURE_FAILURE_WEBGL_T_UNIT", reason }; return false; } @@ -932,8 +929,8 @@ WebGLContext::InitAndValidateGL(nsACString* const out_failReason, nsACString* co // initialize shader translator if (!ShInitialize()) { - *out_failureId = "FEATURE_FAILURE_WEBGL_GLSL"; - out_failReason->AssignLiteral("GLSL translator initialization failed!"); + *out_failReason = { "FEATURE_FAILURE_WEBGL_GLSL", + "GLSL translator initialization failed!" }; return false; } @@ -947,16 +944,15 @@ WebGLContext::InitAndValidateGL(nsACString* const out_failReason, nsACString* co // getError call will give the correct result. error = gl->fGetError(); if (error != LOCAL_GL_NO_ERROR) { - *out_failureId = "FEATURE_FAILURE_WEBGL_GLERR_2"; const nsPrintfCString reason("GL error 0x%x occurred during WebGL context" " initialization!", error); - out_failReason->Assign(reason); + *out_failReason = { "FEATURE_FAILURE_WEBGL_GLERR_2", reason }; return false; } if (IsWebGL2() && - !InitWebGL2(out_failReason, out_failureId)) + !InitWebGL2(out_failReason)) { // Todo: Bug 898404: Only allow WebGL2 on GL>=3.0 on desktop GL. return false;