Bug 1370544 - Ensure EGLSurface is created with the same EGLConfig as the context r=jgilbert
MozReview-Commit-ID: 1cN7VzCa2lV
--- a/gfx/gl/GLContextEGL.h
+++ b/gfx/gl/GLContextEGL.h
@@ -128,14 +128,18 @@ protected:
bool mIsDoubleBuffered;
bool mCanBindToTexture;
bool mShareWithEGLImage;
bool mOwnsContext;
static EGLSurface CreatePBufferSurfaceTryingPowerOfTwo(EGLConfig config,
EGLenum bindToTextureFormat,
gfx::IntSize& pbsize);
+#if defined(MOZ_WIDGET_ANDROID)
+public:
+ EGLSurface CreateCompatibleSurface(void* aWindow);
+#endif // defined(MOZ_WIDGET_ANDROID)
};
} // namespace gl
} // namespace mozilla
#endif // GLCONTEXTEGL_H_
--- a/gfx/gl/GLContextProviderEGL.cpp
+++ b/gfx/gl/GLContextProviderEGL.cpp
@@ -763,43 +763,52 @@ GLContextProviderEGL::CreateForWindow(ns
bool aWebRender,
bool aForceAccelerated)
{
MOZ_ASSERT(aWidget);
return GLContextEGLFactory::Create(GET_NATIVE_WINDOW_FROM_REAL_WIDGET(aWidget),
aWebRender);
}
-#if defined(ANDROID)
+#if defined(MOZ_WIDGET_ANDROID)
EGLSurface
-GLContextProviderEGL::CreateEGLSurface(void* aWindow)
+GLContextEGL::CreateCompatibleSurface(void* aWindow)
+{
+ if (mConfig == EGL_NO_CONFIG) {
+ MOZ_CRASH("GFX: Failed with invalid EGLConfig 2!\n");
+ }
+
+ return GLContextProviderEGL::CreateEGLSurface(aWindow, mConfig);
+}
+
+/* static */ EGLSurface
+GLContextProviderEGL::CreateEGLSurface(void* aWindow, EGLConfig aConfig)
{
// NOTE: aWindow is an ANativeWindow
nsCString discardFailureId;
if (!sEGLLibrary.EnsureInitialized(false, &discardFailureId)) {
MOZ_CRASH("GFX: Failed to load EGL library 4!\n");
}
-
- EGLConfig config;
- if (!CreateConfig(&config, /* aEnableDepthBuffer */ false)) {
+ EGLConfig config = aConfig;
+ if (!config && !CreateConfig(&config, /* aEnableDepthBuffer */ false)) {
MOZ_CRASH("GFX: Failed to create EGLConfig 2!\n");
}
MOZ_ASSERT(aWindow);
EGLSurface surface = sEGLLibrary.fCreateWindowSurface(EGL_DISPLAY(), config, aWindow,
0);
if (surface == EGL_NO_SURFACE) {
MOZ_CRASH("GFX: Failed to create EGLSurface 2!\n");
}
return surface;
}
-void
+/* static */ void
GLContextProviderEGL::DestroyEGLSurface(EGLSurface surface)
{
nsCString discardFailureId;
if (!sEGLLibrary.EnsureInitialized(false, &discardFailureId)) {
MOZ_CRASH("GFX: Failed to load EGL library 5!\n");
}
sEGLLibrary.fDestroySurface(EGL_DISPLAY(), surface);
@@ -975,16 +984,22 @@ GLContextProviderEGL::CreateOffscreen(co
}
bool canOffscreenUseHeadless = true;
if (sEGLLibrary.IsANGLE()) {
// ANGLE needs to use PBuffers.
canOffscreenUseHeadless = false;
}
+#if defined(MOZ_WIDGET_ANDROID)
+ // Using a headless context loses the SurfaceCaps
+ // which can cause a loss of depth and/or stencil
+ canOffscreenUseHeadless = false;
+#endif // defined(MOZ_WIDGET_ANDROID)
+
RefPtr<GLContext> gl;
SurfaceCaps minOffscreenCaps = minCaps;
if (canOffscreenUseHeadless) {
gl = CreateHeadless(flags, out_failureId);
if (!gl) {
return nullptr;
}
--- a/gfx/gl/GLContextProviderImpl.h
+++ b/gfx/gl/GLContextProviderImpl.h
@@ -5,19 +5,19 @@
#ifndef IN_GL_CONTEXT_PROVIDER_H
#error GLContextProviderImpl.h must only be included from GLContextProvider.h
#endif
#ifndef GL_CONTEXT_PROVIDER_NAME
#error GL_CONTEXT_PROVIDER_NAME not defined
#endif
-#if defined(ANDROID)
-typedef void* EGLSurface;
-#endif // defined(ANDROID)
+#if defined(MOZ_WIDGET_ANDROID)
+#include "GLTypes.h" // for EGLSurface and EGLConfig
+#endif // defined(MOZ_WIDGET_ANDROID)
class GL_CONTEXT_PROVIDER_NAME
{
public:
/**
* Create a context that renders to the surface of the widget represented by
* the compositor widget that is passed in. The context is always created
* with an RGB pixel format, with no alpha, depth or stencil.
@@ -107,20 +107,20 @@ public:
* @param aContext External context which will be wrapped by Gecko GLContext.
* @param aSurface External surface which is used for external context.
*
* @return Wrapping Context to use for rendering
*/
static already_AddRefed<GLContext>
CreateWrappingExisting(void* aContext, void* aSurface);
-#if defined(ANDROID)
- static EGLSurface CreateEGLSurface(void* aWindow);
+#if defined(MOZ_WIDGET_ANDROID)
+ static EGLSurface CreateEGLSurface(void* aWindow, EGLConfig aConfig = nullptr);
static void DestroyEGLSurface(EGLSurface surface);
-#endif // defined(ANDROID)
+#endif // defined(MOZ_WIDGET_ANDROID)
/**
* Get a pointer to the global context, creating it if it doesn't exist.
*/
static GLContext*
GetGlobalContext();
/**
--- a/gfx/gl/SharedSurfaceEGL.cpp
+++ b/gfx/gl/SharedSurfaceEGL.cpp
@@ -191,17 +191,19 @@ SharedSurface_SurfaceTexture::Create(GLC
bool hasAlpha,
java::GeckoSurface::Param surface)
{
MOZ_ASSERT(surface);
UniquePtr<SharedSurface_SurfaceTexture> ret;
AndroidNativeWindow window(surface);
- EGLSurface eglSurface = GLContextProviderEGL::CreateEGLSurface(window.NativeWindow());
+ GLContextEGL* egl = GLContextEGL::Cast(prodGL);
+ MOZ_ASSERT(egl);
+ EGLSurface eglSurface = egl->CreateCompatibleSurface(window.NativeWindow());
if (!eglSurface) {
return Move(ret);
}
ret.reset(new SharedSurface_SurfaceTexture(prodGL, size, hasAlpha,
formats, surface, eglSurface));
return Move(ret);
}
--- a/gfx/layers/composite/LayerManagerComposite.cpp
+++ b/gfx/layers/composite/LayerManagerComposite.cpp
@@ -1066,36 +1066,36 @@ LayerManagerComposite::RenderToPresentat
{
widget::CompositorWidget* const widget = mCompositor->GetWidget();
ANativeWindow* window = widget->AsAndroid()->GetPresentationANativeWindow();
if (!window) {
return;
}
- EGLSurface surface = widget->AsAndroid()->GetPresentationEGLSurface();
-
- if (!surface) {
- //create surface;
- surface = GLContextProviderEGL::CreateEGLSurface(window);
- if (!surface) {
- return;
- }
-
- widget->AsAndroid()->SetPresentationEGLSurface(surface);
- }
-
CompositorOGL* compositor = mCompositor->AsCompositorOGL();
GLContext* gl = compositor->gl();
GLContextEGL* egl = GLContextEGL::Cast(gl);
if (!egl) {
return;
}
+ EGLSurface surface = widget->AsAndroid()->GetPresentationEGLSurface();
+
+ if (!surface) {
+ //create surface;
+ surface = egl->CreateCompatibleSurface(window);
+ if (!surface) {
+ return;
+ }
+
+ widget->AsAndroid()->SetPresentationEGLSurface(surface);
+ }
+
const IntSize windowSize(ANativeWindow_getWidth(window),
ANativeWindow_getHeight(window));
if ((windowSize.width <= 0) || (windowSize.height <= 0)) {
return;
}