summaryrefslogtreecommitdiffstats
path: root/gfx/layers/SurfacePoolWayland.h
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--gfx/layers/SurfacePoolWayland.h127
1 files changed, 127 insertions, 0 deletions
diff --git a/gfx/layers/SurfacePoolWayland.h b/gfx/layers/SurfacePoolWayland.h
new file mode 100644
index 0000000000..6a746e732c
--- /dev/null
+++ b/gfx/layers/SurfacePoolWayland.h
@@ -0,0 +1,127 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_layers_SurfacePoolWayland_h
+#define mozilla_layers_SurfacePoolWayland_h
+
+#include <wayland-egl.h>
+
+#include "GLContext.h"
+#include "MozFramebuffer.h"
+#include "mozilla/layers/SurfacePool.h"
+#include "mozilla/widget/WaylandBuffer.h"
+
+#include <unordered_map>
+
+namespace mozilla::layers {
+
+class SurfacePoolWayland final : public SurfacePool {
+ public:
+ // Get a handle for a new window. aGL can be nullptr.
+ RefPtr<SurfacePoolHandle> GetHandleForGL(gl::GLContext* aGL) override;
+
+ // Destroy all GL resources associated with aGL managed by this pool.
+ void DestroyGLResourcesForContext(gl::GLContext* aGL) override;
+
+ private:
+ friend class SurfacePoolHandleWayland;
+ friend RefPtr<SurfacePool> SurfacePool::Create(size_t aPoolSizeLimit);
+
+ explicit SurfacePoolWayland(size_t aPoolSizeLimit);
+
+ RefPtr<widget::WaylandBuffer> ObtainBufferFromPool(const gfx::IntSize& aSize,
+ gl::GLContext* aGL);
+ void ReturnBufferToPool(const RefPtr<widget::WaylandBuffer>& aBuffer);
+ void EnforcePoolSizeLimit();
+ void CollectPendingSurfaces();
+ Maybe<GLuint> GetFramebufferForBuffer(
+ const RefPtr<widget::WaylandBuffer>& aBuffer, gl::GLContext* aGL,
+ bool aNeedsDepthBuffer);
+
+ struct GLResourcesForBuffer final {
+ RefPtr<gl::GLContext> mGL; // non-null
+ UniquePtr<gl::MozFramebuffer> mFramebuffer; // non-null
+ };
+
+ struct SurfacePoolEntry final {
+ const gfx::IntSize mSize;
+ 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);
+
+ RefPtr<gl::DepthAndStencilBuffer> GetDepthBufferForSharing(
+ const MutexAutoLock& aProofOfLock, gl::GLContext* aGL,
+ const gfx::IntSize& aSize);
+ UniquePtr<gl::MozFramebuffer> CreateFramebufferForTexture(
+ const MutexAutoLock& aProofOfLock, gl::GLContext* aGL,
+ const gfx::IntSize& aSize, GLuint aTexture, bool aNeedsDepthBuffer);
+
+ Mutex mMutex MOZ_UNANNOTATED;
+
+ // Stores the entries for surfaces that are in use by NativeLayerWayland, i.e.
+ // an entry is inside mInUseEntries between calls to ObtainSurfaceFromPool()
+ // and ReturnSurfaceToPool().
+ std::unordered_map<widget::WaylandBuffer*, SurfacePoolEntry> mInUseEntries;
+
+ // Stores entries which are no longer in use by NativeLayerWayland but are
+ // still in use by the window server, i.e. for which
+ // WaylandBuffer::IsAttached() still returns true.
+ // These entries are checked once per frame inside
+ // CollectPendingSurfaces(), and returned to mAvailableEntries once the
+ // window server is done.
+ nsTArray<SurfacePoolEntry> mPendingEntries;
+
+ // Stores entries which are available for recycling. These entries are not
+ // in use by a NativeLayerWayland or by the window server.
+ nsTArray<SurfacePoolEntry> mAvailableEntries;
+ size_t mPoolSizeLimit;
+
+ template <typename F>
+ void ForEachEntry(F aFn);
+
+ struct DepthBufferEntry final {
+ RefPtr<gl::GLContext> mGL;
+ gfx::IntSize mSize;
+ WeakPtr<gl::DepthAndStencilBuffer> mBuffer;
+ };
+
+ nsTArray<DepthBufferEntry> mDepthBuffers;
+};
+
+// A surface pool handle that is stored on NativeLayerWayland and keeps the
+// SurfacePool alive.
+class SurfacePoolHandleWayland final : public SurfacePoolHandle {
+ public:
+ SurfacePoolHandleWayland* AsSurfacePoolHandleWayland() override {
+ return this;
+ }
+
+ RefPtr<widget::WaylandBuffer> ObtainBufferFromPool(const gfx::IntSize& aSize);
+ void ReturnBufferToPool(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; }
+ void OnBeginFrame() override;
+ void OnEndFrame() override;
+
+ private:
+ friend class SurfacePoolWayland;
+ SurfacePoolHandleWayland(RefPtr<SurfacePoolWayland> aPool,
+ gl::GLContext* aGL);
+
+ const RefPtr<SurfacePoolWayland> mPool;
+ const RefPtr<gl::GLContext> mGL;
+};
+
+} // namespace mozilla::layers
+
+#endif