diff options
Diffstat (limited to 'mozilla-1619882-1.patch')
-rw-r--r-- | mozilla-1619882-1.patch | 216 |
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( |