mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-11 21:58:31 +09:00
[Optimize] (MG_State/Buffer): vector to replace umap (does that optimize anything?)
This commit is contained in:
+1
-1
@@ -27,7 +27,7 @@ namespace MG_Global {
|
|||||||
}
|
}
|
||||||
|
|
||||||
namespace Common {
|
namespace Common {
|
||||||
inline constexpr int LogLevel = MG_Constants::Common::LOG_LEVEL_DEBUG;
|
inline constexpr int LogLevel = MG_Constants::Common::LOG_LEVEL_FATAL;
|
||||||
inline constexpr int LogTarget = MG_Constants::Common::LOG_TARGET_ALL;
|
inline constexpr int LogTarget = MG_Constants::Common::LOG_TARGET_ALL;
|
||||||
|
|
||||||
#ifdef __ANDROID__
|
#ifdef __ANDROID__
|
||||||
|
|||||||
@@ -107,6 +107,7 @@
|
|||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
#include <format>
|
#include <format>
|
||||||
|
#include <memory>
|
||||||
#include <glslang/Public/ShaderLang.h>
|
#include <glslang/Public/ShaderLang.h>
|
||||||
#include <glslang/Include/Types.h>
|
#include <glslang/Include/Types.h>
|
||||||
#include <glslang/Public/ShaderLang.h>
|
#include <glslang/Public/ShaderLang.h>
|
||||||
@@ -118,6 +119,7 @@
|
|||||||
#include <GLES3/gl32.h>
|
#include <GLES3/gl32.h>
|
||||||
|
|
||||||
#include "MG_Include/UncertainBool.hpp"
|
#include "MG_Include/UncertainBool.hpp"
|
||||||
|
#include "MG_Include/IndexGenerator.hpp"
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ namespace MG_GL::GL {
|
|||||||
GLuint buffer = MG_State_T::bufferState->GetCurrentBinding(target);
|
GLuint buffer = MG_State_T::bufferState->GetCurrentBinding(target);
|
||||||
if (buffer == 0) return;
|
if (buffer == 0) return;
|
||||||
|
|
||||||
auto& bufferObj = MG_State_T::bufferState->buffers_[buffer];
|
auto& bufferObj = *MG_State_T::bufferState->GetOrCreateBufferObject(buffer);
|
||||||
if (!bufferObj.isMapped) return;
|
if (!bufferObj.isMapped) return;
|
||||||
|
|
||||||
size_t start = static_cast<size_t>(offset);
|
size_t start = static_cast<size_t>(offset);
|
||||||
@@ -134,7 +134,7 @@ namespace MG_GL::GL {
|
|||||||
}
|
}
|
||||||
|
|
||||||
GLuint buffer = MG_State_T::bufferState->currentBindings_[target];
|
GLuint buffer = MG_State_T::bufferState->currentBindings_[target];
|
||||||
auto& bufferObj = MG_State_T::bufferState->buffers_[buffer];
|
auto& bufferObj = *MG_State_T::bufferState->GetOrCreateBufferObject(buffer);
|
||||||
|
|
||||||
Diligent::IBuffer* pBuffer = MG_Diligent::g_BufferMap[buffer];
|
Diligent::IBuffer* pBuffer = MG_Diligent::g_BufferMap[buffer];
|
||||||
if (pBuffer) {
|
if (pBuffer) {
|
||||||
@@ -191,7 +191,7 @@ namespace MG_GL::GL {
|
|||||||
if (result == GL_NO_ERROR) {
|
if (result == GL_NO_ERROR) {
|
||||||
GLuint buffer = MG_State_T::bufferState->GetCurrentBinding(target);
|
GLuint buffer = MG_State_T::bufferState->GetCurrentBinding(target);
|
||||||
if (buffer == 0) return;
|
if (buffer == 0) return;
|
||||||
auto& bufferObj = MG_State_T::bufferState->buffers_[buffer];
|
auto& bufferObj = *MG_State_T::bufferState->GetOrCreateBufferObject(buffer);
|
||||||
if (bufferObj.isDynamic) return; // Dynamic buffer should be created by glDraw*
|
if (bufferObj.isDynamic) return; // Dynamic buffer should be created by glDraw*
|
||||||
|
|
||||||
bufferObj.dirty = false;
|
bufferObj.dirty = false;
|
||||||
@@ -310,7 +310,7 @@ namespace MG_GL::GL {
|
|||||||
GLuint buffer = MG_State_T::bufferState->GetCurrentBinding(target);
|
GLuint buffer = MG_State_T::bufferState->GetCurrentBinding(target);
|
||||||
if (buffer == 0) return;
|
if (buffer == 0) return;
|
||||||
|
|
||||||
auto& bufferObj = MG_State_T::bufferState->buffers_[buffer];
|
auto& bufferObj = *MG_State_T::bufferState->GetOrCreateBufferObject(buffer);
|
||||||
if (bufferObj.isDynamic) return; // Dynamic buffer should be created by glDraw*
|
if (bufferObj.isDynamic) return; // Dynamic buffer should be created by glDraw*
|
||||||
|
|
||||||
Diligent::IBuffer* pBuffer = MG_Diligent::g_BufferMap[buffer];
|
Diligent::IBuffer* pBuffer = MG_Diligent::g_BufferMap[buffer];
|
||||||
|
|||||||
@@ -494,7 +494,7 @@ namespace MG_GL::GL {
|
|||||||
if (!attrib.enabled || attrib.buffer == 0) continue;
|
if (!attrib.enabled || attrib.buffer == 0) continue;
|
||||||
|
|
||||||
GLuint buffer = attrib.buffer;
|
GLuint buffer = attrib.buffer;
|
||||||
auto& bufferObj = MG_State_T::bufferState->buffers_[buffer];
|
auto& bufferObj = *MG_State_T::bufferState->GetOrCreateBufferObject(buffer);
|
||||||
|
|
||||||
Diligent::IBuffer *&pBuffer = MG_Diligent::g_BufferMap[buffer];
|
Diligent::IBuffer *&pBuffer = MG_Diligent::g_BufferMap[buffer];
|
||||||
if (bufferObj.isDynamic && (!pBuffer || (pBuffer && pBuffer->GetDesc().Size != bufferObj.data.size()))) {
|
if (bufferObj.isDynamic && (!pBuffer || (pBuffer && pBuffer->GetDesc().Size != bufferObj.data.size()))) {
|
||||||
@@ -529,7 +529,8 @@ namespace MG_GL::GL {
|
|||||||
const void* pOriginalIndices = nullptr;
|
const void* pOriginalIndices = nullptr;
|
||||||
if (pVAO->elementBuffer != 0)
|
if (pVAO->elementBuffer != 0)
|
||||||
{
|
{
|
||||||
auto& bufferObj = MG_State_T::bufferState->buffers_[pVAO->elementBuffer];
|
auto& bufferObj = *MG_State_T::bufferState->GetOrCreateBufferObject(
|
||||||
|
pVAO->elementBuffer);
|
||||||
pOriginalIndices = bufferObj.data.data() + reinterpret_cast<uintptr_t>(pIndices);
|
pOriginalIndices = bufferObj.data.data() + reinterpret_cast<uintptr_t>(pIndices);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -584,10 +585,10 @@ namespace MG_GL::GL {
|
|||||||
}
|
}
|
||||||
else if (pVAO->elementBuffer != 0) {
|
else if (pVAO->elementBuffer != 0) {
|
||||||
GLuint buffer = pVAO->elementBuffer;
|
GLuint buffer = pVAO->elementBuffer;
|
||||||
auto& bufferObj = MG_State_T::bufferState->buffers_[buffer];
|
auto& bufferObj = *MG_State_T::bufferState->GetOrCreateBufferObject(buffer);
|
||||||
|
|
||||||
Diligent::IBuffer*& pBuffer = MG_Diligent::g_BufferMap[buffer];
|
Diligent::IBuffer*& pBuffer = MG_Diligent::g_BufferMap[buffer];
|
||||||
if (bufferObj.isDynamic && (!pBuffer || (pBuffer && pBuffer->GetDesc().Size != bufferObj.data.size()))) {
|
if (bufferObj.isDynamic || (!pBuffer || (pBuffer && pBuffer->GetDesc().Size != bufferObj.data.size()))) {
|
||||||
if (pBuffer) {
|
if (pBuffer) {
|
||||||
pBuffer->Release();
|
pBuffer->Release();
|
||||||
pBuffer = nullptr;
|
pBuffer = nullptr;
|
||||||
@@ -617,14 +618,14 @@ namespace MG_GL::GL {
|
|||||||
|
|
||||||
// Update data for all dynamic buffers
|
// Update data for all dynamic buffers
|
||||||
for (auto& [bufferID, pBuffer] : MG_Diligent::g_BufferMap) {
|
for (auto& [bufferID, pBuffer] : MG_Diligent::g_BufferMap) {
|
||||||
auto it = MG_State_T::bufferState->buffers_.find(bufferID);
|
auto* pBufferObject = MG_State_T::bufferState->GetOrCreateBufferObject(bufferID);
|
||||||
if (it == MG_State_T::bufferState->buffers_.end()) {
|
if (!pBufferObject) {
|
||||||
MG_Util::Debug::LogW("Buffer ID %u not found in bufferState. Skipping update.", bufferID);
|
MG_Util::Debug::LogW("Buffer ID %u not found in bufferState. Skipping update.", bufferID);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& bufferObj = it->second;
|
auto& bufferObj = *pBufferObject;
|
||||||
if (pBuffer && bufferObj.isDynamic && !bufferObj.data.empty()) {
|
if (pBuffer && bufferObj.isDynamic) {
|
||||||
void* pMappedData = nullptr;
|
void* pMappedData = nullptr;
|
||||||
MG_Util::Debug::LogD("Mapping dynamic buffer %u for data update.", bufferID);
|
MG_Util::Debug::LogD("Mapping dynamic buffer %u for data update.", bufferID);
|
||||||
MG_Diligent::g_pContext->MapBuffer(
|
MG_Diligent::g_pContext->MapBuffer(
|
||||||
@@ -786,6 +787,7 @@ namespace MG_GL::GL {
|
|||||||
return;
|
return;
|
||||||
// PrepareForDraw();
|
// PrepareForDraw();
|
||||||
|
|
||||||
|
/*
|
||||||
if (MG_Diligent::IsInRenderPass) {
|
if (MG_Diligent::IsInRenderPass) {
|
||||||
MG_Util::Debug::LogD("Ending current render pass.");
|
MG_Util::Debug::LogD("Ending current render pass.");
|
||||||
MG_Diligent::g_pContext->EndRenderPass();
|
MG_Diligent::g_pContext->EndRenderPass();
|
||||||
@@ -916,6 +918,7 @@ namespace MG_GL::GL {
|
|||||||
MG_Diligent::IsInRenderPass = false;
|
MG_Diligent::IsInRenderPass = false;
|
||||||
|
|
||||||
MG_Util::Debug::LogD("MultiDrawElements completed with %d draws.", indirectCmds.size());
|
MG_Util::Debug::LogD("MultiDrawElements completed with %d draws.", indirectCmds.size());
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void MultiDrawElementsBaseVertex(GLenum mode, const GLsizei *count, GLenum type, const GLvoid *const *indices, GLsizei drawcount, const GLint *basevertex) {
|
void MultiDrawElementsBaseVertex(GLenum mode, const GLsizei *count, GLenum type, const GLvoid *const *indices, GLsizei drawcount, const GLint *basevertex) {
|
||||||
|
|||||||
@@ -6,36 +6,31 @@
|
|||||||
|
|
||||||
#include "BufferState.h"
|
#include "BufferState.h"
|
||||||
|
|
||||||
GLenum BufferState::GenName(GLuint *buffer) {
|
//GLenum BufferState::GenName(GLuint *buffer) {
|
||||||
MG_Util::Debug::LogD("MG_State: Buffer: GenName");
|
// MG_Util::Debug::LogD("MG_State: Buffer: GenName");
|
||||||
if (!buffer)
|
// if (!buffer)
|
||||||
return GL_INVALID_VALUE;
|
// return GL_INVALID_VALUE;
|
||||||
|
//
|
||||||
GLuint id = 0;
|
// GLuint id = 0;
|
||||||
if (freeId_.empty()) {
|
// if (freeId_.empty()) {
|
||||||
id = lastId_++;
|
// id = lastId_++;
|
||||||
} else {
|
// } else {
|
||||||
id = freeId_.back();
|
// id = freeId_.back();
|
||||||
freeId_.pop_back();
|
// freeId_.pop_back();
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
*buffer = id;
|
// *buffer = id;
|
||||||
MG_Util::Debug::LogD("MG_State: Buffer: Gen new name %d", id);
|
// MG_Util::Debug::LogD("MG_State: Buffer: Gen new name %d", id);
|
||||||
|
//
|
||||||
return GL_NO_ERROR;
|
// return GL_NO_ERROR;
|
||||||
}
|
//}
|
||||||
|
|
||||||
GLenum BufferState::GenNameN(GLsizei n, GLuint* buffers) {
|
GLenum BufferState::GenNameN(GLsizei n, GLuint* buffers) {
|
||||||
MG_Util::Debug::LogD("MG_State: Buffer: GenNameN called with n=%d", n);
|
MG_Util::Debug::LogD("MG_State: Buffer: GenNameN called with n=%d", n);
|
||||||
if (n < 0) return GL_INVALID_VALUE;
|
if (n < 0 || buffers == nullptr) return GL_INVALID_VALUE;
|
||||||
|
|
||||||
|
indexGenerator_.Generate(n, buffers);
|
||||||
|
|
||||||
for (GLsizei i = 0; i < n; ++i) {
|
|
||||||
GLenum result = GenName(&buffers[i]);
|
|
||||||
if (result != GL_NO_ERROR) {
|
|
||||||
MG_Util::Debug::LogE("MG_State: Buffer: GenNameN failed with error 0x%x", result);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
MG_Util::Debug::LogD("MG_State: Buffer: GenNameN created buffers successfully");
|
MG_Util::Debug::LogD("MG_State: Buffer: GenNameN created buffers successfully");
|
||||||
return GL_NO_ERROR;
|
return GL_NO_ERROR;
|
||||||
}
|
}
|
||||||
@@ -48,7 +43,7 @@ GLenum BufferState::Create(GLuint buffer) {
|
|||||||
if (ValidateAllocatedHandle(buffer))
|
if (ValidateAllocatedHandle(buffer))
|
||||||
return GL_INVALID_VALUE;
|
return GL_INVALID_VALUE;
|
||||||
|
|
||||||
BufferObject& obj = buffers_[buffer];
|
BufferObject& obj = *GetOrCreateBufferObject(buffer);
|
||||||
MG_Util::Debug::LogD("MG_State: Buffer: Create created buffer %d", buffer);
|
MG_Util::Debug::LogD("MG_State: Buffer: Create created buffer %d", buffer);
|
||||||
obj.generated = true;
|
obj.generated = true;
|
||||||
obj.dirty = true;
|
obj.dirty = true;
|
||||||
@@ -71,7 +66,7 @@ GLenum BufferState::CommitStorage(GLenum target, GLsizeiptr size, const void* da
|
|||||||
if (it == currentBindings_.end() || it->second == 0)
|
if (it == currentBindings_.end() || it->second == 0)
|
||||||
return GL_INVALID_OPERATION;
|
return GL_INVALID_OPERATION;
|
||||||
|
|
||||||
BufferObject& obj = buffers_[it->second];
|
BufferObject& obj = *GetOrCreateBufferObject(it->second);
|
||||||
MG_Util::Debug::LogD("MG_State: Buffer: CommitStorage get buffer object %u at target 0x%x",it->second,target);
|
MG_Util::Debug::LogD("MG_State: Buffer: CommitStorage get buffer object %u at target 0x%x",it->second,target);
|
||||||
obj.usage = usage;
|
obj.usage = usage;
|
||||||
obj.isDynamic = (usage == GL_DYNAMIC_DRAW || usage == GL_DYNAMIC_READ ||
|
obj.isDynamic = (usage == GL_DYNAMIC_DRAW || usage == GL_DYNAMIC_READ ||
|
||||||
@@ -96,7 +91,7 @@ GLenum BufferState::CommitStorageRegion(GLenum target, GLintptr offset, GLsizeip
|
|||||||
if (it == currentBindings_.end() || it->second == 0)
|
if (it == currentBindings_.end() || it->second == 0)
|
||||||
return GL_INVALID_OPERATION;
|
return GL_INVALID_OPERATION;
|
||||||
|
|
||||||
BufferObject& obj = buffers_[it->second];
|
BufferObject& obj = *GetOrCreateBufferObject(it->second);
|
||||||
MG_Util::Debug::LogD("MG_State: Buffer: BufferSubData get buffer object %u at target 0x%x", it->second, target);
|
MG_Util::Debug::LogD("MG_State: Buffer: BufferSubData get buffer object %u at target 0x%x", it->second, target);
|
||||||
|
|
||||||
if (static_cast<size_t>(offset + size) > obj.data.size()) return GL_INVALID_VALUE;
|
if (static_cast<size_t>(offset + size) > obj.data.size()) return GL_INVALID_VALUE;
|
||||||
@@ -125,7 +120,7 @@ GLenum BufferState::AcquireBufferMemoryRange(GLenum target, GLintptr offset, GLs
|
|||||||
return GL_INVALID_OPERATION;
|
return GL_INVALID_OPERATION;
|
||||||
}
|
}
|
||||||
|
|
||||||
BufferObject& obj = buffers_[it->second];
|
BufferObject& obj = *GetOrCreateBufferObject(it->second);
|
||||||
MG_Util::Debug::LogD("MG_State: Buffer: AcquireBufferMemoryRange operating on buffer %u", it->second);
|
MG_Util::Debug::LogD("MG_State: Buffer: AcquireBufferMemoryRange operating on buffer %u", it->second);
|
||||||
if (obj.isMapped) {
|
if (obj.isMapped) {
|
||||||
MG_Util::Debug::LogE("MG_State: Buffer: AcquireBufferMemoryRange failed: buffer %u is already mapped", it->second);
|
MG_Util::Debug::LogE("MG_State: Buffer: AcquireBufferMemoryRange failed: buffer %u is already mapped", it->second);
|
||||||
@@ -161,7 +156,7 @@ GLenum BufferState::SyncBufferMemory(GLenum target, GLintptr offset, GLsizeiptr
|
|||||||
if (it == currentBindings_.end() || it->second == 0)
|
if (it == currentBindings_.end() || it->second == 0)
|
||||||
return GL_INVALID_OPERATION;
|
return GL_INVALID_OPERATION;
|
||||||
|
|
||||||
BufferObject& obj = buffers_[it->second];
|
BufferObject& obj = *GetOrCreateBufferObject(it->second);
|
||||||
if (!obj.isMapped || !(obj.mapAccessFlags & GL_MAP_FLUSH_EXPLICIT_BIT))
|
if (!obj.isMapped || !(obj.mapAccessFlags & GL_MAP_FLUSH_EXPLICIT_BIT))
|
||||||
return GL_INVALID_OPERATION;
|
return GL_INVALID_OPERATION;
|
||||||
|
|
||||||
@@ -185,8 +180,8 @@ GLenum BufferState::CopyBufferRange(GLenum readTarget, GLenum writeTarget, GLint
|
|||||||
if (readBuffer == 0 || writeBuffer == 0 || readBuffer == writeBuffer)
|
if (readBuffer == 0 || writeBuffer == 0 || readBuffer == writeBuffer)
|
||||||
return GL_INVALID_OPERATION;
|
return GL_INVALID_OPERATION;
|
||||||
|
|
||||||
BufferObject& src = buffers_[readBuffer];
|
BufferObject& src = *GetOrCreateBufferObject(readBuffer);
|
||||||
BufferObject& dst = buffers_[writeBuffer];
|
BufferObject& dst = *GetOrCreateBufferObject(writeBuffer);
|
||||||
|
|
||||||
if (static_cast<size_t>(readOffset + size) > src.data.size() ||
|
if (static_cast<size_t>(readOffset + size) > src.data.size() ||
|
||||||
static_cast<size_t>(writeOffset + size) > dst.data.size())
|
static_cast<size_t>(writeOffset + size) > dst.data.size())
|
||||||
@@ -206,7 +201,7 @@ GLenum BufferState::AcquireBufferMemory(GLenum target, GLenum access, void** map
|
|||||||
default:
|
default:
|
||||||
flags = access;
|
flags = access;
|
||||||
}
|
}
|
||||||
return AcquireBufferMemoryRange(target, 0, buffers_[currentBindings_[target]].data.size(), flags, mappedPointer);
|
return AcquireBufferMemoryRange(target, 0, GetOrCreateBufferObject(currentBindings_[target])->data.size(), flags, mappedPointer);
|
||||||
}
|
}
|
||||||
|
|
||||||
GLenum BufferState::ReleaseBufferMemory(GLenum target) {
|
GLenum BufferState::ReleaseBufferMemory(GLenum target) {
|
||||||
@@ -217,7 +212,7 @@ GLenum BufferState::ReleaseBufferMemory(GLenum target) {
|
|||||||
if (it == currentBindings_.end() || it->second == 0)
|
if (it == currentBindings_.end() || it->second == 0)
|
||||||
return GL_INVALID_OPERATION;
|
return GL_INVALID_OPERATION;
|
||||||
|
|
||||||
BufferObject& obj = buffers_[it->second];
|
BufferObject& obj = *GetOrCreateBufferObject(it->second);
|
||||||
if (!obj.isMapped)
|
if (!obj.isMapped)
|
||||||
return GL_INVALID_OPERATION;
|
return GL_INVALID_OPERATION;
|
||||||
|
|
||||||
@@ -234,24 +229,22 @@ GLenum BufferState::ReleaseBufferMemory(GLenum target) {
|
|||||||
return GL_NO_ERROR;
|
return GL_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BufferState::ValidateAllocatedHandle(GLuint buffer) {
|
bool BufferState::ValidateAllocatedHandle(GLuint buffer) const {
|
||||||
bool isValid = buffers_.find(buffer) != buffers_.end();
|
bool isValid = buffer != 0 && bufferObjects_.size() > buffer && bufferObjects_[buffer] != nullptr;
|
||||||
MG_Util::Debug::LogD("MG_State: Buffer: ValidateAllocatedHandle called on buffer %u returns %d", buffer, isValid);
|
MG_Util::Debug::LogD("MG_State: Buffer: ValidateAllocatedHandle called on buffer %u returns %d", buffer, isValid);
|
||||||
return isValid;
|
return isValid;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BufferState::ValidateGeneratedName(GLuint buffer) {
|
bool BufferState::ValidateGeneratedName(GLuint buffer) const {
|
||||||
bool inFreeList = std::find(freeId_.begin(), freeId_.end(), buffer) != freeId_.end();
|
bool isValid = indexGenerator_.IsValid(buffer);
|
||||||
bool lessThanLast = buffer < lastId_; // lastId_ is not generated yet
|
MG_Util::Debug::LogD("MG_State: Buffer: ValidateGeneratedName called on buffer %u returns %s", buffer, isValid ? "true" : "false");
|
||||||
MG_Util::Debug::LogD("MG_State: Buffer: ValidateGeneratedName called on buffer %u returns %d", buffer, lessThanLast && !inFreeList);
|
return isValid;
|
||||||
return lessThanLast && !inFreeList;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BufferState::Delete(GLuint buffer) {
|
void BufferState::Delete(GLuint buffer) {
|
||||||
buffers_.erase(buffer);
|
bufferObjects_[buffer].reset();
|
||||||
if (ValidateGeneratedName(buffer))
|
indexGenerator_.Delete(buffer);
|
||||||
// TODO: Prevent the object that uses a freeId from conflicting with legacy object in the backend.
|
|
||||||
//freeId_.emplace_back(buffer);
|
|
||||||
for (auto& [target, id] : currentBindings_) {
|
for (auto& [target, id] : currentBindings_) {
|
||||||
if (id == buffer) id = 0;
|
if (id == buffer) id = 0;
|
||||||
}
|
}
|
||||||
@@ -293,12 +286,12 @@ GLenum BufferState::QueryPropertyIntVector(GLenum target, GLenum pname, GLint* p
|
|||||||
return GL_INVALID_OPERATION;
|
return GL_INVALID_OPERATION;
|
||||||
}
|
}
|
||||||
GLuint bufferId = bindingIt->second;
|
GLuint bufferId = bindingIt->second;
|
||||||
auto bufferIt = buffers_.find(bufferId);
|
|
||||||
if (bufferIt == buffers_.end()) {
|
if (!ValidateAllocatedHandle(bufferId)) {
|
||||||
return GL_INVALID_OPERATION;
|
return GL_INVALID_OPERATION;
|
||||||
}
|
}
|
||||||
|
|
||||||
const BufferObject& buffer = bufferIt->second;
|
const BufferObject& buffer = *bufferObjects_[bufferId];
|
||||||
|
|
||||||
switch (pname) {
|
switch (pname) {
|
||||||
case GL_BUFFER_ACCESS:
|
case GL_BUFFER_ACCESS:
|
||||||
@@ -328,3 +321,13 @@ GLuint BufferState::GetCurrentBinding(GLenum target) const {
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BufferState::BufferObject* BufferState::GetOrCreateBufferObject(GLuint buffer) {
|
||||||
|
if (bufferObjects_.size() <= buffer) {
|
||||||
|
bufferObjects_.resize(buffer + 1);
|
||||||
|
}
|
||||||
|
if (bufferObjects_[buffer] == nullptr) {
|
||||||
|
bufferObjects_[buffer] = std::make_unique<BufferObject>();
|
||||||
|
}
|
||||||
|
return bufferObjects_[buffer].get();
|
||||||
|
}
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Return: the validity of the operation, according to OpenGL 3 standard
|
// Return: the validity of the operation, according to OpenGL 3 standard
|
||||||
GLenum GenName(GLuint* buffer);
|
// GLenum GenName(GLuint* buffer);
|
||||||
GLenum GenNameN(GLsizei n, GLuint* buffers);
|
GLenum GenNameN(GLsizei n, GLuint* buffers);
|
||||||
GLenum Create(GLuint buffer);
|
GLenum Create(GLuint buffer);
|
||||||
GLenum Bind(GLenum target, GLuint buffer);
|
GLenum Bind(GLenum target, GLuint buffer);
|
||||||
@@ -40,16 +40,20 @@ public:
|
|||||||
GLenum QueryPropertyIntVector(GLenum target, GLenum pname, GLint* params) const;
|
GLenum QueryPropertyIntVector(GLenum target, GLenum pname, GLint* params) const;
|
||||||
GLenum DeleteN(GLsizei n, const GLuint* buffers);
|
GLenum DeleteN(GLsizei n, const GLuint* buffers);
|
||||||
|
|
||||||
bool ValidateAllocatedHandle(GLuint buffer);
|
bool ValidateAllocatedHandle(GLuint buffer) const;
|
||||||
bool ValidateGeneratedName(GLuint buffer);
|
bool ValidateGeneratedName(GLuint buffer) const;
|
||||||
void Delete(GLuint buffer);
|
void Delete(GLuint buffer);
|
||||||
GLuint GetCurrentBinding(GLenum target) const;
|
GLuint GetCurrentBinding(GLenum target) const;
|
||||||
|
|
||||||
|
BufferObject* GetOrCreateBufferObject(GLuint buffer);
|
||||||
|
|
||||||
MG_Global::unordered_map<GLenum, GLuint> currentBindings_;
|
MG_Global::unordered_map<GLenum, GLuint> currentBindings_;
|
||||||
MG_Global::unordered_map<GLuint, BufferObject> buffers_;
|
// MG_Global::unordered_map<GLuint, BufferObject> buffers_;
|
||||||
private:
|
private:
|
||||||
std::vector<GLuint> freeId_;
|
// std::vector<GLuint> freeId_;
|
||||||
GLuint lastId_ = 1;
|
// GLuint lastId_ = 1;
|
||||||
|
IndexGenerator<GLuint> indexGenerator_;
|
||||||
|
std::vector<std::unique_ptr<BufferObject>> bufferObjects_;
|
||||||
|
|
||||||
static bool IsValidTarget_(GLenum target);
|
static bool IsValidTarget_(GLenum target);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,73 @@
|
|||||||
|
//
|
||||||
|
// Created by yello on 2025-06-27.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef INDEXGENERATOR_H
|
||||||
|
#define INDEXGENERATOR_H
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <cstddef> // For size_t
|
||||||
|
#include <algorithm> // For std::min
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
template <typename IndexType>
|
||||||
|
class IndexGenerator {
|
||||||
|
public:
|
||||||
|
// 构造函数
|
||||||
|
IndexGenerator() : next_index_(1) {}
|
||||||
|
explicit IndexGenerator(IndexType n) : next_index_(1) {
|
||||||
|
is_valid_.reserve(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 生成n个新正整数
|
||||||
|
void Generate(size_t n, IndexType *indices) {
|
||||||
|
if (n <= 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 优先给出被删除的索引
|
||||||
|
size_t count_from_freed = std::min(n, freed_indices_.size());
|
||||||
|
for (size_t i = 0; i < count_from_freed; ++i) {
|
||||||
|
indices[i] = freed_indices_.back();
|
||||||
|
freed_indices_.pop_back();
|
||||||
|
// 标记为有效,确保is_valid_的大小足够
|
||||||
|
if (indices[i] >= is_valid_.size()) {
|
||||||
|
is_valid_.resize(static_cast<size_t>(indices[i]) + 1, false); // 0代表无效,1代表有效
|
||||||
|
}
|
||||||
|
is_valid_[indices[i]] = true; // 标记为有效
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果还需要更多的索引,则生成新的索引
|
||||||
|
for (size_t i = count_from_freed; i < n; ++i) {
|
||||||
|
indices[i] = next_index_++;
|
||||||
|
// 确保is_valid_的大小足够
|
||||||
|
if (indices[i] >= is_valid_.size()) {
|
||||||
|
is_valid_.resize(static_cast<size_t>(indices[i]) + 1, false);
|
||||||
|
}
|
||||||
|
is_valid_[indices[i]] = true; // 标记为有效
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除一个已经给出的正整数
|
||||||
|
void Delete(IndexType index) {
|
||||||
|
// 检查索引是否有效且未被删除
|
||||||
|
// 这里的检查是为了避免重复删除或删除未生成的索引
|
||||||
|
if (index < is_valid_.size() && is_valid_[index] == true) {
|
||||||
|
is_valid_[index] = false; // 标记为无效
|
||||||
|
freed_indices_.push_back(index); // 添加到已删除列表中
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查一个正整数是否之前已经被给出,并且没有被删除
|
||||||
|
bool IsValid(IndexType index) const {
|
||||||
|
// 如果索引超出is_valid_的范围,或者对应的位置是0,则认为无效
|
||||||
|
return index < is_valid_.size() && is_valid_[index] == true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
IndexType next_index_; // 下一个将要生成的正整数
|
||||||
|
std::vector<IndexType> freed_indices_; // 存储被删除的索引
|
||||||
|
std::vector<bool> is_valid_; // 标记索引是否有效。0代表无效,1代表有效。
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //INDEXGENERATOR_H
|
||||||
Reference in New Issue
Block a user