summaryrefslogtreecommitdiff
path: root/mozilla-1619882-1.patch
diff options
context:
space:
mode:
Diffstat (limited to 'mozilla-1619882-1.patch')
-rw-r--r--mozilla-1619882-1.patch216
1 files changed, 112 insertions, 104 deletions
diff --git a/mozilla-1619882-1.patch b/mozilla-1619882-1.patch
index 25ff321..3f4cbda 100644
--- a/mozilla-1619882-1.patch
+++ b/mozilla-1619882-1.patch
@@ -13,60 +13,75 @@ diff --git a/gfx/layers/ipc/LayersSurfaces.ipdlh b/gfx/layers/ipc/LayersSurfaces
diff --git a/widget/gtk/WaylandDMABufSurface.h b/widget/gtk/WaylandDMABufSurface.h
--- a/widget/gtk/WaylandDMABufSurface.h
+++ b/widget/gtk/WaylandDMABufSurface.h
-@@ -40,6 +40,23 @@
+@@ -49,9 +49,14 @@
+ SURFACE_NV12,
+ };
- class WaylandDMABufSurfaceRGBA;
++ // Import surface from SurfaceDescriptor. This is usually
++ // used to copy surface from another process over IPC.
++ // When a global reference counter was created for the surface
++ // (see bellow) it's automatically referenced.
+ static already_AddRefed<WaylandDMABufSurface> CreateDMABufSurface(
+ const mozilla::layers::SurfaceDescriptor& aDesc);
-+class DMABufRefcount {
-+ public:
-+ DMABufRefcount();
-+ DMABufRefcount(int aFd);
-+
-+ bool Created() { return mFd > 0; };
-+ int GetFD() { return mFd; }
-+ uint64_t GetRefcount();
-+ void RefAdd();
-+ void Release();
-+
-+ ~DMABufRefcount();
-+
-+ private:
-+ int mFd;
-+};
-+
- class WaylandDMABufSurface {
- public:
- NS_INLINE_DECL_THREADSAFE_REFCOUNTING(WaylandDMABufSurface)
-@@ -82,6 +99,14 @@
++ // Export surface to another process via. SurfaceDescriptor.
+ virtual bool Serialize(
+ mozilla::layers::SurfaceDescriptor& aOutDescriptor) = 0;
+
+@@ -82,6 +87,35 @@
void FenceWait();
void FenceDelete();
++ // Set and get a global surface UID. The UID is shared across process
++ // and it's used to track surface lifetime in various parts of rendering
++ // engine.
+ void SetUID(uint32_t aUID) { mUID = aUID; };
-+ uint32_t GetUID() { return mUID; };
++ uint32_t GetUID() const { return mUID; };
+
++ // Creates a global reference counter objects attached to the surface.
++ // It's created as unreferenced, i.e. IsGlobalRefSet() returns false
++ // right after GlobalRefCountCreate() call.
++ //
++ // The counter is shared by all surface instances across processes
++ // so it tracks global surface usage.
++ //
++ // The counter is automatically referenced when a new surface instance is
++ // created with SurfaceDescriptor (usually copied to another process over IPC)
++ // and it's unreferenced when surface is deleted.
++ //
++ // So without any additional GlobalRefAdd()/GlobalRefRelease() calls
++ // the IsGlobalRefSet() returns true if any other process use the surface.
+ void GlobalRefCountCreate();
-+ bool IsGlobalRefSet();
++
++ // If global reference counter was created by GlobalRefCountCreate()
++ // returns true when there's an active surface reference.
++ bool IsGlobalRefSet() const;
++
++ // Add/Remove additional reference to the surface global reference counter.
+ void GlobalRefAdd();
+ void GlobalRefRelease();
+
WaylandDMABufSurface(SurfaceType aSurfaceType);
protected:
-@@ -89,6 +114,8 @@
+@@ -89,7 +123,10 @@
virtual void ReleaseSurface() = 0;
bool FenceCreate(int aFd);
-+ bool GlobalRefCountImport(int aFd);
+- virtual ~WaylandDMABufSurface() { FenceDelete(); };
++ void GlobalRefCountImport(int aFd);
++ void GlobalRefCountDelete();
+
- virtual ~WaylandDMABufSurface() { FenceDelete(); };
++ virtual ~WaylandDMABufSurface();
SurfaceType mSurfaceType;
-@@ -102,6 +129,9 @@
+ uint64_t mBufferModifier;
+@@ -102,6 +139,9 @@
EGLSyncKHR mSync;
RefPtr<mozilla::gl::GLContext> mGL;
+
-+ mozilla::UniquePtr<DMABufRefcount> mGlobalRefCount;
++ int mGlobalRefCountFd;
+ uint32_t mUID;
};
@@ -74,101 +89,100 @@ diff --git a/widget/gtk/WaylandDMABufSurface.h b/widget/gtk/WaylandDMABufSurface
diff --git a/widget/gtk/WaylandDMABufSurface.cpp b/widget/gtk/WaylandDMABufSurface.cpp
--- a/widget/gtk/WaylandDMABufSurface.cpp
+++ b/widget/gtk/WaylandDMABufSurface.cpp
-@@ -17,6 +17,8 @@
+@@ -17,6 +17,9 @@
#include <unistd.h>
#include <sys/time.h>
#include <dlfcn.h>
+#include <sys/mman.h>
+#include <sys/eventfd.h>
++#include <poll.h>
#include "mozilla/widget/gbm.h"
#include "mozilla/widget/va_drmcommon.h"
-@@ -57,6 +59,73 @@
+@@ -57,6 +60,61 @@
# define VA_FOURCC_NV12 0x3231564E
#endif
-+void DMABufRefcount::RefAdd() {
-+ uint64_t counter;
-+ read(mFd, &counter, sizeof(counter));
-+ counter++;
-+ write(mFd, &counter, sizeof(counter));
-+}
-+
-+void DMABufRefcount::Release() {
-+ uint64_t counter;
-+ read(mFd, &counter, sizeof(counter));
-+ counter--;
-+ write(mFd, &counter, sizeof(counter));
++bool WaylandDMABufSurface::IsGlobalRefSet() const {
++ if (!mGlobalRefCountFd) {
++ return false;
++ }
++ struct pollfd pfd;
++ pfd.fd = mGlobalRefCountFd;
++ pfd.events = POLLIN;
++ return poll(&pfd, 1, 0) == 1;
+}
+
-+uint64_t DMABufRefcount::GetRefcount() {
++void WaylandDMABufSurface::GlobalRefRelease() {
++ MOZ_ASSERT(mGlobalRefCountFd);
+ uint64_t counter;
-+ read(mFd, &counter, sizeof(counter));
-+ write(mFd, &counter, sizeof(counter));
-+ return counter;
++ if (read(mGlobalRefCountFd, &counter, sizeof(counter)) != sizeof(counter)) {
++ // EAGAIN means the refcount is already zero. It happens when we release
++ // last reference to the surface.
++ if (errno != EAGAIN) {
++ NS_WARNING("Failed to unref dmabuf global ref count!");
++ }
++ }
+}
+
-+DMABufRefcount::DMABufRefcount()
-+ : mFd(eventfd(1, EFD_CLOEXEC | EFD_NONBLOCK)) {}
-+
-+DMABufRefcount::DMABufRefcount(int aFd) : mFd(aFd) {}
-+
-+DMABufRefcount::~DMABufRefcount() {
-+ if (mFd > 0) {
-+ close(mFd);
++void WaylandDMABufSurface::GlobalRefAdd() {
++ MOZ_ASSERT(mGlobalRefCountFd);
++ uint64_t counter = 1;
++ if (write(mGlobalRefCountFd, &counter, sizeof(counter)) != sizeof(counter)) {
++ NS_WARNING("Failed to ref dmabuf global ref count!");
+ }
+}
+
+void WaylandDMABufSurface::GlobalRefCountCreate() {
-+ MOZ_ASSERT(!mGlobalRefCount);
-+ mGlobalRefCount = MakeUnique<DMABufRefcount>();
-+ if (!mGlobalRefCount->Created()) {
++ MOZ_ASSERT(!mGlobalRefCountFd);
++ mGlobalRefCountFd = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK | EFD_SEMAPHORE);
++ if (mGlobalRefCountFd < 0) {
+ NS_WARNING("Failed to create dmabuf global ref count!");
-+ mGlobalRefCount = nullptr;
++ mGlobalRefCountFd = 0;
++ return;
+ }
+}
+
-+bool WaylandDMABufSurface::GlobalRefCountImport(int aFd) {
-+ MOZ_ASSERT(!mGlobalRefCount);
-+ mGlobalRefCount = MakeUnique<DMABufRefcount>(aFd);
-+ if (!mGlobalRefCount->Created()) {
-+ NS_WARNING("Failed to import dmabuf global ref count!");
-+ mGlobalRefCount = nullptr;
-+ return false;
-+ }
-+ return true;
-+}
-+
-+bool WaylandDMABufSurface::IsGlobalRefSet() {
-+ MOZ_ASSERT(mGlobalRefCount);
-+ return mGlobalRefCount->GetRefcount() > 1;
-+}
-+
-+void WaylandDMABufSurface::GlobalRefAdd() {
-+ MOZ_ASSERT(mGlobalRefCount);
-+ mGlobalRefCount->RefAdd();
++void WaylandDMABufSurface::GlobalRefCountImport(int aFd) {
++ MOZ_ASSERT(!mGlobalRefCountFd);
++ mGlobalRefCountFd = aFd;
++ GlobalRefAdd();
+}
+
-+void WaylandDMABufSurface::GlobalRefRelease() {
-+ MOZ_ASSERT(mGlobalRefCount);
-+ mGlobalRefCount->Release();
++void WaylandDMABufSurface::GlobalRefCountDelete() {
++ MOZ_ASSERT(mGlobalRefCountFd);
++ if (mGlobalRefCountFd) {
++ GlobalRefRelease();
++ close(mGlobalRefCountFd);
++ mGlobalRefCountFd = 0;
++ }
+}
+
WaylandDMABufSurface::WaylandDMABufSurface(SurfaceType aSurfaceType)
: mSurfaceType(aSurfaceType),
mBufferModifier(DRM_FORMAT_MOD_INVALID),
-@@ -64,7 +133,9 @@
+@@ -64,12 +122,19 @@
mDrmFormats(),
mStrides(),
mOffsets(),
- mSync(0) {
+ mSync(0),
-+ mGlobalRefCount(nullptr),
++ mGlobalRefCountFd(0),
+ mUID(0) {
for (auto& slot : mDmabufFds) {
slot = -1;
}
-@@ -316,6 +387,7 @@
+ }
+
++WaylandDMABufSurface::~WaylandDMABufSurface() {
++ FenceDelete();
++ GlobalRefCountDelete();
++}
++
+ already_AddRefed<WaylandDMABufSurface>
+ WaylandDMABufSurface::CreateDMABufSurface(
+ const mozilla::layers::SurfaceDescriptor& aDesc) {
+@@ -316,6 +381,7 @@
mBufferPlaneCount = desc.fds().Length();
mGbmBufferFlags = desc.flags();
MOZ_RELEASE_ASSERT(mBufferPlaneCount <= DMABUF_BUFFER_PLANES);
@@ -176,21 +190,18 @@ diff --git a/widget/gtk/WaylandDMABufSurface.cpp b/widget/gtk/WaylandDMABufSurfa
for (int i = 0; i < mBufferPlaneCount; i++) {
mDmabufFds[i] = desc.fds()[i].ClonePlatformHandle().release();
-@@ -329,6 +401,13 @@
+@@ -329,6 +395,10 @@
close(fd);
}
}
+
+ if (desc.refCount().Length() > 0) {
-+ int fd = desc.refCount()[0].ClonePlatformHandle().release();
-+ if (!GlobalRefCountImport(fd)) {
-+ close(fd);
-+ }
++ GlobalRefCountImport(desc.refCount()[0].ClonePlatformHandle().release());
+ }
}
bool WaylandDMABufSurfaceRGBA::Create(const SurfaceDescriptor& aDesc) {
-@@ -346,6 +425,7 @@
+@@ -346,6 +416,7 @@
AutoTArray<uint32_t, DMABUF_BUFFER_PLANES> offsets;
AutoTArray<uintptr_t, DMABUF_BUFFER_PLANES> images;
AutoTArray<ipc::FileDescriptor, 1> fenceFDs;
@@ -198,15 +209,15 @@ diff --git a/widget/gtk/WaylandDMABufSurface.cpp b/widget/gtk/WaylandDMABufSurfa
width.AppendElement(mWidth);
height.AppendElement(mHeight);
-@@ -362,9 +442,14 @@
+@@ -362,9 +433,14 @@
egl->fDupNativeFenceFDANDROID(egl->Display(), mSync)));
}
- aOutDescriptor = SurfaceDescriptorDMABuf(
- mSurfaceType, mBufferModifier, mGbmBufferFlags, fds, width, height,
- format, strides, offsets, GetYUVColorSpace(), fenceFDs);
-+ if (mGlobalRefCount) {
-+ refCountFDs.AppendElement(ipc::FileDescriptor(mGlobalRefCount->GetFD()));
++ if (mGlobalRefCountFd) {
++ refCountFDs.AppendElement(ipc::FileDescriptor(mGlobalRefCountFd));
+ }
+
+ aOutDescriptor =
@@ -216,7 +227,7 @@ diff --git a/widget/gtk/WaylandDMABufSurface.cpp b/widget/gtk/WaylandDMABufSurfa
return true;
}
-@@ -693,6 +778,7 @@
+@@ -693,6 +769,7 @@
mBufferPlaneCount = aDesc.fds().Length();
mBufferModifier = aDesc.modifier();
mColorSpace = aDesc.yUVColorSpace();
@@ -224,21 +235,18 @@ diff --git a/widget/gtk/WaylandDMABufSurface.cpp b/widget/gtk/WaylandDMABufSurfa
MOZ_RELEASE_ASSERT(mBufferPlaneCount <= DMABUF_BUFFER_PLANES);
for (int i = 0; i < mBufferPlaneCount; i++) {
-@@ -710,6 +796,13 @@
+@@ -710,6 +787,10 @@
close(fd);
}
}
+
+ if (aDesc.refCount().Length() > 0) {
-+ int fd = aDesc.refCount()[0].ClonePlatformHandle().release();
-+ if (!GlobalRefCountImport(fd)) {
-+ close(fd);
-+ }
++ GlobalRefCountImport(aDesc.refCount()[0].ClonePlatformHandle().release());
+ }
}
bool WaylandDMABufSurfaceNV12::Serialize(
-@@ -721,6 +814,7 @@
+@@ -721,6 +802,7 @@
AutoTArray<uint32_t, DMABUF_BUFFER_PLANES> strides;
AutoTArray<uint32_t, DMABUF_BUFFER_PLANES> offsets;
AutoTArray<ipc::FileDescriptor, 1> fenceFDs;
@@ -246,12 +254,12 @@ diff --git a/widget/gtk/WaylandDMABufSurface.cpp b/widget/gtk/WaylandDMABufSurfa
for (int i = 0; i < mBufferPlaneCount; i++) {
width.AppendElement(mWidth[i]);
-@@ -737,9 +831,13 @@
+@@ -737,9 +819,13 @@
egl->fDupNativeFenceFDANDROID(egl->Display(), mSync)));
}
-+ if (mGlobalRefCount) {
-+ refCountFDs.AppendElement(ipc::FileDescriptor(mGlobalRefCount->GetFD()));
++ if (mGlobalRefCountFd) {
++ refCountFDs.AppendElement(ipc::FileDescriptor(mGlobalRefCountFd));
+ }
+
aOutDescriptor = SurfaceDescriptorDMABuf(
bgstack15