Merge branch 'dev' into Feat/Backend-Direct-Vulkan

This commit is contained in:
2026-03-08 10:31:44 +08:00
89 changed files with 9838 additions and 7946 deletions
File diff suppressed because it is too large Load Diff
+258
View File
@@ -0,0 +1,258 @@
// MobileGL - MobileGL/MG_State/EGLState/Core.h
// Copyright (c) 2025-2026 MobileGL-Dev
// Licensed under the GNU Lesser General Public License v3.0:
// https://www.gnu.org/licenses/gpl-3.0.txt
// https://www.gnu.org/licenses/lgpl-3.0.txt
// SPDX-License-Identifier: LGPL-3.0-only
// End of Source File Header
#pragma once
#include <Includes.h>
#include <type_traits>
namespace MobileGL {
namespace MG_State {
namespace EGLState {
class EGLContext {
public:
using EGLDisplayHandle = ::EGLDisplay;
using EGLConfigHandle = ::EGLConfig;
using EGLSurfaceHandle = ::EGLSurface;
using EGLContextHandle = ::EGLContext;
using EGLSyncHandle = ::EGLSync;
using EGLImageHandle = ::EGLImage;
EGLContext() = default;
// Error
void SetError(EGLint errorCode);
EGLint ConsumeError();
// API
void SetBoundAPI(EGLenum api);
EGLenum GetBoundAPI() const;
// Display
EGLDisplayHandle GetDisplay(NativeDisplayType nativeDisplay);
EGLDisplayHandle GetPlatformDisplay(EGLenum platform, void* nativeDisplay);
Bool ValidateDisplay(EGLDisplayHandle display) const;
Bool IsDisplayInitialized(EGLDisplayHandle display) const;
Bool InitializeDisplay(EGLDisplayHandle display, EGLint* major, EGLint* minor);
Bool TerminateDisplay(EGLDisplayHandle display);
// Config
Bool ChooseConfig(EGLDisplayHandle display, const EGLint* attribList, EGLConfigHandle* configs,
EGLint configSize, EGLint* numConfig);
Bool GetConfigs(EGLDisplayHandle display, EGLConfigHandle* configs, EGLint configSize,
EGLint* numConfig);
Bool ValidateConfig(EGLConfigHandle config) const;
Bool ValidateConfigOnDisplay(EGLDisplayHandle display, EGLConfigHandle config) const;
Bool GetConfigAttrib(EGLDisplayHandle display, EGLConfigHandle config, EGLint attribute,
EGLint* value) const;
// Context
EGLContextHandle CreateContext(EGLDisplayHandle display, EGLConfigHandle config,
EGLContextHandle shareCtx, const EGLint* attribList);
Bool DestroyContext(EGLDisplayHandle display, EGLContextHandle context);
Bool QueryContext(EGLDisplayHandle display, EGLContextHandle context, EGLint attribute,
EGLint* value) const;
Bool ValidateContext(EGLContextHandle context) const;
Bool ValidateContextOnDisplay(EGLDisplayHandle display, EGLContextHandle context) const;
// Surface
EGLSurfaceHandle CreateWindowSurface(EGLDisplayHandle display, EGLConfigHandle config,
NativeWindowType window, const EGLint* attribList);
EGLSurfaceHandle CreatePbufferSurface(EGLDisplayHandle display, EGLConfigHandle config,
const EGLint* attribList);
EGLSurfaceHandle CreatePixmapSurface(EGLDisplayHandle display, EGLConfigHandle config,
EGLNativePixmapType pixmap, const EGLint* attribList);
EGLSurfaceHandle CreatePbufferFromClientBuffer(EGLDisplayHandle display, EGLenum bufferType,
EGLClientBuffer buffer, EGLConfigHandle config,
const EGLint* attribList);
EGLSurfaceHandle CreatePlatformWindowSurface(EGLDisplayHandle display, EGLConfigHandle config,
void* nativeWindow, const EGLAttrib* attribList);
EGLSurfaceHandle CreatePlatformPixmapSurface(EGLDisplayHandle display, EGLConfigHandle config,
void* nativePixmap, const EGLAttrib* attribList);
Bool DestroySurface(EGLDisplayHandle display, EGLSurfaceHandle surface);
Bool QuerySurface(EGLDisplayHandle display, EGLSurfaceHandle surface, EGLint attribute,
EGLint* value) const;
Bool ValidateSurface(EGLSurfaceHandle surface) const;
Bool ValidateSurfaceOnDisplay(EGLDisplayHandle display, EGLSurfaceHandle surface) const;
Bool SwapInterval(EGLDisplayHandle display, EGLint interval);
// Current
Bool MakeCurrent(EGLDisplayHandle display, EGLSurfaceHandle draw, EGLSurfaceHandle read,
EGLContextHandle context);
void ReleaseThread();
EGLContextHandle GetCurrentContext() const;
EGLDisplayHandle GetCurrentDisplay() const;
EGLSurfaceHandle GetCurrentSurface(EGLint readdraw) const;
// Sync
EGLSyncHandle CreateSync(EGLDisplayHandle display, EGLenum type, const EGLAttrib* attribList);
Bool DestroySync(EGLDisplayHandle display, EGLSyncHandle sync);
EGLint ClientWaitSync(EGLDisplayHandle display, EGLSyncHandle sync, EGLint flags, EGLTime timeout);
Bool GetSyncAttrib(EGLDisplayHandle display, EGLSyncHandle sync, EGLint attribute,
EGLAttrib* value) const;
Bool WaitSync(EGLDisplayHandle display, EGLSyncHandle sync, EGLint flags) const;
// Image
EGLImageHandle CreateImage(EGLDisplayHandle display, EGLContextHandle context, EGLenum target,
EGLClientBuffer buffer, const EGLAttrib* attribList);
Bool DestroyImage(EGLDisplayHandle display, EGLImageHandle image);
private:
enum class SurfaceType {
Window,
Pbuffer,
Pixmap,
PbufferFromClientBuffer,
PlatformWindow,
PlatformPixmap
};
struct DisplayLookupKey {
Uint64 NativeDisplayKey = 0;
EGLenum Platform = EGL_NONE;
Bool operator==(const DisplayLookupKey& rhs) const = default;
};
struct DisplayLookupHasher {
SizeT operator()(const DisplayLookupKey& key) const;
};
struct DisplayObject {
Uint64 NativeDisplayKey = 0;
EGLenum Platform = EGL_NONE;
Bool Initialized = false;
EGLint MajorVersion = 1;
EGLint MinorVersion = 5;
EGLint SwapInterval = 1;
Vector<EGLConfigHandle> Configs;
};
struct ConfigObject {
EGLDisplayHandle Display = EGL_NO_DISPLAY;
EGLint ConfigId = 1;
EGLint RedSize = 8;
EGLint GreenSize = 8;
EGLint BlueSize = 8;
EGLint AlphaSize = 8;
EGLint DepthSize = 24;
EGLint StencilSize = 8;
EGLint SurfaceType = EGL_WINDOW_BIT | EGL_PBUFFER_BIT | EGL_PIXMAP_BIT;
EGLint RenderableType = EGL_OPENGL_BIT | EGL_OPENGL_ES2_BIT | EGL_OPENGL_ES3_BIT;
EGLint MinSwapInterval = 0;
EGLint MaxSwapInterval = 4;
EGLint NativeVisualId = 0;
};
struct ContextObject {
EGLDisplayHandle Display = EGL_NO_DISPLAY;
EGLConfigHandle Config = nullptr;
EGLContextHandle SharedContext = nullptr;
EGLenum ClientAPI = EGL_OPENGL_API;
EGLint ClientVersion = 1;
EGLint MajorVersion = 1;
EGLint MinorVersion = 0;
};
struct SurfaceObject {
EGLDisplayHandle Display = EGL_NO_DISPLAY;
EGLConfigHandle Config = nullptr;
SurfaceType Type = SurfaceType::Window;
Uint64 NativeHandleKey = 0;
EGLClientBuffer ClientBuffer = nullptr;
EGLenum BufferType = EGL_NONE;
EGLint Width = 0;
EGLint Height = 0;
EGLint TextureFormat = EGL_NO_TEXTURE;
EGLint TextureTarget = EGL_NO_TEXTURE;
EGLint MipmapLevel = 0;
EGLint MipmapTexture = EGL_FALSE;
EGLint RenderBuffer = EGL_BACK_BUFFER;
EGLint SwapBehavior = EGL_BUFFER_DESTROYED;
};
struct SyncObject {
EGLDisplayHandle Display = EGL_NO_DISPLAY;
EGLenum Type = EGL_SYNC_FENCE;
EGLenum Condition = EGL_SYNC_PRIOR_COMMANDS_COMPLETE;
EGLenum Status = EGL_SIGNALED;
};
struct ImageObject {
EGLDisplayHandle Display = EGL_NO_DISPLAY;
EGLContextHandle Context = nullptr;
EGLenum Target = EGL_NONE;
EGLClientBuffer Buffer = nullptr;
};
struct ThreadCurrentState {
EGLDisplayHandle Display = EGL_NO_DISPLAY;
EGLSurfaceHandle DrawSurface = EGL_NO_SURFACE;
EGLSurfaceHandle ReadSurface = EGL_NO_SURFACE;
EGLContextHandle Context = nullptr;
};
template <typename HandleType>
static HandleType EncodeHandle(Uint64 rawHandle) {
return reinterpret_cast<HandleType>(static_cast<SizeT>(rawHandle));
}
template <typename NativeType>
static Uint64 ToNativeKey(NativeType nativeHandle) {
if constexpr (std::is_pointer_v<NativeType>) {
return static_cast<Uint64>(reinterpret_cast<SizeT>(nativeHandle));
} else {
return static_cast<Uint64>(nativeHandle);
}
}
static Optional<EGLint> ParseAttribValue(const EGLint* attribList, EGLint attrib);
static Optional<EGLAttrib> ParseAttribValue(const EGLAttrib* attribList, EGLint attrib);
static std::thread::id CurrentThreadKey();
EGLDisplayHandle GetOrCreateDisplay(Uint64 nativeDisplayKey, EGLenum platform);
EGLConfigHandle CreateDefaultConfig(EGLDisplayHandle display);
DisplayObject* TryGetDisplay(EGLDisplayHandle display);
const DisplayObject* TryGetDisplay(EGLDisplayHandle display) const;
const ConfigObject* TryGetConfig(EGLConfigHandle config) const;
const ContextObject* TryGetContext(EGLContextHandle context) const;
const SurfaceObject* TryGetSurface(EGLSurfaceHandle surface) const;
const SyncObject* TryGetSync(EGLSyncHandle sync) const;
const ImageObject* TryGetImage(EGLImageHandle image) const;
void ReleaseDisplayObjects(EGLDisplayHandle display);
void ReleaseThreadUnlocked(const std::thread::id& threadKey);
private:
mutable std::recursive_mutex m_mutex;
Uint64 m_nextDisplayHandle = 1;
Uint64 m_nextConfigHandle = 1;
Uint64 m_nextSurfaceHandle = 1;
Uint64 m_nextContextHandle = 1;
Uint64 m_nextSyncHandle = 1;
Uint64 m_nextImageHandle = 1;
UnorderedMap<DisplayLookupKey, EGLDisplayHandle, DisplayLookupHasher> m_displayLookup;
UnorderedMap<EGLDisplayHandle, DisplayObject> m_displays;
UnorderedMap<EGLConfigHandle, ConfigObject> m_configs;
UnorderedMap<EGLSurfaceHandle, SurfaceObject> m_surfaces;
UnorderedMap<EGLContextHandle, ContextObject> m_contexts;
UnorderedMap<EGLSyncHandle, SyncObject> m_syncs;
UnorderedMap<EGLImageHandle, ImageObject> m_images;
UnorderedMap<std::thread::id, EGLint> m_threadErrors;
UnorderedMap<std::thread::id, EGLenum> m_threadBoundAPI;
UnorderedMap<std::thread::id, ThreadCurrentState> m_threadCurrents;
UnorderedMap<EGLContextHandle, std::thread::id> m_contextOwners;
};
} // namespace EGLState
extern UniquePtr<EGLState::EGLContext> pEGLContext;
} // namespace MG_State
} // namespace MobileGL
@@ -7,210 +7,203 @@
// End of Source File Header
#include "BufferObject.h"
#include "MG_Util/Types.h"
namespace MobileGL {
namespace MG_State {
namespace GLState {
BufferObject::BufferObject(Uint externalIndex)
: m_externalIndex(externalIndex), m_size(0), m_usage(BufferUsage::StaticDraw), m_isMapped(false),
m_mappingAccess(BufferMappingAccessBit::Null),
m_change(BufferChangeBits::DirtyBit | BufferChangeBits::PreferReallocationBit), m_mappedRange({0, 0}),
m_dataPtr(MakeShared<Data>()) {
m_change.DirtyRanges.reserve(BufferChange::DEFAULT_RESERVED_DIRTY_RANGES_COUNT);
}
namespace MobileGL::MG_State::GLState {
BufferObject::BufferObject(Uint externalIndex)
: m_externalIndex(externalIndex), m_size(0), m_usage(BufferUsage::StaticDraw), m_isMapped(false),
m_mappingAccess(BufferMappingAccessBit::Null),
m_change(BufferChangeBits::DirtyBit | BufferChangeBits::PreferReallocationBit), m_mappedRange({0, 0}),
m_dataPtr(MakeShared<Data>()), m_ownsStagingData{} {
m_change.DirtyRanges.reserve(BufferChange::DEFAULT_RESERVED_DIRTY_RANGES_COUNT);
}
void BufferObject::Resize(SizeT size) {
m_size = size;
m_dataPtr->reserve(std::bit_ceil(size)); // power-of-2 reserve
m_dataPtr->resize(size);
void BufferObject::Resize(SizeT size) {
m_size = size;
m_dataPtr->reserve(std::bit_ceil(size)); // power-of-2 reserve
m_dataPtr->resize(size);
m_change.Bits |= BufferChangeBits::DirtyBit;
m_change.Bits |= BufferChangeBits::PreferReallocationBit;
}
void BufferObject::UploadData(DataPtr data, SizeT atOffset) {
MOBILEGL_ASSERT(atOffset + data.size <= m_size,
"UploadData out of bounds: atOffset (%zu) + data.size (%zu) > m_size (%zu)", atOffset,
data.size, m_size);
MOBILEGL_ASSERT(!m_isMapped, "Cannot upload data while buffer is mapped.");
Memcpy(m_dataPtr->data() + atOffset, data.data, data.size);
m_change.DirtyRanges.Add({atOffset, atOffset + data.size});
m_change.Bits |= BufferChangeBits::DirtyBit;
m_change.Bits |= BufferChangeBits::ForbidInvalidationBit;
m_change.Bits |= BufferChangeBits::ForbidUnsynchronizationBit;
// This function may be called by `glBufferData`, but we still set the forbid bits above,
// because when `PreferReallocationBit` is set, those bits are ignored anyway.
// The bits can fit the `glBufferSubData` semantics
// (though `glBufferSubData` calls `UploadSubData` instead).
}
void BufferObject::SetUsage(BufferUsage usage) {
m_usage = usage;
}
void BufferObject::ReleaseMemory() {
if (!m_isMapped) return;
if (m_mappingAccess & BufferMappingAccessBit::Write) { // if we wrote to the buffer
if (!(m_mappingAccess & BufferMappingAccessBit::FlushExplicit)) { // if we didn't flush explicitly
Memcpy(m_dataPtr->data() + m_mappedRange.start, m_stagingData.data(),
m_mappedRange.end - m_mappedRange.start);
m_change.DirtyRanges.Add({m_mappedRange.start, m_mappedRange.end});
m_change.Bits |= BufferChangeBits::DirtyBit;
m_change.Bits |= BufferChangeBits::PreferReallocationBit;
}
void BufferObject::UploadData(DataPtr data, SizeT atOffset) {
MOBILEGL_ASSERT(atOffset + data.size <= m_size,
"UploadData out of bounds: atOffset (%zu) + data.size (%zu) > m_size (%zu)", atOffset,
data.size, m_size);
MOBILEGL_ASSERT(!m_isMapped, "Cannot upload data while buffer is mapped.");
Memcpy(m_dataPtr->data() + atOffset, data.data, data.size);
m_change.DirtyRanges.Add({atOffset, atOffset + data.size});
m_change.Bits |= BufferChangeBits::DirtyBit;
m_change.Bits |= BufferChangeBits::ForbidInvalidationBit;
m_change.Bits |= BufferChangeBits::ForbidUnsynchronizationBit;
// This function may be called by `glBufferData`, but we still set the forbid bits above,
// because when `PreferReallocationBit` is set, those bits are ignored anyway.
// The bits can fit the `glBufferSubData` semantics
// (though `glBufferSubData` calls `UploadSubData` instead).
}
m_stagingData.clear();
}
void BufferObject::SetUsage(BufferUsage usage) {
m_usage = usage;
}
m_isMapped = false;
m_mappingAccess = BufferMappingAccessBit::Null;
m_mappedRange = {0, 0};
m_ownsStagingData = false;
}
void BufferObject::ReleaseMemory() {
if (!m_isMapped) return;
void BufferObject::FlushMemoryRange(SizeT offset, SizeT length) {
MOBILEGL_ASSERT(m_isMapped, "Buffer must be mapped to flush memory range.");
MOBILEGL_ASSERT((m_mappingAccess & BufferMappingAccessBit::FlushExplicit),
"Buffer must be mapped with FlushExplicit access to flush memory range.");
MOBILEGL_ASSERT((m_mappingAccess & BufferMappingAccessBit::Write),
"Buffer must be mapped with Write access to flush memory range.");
if (m_mappingAccess & BufferMappingAccessBit::Write) { // if we wrote to the buffer
if (!(m_mappingAccess & BufferMappingAccessBit::FlushExplicit)) { // if we didn't flush explicitly
Memcpy(m_dataPtr->data() + m_mappedRange.start, m_stagingData.data(),
m_mappedRange.end - m_mappedRange.start);
m_change.DirtyRanges.Add({m_mappedRange.start, m_mappedRange.end});
m_change.Bits |= BufferChangeBits::DirtyBit;
}
SizeT start = m_mappedRange.start + offset;
SizeT end = start + length;
MOBILEGL_ASSERT(end <= m_mappedRange.end, "Flush range out of bounds: mappedRange.end (%zu) < end (%zu)",
m_mappedRange.end, end);
m_stagingData.clear();
Memcpy(m_dataPtr->data() + start, m_stagingData.data() + offset, length);
m_change.DirtyRanges.Add({start, end});
m_change.Bits |= BufferChangeBits::DirtyBit;
}
void BufferObject::UploadSubData(DataPtr data, SizeT atOffset) {
MOBILEGL_ASSERT(!m_isMapped, "Cannot upload sub data while buffer is mapped.");
MOBILEGL_ASSERT(atOffset + data.size <= m_size,
"UploadSubData out of bounds: atOffset (%zu) + data.size (%zu) > m_size (%zu)", atOffset,
data.size, m_size);
Memcpy(m_dataPtr->data() + atOffset, data.data, data.size);
m_change.DirtyRanges.Add({atOffset, atOffset + data.size});
m_change.Bits |= BufferChangeBits::DirtyBit;
m_change.Bits |= BufferChangeBits::ForbidInvalidationBit;
m_change.Bits |= BufferChangeBits::ForbidUnsynchronizationBit;
}
void BufferObject::CopyDataFrom(const SharedPtr<BufferObject>& src, SizeT srcOffset, SizeT dstOffset, SizeT size) {
MOBILEGL_ASSERT(!m_isMapped, "Cannot copy data while buffer is mapped.");
MOBILEGL_ASSERT(!src->IsMapped(), "Cannot copy data from a buffer that is mapped.");
MOBILEGL_ASSERT(srcOffset + size <= src->GetSize(),
"Source buffer copy out of bounds: srcOffset (%zu) + size (%zu) > src->GetSize() (%zu)",
srcOffset, size, src->GetSize());
MOBILEGL_ASSERT(dstOffset + size <= m_size,
"Destination buffer copy out of bounds: dstOffset (%zu) + size (%zu) > m_size (%zu)", dstOffset,
size, m_size);
const Uint8* srcData = src->m_dataPtr->data() + srcOffset;
Memcpy(m_dataPtr->data() + dstOffset, srcData, size);
m_change.DirtyRanges.Add({dstOffset, dstOffset + size});
m_change.Bits |= BufferChangeBits::DirtyBit;
}
void* BufferObject::AcquireMemory(Bool markMapped, Bool read, Bool write) {
if (markMapped) {
m_isMapped = true;
auto a = BufferMappingAccessBit::Coherent | BufferMappingAccessBit::Read;
m_mappingAccess = (read ? BufferMappingAccessBit::Read : BufferMappingAccessBit::Null) |
(write ? BufferMappingAccessBit::Write : BufferMappingAccessBit::Null);
m_mappedRange = {0, m_size};
if (m_mappingAccess & BufferMappingAccessBit::Write) {
m_stagingData.resize(m_size);
m_ownsStagingData = true;
if (!(m_mappingAccess &
(BufferMappingAccessBit::InvalidateRange | BufferMappingAccessBit::InvalidateBuffer))) {
Memcpy(m_stagingData.data(), m_dataPtr->data(), m_size);
}
m_isMapped = false;
m_mappingAccess = BufferMappingAccessBit::Null;
m_mappedRange = {0, 0};
m_ownsStagingData = false;
return m_stagingData.data();
}
}
return m_dataPtr->data();
}
void* BufferObject::AcquireMemoryRange(Range1D range, Flags<BufferMappingAccessBit> access) {
MOBILEGL_ASSERT(range.end <= m_size && range.start <= range.end,
"AcquireMemoryRange out of bounds: range (%zu, %zu) exceeds m_size (%zu)", range.start,
range.end, m_size);
m_isMapped = true;
m_mappingAccess = access;
m_mappedRange = range;
if (access & BufferMappingAccessBit::Write) {
m_stagingData.resize(range.end - range.start);
m_ownsStagingData = true;
if (!(access & (BufferMappingAccessBit::InvalidateRange | BufferMappingAccessBit::InvalidateBuffer))) {
Memcpy(m_stagingData.data(), m_dataPtr->data() + range.start, m_stagingData.size());
}
void BufferObject::FlushMemoryRange(SizeT offset, SizeT length) {
MOBILEGL_ASSERT(m_isMapped, "Buffer must be mapped to flush memory range.");
MOBILEGL_ASSERT((m_mappingAccess & BufferMappingAccessBit::FlushExplicit),
"Buffer must be mapped with FlushExplicit access to flush memory range.");
MOBILEGL_ASSERT((m_mappingAccess & BufferMappingAccessBit::Write),
"Buffer must be mapped with Write access to flush memory range.");
return m_stagingData.data();
} else {
m_ownsStagingData = false;
return m_dataPtr->data() + range.start;
}
SizeT start = m_mappedRange.start + offset;
SizeT end = start + length;
MOBILEGL_ASSERT(end <= m_mappedRange.end,
"Flush range out of bounds: mappedRange.end (%zu) < end (%zu)", m_mappedRange.end, end);
m_change.Bits |=
!(access & BufferMappingAccessBit::InvalidateBuffer || access & BufferMappingAccessBit::InvalidateRange)
? BufferChangeBits::ForbidInvalidationBit
: BufferChangeBits::None;
m_change.Bits |= !(access & BufferMappingAccessBit::Unsynchronized)
? BufferChangeBits::ForbidUnsynchronizationBit
: BufferChangeBits::None;
}
Memcpy(m_dataPtr->data() + start, m_stagingData.data() + offset, length);
m_change.DirtyRanges.Add({start, end});
m_change.Bits |= BufferChangeBits::DirtyBit;
}
const SharedPtr<Data>& BufferObject::GetDataReadOnly() const {
return m_dataPtr;
}
void BufferObject::UploadSubData(DataPtr data, SizeT atOffset) {
MOBILEGL_ASSERT(!m_isMapped, "Cannot upload sub data while buffer is mapped.");
MOBILEGL_ASSERT(atOffset + data.size <= m_size,
"UploadSubData out of bounds: atOffset (%zu) + data.size (%zu) > m_size (%zu)",
atOffset, data.size, m_size);
void BufferObject::ClearDirty() {
m_change.DirtyRanges.clear();
m_change.Bits = BufferChangeBits::None;
}
Memcpy(m_dataPtr->data() + atOffset, data.data, data.size);
m_change.DirtyRanges.Add({atOffset, atOffset + data.size});
m_change.Bits |= BufferChangeBits::DirtyBit;
m_change.Bits |= BufferChangeBits::ForbidInvalidationBit;
m_change.Bits |= BufferChangeBits::ForbidUnsynchronizationBit;
}
SizeT BufferObject::GetSize() const {
return m_size;
}
void BufferObject::CopyDataFrom(const SharedPtr<BufferObject>& src, SizeT srcOffset, SizeT dstOffset,
SizeT size) {
MOBILEGL_ASSERT(!m_isMapped, "Cannot copy data while buffer is mapped.");
MOBILEGL_ASSERT(!src->IsMapped(), "Cannot copy data from a buffer that is mapped.");
MOBILEGL_ASSERT(srcOffset + size <= src->GetSize(),
"Source buffer copy out of bounds: srcOffset (%zu) + size (%zu) > src->GetSize() (%zu)",
srcOffset, size, src->GetSize());
MOBILEGL_ASSERT(dstOffset + size <= m_size,
"Destination buffer copy out of bounds: dstOffset (%zu) + size (%zu) > m_size (%zu)",
dstOffset, size, m_size);
BufferUsage BufferObject::GetUsage() const {
return m_usage;
}
const Uint8* srcData = src->m_dataPtr->data() + srcOffset;
Memcpy(m_dataPtr->data() + dstOffset, srcData, size);
m_change.DirtyRanges.Add({dstOffset, dstOffset + size});
m_change.Bits |= BufferChangeBits::DirtyBit;
}
const VecRange1D& BufferObject::GetDirtyRanges() const {
return m_change.DirtyRanges;
}
void* BufferObject::AcquireMemory(Bool markMapped, Bool read, Bool write) {
if (markMapped) {
m_isMapped = true;
auto a = BufferMappingAccessBit::Coherent | BufferMappingAccessBit::Read;
m_mappingAccess = (read ? BufferMappingAccessBit::Read : BufferMappingAccessBit::Null) |
(write ? BufferMappingAccessBit::Write : BufferMappingAccessBit::Null);
m_mappedRange = {0, m_size};
Flags<BufferChangeBits> BufferObject::GetChangeBits() const {
return m_change.Bits;
}
if (m_mappingAccess & BufferMappingAccessBit::Write) {
m_stagingData.resize(m_size);
m_ownsStagingData = true;
Bool BufferObject::IsMapped() const {
return m_isMapped;
}
if (!(m_mappingAccess &
(BufferMappingAccessBit::InvalidateRange | BufferMappingAccessBit::InvalidateBuffer))) {
Memcpy(m_stagingData.data(), m_dataPtr->data(), m_size);
}
Range1D BufferObject::GetMappedRange() const {
return m_isMapped ? m_mappedRange : Range1D{0, 0};
}
return m_stagingData.data();
}
}
Flags<BufferMappingAccessBit> BufferObject::GetMappingAccess() const {
return m_isMapped ? m_mappingAccess : BufferMappingAccessBit::Null;
}
return m_dataPtr->data();
}
void* BufferObject::AcquireMemoryRange(Range1D range, Flags<BufferMappingAccessBit> access) {
MOBILEGL_ASSERT(range.end <= m_size && range.start <= range.end,
"AcquireMemoryRange out of bounds: range (%zu, %zu) exceeds m_size (%zu)", range.start,
range.end, m_size);
m_isMapped = true;
m_mappingAccess = access;
m_mappedRange = range;
if (access & BufferMappingAccessBit::Write) {
m_stagingData.resize(range.end - range.start);
m_ownsStagingData = true;
if (!(access &
(BufferMappingAccessBit::InvalidateRange | BufferMappingAccessBit::InvalidateBuffer))) {
Memcpy(m_stagingData.data(), m_dataPtr->data() + range.start, m_stagingData.size());
}
return m_stagingData.data();
} else {
m_ownsStagingData = false;
return m_dataPtr->data() + range.start;
}
m_change.Bits |= !(access & BufferMappingAccessBit::InvalidateBuffer ||
access & BufferMappingAccessBit::InvalidateRange)
? BufferChangeBits::ForbidInvalidationBit
: BufferChangeBits::None;
m_change.Bits |= !(access & BufferMappingAccessBit::Unsynchronized)
? BufferChangeBits::ForbidUnsynchronizationBit
: BufferChangeBits::None;
}
const SharedPtr<Data> BufferObject::GetDataReadOnly() const {
return m_dataPtr;
}
void BufferObject::ClearDirty() {
m_change.DirtyRanges.clear();
m_change.Bits = BufferChangeBits::None;
}
SizeT BufferObject::GetSize() const {
return m_size;
}
BufferUsage BufferObject::GetUsage() const {
return m_usage;
}
const VecRange1D& BufferObject::GetDirtyRanges() const {
return m_change.DirtyRanges;
}
Flags<BufferChangeBits> BufferObject::GetChangeBits() const {
return m_change.Bits;
}
Bool BufferObject::IsMapped() const {
return m_isMapped;
}
Range1D BufferObject::GetMappedRange() const {
return m_isMapped ? m_mappedRange : Range1D{0, 0};
}
Flags<BufferMappingAccessBit> BufferObject::GetMappingAccess() const {
return m_isMapped ? m_mappingAccess : BufferMappingAccessBit::Null;
}
Uint BufferObject::GetExternalIndex() const {
return m_externalIndex;
}
} // namespace GLState
} // namespace MG_State
} // namespace MobileGL
Uint BufferObject::GetExternalIndex() const {
return m_externalIndex;
}
} // namespace MobileGL::MG_State::GLState
@@ -7,7 +7,6 @@
// End of Source File Header
#pragma once
#include "MG_Util/Types.h"
#include <Includes.h>
#include <MG_Util/Math/VectorTypes.h>
@@ -73,47 +72,45 @@ namespace MobileGL {
VecRange1D DirtyRanges;
};
namespace MG_State {
namespace GLState {
class BufferObject {
public:
using TargetEnum = BufferTarget;
namespace MG_State::GLState {
class BufferObject {
public:
using TargetEnum = BufferTarget;
BufferObject(Uint externalIndex);
BufferObject(Uint externalIndex);
void Resize(SizeT size);
void UploadData(DataPtr data, SizeT atOffset);
void SetUsage(BufferUsage usage);
void* AcquireMemory(Bool markMapped, Bool read, Bool write);
void* AcquireMemoryRange(Range1D range, Flags<BufferMappingAccessBit> access);
void ReleaseMemory();
void FlushMemoryRange(SizeT offset, SizeT length);
void UploadSubData(DataPtr data, SizeT atOffset);
void CopyDataFrom(const SharedPtr<BufferObject>& src, SizeT srcOffset, SizeT dstOffset, SizeT size);
void ClearDirty();
void Resize(SizeT size);
void UploadData(DataPtr data, SizeT atOffset);
void SetUsage(BufferUsage usage);
void* AcquireMemory(Bool markMapped, Bool read, Bool write);
void* AcquireMemoryRange(Range1D range, Flags<BufferMappingAccessBit> access);
void ReleaseMemory();
void FlushMemoryRange(SizeT offset, SizeT length);
void UploadSubData(DataPtr data, SizeT atOffset);
void CopyDataFrom(const SharedPtr<BufferObject>& src, SizeT srcOffset, SizeT dstOffset, SizeT size);
void ClearDirty();
Bool IsMapped() const;
SizeT GetSize() const;
BufferUsage GetUsage() const;
Range1D GetMappedRange() const;
const SharedPtr<Data> GetDataReadOnly() const;
Flags<BufferMappingAccessBit> GetMappingAccess() const;
Uint GetExternalIndex() const;
const VecRange1D& GetDirtyRanges() const;
Flags<BufferChangeBits> GetChangeBits() const;
Bool IsMapped() const;
SizeT GetSize() const;
BufferUsage GetUsage() const;
Range1D GetMappedRange() const;
const SharedPtr<Data>& GetDataReadOnly() const;
Flags<BufferMappingAccessBit> GetMappingAccess() const;
Uint GetExternalIndex() const;
const VecRange1D& GetDirtyRanges() const;
Flags<BufferChangeBits> GetChangeBits() const;
private:
const Uint m_externalIndex = 0;
SizeT m_size = 0;
BufferUsage m_usage = BufferUsage::StaticDraw;
SharedPtr<Data> m_dataPtr;
Bool m_isMapped;
Flags<BufferMappingAccessBit> m_mappingAccess;
BufferChange m_change;
Range1D m_mappedRange;
Vector<Uint8> m_stagingData;
Bool m_ownsStagingData;
};
} // namespace GLState
} // namespace MG_State
private:
const Uint m_externalIndex = 0;
SizeT m_size = 0;
BufferUsage m_usage = BufferUsage::StaticDraw;
SharedPtr<Data> m_dataPtr;
Bool m_isMapped;
Flags<BufferMappingAccessBit> m_mappingAccess;
BufferChange m_change;
Range1D m_mappedRange;
Vector<Uint8> m_stagingData;
Bool m_ownsStagingData;
};
} // namespace MG_State::GLState
} // namespace MobileGL
@@ -8,78 +8,75 @@
#include "BufferState.h"
namespace MobileGL {
namespace MG_State {
namespace GLState {
BufferState::BufferState() : m_indexGenerator(1024, 1) {
for (SizeT i = 0; i < m_bindingSlots.size(); ++i) {
m_bindingSlots[i] = BindingSlot<BufferObject>(GlobalBufferTargets[i]);
}
}
namespace MobileGL::MG_State::GLState {
BufferState::BufferState() : m_indexGenerator(1024, 1) {
for (SizeT i = 0; i < m_bindingSlots.size(); ++i) {
m_bindingSlots[i] = BindingSlot<BufferObject>(GlobalBufferTargets[i]);
}
}
SharedPtr<BufferObject> BufferState::GetBufferObject(Uint index) {
auto it = m_bufferObjects.find(index);
if (it != m_bufferObjects.end()) {
return it->second;
}
return nullptr;
}
const SharedPtr<BufferObject>& BufferState::GetBufferObject(Uint index) {
auto it = m_bufferObjects.find(index);
if (it != m_bufferObjects.end()) {
return it->second;
}
static SharedPtr<BufferObject> nullBufferObject = nullptr;
return nullBufferObject;
}
Vector<Uint> BufferState::GenerateNames(Uint number) {
Vector<Uint> buffers(number);
m_indexGenerator.Generate(number, buffers.data());
return buffers;
}
void BufferState::GenerateNames(Uint number, Vector<Uint>& buffers) {
buffers.resize(number);
m_indexGenerator.Generate(number, buffers.data());
}
SharedPtr<BufferObject> BufferState::CreateBufferObject(Uint index) {
auto bufferObject = MakeShared<BufferObject>(index);
m_bufferObjects[index] = bufferObject;
return bufferObject;
}
const SharedPtr<BufferObject>& BufferState::CreateBufferObject(Uint index) {
auto& bufferObj = m_bufferObjects[index];
if (!bufferObj) {
bufferObj = MakeShared<BufferObject>(index);
}
return bufferObj;
}
BindingSlot<BufferObject>& BufferState::GetBindingSlot(BufferTarget target) {
for (SizeT i = 0; i < m_bindingSlots.size(); ++i) {
if (m_bindingSlots[i].GetTarget() == target) {
return m_bindingSlots[i];
BindingSlot<BufferObject>& BufferState::GetBindingSlot(BufferTarget target) {
for (auto& bindingSlot : m_bindingSlots) {
if (bindingSlot.GetTarget() == target) {
return bindingSlot;
}
}
MOBILEGL_ASSERT(false, "Invalid BufferTarget enum value: %d", static_cast<int>(target));
return m_bindingSlots[0];
}
void BufferState::MarkBufferObjectForDeletion(Uint index) {
if (m_indexGenerator.IsValid(index)) {
auto it = m_bufferObjects.find(index);
if (it != m_bufferObjects.end()) {
for (auto& bindingSlot : m_bindingSlots) {
if (bindingSlot.GetBoundObject() == it->second) {
bindingSlot.Bind(nullptr);
}
}
MOBILEGL_ASSERT(false, "Invalid BufferTarget enum value: %d", static_cast<int>(target));
return m_bindingSlots[0];
m_bufferObjects.erase(it);
}
m_indexGenerator.Delete(index);
}
}
void BufferState::MarkBufferObjectForDeletion(Uint index) {
if (m_indexGenerator.IsValid(index)) {
auto it = m_bufferObjects.find(index);
if (it != m_bufferObjects.end()) {
for (SizeT i = 0; i < m_bindingSlots.size(); ++i) {
if (m_bindingSlots[i].GetBoundObject() == it->second) {
m_bindingSlots[i].Bind(nullptr);
}
}
m_bufferObjects.erase(it);
}
m_indexGenerator.Delete(index);
}
}
Bool BufferState::ValidateName(Uint index) const {
return m_indexGenerator.IsValid(index);
}
Bool BufferState::ValidateName(Uint index) const {
return m_indexGenerator.IsValid(index);
}
Bool BufferState::ValidateBufferObject(Uint index) const {
return m_bufferObjects.find(index) != m_bufferObjects.end();
}
Bool BufferState::ValidateBufferObject(Uint index) const {
return m_bufferObjects.find(index) != m_bufferObjects.end();
BindingSlotRange1D<BufferObject>& BufferState::GetBindingPoint(BufferTarget target, Uint index) {
for (SizeT i = 0; i < BufferBindPointTargets.size(); ++i) {
if (BufferBindPointTargets[i] == target) {
return m_bufferBindPointTargets[i][index];
}
BindingSlotRange1D<BufferObject>& BufferState::GetBindingPoint(BufferTarget target, Uint index) {
for (SizeT i = 0; i < BufferBindPointTargets.size(); ++i) {
if (BufferBindPointTargets[i] == target) {
return m_bufferBindPointTargets[i][index];
}
}
MOBILEGL_ASSERT(false, "Invalid BufferTarget enum value for binding point: %d",
static_cast<int>(target));
return m_bufferBindPointTargets[0][index];
}
} // namespace GLState
} // namespace MG_State
} // namespace MobileGL
}
MOBILEGL_ASSERT(false, "Invalid BufferTarget enum value for binding point: %d", static_cast<int>(target));
return m_bufferBindPointTargets[0][index];
}
} // namespace MobileGL::MG_State::GLState
@@ -11,46 +11,40 @@
#include <MG_Util/Miscellany/IndexGenerator.h>
#include "BufferObject.h"
namespace MobileGL {
namespace MG_State {
namespace GLState {
constexpr const auto GlobalBufferTargets =
ToArray(BufferTarget::Vertex, BufferTarget::Uniform, BufferTarget::CopyRead, BufferTarget::CopyWrite,
BufferTarget::PixelPack, BufferTarget::PixelUnpack, BufferTarget::Query, BufferTarget::Texture,
BufferTarget::TransformFeedback, BufferTarget::AtomicCounter, BufferTarget::DispatchIndirect,
BufferTarget::DrawIndirect, BufferTarget::ShaderStorage);
constexpr const auto BufferBindPointTargets =
ToArray(BufferTarget::Uniform, BufferTarget::TransformFeedback, BufferTarget::AtomicCounter,
BufferTarget::ShaderStorage);
namespace MobileGL::MG_State::GLState {
constexpr const auto GlobalBufferTargets =
ToArray(BufferTarget::Vertex, BufferTarget::Uniform, BufferTarget::CopyRead, BufferTarget::CopyWrite,
BufferTarget::PixelPack, BufferTarget::PixelUnpack, BufferTarget::Query, BufferTarget::Texture,
BufferTarget::TransformFeedback, BufferTarget::AtomicCounter, BufferTarget::DispatchIndirect,
BufferTarget::DrawIndirect, BufferTarget::ShaderStorage);
constexpr const auto BufferBindPointTargets = ToArray(BufferTarget::Uniform, BufferTarget::TransformFeedback,
BufferTarget::AtomicCounter, BufferTarget::ShaderStorage);
class BufferState {
public:
BufferState();
class BufferState {
public:
BufferState();
SharedPtr<BufferObject> GetBufferObject(Uint index);
Vector<Uint> GenerateNames(Uint number);
SharedPtr<BufferObject> CreateBufferObject(Uint index);
BindingSlot<BufferObject>& GetBindingSlot(BufferTarget target);
// For glBindBufferBase / glBindBufferRange
BindingSlotRange1D<BufferObject>& GetBindingPoint(BufferTarget target, Uint index);
constexpr SizeT GetBindingPointCount(const BufferTarget target) const {
auto it = std::find(BufferBindPointTargets.begin(), BufferBindPointTargets.end(), target);
auto index = std::distance(BufferBindPointTargets.begin(), it);
return m_bufferBindPointTargets[index].size();
}
void MarkBufferObjectForDeletion(Uint index);
Bool ValidateName(Uint index) const;
Bool ValidateBufferObject(Uint index) const;
const SharedPtr<BufferObject>& GetBufferObject(Uint index);
void GenerateNames(Uint number, Vector<Uint>& buffers);
const SharedPtr<BufferObject>& CreateBufferObject(Uint index);
BindingSlot<BufferObject>& GetBindingSlot(BufferTarget target);
// For glBindBufferBase / glBindBufferRange
BindingSlotRange1D<BufferObject>& GetBindingPoint(BufferTarget target, Uint index);
constexpr SizeT GetBindingPointCount(const BufferTarget target) const {
auto it = std::find(BufferBindPointTargets.begin(), BufferBindPointTargets.end(), target);
auto index = std::distance(BufferBindPointTargets.begin(), it);
return m_bufferBindPointTargets[index].size();
}
void MarkBufferObjectForDeletion(Uint index);
Bool ValidateName(Uint index) const;
Bool ValidateBufferObject(Uint index) const;
private:
UnorderedMap<Uint, SharedPtr<BufferObject>> m_bufferObjects;
IndexGenerator<Uint> m_indexGenerator;
Array<BindingSlot<BufferObject>, GlobalBufferTargets.size()> m_bindingSlots;
// TODO: query the count somewhere globally?
// For glBindBufferBase / glBindBufferRange
Array<Array<BindingSlotRange1D<BufferObject>, 16>, BufferBindPointTargets.size()>
m_bufferBindPointTargets;
};
} // namespace GLState
} // namespace MG_State
} // namespace MobileGL
private:
UnorderedMap<Uint, SharedPtr<BufferObject>> m_bufferObjects;
IndexGenerator<Uint> m_indexGenerator;
Array<BindingSlot<BufferObject>, GlobalBufferTargets.size()> m_bindingSlots;
// TODO: query the count somewhere globally?
// For glBindBufferBase / glBindBufferRange
Array<Array<BindingSlotRange1D<BufferObject>, 16>, BufferBindPointTargets.size()> m_bufferBindPointTargets;
};
} // namespace MobileGL::MG_State::GLState
+336 -334
View File
@@ -8,436 +8,438 @@
#include "Core.h"
#include "MG_State/GLState/RenderbufferState/RenderbufferObject.h"
#include "MG_State/EGLState/Core.h"
namespace MobileGL {
namespace MG_State {
void Init() {
MGLOG_D("Initializing MobileGL State...");
pGLContext = new MG_State::GLState::GLContext();
namespace MobileGL::MG_State {
void Init() {
MGLOG_D("Initializing MobileGL State...");
pGLContext = MakeUnique<GLState::GLContext>();
pEGLContext = MakeUnique<EGLState::EGLContext>();
}
namespace GLState {
// Error
void GLContext::RecordError(ErrorCode code, UniquePtr<ErrorInfo> info) {
m_errorState.RecordError(code, Move(info));
}
namespace GLState {
// Error
void GLContext::RecordError(ErrorCode code, SharedPtr<ErrorInfo> info) {
m_errorState.RecordError(code, info);
Bool GLContext::HasGLError() const {
return m_errorState.HasGLError();
}
Optional<const Error*> GLContext::PeekGLError() const {
return m_errorState.PeekGLError();
}
Optional<UniquePtr<Error>> GLContext::PopGLError() {
return Move(m_errorState.PopGLError());
}
Bool GLContext::HasNonGLError() const {
return m_errorState.HasNonGLError();
}
Optional<const Error*> GLContext::PeekNonGLError() const {
return m_errorState.PeekNonGLError();
}
Optional<UniquePtr<Error>> GLContext::PopNonGLError() {
return Move(m_errorState.PopNonGLError());
}
void GLContext::ClearErrors() {
m_errorState.Clear();
}
// Buffer
void GLContext::GenBufferNames(Uint number, Vector<Uint>& buffers) {
m_bufferState.GenerateNames(number, buffers);
}
const SharedPtr<BufferObject>& GLContext::GetBufferObject(Uint index) {
return m_bufferState.GetBufferObject(index);
}
BindingSlot<BufferObject>& GLContext::GetBufferBindingSlot(BufferTarget target) {
if (target == BufferTarget::Index) {
const auto& vao = m_vertexArrayState.GetBoundVertexArray();
MOBILEGL_ASSERT(vao != nullptr, "No VAO is currently bound when accessing index buffer binding slot.");
return vao->GetIndexBufferBindingSlot();
}
Bool GLContext::HasGLError() const {
return m_errorState.HasGLError();
}
return m_bufferState.GetBindingSlot(target);
}
Optional<const Error> GLContext::PeekGLError() const {
return m_errorState.PeekGLError();
}
BindingSlotRange1D<BufferObject>& GLContext::GetBufferBindingPoint(BufferTarget target, Uint index) {
return m_bufferState.GetBindingPoint(target, index);
}
Optional<Error> GLContext::PopGLError() {
return m_errorState.PopGLError();
}
const SharedPtr<BufferObject>& GLContext::CreateBufferObject(Uint index) {
return m_bufferState.CreateBufferObject(index);
}
Bool GLContext::HasNonGLError() const {
return m_errorState.HasNonGLError();
}
void GLContext::MarkBufferObjectForDeletion(Uint index) {
if (ValidateBufferObject(index)) {
auto bufferObject = m_bufferState.GetBufferObject(index);
auto& vaos = m_vertexArrayState.GetAllVertexArrays();
for (auto& vao : vaos) {
if (vao == nullptr) continue;
Optional<const Error> GLContext::PeekNonGLError() const {
return m_errorState.PeekNonGLError();
}
Optional<Error> GLContext::PopNonGLError() {
return m_errorState.PopNonGLError();
}
void GLContext::ClearErrors() {
m_errorState.Clear();
}
// Buffer
Vector<Uint> GLContext::GenBufferNames(Uint number) {
return m_bufferState.GenerateNames(number);
}
SharedPtr<BufferObject> GLContext::GetBufferObject(Uint index) {
return m_bufferState.GetBufferObject(index);
}
BindingSlot<BufferObject>& GLContext::GetBufferBindingSlot(BufferTarget target) {
if (target == BufferTarget::Index) {
const auto& vao = m_vertexArrayState.GetBoundVertexArray();
MOBILEGL_ASSERT(vao != nullptr,
"No VAO is currently bound when accessing index buffer binding slot.");
return vao->GetIndexBufferBindingSlot();
}
return m_bufferState.GetBindingSlot(target);
}
BindingSlotRange1D<BufferObject>& GLContext::GetBufferBindingPoint(BufferTarget target, Uint index) {
return m_bufferState.GetBindingPoint(target, index);
}
SharedPtr<BufferObject> GLContext::CreateBufferObject(Uint index) {
return m_bufferState.CreateBufferObject(index);
}
void GLContext::MarkBufferObjectForDeletion(Uint index) {
if (ValidateBufferObject(index)) {
auto bufferObject = m_bufferState.GetBufferObject(index);
auto& vaos = m_vertexArrayState.GetAllVertexArrays();
for (SizeT i = 0; i < vaos.size(); ++i) {
auto vao = vaos[i];
if (vao == nullptr) continue;
if (vao->GetIndexBufferBindingSlot().GetBoundObject() == bufferObject) {
vao->GetIndexBufferBindingSlot().Bind(nullptr);
}
for (SizeT j = 0; j < VertexArrayObject::MAX_VERTEX_ATTRIBS; ++j) {
if (vao->GetAttribute(j).Buffer == bufferObject) {
vao->BindAttributeBuffer(j, nullptr);
}
if (vao->GetIndexBufferBindingSlot().GetBoundObject() == bufferObject) {
vao->GetIndexBufferBindingSlot().Bind(nullptr);
}
for (SizeT j = 0; j < VertexArrayObject::MAX_VERTEX_ATTRIBS; ++j) {
if (vao->GetAttribute(j).Buffer == bufferObject) {
vao->BindAttributeBuffer(j, nullptr);
}
}
}
m_bufferState.MarkBufferObjectForDeletion(index);
}
Bool GLContext::ValidateBufferName(Uint index) const {
return m_bufferState.ValidateName(index);
}
m_bufferState.MarkBufferObjectForDeletion(index);
}
Bool GLContext::ValidateBufferObject(Uint index) const {
return m_bufferState.ValidateBufferObject(index);
}
Bool GLContext::ValidateBufferName(Uint index) const {
return m_bufferState.ValidateName(index);
}
// VertexArray
Vector<Uint> GLContext::GenVertexArrayNames(Uint number) {
return m_vertexArrayState.GenerateNames(number);
}
Bool GLContext::ValidateBufferObject(Uint index) const {
return m_bufferState.ValidateBufferObject(index);
}
SharedPtr<VertexArrayObject> GLContext::GetVertexArrayObject(Uint index) {
return m_vertexArrayState.GetVertexArrayObject(index);
}
// VertexArray
void GLContext::GenVertexArrayNames(Uint number, Vector<Uint>& vertexArrays) {
m_vertexArrayState.GenerateNames(number, vertexArrays);
}
void GLContext::BindVertexArray(Uint index) {
m_vertexArrayState.Bind(index);
}
const SharedPtr<VertexArrayObject>& GLContext::GetVertexArrayObject(Uint index) {
return m_vertexArrayState.GetVertexArrayObject(index);
}
SharedPtr<VertexArrayObject> GLContext::CreateVertexArrayObject(Uint index) {
return m_vertexArrayState.CreateVertexArrayObject(index);
}
void GLContext::BindVertexArray(Uint index) {
m_vertexArrayState.Bind(index);
}
void GLContext::MarkVertexArrayForDeletion(Uint index) {
m_vertexArrayState.MarkVertexArrayForDeletion(index);
}
const SharedPtr<VertexArrayObject>& GLContext::CreateVertexArrayObject(Uint index) {
return m_vertexArrayState.CreateVertexArrayObject(index);
}
Bool GLContext::ValidateVertexArrayName(Uint index) const {
return m_vertexArrayState.ValidateName(index);
}
void GLContext::MarkVertexArrayForDeletion(Uint index) {
m_vertexArrayState.MarkVertexArrayForDeletion(index);
}
Bool GLContext::ValidateVertexArrayObject(Uint index) const {
return m_vertexArrayState.ValidateVertexArrayObject(index);
}
Bool GLContext::ValidateVertexArrayName(Uint index) const {
return m_vertexArrayState.ValidateName(index);
}
SharedPtr<VertexArrayObject> GLContext::GetBoundVertexArray() {
return m_vertexArrayState.GetBoundVertexArray();
}
Bool GLContext::ValidateVertexArrayObject(Uint index) const {
return m_vertexArrayState.ValidateVertexArrayObject(index);
}
// Texture
Vector<Uint> GLContext::GenTextureNames(Uint number) {
return m_textureState.GenerateNames(number);
}
const SharedPtr<VertexArrayObject>& GLContext::GetBoundVertexArray() {
return m_vertexArrayState.GetBoundVertexArray();
}
SharedPtr<ITextureObject> GLContext::GetTextureObject(Uint index) {
return m_textureState.GetTextureObject(index);
}
// Texture
void GLContext::GenTextureNames(Uint number, Vector<Uint>& textures) {
m_textureState.GenerateNames(number, textures);
}
SharedPtr<ITextureObject> GLContext::CreateTextureObject(Uint index, TextureTarget target) {
return m_textureState.CreateTextureObject(index, target);
}
const SharedPtr<ITextureObject>& GLContext::GetTextureObject(Uint index) {
return m_textureState.GetTextureObject(index);
}
void GLContext::MarkTextureObjectForDeletion(Uint index) {
m_textureState.MarkTextureObjectForDeletion(index);
}
const SharedPtr<ITextureObject>& GLContext::CreateTextureObject(Uint index, TextureTarget target) {
return m_textureState.CreateTextureObject(index, target);
}
TextureUnit& GLContext::GetTextureUnitObject(Int unit) {
return m_textureState.GetUnitObject(unit);
}
void GLContext::MarkTextureObjectForDeletion(Uint index) {
m_textureState.MarkTextureObjectForDeletion(index);
}
Bool GLContext::ValidateTextureName(Uint index) const {
return m_textureState.ValidateName(index);
}
TextureUnit& GLContext::GetTextureUnitObject(Int unit) {
return m_textureState.GetUnitObject(unit);
}
Bool GLContext::ValidateTextureObject(Uint index) const {
return m_textureState.ValidateTextureObject(index);
}
Bool GLContext::ValidateTextureName(Uint index) const {
return m_textureState.ValidateName(index);
}
Int GLContext::GetActiveTextureUnit() const {
return m_textureState.GetActiveTextureUnit();
}
Bool GLContext::ValidateTextureObject(Uint index) const {
return m_textureState.ValidateTextureObject(index);
}
void GLContext::SetActiveTextureUnit(Int unit) {
m_textureState.SetActiveTextureUnit(unit);
}
Int GLContext::GetActiveTextureUnit() const {
return m_textureState.GetActiveTextureUnit();
}
// Program
Uint GLContext::CreateProgram() {
return m_programState.CreateProgram();
}
void GLContext::SetActiveTextureUnit(Int unit) {
m_textureState.SetActiveTextureUnit(unit);
}
Uint GLContext::CreateShader(const ShaderStage stage) {
return m_programState.CreateShader(stage);
}
// Program
Uint GLContext::CreateProgram() {
return m_programState.CreateProgram();
}
void GLContext::MarkProgramForDeletion(const Uint index) {
return m_programState.MarkProgramObjectForDeletion(index);
}
Uint GLContext::CreateShader(const ShaderStage stage) {
return m_programState.CreateShader(stage);
}
void GLContext::MarkShaderForDeletion(const Uint index) {
return m_programState.MarkShaderObjectForDeletion(index);
}
void GLContext::MarkProgramForDeletion(const Uint index) {
return m_programState.MarkProgramObjectForDeletion(index);
}
Bool GLContext::ValidateProgramName(const Uint index) const {
return m_programState.ValidateProgramObject(index);
}
void GLContext::MarkShaderForDeletion(const Uint index) {
return m_programState.MarkShaderObjectForDeletion(index);
}
Bool GLContext::ValidateShaderName(const Uint index) const {
return m_programState.ValidateShaderObject(index);
}
Bool GLContext::ValidateProgramName(const Uint index) const {
return m_programState.ValidateProgramObject(index);
}
SharedPtr<ProgramObject> GLContext::GetProgramObject(const Uint index) {
return m_programState.GetProgramObject(index);
}
Bool GLContext::ValidateShaderName(const Uint index) const {
return m_programState.ValidateShaderObject(index);
}
SharedPtr<ShaderObject> GLContext::GetShaderObject(const Uint index) {
return m_programState.GetShaderObject(index);
}
const SharedPtr<ProgramObject>& GLContext::GetProgramObject(const Uint index) {
return m_programState.GetProgramObject(index);
}
void GLContext::UseProgram(Uint program) {
return m_programState.UseProgram(program);
}
const SharedPtr<ShaderObject>& GLContext::GetShaderObject(const Uint index) {
return m_programState.GetShaderObject(index);
}
SharedPtr<ProgramObject> GLContext::GetCurrentProgram() {
return m_programState.GetCurrentProgram();
}
void GLContext::UseProgram(Uint program) {
return m_programState.UseProgram(program);
}
// RenderState
Uint GLContext::GetRenderStateParametersVersion() const {
return m_renderState.GetVersion();
}
const SharedPtr<ProgramObject>& GLContext::GetCurrentProgram() {
return m_programState.GetCurrentProgram();
}
const RenderStateParameters& GLContext::GetRenderStateParameters() const {
return m_renderState.GetAllParameters();
}
// RenderState
Uint GLContext::GetRenderStateParametersVersion() const {
return m_renderState.GetVersion();
}
void GLContext::SetViewport(IntVec4 viewport) {
m_renderState.SetViewport(viewport);
}
const RenderStateParameters& GLContext::GetRenderStateParameters() const {
return m_renderState.GetAllParameters();
}
const IntVec4& GLContext::GetViewport() const {
return m_renderState.GetViewport();
}
void GLContext::SetViewport(IntVec4 viewport) {
m_renderState.SetViewport(viewport);
}
void GLContext::SetCapability(CapabilityInput cap, Bool enabled) {
m_renderState.SetCapability(cap, enabled);
}
const IntVec4& GLContext::GetViewport() const {
return m_renderState.GetViewport();
}
Bool GLContext::IsCapabilityEnabled(CapabilityInput cap) const {
return m_renderState.IsCapabilityEnabled(cap);
}
void GLContext::SetCapability(CapabilityInput cap, Bool enabled) {
m_renderState.SetCapability(cap, enabled);
}
void GLContext::SetCapabilityIndexed(CapabilityInput cap, Uint index, Bool enabled) {
m_renderState.SetCapabilityIndexed(cap, index, enabled);
}
Bool GLContext::IsCapabilityEnabled(CapabilityInput cap) const {
return m_renderState.IsCapabilityEnabled(cap);
}
Bool GLContext::IsCapabilityEnabledIndexed(CapabilityInput cap, Uint index) const {
return m_renderState.IsCapabilityEnabledIndexed(cap, index);
}
void GLContext::SetCapabilityIndexed(CapabilityInput cap, Uint index, Bool enabled) {
m_renderState.SetCapabilityIndexed(cap, index, enabled);
}
void GLContext::SetBlendFunc(BlendFactor srcRGB, BlendFactor dstRGB, BlendFactor srcAlpha,
BlendFactor dstAlpha) {
m_renderState.SetBlendFunc(srcRGB, dstRGB, srcAlpha, dstAlpha);
}
Bool GLContext::IsCapabilityEnabledIndexed(CapabilityInput cap, Uint index) const {
return m_renderState.IsCapabilityEnabledIndexed(cap, index);
}
void GLContext::GetBlendFunc(BlendFactor& srcRGB, BlendFactor& dstRGB, BlendFactor& srcAlpha,
BlendFactor& dstAlpha) const {
m_renderState.GetBlendFunc(srcRGB, dstRGB, srcAlpha, dstAlpha);
}
void GLContext::SetBlendFunc(BlendFactor srcRGB, BlendFactor dstRGB, BlendFactor srcAlpha,
BlendFactor dstAlpha) {
m_renderState.SetBlendFunc(srcRGB, dstRGB, srcAlpha, dstAlpha);
}
void GLContext::SetBlendFuncIndexed(Uint index, BlendFactor srcRGB, BlendFactor dstRGB,
BlendFactor srcAlpha, BlendFactor dstAlpha) {
m_renderState.SetBlendFuncIndexed(index, srcRGB, dstRGB, srcAlpha, dstAlpha);
}
void GLContext::GetBlendFunc(BlendFactor& srcRGB, BlendFactor& dstRGB, BlendFactor& srcAlpha,
BlendFactor& dstAlpha) const {
m_renderState.GetBlendFunc(srcRGB, dstRGB, srcAlpha, dstAlpha);
}
void GLContext::GetBlendFuncIndexed(Uint index, BlendFactor& srcRGB, BlendFactor& dstRGB,
BlendFactor& srcAlpha, BlendFactor& dstAlpha) const {
m_renderState.GetBlendFuncIndexed(index, srcRGB, dstRGB, srcAlpha, dstAlpha);
}
void GLContext::SetBlendFuncIndexed(Uint index, BlendFactor srcRGB, BlendFactor dstRGB, BlendFactor srcAlpha,
BlendFactor dstAlpha) {
m_renderState.SetBlendFuncIndexed(index, srcRGB, dstRGB, srcAlpha, dstAlpha);
}
void GLContext::SetDepthFunc(DepthTestFunc func) {
m_renderState.SetDepthFunc(func);
}
void GLContext::GetBlendFuncIndexed(Uint index, BlendFactor& srcRGB, BlendFactor& dstRGB, BlendFactor& srcAlpha,
BlendFactor& dstAlpha) const {
m_renderState.GetBlendFuncIndexed(index, srcRGB, dstRGB, srcAlpha, dstAlpha);
}
DepthTestFunc GLContext::GetDepthFunc() const {
return m_renderState.GetDepthFunc();
}
void GLContext::SetDepthFunc(DepthTestFunc func) {
m_renderState.SetDepthFunc(func);
}
void GLContext::SetDepthMask(Bool flag) {
m_renderState.SetDepthMask(flag);
}
DepthTestFunc GLContext::GetDepthFunc() const {
return m_renderState.GetDepthFunc();
}
Bool GLContext::GetDepthMask() const {
return m_renderState.GetDepthMask();
}
void GLContext::SetDepthMask(Bool flag) {
m_renderState.SetDepthMask(flag);
}
void GLContext::SetColorMask(BoolVec4 mask) {
m_renderState.SetColorMask(mask);
}
Bool GLContext::GetDepthMask() const {
return m_renderState.GetDepthMask();
}
const BoolVec4 GLContext::GetColorMask() const {
return m_renderState.GetColorMask();
}
void GLContext::SetColorMask(BoolVec4 mask) {
m_renderState.SetColorMask(mask);
}
void GLContext::SetClearColor(FloatVec4 color) {
m_renderState.SetClearColor(color);
}
BoolVec4 GLContext::GetColorMask() const {
return m_renderState.GetColorMask();
}
const FloatVec4& GLContext::GetClearColor() const {
return m_renderState.GetClearColor();
}
void GLContext::SetClearColor(FloatVec4 color) {
m_renderState.SetClearColor(color);
}
void GLContext::SetClearDepth(Float depth) {
m_renderState.SetClearDepth(depth);
}
const FloatVec4& GLContext::GetClearColor() const {
return m_renderState.GetClearColor();
}
Float GLContext::GetClearDepth() const {
return m_renderState.GetClearDepth();
}
void GLContext::SetClearDepth(Float depth) {
m_renderState.SetClearDepth(depth);
}
void GLContext::SetClearStencil(Int stencil) {
m_renderState.SetClearStencil(stencil);
}
Float GLContext::GetClearDepth() const {
return m_renderState.GetClearDepth();
}
void GLContext::SetClearStencil(Int stencil) {
m_renderState.SetClearStencil(stencil);
}
Uint32 GLContext::GetClearStencil() const {
return m_renderState.GetClearStencil();
}
void GLContext::SetPixelStoreParam(PixelStoreParam param, Int value) {
m_renderState.SetPixelStoreParam(param, value);
}
void GLContext::SetPixelStoreParam(PixelStoreParam param, Int value) {
m_renderState.SetPixelStoreParam(param, value);
}
Int GLContext::GetPixelStoreParam(PixelStoreParam param) const {
return m_renderState.GetPixelStoreParam(param);
}
Int GLContext::GetPixelStoreParam(PixelStoreParam param) const {
return m_renderState.GetPixelStoreParam(param);
}
PixelStoreParameters GLContext::GetPixelStoreParameters(Bool isUnpack) const {
return m_renderState.GetPixelStoreParameters(isUnpack);
}
PixelStoreParameters GLContext::GetPixelStoreParameters(Bool isUnpack) const {
return m_renderState.GetPixelStoreParameters(isUnpack);
}
void GLContext::SetCullFaceMode(CullFaceMode mode) {
m_renderState.SetCullFaceMode(mode);
}
void GLContext::SetCullFaceMode(CullFaceMode mode) {
m_renderState.SetCullFaceMode(mode);
}
CullFaceMode GLContext::GetCullFaceMode() const {
return m_renderState.GetCullFaceMode();
}
CullFaceMode GLContext::GetCullFaceMode() const {
return m_renderState.GetCullFaceMode();
}
void GLContext::SetScissorBox(IntVec4 box) {
m_renderState.SetScissorBox(box);
}
void GLContext::SetScissorBox(IntVec4 box) {
m_renderState.SetScissorBox(box);
}
const IntVec4& GLContext::GetScissorBox() const {
return m_renderState.GetScissorBox();
}
const IntVec4& GLContext::GetScissorBox() const {
return m_renderState.GetScissorBox();
}
// Framebuffer
Vector<Uint> GLContext::GenFramebufferNames(Uint number) {
return m_framebufferState.GenerateNames(number);
}
// Framebuffer
void GLContext::GenFramebufferNames(Uint number, Vector<Uint>& framebuffers) {
m_framebufferState.GenerateNames(number, framebuffers);
}
SharedPtr<FramebufferObject> GLContext::GetFramebufferObject(Uint index) {
return m_framebufferState.GetFramebufferObject(index);
}
const SharedPtr<FramebufferObject>& GLContext::GetFramebufferObject(Uint index) {
return m_framebufferState.GetFramebufferObject(index);
}
BindingSlot<FramebufferObject>& GLContext::GetFramebufferBindingSlot(FramebufferTarget target) {
return m_framebufferState.GetBindingSlot(target);
}
BindingSlot<FramebufferObject>& GLContext::GetFramebufferBindingSlot(FramebufferTarget target) {
return m_framebufferState.GetBindingSlot(target);
}
SharedPtr<FramebufferObject> GLContext::CreateFramebufferObject(Uint index) {
return m_framebufferState.CreateFramebufferObject(index);
}
const SharedPtr<FramebufferObject>& GLContext::CreateFramebufferObject(Uint index) {
return m_framebufferState.CreateFramebufferObject(index);
}
void GLContext::MarkFramebufferObjectForDeletion(Uint index) {
m_framebufferState.MarkFramebufferObjectForDeletion(index);
}
void GLContext::MarkFramebufferObjectForDeletion(Uint index) {
m_framebufferState.MarkFramebufferObjectForDeletion(index);
}
Bool GLContext::ValidateFramebufferName(Uint index) const {
return m_framebufferState.ValidateName(index);
}
Bool GLContext::ValidateFramebufferName(Uint index) const {
return m_framebufferState.ValidateName(index);
}
Bool GLContext::ValidateFramebufferObject(Uint index) const {
return m_framebufferState.ValidateFramebufferObject(index);
}
Bool GLContext::ValidateFramebufferObject(Uint index) const {
return m_framebufferState.ValidateFramebufferObject(index);
}
// Sampler
Vector<Uint> GLContext::GenSamplerNames(Uint number) {
return m_samplerState.GenerateNames(number);
}
// Sampler
void GLContext::GenSamplerNames(Uint number, Vector<Uint>& samplers) {
m_samplerState.GenerateNames(number, samplers);
}
SharedPtr<SamplerObject> GLContext::GetSamplerObject(Uint index) {
return m_samplerState.GetSamplerObject(index);
}
const SharedPtr<SamplerObject>& GLContext::GetSamplerObject(Uint index) {
return m_samplerState.GetSamplerObject(index);
}
SharedPtr<SamplerObject> GLContext::CreateSamplerObject(Uint index) {
return m_samplerState.CreateSamplerObject(index);
}
const SharedPtr<SamplerObject>& GLContext::CreateSamplerObject(Uint index) {
return m_samplerState.CreateSamplerObject(index);
}
void GLContext::MarkSamplerObjectForDeletion(Uint index) {
// Unbind the sampler from all texture units
if (ValidateSamplerObject(index)) {
auto sampler = m_samplerState.GetSamplerObject(index);
for (Int unit = 0; unit < TextureState::MAX_TEXTURE_IMAGE_UNITS; ++unit) {
auto& textureUnit = m_textureState.GetUnitObject(unit);
if (textureUnit.GetSamplerObject() == sampler) {
textureUnit.SetSamplerObject(nullptr);
}
void GLContext::MarkSamplerObjectForDeletion(Uint index) {
// Unbind the sampler from all texture units
if (ValidateSamplerObject(index)) {
auto sampler = m_samplerState.GetSamplerObject(index);
for (Int unit = 0; unit < TextureState::MAX_TEXTURE_IMAGE_UNITS; ++unit) {
auto& textureUnit = m_textureState.GetUnitObject(unit);
if (textureUnit.GetSamplerObject() == sampler) {
textureUnit.SetSamplerObject(nullptr);
}
}
m_samplerState.MarkSamplerObjectForDeletion(index);
}
m_samplerState.MarkSamplerObjectForDeletion(index);
}
Bool GLContext::ValidateSamplerName(Uint index) const {
return m_samplerState.ValidateName(index);
}
Bool GLContext::ValidateSamplerName(Uint index) const {
return m_samplerState.ValidateName(index);
}
Bool GLContext::ValidateSamplerObject(Uint index) const {
return m_samplerState.ValidateSamplerObject(index);
}
Bool GLContext::ValidateSamplerObject(Uint index) const {
return m_samplerState.ValidateSamplerObject(index);
}
// Renderbuffer
Vector<Uint> GLContext::GenRenderbufferNames(Uint number) {
return m_renderbufferState.GenerateNames(number);
}
// Renderbuffer
void GLContext::GenRenderbufferNames(Uint number, Vector<Uint>& renderbuffers) {
m_renderbufferState.GenerateNames(number, renderbuffers);
}
SharedPtr<RenderbufferObject> GLContext::GetRenderbufferObject(Uint index) {
return m_renderbufferState.GetRenderbufferObject(index);
}
const SharedPtr<RenderbufferObject>& GLContext::GetRenderbufferObject(Uint index) {
return m_renderbufferState.GetRenderbufferObject(index);
}
BindingSlot<RenderbufferObject>& GLContext::GetRenderbufferBindingSlot(RenderbufferTarget target) {
return m_renderbufferState.GetBindingSlot(target);
}
BindingSlot<RenderbufferObject>& GLContext::GetRenderbufferBindingSlot(RenderbufferTarget target) {
return m_renderbufferState.GetBindingSlot(target);
}
SharedPtr<RenderbufferObject> GLContext::CreateRenderbufferObject(Uint index) {
return m_renderbufferState.CreateRenderbufferObject(index);
}
const SharedPtr<RenderbufferObject>& GLContext::CreateRenderbufferObject(Uint index) {
return m_renderbufferState.CreateRenderbufferObject(index);
}
void GLContext::MarkRenderbufferObjectForDeletion(Uint index) {
m_renderbufferState.MarkRenderbufferObjectForDeletion(index);
}
void GLContext::MarkRenderbufferObjectForDeletion(Uint index) {
m_renderbufferState.MarkRenderbufferObjectForDeletion(index);
}
Bool GLContext::ValidateRenderbufferName(Uint index) const {
return m_renderbufferState.ValidateName(index);
}
} // namespace GLState
Bool GLContext::ValidateRenderbufferName(Uint index) const {
return m_renderbufferState.ValidateName(index);
}
GLState::GLContext* pGLContext;
} // namespace MG_State
} // namespace MobileGL
Bool GLContext::ValidateRenderbufferObject(Uint index) const {
return m_renderbufferState.ValidateRenderbufferObject(index);
}
} // namespace GLState
UniquePtr<GLState::GLContext> pGLContext;
} // namespace MobileGL::MG_State
+29 -29
View File
@@ -30,42 +30,42 @@ namespace MobileGL {
GLContext() = default;
// Error
void RecordError(ErrorCode code, SharedPtr<ErrorInfo> info = nullptr);
void RecordError(ErrorCode code, UniquePtr<ErrorInfo> info);
Bool HasGLError() const;
Optional<const Error> PeekGLError() const;
Optional<Error> PopGLError();
Optional<const Error*> PeekNonGLError() const;
Optional<UniquePtr<Error>> PopNonGLError();
Bool HasNonGLError() const;
Optional<const Error> PeekNonGLError() const;
Optional<Error> PopNonGLError();
Optional<const Error*> PeekGLError() const;
Optional<UniquePtr<Error>> PopGLError();
void ClearErrors();
// Buffer
Vector<Uint> GenBufferNames(Uint number);
SharedPtr<BufferObject> GetBufferObject(Uint index);
void GenBufferNames(Uint number, Vector<Uint>& buffers);
const SharedPtr<BufferObject>& GetBufferObject(Uint index);
BindingSlot<BufferObject>& GetBufferBindingSlot(BufferTarget target);
BindingSlotRange1D<BufferObject>& GetBufferBindingPoint(BufferTarget target, Uint index);
constexpr SizeT GetBufferBindingPointCount(BufferTarget target) const {
return m_bufferState.GetBindingPointCount(target);
}
SharedPtr<BufferObject> CreateBufferObject(Uint index);
const SharedPtr<BufferObject>& CreateBufferObject(Uint index);
void MarkBufferObjectForDeletion(Uint index);
Bool ValidateBufferName(Uint index) const;
Bool ValidateBufferObject(Uint index) const;
// VertexArray
Vector<Uint> GenVertexArrayNames(Uint number);
SharedPtr<VertexArrayObject> GetVertexArrayObject(Uint index);
void GenVertexArrayNames(Uint number, Vector<Uint>& vertexArrays);
const SharedPtr<VertexArrayObject>& GetVertexArrayObject(Uint index);
void BindVertexArray(Uint index);
SharedPtr<VertexArrayObject> CreateVertexArrayObject(Uint index);
const SharedPtr<VertexArrayObject>& CreateVertexArrayObject(Uint index);
void MarkVertexArrayForDeletion(Uint index);
Bool ValidateVertexArrayName(Uint index) const;
Bool ValidateVertexArrayObject(Uint index) const;
SharedPtr<VertexArrayObject> GetBoundVertexArray();
const SharedPtr<VertexArrayObject>& GetBoundVertexArray();
// Texture
Vector<Uint> GenTextureNames(Uint number);
SharedPtr<ITextureObject> GetTextureObject(Uint index);
SharedPtr<ITextureObject> CreateTextureObject(Uint index, TextureTarget target);
void GenTextureNames(Uint number, Vector<Uint>& textures);
const SharedPtr<ITextureObject>& GetTextureObject(Uint index);
const SharedPtr<ITextureObject>& CreateTextureObject(Uint index, TextureTarget target);
void MarkTextureObjectForDeletion(Uint index);
TextureUnit& GetTextureUnitObject(Int unit);
Bool ValidateTextureName(Uint index) const;
@@ -80,10 +80,10 @@ namespace MobileGL {
void MarkShaderForDeletion(Uint index);
Bool ValidateProgramName(Uint index) const;
Bool ValidateShaderName(Uint index) const;
SharedPtr<ProgramObject> GetProgramObject(Uint index);
SharedPtr<ShaderObject> GetShaderObject(Uint index);
const SharedPtr<ProgramObject>& GetProgramObject(Uint index);
const SharedPtr<ShaderObject>& GetShaderObject(Uint index);
void UseProgram(Uint program);
SharedPtr<ProgramObject> GetCurrentProgram();
const SharedPtr<ProgramObject>& GetCurrentProgram();
// RenderState
Uint GetRenderStateParametersVersion() const;
@@ -106,7 +106,7 @@ namespace MobileGL {
void SetDepthMask(Bool flag);
Bool GetDepthMask() const;
void SetColorMask(BoolVec4 mask);
const BoolVec4 GetColorMask() const;
BoolVec4 GetColorMask() const;
void SetClearColor(FloatVec4 color);
const FloatVec4& GetClearColor() const;
void SetClearDepth(Float depth);
@@ -122,27 +122,27 @@ namespace MobileGL {
const IntVec4& GetScissorBox() const; // x, y, width, height
// Framebuffer
Vector<Uint> GenFramebufferNames(Uint number);
SharedPtr<FramebufferObject> GetFramebufferObject(Uint index);
void GenFramebufferNames(Uint number, Vector<Uint>& framebuffers);
const SharedPtr<FramebufferObject>& GetFramebufferObject(Uint index);
BindingSlot<FramebufferObject>& GetFramebufferBindingSlot(FramebufferTarget target);
SharedPtr<FramebufferObject> CreateFramebufferObject(Uint index);
const SharedPtr<FramebufferObject>& CreateFramebufferObject(Uint index);
void MarkFramebufferObjectForDeletion(Uint index);
Bool ValidateFramebufferName(Uint index) const;
Bool ValidateFramebufferObject(Uint index) const;
// Sampler
Vector<Uint> GenSamplerNames(Uint number);
SharedPtr<SamplerObject> GetSamplerObject(Uint index);
SharedPtr<SamplerObject> CreateSamplerObject(Uint index);
void GenSamplerNames(Uint number, Vector<Uint>& samplers);
const SharedPtr<SamplerObject>& GetSamplerObject(Uint index);
const SharedPtr<SamplerObject>& CreateSamplerObject(Uint index);
void MarkSamplerObjectForDeletion(Uint index);
Bool ValidateSamplerName(Uint index) const;
Bool ValidateSamplerObject(Uint index) const;
// Renderbuffer
Vector<Uint> GenRenderbufferNames(Uint number);
SharedPtr<RenderbufferObject> GetRenderbufferObject(Uint index);
void GenRenderbufferNames(Uint number, Vector<Uint>& renderbuffers);
const SharedPtr<RenderbufferObject>& GetRenderbufferObject(Uint index);
BindingSlot<RenderbufferObject>& GetRenderbufferBindingSlot(RenderbufferTarget target);
SharedPtr<RenderbufferObject> CreateRenderbufferObject(Uint index);
const SharedPtr<RenderbufferObject>& CreateRenderbufferObject(Uint index);
void MarkRenderbufferObjectForDeletion(Uint index);
Bool ValidateRenderbufferName(Uint index) const;
Bool ValidateRenderbufferObject(Uint index) const;
@@ -161,6 +161,6 @@ namespace MobileGL {
};
} // namespace GLState
extern GLState::GLContext* pGLContext;
extern UniquePtr<GLState::GLContext> pGLContext;
} // namespace MG_State
} // namespace MobileGL
+43 -47
View File
@@ -10,57 +10,53 @@
#include <MG_Util/Converters/GLToStr/GLEnumConverter.h>
#include <MG_Util/Converters/MGToGL/ErrorCodeConverter.h>
namespace MobileGL {
namespace MG_State {
namespace GLState {
void ErrorState::RecordError(ErrorCode code, SharedPtr<ErrorInfo> info) {
if (code == ErrorCode::NoError) {
MGLOG_E("Recording Non-OpenGL error:\n%s", info->ToString().c_str());
m_nonGLErrors.push_back(Error{code, info});
} else {
MGLOG_E("Recording OpenGL error (%s):\n%s",
MG_Util::ConvertGLEnumToString(MG_Util::ConvertErrorCodeToGLEnum(code)).c_str(),
info->ToString().c_str());
m_errors.push_back(Error{code, info});
}
}
namespace MobileGL::MG_State::GLState {
void ErrorState::RecordError(ErrorCode code, UniquePtr<ErrorInfo> info) {
if (code == ErrorCode::NoError) {
MGLOG_E("Recording Non-OpenGL error:\n%s", info->toString().c_str());
m_nonGLErrors.push_back(MakeUnique<Error>(code, Move(info)));
} else {
MGLOG_E("Recording OpenGL error (%s):\n%s",
MG_Util::ConvertGLEnumToString(MG_Util::ConvertErrorCodeToGLEnum(code)).c_str(),
info->toString().c_str());
m_errors.push_back(MakeUnique<Error>(code, Move(info)));
}
}
Bool ErrorState::HasNonGLError() const {
return !m_nonGLErrors.empty();
}
Bool ErrorState::HasNonGLError() const {
return !m_nonGLErrors.empty();
}
Optional<const Error> ErrorState::PeekNonGLError() const {
if (m_nonGLErrors.empty()) return Optional<const Error>{};
return Optional<const Error>{m_nonGLErrors.front()};
}
Optional<const Error*> ErrorState::PeekNonGLError() const {
if (m_nonGLErrors.empty()) return Nullopt;
return Optional<const Error*>{m_nonGLErrors.front().get()};
}
Optional<Error> ErrorState::PopNonGLError() {
if (m_nonGLErrors.empty()) return Optional<const Error>{};
auto error = Move(m_nonGLErrors.front());
m_nonGLErrors.erase(m_nonGLErrors.begin());
return Optional<const Error>{error};
}
Optional<UniquePtr<Error>> ErrorState::PopNonGLError() {
if (m_nonGLErrors.empty()) return Nullopt;
auto error = Move(m_nonGLErrors.front());
m_nonGLErrors.erase(m_nonGLErrors.begin());
return Move(error);
}
Bool ErrorState::HasGLError() const {
return !m_errors.empty();
}
Bool ErrorState::HasGLError() const {
return !m_errors.empty();
}
Optional<const Error> ErrorState::PeekGLError() const {
if (m_errors.empty()) return Optional<const Error>{};
return Optional<const Error>{m_errors.front()};
}
Optional<const Error*> ErrorState::PeekGLError() const {
if (m_errors.empty()) return Optional<const Error*>{};
return Optional<const Error*>{m_errors.front().get()};
}
Optional<Error> ErrorState::PopGLError() {
if (m_errors.empty()) return Optional<const Error>{};
auto error = Move(m_errors.front());
m_errors.erase(m_errors.begin());
return Optional<const Error>{error};
}
Optional<UniquePtr<Error>> ErrorState::PopGLError() {
if (m_errors.empty()) return Nullopt;
auto error = Move(m_errors.front());
m_errors.erase(m_errors.begin());
return Move(error);
}
void ErrorState::Clear() {
m_errors.clear();
m_nonGLErrors.clear();
}
} // namespace GLState
} // namespace MG_State
} // namespace MobileGL
void ErrorState::Clear() {
m_errors.clear();
m_nonGLErrors.clear();
}
} // namespace MobileGL::MG_State::GLState
+18 -20
View File
@@ -14,26 +14,24 @@
namespace MobileGL {
struct Error {
ErrorCode code;
SharedPtr<ErrorInfo> info;
UniquePtr<ErrorInfo> info;
};
namespace MG_State {
namespace GLState {
class ErrorState {
public:
void RecordError(ErrorCode code, SharedPtr<ErrorInfo> info = nullptr);
Bool HasNonGLError() const;
Optional<const Error> PeekNonGLError() const;
Optional<Error> PopNonGLError();
Bool HasGLError() const;
Optional<const Error> PeekGLError() const;
Optional<Error> PopGLError();
void Clear();
namespace MG_State::GLState {
class ErrorState {
public:
void RecordError(ErrorCode code, UniquePtr<ErrorInfo> info);
Bool HasNonGLError() const;
Optional<const Error*> PeekNonGLError() const;
Optional<UniquePtr<Error>> PopNonGLError();
Bool HasGLError() const;
Optional<const Error*> PeekGLError() const;
Optional<UniquePtr<Error>> PopGLError();
void Clear();
private:
Vector<Error> m_errors;
Vector<Error> m_nonGLErrors;
};
} // namespace GLState
} // namespace MG_State
} // namespace MobileGL
private:
Vector<UniquePtr<Error>> m_errors;
Vector<UniquePtr<Error>> m_nonGLErrors;
};
} // namespace MG_State::GLState
} // namespace MobileGL
@@ -13,7 +13,7 @@ namespace MobileGL {
class ErrorInfo {
public:
virtual ~ErrorInfo() = default;
virtual String ToString() const = 0;
virtual String toString() const = 0;
};
class GenericErrorInfo : public ErrorInfo {
@@ -24,7 +24,7 @@ namespace MobileGL {
explicit GenericErrorInfo(String m_prefix, String m_prefix_2, String message)
: m_message(Move(message)), m_prefix(Move(m_prefix)), m_prefix_2(Move(m_prefix_2)) {}
String ToString() const override {
String toString() const override {
StringStream ss;
if (m_prefix.has_value()) {
ss << "[" << m_prefix.value() << "] ";
@@ -9,157 +9,153 @@
#include "FramebufferObject.h"
#include "MG_Util/Types.h"
namespace MobileGL {
namespace MG_State {
namespace GLState {
// FramebufferAttachmentObject
FramebufferAttachmentObject::FramebufferAttachmentObject(
SharedPtr<MG_State::GLState::ITextureObject> texture, Int level)
: m_texture(texture), m_textureLevel(level) {}
FramebufferAttachmentObject::FramebufferAttachmentObject(SharedPtr<RenderbufferObject> renderbuffer)
: m_renderbuffer(renderbuffer) {}
FramebufferAttachmentObject::FramebufferAttachmentObject(Bool IsValid)
: m_texture(nullptr), m_renderbuffer(nullptr) {
m_isValid = IsValid;
}
namespace MobileGL::MG_State::GLState {
// FramebufferAttachmentObject
FramebufferAttachmentObject::FramebufferAttachmentObject(
const SharedPtr<MG_State::GLState::ITextureObject>& texture, Int level)
: m_texture(texture), m_textureLevel(level) {}
FramebufferAttachmentObject::FramebufferAttachmentObject(const SharedPtr<RenderbufferObject>& renderbuffer)
: m_renderbuffer(renderbuffer) {}
FramebufferAttachmentObject::FramebufferAttachmentObject(Bool IsValid)
: m_texture(nullptr), m_renderbuffer(nullptr) {
m_isValid = IsValid;
}
Bool FramebufferAttachmentObject::IsTexture() const {
return m_texture != nullptr;
}
Bool FramebufferAttachmentObject::IsTexture() const {
return m_texture != nullptr;
}
Bool FramebufferAttachmentObject::IsRenderbuffer() const {
return m_renderbuffer != nullptr;
}
Bool FramebufferAttachmentObject::IsRenderbuffer() const {
return m_renderbuffer != nullptr;
}
Bool FramebufferAttachmentObject::IsEmpty() const {
return m_texture == nullptr && m_renderbuffer == nullptr;
}
Bool FramebufferAttachmentObject::IsEmpty() const {
return m_texture == nullptr && m_renderbuffer == nullptr;
}
SharedPtr<MG_State::GLState::ITextureObject> FramebufferAttachmentObject::GetTexture() const {
return m_texture;
}
const SharedPtr<MG_State::GLState::ITextureObject>& FramebufferAttachmentObject::GetTexture() const {
return m_texture;
}
SharedPtr<RenderbufferObject> FramebufferAttachmentObject::GetRenderbuffer() const {
return m_renderbuffer;
}
const SharedPtr<RenderbufferObject>& FramebufferAttachmentObject::GetRenderbuffer() const {
return m_renderbuffer;
}
Int FramebufferAttachmentObject::GetTextureLevel() const {
return m_textureLevel;
}
Int FramebufferAttachmentObject::GetTextureLevel() const {
return m_textureLevel;
}
Bool FramebufferAttachmentObject::IsComplete() const {
if (IsTexture()) {
Bool complete = m_texture->IsComplete();
return complete;
} else if (IsRenderbuffer()) {
Bool complete = m_renderbuffer->IsAllocated();
return complete;
}
Bool FramebufferAttachmentObject::IsComplete() const {
if (IsTexture()) {
Bool complete = m_texture->IsComplete();
return complete;
} else if (IsRenderbuffer()) {
Bool complete = m_renderbuffer->IsAllocated();
return complete;
}
return false;
}
IntVec3 FramebufferAttachmentObject::GetSize() const {
if (IsTexture()) {
// TODO: get correct upload target
MOBILEGL_ASSERT(nullptr != static_cast<MG_State::GLState::TextureObjectMipmap*>(m_texture.get()),
"Texture object here should always be an object with mipmap");
auto textureMipmapObject = static_cast<MG_State::GLState::TextureObjectMipmap*>(m_texture.get());
return textureMipmapObject->GetMipmapTexelSize(TextureUploadTarget::Texture2D, m_textureLevel);
} else if (IsRenderbuffer()) {
return {m_renderbuffer->GetWidth(), m_renderbuffer->GetHeight(), 1};
}
return {0, 0, 0};
}
Bool FramebufferAttachmentObject::IsValid() const {
return m_isValid;
}
// FramebufferObject
FramebufferObject::FramebufferObject(Uint externalIndex)
: m_externalIndex(externalIndex), m_attachmentVersions{}, m_drawBuffers{} {
m_attachmentObjects.fill(FramebufferAttachmentObject(false));
m_drawBuffers.fill(FramebufferAttachmentType::None);
m_drawBuffers[0] = FramebufferAttachmentType::Color0;
m_attachmentVersions.fill(0);
}
void FramebufferObject::AttachTexture(FramebufferAttachmentType type, const SharedPtr<ITextureObject>& texture,
int level) {
m_attachmentObjects[static_cast<SizeT>(type)] = FramebufferAttachmentObject(texture, level);
BumpAttachmentVersion(type);
}
void FramebufferObject::AttachRenderbuffer(FramebufferAttachmentType type,
const SharedPtr<RenderbufferObject>& renderbuffer) {
m_attachmentObjects[static_cast<SizeT>(type)] = FramebufferAttachmentObject(renderbuffer);
BumpAttachmentVersion(type);
}
void FramebufferObject::Detach(FramebufferAttachmentType type) {
m_attachmentObjects[static_cast<SizeT>(type)] = FramebufferAttachmentObject(false);
BumpAttachmentVersion(type);
}
const FramebufferAttachmentObject& FramebufferObject::GetAttachment(FramebufferAttachmentType type) const {
return m_attachmentObjects[static_cast<SizeT>(type)];
}
const FramebufferObject::FramebufferAttachmentObjectArray& FramebufferObject::GetAllAttachmentObjects() const {
return m_attachmentObjects;
}
Bool FramebufferObject::CheckCompleteness() const {
if (m_attachmentObjects.empty()) {
return false;
}
Int width = -1, height = -1;
Int validAttachmentCount = 0;
for (const auto& attachmentObject : m_attachmentObjects) {
if (!attachmentObject.IsValid()) continue;
++validAttachmentCount;
const auto& attachment = attachmentObject;
auto attachmentSize = attachment.GetSize();
Int w = attachmentSize.x();
Int h = attachmentSize.y();
if (width == -1) {
width = w;
height = h;
} else if (width != w || height != h) {
return false;
}
IntVec3 FramebufferAttachmentObject::GetSize() const {
if (IsTexture()) {
// TODO: get correct upload target
MOBILEGL_ASSERT(nullptr != dynamic_cast<MG_State::GLState::TextureObjectMipmap*>(m_texture.get()),
"Texture object here should always be an object with mipmap");
auto textureMipmapObject = static_cast<MG_State::GLState::TextureObjectMipmap*>(m_texture.get());
return textureMipmapObject->GetMipmapTexelSize(TextureUploadTarget::Texture2D, m_textureLevel);
} else if (IsRenderbuffer()) {
return IntVec3(m_renderbuffer->GetWidth(), m_renderbuffer->GetHeight(), 1);
}
return {0, 0, 0};
if (!attachment.IsComplete()) {
return false;
}
}
Bool FramebufferAttachmentObject::IsValid() const {
return m_isValid;
}
if (validAttachmentCount == 0) return false;
return true;
}
// FramebufferObject
FramebufferObject::FramebufferObject(Uint externalIndex) : m_externalIndex(externalIndex) {
m_attachmentObjects.fill(FramebufferAttachmentObject(false));
m_drawBuffers.fill(FramebufferAttachmentType::None);
m_drawBuffers[0] = FramebufferAttachmentType::Color0;
m_attachmentVersions.fill(0);
}
void FramebufferObject::SetDrawBuffer(Uint index, FramebufferAttachmentType buffer) {
if (m_drawBuffers[index] == buffer) return;
m_drawBuffers[index] = buffer;
BumpAttachmentVersion(buffer);
}
void FramebufferObject::AttachTexture(FramebufferAttachmentType type, SharedPtr<ITextureObject> texture,
int level) {
m_attachmentObjects[static_cast<SizeT>(type)] = FramebufferAttachmentObject(std::move(texture), level);
BumpAttachmentVersion(type);
}
const FramebufferObject::FramebufferAttachmentArray& FramebufferObject::GetDrawBuffers() const {
return m_drawBuffers;
}
void FramebufferObject::AttachRenderbuffer(FramebufferAttachmentType type,
std::shared_ptr<RenderbufferObject> renderbuffer) {
m_attachmentObjects[static_cast<SizeT>(type)] = FramebufferAttachmentObject(renderbuffer);
BumpAttachmentVersion(type);
}
Uint FramebufferObject::GetExternalIndex() const {
return m_externalIndex;
}
void FramebufferObject::Detach(FramebufferAttachmentType type) {
m_attachmentObjects[static_cast<SizeT>(type)] = FramebufferAttachmentObject(false);
BumpAttachmentVersion(type);
}
const FramebufferAttachmentObject& FramebufferObject::GetAttachment(FramebufferAttachmentType type) const {
return m_attachmentObjects[static_cast<SizeT>(type)];
}
const FramebufferObject::FramebufferAttachmentObjectArray& FramebufferObject::GetAllAttachmentObjects()
const {
return m_attachmentObjects;
}
Bool FramebufferObject::CheckCompleteness() const {
if (m_attachmentObjects.empty()) {
return false;
}
Int width = -1, height = -1;
Int validAttachmentCount = 0;
for (SizeT i = 0; i < m_attachmentObjects.size(); ++i) {
if (!m_attachmentObjects[i].IsValid()) continue;
++validAttachmentCount;
const auto& attachment = m_attachmentObjects[i];
auto attachmentSize = attachment.GetSize();
Int w = attachmentSize.x();
Int h = attachmentSize.y();
if (width == -1) {
width = w;
height = h;
} else if (width != w || height != h) {
return false;
}
if (!attachment.IsComplete()) {
return false;
}
}
if (validAttachmentCount == 0) return false;
return true;
}
void FramebufferObject::SetDrawBuffer(Uint index, FramebufferAttachmentType buffer) {
if (m_drawBuffers[index] == buffer) return;
m_drawBuffers[index] = buffer;
BumpAttachmentVersion(buffer);
}
const FramebufferObject::FramebufferAttachmentArray& FramebufferObject::GetDrawBuffers() const {
return m_drawBuffers;
}
Uint FramebufferObject::GetExternalIndex() const {
return m_externalIndex;
}
void FramebufferObject::BumpAttachmentVersion(FramebufferAttachmentType type) {
++m_attachmentVersions[static_cast<SizeT>(type)];
++m_objectVersion;
}
} // namespace GLState
} // namespace MG_State
} // namespace MobileGL
void FramebufferObject::BumpAttachmentVersion(FramebufferAttachmentType type) {
++m_attachmentVersions[static_cast<SizeT>(type)];
++m_objectVersion;
}
} // namespace MobileGL::MG_State::GLState
@@ -7,6 +7,7 @@
// End of Source File Header
#pragma once
#include "MG_Util/Types.h"
#include <Includes.h>
#include <MG_State/GLState/TextureState/TextureObject.h>
#include <MG_State/GLState/RenderbufferState/RenderbufferObject.h>
@@ -68,81 +69,78 @@ namespace MobileGL {
Unknown = -1
};
namespace MG_State {
namespace GLState {
class FramebufferAttachmentObject {
public:
explicit FramebufferAttachmentObject(SharedPtr<MG_State::GLState::ITextureObject> texture,
Int level = 0);
explicit FramebufferAttachmentObject(SharedPtr<RenderbufferObject> renderbuffer);
explicit FramebufferAttachmentObject(Bool IsValid = true);
namespace MG_State::GLState {
class FramebufferAttachmentObject {
public:
explicit FramebufferAttachmentObject(const SharedPtr<MG_State::GLState::ITextureObject>& texture,
Int level = 0);
explicit FramebufferAttachmentObject(const SharedPtr<RenderbufferObject>& renderbuffer);
explicit FramebufferAttachmentObject(Bool IsValid = true);
Bool IsTexture() const;
Bool IsRenderbuffer() const;
Bool IsEmpty() const;
SharedPtr<MG_State::GLState::ITextureObject> GetTexture() const;
SharedPtr<RenderbufferObject> GetRenderbuffer() const;
Int GetTextureLevel() const;
Bool IsComplete() const;
IntVec3 GetSize() const;
Bool IsValid() const;
Bool IsTexture() const;
Bool IsRenderbuffer() const;
Bool IsEmpty() const;
const SharedPtr<MG_State::GLState::ITextureObject>& GetTexture() const;
const SharedPtr<RenderbufferObject>& GetRenderbuffer() const;
Int GetTextureLevel() const;
Bool IsComplete() const;
IntVec3 GetSize() const;
Bool IsValid() const;
private:
SharedPtr<MG_State::GLState::ITextureObject> m_texture = nullptr;
SharedPtr<RenderbufferObject> m_renderbuffer = nullptr;
Int m_textureLevel = 0;
Bool m_isValid = true;
};
private:
SharedPtr<MG_State::GLState::ITextureObject> m_texture = nullptr;
SharedPtr<RenderbufferObject> m_renderbuffer = nullptr;
Int m_textureLevel = 0;
Bool m_isValid = true;
};
class FramebufferObject {
public:
static constexpr Uint MAX_DRAW_BUFFERS = 8;
class FramebufferObject {
public:
static constexpr Uint MAX_DRAW_BUFFERS = 8;
using TargetEnum = FramebufferTarget;
using FramebufferAttachmentObjectArray =
Array<FramebufferAttachmentObject,
static_cast<SizeT>(FramebufferAttachmentType::FramebufferAttachmentTypeCount)>;
using FramebufferAttachmentArray = Array<FramebufferAttachmentType, MAX_DRAW_BUFFERS>;
using FramebufferAttachmentVersionArray =
Array<Uint16, static_cast<SizeT>(FramebufferAttachmentType::FramebufferAttachmentTypeCount)>;
using TargetEnum = FramebufferTarget;
using FramebufferAttachmentObjectArray =
Array<FramebufferAttachmentObject,
static_cast<SizeT>(FramebufferAttachmentType::FramebufferAttachmentTypeCount)>;
using FramebufferAttachmentArray = Array<FramebufferAttachmentType, MAX_DRAW_BUFFERS>;
using FramebufferAttachmentVersionArray =
Array<Uint16, static_cast<SizeT>(FramebufferAttachmentType::FramebufferAttachmentTypeCount)>;
FramebufferObject(Uint externalIndex);
FramebufferObject(Uint externalIndex);
void AttachTexture(FramebufferAttachmentType type, SharedPtr<ITextureObject> texture, int level = 0);
void AttachRenderbuffer(FramebufferAttachmentType type,
std::shared_ptr<RenderbufferObject> renderbuffer);
void Detach(FramebufferAttachmentType type);
const FramebufferAttachmentObject& GetAttachment(FramebufferAttachmentType type) const;
const FramebufferAttachmentObjectArray& GetAllAttachmentObjects() const;
Bool CheckCompleteness() const;
// aka. `buffer` as in glDrawBuffers/glReadBuffers
void SetDrawBuffer(Uint index, FramebufferAttachmentType buffer);
const FramebufferAttachmentArray& GetDrawBuffers() const;
void SetReadBuffer(FramebufferAttachmentType buf) { m_readBuffer = buf; }
FramebufferAttachmentType GetReadBuffer() const { return m_readBuffer; }
void AttachTexture(FramebufferAttachmentType type, const SharedPtr<ITextureObject>& texture, int level = 0);
void AttachRenderbuffer(FramebufferAttachmentType type, const SharedPtr<RenderbufferObject>& renderbuffer);
void Detach(FramebufferAttachmentType type);
const FramebufferAttachmentObject& GetAttachment(FramebufferAttachmentType type) const;
const FramebufferAttachmentObjectArray& GetAllAttachmentObjects() const;
Bool CheckCompleteness() const;
// aka. `buffer` as in glDrawBuffers/glReadBuffers
void SetDrawBuffer(Uint index, FramebufferAttachmentType buffer);
const FramebufferAttachmentArray& GetDrawBuffers() const;
void SetReadBuffer(FramebufferAttachmentType buf) { m_readBuffer = buf; }
FramebufferAttachmentType GetReadBuffer() const { return m_readBuffer; }
const FramebufferAttachmentVersionArray GetAllFramebufferAttachmentVersions() const {
return m_attachmentVersions;
}
FramebufferAttachmentVersionArray GetAllFramebufferAttachmentVersions() const {
return m_attachmentVersions;
}
Uint16 GetObjectVersion() const { return m_objectVersion; }
Uint16 GetObjectVersion() const { return m_objectVersion; }
Uint GetExternalIndex() const;
Uint GetExternalIndex() const;
private:
void BumpAttachmentVersion(FramebufferAttachmentType type);
private:
void BumpAttachmentVersion(FramebufferAttachmentType type);
const Uint m_externalIndex = 0;
FramebufferAttachmentObjectArray m_attachmentObjects;
FramebufferAttachmentVersionArray m_attachmentVersions;
const Uint m_externalIndex = 0;
FramebufferAttachmentObjectArray m_attachmentObjects;
FramebufferAttachmentVersionArray m_attachmentVersions;
FramebufferAttachmentArray m_drawBuffers; // Probably no versioning needed for this, just check equality
FramebufferAttachmentType m_readBuffer = FramebufferAttachmentType::Color0; // ditto
FramebufferAttachmentArray m_drawBuffers; // Probably no versioning needed for this, just check equality
FramebufferAttachmentType m_readBuffer = FramebufferAttachmentType::Color0; // ditto
// This version will bump when draw/read buffer changes (by `glDrawBuffer(s)`/`glReadBuffer`)
Uint16 m_objectVersion = 0;
};
// This version will bump when draw/read buffer changes (by `glDrawBuffer(s)`/`glReadBuffer`)
Uint16 m_objectVersion = 0;
};
} // namespace GLState
} // namespace MG_State
} // namespace MG_State::GLState
} // namespace MobileGL
@@ -9,74 +9,73 @@
#include "FramebufferState.h"
#include "MG_State/GLState/FramebufferState/FramebufferObject.h"
namespace MobileGL {
namespace MG_State {
namespace GLState {
FramebufferState::FramebufferState() {
for (SizeT i = 0; i < m_bindingSlots.size(); ++i) {
m_bindingSlots[i] = BindingSlot<FramebufferObject>(static_cast<FramebufferTarget>(i));
}
}
namespace MobileGL::MG_State::GLState {
FramebufferState::FramebufferState() {
for (SizeT i = 0; i < m_bindingSlots.size(); ++i) {
m_bindingSlots[i] = BindingSlot<FramebufferObject>(static_cast<FramebufferTarget>(i));
}
}
SharedPtr<FramebufferObject> FramebufferState::GetFramebufferObject(Uint index) {
auto it = m_framebufferObjects.find(index);
if (it != m_framebufferObjects.end()) {
return it->second;
}
return nullptr;
}
const SharedPtr<FramebufferObject>& FramebufferState::GetFramebufferObject(Uint index) {
auto it = m_framebufferObjects.find(index);
if (it != m_framebufferObjects.end()) {
return it->second;
}
static SharedPtr<FramebufferObject> nullFramebufferObject = nullptr;
return nullFramebufferObject;
}
Vector<Uint> FramebufferState::GenerateNames(Uint number) {
Vector<Uint> buffers(number);
m_indexGenerator.Generate(number, buffers.data());
return buffers;
}
void FramebufferState::GenerateNames(Uint number, Vector<Uint>& buffers) {
buffers.resize(number);
m_indexGenerator.Generate(number, buffers.data());
}
SharedPtr<FramebufferObject> FramebufferState::CreateFramebufferObject(Uint index) {
if (index == 0) {
if (!m_indexGenerator.IsValid(0)) {
m_indexGenerator.Insert(0);
} else {
return nullptr;
const SharedPtr<FramebufferObject>& FramebufferState::CreateFramebufferObject(Uint index) {
if (index == 0) {
if (!m_indexGenerator.IsValid(0)) {
m_indexGenerator.Insert(0);
} else {
static SharedPtr<FramebufferObject> nullFramebufferObject = nullptr;
return nullFramebufferObject;
}
}
auto& framebufferObject = m_framebufferObjects[index];
if (!framebufferObject) {
framebufferObject = MakeShared<FramebufferObject>(index);
}
return framebufferObject;
}
BindingSlot<FramebufferObject>& FramebufferState::GetBindingSlot(FramebufferTarget target) {
for (auto& bindingSlot : m_bindingSlots) {
if (bindingSlot.GetTarget() == target) {
return bindingSlot;
}
}
MOBILEGL_ASSERT(false, "Invalid FramebufferTarget enum value: %d", static_cast<int>(target));
return m_bindingSlots[0];
}
void FramebufferState::MarkFramebufferObjectForDeletion(Uint index) {
if (m_indexGenerator.IsValid(index)) {
auto it = m_framebufferObjects.find(index);
if (it != m_framebufferObjects.end()) {
for (auto& bindingSlot : m_bindingSlots) {
if (bindingSlot.GetBoundObject() == it->second) {
bindingSlot.Bind(nullptr);
}
}
auto bufferObject = MakeShared<FramebufferObject>(index);
m_framebufferObjects[index] = bufferObject;
return bufferObject;
m_framebufferObjects.erase(it);
}
m_indexGenerator.Delete(index);
}
}
BindingSlot<FramebufferObject>& FramebufferState::GetBindingSlot(FramebufferTarget target) {
for (SizeT i = 0; i < m_bindingSlots.size(); ++i) {
if (m_bindingSlots[i].GetTarget() == target) {
return m_bindingSlots[i];
}
}
MOBILEGL_ASSERT(false, "Invalid FramebufferTarget enum value: %d", static_cast<int>(target));
return m_bindingSlots[0];
}
Bool FramebufferState::ValidateName(Uint index) const {
return m_indexGenerator.IsValid(index);
}
void FramebufferState::MarkFramebufferObjectForDeletion(Uint index) {
if (m_indexGenerator.IsValid(index)) {
auto it = m_framebufferObjects.find(index);
if (it != m_framebufferObjects.end()) {
for (SizeT i = 0; i < m_bindingSlots.size(); ++i) {
if (m_bindingSlots[i].GetBoundObject() == it->second) {
m_bindingSlots[i].Bind(nullptr);
}
}
m_framebufferObjects.erase(it);
}
m_indexGenerator.Delete(index);
}
}
Bool FramebufferState::ValidateName(Uint index) const {
return m_indexGenerator.IsValid(index);
}
Bool FramebufferState::ValidateFramebufferObject(Uint index) const {
return m_framebufferObjects.find(index) != m_framebufferObjects.end();
}
} // namespace GLState
} // namespace MG_State
} // namespace MobileGL
Bool FramebufferState::ValidateFramebufferObject(Uint index) const {
return m_framebufferObjects.find(index) != m_framebufferObjects.end();
}
} // namespace MobileGL::MG_State::GLState
@@ -11,28 +11,24 @@
#include <MG_Util/Miscellany/IndexGenerator.h>
#include "FramebufferObject.h"
namespace MobileGL {
namespace MG_State {
namespace GLState {
class FramebufferState {
public:
FramebufferState();
namespace MobileGL::MG_State::GLState {
class FramebufferState {
public:
FramebufferState();
// FBO 0 should be created by MG_Backend when initializing the context
SharedPtr<FramebufferObject> GetFramebufferObject(Uint index);
Vector<Uint> GenerateNames(Uint number);
SharedPtr<FramebufferObject> CreateFramebufferObject(Uint index);
BindingSlot<FramebufferObject>& GetBindingSlot(FramebufferTarget target);
void MarkFramebufferObjectForDeletion(Uint index);
Bool ValidateName(Uint index) const;
Bool ValidateFramebufferObject(Uint index) const;
// FBO 0 should be created by MG_Backend when initializing the context
const SharedPtr<FramebufferObject>& GetFramebufferObject(Uint index);
void GenerateNames(Uint number, Vector<Uint>& framebuffers);
const SharedPtr<FramebufferObject>& CreateFramebufferObject(Uint index);
BindingSlot<FramebufferObject>& GetBindingSlot(FramebufferTarget target);
void MarkFramebufferObjectForDeletion(Uint index);
Bool ValidateName(Uint index) const;
Bool ValidateFramebufferObject(Uint index) const;
private:
UnorderedMap<Uint, SharedPtr<FramebufferObject>> m_framebufferObjects;
IndexGenerator<Uint> m_indexGenerator;
Array<BindingSlot<FramebufferObject>, static_cast<SizeT>(FramebufferTarget::FramebufferTargetCount)>
m_bindingSlots;
};
} // namespace GLState
} // namespace MG_State
} // namespace MobileGL
private:
UnorderedMap<Uint, SharedPtr<FramebufferObject>> m_framebufferObjects;
IndexGenerator<Uint> m_indexGenerator;
Array<BindingSlot<FramebufferObject>, static_cast<SizeT>(FramebufferTarget::FramebufferTargetCount)>
m_bindingSlots;
};
} // namespace MobileGL::MG_State::GLState
File diff suppressed because it is too large Load Diff
@@ -9,180 +9,176 @@
#pragma once
#include <Includes.h>
#include "ShaderObject.h"
#include "MG_Util/Metrics/BufferMetrics.h"
#include "MG_Util/ShaderTranspiler/SpvcSession.h"
namespace MobileGL {
namespace MG_State {
namespace GLState {
class ProgramObject {
public:
ProgramObject(Uint externalIndex) : m_externalIndex(externalIndex) {}
bool ShaderIsAttached(SharedPtr<ShaderObject> shader);
bool AttachShader(SharedPtr<ShaderObject> shader);
SizeT DetachShader(SharedPtr<ShaderObject> shader);
SizeT RemoveShader(SharedPtr<ShaderObject> shader);
void Link(Bool addDefaultFSIfMissingForRenderingPipelineProgram = false);
void MarkAsDeleted();
#include <MG_Util/Metrics/BufferMetrics.h>
#include <MG_Util/ShaderTranspiler/SpvcSession.h>
void SetExplicitVertexInLocation(Uint index, const char* name);
void SetExplicitFragmentOutLocation(Uint index, const char* name);
Int GetFragmentDataLocation(const char* name);
namespace MobileGL::MG_State::GLState {
class ProgramObject {
public:
ProgramObject(Uint externalIndex) : m_externalIndex(externalIndex) {}
bool ShaderIsAttached(const SharedPtr<ShaderObject>& shader);
bool AttachShader(const SharedPtr<ShaderObject>& shader);
SizeT DetachShader(const SharedPtr<ShaderObject>& shader);
SizeT RemoveShader(const SharedPtr<ShaderObject>& shader);
void Link(Bool addDefaultFSIfMissingForRenderingPipelineProgram = false);
void MarkAsDeleted();
Vector<SharedPtr<ShaderObject>>& GetAttachedShaders();
const Vector<SharedPtr<ShaderObject>>& GetAttachedShaders() const;
const String& GetInfoLog() const { return m_infoLog; }
Int GetUniformMaxLength() const { return m_uniformNameMaxLength; }
Uint GetUniformCount() { return m_activeUniformCount; }
Uint GetMaxUniformLocation() const { return m_maxUniformLocation; }
Int GetUniformLocation(const String& name) const {
const auto it = m_uniformLocations.find(name);
if (it == m_uniformLocations.end()) return -1;
return (Int)it->second;
}
void SetExplicitVertexInLocation(Uint index, const char* name);
void SetExplicitFragmentOutLocation(Uint index, const char* name);
Int GetFragmentDataLocation(const char* name);
GLenum GetUniformType(Uint location) const {
auto& uniform = m_program->getUniform(m_uniformIndexInTProgram[location]);
return uniform.glDefineType;
}
Vector<SharedPtr<ShaderObject>>& GetAttachedShaders();
const Vector<SharedPtr<ShaderObject>>& GetAttachedShaders() const;
const String& GetInfoLog() const { return m_infoLog; }
Int GetUniformMaxLength() const { return m_uniformNameMaxLength; }
Uint GetUniformCount() const { return m_activeUniformCount; }
Uint GetMaxUniformLocation() const { return m_maxUniformLocation; }
Int GetUniformLocation(const String& name) const {
const auto it = m_uniformLocations.find(name);
if (it == m_uniformLocations.end()) return -1;
return (Int)it->second;
}
const glslang::TType* GetUniformTType(Uint location) const {
auto& uniform = m_program->getUniform(m_uniformIndexInTProgram[location]);
return uniform.getType();
}
GLenum GetUniformType(Uint location) const {
auto& uniform = m_program->getUniform(m_uniformIndexInTProgram[location]);
return uniform.glDefineType;
}
Bool IsUniformOpaqueAtLocation(Uint location) const { return GetUniformTType(location)->isOpaque(); }
const glslang::TType* GetUniformTType(Uint location) const {
auto& uniform = m_program->getUniform(m_uniformIndexInTProgram[location]);
return uniform.getType();
}
const String& GetUniformName(Uint location) const {
auto& uniform = m_program->getUniform(m_uniformIndexInTProgram[location]);
return uniform.name;
}
Uint GetUniformOffset(Uint location) const { return m_uniformOffsets[location]; }
Uint GetUniformSizesInBytes(Uint location) const {
return MG_Util::GetGLTypeSize(GetUniformType(location));
}
Bool IsUniformOpaqueAtLocation(Uint location) const { return GetUniformTType(location)->isOpaque(); }
Int GetAttributeLocation(const String& name) {
const auto it = std::find(m_attribs.begin(), m_attribs.end(), name);
return (it == m_attribs.end()) ? -1 : std::distance(m_attribs.begin(), it);
}
GLenum GetAttribType(Uint index) const { return m_attribTypes[index]; }
const String& GetAttribName(Uint index) const { return m_attribs[index]; }
void* MapUBO() { return m_uboScratch.data(); }
const void* GetUBOData() const { return m_uboScratch.data(); }
Uint GetUBOSize() const { return static_cast<Uint>(m_uboScratch.size()); }
const String& GetUniformName(Uint location) const {
auto& uniform = m_program->getUniform(m_uniformIndexInTProgram[location]);
return uniform.name;
}
Uint GetUniformOffset(Uint location) const { return m_uniformOffsets[location]; }
Uint GetUniformSizesInBytes(Uint location) const { return MG_Util::GetGLTypeSize(GetUniformType(location)); }
void SetUniformSamplerOrImageUnitIndex(Uint location, Int unit) {
m_uniformSamplerOrImageUnitIndex[location] = unit;
}
Int GetAttributeLocation(const String& name) {
const auto it = std::find(m_attribs.begin(), m_attribs.end(), name);
return (it == m_attribs.end()) ? -1 : (Int)std::distance(m_attribs.begin(), it);
}
GLenum GetAttribType(Uint index) const { return m_attribTypes[index]; }
const String& GetAttribName(Uint index) const { return m_attribs[index]; }
void* MapUBO() { return m_uboScratch.data(); }
const void* GetUBOData() const { return m_uboScratch.data(); }
Uint GetUBOSize() const { return static_cast<Uint>(m_uboScratch.size()); }
Int GetUniformSamplerOrImageUnitIndex(Uint location) const {
return m_uniformSamplerOrImageUnitIndex[location];
}
void SetUniformSamplerOrImageUnitIndex(Uint location, Int unit) {
m_uniformSamplerOrImageUnitIndex[location] = unit;
}
Bool GetDeleteStatus() const { return m_deleteStatus; }
Bool GetLinkStatus() const { return m_linkStatus; }
Bool GetValidateStatus() const { return m_validateStatus; }
Int GetActiveAtomicCounterCount() const { return m_program->getNumAtomicCounters(); }
Int GetActiveAttributesCount() const { return m_program->getNumPipeInputs(); }
Int GetActiveUniformBlocksCount() const { return m_program->getNumUniformBlocks(); }
Int GetActiveAttributesMaxLength() const { return m_attribInNameMaxLength; }
Int GetActiveUniformBlocksMaxNameLength() const { return m_uniformBlockNameMaxLength; }
Uint GetUniformBlockIndex(const char* name) const {
auto it = m_uniformBlockIndexByName.find(name);
if (it != m_uniformBlockIndexByName.end()) return it->second;
return 0xFFFFFFFFu; // GL_INVALID_INDEX
}
Bool IsActiveUniformBlock(Uint index) const {
if (index >= GetActiveUniformBlocksCount()) return false;
return true;
}
Uint GetUBOSizeAt(Uint index) const {
if (!IsActiveUniformBlock(index)) return 0;
return m_program->getUniformBlock(index).size;
}
Int GetUniformSamplerOrImageUnitIndex(Uint location) const {
return m_uniformSamplerOrImageUnitIndex[location];
}
const String& GetUniformBlockName(Uint index) const {
auto& ubo = m_program->getUniformBlock(index);
return ubo.name;
}
Bool GetDeleteStatus() const { return m_deleteStatus; }
Bool GetLinkStatus() const { return m_linkStatus; }
Bool GetValidateStatus() const { return m_validateStatus; }
Int GetActiveAtomicCounterCount() const { return m_program->getNumAtomicCounters(); }
Int GetActiveAttributesCount() const { return m_program->getNumPipeInputs(); }
Int GetActiveUniformBlocksCount() const { return m_program->getNumUniformBlocks(); }
Int GetActiveAttributesMaxLength() const { return m_attribInNameMaxLength; }
Int GetActiveUniformBlocksMaxNameLength() const { return m_uniformBlockNameMaxLength; }
Uint GetUniformBlockIndex(const char* name) const {
auto it = m_uniformBlockIndexByName.find(name);
if (it != m_uniformBlockIndexByName.end()) return it->second;
return 0xFFFFFFFFu; // GL_INVALID_INDEX
}
Bool IsActiveUniformBlock(Uint index) const {
if (index >= GetActiveUniformBlocksCount()) return false;
return true;
}
Uint GetUBOSizeAt(Uint index) const {
if (!IsActiveUniformBlock(index)) return 0;
return m_program->getUniformBlock((Int)index).size;
}
// Set by glUniformBlockBinding
void SetUniformBlockBinding(Uint index, Uint binding) { m_uniformBlockBinding[index] = binding; }
const String& GetUniformBlockName(Uint index) const {
auto& ubo = m_program->getUniformBlock((Int)index);
return ubo.name;
}
Uint GetUniformBlockBinding(Uint index) const { return m_uniformBlockBinding[index]; }
// Set by glUniformBlockBinding
void SetUniformBlockBinding(Uint index, Uint binding) { m_uniformBlockBinding[index] = (Int)binding; }
Vector<Vector<unsigned>>& GetGeneratedSpirv() { return m_generatedSpirv; }
const Vector<Vector<unsigned>>& GetGeneratedSpirv() const { return m_generatedSpirv; }
Uint GetUniformBlockBinding(Uint index) const { return m_uniformBlockBinding[index]; }
Int GetShaderIndexByStage(ShaderStage stage) const {
auto it = std::find_if(m_shaders.begin(), m_shaders.end(),
[stage](const SharedPtr<ShaderObject>& shader) { return shader->GetShaderStage() == stage; });
return it == m_shaders.end() ? -1 : std::distance(m_shaders.begin(), it);
}
Vector<Vector<unsigned>>& GetGeneratedSpirv() { return m_generatedSpirv; }
const Vector<Vector<unsigned>>& GetGeneratedSpirv() const { return m_generatedSpirv; }
Uint GetExternalIndex() const { return m_externalIndex; }
Int GetShaderIndexByStage(ShaderStage stage) const {
auto it = std::find_if(m_shaders.begin(), m_shaders.end(), [stage](const SharedPtr<ShaderObject>& shader) {
return shader->GetShaderStage() == stage;
});
return it == m_shaders.end() ? -1 : (Int)std::distance(m_shaders.begin(), it);
}
// const UnorderedMap<String, Uint>& GetAttribLocationMap() const { return
// m_attribLocation; }
Uint GetExternalIndex() const { return m_externalIndex; }
private:
void DoReflection();
void GenerateBinary();
void WaitUntilGenerationCompleted();
void AddDefaultFragmentShaderIfMissing();
// const UnorderedMap<String, Uint>& GetAttribLocationMap() const { return
// m_attribLocation; }
const Uint m_externalIndex = 0;
Vector<SharedPtr<ShaderObject>> m_shaders;
Vector<SharedPtr<ShaderObject>> m_detachedShaders; // Store detached shaders and remove on next link
private:
void DoReflection();
void GenerateBinary();
void WaitUntilGenerationCompleted() const;
void AddDefaultFragmentShaderIfMissing();
SharedPtr<glslang::TProgram> m_program;
const Uint m_externalIndex = 0;
Vector<SharedPtr<ShaderObject>> m_shaders;
Vector<SharedPtr<ShaderObject>> m_detachedShaders; // Store detached shaders and remove on next link
Vector<Vector<unsigned>> m_generatedSpirv;
SharedPtr<glslang::TProgram> m_program;
// Attributes (Vertex in)
UnorderedMap<String, Uint> m_explicitAttribLocations;
Vector<String> m_attribs;
Vector<GLenum> m_attribTypes;
// For SpvcSession::SetVertexAttribLocation()
// UnorderedMap<String, Uint> m_attribLocation;
Vector<Vector<unsigned>> m_generatedSpirv;
// FragData (Frag out)
UnorderedMap<String, Uint> m_explicitFragDataLocation;
// Attributes (Vertex in)
UnorderedMap<String, Uint> m_explicitAttribLocations;
Vector<String> m_attribs;
Vector<GLenum> m_attribTypes;
// For SpvcSession::SetVertexAttribLocation()
// UnorderedMap<String, Uint> m_attribLocation;
// Uniforms
UnorderedMap<String, Uint> m_uniformLocations;
// Ordered by location,
// aka. m_uniformIndexInTProgram[loc] == "uniform index of TProgram at location `loc`"
Vector<Int> m_uniformIndexInTProgram;
// ditto. Will be set at glUniform1i
Vector<Int> m_uniformSamplerOrImageUnitIndex;
// FragData (Frag out)
UnorderedMap<String, Uint> m_explicitFragDataLocation;
// Ordered by uniform block index
// index is DIFFERENT from binding!!!
//
// Let's define UniformBlockIndex == the order at glslang getUniformBlock()
// aka `i = glGetUniformBlockIndex(prog, "BlockName")` implies:
// `prog->getUniformBlock(i) == "BlockName"`
UnorderedMap<String, Uint> m_uniformBlockIndexByName;
Vector<Int> m_uniformBlockBinding;
// Uniforms
UnorderedMap<String, Uint> m_uniformLocations;
// Ordered by location,
// aka. m_uniformIndexInTProgram[loc] == "uniform index of TProgram at location `loc`"
Vector<Int> m_uniformIndexInTProgram;
// ditto. Will be set at glUniform1i
Vector<Int> m_uniformSamplerOrImageUnitIndex;
// Need to be reflected after linking of SPIR-V binary
Vector<Uint> m_uniformOffsets;
Vector<Uint> m_uniformSizesInBytes;
Vector<Uint8> m_uboScratch;
// Ordered by uniform block index
// index is DIFFERENT from binding!!!
//
// Let's define UniformBlockIndex == the order at glslang getUniformBlock()
// aka `i = glGetUniformBlockIndex(prog, "BlockName")` implies:
// `prog->getUniformBlock(i) == "BlockName"`
UnorderedMap<String, Uint> m_uniformBlockIndexByName;
Vector<Int> m_uniformBlockBinding;
Uint m_activeUniformCount = 0;
Uint m_maxUniformLocation = 0;
Int m_uniformNameMaxLength = 0;
Int m_attribInNameMaxLength = 0;
Int m_uniformBlockNameMaxLength = 0;
// Need to be reflected after linking of SPIR-V binary
Vector<Uint> m_uniformOffsets;
Vector<Uint> m_uniformSizesInBytes;
Vector<Uint8> m_uboScratch;
String m_infoLog;
Bool m_deleteStatus = false;
Bool m_linkStatus = false;
Bool m_validateStatus = true;
};
} // namespace GLState
} // namespace MG_State
} // namespace MobileGL
Uint m_activeUniformCount = 0;
Uint m_maxUniformLocation = 0;
Int m_uniformNameMaxLength = 0;
Int m_attribInNameMaxLength = 0;
Int m_uniformBlockNameMaxLength = 0;
String m_infoLog;
Bool m_deleteStatus = false;
Bool m_linkStatus = false;
Bool m_validateStatus = true;
};
} // namespace MobileGL::MG_State::GLState
@@ -8,73 +8,71 @@
#include "ProgramState.h"
namespace MobileGL {
namespace MG_State {
namespace GLState {
Uint ProgramState::CreateProgram() {
Uint programId = 0;
m_programIndexGenerator.Generate(1, &programId);
EnsureIndexAvail(programId, m_programObjects);
auto programObject = MakeShared<ProgramObject>(programId);
if (programObject == nullptr) return 0;
m_programObjects[programId] = programObject;
return programId;
}
namespace MobileGL::MG_State::GLState {
Uint ProgramState::CreateProgram() {
Uint programId = 0;
m_programIndexGenerator.Generate(1, &programId);
EnsureIndexAvail(programId, m_programObjects);
auto programObject = MakeShared<ProgramObject>(programId);
if (programObject == nullptr) return 0;
m_programObjects[programId] = programObject;
return programId;
}
SharedPtr<ProgramObject> ProgramState::GetProgramObject(const Uint id) {
if (!CheckIndexAvail(id, m_programObjects)) return nullptr; // FIXME: add error reporting here
return m_programObjects[id];
}
const SharedPtr<ProgramObject>& ProgramState::GetProgramObject(const Uint id) {
static SharedPtr<ProgramObject> nullProgramObject = nullptr;
if (!CheckIndexAvail(id, m_programObjects)) return nullProgramObject; // FIXME: add error reporting here
return m_programObjects[id];
}
void ProgramState::MarkProgramObjectForDeletion(const Uint program) {
if (!CheckIndexAvail(program, m_programObjects)) return; // FIXME: add error reporting here
auto& programObject = m_programObjects[program];
if (programObject != nullptr) {
programObject->MarkAsDeleted();
programObject.reset();
m_programIndexGenerator.Delete(program);
}
}
void ProgramState::MarkProgramObjectForDeletion(const Uint program) {
if (!CheckIndexAvail(program, m_programObjects)) return; // FIXME: add error reporting here
auto& programObject = m_programObjects[program];
if (programObject != nullptr) {
programObject->MarkAsDeleted();
programObject.reset();
m_programIndexGenerator.Delete(program);
}
}
Bool ProgramState::ValidateProgramObject(const Uint program) const {
return CheckIndexAvail(program, m_programObjects) && m_programObjects[program] != nullptr;
}
Bool ProgramState::ValidateProgramObject(const Uint program) const {
return CheckIndexAvail(program, m_programObjects) && m_programObjects[program] != nullptr;
}
void ProgramState::UseProgram(Uint program) {
if (program == 0) m_currentProgram.reset();
void ProgramState::UseProgram(Uint program) {
if (program == 0) m_currentProgram.reset();
if (!CheckIndexAvail(program, m_programObjects)) return;
m_currentProgram = m_programObjects[program];
}
if (!CheckIndexAvail(program, m_programObjects)) return;
m_currentProgram = m_programObjects[program];
}
Uint ProgramState::CreateShader(ShaderStage stage) {
Uint shaderId = 0;
m_shaderIndexGenerator.Generate(1, &shaderId);
EnsureIndexAvail(shaderId, m_shaderObjects);
auto shaderObject = MakeShared<ShaderObject>(stage, shaderId);
if (shaderObject == nullptr) return 0;
m_shaderObjects[shaderId] = shaderObject;
return shaderId;
}
Uint ProgramState::CreateShader(ShaderStage stage) {
Uint shaderId = 0;
m_shaderIndexGenerator.Generate(1, &shaderId);
EnsureIndexAvail(shaderId, m_shaderObjects);
auto shaderObject = MakeShared<ShaderObject>(stage, shaderId);
if (shaderObject == nullptr) return 0;
m_shaderObjects[shaderId] = shaderObject;
return shaderId;
}
SharedPtr<ShaderObject> ProgramState::GetShaderObject(const Uint shader) {
if (!CheckIndexAvail(shader, m_shaderObjects)) return nullptr;
return m_shaderObjects[shader];
}
const SharedPtr<ShaderObject>& ProgramState::GetShaderObject(const Uint shader) {
static SharedPtr<ShaderObject> nullShaderObject = nullptr;
if (!CheckIndexAvail(shader, m_shaderObjects)) return nullShaderObject;
return m_shaderObjects[shader];
}
void ProgramState::MarkShaderObjectForDeletion(Uint shader) {
if (!CheckIndexAvail(shader, m_shaderObjects)) return;
auto& shaderObject = m_shaderObjects[shader];
if (shaderObject != nullptr) {
m_shaderObjects[shader]->MarkAsDeleted();
m_shaderObjects[shader].reset();
m_shaderIndexGenerator.Delete(shader);
}
}
void ProgramState::MarkShaderObjectForDeletion(Uint shader) {
if (!CheckIndexAvail(shader, m_shaderObjects)) return;
auto& shaderObject = m_shaderObjects[shader];
if (shaderObject != nullptr) {
m_shaderObjects[shader]->MarkAsDeleted();
m_shaderObjects[shader].reset();
m_shaderIndexGenerator.Delete(shader);
}
}
Bool ProgramState::ValidateShaderObject(Uint shader) const {
return CheckIndexAvail(shader, m_shaderObjects) && m_shaderObjects[shader] != nullptr;
}
} // namespace GLState
} // namespace MG_State
} // namespace MobileGL
Bool ProgramState::ValidateShaderObject(Uint shader) const {
return CheckIndexAvail(shader, m_shaderObjects) && m_shaderObjects[shader] != nullptr;
}
} // namespace MobileGL::MG_State::GLState
@@ -11,49 +11,45 @@
#include <MG_Util/Miscellany/IndexGenerator.h>
#include "ProgramObject.h"
namespace MobileGL {
namespace MG_State {
namespace GLState {
class ProgramState {
public:
// This function WILL actually create the program object.
// To retrieve created program object, use GetProgramObject()
Uint CreateProgram();
SharedPtr<ProgramObject> GetProgramObject(Uint id);
void MarkProgramObjectForDeletion(Uint program);
Bool ValidateProgramObject(Uint program) const;
namespace MobileGL::MG_State::GLState {
class ProgramState {
public:
// This function WILL actually create the program object.
// To retrieve created program object, use GetProgramObject()
Uint CreateProgram();
const SharedPtr<ProgramObject>& GetProgramObject(Uint id);
void MarkProgramObjectForDeletion(Uint program);
Bool ValidateProgramObject(Uint program) const;
void UseProgram(Uint program);
void UseProgram(Uint program);
Uint CreateShader(ShaderStage stage);
SharedPtr<ShaderObject> GetShaderObject(Uint shader);
void MarkShaderObjectForDeletion(Uint shader);
Bool ValidateShaderObject(Uint shader) const;
Uint CreateShader(ShaderStage stage);
const SharedPtr<ShaderObject>& GetShaderObject(Uint shader);
void MarkShaderObjectForDeletion(Uint shader);
Bool ValidateShaderObject(Uint shader) const;
SharedPtr<ProgramObject> GetCurrentProgram() const { return m_currentProgram; }
const SharedPtr<ProgramObject>& GetCurrentProgram() const { return m_currentProgram; }
private:
template <typename T>
static Bool CheckIndexAvail(const SizeT idx, const Vector<T>& vec) {
return idx < vec.size();
}
private:
template <typename T>
static Bool CheckIndexAvail(const SizeT idx, const Vector<T>& vec) {
return idx < vec.size();
}
template <typename T>
static void EnsureIndexAvail(const SizeT idx, Vector<T>& vec) {
if (CheckIndexAvail(idx, vec)) return;
template <typename T>
static void EnsureIndexAvail(const SizeT idx, Vector<T>& vec) {
if (CheckIndexAvail(idx, vec)) return;
vec.reserve(std::bit_ceil(idx));
vec.resize(idx + 1);
}
vec.reserve(std::bit_ceil(idx));
vec.resize(idx + 1);
}
IndexGenerator<Uint> m_programIndexGenerator;
Vector<SharedPtr<ProgramObject>> m_programObjects;
IndexGenerator<Uint> m_programIndexGenerator;
Vector<SharedPtr<ProgramObject>> m_programObjects;
IndexGenerator<Uint> m_shaderIndexGenerator;
Vector<SharedPtr<ShaderObject>> m_shaderObjects;
IndexGenerator<Uint> m_shaderIndexGenerator;
Vector<SharedPtr<ShaderObject>> m_shaderObjects;
SharedPtr<ProgramObject> m_currentProgram;
};
} // namespace GLState
} // namespace MG_State
} // namespace MobileGL
SharedPtr<ProgramObject> m_currentProgram;
};
} // namespace MobileGL::MG_State::GLState
@@ -13,43 +13,40 @@
#include <MG_Util/ShaderTranspiler/ShaderSourceProcessor.h>
#include <MG_Util/ShaderTranspiler/glslang/UniformTraverser.h>
namespace MobileGL {
namespace MG_State {
namespace GLState {
void ShaderObject::SetShaderSource(const String& source) {
m_source = source;
}
namespace MobileGL::MG_State::GLState {
void ShaderObject::SetShaderSource(const String& source) {
m_source = source;
}
void ShaderObject::SetShaderSource(String&& source) {
m_source = Move(source);
}
void ShaderObject::SetShaderSource(String&& source) {
m_source = Move(source);
}
void ShaderObject::Compile() {
using namespace MG_Util::ShaderTranspiler;
MG_Util::ShaderTranspiler::PreprocessShaderSource(m_stage, m_source);
void ShaderObject::Compile() {
using namespace MG_Util::ShaderTranspiler;
MG_Util::ShaderTranspiler::PreprocessShaderSource(m_stage, m_source);
// Compile for OpenGL here, so that we can do validation and link
// like a real OpenGL driver at linking stage
// Will compile for other backends later.
ShaderAttrib attrib{
.shaderType = MG_Util::ConvertShaderStageToGLEnum(m_stage), .sourceStr = m_source, .flags = ShaderCompileBits::CompileForOpenGL};
// Compile for OpenGL here, so that we can do validation and link
// like a real OpenGL driver at linking stage
// Will compile for other backends later.
ShaderAttrib attrib{.shaderType = MG_Util::ConvertShaderStageToGLEnum(m_stage),
.sourceStr = m_source,
.flags = ShaderCompileBits::CompileForOpenGL};
auto result = ShaderCompiler::CompileShader(attrib);
if (result) {
m_compileStatus = true;
m_shader = result.value();
} else {
m_compileStatus = false;
m_infoLog = result.error().log;
MGLOG_D("ShaderObject::Compile: Shader %d compilation failed.\nSource:\n%s\nInfoLog:\n%s\nSetting "
"m_compileStatus = false as a result.",
m_externalIndex, m_source.c_str(), m_infoLog.c_str());
}
}
auto result = ShaderCompiler::CompileShader(attrib);
if (result) {
m_compileStatus = true;
m_shader = result.value();
} else {
m_compileStatus = false;
m_infoLog = result.error().log;
MGLOG_D("ShaderObject::Compile: Shader %d compilation failed.\nSource:\n%s\nInfoLog:\n%s\nSetting "
"m_compileStatus = false as a result.",
m_externalIndex, m_source.c_str(), m_infoLog.c_str());
}
}
void ShaderObject::MarkAsDeleted() {
m_deleteStatus = true;
}
} // namespace GLState
} // namespace MG_State
} // namespace MobileGL
void ShaderObject::MarkAsDeleted() {
m_deleteStatus = true;
}
} // namespace MobileGL::MG_State::GLState
@@ -21,37 +21,35 @@ namespace MobileGL {
Unknown = -1
};
namespace MG_State {
namespace GLState {
class ShaderObject {
public:
ShaderObject(const ShaderStage stage, Uint externalIndex)
: m_stage(stage), m_externalIndex(externalIndex) {}
void SetShaderSource(const String& source);
void SetShaderSource(String&& source);
void Compile();
void MarkAsDeleted();
namespace MG_State::GLState {
class ShaderObject {
public:
ShaderObject(const ShaderStage stage, Uint externalIndex)
: m_stage(stage), m_externalIndex(externalIndex) {}
void SetShaderSource(const String& source);
void SetShaderSource(String&& source);
void Compile();
void MarkAsDeleted();
Uint GetExternalIndex() const { return m_externalIndex; }
ShaderStage GetShaderStage() const { return m_stage; }
const String& GetShaderSource() const { return m_source; }
SharedPtr<glslang::TShader> GetCompiledShader() const { return m_shader; }
const String& GetInfoLog() const { return m_infoLog; }
const UnorderedMap<String, Uint>& GetUniformLocations() const { return m_uniforms; }
Bool GetCompileStatus() const { return m_compileStatus; }
Bool GetDeleteStatus() const { return m_deleteStatus; }
Uint GetExternalIndex() const { return m_externalIndex; }
ShaderStage GetShaderStage() const { return m_stage; }
const String& GetShaderSource() const { return m_source; }
const SharedPtr<glslang::TShader>& GetCompiledShader() const { return m_shader; }
const String& GetInfoLog() const { return m_infoLog; }
const UnorderedMap<String, Uint>& GetUniformLocations() const { return m_uniforms; }
Bool GetCompileStatus() const { return m_compileStatus; }
Bool GetDeleteStatus() const { return m_deleteStatus; }
private:
const Uint m_externalIndex = 0;
const ShaderStage m_stage;
String m_source;
SharedPtr<glslang::TShader> m_shader;
UnorderedMap<String, Uint> m_uniforms;
private:
const Uint m_externalIndex = 0;
const ShaderStage m_stage;
String m_source;
SharedPtr<glslang::TShader> m_shader;
UnorderedMap<String, Uint> m_uniforms;
String m_infoLog;
Bool m_deleteStatus = false;
Bool m_compileStatus = false;
};
} // namespace GLState
} // namespace MG_State
String m_infoLog;
Bool m_deleteStatus = false;
Bool m_compileStatus = false;
};
} // namespace MG_State::GLState
} // namespace MobileGL
@@ -38,8 +38,8 @@ namespace MobileGL {
void RenderState::SetCapability(CapabilityInput cap, Bool enabled) {
#define SET_CAPABILITY(capability, flag) \
case CapabilityInput::capability: \
if (m_parameters.capability##Enabled == flag) break; \
m_parameters.capability##Enabled = flag; \
if (m_parameters.capability##Enabled == (flag)) break; \
m_parameters.capability##Enabled = (flag); \
++m_version; \
break;
@@ -195,7 +195,7 @@ namespace MobileGL {
++m_version;
}
const BoolVec4 RenderState::GetColorMask() const {
BoolVec4 RenderState::GetColorMask() const {
return m_parameters.ColorMask;
}
@@ -237,8 +237,8 @@ namespace MobileGL {
void RenderState::SetPixelStoreParam(PixelStoreParam param, Int value) {
#define SET_PIXEL_STORE_PARAM(paramNameHead, paramNameTail, val) \
case PixelStoreParam::paramNameHead##paramNameTail: \
if (m_pixelStore##paramNameHead##Parameters.paramNameTail == val) break; \
m_pixelStore##paramNameHead##Parameters.paramNameTail = val; \
if (m_pixelStore##paramNameHead##Parameters.paramNameTail == (val)) break; \
m_pixelStore##paramNameHead##Parameters.paramNameTail = (val); \
break;
switch (param) {
@@ -201,7 +201,7 @@ namespace MobileGL {
// Color Mask
void SetColorMask(BoolVec4 mask);
const BoolVec4 GetColorMask() const;
BoolVec4 GetColorMask() const;
// Clear State
void SetClearColor(FloatVec4 color);
@@ -7,68 +7,67 @@
// End of Source File Header
#include "RenderbufferState.h"
#include "MG_Util/Types.h"
namespace MobileGL {
namespace MG_State {
namespace GLState {
RenderbufferState::RenderbufferState() : m_indexGenerator(1024, 1) {
for (SizeT i = 0; i < m_bindingSlots.size(); ++i) {
m_bindingSlots[i] = BindingSlot<RenderbufferObject>(static_cast<RenderbufferTarget>(i));
}
namespace MobileGL::MG_State::GLState {
RenderbufferState::RenderbufferState() : m_indexGenerator(1024, 1) {
for (SizeT i = 0; i < m_bindingSlots.size(); ++i) {
m_bindingSlots[i] = BindingSlot<RenderbufferObject>(static_cast<RenderbufferTarget>(i));
}
}
const SharedPtr<RenderbufferObject>& RenderbufferState::GetRenderbufferObject(Uint index) {
auto it = m_renderbufferObjects.find(index);
if (it != m_renderbufferObjects.end()) {
return it->second;
}
static SharedPtr<RenderbufferObject> nullRenderbufferObject = nullptr;
return nullRenderbufferObject;
}
void RenderbufferState::GenerateNames(Uint number, Vector<Uint>& renderbuffers) {
renderbuffers.resize(number);
m_indexGenerator.Generate(number, renderbuffers.data());
}
const SharedPtr<RenderbufferObject>& RenderbufferState::CreateRenderbufferObject(Uint index) {
auto& bufferObject = m_renderbufferObjects[index];
if (!bufferObject) {
bufferObject = MakeShared<RenderbufferObject>(index);
}
return bufferObject;
}
BindingSlot<RenderbufferObject>& RenderbufferState::GetBindingSlot(RenderbufferTarget target) {
for (auto& bindingSlot : m_bindingSlots) {
if (bindingSlot.GetTarget() == target) {
return bindingSlot;
}
}
MOBILEGL_ASSERT(false, "Invalid RenderbufferTarget enum value: %d", static_cast<int>(target));
return m_bindingSlots[0];
}
SharedPtr<RenderbufferObject> RenderbufferState::GetRenderbufferObject(Uint index) {
auto it = m_renderbufferObjects.find(index);
if (it != m_renderbufferObjects.end()) {
return it->second;
}
return nullptr;
}
Vector<Uint> RenderbufferState::GenerateNames(Uint number) {
Vector<Uint> buffers(number);
m_indexGenerator.Generate(number, buffers.data());
return buffers;
}
SharedPtr<RenderbufferObject> RenderbufferState::CreateRenderbufferObject(Uint index) {
auto bufferObject = MakeShared<RenderbufferObject>(index);
m_renderbufferObjects[index] = bufferObject;
return bufferObject;
}
BindingSlot<RenderbufferObject>& RenderbufferState::GetBindingSlot(RenderbufferTarget target) {
for (SizeT i = 0; i < m_bindingSlots.size(); ++i) {
if (m_bindingSlots[i].GetTarget() == target) {
return m_bindingSlots[i];
void RenderbufferState::MarkRenderbufferObjectForDeletion(Uint index) {
if (m_indexGenerator.IsValid(index)) {
auto it = m_renderbufferObjects.find(index);
if (it != m_renderbufferObjects.end()) {
for (auto& bindingSlot : m_bindingSlots) {
if (bindingSlot.GetBoundObject() == it->second) {
bindingSlot.Bind(nullptr);
}
}
MOBILEGL_ASSERT(false, "Invalid RenderbufferTarget enum value: %d", static_cast<int>(target));
return m_bindingSlots[0];
m_renderbufferObjects.erase(it);
}
m_indexGenerator.Delete(index);
}
}
void RenderbufferState::MarkRenderbufferObjectForDeletion(Uint index) {
if (m_indexGenerator.IsValid(index)) {
auto it = m_renderbufferObjects.find(index);
if (it != m_renderbufferObjects.end()) {
for (SizeT i = 0; i < m_bindingSlots.size(); ++i) {
if (m_bindingSlots[i].GetBoundObject() == it->second) {
m_bindingSlots[i].Bind(nullptr);
}
}
m_renderbufferObjects.erase(it);
}
m_indexGenerator.Delete(index);
}
}
Bool RenderbufferState::ValidateName(Uint index) const {
return m_indexGenerator.IsValid(index);
}
Bool RenderbufferState::ValidateName(Uint index) const {
return m_indexGenerator.IsValid(index);
}
Bool RenderbufferState::ValidateRenderbufferObject(Uint index) const {
return m_renderbufferObjects.find(index) != m_renderbufferObjects.end();
}
} // namespace GLState
} // namespace MG_State
} // namespace MobileGL
Bool RenderbufferState::ValidateRenderbufferObject(Uint index) const {
return m_renderbufferObjects.find(index) != m_renderbufferObjects.end();
}
} // namespace MobileGL::MG_State::GLState
@@ -11,27 +11,23 @@
#include <MG_Util/Miscellany/IndexGenerator.h>
#include "RenderbufferObject.h"
namespace MobileGL {
namespace MG_State {
namespace GLState {
class RenderbufferState {
public:
RenderbufferState();
namespace MobileGL::MG_State::GLState {
class RenderbufferState {
public:
RenderbufferState();
SharedPtr<RenderbufferObject> GetRenderbufferObject(Uint index);
Vector<Uint> GenerateNames(Uint number);
SharedPtr<RenderbufferObject> CreateRenderbufferObject(Uint index);
BindingSlot<RenderbufferObject>& GetBindingSlot(RenderbufferTarget target);
void MarkRenderbufferObjectForDeletion(Uint index);
Bool ValidateName(Uint index) const;
Bool ValidateRenderbufferObject(Uint index) const;
const SharedPtr<RenderbufferObject>& GetRenderbufferObject(Uint index);
void GenerateNames(Uint number, Vector<Uint>& renderbuffers);
const SharedPtr<RenderbufferObject>& CreateRenderbufferObject(Uint index);
BindingSlot<RenderbufferObject>& GetBindingSlot(RenderbufferTarget target);
void MarkRenderbufferObjectForDeletion(Uint index);
Bool ValidateName(Uint index) const;
Bool ValidateRenderbufferObject(Uint index) const;
private:
UnorderedMap<Uint, SharedPtr<RenderbufferObject>> m_renderbufferObjects;
IndexGenerator<Uint> m_indexGenerator;
Array<BindingSlot<RenderbufferObject>, static_cast<SizeT>(RenderbufferTarget::RenderbufferTargetCount)>
m_bindingSlots;
};
} // namespace GLState
} // namespace MG_State
} // namespace MobileGL
private:
UnorderedMap<Uint, SharedPtr<RenderbufferObject>> m_renderbufferObjects;
IndexGenerator<Uint> m_indexGenerator;
Array<BindingSlot<RenderbufferObject>, static_cast<SizeT>(RenderbufferTarget::RenderbufferTargetCount)>
m_bindingSlots;
};
} // namespace MobileGL::MG_State::GLState
@@ -8,42 +8,38 @@
#include "SamplerState.h"
namespace MobileGL {
namespace MG_State {
namespace GLState {
SamplerState::SamplerState() : m_indexGenerator(1024, 1) {}
namespace MobileGL::MG_State::GLState {
SamplerState::SamplerState() : m_indexGenerator(1024, 1) {}
Vector<Uint> SamplerState::GenerateNames(Uint number) {
Vector<Uint> names(number);
m_indexGenerator.Generate(number, names.data());
return names;
}
void SamplerState::GenerateNames(Uint number, Vector<Uint>& samplers) {
samplers.resize(number);
m_indexGenerator.Generate(number, samplers.data());
}
SharedPtr<SamplerObject> SamplerState::GetSamplerObject(Uint index) {
auto it = m_samplerObjects.find(index);
return it != m_samplerObjects.end() ? it->second : nullptr;
}
const SharedPtr<SamplerObject>& SamplerState::GetSamplerObject(Uint index) {
auto it = m_samplerObjects.find(index);
static SharedPtr<SamplerObject> nullSamplerObject = nullptr;
return it != m_samplerObjects.end() ? it->second : nullSamplerObject;
}
SharedPtr<SamplerObject> SamplerState::CreateSamplerObject(Uint index) {
auto sampler = MakeShared<SamplerObject>(index);
m_samplerObjects[index] = sampler;
return sampler;
}
const SharedPtr<SamplerObject>& SamplerState::CreateSamplerObject(Uint index) {
auto& sampler = m_samplerObjects[index];
sampler = MakeShared<SamplerObject>(index);
return sampler;
}
void SamplerState::MarkSamplerObjectForDeletion(Uint index) {
if (m_indexGenerator.IsValid(index)) {
m_samplerObjects.erase(index);
m_indexGenerator.Delete(index);
}
}
void SamplerState::MarkSamplerObjectForDeletion(Uint index) {
if (m_indexGenerator.IsValid(index)) {
m_samplerObjects.erase(index);
m_indexGenerator.Delete(index);
}
}
Bool SamplerState::ValidateName(Uint index) const {
return m_indexGenerator.IsValid(index);
}
Bool SamplerState::ValidateName(Uint index) const {
return m_indexGenerator.IsValid(index);
}
Bool SamplerState::ValidateSamplerObject(Uint index) const {
return m_samplerObjects.find(index) != m_samplerObjects.end();
}
} // namespace GLState
} // namespace MG_State
} // namespace MobileGL
Bool SamplerState::ValidateSamplerObject(Uint index) const {
return m_samplerObjects.find(index) != m_samplerObjects.end();
}
} // namespace MobileGL::MG_State::GLState
@@ -18,9 +18,9 @@ namespace MobileGL {
public:
SamplerState();
Vector<Uint> GenerateNames(Uint number);
SharedPtr<SamplerObject> GetSamplerObject(Uint index);
SharedPtr<SamplerObject> CreateSamplerObject(Uint index);
void GenerateNames(Uint number, Vector<Uint>& samplers);
const SharedPtr<SamplerObject>& GetSamplerObject(Uint index);
const SharedPtr<SamplerObject>& CreateSamplerObject(Uint index);
void MarkSamplerObjectForDeletion(Uint index);
Bool ValidateName(Uint index) const;
Bool ValidateSamplerObject(Uint index) const;
@@ -31,7 +31,7 @@ namespace MobileGL {
return {0, 0, 0};
}
SharedPtr<SamplerObject> TextureObjectBase::GetSamplerObject() const {
const SharedPtr<SamplerObject>& TextureObjectBase::GetSamplerObject() const {
return m_sampler;
}
@@ -14,113 +14,107 @@
#include <Includes.h>
#include <MG_Util/Math/VectorTypes.h>
namespace MobileGL {
namespace MG_State {
namespace GLState {
class ITextureObject {
public:
using TargetEnum = TextureTarget;
virtual ~ITextureObject() = default;
namespace MobileGL::MG_State::GLState {
class ITextureObject {
public:
using TargetEnum = TextureTarget;
virtual ~ITextureObject() = default;
virtual TextureStorageType GetStorageType() const = 0;
virtual TextureStorageType GetStorageType() const = 0;
virtual TextureInternalFormat GetFormat() const = 0;
virtual TextureTarget GetTarget() const = 0;
virtual const Vector<TextureUploadTarget>& GetUploadTargets() const = 0;
virtual IntVec3 GetBaseSize() const = 0;
virtual SharedPtr<SamplerObject> GetSamplerObject() const = 0;
virtual void SetInternalFormat(TextureInternalFormat format) = 0;
virtual Bool IsComplete() const = 0;
virtual Uint GetExternalIndex() const = 0;
virtual const FloatVec4& GetBorderColor() const = 0;
virtual void SetBorderColor(const FloatVec4& color) = 0;
virtual TextureSwizzleParam GetSwizzleParam(TextureSwizzleParam param) const = 0;
virtual void SetSwizzleParam(TextureSwizzleParam param, TextureSwizzleParam value) = 0;
virtual void SetSwizzleParamRGBA(const Vec4<TextureSwizzleParam>& values) = 0;
virtual const Vec4<TextureSwizzleParam>& GetAllSwizzleParams() const = 0;
virtual const UintVec2& GetLevelRange() const = 0;
virtual void SetBaseLevel(Uint baseLevel) = 0;
virtual void SetMaxLevel(Uint maxLevel) = 0;
virtual Uint16 GetTextureParamsVersion() const = 0;
virtual TextureInternalFormat GetFormat() const = 0;
virtual TextureTarget GetTarget() const = 0;
virtual const Vector<TextureUploadTarget>& GetUploadTargets() const = 0;
virtual IntVec3 GetBaseSize() const = 0;
virtual const SharedPtr<SamplerObject>& GetSamplerObject() const = 0;
virtual void SetInternalFormat(TextureInternalFormat format) = 0;
virtual Bool IsComplete() const = 0;
virtual Uint GetExternalIndex() const = 0;
virtual const FloatVec4& GetBorderColor() const = 0;
virtual void SetBorderColor(const FloatVec4& color) = 0;
virtual TextureSwizzleParam GetSwizzleParam(TextureSwizzleParam param) const = 0;
virtual void SetSwizzleParam(TextureSwizzleParam param, TextureSwizzleParam value) = 0;
virtual void SetSwizzleParamRGBA(const Vec4<TextureSwizzleParam>& values) = 0;
virtual const Vec4<TextureSwizzleParam>& GetAllSwizzleParams() const = 0;
virtual const UintVec2& GetLevelRange() const = 0;
virtual void SetBaseLevel(Uint baseLevel) = 0;
virtual void SetMaxLevel(Uint maxLevel) = 0;
virtual Uint16 GetTextureParamsVersion() const = 0;
protected:
virtual Uint GetIndexOfTextureUploadTarget(TextureUploadTarget target) const = 0;
};
protected:
virtual Uint GetIndexOfTextureUploadTarget(TextureUploadTarget target) const = 0;
};
class TextureObjectBase : public ITextureObject {
public:
TextureObjectBase(TextureTarget target, Uint externalIndex);
virtual ~TextureObjectBase() = default;
class TextureObjectBase : public ITextureObject {
public:
TextureObjectBase(TextureTarget target, Uint externalIndex);
virtual ~TextureObjectBase() = default;
TextureInternalFormat GetFormat() const override;
TextureTarget GetTarget() const override;
IntVec3 GetBaseSize() const override;
SharedPtr<SamplerObject> GetSamplerObject() const override;
void SetInternalFormat(TextureInternalFormat format) override;
Bool IsComplete() const override;
Uint GetExternalIndex() const override;
const FloatVec4& GetBorderColor() const override;
void SetBorderColor(const FloatVec4& color) override;
TextureSwizzleParam GetSwizzleParam(TextureSwizzleParam param) const override;
const Vec4<TextureSwizzleParam>& GetAllSwizzleParams() const override;
void SetSwizzleParam(TextureSwizzleParam param, TextureSwizzleParam value) override;
void SetSwizzleParamRGBA(const Vec4<TextureSwizzleParam>& values) override;
const UintVec2& GetLevelRange() const override;
void SetBaseLevel(Uint baseLevel) override;
void SetMaxLevel(Uint maxLevel) override;
Uint16 GetTextureParamsVersion() const override;
TextureInternalFormat GetFormat() const override;
TextureTarget GetTarget() const override;
IntVec3 GetBaseSize() const override;
const SharedPtr<SamplerObject>& GetSamplerObject() const override;
void SetInternalFormat(TextureInternalFormat format) override;
Bool IsComplete() const override;
Uint GetExternalIndex() const override;
const FloatVec4& GetBorderColor() const override;
void SetBorderColor(const FloatVec4& color) override;
TextureSwizzleParam GetSwizzleParam(TextureSwizzleParam param) const override;
const Vec4<TextureSwizzleParam>& GetAllSwizzleParams() const override;
void SetSwizzleParam(TextureSwizzleParam param, TextureSwizzleParam value) override;
void SetSwizzleParamRGBA(const Vec4<TextureSwizzleParam>& values) override;
const UintVec2& GetLevelRange() const override;
void SetBaseLevel(Uint baseLevel) override;
void SetMaxLevel(Uint maxLevel) override;
Uint16 GetTextureParamsVersion() const override;
protected:
const Uint m_externalIndex;
const TextureTarget m_target = TextureTarget::Unknown;
TextureInternalFormat m_internalFormat = TextureInternalFormat::Unknown;
SharedPtr<SamplerObject> m_sampler = nullptr;
FloatVec4 m_borderColor = {0.0f, 0.0f, 0.0f, 0.0f};
Vec4<TextureSwizzleParam> m_swizzleParams = {TextureSwizzleParam::Red, TextureSwizzleParam::Green,
TextureSwizzleParam::Blue, TextureSwizzleParam::Alpha};
UintVec2 m_levelRange = {0, 1000};
Uint16 m_textureParamsVersion = 0;
};
protected:
const Uint m_externalIndex;
const TextureTarget m_target = TextureTarget::Unknown;
TextureInternalFormat m_internalFormat = TextureInternalFormat::Unknown;
SharedPtr<SamplerObject> m_sampler = nullptr;
FloatVec4 m_borderColor = {0.0f, 0.0f, 0.0f, 0.0f};
Vec4<TextureSwizzleParam> m_swizzleParams = {TextureSwizzleParam::Red, TextureSwizzleParam::Green,
TextureSwizzleParam::Blue, TextureSwizzleParam::Alpha};
UintVec2 m_levelRange = {0, 1000};
Uint16 m_textureParamsVersion = 0;
};
class TextureObjectMipmap : public TextureObjectBase {
public:
TextureObjectMipmap(TextureTarget target, Uint externalIndex)
: TextureObjectBase(target, externalIndex) {}
class TextureObjectMipmap : public TextureObjectBase {
public:
TextureObjectMipmap(TextureTarget target, Uint externalIndex) : TextureObjectBase(target, externalIndex) {}
TextureStorageType GetStorageType() const override { return TextureStorageType::Mipmap; }
TextureStorageType GetStorageType() const override { return TextureStorageType::Mipmap; }
virtual Uint GetMipmapLevelCount() const = 0;
virtual const IntVec3 GetMipmapTexelSize(TextureUploadTarget target, Uint mipmapLevel) const = 0;
virtual const SizeT GetMipmapByteSize(TextureUploadTarget target, Uint mipmapLevel) const = 0;
virtual void AllocateStorage(TextureUploadTarget uploadTarget, Uint mipmapLevel, MipmapInput input) = 0;
virtual void UpdateMipmapSubData(TextureUploadTarget uploadTarget, Uint mipmapLevel, DataPtr input) = 0;
virtual void* MapMipmapData(TextureUploadTarget uploadTarget, Uint mipmapLevel) = 0;
virtual void MarkStorageDirty(TextureUploadTarget uploadTarget, Uint mipmapLevel,
Bool dirty = true) = 0;
virtual Bool IsStorageDirty(TextureUploadTarget uploadTarget, Uint mipmapLevel) const = 0;
};
virtual Uint GetMipmapLevelCount() const = 0;
virtual const IntVec3 GetMipmapTexelSize(TextureUploadTarget target, Uint mipmapLevel) const = 0;
virtual const SizeT GetMipmapByteSize(TextureUploadTarget target, Uint mipmapLevel) const = 0;
virtual void AllocateStorage(TextureUploadTarget uploadTarget, Uint mipmapLevel, MipmapInput input) = 0;
virtual void UpdateMipmapSubData(TextureUploadTarget uploadTarget, Uint mipmapLevel, DataPtr input) = 0;
virtual void* MapMipmapData(TextureUploadTarget uploadTarget, Uint mipmapLevel) = 0;
virtual void MarkStorageDirty(TextureUploadTarget uploadTarget, Uint mipmapLevel, Bool dirty = true) = 0;
virtual Bool IsStorageDirty(TextureUploadTarget uploadTarget, Uint mipmapLevel) const = 0;
};
class TextureObjectWithOneMipmap : public TextureObjectMipmap {
public:
TextureObjectWithOneMipmap(TextureTarget target, Uint externalIndex)
: TextureObjectMipmap(target, externalIndex) {}
virtual ~TextureObjectWithOneMipmap() = default;
class TextureObjectWithOneMipmap : public TextureObjectMipmap {
public:
TextureObjectWithOneMipmap(TextureTarget target, Uint externalIndex)
: TextureObjectMipmap(target, externalIndex) {}
virtual ~TextureObjectWithOneMipmap() = default;
Uint GetMipmapLevelCount() const override;
const IntVec3 GetMipmapTexelSize(TextureUploadTarget target, Uint mipmapLevel) const override;
const SizeT GetMipmapByteSize(TextureUploadTarget target, Uint mipmapLevel) const override;
void AllocateStorage(TextureUploadTarget uploadTarget, Uint mipmapLevel, MipmapInput input) override;
void UpdateMipmapSubData(TextureUploadTarget uploadTarget, Uint mipmapLevel, DataPtr input) override;
void* MapMipmapData(TextureUploadTarget uploadTarget, Uint mipmapLevel) override;
void MarkStorageDirty(TextureUploadTarget uploadTarget, Uint mipmapLevel, Bool dirty) override;
bool IsStorageDirty(TextureUploadTarget uploadTarget, Uint mipmapLevel) const override;
Uint GetMipmapLevelCount() const override;
const IntVec3 GetMipmapTexelSize(TextureUploadTarget target, Uint mipmapLevel) const override;
const SizeT GetMipmapByteSize(TextureUploadTarget target, Uint mipmapLevel) const override;
void AllocateStorage(TextureUploadTarget uploadTarget, Uint mipmapLevel, MipmapInput input) override;
void UpdateMipmapSubData(TextureUploadTarget uploadTarget, Uint mipmapLevel, DataPtr input) override;
void* MapMipmapData(TextureUploadTarget uploadTarget, Uint mipmapLevel) override;
void MarkStorageDirty(TextureUploadTarget uploadTarget, Uint mipmapLevel, Bool dirty) override;
bool IsStorageDirty(TextureUploadTarget uploadTarget, Uint mipmapLevel) const override;
IntVec3 GetBaseSize() const override;
Bool IsComplete() const override;
IntVec3 GetBaseSize() const override;
Bool IsComplete() const override;
protected:
MipmapUploadTargetArray<1> m_textureStorage;
};
} // namespace GLState
} // namespace MG_State
} // namespace MobileGL
protected:
MipmapUploadTargetArray<1> m_textureStorage;
};
} // namespace MobileGL::MG_State::GLState
@@ -8,7 +8,7 @@
#pragma once
#include "TextureObject.h"
#include "MG_State/GLState/BufferState/BufferObject.h"
#include <MG_State/GLState/BufferState/BufferObject.h>
namespace MobileGL {
namespace MG_State {
@@ -17,115 +17,111 @@
#include "TextureObjectBuffer.h"
#include "TextureObjectStubs.h"
namespace MobileGL {
namespace MG_State {
namespace GLState {
TextureState::TextureState() : m_indexGenerator(1024, 1) {
for (int i = 0; i < MAX_TEXTURE_IMAGE_UNITS; ++i) {
m_textureUnits[i] = TextureUnit();
}
}
namespace MobileGL::MG_State::GLState {
TextureState::TextureState() : m_indexGenerator(1024, 1) {
for (int i = 0; i < MAX_TEXTURE_IMAGE_UNITS; ++i) {
m_textureUnits[i] = TextureUnit();
}
}
SharedPtr<ITextureObject> TextureState::GetTextureObject(Uint index) {
auto it = m_textureObjects.find(index);
if (it != m_textureObjects.end()) {
return it->second;
}
return nullptr;
}
const SharedPtr<ITextureObject>& TextureState::GetTextureObject(Uint index) {
auto it = m_textureObjects.find(index);
if (it != m_textureObjects.end()) {
return it->second;
}
static SharedPtr<ITextureObject> nullTextureObject = nullptr;
return nullTextureObject;
}
Vector<Uint> TextureState::GenerateNames(Uint number) {
Vector<Uint> textures(number);
m_indexGenerator.Generate(number, textures.data());
return textures;
}
void TextureState::GenerateNames(Uint number, Vector<Uint>& textures) {
textures.resize(number);
m_indexGenerator.Generate(number, textures.data());
}
SharedPtr<ITextureObject> TextureState::CreateTextureObject(Uint index, TextureTarget target) {
SharedPtr<ITextureObject> textureObject = nullptr;
switch (target) {
case TextureTarget::Texture1D:
textureObject = MakeShared<TextureObject1D>(index);
break;
case TextureTarget::TextureCubeMap:
textureObject = MakeShared<TextureObject2DCube>(index);
break;
case TextureTarget::Texture2D:
textureObject = MakeShared<TextureObject2D>(index);
break;
case TextureTarget::Texture3D:
textureObject = MakeShared<TextureObject3D>(index);
break;
case TextureTarget::TextureBuffer:
textureObject = MakeShared<TextureObjectBuffer>(index);
break;
const SharedPtr<ITextureObject>& TextureState::CreateTextureObject(Uint index, TextureTarget target) {
auto& textureObject = m_textureObjects[index];
switch (target) {
case TextureTarget::Texture1D:
textureObject = MakeShared<TextureObject1D>(index);
break;
case TextureTarget::TextureCubeMap:
textureObject = MakeShared<TextureObject2DCube>(index);
break;
case TextureTarget::Texture2D:
textureObject = MakeShared<TextureObject2D>(index);
break;
case TextureTarget::Texture3D:
textureObject = MakeShared<TextureObject3D>(index);
break;
case TextureTarget::TextureBuffer:
textureObject = MakeShared<TextureObjectBuffer>(index);
break;
// These texture types are stubbed:
case TextureTarget::TextureRectangle:
textureObject = MakeShared<TextureObjectRectangle>(index);
break;
case TextureTarget::Texture2DMultisample:
textureObject = MakeShared<TextureObject2DMultisample>(index);
break;
case TextureTarget::Texture1DArray:
textureObject = MakeShared<TextureObject1DArray>(index);
break;
case TextureTarget::Texture2DArray:
textureObject = MakeShared<TextureObject2DArray>(index);
break;
case TextureTarget::TextureCubeMapArray:
textureObject = MakeShared<TextureObjectCubeMapArray>(index);
break;
case TextureTarget::Texture2DMultisampleArray:
textureObject = MakeShared<TextureObject2DMultisampleArray>(index);
break;
default:
MOBILEGL_ASSERT(false, "Unimplemented texture type when creating texture object!: %d", (int)target);
return nullptr;
}
// These texture types are stubbed:
case TextureTarget::TextureRectangle:
textureObject = MakeShared<TextureObjectRectangle>(index);
break;
case TextureTarget::Texture2DMultisample:
textureObject = MakeShared<TextureObject2DMultisample>(index);
break;
case TextureTarget::Texture1DArray:
textureObject = MakeShared<TextureObject1DArray>(index);
break;
case TextureTarget::Texture2DArray:
textureObject = MakeShared<TextureObject2DArray>(index);
break;
case TextureTarget::TextureCubeMapArray:
textureObject = MakeShared<TextureObjectCubeMapArray>(index);
break;
case TextureTarget::Texture2DMultisampleArray:
textureObject = MakeShared<TextureObject2DMultisampleArray>(index);
break;
default:
MOBILEGL_ASSERT(false, "Unimplemented texture type when creating texture object!: %d", (int)target);
static SharedPtr<ITextureObject> nullTextureObject = nullptr;
return nullTextureObject;
}
m_textureObjects[index] = textureObject;
return textureObject;
}
return textureObject;
}
void TextureState::MarkTextureObjectForDeletion(Uint index) {
if (m_indexGenerator.IsValid(index)) {
auto it = m_textureObjects.find(index);
if (it != m_textureObjects.end()) {
for (auto& unit : m_textureUnits) {
auto& bindingSlots = unit.GetAllBindingSlots();
for (SizeT i = 0; i < bindingSlots.size(); ++i) {
if (bindingSlots[i].GetBoundObject() == it->second) {
bindingSlots[i].Bind(nullptr);
}
}
void TextureState::MarkTextureObjectForDeletion(Uint index) {
if (m_indexGenerator.IsValid(index)) {
auto it = m_textureObjects.find(index);
if (it != m_textureObjects.end()) {
for (auto& unit : m_textureUnits) {
auto& bindingSlots = unit.GetAllBindingSlots();
for (auto& bindingSlot : bindingSlots) {
if (bindingSlot.GetBoundObject() == it->second) {
bindingSlot.Bind(nullptr);
}
m_textureObjects.erase(it);
}
m_indexGenerator.Delete(index);
}
m_textureObjects.erase(it);
}
m_indexGenerator.Delete(index);
}
}
TextureUnit& TextureState::GetUnitObject(Int unit) {
MOBILEGL_ASSERT(unit >= 0 && unit < MAX_TEXTURE_IMAGE_UNITS, "Texture unit is out of range: %d > %d",
unit, MAX_TEXTURE_IMAGE_UNITS - 1);
return m_textureUnits[unit];
}
TextureUnit& TextureState::GetUnitObject(Int unit) {
MOBILEGL_ASSERT(unit >= 0 && unit < MAX_TEXTURE_IMAGE_UNITS, "Texture unit is out of range: %d > %d", unit,
MAX_TEXTURE_IMAGE_UNITS - 1);
return m_textureUnits[unit];
}
Int TextureState::GetActiveTextureUnit() const {
return m_activeTextureUnit;
}
Int TextureState::GetActiveTextureUnit() const {
return m_activeTextureUnit;
}
void TextureState::SetActiveTextureUnit(Int unit) {
m_activeTextureUnit = unit;
}
void TextureState::SetActiveTextureUnit(Int unit) {
m_activeTextureUnit = unit;
}
Bool TextureState::ValidateName(Uint index) const {
return m_indexGenerator.IsValid(index);
}
Bool TextureState::ValidateName(Uint index) const {
return m_indexGenerator.IsValid(index);
}
Bool TextureState::ValidateTextureObject(Uint index) const {
return m_textureObjects.find(index) != m_textureObjects.end();
}
} // namespace GLState
} // namespace MG_State
} // namespace MobileGL
Bool TextureState::ValidateTextureObject(Uint index) const {
return m_textureObjects.find(index) != m_textureObjects.end();
}
} // namespace MobileGL::MG_State::GLState
@@ -13,30 +13,26 @@
#include "MG_Util/Types.h"
#include "TextureUnit.h"
namespace MobileGL {
namespace MG_State {
namespace GLState {
class TextureState {
public:
static constexpr int MAX_TEXTURE_IMAGE_UNITS = 32;
namespace MobileGL::MG_State::GLState {
class TextureState {
public:
static constexpr int MAX_TEXTURE_IMAGE_UNITS = 32;
TextureState();
Vector<Uint> GenerateNames(Uint number);
SharedPtr<ITextureObject> CreateTextureObject(Uint index, TextureTarget target);
SharedPtr<ITextureObject> GetTextureObject(Uint index);
TextureUnit& GetUnitObject(Int unit);
Int GetActiveTextureUnit() const;
void SetActiveTextureUnit(Int unit);
void MarkTextureObjectForDeletion(Uint index);
Bool ValidateName(Uint index) const;
Bool ValidateTextureObject(Uint index) const;
TextureState();
void GenerateNames(Uint number, Vector<Uint>& textures);
const SharedPtr<ITextureObject>& CreateTextureObject(Uint index, TextureTarget target);
const SharedPtr<ITextureObject>& GetTextureObject(Uint index);
TextureUnit& GetUnitObject(Int unit);
Int GetActiveTextureUnit() const;
void SetActiveTextureUnit(Int unit);
void MarkTextureObjectForDeletion(Uint index);
Bool ValidateName(Uint index) const;
Bool ValidateTextureObject(Uint index) const;
private:
Int m_activeTextureUnit = 0;
Array<TextureUnit, MAX_TEXTURE_IMAGE_UNITS> m_textureUnits;
IndexGenerator<Uint> m_indexGenerator;
UnorderedMap<GLuint, SharedPtr<ITextureObject>> m_textureObjects;
};
} // namespace GLState
} // namespace MG_State
} // namespace MobileGL
private:
Int m_activeTextureUnit = 0;
Array<TextureUnit, MAX_TEXTURE_IMAGE_UNITS> m_textureUnits;
IndexGenerator<Uint> m_indexGenerator;
UnorderedMap<GLuint, SharedPtr<ITextureObject>> m_textureObjects;
};
} // namespace MobileGL::MG_State::GLState
@@ -8,31 +8,26 @@
#include "TextureUnit.h"
namespace MobileGL {
namespace MG_State {
namespace GLState {
TextureUnit::TextureUnit() : m_sampler(nullptr) {
for (int i = 0; i < (int)TextureTarget::TextureTargetCount; ++i) {
m_slots[i] = BindingSlot<ITextureObject>(static_cast<TextureTarget>(i));
}
}
namespace MobileGL::MG_State::GLState {
TextureUnit::TextureUnit() : m_sampler(nullptr) {
for (int i = 0; i < (int)TextureTarget::TextureTargetCount; ++i) {
m_slots[i] = BindingSlot<ITextureObject>(static_cast<TextureTarget>(i));
}
}
BindingSlot<ITextureObject>& TextureUnit::GetBindingSlot(TextureTarget target) {
return m_slots[(int)target];
}
BindingSlot<ITextureObject>& TextureUnit::GetBindingSlot(TextureTarget target) {
return m_slots[(int)target];
}
Array<BindingSlot<ITextureObject>, (int)TextureTarget::TextureTargetCount>& TextureUnit::
GetAllBindingSlots() {
return m_slots;
}
Array<BindingSlot<ITextureObject>, (int)TextureTarget::TextureTargetCount>& TextureUnit::GetAllBindingSlots() {
return m_slots;
}
void TextureUnit::SetSamplerObject(SharedPtr<SamplerObject> sampler) {
m_sampler = sampler;
}
void TextureUnit::SetSamplerObject(const SharedPtr<SamplerObject>& sampler) {
m_sampler = sampler;
}
SharedPtr<SamplerObject> TextureUnit::GetSamplerObject() const {
return m_sampler;
}
} // namespace GLState
} // namespace MG_State
} // namespace MobileGL
const SharedPtr<SamplerObject>& TextureUnit::GetSamplerObject() const {
return m_sampler;
}
} // namespace MobileGL::MG_State::GLState
@@ -11,21 +11,17 @@
#include <MG_State/GLState/SamplerState/SamplerObject.h>
#include "TextureObject.h"
namespace MobileGL {
namespace MG_State {
namespace GLState {
class TextureUnit {
public:
TextureUnit();
BindingSlot<ITextureObject>& GetBindingSlot(TextureTarget target);
SharedPtr<SamplerObject> GetSamplerObject() const;
Array<BindingSlot<ITextureObject>, (int)TextureTarget::TextureTargetCount>& GetAllBindingSlots();
void SetSamplerObject(SharedPtr<SamplerObject> sampler);
namespace MobileGL::MG_State::GLState {
class TextureUnit {
public:
TextureUnit();
BindingSlot<ITextureObject>& GetBindingSlot(TextureTarget target);
const SharedPtr<SamplerObject>& GetSamplerObject() const;
Array<BindingSlot<ITextureObject>, (int)TextureTarget::TextureTargetCount>& GetAllBindingSlots();
void SetSamplerObject(const SharedPtr<SamplerObject>& sampler);
private:
Array<BindingSlot<ITextureObject>, (int)TextureTarget::TextureTargetCount> m_slots;
SharedPtr<SamplerObject> m_sampler;
};
} // namespace GLState
} // namespace MG_State
} // namespace MobileGL
private:
Array<BindingSlot<ITextureObject>, (int)TextureTarget::TextureTargetCount> m_slots;
SharedPtr<SamplerObject> m_sampler;
};
} // namespace MobileGL::MG_State::GLState
@@ -8,137 +8,132 @@
#include "VertexArrayObject.h"
namespace MobileGL {
namespace MG_State {
namespace GLState {
VertexArrayObject::VertexArrayObject(Uint externIndex) : m_externalIndex(externIndex) {
for (int index = 0; index < MAX_VERTEX_ATTRIBS; ++index) {
auto& attr = m_attributes[index];
attr.Enabled = false;
attr.Size = 4;
attr.Type = DataType::Float32;
attr.Normalized = false;
attr.Stride = 0;
attr.Offset = 0;
attr.Buffer = nullptr;
namespace MobileGL::MG_State::GLState {
VertexArrayObject::VertexArrayObject(Uint externIndex) : m_externalIndex(externIndex) {
for (int index = 0; index < MAX_VERTEX_ATTRIBS; ++index) {
auto& attr = m_attributes[index];
attr.Enabled = false;
attr.Size = 4;
attr.Type = DataType::Float32;
attr.Normalized = false;
attr.Stride = 0;
attr.Offset = 0;
attr.Buffer = nullptr;
BumpAttributeFormatVersion(index);
}
}
BumpAttributeFormatVersion(index);
}
}
void VertexArrayObject::EnableAttribute(Uint index) {
if (index >= MAX_VERTEX_ATTRIBS) return;
void VertexArrayObject::EnableAttribute(Uint index) {
if (index >= MAX_VERTEX_ATTRIBS) return;
if (m_attributes[index].Enabled) return;
if (m_attributes[index].Enabled) return;
m_attributes[index].Enabled = true;
BumpAttributeSwitchVersion(index);
}
m_attributes[index].Enabled = true;
BumpAttributeSwitchVersion(index);
}
void VertexArrayObject::DisableAttribute(Uint index) {
if (index >= MAX_VERTEX_ATTRIBS) return;
void VertexArrayObject::DisableAttribute(Uint index) {
if (index >= MAX_VERTEX_ATTRIBS) return;
if (!m_attributes[index].Enabled) return;
if (!m_attributes[index].Enabled) return;
m_attributes[index].Enabled = false;
BumpAttributeSwitchVersion(index);
}
m_attributes[index].Enabled = false;
BumpAttributeSwitchVersion(index);
}
Bool VertexArrayObject::IsAttributeEnabled(Uint index) const {
if (index >= MAX_VERTEX_ATTRIBS) return false;
return m_attributes[index].Enabled;
}
Bool VertexArrayObject::IsAttributeEnabled(Uint index) const {
if (index >= MAX_VERTEX_ATTRIBS) return false;
return m_attributes[index].Enabled;
}
void VertexArrayObject::SetAttributeFormat(Uint index, int size, DataType type, Bool normalized, int stride,
SizeT offset, Bool isInteger) {
if (index >= MAX_VERTEX_ATTRIBS) return;
void VertexArrayObject::SetAttributeFormat(Uint index, int size, DataType type, Bool normalized, int stride,
SizeT offset, Bool isInteger) {
if (index >= MAX_VERTEX_ATTRIBS) return;
if (m_attributes[index].Size == size && m_attributes[index].Type == type &&
m_attributes[index].Normalized == normalized && m_attributes[index].Stride == stride &&
m_attributes[index].Offset == offset && m_attributes[index].IsInteger == isInteger) {
return;
}
if (m_attributes[index].Size == size && m_attributes[index].Type == type &&
m_attributes[index].Normalized == normalized && m_attributes[index].Stride == stride &&
m_attributes[index].Offset == offset && m_attributes[index].IsInteger == isInteger) {
return;
}
if (size < 1 || size > 4) {
return;
}
if (size < 1 || size > 4) {
return;
}
auto& attr = m_attributes[index];
attr.Size = size;
attr.Type = type;
attr.Normalized = normalized;
attr.Stride = stride;
attr.Offset = offset;
attr.IsInteger = isInteger;
auto& attr = m_attributes[index];
attr.Size = size;
attr.Type = type;
attr.Normalized = normalized;
attr.Stride = stride;
attr.Offset = offset;
attr.IsInteger = isInteger;
BumpAttributeFormatVersion(index);
}
BumpAttributeFormatVersion(index);
}
void VertexArrayObject::BindAttributeBuffer(Uint index, const SharedPtr<BufferObject>& buffer) {
if (index >= MAX_VERTEX_ATTRIBS) return;
void VertexArrayObject::BindAttributeBuffer(Uint index, const SharedPtr<BufferObject>& buffer) {
if (index >= MAX_VERTEX_ATTRIBS) return;
if (m_attributes[index].Buffer == buffer) return;
if (m_attributes[index].Buffer == buffer) return;
m_attributes[index].Buffer = buffer;
BumpAttributeBufferVersion(index);
}
m_attributes[index].Buffer = buffer;
BumpAttributeBufferVersion(index);
}
BindingSlot<BufferObject>& VertexArrayObject::GetIndexBufferBindingSlot() {
return m_indexBufferBindingSlot;
}
BindingSlot<BufferObject>& VertexArrayObject::GetIndexBufferBindingSlot() {
return m_indexBufferBindingSlot;
}
const VertexAttribute& VertexArrayObject::GetAttribute(Uint index) const {
static VertexAttribute emptyAttr;
if (index >= MAX_VERTEX_ATTRIBS) return emptyAttr;
return m_attributes[index];
}
const VertexAttribute& VertexArrayObject::GetAttribute(Uint index) const {
static VertexAttribute emptyAttr;
if (index >= MAX_VERTEX_ATTRIBS) return emptyAttr;
return m_attributes[index];
}
const Array<VertexAttribute, VertexArrayObject::MAX_VERTEX_ATTRIBS>& VertexArrayObject::GetAllAttributes()
const {
return m_attributes;
}
const Array<VertexAttribute, VertexArrayObject::MAX_VERTEX_ATTRIBS>& VertexArrayObject::GetAllAttributes() const {
return m_attributes;
}
Uint VertexArrayObject::GetExternalIndex() const {
return m_externalIndex;
}
Uint VertexArrayObject::GetExternalIndex() const {
return m_externalIndex;
}
void VertexArrayObject::SetAttributeDivisor(Uint index, Uint divisor) {
if (index >= MAX_VERTEX_ATTRIBS) return;
if (m_attributes[index].Divisor == divisor) return;
m_attributes[index].Divisor = divisor;
BumpAttributeFormatVersion(index);
}
void VertexArrayObject::SetAttributeDivisor(Uint index, Uint divisor) {
if (index >= MAX_VERTEX_ATTRIBS) return;
if (m_attributes[index].Divisor == divisor) return;
m_attributes[index].Divisor = divisor;
BumpAttributeFormatVersion(index);
}
Uint VertexArrayObject::GetAttributeDivisor(Uint index) const {
if (index >= MAX_VERTEX_ATTRIBS) return 0;
return m_attributes[index].Divisor;
}
Uint VertexArrayObject::GetAttributeDivisor(Uint index) const {
if (index >= MAX_VERTEX_ATTRIBS) return 0;
return m_attributes[index].Divisor;
}
void VertexArrayObject::BumpAttributeFormatVersion(Uint index) {
if (index >= MAX_VERTEX_ATTRIBS) return;
++m_attributeVersions[index].FormatVersion;
}
void VertexArrayObject::BumpAttributeFormatVersion(Uint index) {
if (index >= MAX_VERTEX_ATTRIBS) return;
++m_attributeVersions[index].FormatVersion;
}
void VertexArrayObject::BumpAttributeBufferVersion(Uint index) {
if (index >= MAX_VERTEX_ATTRIBS) return;
++m_attributeVersions[index].BufferVersion;
}
void VertexArrayObject::BumpAttributeBufferVersion(Uint index) {
if (index >= MAX_VERTEX_ATTRIBS) return;
++m_attributeVersions[index].BufferVersion;
}
void VertexArrayObject::BumpAttributeSwitchVersion(Uint index) {
if (index >= MAX_VERTEX_ATTRIBS) return;
++m_attributeVersions[index].SwitchVersion;
}
void VertexArrayObject::BumpAttributeSwitchVersion(Uint index) {
if (index >= MAX_VERTEX_ATTRIBS) return;
++m_attributeVersions[index].SwitchVersion;
}
const VertexAttributeVersion& VertexArrayObject::GetAttributeVersion(Uint index) const {
static VertexAttributeVersion emptyVersion;
if (index >= MAX_VERTEX_ATTRIBS) return emptyVersion;
return m_attributeVersions[index];
}
const VertexAttributeVersion& VertexArrayObject::GetAttributeVersion(Uint index) const {
static VertexAttributeVersion emptyVersion;
if (index >= MAX_VERTEX_ATTRIBS) return emptyVersion;
return m_attributeVersions[index];
}
const Array<VertexAttributeVersion, VertexArrayObject::MAX_VERTEX_ATTRIBS>& VertexArrayObject::
GetAllAttributeVersions() const {
return m_attributeVersions;
}
} // namespace GLState
} // namespace MG_State
} // namespace MobileGL
const Array<VertexAttributeVersion, VertexArrayObject::MAX_VERTEX_ATTRIBS>& VertexArrayObject::
GetAllAttributeVersions() const {
return m_attributeVersions;
}
} // namespace MobileGL::MG_State::GLState
@@ -8,76 +8,74 @@
#include "VertexArrayState.h"
namespace MobileGL {
namespace MG_State {
namespace GLState {
VertexArrayState::VertexArrayState() : m_indexGenerator(1024, 1) {
// Generate default VAO at index 0, which is not valid in core profile, but still remains for
// compatibility reasons.
m_indexGenerator.Insert(0);
auto defaultVAO = MakeShared<VertexArrayObject>(0);
m_vertexArrays.push_back(defaultVAO);
m_boundVertexArray = defaultVAO;
namespace MobileGL::MG_State::GLState {
VertexArrayState::VertexArrayState() : m_indexGenerator(1024, 1) {
// Generate default VAO at index 0, which is not valid in core profile, but still remains for
// compatibility reasons.
m_indexGenerator.Insert(0);
auto defaultVAO = MakeShared<VertexArrayObject>(0);
m_vertexArrays.push_back(defaultVAO);
m_boundVertexArray = defaultVAO;
}
const SharedPtr<VertexArrayObject>& VertexArrayState::GetVertexArrayObject(Uint index) {
if (index >= m_vertexArrays.size()) {
// FIXME: report a GL error here
static SharedPtr<VertexArrayObject> nullVertexArrayObject = nullptr;
return nullVertexArrayObject;
}
return m_vertexArrays[index];
}
void VertexArrayState::GenerateNames(Uint number, Vector<Uint>& arrays) {
arrays.resize(number);
m_indexGenerator.Generate(number, arrays.data());
}
void VertexArrayState::Bind(Uint index) {
m_boundVertexArray = GetVertexArrayObject(index);
}
const SharedPtr<VertexArrayObject>& VertexArrayState::CreateVertexArrayObject(Uint index) {
if (index >= m_vertexArrays.size()) {
// power-of-2 reallocation
m_vertexArrays.reserve(std::bit_ceil(index + 1));
m_vertexArrays.resize(index + 1, nullptr);
}
auto& vao = m_vertexArrays[index];
vao = MakeShared<VertexArrayObject>(index);
return vao;
}
void VertexArrayState::MarkVertexArrayForDeletion(Uint index) {
if (m_indexGenerator.IsValid(index)) {
if (m_boundVertexArray) {
m_boundVertexArray = nullptr;
}
SharedPtr<VertexArrayObject> VertexArrayState::GetVertexArrayObject(Uint index) {
if (index >= m_vertexArrays.size())
// FIXME: report a GL error here
return nullptr;
return m_vertexArrays[index];
if (ValidateVertexArrayObject(index)) {
m_vertexArrays[index] = nullptr;
}
Vector<Uint> VertexArrayState::GenerateNames(Uint number) {
Vector<Uint> arrays(number);
m_indexGenerator.Generate(number, arrays.data());
return arrays;
}
m_indexGenerator.Delete(index);
}
// FIXME: report GL error here?
}
void VertexArrayState::Bind(Uint index) {
m_boundVertexArray = GetVertexArrayObject(index);
}
Bool VertexArrayState::ValidateName(Uint index) const {
return m_indexGenerator.IsValid(index);
}
SharedPtr<VertexArrayObject> VertexArrayState::CreateVertexArrayObject(Uint index) {
if (index >= m_vertexArrays.size()) {
// power-of-2 reallocation
m_vertexArrays.reserve(std::bit_ceil(index + 1));
m_vertexArrays.resize(index + 1, nullptr);
}
auto vao = m_vertexArrays[index] = MakeShared<VertexArrayObject>(index);
return vao;
}
Bool VertexArrayState::ValidateVertexArrayObject(Uint index) const {
return index < m_vertexArrays.size() && m_vertexArrays[index] != nullptr;
}
void VertexArrayState::MarkVertexArrayForDeletion(Uint index) {
if (m_indexGenerator.IsValid(index)) {
if (m_boundVertexArray) {
m_boundVertexArray = nullptr;
}
const SharedPtr<VertexArrayObject>& VertexArrayState::GetBoundVertexArray() {
return m_boundVertexArray;
}
if (ValidateVertexArrayObject(index)) {
m_vertexArrays[index] = nullptr;
}
m_indexGenerator.Delete(index);
}
// FIXME: report GL error here?
}
Bool VertexArrayState::ValidateName(Uint index) const {
return m_indexGenerator.IsValid(index);
}
Bool VertexArrayState::ValidateVertexArrayObject(Uint index) const {
return index < m_vertexArrays.size() && m_vertexArrays[index] != nullptr;
}
SharedPtr<VertexArrayObject> VertexArrayState::GetBoundVertexArray() {
return m_boundVertexArray;
}
Vector<SharedPtr<VertexArrayObject>>& VertexArrayState::GetAllVertexArrays() {
return m_vertexArrays;
}
} // namespace GLState
} // namespace MG_State
} // namespace MobileGL
Vector<SharedPtr<VertexArrayObject>>& VertexArrayState::GetAllVertexArrays() {
return m_vertexArrays;
}
} // namespace MobileGL::MG_State::GLState
@@ -18,14 +18,14 @@ namespace MobileGL {
public:
VertexArrayState();
SharedPtr<VertexArrayObject> GetVertexArrayObject(Uint index);
Vector<Uint> GenerateNames(Uint number);
const SharedPtr<VertexArrayObject>& GetVertexArrayObject(Uint index);
void GenerateNames(Uint number, Vector<Uint>& arrays);
void Bind(Uint index);
SharedPtr<VertexArrayObject> CreateVertexArrayObject(Uint index);
const SharedPtr<VertexArrayObject>& CreateVertexArrayObject(Uint index);
void MarkVertexArrayForDeletion(Uint index);
Bool ValidateName(Uint index) const;
Bool ValidateVertexArrayObject(Uint index) const;
SharedPtr<VertexArrayObject> GetBoundVertexArray();
const SharedPtr<VertexArrayObject>& GetBoundVertexArray();
Vector<SharedPtr<VertexArrayObject>>& GetAllVertexArrays();
private: