#pragma once #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace mbgl { class View; namespace gl { constexpr size_t TextureMax = 64; using ProcAddress = void (*)(); namespace extension { class VertexArray; class Debugging; class ProgramBinary; } // namespace extension class Context : private util::noncopyable { public: Context(); ~Context(); void initializeExtensions(const std::function&); void enableDebugging(); UniqueShader createShader(ShaderType type, const std::string& source); UniqueProgram createProgram(ShaderID vertexShader, ShaderID fragmentShader); UniqueProgram createProgram(BinaryProgramFormat binaryFormat, const std::string& binaryProgram); void verifyProgramLinkage(ProgramID); void linkProgram(ProgramID); UniqueTexture createTexture(); bool supportsVertexArrays() const; UniqueVertexArray createVertexArray(); #if MBGL_HAS_BINARY_PROGRAMS bool supportsProgramBinaries() const; #else constexpr bool supportsProgramBinaries() const { return false; } #endif optional> getBinaryProgram(ProgramID) const; template VertexBuffer createVertexBuffer(VertexVector&& v) { return VertexBuffer { v.vertexSize(), createVertexBuffer(v.data(), v.byteSize()) }; } template IndexBuffer createIndexBuffer(IndexVector&& v) { return IndexBuffer { createIndexBuffer(v.data(), v.byteSize()) }; } template Renderbuffer createRenderbuffer(const Size size) { static_assert(type == RenderbufferType::RGBA || type == RenderbufferType::DepthStencil || type == RenderbufferType::DepthComponent, "invalid renderbuffer type"); return { size, createRenderbuffer(type, size) }; } Framebuffer createFramebuffer(const Renderbuffer&, const Renderbuffer&); Framebuffer createFramebuffer(const Renderbuffer&); Framebuffer createFramebuffer(const Texture&, const Renderbuffer&); Framebuffer createFramebuffer(const Texture&); Framebuffer createFramebuffer(const Texture&, const Renderbuffer&); template Image readFramebuffer(const Size size, bool flip = true) { static_assert(Image::channels == (format == TextureFormat::RGBA ? 4 : 1), "image format mismatch"); return { size, readFramebuffer(size, format, flip) }; } #if not MBGL_USE_GLES2 template void drawPixels(const Image& image) { auto format = image.channels == 4 ? TextureFormat::RGBA : TextureFormat::Alpha; drawPixels(image.size, image.data.get(), format); } #endif // MBGL_USE_GLES2 // Create a texture from an image with data. template Texture createTexture(const Image& image, TextureUnit unit = 0) { auto format = image.channels == 4 ? TextureFormat::RGBA : TextureFormat::Alpha; return { image.size, createTexture(image.size, image.data.get(), format, unit) }; } template void updateTexture(Texture& obj, const Image& image, TextureUnit unit = 0) { auto format = image.channels == 4 ? TextureFormat::RGBA : TextureFormat::Alpha; updateTexture(obj.texture.get(), image.size, image.data.get(), format, unit); obj.size = image.size; } // Creates an empty texture with the specified dimensions. Texture createTexture(const Size size, TextureFormat format = TextureFormat::RGBA, TextureUnit unit = 0) { return { size, createTexture(size, nullptr, format, unit) }; } void bindTexture(Texture&, TextureUnit = 0, TextureFilter = TextureFilter::Nearest, TextureMipMap = TextureMipMap::No, TextureWrap wrapX = TextureWrap::Clamp, TextureWrap wrapY = TextureWrap::Clamp); void clear(optional color, optional depth, optional stencil); void setDrawMode(const Points&); void setDrawMode(const Lines&); void setDrawMode(const LineStrip&); void setDrawMode(const Triangles&); void setDrawMode(const TriangleStrip&); void setDepthMode(const DepthMode&); void setStencilMode(const StencilMode&); void setColorMode(const ColorMode&); void draw(PrimitiveType, std::size_t indexOffset, std::size_t indexLength); // 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() && abandonedVertexArrays.empty() && abandonedFramebuffers.empty(); } void setDirtyState(); extension::Debugging* getDebuggingExtension() const { return debugging.get(); } extension::VertexArray* getVertexArrayExtension() const { return vertexArray.get(); } private: std::unique_ptr debugging; std::unique_ptr vertexArray; #if MBGL_HAS_BINARY_PROGRAMS std::unique_ptr programBinary; #endif public: State activeTexture; State bindFramebuffer; State viewport; std::array, 2> texture; State vertexArrayObject { *this }; State program; State vertexBuffer; State elementBuffer; #if not MBGL_USE_GLES2 State pixelZoom; State rasterPos; State pixelStorePack; State pixelStoreUnpack; State pixelTransferDepth; State pixelTransferStencil; #endif // MBGL_USE_GLES2 private: State stencilFunc; State stencilMask; State stencilTest; State stencilOp; State depthRange; State depthMask; State depthTest; State depthFunc; State blend; State blendEquation; State blendFunc; State blendColor; State colorMask; State clearDepth; State clearColor; State clearStencil; State lineWidth; State bindRenderbuffer; #if not MBGL_USE_GLES2 State pointSize; #endif // MBGL_USE_GLES2 UniqueBuffer createVertexBuffer(const void* data, std::size_t size); UniqueBuffer createIndexBuffer(const void* data, std::size_t size); UniqueTexture createTexture(Size size, const void* data, TextureFormat, TextureUnit); void updateTexture(TextureID, Size size, const void* data, TextureFormat, TextureUnit); UniqueFramebuffer createFramebuffer(); UniqueRenderbuffer createRenderbuffer(RenderbufferType, Size size); std::unique_ptr readFramebuffer(Size, TextureFormat, bool flip); #if not MBGL_USE_GLES2 void drawPixels(Size size, const void* data, TextureFormat); #endif // MBGL_USE_GLES2 friend detail::ProgramDeleter; friend detail::ShaderDeleter; friend detail::BufferDeleter; friend detail::TextureDeleter; friend detail::VertexArrayDeleter; friend detail::FramebufferDeleter; friend detail::RenderbufferDeleter; std::vector pooledTextures; std::vector abandonedPrograms; std::vector abandonedShaders; std::vector abandonedBuffers; std::vector abandonedTextures; std::vector abandonedVertexArrays; std::vector abandonedFramebuffers; std::vector abandonedRenderbuffers; public: // For testing bool disableVAOExtension = false; }; } // namespace gl } // namespace mbgl