mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-13 14:48:32 +09:00
[Perf|Improvement] (All): Improve performance & optimize code.
This commit is contained in:
@@ -388,8 +388,6 @@ namespace MobileGL {
|
||||
*value = cfg->SurfaceType;
|
||||
return true;
|
||||
case EGL_RENDERABLE_TYPE:
|
||||
*value = cfg->RenderableType;
|
||||
return true;
|
||||
case EGL_CONFORMANT:
|
||||
*value = cfg->RenderableType;
|
||||
return true;
|
||||
@@ -878,8 +876,8 @@ namespace MobileGL {
|
||||
Bool EGLContext::MakeCurrent(EGLDisplayHandle display, EGLSurfaceHandle draw, EGLSurfaceHandle read,
|
||||
EGLContextHandle context) {
|
||||
const std::lock_guard<std::recursive_mutex> lock(m_mutex);
|
||||
const Bool releaseCurrentRequest = display == EGL_NO_DISPLAY && draw == EGL_NO_SURFACE &&
|
||||
read == EGL_NO_SURFACE && context == nullptr;
|
||||
const Bool releaseCurrentRequest =
|
||||
display == EGL_NO_DISPLAY && draw == EGL_NO_SURFACE && read == EGL_NO_SURFACE && context == nullptr;
|
||||
const auto threadKey = CurrentThreadKey();
|
||||
if (releaseCurrentRequest) {
|
||||
ReleaseThreadUnlocked(threadKey);
|
||||
@@ -1130,6 +1128,6 @@ namespace MobileGL {
|
||||
}
|
||||
} // namespace EGLState
|
||||
|
||||
EGLState::EGLContext* pEGLContext;
|
||||
UniquePtr<EGLState::EGLContext> pEGLContext;
|
||||
} // namespace MG_State
|
||||
} // namespace MobileGL
|
||||
|
||||
@@ -253,6 +253,6 @@ namespace MobileGL {
|
||||
};
|
||||
} // namespace EGLState
|
||||
|
||||
extern EGLState::EGLContext* pEGLContext;
|
||||
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
|
||||
|
||||
+388
-388
@@ -10,436 +10,436 @@
|
||||
#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();
|
||||
pEGLContext = new MG_State::EGLState::EGLContext();
|
||||
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);
|
||||
}
|
||||
|
||||
Bool GLContext::ValidateTextureObject(Uint index) const {
|
||||
return m_textureState.ValidateTextureObject(index);
|
||||
}
|
||||
|
||||
Int GLContext::GetActiveTextureUnit() const {
|
||||
return m_textureState.GetActiveTextureUnit();
|
||||
}
|
||||
TextureUnit& GLContext::GetTextureUnitObject(Int unit) {
|
||||
return m_textureState.GetUnitObject(unit);
|
||||
}
|
||||
|
||||
void GLContext::SetActiveTextureUnit(Int unit) {
|
||||
m_textureState.SetActiveTextureUnit(unit);
|
||||
}
|
||||
Bool GLContext::ValidateTextureName(Uint index) const {
|
||||
return m_textureState.ValidateName(index);
|
||||
}
|
||||
|
||||
// Program
|
||||
Uint GLContext::CreateProgram() {
|
||||
return m_programState.CreateProgram();
|
||||
}
|
||||
Bool GLContext::ValidateTextureObject(Uint index) const {
|
||||
return m_textureState.ValidateTextureObject(index);
|
||||
}
|
||||
|
||||
Uint GLContext::CreateShader(const ShaderStage stage) {
|
||||
return m_programState.CreateShader(stage);
|
||||
}
|
||||
Int GLContext::GetActiveTextureUnit() const {
|
||||
return m_textureState.GetActiveTextureUnit();
|
||||
}
|
||||
|
||||
void GLContext::MarkProgramForDeletion(const Uint index) {
|
||||
return m_programState.MarkProgramObjectForDeletion(index);
|
||||
}
|
||||
|
||||
void GLContext::MarkShaderForDeletion(const Uint index) {
|
||||
return m_programState.MarkShaderObjectForDeletion(index);
|
||||
}
|
||||
|
||||
Bool GLContext::ValidateProgramName(const Uint index) const {
|
||||
return m_programState.ValidateProgramObject(index);
|
||||
}
|
||||
|
||||
Bool GLContext::ValidateShaderName(const Uint index) const {
|
||||
return m_programState.ValidateShaderObject(index);
|
||||
}
|
||||
|
||||
SharedPtr<ProgramObject> GLContext::GetProgramObject(const Uint index) {
|
||||
return m_programState.GetProgramObject(index);
|
||||
}
|
||||
|
||||
SharedPtr<ShaderObject> GLContext::GetShaderObject(const Uint index) {
|
||||
return m_programState.GetShaderObject(index);
|
||||
}
|
||||
|
||||
void GLContext::UseProgram(Uint program) {
|
||||
return m_programState.UseProgram(program);
|
||||
}
|
||||
|
||||
SharedPtr<ProgramObject> GLContext::GetCurrentProgram() {
|
||||
return m_programState.GetCurrentProgram();
|
||||
}
|
||||
|
||||
// RenderState
|
||||
Uint GLContext::GetRenderStateParametersVersion() const {
|
||||
return m_renderState.GetVersion();
|
||||
}
|
||||
|
||||
const RenderStateParameters& GLContext::GetRenderStateParameters() const {
|
||||
return m_renderState.GetAllParameters();
|
||||
}
|
||||
|
||||
void GLContext::SetViewport(IntVec4 viewport) {
|
||||
m_renderState.SetViewport(viewport);
|
||||
}
|
||||
|
||||
const IntVec4& GLContext::GetViewport() const {
|
||||
return m_renderState.GetViewport();
|
||||
}
|
||||
|
||||
void GLContext::SetCapability(CapabilityInput cap, Bool enabled) {
|
||||
m_renderState.SetCapability(cap, enabled);
|
||||
}
|
||||
|
||||
Bool GLContext::IsCapabilityEnabled(CapabilityInput cap) const {
|
||||
return m_renderState.IsCapabilityEnabled(cap);
|
||||
}
|
||||
|
||||
void GLContext::SetCapabilityIndexed(CapabilityInput cap, Uint index, Bool enabled) {
|
||||
m_renderState.SetCapabilityIndexed(cap, index, enabled);
|
||||
}
|
||||
|
||||
Bool GLContext::IsCapabilityEnabledIndexed(CapabilityInput cap, Uint index) const {
|
||||
return m_renderState.IsCapabilityEnabledIndexed(cap, index);
|
||||
}
|
||||
|
||||
void GLContext::SetBlendFunc(BlendFactor srcRGB, BlendFactor dstRGB, BlendFactor srcAlpha,
|
||||
BlendFactor dstAlpha) {
|
||||
m_renderState.SetBlendFunc(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::SetBlendFuncIndexed(Uint index, BlendFactor srcRGB, BlendFactor dstRGB,
|
||||
BlendFactor srcAlpha, BlendFactor dstAlpha) {
|
||||
m_renderState.SetBlendFuncIndexed(index, 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::SetDepthFunc(DepthTestFunc func) {
|
||||
m_renderState.SetDepthFunc(func);
|
||||
}
|
||||
|
||||
DepthTestFunc GLContext::GetDepthFunc() const {
|
||||
return m_renderState.GetDepthFunc();
|
||||
}
|
||||
|
||||
void GLContext::SetDepthMask(Bool flag) {
|
||||
m_renderState.SetDepthMask(flag);
|
||||
}
|
||||
|
||||
Bool GLContext::GetDepthMask() const {
|
||||
return m_renderState.GetDepthMask();
|
||||
}
|
||||
|
||||
void GLContext::SetColorMask(BoolVec4 mask) {
|
||||
m_renderState.SetColorMask(mask);
|
||||
}
|
||||
|
||||
const BoolVec4 GLContext::GetColorMask() const {
|
||||
return m_renderState.GetColorMask();
|
||||
}
|
||||
|
||||
void GLContext::SetClearColor(FloatVec4 color) {
|
||||
m_renderState.SetClearColor(color);
|
||||
}
|
||||
|
||||
const FloatVec4& GLContext::GetClearColor() const {
|
||||
return m_renderState.GetClearColor();
|
||||
}
|
||||
|
||||
void GLContext::SetClearDepth(Float depth) {
|
||||
m_renderState.SetClearDepth(depth);
|
||||
}
|
||||
|
||||
Float GLContext::GetClearDepth() const {
|
||||
return m_renderState.GetClearDepth();
|
||||
}
|
||||
|
||||
void GLContext::SetClearStencil(Int stencil) {
|
||||
m_renderState.SetClearStencil(stencil);
|
||||
}
|
||||
|
||||
Int GLContext::GetClearStencil() const {
|
||||
return m_renderState.GetClearStencil();
|
||||
}
|
||||
|
||||
void GLContext::SetPixelStoreParam(PixelStoreParam param, Int value) {
|
||||
m_renderState.SetPixelStoreParam(param, value);
|
||||
}
|
||||
|
||||
Int GLContext::GetPixelStoreParam(PixelStoreParam param) const {
|
||||
return m_renderState.GetPixelStoreParam(param);
|
||||
}
|
||||
|
||||
PixelStoreParameters GLContext::GetPixelStoreParameters(Bool isUnpack) const {
|
||||
return m_renderState.GetPixelStoreParameters(isUnpack);
|
||||
}
|
||||
|
||||
void GLContext::SetCullFaceMode(CullFaceMode mode) {
|
||||
m_renderState.SetCullFaceMode(mode);
|
||||
}
|
||||
|
||||
CullFaceMode GLContext::GetCullFaceMode() const {
|
||||
return m_renderState.GetCullFaceMode();
|
||||
}
|
||||
|
||||
void GLContext::SetScissorBox(IntVec4 box) {
|
||||
m_renderState.SetScissorBox(box);
|
||||
}
|
||||
|
||||
const IntVec4& GLContext::GetScissorBox() const {
|
||||
return m_renderState.GetScissorBox();
|
||||
}
|
||||
|
||||
// Framebuffer
|
||||
Vector<Uint> GLContext::GenFramebufferNames(Uint number) {
|
||||
return m_framebufferState.GenerateNames(number);
|
||||
}
|
||||
|
||||
SharedPtr<FramebufferObject> GLContext::GetFramebufferObject(Uint index) {
|
||||
return m_framebufferState.GetFramebufferObject(index);
|
||||
}
|
||||
|
||||
BindingSlot<FramebufferObject>& GLContext::GetFramebufferBindingSlot(FramebufferTarget target) {
|
||||
return m_framebufferState.GetBindingSlot(target);
|
||||
}
|
||||
|
||||
SharedPtr<FramebufferObject> GLContext::CreateFramebufferObject(Uint index) {
|
||||
return m_framebufferState.CreateFramebufferObject(index);
|
||||
}
|
||||
|
||||
void GLContext::MarkFramebufferObjectForDeletion(Uint index) {
|
||||
m_framebufferState.MarkFramebufferObjectForDeletion(index);
|
||||
}
|
||||
|
||||
Bool GLContext::ValidateFramebufferName(Uint index) const {
|
||||
return m_framebufferState.ValidateName(index);
|
||||
}
|
||||
|
||||
Bool GLContext::ValidateFramebufferObject(Uint index) const {
|
||||
return m_framebufferState.ValidateFramebufferObject(index);
|
||||
}
|
||||
|
||||
// Sampler
|
||||
Vector<Uint> GLContext::GenSamplerNames(Uint number) {
|
||||
return m_samplerState.GenerateNames(number);
|
||||
}
|
||||
|
||||
SharedPtr<SamplerObject> GLContext::GetSamplerObject(Uint index) {
|
||||
return m_samplerState.GetSamplerObject(index);
|
||||
}
|
||||
|
||||
SharedPtr<SamplerObject> GLContext::CreateSamplerObject(Uint index) {
|
||||
return m_samplerState.CreateSamplerObject(index);
|
||||
}
|
||||
void GLContext::SetActiveTextureUnit(Int unit) {
|
||||
m_textureState.SetActiveTextureUnit(unit);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
// Program
|
||||
Uint GLContext::CreateProgram() {
|
||||
return m_programState.CreateProgram();
|
||||
}
|
||||
|
||||
Uint GLContext::CreateShader(const ShaderStage stage) {
|
||||
return m_programState.CreateShader(stage);
|
||||
}
|
||||
|
||||
void GLContext::MarkProgramForDeletion(const Uint index) {
|
||||
return m_programState.MarkProgramObjectForDeletion(index);
|
||||
}
|
||||
|
||||
void GLContext::MarkShaderForDeletion(const Uint index) {
|
||||
return m_programState.MarkShaderObjectForDeletion(index);
|
||||
}
|
||||
|
||||
Bool GLContext::ValidateProgramName(const Uint index) const {
|
||||
return m_programState.ValidateProgramObject(index);
|
||||
}
|
||||
|
||||
Bool GLContext::ValidateShaderName(const Uint index) const {
|
||||
return m_programState.ValidateShaderObject(index);
|
||||
}
|
||||
|
||||
const SharedPtr<ProgramObject>& GLContext::GetProgramObject(const Uint index) {
|
||||
return m_programState.GetProgramObject(index);
|
||||
}
|
||||
|
||||
const SharedPtr<ShaderObject>& GLContext::GetShaderObject(const Uint index) {
|
||||
return m_programState.GetShaderObject(index);
|
||||
}
|
||||
|
||||
void GLContext::UseProgram(Uint program) {
|
||||
return m_programState.UseProgram(program);
|
||||
}
|
||||
|
||||
const SharedPtr<ProgramObject>& GLContext::GetCurrentProgram() {
|
||||
return m_programState.GetCurrentProgram();
|
||||
}
|
||||
|
||||
// RenderState
|
||||
Uint GLContext::GetRenderStateParametersVersion() const {
|
||||
return m_renderState.GetVersion();
|
||||
}
|
||||
|
||||
const RenderStateParameters& GLContext::GetRenderStateParameters() const {
|
||||
return m_renderState.GetAllParameters();
|
||||
}
|
||||
|
||||
void GLContext::SetViewport(IntVec4 viewport) {
|
||||
m_renderState.SetViewport(viewport);
|
||||
}
|
||||
|
||||
const IntVec4& GLContext::GetViewport() const {
|
||||
return m_renderState.GetViewport();
|
||||
}
|
||||
|
||||
void GLContext::SetCapability(CapabilityInput cap, Bool enabled) {
|
||||
m_renderState.SetCapability(cap, enabled);
|
||||
}
|
||||
|
||||
Bool GLContext::IsCapabilityEnabled(CapabilityInput cap) const {
|
||||
return m_renderState.IsCapabilityEnabled(cap);
|
||||
}
|
||||
|
||||
void GLContext::SetCapabilityIndexed(CapabilityInput cap, Uint index, Bool enabled) {
|
||||
m_renderState.SetCapabilityIndexed(cap, index, enabled);
|
||||
}
|
||||
|
||||
Bool GLContext::IsCapabilityEnabledIndexed(CapabilityInput cap, Uint index) const {
|
||||
return m_renderState.IsCapabilityEnabledIndexed(cap, index);
|
||||
}
|
||||
|
||||
void GLContext::SetBlendFunc(BlendFactor srcRGB, BlendFactor dstRGB, BlendFactor srcAlpha,
|
||||
BlendFactor dstAlpha) {
|
||||
m_renderState.SetBlendFunc(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::SetBlendFuncIndexed(Uint index, BlendFactor srcRGB, BlendFactor dstRGB, BlendFactor srcAlpha,
|
||||
BlendFactor dstAlpha) {
|
||||
m_renderState.SetBlendFuncIndexed(index, 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::SetDepthFunc(DepthTestFunc func) {
|
||||
m_renderState.SetDepthFunc(func);
|
||||
}
|
||||
|
||||
DepthTestFunc GLContext::GetDepthFunc() const {
|
||||
return m_renderState.GetDepthFunc();
|
||||
}
|
||||
|
||||
void GLContext::SetDepthMask(Bool flag) {
|
||||
m_renderState.SetDepthMask(flag);
|
||||
}
|
||||
|
||||
Bool GLContext::GetDepthMask() const {
|
||||
return m_renderState.GetDepthMask();
|
||||
}
|
||||
|
||||
void GLContext::SetColorMask(BoolVec4 mask) {
|
||||
m_renderState.SetColorMask(mask);
|
||||
}
|
||||
|
||||
BoolVec4 GLContext::GetColorMask() const {
|
||||
return m_renderState.GetColorMask();
|
||||
}
|
||||
|
||||
void GLContext::SetClearColor(FloatVec4 color) {
|
||||
m_renderState.SetClearColor(color);
|
||||
}
|
||||
|
||||
const FloatVec4& GLContext::GetClearColor() const {
|
||||
return m_renderState.GetClearColor();
|
||||
}
|
||||
|
||||
void GLContext::SetClearDepth(Float depth) {
|
||||
m_renderState.SetClearDepth(depth);
|
||||
}
|
||||
|
||||
Float GLContext::GetClearDepth() const {
|
||||
return m_renderState.GetClearDepth();
|
||||
}
|
||||
|
||||
void GLContext::SetClearStencil(Int stencil) {
|
||||
m_renderState.SetClearStencil(stencil);
|
||||
}
|
||||
|
||||
Int GLContext::GetClearStencil() const {
|
||||
return m_renderState.GetClearStencil();
|
||||
}
|
||||
|
||||
void GLContext::SetPixelStoreParam(PixelStoreParam param, Int value) {
|
||||
m_renderState.SetPixelStoreParam(param, value);
|
||||
}
|
||||
|
||||
Int GLContext::GetPixelStoreParam(PixelStoreParam param) const {
|
||||
return m_renderState.GetPixelStoreParam(param);
|
||||
}
|
||||
|
||||
PixelStoreParameters GLContext::GetPixelStoreParameters(Bool isUnpack) const {
|
||||
return m_renderState.GetPixelStoreParameters(isUnpack);
|
||||
}
|
||||
|
||||
void GLContext::SetCullFaceMode(CullFaceMode mode) {
|
||||
m_renderState.SetCullFaceMode(mode);
|
||||
}
|
||||
|
||||
CullFaceMode GLContext::GetCullFaceMode() const {
|
||||
return m_renderState.GetCullFaceMode();
|
||||
}
|
||||
|
||||
void GLContext::SetScissorBox(IntVec4 box) {
|
||||
m_renderState.SetScissorBox(box);
|
||||
}
|
||||
|
||||
const IntVec4& GLContext::GetScissorBox() const {
|
||||
return m_renderState.GetScissorBox();
|
||||
}
|
||||
|
||||
// Framebuffer
|
||||
void GLContext::GenFramebufferNames(Uint number, Vector<Uint>& framebuffers) {
|
||||
m_framebufferState.GenerateNames(number, framebuffers);
|
||||
}
|
||||
|
||||
const SharedPtr<FramebufferObject>& GLContext::GetFramebufferObject(Uint index) {
|
||||
return m_framebufferState.GetFramebufferObject(index);
|
||||
}
|
||||
|
||||
BindingSlot<FramebufferObject>& GLContext::GetFramebufferBindingSlot(FramebufferTarget target) {
|
||||
return m_framebufferState.GetBindingSlot(target);
|
||||
}
|
||||
|
||||
const SharedPtr<FramebufferObject>& GLContext::CreateFramebufferObject(Uint index) {
|
||||
return m_framebufferState.CreateFramebufferObject(index);
|
||||
}
|
||||
|
||||
void GLContext::MarkFramebufferObjectForDeletion(Uint index) {
|
||||
m_framebufferState.MarkFramebufferObjectForDeletion(index);
|
||||
}
|
||||
|
||||
Bool GLContext::ValidateFramebufferName(Uint index) const {
|
||||
return m_framebufferState.ValidateName(index);
|
||||
}
|
||||
|
||||
Bool GLContext::ValidateFramebufferObject(Uint index) const {
|
||||
return m_framebufferState.ValidateFramebufferObject(index);
|
||||
}
|
||||
|
||||
// Sampler
|
||||
void GLContext::GenSamplerNames(Uint number, Vector<Uint>& samplers) {
|
||||
m_samplerState.GenerateNames(number, samplers);
|
||||
}
|
||||
|
||||
const SharedPtr<SamplerObject>& GLContext::GetSamplerObject(Uint index) {
|
||||
return m_samplerState.GetSamplerObject(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);
|
||||
}
|
||||
}
|
||||
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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 != dynamic_cast<MG_State::GLState::TextureObjectMipmap*>(m_texture.get()),
|
||||
"Texture object here should always be an object with mipmap");
|
||||
auto textureMipmapObject = dynamic_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>
|
||||
@@ -67,81 +68,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:
|
||||
|
||||
Reference in New Issue
Block a user