[Fix] (MG_Impl, MG_State, MG_Backend, MG_Util): Do source audit by Codex.

This commit is contained in:
BZLZHH
2026-06-09 15:34:19 +08:00
parent be3c3eb9bb
commit 727939af5b
93 changed files with 6019 additions and 731 deletions
+232 -125
View File
@@ -16,6 +16,10 @@
#include <MG_Backend/BackendObjects.h>
namespace MobileGL::MG_Impl::GLImpl {
static GLint BoolToGLInt(bool value) {
return value ? GL_TRUE : GL_FALSE;
}
static bool CheckShaderNameValidity(Uint shader) {
if (shader == 0 || !MG_State::pGLContext->ValidateShaderName(shader)) {
MG_State::pGLContext->RecordError(
@@ -80,6 +84,16 @@ namespace MobileGL::MG_Impl::GLImpl {
if (length) *length = sz;
}
bool RecordInvalidUniformLocationError(const char* functionName, GLint location, const String& targetDescription) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", functionName,
"location " + std::to_string(location) +
" does not correspond to a valid uniform variable location for " +
targetDescription + "."));
return false;
}
void AttachShader_State(GLuint program, GLuint shader) {
auto& programObject = TryToGetProgramObject(program);
if (!programObject) return;
@@ -188,9 +202,10 @@ namespace MobileGL::MG_Impl::GLImpl {
std::to_string(program) + "."));
return;
}
if (type != nullptr) *type = programObject->GetAttribType(index);
if (size != nullptr) *size = programObject->GetActiveAttribArraySize(index);
if (type != nullptr) *type = programObject->GetActiveAttribType(index);
if (bufSize == 0) return;
auto& attribName = programObject->GetAttribName(index);
auto& attribName = programObject->GetActiveAttribName(index);
CopyStr(bufSize, length, name, attribName.c_str(), (GLsizei)attribName.length());
}
@@ -216,13 +231,38 @@ namespace MobileGL::MG_Impl::GLImpl {
std::to_string(program) + "."));
return;
}
if (type != nullptr) *type = programObject->GetUniformType(index);
if (size != nullptr) *size = programObject->GetActiveUniformArraySize(index);
if (type != nullptr) *type = programObject->GetActiveUniformType(index);
if (bufSize == 0) return;
auto& uniformName = programObject->GetUniformName(index);
auto& uniformName = programObject->GetActiveUniformName(index);
CopyStr(bufSize, length, name, uniformName.c_str(), (GLsizei)uniformName.length());
}
void GetUniformIndices_State(GLuint program, GLsizei uniformCount, const GLchar* const* uniformNames,
GLuint* uniformIndices) {
if (uniformCount < 0) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidValue,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
"uniformCount " + std::to_string(uniformCount) + " is less than 0."));
return;
}
auto& programObject = TryToGetProgramObject(program);
if (!programObject || !programObject->GetLinkStatus()) return;
if (uniformCount == 0 || uniformNames == nullptr || uniformIndices == nullptr) return;
for (GLsizei i = 0; i < uniformCount; ++i) {
const char* uniformName = uniformNames[i];
if (uniformName == nullptr) {
uniformIndices[i] = GL_INVALID_INDEX;
continue;
}
const Int uniformIndex = programObject->GetActiveUniformIndex(uniformName);
uniformIndices[i] = uniformIndex >= 0 ? static_cast<GLuint>(uniformIndex) : GL_INVALID_INDEX;
}
}
void GetAttachedShaders_State(GLuint program, GLsizei maxCount, GLsizei* count, GLuint* shaders) {
if (maxCount < 0) {
MG_State::pGLContext->RecordError(
@@ -268,7 +308,7 @@ namespace MobileGL::MG_Impl::GLImpl {
break;
case GL_INFO_LOG_LENGTH: {
const auto& log = programObject->GetInfoLog();
*params = (GLint)log.length();
*params = log.empty() ? 0 : static_cast<GLint>(log.length()) + 1;
MGLOG_D("%s: %s = %d", __func__, MG_Util::ConvertGLEnumToString(pname).c_str(), *params);
break;
}
@@ -287,7 +327,7 @@ namespace MobileGL::MG_Impl::GLImpl {
MGLOG_D("%s: %s = %d", __func__, MG_Util::ConvertGLEnumToString(pname).c_str(), *params);
break;
case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
*params = programObject->GetActiveAttributesMaxLength();
*params = programObject->GetActiveAttributesMaxLength() + 1;
MGLOG_D("%s: %s = %d", __func__, MG_Util::ConvertGLEnumToString(pname).c_str(), *params);
break;
case GL_ACTIVE_UNIFORMS:
@@ -295,7 +335,7 @@ namespace MobileGL::MG_Impl::GLImpl {
MGLOG_D("%s: %s = %d", __func__, MG_Util::ConvertGLEnumToString(pname).c_str(), *params);
break;
case GL_ACTIVE_UNIFORM_MAX_LENGTH:
*params = programObject->GetUniformMaxLength();
*params = programObject->GetUniformMaxLength() + 1;
MGLOG_D("%s: %s = %d", __func__, MG_Util::ConvertGLEnumToString(pname).c_str(), *params);
break;
case GL_ACTIVE_UNIFORM_BLOCKS: // GL >= 3.1
@@ -303,22 +343,21 @@ namespace MobileGL::MG_Impl::GLImpl {
MGLOG_D("%s: %s = %d", __func__, MG_Util::ConvertGLEnumToString(pname).c_str(), *params);
break;
case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH: // ditto.
*params = programObject->GetActiveUniformBlocksMaxNameLength();
*params = programObject->GetActiveUniformBlocksMaxNameLength() + 1;
MGLOG_D("%s: %s = %d", __func__, MG_Util::ConvertGLEnumToString(pname).c_str(), *params);
break;
case GL_COMPUTE_WORK_GROUP_SIZE: { // GL >= 4.3
auto getProgramiv = MG_Backend::gBackendFunctionsTable.GL.GetProgramiv;
if (!getProgramiv) {
params[0] = 1;
params[1] = 1;
params[2] = 1;
if (!programObject->GetLinkStatus()) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
"Backend does not support program integer queries."));
std::to_string(program) +
" is not a program object that has been linked."));
return;
}
getProgramiv(program, pname, params);
params[0] = static_cast<GLint>(programObject->GetComputeLocalSize(0));
params[1] = static_cast<GLint>(programObject->GetComputeLocalSize(1));
params[2] = static_cast<GLint>(programObject->GetComputeLocalSize(2));
MGLOG_D("%s: %s = (%d, %d, %d)", __func__, MG_Util::ConvertGLEnumToString(pname).c_str(), params[0],
params[1], params[2]);
break;
@@ -423,25 +462,13 @@ namespace MobileGL::MG_Impl::GLImpl {
}
// Check if location is valid
if (location < 0 || location > programObject->GetMaxUniformLocation()) {
if (!programObject->IsValidUniformLocation(location)) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
"location " + std::to_string(location) +
" does not correspond to a valid uniform variable location "
"for the specified program object."));
return;
}
// Check if the location corresponds to an active uniform
const auto& uniformName = programObject->GetUniformName(location);
if (uniformName.empty()) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
"location " + std::to_string(location) +
" does not correspond to a valid uniform variable location "
"for the specified program object."));
MakeUnique<GenericErrorInfo>(
"MG_Impl/GLImpl", __func__,
"location " + std::to_string(location) +
" does not correspond to a valid uniform variable location for the specified program object."));
return;
}
@@ -468,12 +495,64 @@ namespace MobileGL::MG_Impl::GLImpl {
// TODO: handle 1i variant as texture unit
}
template <typename T>
void GetUniformScalar_State(GLuint program, GLint location, T* params) {
auto& programObject = TryToGetProgramObject(program);
if (!programObject) return;
if (!programObject->GetLinkStatus()) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
std::to_string(program) + " has not been successfully linked."));
return;
}
if (!programObject->IsValidUniformLocation(location)) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation,
MakeUnique<GenericErrorInfo>(
"MG_Impl/GLImpl", __func__,
"location " + std::to_string(location) +
" does not correspond to a valid uniform variable location for the specified program object."));
return;
}
if (programObject->IsUniformOpaqueAtLocation(location)) {
const Int unit = std::max(programObject->GetUniformSamplerOrImageUnitIndex(location), 0);
*params = static_cast<T>(unit);
return;
}
auto offset = programObject->GetUniformOffset(location);
auto size = programObject->GetUniformSizesInBytes(location);
char* pUBO = static_cast<char*>(programObject->MapUBO());
auto* ttype = programObject->GetUniformTType(location);
if constexpr (std::is_same_v<T, GLfloat>) {
if (ttype->isMatrix() && ttype->getMatrixCols() == 3) {
auto* pBase = pUBO + offset;
for (int i = 0; i < ttype->getMatrixRows(); i++) {
Memcpy(reinterpret_cast<char*>(params) + ttype->getMatrixCols() * sizeof(GLfloat) * i,
pBase + 4 * sizeof(GLfloat) * i, ttype->getMatrixCols() * sizeof(GLfloat));
}
return;
}
}
Memcpy(params, pUBO + offset, size);
}
void GetUniformfv_State(GLuint program, GLint location, GLfloat* params) {
GetUniform_State(program, location, params);
GetUniformScalar_State(program, location, params);
}
void GetUniformiv_State(GLuint program, GLint location, GLint* params) {
GetUniform_State(program, location, params);
GetUniformScalar_State(program, location, params);
}
void GetUniformuiv_State(GLuint program, GLint location, GLuint* params) {
GetUniformScalar_State(program, location, params);
}
GLboolean IsProgram_State(GLuint program) {
@@ -585,18 +664,11 @@ namespace MobileGL::MG_Impl::GLImpl {
return;
}
if (location > programObject->GetMaxUniformLocation() || location < -1) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
"location " + std::to_string(location) +
" is an invalid uniform location for the current program "
"object and location " +
std::to_string(location) + " is not equal to -1."));
return;
}
for (GLint offset = 0; offset < count; offset++) {
if (!programObject->IsValidUniformLocation(location + offset)) {
RecordInvalidUniformLocationError(__func__, location + offset, "the current program object");
return;
}
Uniform_State<ItemCount>(*programObject, location + offset, value + offset * ItemCount);
}
}
@@ -616,17 +688,12 @@ namespace MobileGL::MG_Impl::GLImpl {
return;
}
if (location > programObject->GetMaxUniformLocation() || location < -1) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
"location " + std::to_string(location) +
" is an invalid uniform location for program " +
std::to_string(program) + "."));
return;
}
for (GLint offset = 0; offset < count; offset++) {
if (!programObject->IsValidUniformLocation(location + offset)) {
RecordInvalidUniformLocationError(__func__, location + offset,
"program " + std::to_string(program));
return;
}
Uniform_State<ItemCount>(*programObject, location + offset, value + offset * ItemCount);
}
}
@@ -744,19 +811,12 @@ namespace MobileGL::MG_Impl::GLImpl {
return;
}
if (location > programObject->GetMaxUniformLocation() || location < -1) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
"location " + std::to_string(location) +
" is an invalid uniform location for the current program "
"object and location " +
std::to_string(location) + " is not equal to -1."));
return;
}
// For matrix uniforms, we handle each matrix individually
for (GLint i = 0; i < count; i++) {
if (!programObject->IsValidUniformLocation(location + i)) {
RecordInvalidUniformLocationError(__func__, location + i, "the current program object");
return;
}
if (transpose == GL_TRUE) {
// Transpose the matrix before uploading
GLfloat transposedMatrix[4];
@@ -782,20 +842,13 @@ namespace MobileGL::MG_Impl::GLImpl {
return;
}
if (location > programObject->GetMaxUniformLocation() || location < -1) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
"location " + std::to_string(location) +
" is an invalid uniform location for the current program "
"object and location " +
std::to_string(location) + " is not equal to -1."));
return;
}
// For matrix uniforms, we handle each matrix individually
// Handle padding in mat3 correctly!!
for (GLint i = 0; i < count; i++) {
if (!programObject->IsValidUniformLocation(location + i)) {
RecordInvalidUniformLocationError(__func__, location + i, "the current program object");
return;
}
if (transpose == GL_TRUE) {
// Transpose the matrix before uploading
GLfloat transposedMatrix[9];
@@ -825,19 +878,12 @@ namespace MobileGL::MG_Impl::GLImpl {
return;
}
if (location > programObject->GetMaxUniformLocation() || location < -1) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
"location " + std::to_string(location) +
" is an invalid uniform location for the current program "
"object and location " +
std::to_string(location) + " is not equal to -1."));
return;
}
// For matrix uniforms, we handle each matrix individually
for (GLint i = 0; i < count; i++) {
if (!programObject->IsValidUniformLocation(location + i)) {
RecordInvalidUniformLocationError(__func__, location + i, "the current program object");
return;
}
if (transpose == GL_TRUE) {
// Transpose the matrix before uploading
GLfloat transposedMatrix[16];
@@ -865,17 +911,11 @@ namespace MobileGL::MG_Impl::GLImpl {
return;
}
if (location > programObject->GetMaxUniformLocation() || location < -1) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
"location " + std::to_string(location) +
" is an invalid uniform location for program " +
std::to_string(program) + "."));
return;
}
for (GLint i = 0; i < count; i++) {
if (!programObject->IsValidUniformLocation(location + i)) {
RecordInvalidUniformLocationError(__func__, location + i, "program " + std::to_string(program));
return;
}
if (transpose == GL_TRUE) {
GLfloat transposedMatrix[4];
TransposeMatrix2x2(value + i * 4, transposedMatrix);
@@ -901,17 +941,11 @@ namespace MobileGL::MG_Impl::GLImpl {
return;
}
if (location > programObject->GetMaxUniformLocation() || location < -1) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
"location " + std::to_string(location) +
" is an invalid uniform location for program " +
std::to_string(program) + "."));
return;
}
for (GLint i = 0; i < count; i++) {
if (!programObject->IsValidUniformLocation(location + i)) {
RecordInvalidUniformLocationError(__func__, location + i, "program " + std::to_string(program));
return;
}
if (transpose == GL_TRUE) {
GLfloat transposedMatrix[9];
TransposeMatrix3x3(value + i * 9, transposedMatrix);
@@ -941,17 +975,11 @@ namespace MobileGL::MG_Impl::GLImpl {
return;
}
if (location > programObject->GetMaxUniformLocation() || location < -1) {
MG_State::pGLContext->RecordError(
ErrorCode::InvalidOperation,
MakeUnique<GenericErrorInfo>("MG_Impl/GLImpl", __func__,
"location " + std::to_string(location) +
" is an invalid uniform location for program " +
std::to_string(program) + "."));
return;
}
for (GLint i = 0; i < count; i++) {
if (!programObject->IsValidUniformLocation(location + i)) {
RecordInvalidUniformLocationError(__func__, location + i, "program " + std::to_string(program));
return;
}
if (transpose == GL_TRUE) {
GLfloat transposedMatrix[16];
TransposeMatrix4x4(value + i * 16, transposedMatrix);
@@ -1033,22 +1061,52 @@ namespace MobileGL::MG_Impl::GLImpl {
break;
}
case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS: {
// TODO: deduct global ubo?
*params = programObject->GetActiveUniformBlocksCount();
*params = programObject->GetUniformBlockActiveUniformCount(uniformBlockIndex);
MGLOG_D("%s: GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS = %d", __func__, *params);
break;
}
case GL_UNIFORM_BLOCK_BINDING: {
// TODO
MGLOG_D("%s: GL_UNIFORM_BLOCK_BINDING = <TODO>", __func__, *params);
*params = static_cast<GLint>(programObject->GetUniformBlockBinding(uniformBlockIndex));
MGLOG_D("%s: GL_UNIFORM_BLOCK_BINDING = %d", __func__, *params);
break;
}
case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:
case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:
*params = BoolToGLInt(programObject->IsUniformBlockReferencedByStage(uniformBlockIndex, EShLangVertex));
MGLOG_D("%s: GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER = %d", __func__, *params);
break;
case GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_CONTROL_SHADER:
*params =
BoolToGLInt(programObject->IsUniformBlockReferencedByStage(uniformBlockIndex, EShLangTessControl));
MGLOG_D("%s: GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_CONTROL_SHADER = %d", __func__, *params);
break;
case GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_EVALUATION_SHADER:
*params =
BoolToGLInt(programObject->IsUniformBlockReferencedByStage(uniformBlockIndex, EShLangTessEvaluation));
MGLOG_D("%s: GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_EVALUATION_SHADER = %d", __func__, *params);
break;
case GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER:
*params = BoolToGLInt(programObject->IsUniformBlockReferencedByStage(uniformBlockIndex, EShLangGeometry));
MGLOG_D("%s: GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER = %d", __func__, *params);
break;
case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:
*params = BoolToGLInt(programObject->IsUniformBlockReferencedByStage(uniformBlockIndex, EShLangFragment));
MGLOG_D("%s: GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER = %d", __func__, *params);
break;
case GL_UNIFORM_BLOCK_REFERENCED_BY_COMPUTE_SHADER:
*params = BoolToGLInt(programObject->IsUniformBlockReferencedByStage(uniformBlockIndex, EShLangCompute));
MGLOG_D("%s: GL_UNIFORM_BLOCK_REFERENCED_BY_COMPUTE_SHADER = %d", __func__, *params);
break;
case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES: {
GLint uniformIndexCount = 0;
for (Uint uniformIndex = 0; uniformIndex < programObject->GetUniformCount(); ++uniformIndex) {
if (programObject->GetActiveUniformBlockIndex(uniformIndex) != static_cast<Int>(uniformBlockIndex)) {
continue;
}
params[uniformIndexCount++] = static_cast<GLint>(uniformIndex);
}
MGLOG_D("%s: GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES count = %d", __func__, uniformIndexCount);
break;
}
default:
MGLOG_E("%s: unknown pname = %p %s", __func__, pname, MG_Util::ConvertGLEnumToString(pname).c_str());
MG_State::pGLContext->RecordError(
@@ -1084,7 +1142,7 @@ namespace MobileGL::MG_Impl::GLImpl {
const auto& name = programObject->GetUniformBlockName(uniformBlockIndex);
CopyStr(bufSize, length, uniformBlockName, name.c_str(), (GLsizei)name.length());
MGLOG_D("%s: \"%s\" at uniformBlockIndex %02d, length = %d", __func__, uniformBlockName, uniformBlockIndex,
*length);
length ? *length : 0);
}
void BindFragDataLocation_State(GLuint program, GLuint colorNumber, const char* name) {
@@ -1166,6 +1224,16 @@ namespace MobileGL::MG_Impl::GLImpl {
GetActiveUniform_State(program, index, bufSize, length, size, type, name);
}
void GetActiveUniformName(GLuint program, GLuint uniformIndex, GLsizei bufSize, GLsizei* length,
GLchar* uniformName) {
GetActiveUniform_State(program, uniformIndex, bufSize, length, nullptr, nullptr, uniformName);
}
void GetUniformIndices(GLuint program, GLsizei uniformCount, const GLchar* const* uniformNames,
GLuint* uniformIndices) {
GetUniformIndices_State(program, uniformCount, uniformNames, uniformIndices);
}
void GetAttachedShaders(GLuint program, GLsizei maxCount, GLsizei* count, GLuint* shaders) {
GetAttachedShaders_State(program, maxCount, count, shaders);
}
@@ -1206,6 +1274,10 @@ namespace MobileGL::MG_Impl::GLImpl {
GetUniformiv_State(program, location, params);
}
void GetUniformuiv(GLuint program, GLint location, GLuint* params) {
GetUniformuiv_State(program, location, params);
}
GLboolean IsProgram(GLuint program) {
return IsProgram_State(program);
}
@@ -1263,6 +1335,25 @@ namespace MobileGL::MG_Impl::GLImpl {
Uniform4iv(location, 1, v);
}
void Uniform1ui(GLint location, GLuint v0) {
Uniform1uiv(location, 1, &v0);
}
void Uniform2ui(GLint location, GLuint v0, GLuint v1) {
GLuint v[] = {v0, v1};
Uniform2uiv(location, 1, v);
}
void Uniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2) {
GLuint v[] = {v0, v1, v2};
Uniform3uiv(location, 1, v);
}
void Uniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3) {
GLuint v[] = {v0, v1, v2, v3};
Uniform4uiv(location, 1, v);
}
void Uniform1fv(GLint location, GLsizei count, const GLfloat* value) {
Uniform1fv_State(location, count, value);
}
@@ -1295,6 +1386,22 @@ namespace MobileGL::MG_Impl::GLImpl {
Uniform4iv_State(location, count, value);
}
void Uniform1uiv(GLint location, GLsizei count, const GLuint* value) {
Uniformv_State<1>(location, count, value);
}
void Uniform2uiv(GLint location, GLsizei count, const GLuint* value) {
Uniformv_State<2>(location, count, value);
}
void Uniform3uiv(GLint location, GLsizei count, const GLuint* value) {
Uniformv_State<3>(location, count, value);
}
void Uniform4uiv(GLint location, GLsizei count, const GLuint* value) {
Uniformv_State<4>(location, count, value);
}
void UniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) {
UniformMatrix2fv_State(location, count, transpose, value);
}