Bug 1276732 - Report the GLContext error to WebGL for telemetry. r=jrmuizel
MozReview-Commit-ID: 24eb4FXMOiI
This commit is contained in:
@@ -587,7 +587,7 @@ CreateGLWithEGL(const gl::SurfaceCaps& caps, gl::CreateContextFlags flags,
|
|||||||
{
|
{
|
||||||
const gfx::IntSize dummySize(16, 16);
|
const gfx::IntSize dummySize(16, 16);
|
||||||
RefPtr<GLContext> gl = gl::GLContextProviderEGL::CreateOffscreen(dummySize, caps,
|
RefPtr<GLContext> gl = gl::GLContextProviderEGL::CreateOffscreen(dummySize, caps,
|
||||||
flags);
|
flags, *out_failureId);
|
||||||
if (gl && gl->IsANGLE()) {
|
if (gl && gl->IsANGLE()) {
|
||||||
gl = nullptr;
|
gl = nullptr;
|
||||||
}
|
}
|
||||||
@@ -611,7 +611,7 @@ CreateGLWithANGLE(const gl::SurfaceCaps& caps, gl::CreateContextFlags flags,
|
|||||||
{
|
{
|
||||||
const gfx::IntSize dummySize(16, 16);
|
const gfx::IntSize dummySize(16, 16);
|
||||||
RefPtr<GLContext> gl = gl::GLContextProviderEGL::CreateOffscreen(dummySize, caps,
|
RefPtr<GLContext> gl = gl::GLContextProviderEGL::CreateOffscreen(dummySize, caps,
|
||||||
flags);
|
flags, *out_failureId);
|
||||||
if (gl && !gl->IsANGLE()) {
|
if (gl && !gl->IsANGLE()) {
|
||||||
gl = nullptr;
|
gl = nullptr;
|
||||||
}
|
}
|
||||||
@@ -647,7 +647,8 @@ CreateGLWithDefault(const gl::SurfaceCaps& caps, gl::CreateContextFlags flags,
|
|||||||
}
|
}
|
||||||
|
|
||||||
const gfx::IntSize dummySize(16, 16);
|
const gfx::IntSize dummySize(16, 16);
|
||||||
RefPtr<GLContext> gl = gl::GLContextProvider::CreateOffscreen(dummySize, caps, flags);
|
RefPtr<GLContext> gl = gl::GLContextProvider::CreateOffscreen(dummySize, caps,
|
||||||
|
flags, *out_failureId);
|
||||||
|
|
||||||
if (gl && gl->IsANGLE()) {
|
if (gl && gl->IsANGLE()) {
|
||||||
gl = nullptr;
|
gl = nullptr;
|
||||||
|
|||||||
@@ -92,7 +92,8 @@ static RefPtr<GLContext> sPluginContext = nullptr;
|
|||||||
static bool EnsureGLContext()
|
static bool EnsureGLContext()
|
||||||
{
|
{
|
||||||
if (!sPluginContext) {
|
if (!sPluginContext) {
|
||||||
sPluginContext = GLContextProvider::CreateHeadless(CreateContextFlags::REQUIRE_COMPAT_PROFILE);
|
nsCString failureId;
|
||||||
|
sPluginContext = GLContextProvider::CreateHeadless(CreateContextFlags::REQUIRE_COMPAT_PROFILE, failureId);
|
||||||
}
|
}
|
||||||
|
|
||||||
return sPluginContext != nullptr;
|
return sPluginContext != nullptr;
|
||||||
|
|||||||
@@ -23,7 +23,8 @@ class GLContextEGL : public GLContext
|
|||||||
GLContextEGL *shareContext,
|
GLContextEGL *shareContext,
|
||||||
bool isOffscreen,
|
bool isOffscreen,
|
||||||
EGLConfig config,
|
EGLConfig config,
|
||||||
EGLSurface surface);
|
EGLSurface surface,
|
||||||
|
nsACString& aFailureId);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(GLContextEGL, override)
|
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(GLContextEGL, override)
|
||||||
@@ -106,7 +107,8 @@ public:
|
|||||||
static already_AddRefed<GLContextEGL>
|
static already_AddRefed<GLContextEGL>
|
||||||
CreateEGLPBufferOffscreenContext(CreateContextFlags flags,
|
CreateEGLPBufferOffscreenContext(CreateContextFlags flags,
|
||||||
const gfx::IntSize& size,
|
const gfx::IntSize& size,
|
||||||
const SurfaceCaps& minCaps);
|
const SurfaceCaps& minCaps,
|
||||||
|
nsACString& aFailureId);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
friend class GLContextProviderEGL;
|
friend class GLContextProviderEGL;
|
||||||
|
|||||||
@@ -321,14 +321,17 @@ CreateOffscreenFBOContext(CreateContextFlags flags)
|
|||||||
}
|
}
|
||||||
|
|
||||||
already_AddRefed<GLContext>
|
already_AddRefed<GLContext>
|
||||||
GLContextProviderCGL::CreateHeadless(CreateContextFlags flags)
|
GLContextProviderCGL::CreateHeadless(CreateContextFlags flags, nsACString& aFailureId)
|
||||||
{
|
{
|
||||||
RefPtr<GLContextCGL> gl;
|
RefPtr<GLContextCGL> gl;
|
||||||
gl = CreateOffscreenFBOContext(flags);
|
gl = CreateOffscreenFBOContext(flags);
|
||||||
if (!gl)
|
if (!gl) {
|
||||||
|
aFailureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_CGL_FBO");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
if (!gl->Init()) {
|
if (!gl->Init()) {
|
||||||
|
aFailureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_CGL_INIT");
|
||||||
NS_WARNING("Failed during Init.");
|
NS_WARNING("Failed during Init.");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@@ -339,14 +342,18 @@ GLContextProviderCGL::CreateHeadless(CreateContextFlags flags)
|
|||||||
already_AddRefed<GLContext>
|
already_AddRefed<GLContext>
|
||||||
GLContextProviderCGL::CreateOffscreen(const IntSize& size,
|
GLContextProviderCGL::CreateOffscreen(const IntSize& size,
|
||||||
const SurfaceCaps& minCaps,
|
const SurfaceCaps& minCaps,
|
||||||
CreateContextFlags flags)
|
CreateContextFlags flags,
|
||||||
|
nsACString& aFailureId)
|
||||||
{
|
{
|
||||||
RefPtr<GLContext> gl = CreateHeadless(flags);
|
RefPtr<GLContext> gl = CreateHeadless(flags, aFailureId);
|
||||||
if (!gl)
|
if (!gl) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
if (!gl->InitOffscreen(size, minCaps))
|
if (!gl->InitOffscreen(size, minCaps)) {
|
||||||
|
aFailureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_CGL_INIT");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
return gl.forget();
|
return gl.forget();
|
||||||
}
|
}
|
||||||
@@ -361,7 +368,9 @@ GLContextProviderCGL::GetGlobalContext()
|
|||||||
triedToCreateContext = true;
|
triedToCreateContext = true;
|
||||||
|
|
||||||
MOZ_RELEASE_ASSERT(!gGlobalContext);
|
MOZ_RELEASE_ASSERT(!gGlobalContext);
|
||||||
RefPtr<GLContext> temp = CreateHeadless(CreateContextFlags::NONE);
|
nsCString discardFailureId;
|
||||||
|
RefPtr<GLContext> temp = CreateHeadless(CreateContextFlags::NONE,
|
||||||
|
discardFailureId);
|
||||||
gGlobalContext = temp;
|
gGlobalContext = temp;
|
||||||
|
|
||||||
if (!gGlobalContext) {
|
if (!gGlobalContext) {
|
||||||
|
|||||||
@@ -455,7 +455,8 @@ GLContextEGL::HoldSurface(gfxASurface *aSurf) {
|
|||||||
/* static */ EGLSurface
|
/* static */ EGLSurface
|
||||||
GLContextEGL::CreateSurfaceForWindow(nsIWidget* aWidget)
|
GLContextEGL::CreateSurfaceForWindow(nsIWidget* aWidget)
|
||||||
{
|
{
|
||||||
if (!sEGLLibrary.EnsureInitialized()) {
|
nsCString discardFailureId;
|
||||||
|
if (!sEGLLibrary.EnsureInitialized(false, discardFailureId)) {
|
||||||
MOZ_CRASH("GFX: Failed to load EGL library!\n");
|
MOZ_CRASH("GFX: Failed to load EGL library!\n");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@@ -488,9 +489,11 @@ GLContextEGL::CreateGLContext(CreateContextFlags flags,
|
|||||||
GLContextEGL *shareContext,
|
GLContextEGL *shareContext,
|
||||||
bool isOffscreen,
|
bool isOffscreen,
|
||||||
EGLConfig config,
|
EGLConfig config,
|
||||||
EGLSurface surface)
|
EGLSurface surface,
|
||||||
|
nsACString& aFailureId)
|
||||||
{
|
{
|
||||||
if (sEGLLibrary.fBindAPI(LOCAL_EGL_OPENGL_ES_API) == LOCAL_EGL_FALSE) {
|
if (sEGLLibrary.fBindAPI(LOCAL_EGL_OPENGL_ES_API) == LOCAL_EGL_FALSE) {
|
||||||
|
aFailureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_EGL_ES");
|
||||||
NS_WARNING("Failed to bind API to GLES!");
|
NS_WARNING("Failed to bind API to GLES!");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@@ -527,6 +530,7 @@ GLContextEGL::CreateGLContext(CreateContextFlags flags,
|
|||||||
contextAttribs.Elements());
|
contextAttribs.Elements());
|
||||||
}
|
}
|
||||||
if (!context) {
|
if (!context) {
|
||||||
|
aFailureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_EGL_CREATE");
|
||||||
NS_WARNING("Failed to create EGLContext!");
|
NS_WARNING("Failed to create EGLContext!");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@@ -538,8 +542,10 @@ GLContextEGL::CreateGLContext(CreateContextFlags flags,
|
|||||||
surface,
|
surface,
|
||||||
context);
|
context);
|
||||||
|
|
||||||
if (!glContext->Init())
|
if (!glContext->Init()) {
|
||||||
|
aFailureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_EGL_INIT");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
return glContext.forget();
|
return glContext.forget();
|
||||||
}
|
}
|
||||||
@@ -738,7 +744,8 @@ CreateConfig(EGLConfig* aConfig, nsIWidget* aWidget)
|
|||||||
already_AddRefed<GLContext>
|
already_AddRefed<GLContext>
|
||||||
GLContextProviderEGL::CreateWrappingExisting(void* aContext, void* aSurface)
|
GLContextProviderEGL::CreateWrappingExisting(void* aContext, void* aSurface)
|
||||||
{
|
{
|
||||||
if (!sEGLLibrary.EnsureInitialized()) {
|
nsCString discardFailureId;
|
||||||
|
if (!sEGLLibrary.EnsureInitialized(false, discardFailureId)) {
|
||||||
MOZ_CRASH("GFX: Failed to load EGL library 2!\n");
|
MOZ_CRASH("GFX: Failed to load EGL library 2!\n");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@@ -763,7 +770,8 @@ GLContextProviderEGL::CreateWrappingExisting(void* aContext, void* aSurface)
|
|||||||
already_AddRefed<GLContext>
|
already_AddRefed<GLContext>
|
||||||
GLContextProviderEGL::CreateForWindow(nsIWidget *aWidget, bool aForceAccelerated)
|
GLContextProviderEGL::CreateForWindow(nsIWidget *aWidget, bool aForceAccelerated)
|
||||||
{
|
{
|
||||||
if (!sEGLLibrary.EnsureInitialized()) {
|
nsCString discardFailureId;
|
||||||
|
if (!sEGLLibrary.EnsureInitialized(false, discardFailureId)) {
|
||||||
MOZ_CRASH("GFX: Failed to load EGL library 3!\n");
|
MOZ_CRASH("GFX: Failed to load EGL library 3!\n");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@@ -786,7 +794,7 @@ GLContextProviderEGL::CreateForWindow(nsIWidget *aWidget, bool aForceAccelerated
|
|||||||
RefPtr<GLContextEGL> glContext =
|
RefPtr<GLContextEGL> glContext =
|
||||||
GLContextEGL::CreateGLContext(CreateContextFlags::NONE, caps,
|
GLContextEGL::CreateGLContext(CreateContextFlags::NONE, caps,
|
||||||
nullptr, false,
|
nullptr, false,
|
||||||
config, surface);
|
config, surface, discardFailureId);
|
||||||
|
|
||||||
if (!glContext) {
|
if (!glContext) {
|
||||||
MOZ_CRASH("GFX: Failed to create EGLContext!\n");
|
MOZ_CRASH("GFX: Failed to create EGLContext!\n");
|
||||||
@@ -804,7 +812,8 @@ GLContextProviderEGL::CreateForWindow(nsIWidget *aWidget, bool aForceAccelerated
|
|||||||
EGLSurface
|
EGLSurface
|
||||||
GLContextProviderEGL::CreateEGLSurface(void* aWindow)
|
GLContextProviderEGL::CreateEGLSurface(void* aWindow)
|
||||||
{
|
{
|
||||||
if (!sEGLLibrary.EnsureInitialized()) {
|
nsCString discardFailureId;
|
||||||
|
if (!sEGLLibrary.EnsureInitialized(false, discardFailureId)) {
|
||||||
MOZ_CRASH("GFX: Failed to load EGL library 4!\n");
|
MOZ_CRASH("GFX: Failed to load EGL library 4!\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -827,7 +836,8 @@ GLContextProviderEGL::CreateEGLSurface(void* aWindow)
|
|||||||
void
|
void
|
||||||
GLContextProviderEGL::DestroyEGLSurface(EGLSurface surface)
|
GLContextProviderEGL::DestroyEGLSurface(EGLSurface surface)
|
||||||
{
|
{
|
||||||
if (!sEGLLibrary.EnsureInitialized()) {
|
nsCString discardFailureId;
|
||||||
|
if (!sEGLLibrary.EnsureInitialized(false, discardFailureId)) {
|
||||||
MOZ_CRASH("GFX: Failed to load EGL library 5!\n");
|
MOZ_CRASH("GFX: Failed to load EGL library 5!\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -938,15 +948,18 @@ ChooseConfig(GLLibraryEGL* egl, CreateContextFlags flags, const SurfaceCaps& min
|
|||||||
/*static*/ already_AddRefed<GLContextEGL>
|
/*static*/ already_AddRefed<GLContextEGL>
|
||||||
GLContextEGL::CreateEGLPBufferOffscreenContext(CreateContextFlags flags,
|
GLContextEGL::CreateEGLPBufferOffscreenContext(CreateContextFlags flags,
|
||||||
const mozilla::gfx::IntSize& size,
|
const mozilla::gfx::IntSize& size,
|
||||||
const SurfaceCaps& minCaps)
|
const SurfaceCaps& minCaps,
|
||||||
|
nsACString& aFailureId)
|
||||||
{
|
{
|
||||||
bool forceEnableHardware = bool(flags & CreateContextFlags::FORCE_ENABLE_HARDWARE);
|
bool forceEnableHardware = bool(flags & CreateContextFlags::FORCE_ENABLE_HARDWARE);
|
||||||
if (!sEGLLibrary.EnsureInitialized(forceEnableHardware))
|
if (!sEGLLibrary.EnsureInitialized(forceEnableHardware, aFailureId)) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
SurfaceCaps configCaps;
|
SurfaceCaps configCaps;
|
||||||
EGLConfig config = ChooseConfig(&sEGLLibrary, flags, minCaps, &configCaps);
|
EGLConfig config = ChooseConfig(&sEGLLibrary, flags, minCaps, &configCaps);
|
||||||
if (config == EGL_NO_CONFIG) {
|
if (config == EGL_NO_CONFIG) {
|
||||||
|
aFailureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_EGL_NO_CONFIG");
|
||||||
NS_WARNING("Failed to find a compatible config.");
|
NS_WARNING("Failed to find a compatible config.");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@@ -960,12 +973,13 @@ GLContextEGL::CreateEGLPBufferOffscreenContext(CreateContextFlags flags,
|
|||||||
LOCAL_EGL_NONE,
|
LOCAL_EGL_NONE,
|
||||||
pbSize);
|
pbSize);
|
||||||
if (!surface) {
|
if (!surface) {
|
||||||
|
aFailureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_EGL_POT");
|
||||||
NS_WARNING("Failed to create PBuffer for context!");
|
NS_WARNING("Failed to create PBuffer for context!");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<GLContextEGL> gl = GLContextEGL::CreateGLContext(flags, configCaps, nullptr, true,
|
RefPtr<GLContextEGL> gl = GLContextEGL::CreateGLContext(flags, configCaps, nullptr, true,
|
||||||
config, surface);
|
config, surface, aFailureId);
|
||||||
if (!gl) {
|
if (!gl) {
|
||||||
NS_WARNING("Failed to create GLContext from PBuffer");
|
NS_WARNING("Failed to create GLContext from PBuffer");
|
||||||
sEGLLibrary.fDestroySurface(sEGLLibrary.Display(), surface);
|
sEGLLibrary.fDestroySurface(sEGLLibrary.Display(), surface);
|
||||||
@@ -976,11 +990,12 @@ GLContextEGL::CreateEGLPBufferOffscreenContext(CreateContextFlags flags,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*static*/ already_AddRefed<GLContext>
|
/*static*/ already_AddRefed<GLContext>
|
||||||
GLContextProviderEGL::CreateHeadless(CreateContextFlags flags)
|
GLContextProviderEGL::CreateHeadless(CreateContextFlags flags, nsACString& aFailureId)
|
||||||
{
|
{
|
||||||
mozilla::gfx::IntSize dummySize = mozilla::gfx::IntSize(16, 16);
|
mozilla::gfx::IntSize dummySize = mozilla::gfx::IntSize(16, 16);
|
||||||
SurfaceCaps dummyCaps = SurfaceCaps::Any();
|
SurfaceCaps dummyCaps = SurfaceCaps::Any();
|
||||||
return GLContextEGL::CreateEGLPBufferOffscreenContext(flags, dummySize, dummyCaps);
|
return GLContextEGL::CreateEGLPBufferOffscreenContext(flags, dummySize, dummyCaps,
|
||||||
|
aFailureId);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Under EGL, on Android, pbuffers are supported fine, though
|
// Under EGL, on Android, pbuffers are supported fine, though
|
||||||
@@ -988,11 +1003,14 @@ GLContextProviderEGL::CreateHeadless(CreateContextFlags flags)
|
|||||||
/*static*/ already_AddRefed<GLContext>
|
/*static*/ already_AddRefed<GLContext>
|
||||||
GLContextProviderEGL::CreateOffscreen(const mozilla::gfx::IntSize& size,
|
GLContextProviderEGL::CreateOffscreen(const mozilla::gfx::IntSize& size,
|
||||||
const SurfaceCaps& minCaps,
|
const SurfaceCaps& minCaps,
|
||||||
CreateContextFlags flags)
|
CreateContextFlags flags,
|
||||||
|
nsACString& aFailureId)
|
||||||
{
|
{
|
||||||
bool forceEnableHardware = bool(flags & CreateContextFlags::FORCE_ENABLE_HARDWARE);
|
bool forceEnableHardware = bool(flags & CreateContextFlags::FORCE_ENABLE_HARDWARE);
|
||||||
if (!sEGLLibrary.EnsureInitialized(forceEnableHardware)) // Needed for IsANGLE().
|
if (!sEGLLibrary.EnsureInitialized(forceEnableHardware, aFailureId)) { // Needed for IsANGLE().
|
||||||
|
aFailureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_EGL_LIB_INIT");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
bool canOffscreenUseHeadless = true;
|
bool canOffscreenUseHeadless = true;
|
||||||
if (sEGLLibrary.IsANGLE()) {
|
if (sEGLLibrary.IsANGLE()) {
|
||||||
@@ -1004,9 +1022,10 @@ GLContextProviderEGL::CreateOffscreen(const mozilla::gfx::IntSize& size,
|
|||||||
SurfaceCaps minOffscreenCaps = minCaps;
|
SurfaceCaps minOffscreenCaps = minCaps;
|
||||||
|
|
||||||
if (canOffscreenUseHeadless) {
|
if (canOffscreenUseHeadless) {
|
||||||
gl = CreateHeadless(flags);
|
gl = CreateHeadless(flags, aFailureId);
|
||||||
if (!gl)
|
if (!gl) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
SurfaceCaps minBackbufferCaps = minOffscreenCaps;
|
SurfaceCaps minBackbufferCaps = minOffscreenCaps;
|
||||||
if (minOffscreenCaps.antialias) {
|
if (minOffscreenCaps.antialias) {
|
||||||
@@ -1015,9 +1034,11 @@ GLContextProviderEGL::CreateOffscreen(const mozilla::gfx::IntSize& size,
|
|||||||
minBackbufferCaps.stencil = false;
|
minBackbufferCaps.stencil = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
gl = GLContextEGL::CreateEGLPBufferOffscreenContext(flags, size, minBackbufferCaps);
|
gl = GLContextEGL::CreateEGLPBufferOffscreenContext(flags, size, minBackbufferCaps,
|
||||||
if (!gl)
|
aFailureId);
|
||||||
|
if (!gl) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
// Pull the actual resulting caps to ensure that our offscreen matches our
|
// Pull the actual resulting caps to ensure that our offscreen matches our
|
||||||
// backbuffer.
|
// backbuffer.
|
||||||
@@ -1031,8 +1052,10 @@ GLContextProviderEGL::CreateOffscreen(const mozilla::gfx::IntSize& size,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Init the offscreen with the updated offscreen caps.
|
// Init the offscreen with the updated offscreen caps.
|
||||||
if (!gl->InitOffscreen(size, minOffscreenCaps))
|
if (!gl->InitOffscreen(size, minOffscreenCaps)) {
|
||||||
|
aFailureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_EGL_OFFSCREEN");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
return gl.forget();
|
return gl.forget();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1223,7 +1223,8 @@ GLContextGLX::FindFBConfigForWindow(Display* display, int screen, Window window,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static already_AddRefed<GLContextGLX>
|
static already_AddRefed<GLContextGLX>
|
||||||
CreateOffscreenPixmapContext(const IntSize& size, const SurfaceCaps& minCaps, ContextProfile profile = ContextProfile::OpenGLCompatibility)
|
CreateOffscreenPixmapContext(const IntSize& size, const SurfaceCaps& minCaps, nsACString& aFailureId,
|
||||||
|
ContextProfile profile = ContextProfile::OpenGLCompatibility)
|
||||||
{
|
{
|
||||||
GLXLibrary* glx = &sGLXLibrary;
|
GLXLibrary* glx = &sGLXLibrary;
|
||||||
if (!glx->EnsureInitialized())
|
if (!glx->EnsureInitialized())
|
||||||
@@ -1285,17 +1286,18 @@ DONE_CREATING_PIXMAP:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*static*/ already_AddRefed<GLContext>
|
/*static*/ already_AddRefed<GLContext>
|
||||||
GLContextProviderGLX::CreateHeadless(CreateContextFlags)
|
GLContextProviderGLX::CreateHeadless(CreateContextFlags, nsACString& aFailureId)
|
||||||
{
|
{
|
||||||
IntSize dummySize = IntSize(16, 16);
|
IntSize dummySize = IntSize(16, 16);
|
||||||
SurfaceCaps dummyCaps = SurfaceCaps::Any();
|
SurfaceCaps dummyCaps = SurfaceCaps::Any();
|
||||||
return CreateOffscreenPixmapContext(dummySize, dummyCaps);
|
return CreateOffscreenPixmapContext(dummySize, dummyCaps, aFailureId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*static*/ already_AddRefed<GLContext>
|
/*static*/ already_AddRefed<GLContext>
|
||||||
GLContextProviderGLX::CreateOffscreen(const IntSize& size,
|
GLContextProviderGLX::CreateOffscreen(const IntSize& size,
|
||||||
const SurfaceCaps& minCaps,
|
const SurfaceCaps& minCaps,
|
||||||
CreateContextFlags flags)
|
CreateContextFlags flags,
|
||||||
|
nsACString& aFailureId)
|
||||||
{
|
{
|
||||||
SurfaceCaps minBackbufferCaps = minCaps;
|
SurfaceCaps minBackbufferCaps = minCaps;
|
||||||
if (minCaps.antialias) {
|
if (minCaps.antialias) {
|
||||||
@@ -1310,12 +1312,14 @@ GLContextProviderGLX::CreateOffscreen(const IntSize& size,
|
|||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<GLContext> gl;
|
RefPtr<GLContext> gl;
|
||||||
gl = CreateOffscreenPixmapContext(size, minBackbufferCaps, profile);
|
gl = CreateOffscreenPixmapContext(size, minBackbufferCaps, aFailureId, profile);
|
||||||
if (!gl)
|
if (!gl)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
if (!gl->InitOffscreen(size, minCaps))
|
if (!gl->InitOffscreen(size, minCaps)) {
|
||||||
|
aFailureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_GLX_INIT");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
return gl.forget();
|
return gl.forget();
|
||||||
}
|
}
|
||||||
@@ -1332,7 +1336,8 @@ GLContextProviderGLX::GetGlobalContext()
|
|||||||
triedToCreateContext = true;
|
triedToCreateContext = true;
|
||||||
|
|
||||||
MOZ_RELEASE_ASSERT(!gGlobalContext);
|
MOZ_RELEASE_ASSERT(!gGlobalContext);
|
||||||
RefPtr<GLContext> temp = CreateHeadless(CreateContextFlags::NONE);
|
nsCString discardFailureId;
|
||||||
|
RefPtr<GLContext> temp = CreateHeadless(CreateContextFlags::NONE, discardFailureId);
|
||||||
gGlobalContext = temp;
|
gGlobalContext = temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -67,11 +67,12 @@ public:
|
|||||||
static already_AddRefed<GLContext>
|
static already_AddRefed<GLContext>
|
||||||
CreateOffscreen(const mozilla::gfx::IntSize& size,
|
CreateOffscreen(const mozilla::gfx::IntSize& size,
|
||||||
const SurfaceCaps& minCaps,
|
const SurfaceCaps& minCaps,
|
||||||
CreateContextFlags flags);
|
CreateContextFlags flags,
|
||||||
|
nsACString& failureId);
|
||||||
|
|
||||||
// Just create a context. We'll add offscreen stuff ourselves.
|
// Just create a context. We'll add offscreen stuff ourselves.
|
||||||
static already_AddRefed<GLContext>
|
static already_AddRefed<GLContext>
|
||||||
CreateHeadless(CreateContextFlags flags);
|
CreateHeadless(CreateContextFlags flags, nsACString& aFailureId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create wrapping Gecko GLContext for external gl context.
|
* Create wrapping Gecko GLContext for external gl context.
|
||||||
|
|||||||
@@ -23,8 +23,10 @@ GLContextProviderNull::CreateWrappingExisting(void*, void*)
|
|||||||
already_AddRefed<GLContext>
|
already_AddRefed<GLContext>
|
||||||
GLContextProviderNull::CreateOffscreen(const gfx::IntSize&,
|
GLContextProviderNull::CreateOffscreen(const gfx::IntSize&,
|
||||||
const SurfaceCaps&,
|
const SurfaceCaps&,
|
||||||
CreateContextFlags)
|
CreateContextFlags,
|
||||||
|
nsACString& aFailureId)
|
||||||
{
|
{
|
||||||
|
aFailureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_NULL");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -641,7 +641,7 @@ CreateWindowOffscreenContext()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*static*/ already_AddRefed<GLContext>
|
/*static*/ already_AddRefed<GLContext>
|
||||||
GLContextProviderWGL::CreateHeadless(CreateContextFlags)
|
GLContextProviderWGL::CreateHeadless(CreateContextFlags, nsACString& aFailureId)
|
||||||
{
|
{
|
||||||
if (!sWGLLib.EnsureInitialized()) {
|
if (!sWGLLib.EnsureInitialized()) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@@ -676,14 +676,17 @@ GLContextProviderWGL::CreateHeadless(CreateContextFlags)
|
|||||||
/*static*/ already_AddRefed<GLContext>
|
/*static*/ already_AddRefed<GLContext>
|
||||||
GLContextProviderWGL::CreateOffscreen(const IntSize& size,
|
GLContextProviderWGL::CreateOffscreen(const IntSize& size,
|
||||||
const SurfaceCaps& minCaps,
|
const SurfaceCaps& minCaps,
|
||||||
CreateContextFlags flags)
|
CreateContextFlags flags,
|
||||||
|
nsACString& aFailureId)
|
||||||
{
|
{
|
||||||
RefPtr<GLContext> gl = CreateHeadless(flags);
|
RefPtr<GLContext> gl = CreateHeadless(flags, aFailureId);
|
||||||
if (!gl)
|
if (!gl)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
if (!gl->InitOffscreen(size, minCaps))
|
if (!gl->InitOffscreen(size, minCaps)) {
|
||||||
|
aFailureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_WGL_INIT");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
return gl.forget();
|
return gl.forget();
|
||||||
}
|
}
|
||||||
@@ -698,7 +701,8 @@ GLContextProviderWGL::GetGlobalContext()
|
|||||||
triedToCreateContext = true;
|
triedToCreateContext = true;
|
||||||
|
|
||||||
MOZ_RELEASE_ASSERT(!gGlobalContext);
|
MOZ_RELEASE_ASSERT(!gGlobalContext);
|
||||||
RefPtr<GLContext> temp = CreateHeadless(CreateContextFlags::NONE);
|
nsCString discardFailureId;
|
||||||
|
RefPtr<GLContext> temp = CreateHeadless(CreateContextFlags::NONE, discardFailureId);
|
||||||
gGlobalContext = temp;
|
gGlobalContext = temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -142,7 +142,7 @@ GetAndInitWARPDisplay(GLLibraryEGL& egl, void* displayType)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
IsAccelAngleSupported(const nsCOMPtr<nsIGfxInfo>& gfxInfo)
|
IsAccelAngleSupported(const nsCOMPtr<nsIGfxInfo>& gfxInfo, nsACString& aFailureId)
|
||||||
{
|
{
|
||||||
int32_t angleSupport;
|
int32_t angleSupport;
|
||||||
nsCString failureId;
|
nsCString failureId;
|
||||||
@@ -152,6 +152,9 @@ IsAccelAngleSupported(const nsCOMPtr<nsIGfxInfo>& gfxInfo)
|
|||||||
&angleSupport);
|
&angleSupport);
|
||||||
Telemetry::Accumulate(Telemetry::CANVAS_WEBGL_ACCL_FAILURE_ID,
|
Telemetry::Accumulate(Telemetry::CANVAS_WEBGL_ACCL_FAILURE_ID,
|
||||||
failureId);
|
failureId);
|
||||||
|
if (failureId.IsEmpty()) {
|
||||||
|
aFailureId = failureId;
|
||||||
|
}
|
||||||
return (angleSupport == nsIGfxInfo::FEATURE_STATUS_OK);
|
return (angleSupport == nsIGfxInfo::FEATURE_STATUS_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -201,7 +204,9 @@ GLLibraryEGL::ReadbackEGLImage(EGLImage image, gfx::DataSourceSurface* out_surfa
|
|||||||
{
|
{
|
||||||
StaticMutexAutoUnlock lock(sMutex);
|
StaticMutexAutoUnlock lock(sMutex);
|
||||||
if (!mReadbackGL) {
|
if (!mReadbackGL) {
|
||||||
mReadbackGL = gl::GLContextProvider::CreateHeadless(gl::CreateContextFlags::NONE);
|
nsCString discardFailureId;
|
||||||
|
mReadbackGL = gl::GLContextProvider::CreateHeadless(gl::CreateContextFlags::NONE,
|
||||||
|
discardFailureId);
|
||||||
}
|
}
|
||||||
|
|
||||||
ScopedTexture destTex(mReadbackGL);
|
ScopedTexture destTex(mReadbackGL);
|
||||||
@@ -223,7 +228,7 @@ GLLibraryEGL::ReadbackEGLImage(EGLImage image, gfx::DataSourceSurface* out_surfa
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
GLLibraryEGL::EnsureInitialized(bool forceAccel)
|
GLLibraryEGL::EnsureInitialized(bool forceAccel, nsACString& aFailureId)
|
||||||
{
|
{
|
||||||
if (mInitialized) {
|
if (mInitialized) {
|
||||||
return true;
|
return true;
|
||||||
@@ -389,7 +394,7 @@ GLLibraryEGL::EnsureInitialized(bool forceAccel)
|
|||||||
EGLDisplay chosenDisplay = nullptr;
|
EGLDisplay chosenDisplay = nullptr;
|
||||||
|
|
||||||
if (IsExtensionSupported(ANGLE_platform_angle_d3d)) {
|
if (IsExtensionSupported(ANGLE_platform_angle_d3d)) {
|
||||||
bool accelAngleSupport = IsAccelAngleSupported(gfxInfo);
|
bool accelAngleSupport = IsAccelAngleSupported(gfxInfo, aFailureId);
|
||||||
|
|
||||||
bool shouldTryAccel = forceAccel || accelAngleSupport;
|
bool shouldTryAccel = forceAccel || accelAngleSupport;
|
||||||
bool shouldTryWARP = !shouldTryAccel;
|
bool shouldTryWARP = !shouldTryAccel;
|
||||||
@@ -410,6 +415,9 @@ GLLibraryEGL::EnsureInitialized(bool forceAccel)
|
|||||||
// If falling back to WARP did not work and we don't want to try
|
// If falling back to WARP did not work and we don't want to try
|
||||||
// using HW accelerated ANGLE, then fail.
|
// using HW accelerated ANGLE, then fail.
|
||||||
if (!shouldTryAccel) {
|
if (!shouldTryAccel) {
|
||||||
|
if (aFailureId.IsEmpty()) {
|
||||||
|
aFailureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_WARP_FALLBACK");
|
||||||
|
}
|
||||||
NS_ERROR("Fallback WARP ANGLE context failed to initialize.");
|
NS_ERROR("Fallback WARP ANGLE context failed to initialize.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -422,6 +430,9 @@ GLLibraryEGL::EnsureInitialized(bool forceAccel)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!chosenDisplay) {
|
if (!chosenDisplay) {
|
||||||
|
if (aFailureId.IsEmpty()) {
|
||||||
|
aFailureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_NO_DISPLAY");
|
||||||
|
}
|
||||||
NS_WARNING("Failed to initialize a display.");
|
NS_WARNING("Failed to initialize a display.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -535,7 +535,7 @@ public:
|
|||||||
|
|
||||||
bool ReadbackEGLImage(EGLImage image, gfx::DataSourceSurface* out_surface);
|
bool ReadbackEGLImage(EGLImage image, gfx::DataSourceSurface* out_surface);
|
||||||
|
|
||||||
bool EnsureInitialized(bool forceAccel = false);
|
bool EnsureInitialized(bool forceAccel, nsACString& aFailureId);
|
||||||
|
|
||||||
void DumpEGLConfig(EGLConfig cfg);
|
void DumpEGLConfig(EGLConfig cfg);
|
||||||
void DumpEGLConfigs();
|
void DumpEGLConfigs();
|
||||||
|
|||||||
@@ -51,7 +51,9 @@ GLImage::GetAsSourceSurface()
|
|||||||
MOZ_ASSERT(NS_IsMainThread(), "Should be on the main thread");
|
MOZ_ASSERT(NS_IsMainThread(), "Should be on the main thread");
|
||||||
|
|
||||||
if (!sSnapshotContext) {
|
if (!sSnapshotContext) {
|
||||||
sSnapshotContext = GLContextProvider::CreateHeadless(CreateContextFlags::NONE);
|
nsCString discardFailureId;
|
||||||
|
sSnapshotContext = GLContextProvider::CreateHeadless(CreateContextFlags::NONE,
|
||||||
|
discardFailureId);
|
||||||
if (!sSnapshotContext) {
|
if (!sSnapshotContext) {
|
||||||
NS_WARNING("Failed to create snapshot GLContext");
|
NS_WARNING("Failed to create snapshot GLContext");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|||||||
@@ -131,8 +131,10 @@ CompositorOGL::CreateContext()
|
|||||||
caps.preserve = false;
|
caps.preserve = false;
|
||||||
caps.bpp16 = gfxPlatform::GetPlatform()->GetOffscreenFormat() == SurfaceFormat::R5G6B5_UINT16;
|
caps.bpp16 = gfxPlatform::GetPlatform()->GetOffscreenFormat() == SurfaceFormat::R5G6B5_UINT16;
|
||||||
|
|
||||||
|
nsCString discardFailureId;
|
||||||
context = GLContextProvider::CreateOffscreen(mSurfaceSize,
|
context = GLContextProvider::CreateOffscreen(mSurfaceSize,
|
||||||
caps, CreateContextFlags::REQUIRE_COMPAT_PROFILE);
|
caps, CreateContextFlags::REQUIRE_COMPAT_PROFILE,
|
||||||
|
discardFailureId);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!context) {
|
if (!context) {
|
||||||
|
|||||||
@@ -48,9 +48,11 @@ public:
|
|||||||
mozilla::gl::SurfaceCaps caps = mozilla::gl::SurfaceCaps::ForRGB();
|
mozilla::gl::SurfaceCaps caps = mozilla::gl::SurfaceCaps::ForRGB();
|
||||||
caps.preserve = false;
|
caps.preserve = false;
|
||||||
caps.bpp16 = false;
|
caps.bpp16 = false;
|
||||||
|
nsCString discardFailureId;
|
||||||
RefPtr<GLContext> context = GLContextProvider::CreateOffscreen(
|
RefPtr<GLContext> context = GLContextProvider::CreateOffscreen(
|
||||||
IntSize(gCompWidth, gCompHeight), caps,
|
IntSize(gCompWidth, gCompHeight), caps,
|
||||||
CreateContextFlags::REQUIRE_COMPAT_PROFILE);
|
CreateContextFlags::REQUIRE_COMPAT_PROFILE,
|
||||||
|
discardFailureId);
|
||||||
return context.forget().take();
|
return context.forget().take();
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|||||||
@@ -1321,8 +1321,10 @@ gfxPlatform::GetSkiaGLGlue()
|
|||||||
* stands, this only works on the main thread.
|
* stands, this only works on the main thread.
|
||||||
*/
|
*/
|
||||||
RefPtr<GLContext> glContext;
|
RefPtr<GLContext> glContext;
|
||||||
|
nsCString discardFailureId;
|
||||||
glContext = GLContextProvider::CreateHeadless(CreateContextFlags::REQUIRE_COMPAT_PROFILE |
|
glContext = GLContextProvider::CreateHeadless(CreateContextFlags::REQUIRE_COMPAT_PROFILE |
|
||||||
CreateContextFlags::ALLOW_OFFLINE_RENDERER);
|
CreateContextFlags::ALLOW_OFFLINE_RENDERER,
|
||||||
|
discardFailureId);
|
||||||
if (!glContext) {
|
if (!glContext) {
|
||||||
printf_stderr("Failed to create GLContext for SkiaGL!\n");
|
printf_stderr("Failed to create GLContext for SkiaGL!\n");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|||||||
@@ -75,7 +75,9 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<gl::GLContext> gl;
|
RefPtr<gl::GLContext> gl;
|
||||||
gl = gl::GLContextProvider::CreateHeadless(gl::CreateContextFlags::REQUIRE_COMPAT_PROFILE);
|
nsCString discardFailureId;
|
||||||
|
gl = gl::GLContextProvider::CreateHeadless(gl::CreateContextFlags::REQUIRE_COMPAT_PROFILE,
|
||||||
|
discardFailureId);
|
||||||
|
|
||||||
if (!gl) {
|
if (!gl) {
|
||||||
// Setting mReady to true here means that we won't retry. Everything will
|
// Setting mReady to true here means that we won't retry. Everything will
|
||||||
|
|||||||
Reference in New Issue
Block a user