firefox/D278449.patch
2026-01-20 08:27:17 +01:00

195 lines
8.1 KiB
Diff

diff --git a/gfx/layers/SurfacePoolWayland.h b/gfx/layers/SurfacePoolWayland.h
--- a/gfx/layers/SurfacePoolWayland.h
+++ b/gfx/layers/SurfacePoolWayland.h
@@ -30,13 +30,15 @@
friend RefPtr<SurfacePool> SurfacePool::Create(size_t aPoolSizeLimit);
explicit SurfacePoolWayland(size_t aPoolSizeLimit);
RefPtr<widget::WaylandBuffer> ObtainBufferFromPool(
+ const widget::WaylandSurfaceLock& aWaylandSurfaceLock,
const gfx::IntSize& aSize, gl::GLContext* aGL,
RefPtr<widget::DRMFormat> aFormat);
- void ReturnBufferToPool(const RefPtr<widget::WaylandBuffer>& aBuffer);
+ void ReturnBufferToPool(const widget::WaylandSurfaceLock& aWaylandSurfaceLock,
+ const RefPtr<widget::WaylandBuffer>& aBuffer);
void EnforcePoolSizeLimit();
void CollectPendingSurfaces();
Maybe<GLuint> GetFramebufferForBuffer(
const RefPtr<widget::WaylandBuffer>& aBuffer, gl::GLContext* aGL,
bool aNeedsDepthBuffer);
@@ -44,20 +46,23 @@
struct GLResourcesForBuffer final {
RefPtr<gl::GLContext> mGL; // non-null
UniquePtr<gl::MozFramebuffer> mFramebuffer; // non-null
};
+ // Keep mWaylandSurface / mWaylandBuffer in pair as we don't share
+ // mWaylandBuffer among WaylandSurfaces.
struct SurfacePoolEntry final {
const gfx::IntSize mSize;
- const RefPtr<widget::WaylandBuffer> mWaylandBuffer; // non-null
+ const RefPtr<widget::WaylandSurface> mWaylandSurface; // non-null
+ const RefPtr<widget::WaylandBuffer> mWaylandBuffer; // non-null
Maybe<GLResourcesForBuffer> mGLResources;
};
- bool CanRecycleSurfaceForRequest(const MutexAutoLock& aProofOfLock,
- const SurfacePoolEntry& aEntry,
- const gfx::IntSize& aSize,
- gl::GLContext* aGL);
+ bool CanRecycleSurfaceForRequest(
+ const MutexAutoLock& aProofOfLock, const SurfacePoolEntry& aEntry,
+ const widget::WaylandSurfaceLock& aWaylandSurfaceLock,
+ const gfx::IntSize& aSize, gl::GLContext* aGL);
RefPtr<gl::DepthAndStencilBuffer> GetDepthBufferForSharing(
const MutexAutoLock& aProofOfLock, gl::GLContext* aGL,
const gfx::IntSize& aSize);
UniquePtr<gl::MozFramebuffer> CreateFramebufferForTexture(
@@ -103,12 +108,14 @@
SurfacePoolHandleWayland* AsSurfacePoolHandleWayland() override {
return this;
}
RefPtr<widget::WaylandBuffer> ObtainBufferFromPool(
+ const widget::WaylandSurfaceLock& aWaylandSurfaceLock,
const gfx::IntSize& aSize, RefPtr<widget::DRMFormat> aFormat);
- void ReturnBufferToPool(const RefPtr<widget::WaylandBuffer>& aBuffer);
+ void ReturnBufferToPool(const widget::WaylandSurfaceLock& aWaylandSurfaceLock,
+ const RefPtr<widget::WaylandBuffer>& aBuffer);
Maybe<GLuint> GetFramebufferForBuffer(
const RefPtr<widget::WaylandBuffer>& aBuffer, bool aNeedsDepthBuffer);
const auto& gl() { return mGL; }
RefPtr<SurfacePool> Pool() override { return mPool; }
diff --git a/gfx/layers/SurfacePoolWayland.cpp b/gfx/layers/SurfacePoolWayland.cpp
--- a/gfx/layers/SurfacePoolWayland.cpp
+++ b/gfx/layers/SurfacePoolWayland.cpp
@@ -71,12 +71,20 @@
[&](const DepthBufferEntry& entry) { return entry.mGL == aGL; });
}
bool SurfacePoolWayland::CanRecycleSurfaceForRequest(
const MutexAutoLock& aProofOfLock, const SurfacePoolEntry& aEntry,
- const IntSize& aSize, GLContext* aGL) {
- MOZ_DIAGNOSTIC_ASSERT(!aEntry.mWaylandBuffer->IsAttached());
+ const widget::WaylandSurfaceLock& aWaylandSurfaceLock, const IntSize& aSize,
+ GLContext* aGL) {
+ if (aEntry.mWaylandSurface != aWaylandSurfaceLock.GetWaylandSurface()) {
+ LOGVERBOSE(
+ "SurfacePoolWayland::CanRecycleSurfaceForRequest(): can't recycle due "
+ "to different WaylandSurface.");
+ return false;
+ }
+ MOZ_DIAGNOSTIC_ASSERT(
+ !aEntry.mWaylandBuffer->IsAttached(aWaylandSurfaceLock));
if (aEntry.mSize != aSize) {
LOGVERBOSE(
"SurfacePoolWayland::CanRecycleSurfaceForRequest(): can't recycle due "
"to different sizes.");
return false;
@@ -93,18 +101,20 @@
aGL == nullptr);
return aGL == nullptr;
}
RefPtr<WaylandBuffer> SurfacePoolWayland::ObtainBufferFromPool(
- const IntSize& aSize, GLContext* aGL, RefPtr<widget::DRMFormat> aFormat) {
+ const widget::WaylandSurfaceLock& aWaylandSurfaceLock, const IntSize& aSize,
+ GLContext* aGL, RefPtr<widget::DRMFormat> aFormat) {
MutexAutoLock lock(mMutex);
- auto iterToRecycle = std::find_if(
- mAvailableEntries.begin(), mAvailableEntries.end(),
- [&](const SurfacePoolEntry& aEntry) {
- return CanRecycleSurfaceForRequest(lock, aEntry, aSize, aGL);
- });
+ auto iterToRecycle =
+ std::find_if(mAvailableEntries.begin(), mAvailableEntries.end(),
+ [&](const SurfacePoolEntry& aEntry) {
+ return CanRecycleSurfaceForRequest(
+ lock, aEntry, aWaylandSurfaceLock, aSize, aGL);
+ });
if (iterToRecycle != mAvailableEntries.end()) {
RefPtr<WaylandBuffer> buffer = iterToRecycle->mWaylandBuffer;
mInUseEntries.insert({buffer.get(), std::move(*iterToRecycle)});
mAvailableEntries.RemoveElementAt(iterToRecycle);
LOGVERBOSE(
@@ -123,28 +133,32 @@
} else {
buffer = widget::WaylandBufferSHM::Create(
LayoutDeviceIntSize::FromUnknownSize(aSize));
}
if (buffer) {
- mInUseEntries.insert({buffer.get(), SurfacePoolEntry{aSize, buffer, {}}});
+ mInUseEntries.insert(
+ {buffer.get(),
+ SurfacePoolEntry{
+ aSize, aWaylandSurfaceLock.GetWaylandSurface(), buffer, {}}});
}
LOGVERBOSE(
"SurfacePoolWayland::ObtainBufferFromPool() created [%p] U[%d] P[%d] "
"A[%d]",
buffer.get(), (int)mInUseEntries.size(), (int)mPendingEntries.Length(),
(int)mAvailableEntries.Length());
return buffer;
}
void SurfacePoolWayland::ReturnBufferToPool(
+ const widget::WaylandSurfaceLock& aWaylandSurfaceLock,
const RefPtr<WaylandBuffer>& aBuffer) {
MutexAutoLock lock(mMutex);
auto inUseEntryIter = mInUseEntries.find(aBuffer);
MOZ_RELEASE_ASSERT(inUseEntryIter != mInUseEntries.end());
- if (aBuffer->IsAttached()) {
+ if (aBuffer->IsAttached(aWaylandSurfaceLock)) {
mPendingEntries.AppendElement(std::move(inUseEntryIter->second));
} else {
mAvailableEntries.AppendElement(std::move(inUseEntryIter->second));
}
mInUseEntries.erase(inUseEntryIter);
@@ -177,14 +191,15 @@
}
void SurfacePoolWayland::CollectPendingSurfaces() {
MutexAutoLock lock(mMutex);
mPendingEntries.RemoveElementsBy([&](auto& entry) {
+ widget::WaylandSurfaceLock lock(entry.mWaylandSurface);
LOGVERBOSE(
"SurfacePoolWayland::CollectPendingSurfaces() [%p] attached [%d]",
- entry.mWaylandBuffer.get(), entry.mWaylandBuffer->IsAttached());
- if (!entry.mWaylandBuffer->IsAttached()) {
+ entry.mWaylandBuffer.get(), entry.mWaylandBuffer->IsAttached(lock));
+ if (!entry.mWaylandBuffer->IsAttached(lock)) {
mAvailableEntries.AppendElement(std::move(entry));
return true;
}
return false;
});
@@ -282,17 +297,19 @@
}
void SurfacePoolHandleWayland::OnEndFrame() { mPool->EnforcePoolSizeLimit(); }
RefPtr<WaylandBuffer> SurfacePoolHandleWayland::ObtainBufferFromPool(
- const IntSize& aSize, RefPtr<widget::DRMFormat> aFormat) {
- return mPool->ObtainBufferFromPool(aSize, mGL, aFormat);
+ const widget::WaylandSurfaceLock& aWaylandSurfaceLock, const IntSize& aSize,
+ RefPtr<widget::DRMFormat> aFormat) {
+ return mPool->ObtainBufferFromPool(aWaylandSurfaceLock, aSize, mGL, aFormat);
}
void SurfacePoolHandleWayland::ReturnBufferToPool(
+ const widget::WaylandSurfaceLock& aProofOfLock,
const RefPtr<WaylandBuffer>& aBuffer) {
- mPool->ReturnBufferToPool(aBuffer);
+ mPool->ReturnBufferToPool(aProofOfLock, aBuffer);
}
Maybe<GLuint> SurfacePoolHandleWayland::GetFramebufferForBuffer(
const RefPtr<WaylandBuffer>& aBuffer, bool aNeedsDepthBuffer) {
return mPool->GetFramebufferForBuffer(aBuffer, mGL, aNeedsDepthBuffer);