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 CreateEGLPBufferOffscreenContextImpl( std::shared_ptr, const GLContextCreateDesc&, const gfx::IntSize& size, bool aUseGles, nsACString* const out_FailureId); + static RefPtr CreateEGLSurfacelessContext( + const std::shared_ptr 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::Creat } /*static*/ +RefPtr GLContextEGL::CreateEGLSurfacelessContext( + const std::shared_ptr display, const GLContextCreateDesc& desc, + nsACString* const out_failureId) { + const EGLConfig config = {}; + auto fullDesc = GLContextDesc{desc}; + fullDesc.isOffscreen = true; + RefPtr 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 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 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 GetAn return EglDisplay::Create(egl, display, false, aProofOfLock); } +#ifdef MOZ_WAYLAND +static std::shared_ptr 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 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 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 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; }