Blob Blame History Raw
diff --git a/widget/gtk/DMABufSurface.h b/widget/gtk/DMABufSurface.h
--- a/widget/gtk/DMABufSurface.h
+++ b/widget/gtk/DMABufSurface.h
@@ -173,13 +173,13 @@
   SurfaceType mSurfaceType;
   uint64_t mBufferModifiers[DMABUF_BUFFER_PLANES];
 
   int mBufferPlaneCount;
   int mDmabufFds[DMABUF_BUFFER_PLANES];
-  uint32_t mDrmFormats[DMABUF_BUFFER_PLANES];
-  uint32_t mStrides[DMABUF_BUFFER_PLANES];
-  uint32_t mOffsets[DMABUF_BUFFER_PLANES];
+  int32_t mDrmFormats[DMABUF_BUFFER_PLANES];
+  int32_t mStrides[DMABUF_BUFFER_PLANES];
+  int32_t mOffsets[DMABUF_BUFFER_PLANES];
 
   struct gbm_bo* mGbmBufferObject[DMABUF_BUFFER_PLANES];
   void* mMappedRegion[DMABUF_BUFFER_PLANES];
   void* mMappedRegionData[DMABUF_BUFFER_PLANES];
   uint32_t mMappedRegionStride[DMABUF_BUFFER_PLANES];
@@ -198,10 +198,14 @@
 class DMABufSurfaceRGBA : public DMABufSurface {
  public:
   static already_AddRefed<DMABufSurfaceRGBA> CreateDMABufSurface(
       int aWidth, int aHeight, int aDMABufSurfaceFlags);
 
+  static already_AddRefed<DMABufSurface> CreateDMABufSurface(
+      mozilla::gl::GLContext* aGLContext, const EGLImageKHR aEGLImage,
+      int aWidth, int aHeight);
+
   bool Serialize(mozilla::layers::SurfaceDescriptor& aOutDescriptor);
 
   DMABufSurfaceRGBA* GetAsDMABufSurfaceRGBA() { return this; }
 
   void Clear();
@@ -247,10 +251,12 @@
  private:
   ~DMABufSurfaceRGBA();
 
   bool Create(int aWidth, int aHeight, int aDMABufSurfaceFlags);
   bool Create(const mozilla::layers::SurfaceDescriptor& aDesc);
+  bool Create(mozilla::gl::GLContext* aGLContext, const EGLImageKHR aEGLImage,
+              int aWidth, int aHeight);
 
   bool ImportSurfaceDescriptor(const mozilla::layers::SurfaceDescriptor& aDesc);
 
   bool OpenFileDescriptorForPlane(const mozilla::MutexAutoLock& aProofOfLock,
                                   int aPlane);
diff --git a/widget/gtk/DMABufSurface.cpp b/widget/gtk/DMABufSurface.cpp
--- a/widget/gtk/DMABufSurface.cpp
+++ b/widget/gtk/DMABufSurface.cpp
@@ -204,10 +204,12 @@
   }
 }
 
 void DMABufSurface::FenceSet() {
   if (!mGL || !mGL->MakeCurrent()) {
+    MOZ_DIAGNOSTIC_ASSERT(mGL,
+                          "DMABufSurface::FenceSet(): missing GL context!");
     return;
   }
   const auto& gle = gl::GLContextEGL::Cast(mGL);
   const auto& egl = gle->mEgl;
 
@@ -228,21 +230,23 @@
   mGL->fFinish();
 }
 
 void DMABufSurface::FenceWait() {
   if (!mGL || mSyncFd < 0) {
+    MOZ_DIAGNOSTIC_ASSERT(mGL,
+                          "DMABufSurface::FenceWait() missing GL context!");
     return;
   }
 
   const auto& gle = gl::GLContextEGL::Cast(mGL);
   const auto& egl = gle->mEgl;
 
   const EGLint attribs[] = {LOCAL_EGL_SYNC_NATIVE_FENCE_FD_ANDROID, mSyncFd,
                             LOCAL_EGL_NONE};
   EGLSync sync = egl->fCreateSync(LOCAL_EGL_SYNC_NATIVE_FENCE_ANDROID, attribs);
   if (!sync) {
-    MOZ_ASSERT(false, "Failed to create GLFence!");
+    MOZ_ASSERT(false, "DMABufSurface::FenceWait(): Failed to create GLFence!");
     // We failed to create GLFence so clear mSyncFd to avoid another try.
     close(mSyncFd);
     mSyncFd = -1;
     return;
   }
@@ -338,17 +342,18 @@
   mGmbFormat = GetDMABufDevice()->GetGbmFormat(mSurfaceFlags & DMABUF_ALPHA);
   if (!mGmbFormat) {
     // Requested DRM format is not supported.
     return false;
   }
+  mDrmFormats[0] = mGmbFormat->mFormat;
 
   bool useModifiers = (aDMABufSurfaceFlags & DMABUF_USE_MODIFIERS) &&
                       mGmbFormat->mModifiersCount > 0;
   if (useModifiers) {
     LOGDMABUF(("    Creating with modifiers\n"));
     mGbmBufferObject[0] = nsGbmLib::CreateWithModifiers(
-        GetDMABufDevice()->GetGbmDevice(), mWidth, mHeight, mGmbFormat->mFormat,
+        GetDMABufDevice()->GetGbmDevice(), mWidth, mHeight, mDrmFormats[0],
         mGmbFormat->mModifiers, mGmbFormat->mModifiersCount);
     if (mGbmBufferObject[0]) {
       mBufferModifiers[0] = nsGbmLib::GetModifier(mGbmBufferObject[0]);
     }
   }
@@ -356,11 +361,11 @@
   if (!mGbmBufferObject[0]) {
     LOGDMABUF(("    Creating without modifiers\n"));
     mGbmBufferFlags = GBM_BO_USE_LINEAR;
     mGbmBufferObject[0] =
         nsGbmLib::Create(GetDMABufDevice()->GetGbmDevice(), mWidth, mHeight,
-                         mGmbFormat->mFormat, mGbmBufferFlags);
+                         mDrmFormats[0], mGbmBufferFlags);
     mBufferModifiers[0] = DRM_FORMAT_MOD_INVALID;
   }
 
   if (!mGbmBufferObject[0]) {
     LOGDMABUF(("    Failed to create GbmBufferObject\n"));
@@ -386,22 +391,51 @@
 
   LOGDMABUF(("    Success\n"));
   return true;
 }
 
+bool DMABufSurfaceRGBA::Create(mozilla::gl::GLContext* aGLContext,
+                               const EGLImageKHR aEGLImage, int aWidth,
+                               int aHeight) {
+  LOGDMABUF(("DMABufSurfaceRGBA::Create() from EGLImage UID = %d\n", mUID));
+  if (!aGLContext) {
+    return false;
+  }
+  const auto& gle = gl::GLContextEGL::Cast(aGLContext);
+  const auto& egl = gle->mEgl;
+
+  mGL = aGLContext;
+  mWidth = aWidth;
+  mHeight = aHeight;
+  mEGLImage = aEGLImage;
+  if (!egl->fExportDMABUFImageQuery(mEGLImage, mDrmFormats, &mBufferPlaneCount,
+                                    mBufferModifiers)) {
+    LOGDMABUF(("  ExportDMABUFImageQueryMESA failed, quit\n"));
+    return false;
+  }
+  if (mBufferPlaneCount > DMABUF_BUFFER_PLANES) {
+    LOGDMABUF(("  wrong plane count %d, quit\n", mBufferPlaneCount));
+    return false;
+  }
+  if (!egl->fExportDMABUFImage(mEGLImage, mDmabufFds, mStrides, mOffsets)) {
+    LOGDMABUF(("  ExportDMABUFImageMESA failed, quit\n"));
+    return false;
+  }
+
+  LOGDMABUF(("  imported size %d x %d format %x planes %d", mWidth, mHeight,
+             mDrmFormats[0], mBufferPlaneCount));
+  return true;
+}
+
 bool DMABufSurfaceRGBA::ImportSurfaceDescriptor(
     const SurfaceDescriptor& aDesc) {
   const SurfaceDescriptorDMABuf& desc = aDesc.get_SurfaceDescriptorDMABuf();
 
   mWidth = desc.width()[0];
   mHeight = desc.height()[0];
   mBufferModifiers[0] = desc.modifier()[0];
-  if (mBufferModifiers[0] != DRM_FORMAT_MOD_INVALID) {
-    mGmbFormat = GetDMABufDevice()->GetExactGbmFormat(desc.format()[0]);
-  } else {
-    mDrmFormats[0] = desc.format()[0];
-  }
+  mDrmFormats[0] = desc.format()[0];
   mBufferPlaneCount = desc.fds().Length();
   mGbmBufferFlags = desc.flags();
   MOZ_RELEASE_ASSERT(mBufferPlaneCount <= DMABUF_BUFFER_PLANES);
   mUID = desc.uid();
 
@@ -431,10 +465,12 @@
 
   if (desc.refCount().Length() > 0) {
     GlobalRefCountImport(desc.refCount()[0].ClonePlatformHandle().release());
   }
 
+  LOGDMABUF(("  imported size %d x %d format %x planes %d", mWidth, mHeight,
+             mDrmFormats[0], mBufferPlaneCount));
   return true;
 }
 
 bool DMABufSurfaceRGBA::Create(const SurfaceDescriptor& aDesc) {
   return ImportSurfaceDescriptor(aDesc);
@@ -460,11 +496,11 @@
     return false;
   }
 
   width.AppendElement(mWidth);
   height.AppendElement(mHeight);
-  format.AppendElement(mGmbFormat->mFormat);
+  format.AppendElement(mDrmFormats[0]);
   modifiers.AppendElement(mBufferModifiers[0]);
   for (int i = 0; i < mBufferPlaneCount; i++) {
     fds.AppendElement(ipc::FileDescriptor(mDmabufFds[i]));
     strides.AppendElement(mStrides[i]);
     offsets.AppendElement(mOffsets[i]);
@@ -486,23 +522,20 @@
       fenceFDs, mUID, refCountFDs);
   return true;
 }
 
 bool DMABufSurfaceRGBA::CreateTexture(GLContext* aGLContext, int aPlane) {
+  LOGDMABUF(("DMABufSurfaceRGBA::CreateTexture() UID %d\n", mUID));
   MOZ_ASSERT(!mEGLImage && !mTexture, "EGLImage is already created!");
 
   nsTArray<EGLint> attribs;
   attribs.AppendElement(LOCAL_EGL_WIDTH);
   attribs.AppendElement(mWidth);
   attribs.AppendElement(LOCAL_EGL_HEIGHT);
   attribs.AppendElement(mHeight);
   attribs.AppendElement(LOCAL_EGL_LINUX_DRM_FOURCC_EXT);
-  if (mGmbFormat) {
-    attribs.AppendElement(mGmbFormat->mFormat);
-  } else {
-    attribs.AppendElement(mDrmFormats[0]);
-  }
+  attribs.AppendElement(mDrmFormats[0]);
 #define ADD_PLANE_ATTRIBS(plane_idx)                                        \
   {                                                                         \
     attribs.AppendElement(LOCAL_EGL_DMA_BUF_PLANE##plane_idx##_FD_EXT);     \
     attribs.AppendElement(mDmabufFds[plane_idx]);                           \
     attribs.AppendElement(LOCAL_EGL_DMA_BUF_PLANE##plane_idx##_OFFSET_EXT); \
@@ -560,10 +593,11 @@
 
   return true;
 }
 
 void DMABufSurfaceRGBA::ReleaseTextures() {
+  LOGDMABUF(("DMABufSurfaceRGBA::ReleaseTextures() UID %d\n", mUID));
   FenceDelete();
 
   if (!mTexture) {
     return;
   }
@@ -618,11 +652,11 @@
   zwp_linux_buffer_params_v1_add(params, mDmabufFds[0], 0, mOffsets[0],
                                  mStrides[0], mBufferModifiers[0] >> 32,
                                  mBufferModifiers[0] & 0xffffffff);
 
   mWlBuffer = zwp_linux_buffer_params_v1_create_immed(
-      params, GetWidth(), GetHeight(), mGmbFormat->mFormat, 0);
+      params, GetWidth(), GetHeight(), mDrmFormats[0], 0);
 
   CloseFileDescriptors(lockFD);
 
   return mWlBuffer != nullptr;
 }
@@ -806,10 +840,20 @@
     return nullptr;
   }
   return surf.forget();
 }
 
+already_AddRefed<DMABufSurface> DMABufSurfaceRGBA::CreateDMABufSurface(
+    mozilla::gl::GLContext* aGLContext, const EGLImageKHR aEGLImage, int aWidth,
+    int aHeight) {
+  RefPtr<DMABufSurfaceRGBA> surf = new DMABufSurfaceRGBA();
+  if (!surf->Create(aGLContext, aEGLImage, aWidth, aHeight)) {
+    return nullptr;
+  }
+  return surf.forget();
+}
+
 already_AddRefed<DMABufSurfaceYUV> DMABufSurfaceYUV::CreateYUVSurface(
     const VADRMPRIMESurfaceDescriptor& aDesc, int aWidth, int aHeight) {
   RefPtr<DMABufSurfaceYUV> surf = new DMABufSurfaceYUV();
   LOGDMABUF(("DMABufSurfaceYUV::CreateYUVSurface() UID %d from desc\n",
              surf->GetUID()));