diff options
Diffstat (limited to '')
-rw-r--r-- | gfx/layers/SurfacePoolWayland.h | 127 |
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 |