195 lines
8.1 KiB
Diff
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);
|
|
|