-
-
Notifications
You must be signed in to change notification settings - Fork 561
Expand file tree
/
Copy pathcontext.hpp
More file actions
243 lines (192 loc) · 9.41 KB
/
Copy pathcontext.hpp
File metadata and controls
243 lines (192 loc) · 9.41 KB
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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
#pragma once
#include <mbgl/actor/scheduler.hpp>
#include <mbgl/gfx/backend.hpp>
#include <mbgl/gfx/command_encoder.hpp>
#include <mbgl/gfx/context_observer.hpp>
#include <mbgl/gfx/draw_scope.hpp>
#include <mbgl/gfx/renderbuffer.hpp>
#include <mbgl/gfx/rendering_stats.hpp>
#include <mbgl/gfx/types.hpp>
#include <mbgl/gfx/uniform_buffer.hpp>
#include <memory>
#include <string>
#include <mutex>
#include <shared_mutex>
#include <unordered_set>
namespace mbgl {
class PaintParameters;
class ProgramParameters;
class TileLayerGroup;
class LayerGroup;
class RenderTarget;
using TileLayerGroupPtr = std::shared_ptr<TileLayerGroup>;
using LayerGroupPtr = std::shared_ptr<LayerGroup>;
using RenderTargetPtr = std::shared_ptr<RenderTarget>;
namespace gfx {
class DepthMode;
class ColorMode;
class OffscreenTexture;
class ShaderRegistry;
class Drawable;
class DrawableBuilder;
class DynamicTexture;
class ShaderProgramBase;
class Texture2D;
class VertexAttributeArray;
using DrawablePtr = std::shared_ptr<Drawable>;
using DynamicTexturePtr = std::shared_ptr<DynamicTexture>;
using ShaderProgramBasePtr = std::shared_ptr<ShaderProgramBase>;
using Texture2DPtr = std::shared_ptr<Texture2D>;
using UniformBufferPtr = std::shared_ptr<UniformBuffer>;
using UniqueDrawableBuilder = std::unique_ptr<DrawableBuilder>;
using VertexAttributeArrayPtr = std::shared_ptr<VertexAttributeArray>;
namespace {
ContextObserver nullObserver;
}
class Context {
protected:
Context(uint32_t maximumVertexBindingCount_)
: maximumVertexBindingCount(maximumVertexBindingCount_),
observer(&nullObserver) {}
public:
static constexpr const uint32_t minimumRequiredVertexBindingCount = 8;
const uint32_t maximumVertexBindingCount;
Context(Context&&) = delete;
Context(const Context&) = delete;
Context& operator=(Context&& other) = delete;
Context& operator=(const Context& other) = delete;
virtual ~Context() = default;
virtual void setObserver(ContextObserver* observer_) { observer = observer_ ? observer_ : &nullObserver; }
virtual void beginFrame() = 0;
virtual void endFrame() = 0;
/// Called at the end of a frame.
virtual void performCleanup() = 0;
/// Called when the app receives a memory warning and before it goes to the background.
virtual void reduceMemoryUsage() = 0;
virtual std::unique_ptr<OffscreenTexture> createOffscreenTexture(Size, TextureChannelDataType) = 0;
/// Create an offscreen texture with explicit depth/stencil attachments. Terrain drape
/// targets need a stencil to clip overlapping draped tiles against each other, as
/// maplibre-gl-js does for its render-to-texture framebuffer.
virtual std::unique_ptr<OffscreenTexture> createOffscreenTexture(Size,
TextureChannelDataType,
bool depth,
bool stencil) = 0;
template <RenderbufferPixelType pixelType>
Renderbuffer<pixelType> createRenderbuffer(const Size size) {
return {size, createRenderbufferResource(pixelType, size)};
}
DrawScope createDrawScope() { return DrawScope{createDrawScopeResource()}; }
virtual std::unique_ptr<CommandEncoder> createCommandEncoder() = 0;
gfx::RenderingStats& renderingStats() { return stats; }
const gfx::RenderingStats& renderingStats() const { return stats; }
// Per-frame budget for constructing new-tile drawables, counted per *tile* (not per
// layer): a burst of newly revealed tiles otherwise builds all their drawables in one
// frame, stalling it for tens to hundreds of ms. RenderOrchestrator::updateLayers resets
// the budget each frame; a layer's update() calls allowNewTileBuild(tileKey) before
// building a new tile. The first layer to reach a given tile spends one budget unit and
// records the tile, so every layer of that tile builds together (no half-built tiles);
// once the budget is spent, further new tiles are deferred and retried next frame. The
// key is a hash of the tile id (avoids a gfx->tile dependency); a rare collision only
// lets an extra tile through, which is harmless.
void resetNewTileBuildBudget(int maxNewTiles) {
newTileBudget = maxNewTiles;
newTileBuildDeferred = false;
newTilesAllowed.clear();
}
bool allowNewTileBuild(std::size_t tileKey) {
if (newTilesAllowed.contains(tileKey)) {
return true; // another layer already started this tile this frame
}
if (newTileBudget <= 0) {
newTileBuildDeferred = true;
return false;
}
--newTileBudget;
newTilesAllowed.insert(tileKey);
return true;
}
bool newTileBuildWasDeferred() const { return newTileBuildDeferred; }
void threadSafeAccessRenderingStats(const std::function<void(RenderingStats&)>& function) {
std::scoped_lock lock(renderingStatsMutex);
function(stats);
}
RenderingStats threadSafeCopyRenderingStats() {
std::shared_lock lock(renderingStatsMutex);
return stats;
}
#ifndef NDEBUG
virtual void visualizeStencilBuffer() = 0;
virtual void visualizeDepthBuffer(float depthRangeSize) = 0;
#endif
virtual void clearStencilBuffer(int32_t) = 0;
/// Sets dirty state
virtual void setDirtyState() = 0;
/// Create a new vertex attribute array
virtual gfx::VertexAttributeArrayPtr createVertexAttributeArray() const = 0;
/// Create a new drawable builder
virtual UniqueDrawableBuilder createDrawableBuilder(std::string name) = 0;
/// Create a new uniform buffer
/// @param data The data to copy, may be `nullptr`
/// @param size The size of the buffer
/// @param persistent Performance hint, optimize for few or many uses
virtual UniformBufferPtr createUniformBuffer(const void* data,
std::size_t size,
bool persistent = false,
bool ssbo = false) = 0;
virtual UniqueUniformBufferArray createLayerUniformBufferArray() = 0;
/// Get the generic shader with the specified name
virtual gfx::ShaderProgramBasePtr getGenericShader(gfx::ShaderRegistry&, const std::string& name) = 0;
/// Create a tile layer group implementation
virtual TileLayerGroupPtr createTileLayerGroup(int32_t layerIndex,
std::size_t initialCapacity,
std::string name,
bool renderToTerrain) = 0;
/// Create a layer group implementation
virtual LayerGroupPtr createLayerGroup(int32_t layerIndex,
std::size_t initialCapacity,
std::string name,
bool renderToTerrain) = 0;
/// Create a texture
virtual Texture2DPtr createTexture2D() = 0;
/// Create a dynamic texture
virtual DynamicTexturePtr createDynamicTexture(Size size, TexturePixelType pixelType) = 0;
/// Create a render target. `stencil` attaches a stencil buffer, which terrain drape
/// targets need to clip overlapping draped tiles against each other.
virtual RenderTargetPtr createRenderTarget(const Size size, const TextureChannelDataType type, bool stencil) = 0;
/// Resets the context state to defaults
virtual void resetState(gfx::DepthMode depthMode, gfx::ColorMode colorMode) = 0;
/// Update the uniform buffer with the provided data if it already exists, otherwise create it.
/// @return True if the buffer was created, false if it was updated
virtual bool emplaceOrUpdateUniformBuffer(gfx::UniformBufferPtr&,
const void* data,
std::size_t size,
bool persistent = false) = 0;
/// `emplaceOrUpdateUniformBuffer` with type inference
template <typename T>
bool emplaceOrUpdateUniformBuffer(gfx::UniformBufferPtr& ptr, const T* data, bool persistent = false)
requires(!std::is_pointer_v<T>)
{
return emplaceOrUpdateUniformBuffer(ptr, data, sizeof(T), persistent);
}
/// Get the global uniform buffers
virtual const gfx::UniformBufferArray& getGlobalUniformBuffers() const = 0;
/// Get the mutable global uniform buffer array
virtual gfx::UniformBufferArray& mutableGlobalUniformBuffers() = 0;
/// Bind the global uniform buffers
virtual void bindGlobalUniformBuffers(gfx::RenderPass&) const noexcept = 0;
/// Unbind the global uniform buffers
virtual void unbindGlobalUniformBuffers(gfx::RenderPass&) const noexcept = 0;
protected:
virtual std::unique_ptr<RenderbufferResource> createRenderbufferResource(RenderbufferPixelType, Size) = 0;
virtual std::unique_ptr<DrawScopeResource> createDrawScopeResource() = 0;
std::shared_mutex renderingStatsMutex;
gfx::RenderingStats stats;
ContextObserver* observer;
// Progressive new-tile build budget (see resetNewTileBuildBudget). Defaults to
// effectively unlimited so any path that never resets it is unaffected.
int newTileBudget = 1 << 30;
bool newTileBuildDeferred = false;
std::unordered_set<std::size_t> newTilesAllowed;
};
} // namespace gfx
} // namespace mbgl