#pragma once #include #include "DirectGLES.h" #include #include namespace MobileGL::MG_Backend::DirectGLES { namespace BufferImpl { class BackendBufferObject { public: BackendBufferObject(); void SyncToBackend(SharedPtr& stateBufferObject); Uint GetBackendBufferId() { return m_backendBufferId; } void Bind(); void Bind(GLenum target); private: void SyncToBackend_glBufferData(SharedPtr& stateBufferObject); void SyncToBackend_glBufferSubData(SharedPtr& stateBufferObject); void SyncToBackend_glMapBufferRange(SharedPtr& stateBufferObject, Bool invalidate = false); Uint m_backendBufferId = 0; SizeT m_prevBufferSize = 0; Bool m_isInitialized = false; }; extern UnorderedMap, SharedPtr> g_backendBufferObjects; } // namespace BufferImpl namespace VertexArrayImpl { class BackendVertexArrayObject { public: BackendVertexArrayObject(); void SyncToBackend(SharedPtr& stateVAOObject); Uint GetBackendVertexArrayId() { return m_backendVAOId; } void Bind(); private: Uint m_backendVAOId = 0; Bool m_isInitialized = false; }; extern UnorderedMap, SharedPtr> g_backendVertexArrayObjects; } // namespace VertexArrayImpl namespace TextureImpl { struct StateTextureBasicInfo { // Used for tracking texture state changes TextureInternalFormat internalFormat = TextureInternalFormat::Unknown; SizeT width = 0; SizeT height = 0; SizeT depth = 0; SizeT mipmapLevels = 0; bool operator==(const StateTextureBasicInfo& other) const { return internalFormat == other.internalFormat && width == other.width && height == other.height && depth == other.depth && mipmapLevels == other.mipmapLevels; } bool operator!=(const StateTextureBasicInfo& other) const { return !(*this == other); } }; class BackendTextureObject { public: BackendTextureObject(); void SyncToBackend(SharedPtr& stateTextureObject); void Bind(GLenum target); Uint GetBackendTextureId(); private: Uint m_backendTextureId = 0; Bool m_isInitialized = false; StateTextureBasicInfo m_prevTextureInfo; }; extern UnorderedMap, SharedPtr> g_backendTextureObjects; } // namespace TextureImpl namespace FramebufferImpl { class BackendFramebufferObject { public: BackendFramebufferObject(); void SyncToBackend(SharedPtr& stateFBOObject, FramebufferTarget asTarget); Uint GetBackendFramebufferId() { return m_backendFBOId; } void Bind(FramebufferTarget target); private: Uint m_backendFBOId = 0; /* this will save buffers in its original form, reversion, absence or not consecutive are all allowed, as long as GL spec allows it i.e. it could be like [COLOR_ATTACHMENT0, COLOR_ATTACHMENT5, NONE, COLOR_ATTACHMENT4] Probably useful to re-link shader output according to this. aka. realizing `glBindFragDataLocation` */ GLenum m_frontendBuffers[MG_State::GLState::FramebufferObject::MAX_DRAW_BUFFERS] = {GL_NONE}; /* this will save buffers in its compacted GL form, not consecutive is not allowed i.e. it could be like [COLOR_ATTACHMENT0, COLOR_ATTACHMENT5, COLOR_ATTACHMENT4] (no GL_NONE among those) */ GLenum m_compactedFrontendBuffers[MG_State::GLState::FramebufferObject::MAX_DRAW_BUFFERS] = {GL_NONE}; /* this will save buffers in stricter ES rules reversion, absence or not consecutive are not allowed, according to ES spec i.e. it could be like [COLOR_ATTACHMENT0, COLOR_ATTACHMENT1, NONE, NONE, ...] this array could be provided as data directly to ES `glDrawBuffers` function */ GLenum m_backendBuffers[MG_State::GLState::FramebufferObject::MAX_DRAW_BUFFERS] = {GL_NONE}; }; extern UnorderedMap, SharedPtr> g_backendFramebufferObjects; } // namespace FramebufferImpl namespace PrgramImpl { class BackendProgramObjectImpl { public: BackendProgramObjectImpl(); ~BackendProgramObjectImpl(); void SyncToBackend(SharedPtr& stateProgramObject); void Use(); Uint GetBackendProgramId() const { return m_backendProgramId; } Uint GetBackendGlobalUBOId() const { return m_backendGlobalUBOId; } private: Uint m_backendProgramId = 0; Uint m_backendGlobalUBOId = 0; Bool m_isInitialized = false; }; extern UnorderedMap, SharedPtr> g_backendProgramObjects; } // namespace PrgramImpl } // namespace MobileGL::MG_Backend::DirectGLES