зеркало из https://github.com/mozilla/gecko-dev.git
128 строки
4.5 KiB
C++
128 строки
4.5 KiB
C++
/* -*- 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;
|
|
|
|
// 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
|