Bug 1613358 [Wayland] Implement WaylandDMABUFSurfaceImage dmabuf image, r=sotaro
☠☠ backed out by 54750c57c13f ☠ ☠
authorMartin Stransky <stransky@redhat.com>
Thu, 06 Feb 2020 12:10:57 +0000
changeset 512726 6381c1f2aedca240ebbeb8feafb96f5b5977afce
parent 512725 12c004663a5c03385170eb1ac009e3bcdc2547ea
child 512727 92eb6f6a045fdc895873e537637b8a515501bf68
push id37097
push usercsabou@mozilla.com
push dateThu, 06 Feb 2020 21:47:20 +0000
treeherdermozilla-central@b372743705c9 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssotaro
bugs1613358
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 1613358 [Wayland] Implement WaylandDMABUFSurfaceImage dmabuf image, r=sotaro Implement WaylandDMABUFSurfaceImage which is backed by dma buf memory on Wayland and it holds decoded video images produced by ffmpeg va-api decoder. Differential Revision: https://phabricator.services.mozilla.com/D61678
gfx/gl/GLBlitHelper.cpp
gfx/layers/ImageContainer.h
gfx/layers/ImageTypes.h
gfx/layers/WaylandDMABUFSurfaceImage.cpp
gfx/layers/WaylandDMABUFSurfaceImage.h
gfx/layers/moz.build
gfx/layers/opengl/WaylandDMABUFTextureClientOGL.h
--- a/gfx/gl/GLBlitHelper.cpp
+++ b/gfx/gl/GLBlitHelper.cpp
@@ -716,17 +716,21 @@ bool GLBlitHelper::BlitImageToFramebuffe
 #else
     case ImageFormat::GPU_VIDEO:
     case ImageFormat::D3D11_SHARE_HANDLE_TEXTURE:
     case ImageFormat::D3D11_YCBCR_IMAGE:
     case ImageFormat::D3D9_RGB32_TEXTURE:
       MOZ_ASSERT(false);
       return false;
 #endif
-
+#ifdef MOZ_WAYLAND
+    case ImageFormat::WAYLAND_DMABUF:
+      MOZ_ASSERT(false);
+      return false;
+#endif
     case ImageFormat::CAIRO_SURFACE:
     case ImageFormat::NV_IMAGE:
     case ImageFormat::OVERLAY_IMAGE:
     case ImageFormat::SHARED_RGB:
     case ImageFormat::TEXTURE_WRAPPER:
       return false;  // todo
   }
   return false;
--- a/gfx/layers/ImageContainer.h
+++ b/gfx/layers/ImageContainer.h
@@ -162,16 +162,18 @@ struct ImageBackendData {
 
 /* Forward declarations for Image derivatives. */
 class GLImage;
 class SharedRGBImage;
 #ifdef MOZ_WIDGET_ANDROID
 class SurfaceTextureImage;
 #elif defined(XP_MACOSX)
 class MacIOSurfaceImage;
+#elif MOZ_WAYLAND
+class WaylandDMABUFSurfaceImage;
 #endif
 
 /**
  * A class representing a buffer of pixel data. The data can be in one
  * of various formats including YCbCr.
  *
  * Create an image using an ImageContainer. Fill the image with data, and
  * then call ImageContainer::SetImage to display it. An image must not be
@@ -222,16 +224,21 @@ class Image {
   virtual GLImage* AsGLImage() { return nullptr; }
 #ifdef MOZ_WIDGET_ANDROID
   virtual SurfaceTextureImage* AsSurfaceTextureImage() { return nullptr; }
 #endif
 #ifdef XP_MACOSX
   virtual MacIOSurfaceImage* AsMacIOSurfaceImage() { return nullptr; }
 #endif
   virtual PlanarYCbCrImage* AsPlanarYCbCrImage() { return nullptr; }
+#ifdef MOZ_WAYLAND
+  virtual WaylandDMABUFSurfaceImage* AsWaylandDMABUFSurfaceImage() {
+    return nullptr;
+  }
+#endif
 
   virtual NVImage* AsNVImage() { return nullptr; }
 
  protected:
   Image(void* aImplData, ImageFormat aFormat)
       : mImplData(aImplData), mSerial(++sSerialCounter), mFormat(aFormat) {}
 
   // Protected destructor, to discourage deletion outside of Release():
--- a/gfx/layers/ImageTypes.h
+++ b/gfx/layers/ImageTypes.h
@@ -84,17 +84,23 @@ enum class ImageFormat {
    * A D3D11 backed YUV image.
    */
   D3D11_YCBCR_IMAGE,
 
   /**
    * An opaque handle that refers to an Image stored in the GPU
    * process.
    */
-  GPU_VIDEO
+  GPU_VIDEO,
+
+  /**
+   * The WAYLAND_DMABUF format creates a SharedDMABUFImage, which stores YUV
+   * data in DMABUF memory. Used on Wayland by VAAPI decoder.
+   */
+  WAYLAND_DMABUF,
 };
 
 enum class StereoMode {
   MONO,
   LEFT_RIGHT,
   RIGHT_LEFT,
   BOTTOM_TOP,
   TOP_BOTTOM,
new file mode 100644
--- /dev/null
+++ b/gfx/layers/WaylandDMABUFSurfaceImage.cpp
@@ -0,0 +1,27 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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 "WaylandDMABUFSurfaceImage.h"
+#include "gfxPlatform.h"
+#include "mozilla/layers/CompositableClient.h"
+#include "mozilla/layers/CompositableForwarder.h"
+#include "mozilla/layers/WaylandDMABUFTextureClientOGL.h"
+#include "mozilla/UniquePtr.h"
+
+using namespace mozilla;
+using namespace mozilla::layers;
+using namespace mozilla::gfx;
+
+TextureClient* WaylandDMABUFSurfaceImage::GetTextureClient(
+    KnowsCompositor* aKnowsCompositor) {
+  if (!mTextureClient) {
+    BackendType backend = BackendType::NONE;
+    mTextureClient = TextureClient::CreateWithData(
+        WaylandDMABUFTextureData::Create(mSurface, backend),
+        TextureFlags::DEFAULT, aKnowsCompositor->GetTextureForwarder());
+  }
+  return mTextureClient;
+}
new file mode 100644
--- /dev/null
+++ b/gfx/layers/WaylandDMABUFSurfaceImage.h
@@ -0,0 +1,66 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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 WAYLAND_SURFACE_DMABUF_H
+#define WAYLAND_SURFACE_DMABUF_H
+
+#include "ImageContainer.h"
+#include "mozilla/widget/WaylandDMABufSurface.h"
+#include "mozilla/gfx/Point.h"
+#include "mozilla/layers/TextureClient.h"
+
+namespace mozilla {
+namespace layers {
+
+// An alias for av_buffer_unref(AVBufferRef**)
+typedef void (*AVFrameReleaseCallback)(void** aFrameRef);
+
+class WaylandDMABUFSurfaceImage : public Image {
+ public:
+  explicit WaylandDMABUFSurfaceImage(WaylandDMABufSurface* aSurface,
+                                     AVFrameReleaseCallback aReleaseCallback,
+                                     void* aDecoder, void* aFrameRef)
+      : Image(nullptr, ImageFormat::WAYLAND_DMABUF),
+        mSurface(aSurface),
+        mReleaseCallback(aReleaseCallback),
+        mFrameRef(aFrameRef) {}
+
+  ~WaylandDMABUFSurfaceImage() {
+    if (mReleaseCallback) {
+      mReleaseCallback(&mFrameRef);
+    }
+  }
+
+  WaylandDMABufSurface* GetSurface() { return mSurface; }
+
+  gfx::IntSize GetSize() const override {
+    return gfx::IntSize::Truncate(mSurface->GetWidth(), mSurface->GetHeight());
+  }
+
+  already_AddRefed<gfx::SourceSurface> GetAsSourceSurface() override {
+    return nullptr;
+  }
+
+  TextureClient* GetTextureClient(KnowsCompositor* aKnowsCompositor) override;
+
+ private:
+  RefPtr<WaylandDMABufSurface> mSurface;
+  RefPtr<TextureClient> mTextureClient;
+
+  // When WaylandDMABUFSurfaceImage is created on top of ffmpeg frame located at
+  // GPU memory we need to keep it until painting of the frame is finished.
+
+  // mReleaseCallback points to av_buffer_unref() from libva library.
+  AVFrameReleaseCallback mReleaseCallback;
+  // AVBufferRef* which points to a frame located at GPU.
+  // We own this reference.
+  void* mFrameRef;
+};
+
+}  // namespace layers
+}  // namespace mozilla
+
+#endif  // WAYLAND_SURFACE_DMABUF_H
--- a/gfx/layers/moz.build
+++ b/gfx/layers/moz.build
@@ -295,20 +295,22 @@ if CONFIG['MOZ_X11']:
         'ipc/ShadowLayerUtilsX11.cpp',
         'opengl/X11TextureSourceOGL.cpp',
     ]
 
 if CONFIG['MOZ_WAYLAND']:
     EXPORTS.mozilla.layers += [
         'opengl/WaylandDMABUFTextureClientOGL.h',
         'opengl/WaylandDMABUFTextureHostOGL.h',
+        'WaylandDMABUFSurfaceImage.h',
     ]
     SOURCES += [
         'opengl/WaylandDMABUFTextureClientOGL.cpp',
         'opengl/WaylandDMABUFTextureHostOGL.cpp',
+        'WaylandDMABUFSurfaceImage.cpp',
     ]
 
 if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
     EXPORTS.mozilla.layers += [
         'NativeLayerCA.h',
         'SurfacePoolCA.h',
         'TextureSync.h',
     ]
--- a/gfx/layers/opengl/WaylandDMABUFTextureClientOGL.h
+++ b/gfx/layers/opengl/WaylandDMABUFTextureClientOGL.h
@@ -14,16 +14,22 @@ class WaylandDMABufSurface;
 namespace mozilla {
 namespace layers {
 
 class WaylandDMABUFTextureData : public TextureData {
  public:
   static WaylandDMABUFTextureData* Create(const gfx::IntSize& aSize,
                                           gfx::SurfaceFormat aFormat,
                                           gfx::BackendType aBackend);
+
+  static WaylandDMABUFTextureData* Create(WaylandDMABufSurface* aSurface,
+                                          gfx::BackendType aBackend) {
+    return new WaylandDMABUFTextureData(aSurface, aBackend);
+  }
+
   ~WaylandDMABUFTextureData();
 
   virtual TextureData* CreateSimilar(
       LayersIPCChannel* aAllocator, LayersBackend aLayersBackend,
       TextureFlags aFlags = TextureFlags::DEFAULT,
       TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT) const override;
 
   void FillInfo(TextureData::Info& aInfo) const override;