diff -up firefox-102.0/gfx/gl/SharedSurfaceDMABUF.cpp.D147637.diff firefox-102.0/gfx/gl/SharedSurfaceDMABUF.cpp --- firefox-102.0/gfx/gl/SharedSurfaceDMABUF.cpp.D147637.diff 2022-06-23 09:08:46.000000000 +0200 +++ firefox-102.0/gfx/gl/SharedSurfaceDMABUF.cpp 2022-06-28 16:37:52.264835137 +0200 @@ -9,25 +9,58 @@ #include "GLContextEGL.h" #include "MozFramebuffer.h" #include "mozilla/layers/LayersSurfaces.h" // for SurfaceDescriptor, etc +#include "mozilla/gfx/gfxVars.h" namespace mozilla::gl { +static bool HasDmaBufExtensions(const GLContextEGL* gl) { + const auto& egl = *(gl->mEgl); + return egl.IsExtensionSupported(EGLExtension::EXT_image_dma_buf_import) && + egl.IsExtensionSupported( + EGLExtension::EXT_image_dma_buf_import_modifiers) && + egl.IsExtensionSupported(EGLExtension::MESA_image_dma_buf_export); +} + /*static*/ UniquePtr SharedSurface_DMABUF::Create( const SharedSurfaceDesc& desc) { - const auto flags = static_cast( - DMABUF_TEXTURE | DMABUF_USE_MODIFIERS | DMABUF_ALPHA); - const RefPtr surface = DMABufSurfaceRGBA::CreateDMABufSurface( - desc.size.width, desc.size.height, flags); - if (!surface || !surface->CreateTexture(desc.gl)) { - return nullptr; + const auto& gle = GLContextEGL::Cast(desc.gl); + const auto& context = gle->mContext; + const auto& egl = *(gle->mEgl); + + RefPtr surface; + UniquePtr fb; + + if (!HasDmaBufExtensions(gle) || !gfx::gfxVars::UseDMABufSurfaceExport()) { + // Use MESA_image_dma_buf_export is not supported or it's broken. + // Create dmabuf surface directly via. GBM and create + // EGLImage/framebuffer over it. + const auto flags = static_cast( + DMABUF_TEXTURE | DMABUF_USE_MODIFIERS | DMABUF_ALPHA); + surface = DMABufSurfaceRGBA::CreateDMABufSurface(desc.size.width, + desc.size.height, flags); + if (!surface || !surface->CreateTexture(desc.gl)) { + return nullptr; + } + const auto tex = surface->GetTexture(); + fb = MozFramebuffer::CreateForBacking(desc.gl, desc.size, 0, false, + LOCAL_GL_TEXTURE_2D, tex); + if (!fb) return nullptr; + } else { + // Use MESA_image_dma_buf_export so create EGLImage/framebuffer directly + // and derive dmabuf from it. + fb = MozFramebuffer::Create(desc.gl, desc.size, 0, false); + if (!fb) return nullptr; + + const auto buffer = reinterpret_cast(fb->ColorTex()); + const auto image = + egl.fCreateImage(context, LOCAL_EGL_GL_TEXTURE_2D, buffer, nullptr); + if (!image) return nullptr; + + surface = DMABufSurfaceRGBA::CreateDMABufSurface( + desc.gl, image, desc.size.width, desc.size.height); + if (!surface) return nullptr; } - - const auto tex = surface->GetTexture(); - auto fb = MozFramebuffer::CreateForBacking(desc.gl, desc.size, 0, false, - LOCAL_GL_TEXTURE_2D, tex); - if (!fb) return nullptr; - return AsUnique(new SharedSurface_DMABUF(desc, std::move(fb), surface)); } @@ -61,7 +94,7 @@ UniquePtr Surface } auto dmabufFactory = MakeUnique(gl); - if (dmabufFactory->CanCreateSurface()) { + if (dmabufFactory->CanCreateSurface(gl)) { return dmabufFactory; } @@ -71,8 +104,38 @@ UniquePtr Surface return nullptr; } +bool SurfaceFactory_DMABUF::CanCreateSurface(GLContext& gl) { + UniquePtr test = + CreateShared(gfx::IntSize(1, 1), gfx::ColorSpace2::SRGB); + if (!test) { + LOGDMABUF(( + "SurfaceFactory_DMABUF::CanCreateSurface() failed to create surface.")); + return false; + } + auto desc = test->ToSurfaceDescriptor(); + if (!desc) { + LOGDMABUF( + ("SurfaceFactory_DMABUF::CanCreateSurface() failed to serialize " + "surface.")); + return false; + } + RefPtr importedSurface = + DMABufSurface::CreateDMABufSurface(*desc); + if (!importedSurface) { + LOGDMABUF(( + "SurfaceFactory_DMABUF::CanCreateSurface() failed to import surface.")); + return false; + } + if (!importedSurface->CreateTexture(&gl)) { + LOGDMABUF( + ("SurfaceFactory_DMABUF::CanCreateSurface() failed to create texture " + "over surface.")); + return false; + } + return true; +} + SurfaceFactory_DMABUF::SurfaceFactory_DMABUF(GLContext& gl) : SurfaceFactory({&gl, SharedSurfaceType::EGLSurfaceDMABUF, layers::TextureType::DMABUF, true}) {} - } // namespace mozilla::gl diff -up firefox-102.0/gfx/gl/SharedSurfaceDMABUF.h.D147637.diff firefox-102.0/gfx/gl/SharedSurfaceDMABUF.h --- firefox-102.0/gfx/gl/SharedSurfaceDMABUF.h.D147637.diff 2022-06-23 09:08:47.000000000 +0200 +++ firefox-102.0/gfx/gl/SharedSurfaceDMABUF.h 2022-06-28 15:00:20.339991965 +0200 @@ -59,11 +59,7 @@ class SurfaceFactory_DMABUF : public Sur return SharedSurface_DMABUF::Create(desc); } - bool CanCreateSurface() { - UniquePtr test = - CreateShared(gfx::IntSize(1, 1), gfx::ColorSpace2::SRGB); - return test != nullptr; - } + bool CanCreateSurface(GLContext& gl); }; } // namespace gl