diff options
author | Konstantin Käfer <mail@kkaefer.com> | 2016-09-27 17:52:14 +0200 |
---|---|---|
committer | John Firebaugh <john.firebaugh@gmail.com> | 2016-09-27 11:03:29 -0700 |
commit | 44c7e9d05edbe6fee9e8f98b91380b6c07e57ac7 (patch) | |
tree | cb2ee7fed51efe737543bb6f2444fac885571c41 /src/mbgl/gl/context.hpp | |
parent | ce42d22984d19fa020e6fba77e2585c0fd9dacf4 (diff) | |
download | qtlocation-mapboxgl-44c7e9d05edbe6fee9e8f98b91380b6c07e57ac7.tar.gz |
[core] merge gl::ObjectStore into gl::Context
Diffstat (limited to 'src/mbgl/gl/context.hpp')
-rw-r--r-- | src/mbgl/gl/context.hpp | 143 |
1 files changed, 81 insertions, 62 deletions
diff --git a/src/mbgl/gl/context.hpp b/src/mbgl/gl/context.hpp index 995f087c6b..5aa55b6a28 100644 --- a/src/mbgl/gl/context.hpp +++ b/src/mbgl/gl/context.hpp @@ -1,79 +1,81 @@ #pragma once +#include <mbgl/gl/object.hpp> #include <mbgl/gl/state.hpp> #include <mbgl/gl/value.hpp> +#include <mbgl/util/noncopyable.hpp> + +#include <memory> +#include <vector> namespace mbgl { namespace gl { -class Context { +constexpr GLsizei TextureMax = 64; + +class Context : private util::noncopyable { public: - void resetState() { - stencilFunc.reset(); - stencilMask.reset(); - stencilTest.reset(); - stencilOp.reset(); - depthRange.reset(); - depthMask.reset(); - depthTest.reset(); - depthFunc.reset(); - blend.reset(); - blendFunc.reset(); - blendColor.reset(); - colorMask.reset(); - clearDepth.reset(); - clearColor.reset(); - clearStencil.reset(); - program.reset(); - lineWidth.reset(); - activeTexture.reset(); - bindFramebuffer.reset(); - viewport.reset(); -#ifndef GL_ES_VERSION_2_0 - pixelZoom.reset(); - rasterPos.reset(); -#endif // GL_ES_VERSION_2_0 - for (auto& tex : texture) { - tex.reset(); - } - vertexBuffer.reset(); - elementBuffer.reset(); - vertexArrayObject.reset(); + ~Context(); + + UniqueProgram createProgram() { + return UniqueProgram { MBGL_CHECK_ERROR(glCreateProgram()), { this } }; } - void setDirtyState() { - stencilFunc.setDirty(); - stencilMask.setDirty(); - stencilTest.setDirty(); - stencilOp.setDirty(); - depthRange.setDirty(); - depthMask.setDirty(); - depthTest.setDirty(); - depthFunc.setDirty(); - blend.setDirty(); - blendFunc.setDirty(); - blendColor.setDirty(); - colorMask.setDirty(); - clearDepth.setDirty(); - clearColor.setDirty(); - clearStencil.setDirty(); - program.setDirty(); - lineWidth.setDirty(); - activeTexture.setDirty(); - bindFramebuffer.setDirty(); - viewport.setDirty(); -#ifndef GL_ES_VERSION_2_0 - pixelZoom.setDirty(); - rasterPos.setDirty(); -#endif // GL_ES_VERSION_2_0 - for (auto& tex : texture) { - tex.setDirty(); + 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() { + if (pooledTextures.empty()) { + pooledTextures.resize(TextureMax); + MBGL_CHECK_ERROR(glGenTextures(TextureMax, pooledTextures.data())); } - vertexBuffer.setDirty(); - elementBuffer.setDirty(); - vertexArrayObject.setDirty(); + + GLuint id = pooledTextures.back(); + pooledTextures.pop_back(); + return UniqueTexture { std::move(id), { this } }; } + UniqueVAO createVAO() { + GLuint id = 0; + MBGL_CHECK_ERROR(gl::GenVertexArrays(1, &id)); + return UniqueVAO { std::move(id), { this } }; + } + + UniqueFBO createFBO() { + GLuint id = 0; + MBGL_CHECK_ERROR(glGenFramebuffers(1, &id)); + return UniqueFBO { std::move(id), { 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(); + + // Drain pools and remove abandoned objects, in preparation for destroying the store. + // Only call this while the OpenGL context is exclusive to this thread. + void reset(); + + bool empty() const { + return pooledTextures.empty() + && abandonedPrograms.empty() + && abandonedShaders.empty() + && abandonedBuffers.empty() + && abandonedTextures.empty() + && abandonedVAOs.empty() + && abandonedFBOs.empty(); + } + + void resetState(); + + void setDirtyState(); + State<value::StencilFunc> stencilFunc; State<value::StencilMask> stencilMask; State<value::StencilTest> stencilTest; @@ -102,6 +104,23 @@ public: State<value::BindBuffer<GL_ARRAY_BUFFER>> vertexBuffer; State<value::BindBuffer<GL_ELEMENT_ARRAY_BUFFER>> elementBuffer; State<value::BindVAO> vertexArrayObject; + +private: + friend detail::ProgramDeleter; + friend detail::ShaderDeleter; + friend detail::BufferDeleter; + friend detail::TextureDeleter; + friend detail::VAODeleter; + friend detail::FBODeleter; + + std::vector<GLuint> pooledTextures; + + std::vector<GLuint> abandonedPrograms; + std::vector<GLuint> abandonedShaders; + std::vector<GLuint> abandonedBuffers; + std::vector<GLuint> abandonedTextures; + std::vector<GLuint> abandonedVAOs; + std::vector<GLuint> abandonedFBOs; }; } // namespace gl |