#pragma once #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace mbgl { namespace gl { constexpr size_t TextureMax = 64; using ProcAddress = void (*)(); class RendererBackend; namespace extension { class VertexArray; class Debugging; class ProgramBinary; } // namespace extension class Context final : public gfx::Context { public: Context(RendererBackend&); ~Context() override; Context(const Context&) = delete; Context& operator=(const Context& other) = delete; void initializeExtensions(const std::function&); void enableDebugging(); UniqueShader createShader(ShaderType type, const std::initializer_list& sources); UniqueProgram createProgram(ShaderID vertexShader, ShaderID fragmentShader); UniqueProgram createProgram(BinaryProgramFormat binaryFormat, const std::string& binaryProgram); void verifyProgramLinkage(ProgramID); void linkProgram(ProgramID); UniqueTexture createUniqueTexture(); #if MBGL_HAS_BINARY_PROGRAMS bool supportsProgramBinaries() const; #else constexpr static bool supportsProgramBinaries() { return false; } #endif optional> getBinaryProgram(ProgramID) const; Framebuffer createFramebuffer(const gfx::Renderbuffer&, const gfx::Renderbuffer&); Framebuffer createFramebuffer(const gfx::Renderbuffer&); Framebuffer createFramebuffer(const gfx::Texture&, const gfx::Renderbuffer&); Framebuffer createFramebuffer(const gfx::Texture&); Framebuffer createFramebuffer(const gfx::Texture&, const gfx::Renderbuffer&); template Image readFramebuffer(const Size size, bool flip = true) { static_assert(Image::channels == (format == gfx::TexturePixelType::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 ? gfx::TexturePixelType::RGBA : gfx::TexturePixelType::Alpha; drawPixels(image.size, image.data.get(), format); } #endif // MBGL_USE_GLES2 void clear(optional color, optional depth, optional stencil); void setDepthMode(const gfx::DepthMode&); void setStencilMode(const gfx::StencilMode&); void setColorMode(const gfx::ColorMode&); void setCullFaceMode(const gfx::CullFaceMode&); void draw(const gfx::DrawMode&, 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() override; // 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(); } void setCleanupOnDestruction(bool cleanup) { cleanupOnDestruction = cleanup; } private: RendererBackend& backend; bool cleanupOnDestruction = true; std::unique_ptr debugging; std::unique_ptr vertexArray; #if MBGL_HAS_BINARY_PROGRAMS std::unique_ptr programBinary; #endif public: State activeTextureUnit; State bindFramebuffer; State viewport; State scissorTest; std::array, 2> texture; State program; State vertexBuffer; State bindVertexArray { *this }; VertexArrayState globalVertexArrayState { UniqueVertexArray(0, { this }) }; State pixelStorePack; State pixelStoreUnpack; #if not MBGL_USE_GLES2 State pixelZoom; State rasterPos; 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; State cullFace; State cullFaceSide; State cullFaceWinding; #if not MBGL_USE_GLES2 State pointSize; #endif // MBGL_USE_GLES2 std::unique_ptr createVertexBufferResource(const void* data, std::size_t size, const gfx::BufferUsageType) override; void updateVertexBufferResource(gfx::VertexBufferResource&, const void* data, std::size_t size) override; std::unique_ptr createIndexBufferResource(const void* data, std::size_t size, const gfx::BufferUsageType) override; void updateIndexBufferResource(gfx::IndexBufferResource&, const void* data, std::size_t size) override; std::unique_ptr createTextureResource(Size, const void* data, gfx::TexturePixelType, gfx::TextureChannelDataType) override; void updateTextureResource(gfx::TextureResource&, Size, const void* data, gfx::TexturePixelType, gfx::TextureChannelDataType) override; void updateTextureResourceSub(gfx::TextureResource&, const uint16_t xOffset, const uint16_t yOffset, Size, const void* data, gfx::TexturePixelType, gfx::TextureChannelDataType) override; std::unique_ptr createOffscreenTexture( Size, gfx::TextureChannelDataType = gfx::TextureChannelDataType::UnsignedByte) override; std::unique_ptr createOffscreenTexture( Size, gfx::Renderbuffer&, gfx::TextureChannelDataType = gfx::TextureChannelDataType::UnsignedByte) override; std::unique_ptr createRenderbufferResource(gfx::RenderbufferPixelType, Size size) override; std::unique_ptr createDrawScopeResource() override; UniqueFramebuffer createFramebuffer(); std::unique_ptr readFramebuffer(Size, gfx::TexturePixelType, bool flip); #if not MBGL_USE_GLES2 void drawPixels(Size size, const void* data, gfx::TexturePixelType); #endif // MBGL_USE_GLES2 VertexArray createVertexArray(); bool supportsVertexArrays() const; std::unique_ptr createCommandEncoder() override; 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; #if not defined(NDEBUG) public: void visualizeStencilBuffer() override; void visualizeDepthBuffer(float depthRangeSize) override; #endif void clearStencilBuffer(int32_t) override; }; } // namespace gl } // namespace mbgl