1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
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
|