Bug 1586696 [Wayland] Use wayland dmabuf as WebGL backend, r=jgilbert
authorMartin Stransky <stransky@redhat.com>
Wed, 05 Feb 2020 06:32:25 +0000
changeset 512553 4f788224c8d27a311f9f5620344f963b223bcb58
parent 512552 76ee012b6099f1b2d4095d9d57c2e41f7a7c5a2c
child 512554 51b1d5255b96d48273bb458eead12c6be54c1fea
push id106474
push userrmaries@mozilla.com
push dateWed, 05 Feb 2020 07:10:23 +0000
treeherderautoland@4f788224c8d2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjgilbert
bugs1586696
milestone74.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1586696 [Wayland] Use wayland dmabuf as WebGL backend, r=jgilbert - Create new SharedSurfaceType called EGLSurfaceDMABUF - Implement EGLSurfaceDMABUF by SharedSurfaceDMABUF which is backed by WaylandDMABufSurface. It can be used by Wayland/EGL WebGL backend. - It's disabled by default, can be enabled by widget.wayland_dmabuf_webgl.enabled pref. Differential Revision: https://phabricator.services.mozilla.com/D60114
gfx/gl/GLScreenBuffer.cpp
gfx/gl/SharedSurfaceDMABUF.cpp
gfx/gl/SharedSurfaceDMABUF.h
gfx/gl/SurfaceTypes.h
gfx/gl/moz.build
gfx/layers/opengl/WaylandDMABUFTextureHostOGL.cpp
--- a/gfx/gl/GLScreenBuffer.cpp
+++ b/gfx/gl/GLScreenBuffer.cpp
@@ -29,16 +29,21 @@
 #  include "SharedSurfaceIO.h"
 #endif
 
 #ifdef MOZ_X11
 #  include "GLXLibrary.h"
 #  include "SharedSurfaceGLX.h"
 #endif
 
+#ifdef MOZ_WAYLAND
+#  include "gfxPlatformGtk.h"
+#  include "SharedSurfaceDMABUF.h"
+#endif
+
 namespace mozilla::gl {
 
 using gfx::SurfaceFormat;
 
 UniquePtr<GLScreenBuffer> GLScreenBuffer::Create(GLContext* gl,
                                                  const gfx::IntSize& size,
                                                  const SurfaceCaps& caps) {
   UniquePtr<GLScreenBuffer> ret;
@@ -79,16 +84,23 @@ UniquePtr<SurfaceFactory> GLScreenBuffer
       !StaticPrefs::webgl_force_layers_readback() &&
       (backend == layers::LayersBackend::LAYERS_D3D11 ||
        (backend == layers::LayersBackend::LAYERS_WR && useANGLE));
 
   UniquePtr<SurfaceFactory> factory = nullptr;
   if (useGl) {
 #if defined(XP_MACOSX)
     factory = SurfaceFactory_IOSurface::Create(gl, caps, ipcChannel, flags);
+#elif defined(MOZ_WAYLAND)
+    if (gl->GetContextType() == GLContextType::EGL) {
+      if (gfxPlatformGtk::GetPlatform()->UseWaylandDMABufWebGL()) {
+        factory =
+            MakeUnique<SurfaceFactory_DMABUF>(gl, caps, ipcChannel, flags);
+      }
+    }
 #elif defined(MOZ_X11)
     if (sGLXLibrary.UseTextureFromPixmap())
       factory = SurfaceFactory_GLXDrawable::Create(gl, caps, ipcChannel, flags);
 #elif defined(MOZ_WIDGET_UIKIT)
     factory = MakeUnique<SurfaceFactory_GLTexture>(mGLContext, caps, ipcChannel,
                                                    mFlags);
 #elif defined(MOZ_WIDGET_ANDROID)
     if (XRE_IsParentProcess() && !StaticPrefs::webgl_enable_surface_texture()) {
new file mode 100644
--- /dev/null
+++ b/gfx/gl/SharedSurfaceDMABUF.cpp
@@ -0,0 +1,59 @@
+/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 4; -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "SharedSurfaceDMABUF.h"
+#include "GLContextEGL.h"
+#include "mozilla/layers/LayersSurfaces.h"  // for SurfaceDescriptor, etc
+
+namespace mozilla::gl {
+
+/*static*/
+UniquePtr<SharedSurface_DMABUF> SharedSurface_DMABUF::Create(
+    GLContext* prodGL, const GLFormats& formats, const gfx::IntSize& size,
+    bool hasAlpha) {
+  auto flags = static_cast<WaylandDMABufSurfaceFlags>(DMABUF_TEXTURE |
+                                                      DMABUF_USE_MODIFIERS);
+  if (hasAlpha) {
+    flags = static_cast<WaylandDMABufSurfaceFlags>(flags | DMABUF_ALPHA);
+  }
+
+  RefPtr<WaylandDMABufSurface> surface =
+      WaylandDMABufSurface::CreateDMABufSurface(size.width, size.height, flags);
+  if (!surface || !surface->CreateEGLImage(prodGL)) {
+    return nullptr;
+  }
+
+  UniquePtr<SharedSurface_DMABUF> ret;
+  ret.reset(new SharedSurface_DMABUF(prodGL, size, hasAlpha, surface));
+  return ret;
+}
+
+SharedSurface_DMABUF::SharedSurface_DMABUF(
+    GLContext* gl, const gfx::IntSize& size, bool hasAlpha,
+    RefPtr<WaylandDMABufSurface> aSurface)
+    : SharedSurface(SharedSurfaceType::EGLSurfaceDMABUF,
+                    AttachmentType::GLTexture, gl, size, hasAlpha, true),
+      mSurface(aSurface) {}
+
+SharedSurface_DMABUF::~SharedSurface_DMABUF() {
+  if (!mGL || !mGL->MakeCurrent()) {
+    return;
+  }
+  mSurface->ReleaseEGLImage();
+}
+
+void SharedSurface_DMABUF::ProducerReleaseImpl() {
+  mGL->MakeCurrent();
+  // We don't have a better sync mechanism here so use glFinish() at least.
+  mGL->fFinish();
+}
+
+bool SharedSurface_DMABUF::ToSurfaceDescriptor(
+    layers::SurfaceDescriptor* const out_descriptor) {
+  MOZ_ASSERT(mSurface);
+  return mSurface->Serialize(*out_descriptor);
+}
+
+}  // namespace mozilla::gl
new file mode 100644
--- /dev/null
+++ b/gfx/gl/SharedSurfaceDMABUF.h
@@ -0,0 +1,80 @@
+/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 4; -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef SHARED_SURFACE_DMABUF_H_
+#define SHARED_SURFACE_DMABUF_H_
+
+#include "SharedSurface.h"
+#include "mozilla/widget/WaylandDMABufSurface.h"
+
+namespace mozilla {
+namespace gl {
+
+class GLContext;
+class GLLibraryEGL;
+
+class SharedSurface_DMABUF final : public SharedSurface {
+ public:
+  static UniquePtr<SharedSurface_DMABUF> Create(GLContext* prodGL,
+                                                const GLFormats& formats,
+                                                const gfx::IntSize& size,
+                                                bool hasAlpha);
+
+  static SharedSurface_DMABUF* Cast(SharedSurface* surf) {
+    MOZ_ASSERT(surf->mType == SharedSurfaceType::EGLSurfaceDMABUF);
+
+    return (SharedSurface_DMABUF*)surf;
+  }
+
+ protected:
+  RefPtr<WaylandDMABufSurface> mSurface;
+
+  SharedSurface_DMABUF(GLContext* gl, const gfx::IntSize& size, bool hasAlpha,
+                       RefPtr<WaylandDMABufSurface> aSurface);
+
+  void UpdateProdTexture(const MutexAutoLock& curAutoLock);
+
+ public:
+  virtual ~SharedSurface_DMABUF();
+
+  // Exclusive Content/WebGL lock/unlock of surface for write
+  virtual void LockProdImpl() override {}
+  virtual void UnlockProdImpl() override {}
+
+  // Non-exclusive Content/WebGL lock/unlock of surface for write
+  virtual void ProducerAcquireImpl() override {}
+  virtual void ProducerReleaseImpl() override;
+
+  // Non-exclusive Content/WebGL lock/unlock for read from surface
+  virtual void ProducerReadAcquireImpl() override {}
+  virtual void ProducerReadReleaseImpl() override {}
+
+  virtual GLuint ProdTexture() override { return mSurface->GetGLTexture(); }
+
+  virtual bool ToSurfaceDescriptor(
+      layers::SurfaceDescriptor* const out_descriptor) override;
+};
+
+class SurfaceFactory_DMABUF : public SurfaceFactory {
+ public:
+  SurfaceFactory_DMABUF(GLContext* prodGL, const SurfaceCaps& caps,
+                        const RefPtr<layers::LayersIPCChannel>& allocator,
+                        const layers::TextureFlags& flags)
+      : SurfaceFactory(SharedSurfaceType::EGLSurfaceDMABUF, prodGL, caps,
+                       allocator, flags){};
+
+ public:
+  virtual UniquePtr<SharedSurface> CreateShared(
+      const gfx::IntSize& size) override {
+    bool hasAlpha = mReadCaps.alpha;
+    return SharedSurface_DMABUF::Create(mGL, mFormats, size, hasAlpha);
+  }
+};
+
+}  // namespace gl
+
+}  // namespace mozilla
+
+#endif /* SHARED_SURFACE_DMABUF_H_ */
--- a/gfx/gl/SurfaceTypes.h
+++ b/gfx/gl/SurfaceTypes.h
@@ -73,16 +73,17 @@ enum class SharedSurfaceType : uint8_t {
   EGLImageShare,
   EGLSurfaceANGLE,
   DXGLInterop,
   DXGLInterop2,
   IOSurface,
   GLXDrawable,
   SharedGLTexture,
   AndroidSurfaceTexture,
+  EGLSurfaceDMABUF,
 
   Max
 };
 
 enum class AttachmentType : uint8_t {
   Screen = 0,
 
   GLTexture,
--- a/gfx/gl/moz.build
+++ b/gfx/gl/moz.build
@@ -113,16 +113,17 @@ elif gl_provider == 'GLX':
     ]
     EXPORTS += [
         'SharedSurfaceGLX.h'
     ]
 
 if CONFIG['MOZ_WAYLAND']:
     SOURCES += [
         'GLContextProviderWayland.cpp',
+        'SharedSurfaceDMABUF.cpp'
     ]
 
 UNIFIED_SOURCES += [
     'AndroidSurfaceTexture.cpp',
     'DecomposeIntoNoRepeatTriangles.cpp',
     'GfxTexturesReporter.cpp',
     'GLBlitHelper.cpp',
     'GLContext.cpp',
--- a/gfx/layers/opengl/WaylandDMABUFTextureHostOGL.cpp
+++ b/gfx/layers/opengl/WaylandDMABUFTextureHostOGL.cpp
@@ -69,17 +69,16 @@ void WaylandDMABUFTextureHostOGL::SetTex
   mProvider = aProvider;
 
   if (mTextureSource) {
     mTextureSource->SetTextureSourceProvider(aProvider);
   }
 }
 
 gfx::SurfaceFormat WaylandDMABUFTextureHostOGL::GetFormat() const {
-  MOZ_ASSERT(mTextureSource);
   return mTextureSource ? mTextureSource->GetFormat()
                         : gfx::SurfaceFormat::UNKNOWN;
 }
 
 gfx::IntSize WaylandDMABUFTextureHostOGL::GetSize() const {
   if (!mSurface) {
     return gfx::IntSize();
   }