This repository has been archived by the owner on Aug 8, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
/
object_store.hpp
125 lines (99 loc) · 3.22 KB
/
object_store.hpp
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
#pragma once
#include <mbgl/gl/gl.hpp>
#include <mbgl/util/noncopyable.hpp>
#include <unique_resource.hpp>
#include <array>
#include <algorithm>
#include <cassert>
#include <memory>
#include <vector>
namespace mbgl {
namespace gl {
constexpr GLsizei TextureMax = 64;
class ObjectStore;
struct ProgramDeleter {
ObjectStore* store;
void operator()(GLuint) const;
};
struct ShaderDeleter {
ObjectStore* store;
void operator()(GLuint) const;
};
struct BufferDeleter {
ObjectStore* store;
void operator()(GLuint) const;
};
struct TextureDeleter {
ObjectStore* store;
void operator()(GLuint) const;
};
struct VAODeleter {
ObjectStore* store;
void operator()(GLuint) const;
};
using ObjectPool = std::array<GLuint, TextureMax>;
struct TexturePoolDeleter {
ObjectStore* store;
void operator()(ObjectPool ids) const;
};
using UniqueProgram = std_experimental::unique_resource<GLuint, ProgramDeleter>;
using UniqueShader = std_experimental::unique_resource<GLuint, ShaderDeleter>;
using UniqueBuffer = std_experimental::unique_resource<GLuint, BufferDeleter>;
using UniqueTexture = std_experimental::unique_resource<GLuint, TextureDeleter>;
using UniqueVAO = std_experimental::unique_resource<GLuint, VAODeleter>;
using UniqueTexturePool = std_experimental::unique_resource<ObjectPool, TexturePoolDeleter>;
class ObjectStore : private util::noncopyable {
public:
~ObjectStore();
UniqueProgram createProgram() {
return UniqueProgram { MBGL_CHECK_ERROR(glCreateProgram()), { this } };
}
UniqueShader createShader(GLenum type) {
return UniqueShader { MBGL_CHECK_ERROR(glCreateShader(type)), { this } };
}
UniqueBuffer createBuffer() {
GLuint id = 0;
MBGL_CHECK_ERROR(glGenBuffers(1, &id));
return UniqueBuffer { std::move(id), { this } };
}
UniqueTexture createTexture() {
GLuint id = 0;
MBGL_CHECK_ERROR(glGenTextures(1, &id));
return UniqueTexture { std::move(id), { this } };
}
UniqueVAO createVAO() {
GLuint id = 0;
MBGL_CHECK_ERROR(gl::GenVertexArrays(1, &id));
return UniqueVAO { std::move(id), { this } };
}
UniqueTexturePool createTexturePool() {
ObjectPool ids;
MBGL_CHECK_ERROR(glGenTextures(TextureMax, ids.data()));
assert(ids.size() == size_t(TextureMax));
return UniqueTexturePool { std::move(ids), { this } };
}
// Actually remove the objects we marked as abandoned with the above methods.
// Only call this while the OpenGL context is exclusive to this thread.
void performCleanup();
bool empty() const {
return abandonedPrograms.empty()
&& abandonedShaders.empty()
&& abandonedBuffers.empty()
&& abandonedTextures.empty()
&& abandonedVAOs.empty();
}
private:
friend ProgramDeleter;
friend ShaderDeleter;
friend BufferDeleter;
friend TextureDeleter;
friend VAODeleter;
friend TexturePoolDeleter;
std::vector<GLuint> abandonedPrograms;
std::vector<GLuint> abandonedShaders;
std::vector<GLuint> abandonedBuffers;
std::vector<GLuint> abandonedTextures;
std::vector<GLuint> abandonedVAOs;
};
} // namespace gl
} // namespace mbgl