Blob Blame History Raw
diff -up firefox-101.0/gfx/gl/GLContextEGL.h.D147420.diff firefox-101.0/gfx/gl/GLContextEGL.h
--- firefox-101.0/gfx/gl/GLContextEGL.h.D147420.diff	2022-05-27 01:16:54.000000000 +0200
+++ firefox-101.0/gfx/gl/GLContextEGL.h	2022-06-07 09:01:17.487787806 +0200
@@ -106,6 +106,9 @@ class GLContextEGL final : public GLCont
   static RefPtr<GLContextEGL> CreateEGLPBufferOffscreenContextImpl(
       std::shared_ptr<EglDisplay>, const GLContextCreateDesc&,
       const gfx::IntSize& size, bool aUseGles, nsACString* const out_FailureId);
+  static RefPtr<GLContextEGL> CreateEGLSurfacelessContext(
+      const std::shared_ptr<EglDisplay> display,
+      const GLContextCreateDesc& desc, nsACString* const out_failureId);
 
   static EGLSurface CreateEGLSurfaceForCompositorWidget(
       widget::CompositorWidget* aCompositorWidget, const EGLConfig aConfig);
diff -up firefox-101.0/gfx/gl/GLContextProviderEGL.cpp.D147420.diff firefox-101.0/gfx/gl/GLContextProviderEGL.cpp
--- firefox-101.0/gfx/gl/GLContextProviderEGL.cpp.D147420.diff	2022-05-27 01:16:54.000000000 +0200
+++ firefox-101.0/gfx/gl/GLContextProviderEGL.cpp	2022-06-07 09:01:17.487787806 +0200
@@ -1190,16 +1190,42 @@ RefPtr<GLContextEGL> GLContextEGL::Creat
 }
 
 /*static*/
+RefPtr<GLContextEGL> GLContextEGL::CreateEGLSurfacelessContext(
+    const std::shared_ptr<EglDisplay> display, const GLContextCreateDesc& desc,
+    nsACString* const out_failureId) {
+  const EGLConfig config = {};
+  auto fullDesc = GLContextDesc{desc};
+  fullDesc.isOffscreen = true;
+  RefPtr<GLContextEGL> gl = GLContextEGL::CreateGLContext(
+      display, fullDesc, config, EGL_NO_SURFACE, false, out_failureId);
+  if (!gl) {
+    NS_WARNING("Failed to create surfaceless GL context");
+    return nullptr;
+  }
+  return gl;
+}
+
+/*static*/
 already_AddRefed<GLContext> GLContextProviderEGL::CreateHeadless(
     const GLContextCreateDesc& desc, nsACString* const out_failureId) {
   const auto display = DefaultEglDisplay(out_failureId);
   if (!display) {
     return nullptr;
   }
-  mozilla::gfx::IntSize dummySize = mozilla::gfx::IntSize(16, 16);
-  auto ret = GLContextEGL::CreateEGLPBufferOffscreenContext(
-      display, desc, dummySize, out_failureId);
-  return ret.forget();
+  RefPtr<GLContextEGL> gl;
+#ifdef MOZ_WAYLAND
+  if (!gdk_display_get_default() &&
+      display->IsExtensionSupported(EGLExtension::MESA_platform_surfaceless)) {
+    gl =
+        GLContextEGL::CreateEGLSurfacelessContext(display, desc, out_failureId);
+  } else
+#endif
+  {
+    mozilla::gfx::IntSize dummySize = mozilla::gfx::IntSize(16, 16);
+    gl = GLContextEGL::CreateEGLPBufferOffscreenContext(
+        display, desc, dummySize, out_failureId);
+  }
+  return gl.forget();
 }
 
 // Don't want a global context on Android as 1) share groups across 2 threads
diff -up firefox-101.0/gfx/gl/GLDefs.h.D147420.diff firefox-101.0/gfx/gl/GLDefs.h
--- firefox-101.0/gfx/gl/GLDefs.h.D147420.diff	2022-05-27 01:16:54.000000000 +0200
+++ firefox-101.0/gfx/gl/GLDefs.h	2022-06-07 09:01:17.487787806 +0200
@@ -104,6 +104,9 @@ bool CheckContextLost(const GLContext* g
 // EGL_ANGLE_image_d3d11_texture
 #define LOCAL_EGL_D3D11_TEXTURE_ANGLE                   0x3484
 
+// EGL_MESA_platform_surfaceless
+#define LOCAL_EGL_PLATFORM_SURFACELESS_MESA             0x31DD
+
 // clang-format on
 
 #endif
diff -up firefox-101.0/gfx/gl/GLLibraryEGL.cpp.D147420.diff firefox-101.0/gfx/gl/GLLibraryEGL.cpp
--- firefox-101.0/gfx/gl/GLLibraryEGL.cpp.D147420.diff	2022-05-27 01:16:54.000000000 +0200
+++ firefox-101.0/gfx/gl/GLLibraryEGL.cpp	2022-06-07 09:03:04.077349997 +0200
@@ -82,7 +82,8 @@ static const char* sEGLExtensionNames[]
     "EGL_KHR_swap_buffers_with_damage",
     "EGL_EXT_buffer_age",
     "EGL_KHR_partial_update",
-    "EGL_NV_robustness_video_memory_purge"};
+    "EGL_NV_robustness_video_memory_purge",
+    "EGL_MESA_platform_surfaceless"};
 
 PRLibrary* LoadApitraceLibrary() {
   const char* path = nullptr;
@@ -151,6 +152,19 @@ static std::shared_ptr<EglDisplay> GetAn
   return EglDisplay::Create(egl, display, false, aProofOfLock);
 }
 
+#ifdef MOZ_WAYLAND
+static std::shared_ptr<EglDisplay> GetAndInitSurfacelessDisplay(
+    GLLibraryEGL& egl, const StaticMutexAutoLock& aProofOfLock) {
+  const EGLAttrib attrib_list[] = {LOCAL_EGL_NONE};
+  const EGLDisplay display = egl.fGetPlatformDisplay(
+      LOCAL_EGL_PLATFORM_SURFACELESS_MESA, EGL_DEFAULT_DISPLAY, attrib_list);
+  if (display == EGL_NO_DISPLAY) {
+    return nullptr;
+  }
+  return EglDisplay::Create(egl, display, true, aProofOfLock);
+}
+#endif
+
 static std::shared_ptr<EglDisplay> GetAndInitWARPDisplay(
     GLLibraryEGL& egl, void* displayType,
     const StaticMutexAutoLock& aProofOfLock) {
@@ -629,6 +643,11 @@ bool GLLibraryEGL::Init(nsACString* cons
         END_OF_SYMBOLS};
     (void)fnLoadSymbols(symbols);
   }
+  {
+    const SymLoadStruct symbols[] = {SYMBOL(GetPlatformDisplay),
+                                     END_OF_SYMBOLS};
+    (void)fnLoadSymbols(symbols);
+  }
 
   return true;
 }
@@ -806,7 +825,9 @@ std::shared_ptr<EglDisplay> GLLibraryEGL
 #ifdef MOZ_WAYLAND
     // Some drivers doesn't support EGL_DEFAULT_DISPLAY
     GdkDisplay* gdkDisplay = gdk_display_get_default();
-    if (widget::GdkIsWaylandDisplay(gdkDisplay)) {
+    if (!gdkDisplay) {
+      ret = GetAndInitSurfacelessDisplay(*this, aProofOfLock);
+    } else if (widget::GdkIsWaylandDisplay(gdkDisplay)) {
       nativeDisplay = widget::WaylandDisplayGetWLDisplay(gdkDisplay);
       if (!nativeDisplay) {
         NS_WARNING("Failed to get wl_display.");
@@ -814,7 +835,9 @@ std::shared_ptr<EglDisplay> GLLibraryEGL
       }
     }
 #endif
-    ret = GetAndInitDisplay(*this, nativeDisplay, aProofOfLock);
+    if (!ret) {
+      ret = GetAndInitDisplay(*this, nativeDisplay, aProofOfLock);
+    }
   }
 
   if (!ret) {
diff -up firefox-101.0/gfx/gl/GLLibraryEGL.h.D147420.diff firefox-101.0/gfx/gl/GLLibraryEGL.h
--- firefox-101.0/gfx/gl/GLLibraryEGL.h.D147420.diff	2022-05-27 01:16:54.000000000 +0200
+++ firefox-101.0/gfx/gl/GLLibraryEGL.h	2022-06-07 09:01:17.487787806 +0200
@@ -107,6 +107,7 @@ enum class EGLExtension {
   EXT_buffer_age,
   KHR_partial_update,
   NV_robustness_video_memory_purge,
+  MESA_platform_surfaceless,
   Max
 };
 
diff -up firefox-101.0/widget/gtk/DMABufSurface.cpp.D147420.diff firefox-101.0/widget/gtk/DMABufSurface.cpp
--- firefox-101.0/widget/gtk/DMABufSurface.cpp.D147420.diff	2022-06-07 09:01:17.486787773 +0200
+++ firefox-101.0/widget/gtk/DMABufSurface.cpp	2022-06-07 09:01:17.487787806 +0200
@@ -1259,7 +1259,7 @@ bool DMABufSurfaceYUV::VerifyTextureCrea
     nsCString discardFailureId;
     sSnapshotContext = GLContextProvider::CreateHeadless({}, &discardFailureId);
     if (!sSnapshotContext) {
-      NS_WARNING("Failed to create snapshot GLContext");
+      LOGDMABUF(("  failed to create snapshot GLContext"));
       return false;
     }
   }
@@ -1268,10 +1268,12 @@ bool DMABufSurfaceYUV::VerifyTextureCrea
 
   for (int i = 0; i < mBufferPlaneCount; i++) {
     if (!CreateEGLImage(sSnapshotContext, i)) {
+      LOGDMABUF(("  failed to create EGL image!"));
       return false;
     }
   }
 
+  LOGDMABUF(("  success"));
   return true;
 }