Skip to content
This repository was archived by the owner on Aug 8, 2023. It is now read-only.

Commit 1dfa2db

Browse files
committed
[core] Use unique_resource for GL objects
Source: https://github.com/okdshin/unique_resource These replace the complexity of manually handling moveable-RAII objects with a type specific for that purpose. As suggested in #5141 (comment).
1 parent bd2b3c2 commit 1dfa2db

17 files changed

+171
-234
lines changed

src/mbgl/geometry/buffer.hpp

+9-8
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include <mbgl/gl/object_store.hpp>
55
#include <mbgl/platform/log.hpp>
66
#include <mbgl/util/noncopyable.hpp>
7+
#include <mbgl/util/optional.hpp>
78

89
#include <memory>
910
#include <cstdlib>
@@ -36,11 +37,11 @@ class Buffer : private util::noncopyable {
3637

3738
// Transfers this buffer to the GPU and binds the buffer to the GL context.
3839
void bind(gl::ObjectStore& store) {
39-
if (buffer.created()) {
40-
MBGL_CHECK_ERROR(glBindBuffer(bufferType, getID()));
40+
if (buffer) {
41+
MBGL_CHECK_ERROR(glBindBuffer(bufferType, buffer->get()));
4142
} else {
42-
buffer.create(store);
43-
MBGL_CHECK_ERROR(glBindBuffer(bufferType, getID()));
43+
buffer = store.createBuffer();
44+
MBGL_CHECK_ERROR(glBindBuffer(bufferType, buffer->get()));
4445
if (array == nullptr) {
4546
Log::Debug(Event::OpenGL, "Buffer doesn't contain elements");
4647
pos = 0;
@@ -60,20 +61,20 @@ class Buffer : private util::noncopyable {
6061
}
6162

6263
GLuint getID() const {
63-
return buffer.getID();
64+
return buffer ? buffer->get() : 0;
6465
}
6566

6667
// Uploads the buffer to the GPU to be available when we need it.
6768
inline void upload(gl::ObjectStore& store) {
68-
if (!buffer.created()) {
69+
if (!buffer) {
6970
bind(store);
7071
}
7172
}
7273

7374
protected:
7475
// increase the buffer size by at least /required/ bytes.
7576
inline void *addElement() {
76-
if (buffer.created()) {
77+
if (buffer) {
7778
throw std::runtime_error("Can't add elements after buffer was bound to GPU");
7879
}
7980
if (length < pos + itemSize) {
@@ -114,7 +115,7 @@ class Buffer : private util::noncopyable {
114115
size_t length = 0;
115116

116117
// GL buffer object handle.
117-
gl::BufferHolder buffer;
118+
mbgl::optional<gl::UniqueBuffer> buffer;
118119
};
119120

120121
} // namespace mbgl

src/mbgl/geometry/glyph_atlas.cpp

+5-5
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ void GlyphAtlas::removeGlyphs(uintptr_t tileUID) {
144144

145145
void GlyphAtlas::upload(gl::ObjectStore& store) {
146146
if (dirty) {
147-
const bool first = !texture.created();
147+
const bool first = !texture;
148148
bind(store);
149149

150150
std::lock_guard<std::mutex> lock(mtx);
@@ -184,9 +184,9 @@ void GlyphAtlas::upload(gl::ObjectStore& store) {
184184
}
185185

186186
void GlyphAtlas::bind(gl::ObjectStore& store) {
187-
if (!texture.created()) {
188-
texture.create(store);
189-
MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, texture.getID()));
187+
if (!texture) {
188+
texture = store.createTexture();
189+
MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, texture->get()));
190190
#ifndef GL_ES_VERSION_2_0
191191
MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0));
192192
#endif
@@ -195,6 +195,6 @@ void GlyphAtlas::bind(gl::ObjectStore& store) {
195195
MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
196196
MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
197197
} else {
198-
MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, texture.getID()));
198+
MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, texture->get()));
199199
}
200200
};

src/mbgl/geometry/glyph_atlas.hpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include <mbgl/geometry/binpack.hpp>
44
#include <mbgl/text/glyph_store.hpp>
55
#include <mbgl/util/noncopyable.hpp>
6+
#include <mbgl/util/optional.hpp>
67
#include <mbgl/gl/gl.hpp>
78
#include <mbgl/gl/object_store.hpp>
89

@@ -53,7 +54,7 @@ class GlyphAtlas : public util::noncopyable {
5354
std::unordered_map<FontStack, std::map<uint32_t, GlyphValue>, FontStackHash> index;
5455
const std::unique_ptr<uint8_t[]> data;
5556
std::atomic<bool> dirty;
56-
gl::TextureHolder texture;
57+
mbgl::optional<gl::UniqueTexture> texture;
5758
};
5859

5960
} // namespace mbgl

src/mbgl/geometry/line_atlas.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -129,16 +129,16 @@ void LineAtlas::upload(gl::ObjectStore& store) {
129129

130130
void LineAtlas::bind(gl::ObjectStore& store) {
131131
bool first = false;
132-
if (!texture.created()) {
133-
texture.create(store);
134-
MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, texture.getID()));
132+
if (!texture) {
133+
texture = store.createTexture();
134+
MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, texture->get()));
135135
MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
136136
MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
137137
MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT));
138138
MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
139139
first = true;
140140
} else {
141-
MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, texture.getID()));
141+
MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, texture->get()));
142142
}
143143

144144
if (dirty) {

src/mbgl/geometry/line_atlas.hpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
#include <mbgl/gl/gl.hpp>
44
#include <mbgl/gl/object_store.hpp>
5+
#include <mbgl/util/optional.hpp>
56

67
#include <vector>
78
#include <map>
@@ -35,7 +36,7 @@ class LineAtlas {
3536
private:
3637
const std::unique_ptr<GLbyte[]> data;
3738
bool dirty;
38-
gl::TextureHolder texture;
39+
mbgl::optional<gl::UniqueTexture> texture;
3940
int nextRow = 0;
4041
std::map<size_t, LinePatternPos> positions;
4142
};

src/mbgl/geometry/vao.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,10 @@ void VertexArrayObject::bindVertexArrayObject(gl::ObjectStore& store) {
2626
return;
2727
}
2828

29-
if (!vao.created()) {
30-
vao.create(store);
29+
if (!vao) {
30+
vao = store.createVAO();
3131
}
32-
MBGL_CHECK_ERROR(gl::BindVertexArray(vao.getID()));
32+
MBGL_CHECK_ERROR(gl::BindVertexArray(vao->get()));
3333
}
3434

3535
void VertexArrayObject::verifyBinding(Shader &shader, GLuint vertexBuffer, GLuint elementsBuffer,

src/mbgl/geometry/vao.hpp

+5-4
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include <mbgl/gl/gl.hpp>
55
#include <mbgl/gl/object_store.hpp>
66
#include <mbgl/util/noncopyable.hpp>
7+
#include <mbgl/util/optional.hpp>
78

89
#include <stdexcept>
910

@@ -24,7 +25,7 @@ class VertexArrayObject : public util::noncopyable {
2425
if (bound_shader == 0) {
2526
vertexBuffer.bind(store);
2627
shader.bind(offset);
27-
if (vao.created()) {
28+
if (vao) {
2829
storeBinding(shader, vertexBuffer.getID(), 0, offset);
2930
}
3031
} else {
@@ -39,7 +40,7 @@ class VertexArrayObject : public util::noncopyable {
3940
vertexBuffer.bind(store);
4041
elementsBuffer.bind(store);
4142
shader.bind(offset);
42-
if (vao.created()) {
43+
if (vao) {
4344
storeBinding(shader, vertexBuffer.getID(), elementsBuffer.getID(), offset);
4445
}
4546
} else {
@@ -48,15 +49,15 @@ class VertexArrayObject : public util::noncopyable {
4849
}
4950

5051
GLuint getID() const {
51-
return vao.getID();
52+
return vao->get();
5253
}
5354

5455
private:
5556
void bindVertexArrayObject(gl::ObjectStore&);
5657
void storeBinding(Shader &shader, GLuint vertexBuffer, GLuint elementsBuffer, GLbyte *offset);
5758
void verifyBinding(Shader &shader, GLuint vertexBuffer, GLuint elementsBuffer, GLbyte *offset);
5859

59-
gl::VAOHolder vao;
60+
mbgl::optional<gl::UniqueVAO> vao;
6061

6162
// For debug reasons, we're storing the bind information so that we can
6263
// detect errors and report

src/mbgl/gl/object_store.cpp

+16-62
Original file line numberDiff line numberDiff line change
@@ -5,79 +5,33 @@
55
namespace mbgl {
66
namespace gl {
77

8-
void ProgramHolder::create(ObjectStore& objectStore_) {
9-
if (created()) return;
10-
objectStore = &objectStore_;
11-
id = MBGL_CHECK_ERROR(glCreateProgram());
8+
void ProgramDeleter::operator()(GLuint id) const {
9+
store.get().abandonedPrograms.push_back(id);
1210
}
1311

14-
void ProgramHolder::reset() {
15-
if (!created()) return;
16-
objectStore->abandonedPrograms.push_back(id);
17-
id = 0;
12+
void ShaderDeleter::operator()(GLuint id) const {
13+
store.get().abandonedShaders.push_back(id);
1814
}
1915

20-
void ShaderHolder::create(ObjectStore& objectStore_) {
21-
if (created()) return;
22-
objectStore = &objectStore_;
23-
id = MBGL_CHECK_ERROR(glCreateShader(type));
16+
void BufferDeleter::operator()(GLuint id) const {
17+
store.get().abandonedBuffers.push_back(id);
2418
}
2519

26-
void ShaderHolder::reset() {
27-
if (!created()) return;
28-
objectStore->abandonedShaders.push_back(id);
29-
id = 0;
20+
void TextureDeleter::operator()(GLuint id) const {
21+
store.get().abandonedTextures.push_back(id);
3022
}
3123

32-
void BufferHolder::create(ObjectStore& objectStore_) {
33-
if (created()) return;
34-
objectStore = &objectStore_;
35-
MBGL_CHECK_ERROR(glGenBuffers(1, &id));
24+
void VAODeleter::operator()(GLuint id) const {
25+
store.get().abandonedVAOs.push_back(id);
3626
}
3727

38-
void BufferHolder::reset() {
39-
if (!created()) return;
40-
objectStore->abandonedBuffers.push_back(id);
41-
id = 0;
42-
}
43-
44-
void TextureHolder::create(ObjectStore& objectStore_) {
45-
if (created()) return;
46-
objectStore = &objectStore_;
47-
MBGL_CHECK_ERROR(glGenTextures(1, &id));
48-
}
49-
50-
void TextureHolder::reset() {
51-
if (!created()) return;
52-
objectStore->abandonedTextures.push_back(id);
53-
id = 0;
54-
}
55-
56-
void TexturePoolHolder::create(ObjectStore& objectStore_) {
57-
if (created()) return;
58-
objectStore = &objectStore_;
59-
MBGL_CHECK_ERROR(glGenTextures(TextureMax, ids.data()));
60-
}
61-
62-
void TexturePoolHolder::reset() {
63-
if (!created()) return;
28+
void TexturePoolDeleter::operator()(ObjectPool ids) const {
6429
for (GLuint& id : ids) {
65-
if (id == 0) continue;
66-
objectStore->abandonedTextures.push_back(id);
67-
id = 0;
68-
};
69-
}
70-
71-
void VAOHolder::create(ObjectStore& objectStore_) {
72-
if (created()) return;
73-
objectStore = &objectStore_;
74-
MBGL_CHECK_ERROR(gl::GenVertexArrays(1, &id));
75-
}
76-
77-
void VAOHolder::reset() {
78-
if (!created()) return;
79-
objectStore->abandonedVAOs.push_back(id);
80-
id = 0;
30+
if (id) {
31+
store.get().abandonedTextures.push_back(id);
32+
id = 0;
33+
};
34+
}
8135
}
8236

8337
ObjectStore::~ObjectStore() {

0 commit comments

Comments
 (0)