mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-12 06:08:30 +09:00
[Feat] (...): Add ProgramState while implementing these gl functions. Rename some functions in MG_State.
This commit is contained in:
@@ -45,7 +45,7 @@ GLenum CommonState::SetPixelStoreInt(GLenum pname, GLint param) {
|
||||
return GL_NO_ERROR;
|
||||
}
|
||||
|
||||
GLint CommonState::GetPixelStoreInt(GLenum pname) {
|
||||
GLint CommonState::QueryPixelStoreInt(GLenum pname) {
|
||||
auto it = pixelStoreParams.find(pname);
|
||||
if (it != pixelStoreParams.end()) {
|
||||
return it->second;
|
||||
|
||||
@@ -16,7 +16,7 @@ public:
|
||||
// Return: the validity of the operation, according to OpenGL 3 standard
|
||||
GLenum SetPixelStoreInt(GLenum pname, GLint param);
|
||||
|
||||
GLint GetPixelStoreInt(GLenum pname);
|
||||
GLint QueryPixelStoreInt(GLenum pname);
|
||||
};
|
||||
|
||||
#endif //MOBILEGL_COMMONSTATE_H
|
||||
|
||||
@@ -9,6 +9,7 @@ TextureState* MG_State_T::textureState = nullptr;
|
||||
CommonState* MG_State_T::commonState = nullptr;
|
||||
BufferState* MG_State_T::bufferState = nullptr;
|
||||
VertexArrayState* MG_State_T::vertexArrayState = nullptr;
|
||||
ProgramState* MG_State_T::programState = nullptr;
|
||||
|
||||
namespace MG_State {
|
||||
void Init() {
|
||||
@@ -16,6 +17,7 @@ namespace MG_State {
|
||||
MG_State_T::commonState = new CommonState();
|
||||
MG_State_T::bufferState = new BufferState();
|
||||
MG_State_T::vertexArrayState = new VertexArrayState();
|
||||
MG_State_T::programState = new ProgramState();
|
||||
}
|
||||
|
||||
void Destroy() {
|
||||
@@ -23,6 +25,7 @@ namespace MG_State {
|
||||
delete MG_State_T::commonState;
|
||||
delete MG_State_T::bufferState;
|
||||
delete MG_State_T::vertexArrayState;
|
||||
delete MG_State_T::programState;
|
||||
}
|
||||
|
||||
void SetError(GLenum error) {
|
||||
@@ -88,8 +91,8 @@ namespace MG_State {
|
||||
return MG_State_T::textureState->DeleteN(n, textures);
|
||||
}
|
||||
|
||||
GLenum GetTextureLevelPropertyIntVector(GLenum target, GLint level, GLenum pname, GLint* params) {
|
||||
return MG_State_T::textureState->GetLevelPropertyIntVector(target, level, pname, params);
|
||||
GLenum QueryTextureLevelPropertyIntVector(GLenum target, GLint level, GLenum pname, GLint* params) {
|
||||
return MG_State_T::textureState->QueryLevelPropertyIntVector(target, level, pname, params);
|
||||
}
|
||||
|
||||
// Common
|
||||
@@ -97,8 +100,8 @@ namespace MG_State {
|
||||
return MG_State_T::commonState->SetPixelStoreInt(pname, param);
|
||||
}
|
||||
|
||||
GLint MG_State::GetPixelStoreInt(GLenum pname) {
|
||||
return MG_State_T::commonState->GetPixelStoreInt(pname);
|
||||
GLint MG_State::QueryPixelStoreInt(GLenum pname) {
|
||||
return MG_State_T::commonState->QueryPixelStoreInt(pname);
|
||||
}
|
||||
|
||||
// Buffer
|
||||
@@ -180,4 +183,73 @@ namespace MG_State {
|
||||
index, size, type, GL_FALSE, stride, pointer, true, currentBuffer
|
||||
);
|
||||
}
|
||||
|
||||
// Program
|
||||
GLenum CreateShader(GLenum type, GLuint* shader) {
|
||||
return MG_State_T::programState->CreateShader(type, shader);
|
||||
}
|
||||
|
||||
GLenum CreateProgram(GLuint* program) {
|
||||
return MG_State_T::programState->CreateProgram(program);
|
||||
}
|
||||
|
||||
GLenum DeleteShader(GLuint shader) {
|
||||
return MG_State_T::programState->DeleteShader(shader);
|
||||
}
|
||||
|
||||
GLenum DeleteProgram(GLuint program) {
|
||||
return MG_State_T::programState->DeleteProgram(program);
|
||||
}
|
||||
|
||||
GLenum LinkShaderToProgram(GLuint program, GLuint shader) {
|
||||
return MG_State_T::programState->LinkShaderToProgram(program, shader);
|
||||
}
|
||||
|
||||
GLenum UploadShaderSource(GLuint shader, GLsizei count, const GLchar** string, const GLint* length) {
|
||||
return MG_State_T::programState->UploadShaderSource(shader, count, string, length);
|
||||
}
|
||||
|
||||
GLenum BuildShaderStage(GLuint shader) {
|
||||
return MG_State_T::programState->BuildShaderStage(shader);
|
||||
}
|
||||
|
||||
GLenum FinalizeProgramPipeline(GLuint program) {
|
||||
return MG_State_T::programState->FinalizeProgramPipeline(program);
|
||||
}
|
||||
|
||||
GLenum ActivateRenderProgram(GLuint program) {
|
||||
return MG_State_T::programState->ActivateRenderProgram(program);
|
||||
}
|
||||
|
||||
GLenum DefineProgramAttributeBinding(GLuint program, GLuint index, const GLchar* name) {
|
||||
return MG_State_T::programState->DefineProgramAttributeBinding(program, index, name);
|
||||
}
|
||||
|
||||
GLint QueryProgramAttributeBinding(GLuint program, const GLchar* name) {
|
||||
return MG_State_T::programState->QueryProgramAttributeBinding(program, name);
|
||||
}
|
||||
|
||||
GLint QueryProgramUniformLocation(GLuint program, const GLchar* name) {
|
||||
return MG_State_T::programState->QueryProgramUniformLocation(program, name);
|
||||
}
|
||||
|
||||
GLenum QueryProgramStateIntVector(GLuint program, GLenum pname, GLint* params) {
|
||||
return MG_State_T::programState->QueryProgramStateIntVector(program, pname, params);
|
||||
}
|
||||
|
||||
GLenum QueryShaderStateIntVector(GLuint shader, GLenum pname, GLint* params) {
|
||||
return MG_State_T::programState->QueryShaderStateIntVector(shader, pname, params);
|
||||
}
|
||||
|
||||
GLuint GetCurrentProgram() {
|
||||
return MG_State_T::programState->GetCurrentProgram();
|
||||
}
|
||||
|
||||
bool SetProgramStatus(GLuint program, GLboolean status) {
|
||||
return MG_State_T::programState->SetProgramStatus(program, status);
|
||||
}
|
||||
|
||||
bool SetShaderStatus(GLuint shader, GLboolean status) {
|
||||
return MG_State_T::programState->SetShaderStatus(shader, status);
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,7 @@ struct MG_State_T {
|
||||
static CommonState* commonState;
|
||||
static BufferState* bufferState;
|
||||
static VertexArrayState* vertexArrayState;
|
||||
static ProgramState* programState;
|
||||
};
|
||||
|
||||
namespace MG_State {
|
||||
@@ -36,11 +37,11 @@ namespace MG_State {
|
||||
GLenum SetTexturePropertyFloat(GLenum target, GLenum pname, GLfloat param);
|
||||
GLenum DeleteTexture(GLuint texture);
|
||||
GLenum DeleteTextures(GLsizei n, const GLuint* textures);
|
||||
GLenum GetTextureLevelPropertyIntVector(GLenum target, GLint level, GLenum pname, GLint* params);
|
||||
GLenum QueryTextureLevelPropertyIntVector(GLenum target, GLint level, GLenum pname, GLint* params);
|
||||
|
||||
// Common
|
||||
GLenum SetPixelStoreInt(GLenum pname, GLint param);
|
||||
GLint GetPixelStoreInt(GLenum pname);
|
||||
GLint QueryPixelStoreInt(GLenum pname);
|
||||
|
||||
// Buffer
|
||||
GLenum AcquireBufferMemory(GLenum target, GLenum access, void** mappedPtr);
|
||||
@@ -54,7 +55,6 @@ namespace MG_State {
|
||||
GLenum QueryBufferPropertyIntVector(GLenum target, GLenum pname, GLint* params);
|
||||
|
||||
// VertexArray
|
||||
|
||||
GLenum CreateVertexArray(GLuint* array);
|
||||
GLenum CreateVertexArrays(GLsizei n, GLuint* arrays);
|
||||
GLenum BindVertexArray(GLuint array);
|
||||
@@ -65,6 +65,26 @@ namespace MG_State {
|
||||
const void* pointer);
|
||||
GLenum SetVertexAttributeLayoutInt(GLuint index, GLint size, GLenum type,
|
||||
GLsizei stride, const void* pointer);
|
||||
|
||||
// Program
|
||||
GLenum CreateShader(GLenum type, GLuint* shader);
|
||||
GLenum CreateProgram(GLuint* program);
|
||||
GLenum DeleteShader(GLuint shader);
|
||||
GLenum DeleteProgram(GLuint program);
|
||||
GLenum LinkShaderToProgram(GLuint program, GLuint shader);
|
||||
GLenum UploadShaderSource(GLuint shader, GLsizei count, const GLchar** string, const GLint* length);
|
||||
GLenum BuildShaderStage(GLuint shader);
|
||||
GLenum FinalizeProgramPipeline(GLuint program);
|
||||
GLenum ActivateRenderProgram(GLuint program);
|
||||
GLenum DefineProgramAttributeBinding(GLuint program, GLuint index, const GLchar* name);
|
||||
GLint QueryProgramAttributeBinding(GLuint program, const GLchar* name);
|
||||
GLint QueryProgramUniformLocation(GLuint program, const GLchar* name);
|
||||
GLenum QueryProgramStateIntVector(GLuint program, GLenum pname, GLint* params);
|
||||
GLenum QueryShaderStateIntVector(GLuint shader, GLenum pname, GLint* params);
|
||||
|
||||
GLuint GetCurrentProgram();
|
||||
bool SetProgramStatus(GLuint program, GLboolean status);
|
||||
bool SetShaderStatus(GLuint shader, GLboolean status);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,258 @@
|
||||
//
|
||||
// Created by BZLZHH on 2025/5/1.
|
||||
//
|
||||
|
||||
// TODO: Add more gl error check for buffer state manager.
|
||||
// TODO: Check if the state machine really meets up to OpenGL 3 standard.
|
||||
|
||||
#include "ProgramState.h"
|
||||
|
||||
GLenum ProgramState::CreateShader(GLenum type, GLuint* shader) {
|
||||
if (!shader) return GL_INVALID_VALUE;
|
||||
if (type != GL_VERTEX_SHADER && type != GL_FRAGMENT_SHADER)
|
||||
return GL_INVALID_ENUM;
|
||||
|
||||
GLuint id = freeShaderIds_.empty() ? ++lastShaderId_ : *freeShaderIds_.begin();
|
||||
if (!freeShaderIds_.empty()) freeShaderIds_.erase(freeShaderIds_.begin());
|
||||
|
||||
ShaderObject obj;
|
||||
obj.type = type;
|
||||
obj.compiled = UncertainBool::False;
|
||||
obj.markedForDeletion = false;
|
||||
shaders_[id] = obj;
|
||||
*shader = id;
|
||||
return GL_NO_ERROR;
|
||||
}
|
||||
|
||||
GLenum ProgramState::CreateProgram(GLuint* program) {
|
||||
if (!program) return GL_INVALID_VALUE;
|
||||
|
||||
GLuint id = freeProgramIds_.empty() ? ++lastProgramId_ : *freeProgramIds_.begin();
|
||||
if (!freeProgramIds_.empty()) freeProgramIds_.erase(freeProgramIds_.begin());
|
||||
|
||||
ProgramObject obj;
|
||||
obj.linked = UncertainBool::False;
|
||||
obj.markedForDeletion = false;
|
||||
programs_[id] = obj;
|
||||
*program = id;
|
||||
return GL_NO_ERROR;
|
||||
}
|
||||
|
||||
GLenum ProgramState::DeleteShader(GLuint shader) {
|
||||
if (!ValidateShader_(shader)) return GL_INVALID_VALUE;
|
||||
|
||||
if (shaders_[shader].markedForDeletion) return GL_NO_ERROR;
|
||||
|
||||
bool inUse = false;
|
||||
for (auto& [progId, program] : programs_) {
|
||||
auto it = std::find(program.attachedShaders.begin(),
|
||||
program.attachedShaders.end(), shader);
|
||||
if (it != program.attachedShaders.end()) {
|
||||
inUse = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (inUse) {
|
||||
shaders_[shader].markedForDeletion = true;
|
||||
} else {
|
||||
shaders_.erase(shader);
|
||||
freeShaderIds_.insert(shader);
|
||||
}
|
||||
return GL_NO_ERROR;
|
||||
}
|
||||
|
||||
GLenum ProgramState::DeleteProgram(GLuint program) {
|
||||
if (!ValidateProgram_(program)) return GL_INVALID_VALUE;
|
||||
|
||||
programs_.erase(program);
|
||||
freeProgramIds_.insert(program);
|
||||
if (currentProgram_ == program)
|
||||
currentProgram_ = 0;
|
||||
return GL_NO_ERROR;
|
||||
}
|
||||
|
||||
GLenum ProgramState::LinkShaderToProgram(GLuint program, GLuint shader) {
|
||||
if (!ValidateProgram_(program) || !ValidateShader_(shader))
|
||||
return GL_INVALID_VALUE;
|
||||
|
||||
auto& prog = programs_[program];
|
||||
if (std::find(prog.attachedShaders.begin(),
|
||||
prog.attachedShaders.end(), shader) != prog.attachedShaders.end())
|
||||
return GL_INVALID_OPERATION;
|
||||
|
||||
prog.attachedShaders.push_back(shader);
|
||||
return GL_NO_ERROR;
|
||||
}
|
||||
|
||||
GLenum ProgramState::UploadShaderSource(GLuint shader, GLsizei count,
|
||||
const GLchar** string, const GLint* length) {
|
||||
if (!ValidateShader_(shader)) return GL_INVALID_VALUE;
|
||||
if (count < 0) return GL_INVALID_VALUE;
|
||||
|
||||
std::string source;
|
||||
for (GLsizei i = 0; i < count; ++i) {
|
||||
const GLchar* str = string[i];
|
||||
GLint len = (length && length[i] >= 0) ? length[i] : strlen(str);
|
||||
source.append(str, len);
|
||||
}
|
||||
shaders_[shader].source = std::move(source);
|
||||
return GL_NO_ERROR;
|
||||
}
|
||||
|
||||
GLenum ProgramState::BuildShaderStage(GLuint shader) {
|
||||
if (!ValidateShader_(shader)) return GL_INVALID_VALUE;
|
||||
|
||||
auto& obj = shaders_[shader];
|
||||
// TODO: Add glslang to convert it to SPIR-V first, and then check it in the actual backend.
|
||||
obj.compiled = {UncertainBool::Unknown, UncertainBool::True};
|
||||
obj.compileStatus = GL_TRUE;
|
||||
obj.infoLog.clear();
|
||||
|
||||
return GL_NO_ERROR;
|
||||
}
|
||||
|
||||
GLenum ProgramState::FinalizeProgramPipeline(GLuint program) {
|
||||
if (!ValidateProgram_(program)) return GL_INVALID_VALUE;
|
||||
auto& prog = programs_[program];
|
||||
|
||||
for (GLuint shader : prog.attachedShaders) {
|
||||
if (!shaders_[shader].compiled.toBool())
|
||||
return GL_INVALID_OPERATION;
|
||||
}
|
||||
|
||||
// TODO: Check the actual program linking status.
|
||||
// We might consider using a program emulator (or real backend checking?) or something better in the future.
|
||||
prog.linked = {UncertainBool::Unknown, UncertainBool::True};
|
||||
prog.linkStatus = GL_TRUE;
|
||||
prog.infoLog.clear();
|
||||
|
||||
for (auto& [name, index] : prog.attribBindings) {
|
||||
prog.attribLocations[name] = index;
|
||||
}
|
||||
|
||||
CleanupShaders_();
|
||||
return GL_NO_ERROR;
|
||||
}
|
||||
|
||||
GLenum ProgramState::ActivateRenderProgram(GLuint program) {
|
||||
if (program != 0 && !ValidateProgram_(program))
|
||||
return GL_INVALID_VALUE;
|
||||
|
||||
currentProgram_ = program;
|
||||
return GL_NO_ERROR;
|
||||
}
|
||||
|
||||
GLenum ProgramState::DefineProgramAttributeBinding(GLuint program, GLuint index, const GLchar* name) {
|
||||
if (!ValidateProgram_(program)) return GL_INVALID_VALUE;
|
||||
if (index >= GL_MAX_VERTEX_ATTRIBS) return GL_INVALID_VALUE;
|
||||
|
||||
programs_[program].attribBindings[name] = index;
|
||||
return GL_NO_ERROR;
|
||||
}
|
||||
|
||||
GLint ProgramState::QueryProgramAttributeBinding(GLuint program, const GLchar* name) {
|
||||
if (!ValidateProgram_(program)) return -1;
|
||||
|
||||
auto& prog = programs_[program];
|
||||
if (prog.attribLocations.count(name))
|
||||
return prog.attribLocations[name];
|
||||
return -1;
|
||||
}
|
||||
|
||||
GLint ProgramState::QueryProgramUniformLocation(GLuint program, const GLchar* name) {
|
||||
if (!ValidateProgram_(program)) return -1;
|
||||
|
||||
auto& prog = programs_[program];
|
||||
if (prog.uniformLocations.count(name))
|
||||
return prog.uniformLocations[name];
|
||||
return -1;
|
||||
}
|
||||
|
||||
GLenum ProgramState::QueryProgramStateIntVector(GLuint program, GLenum pname, GLint* params) {
|
||||
if (!ValidateProgram_(program)) return GL_INVALID_VALUE;
|
||||
auto& prog = programs_[program];
|
||||
|
||||
switch (pname) {
|
||||
case GL_LINK_STATUS: *params = prog.linkStatus; break;
|
||||
case GL_DELETE_STATUS: *params = prog.markedForDeletion; break;
|
||||
case GL_ATTACHED_SHADERS: *params = (GLint)prog.attachedShaders.size(); break;
|
||||
default: return GL_INVALID_ENUM;
|
||||
}
|
||||
return GL_NO_ERROR;
|
||||
}
|
||||
|
||||
GLenum ProgramState::QueryShaderStateIntVector(GLuint shader, GLenum pname, GLint* params) {
|
||||
if (!ValidateShader_(shader)) return GL_INVALID_VALUE;
|
||||
auto& obj = shaders_[shader];
|
||||
|
||||
switch (pname) {
|
||||
case GL_COMPILE_STATUS: *params = obj.compileStatus; break;
|
||||
case GL_DELETE_STATUS: *params = obj.markedForDeletion; break;
|
||||
case GL_SHADER_TYPE: *params = obj.type; break;
|
||||
default: return GL_INVALID_ENUM;
|
||||
}
|
||||
return GL_NO_ERROR;
|
||||
}
|
||||
|
||||
bool ProgramState::SetProgramStatus(GLuint program, GLboolean status) {
|
||||
if (!ValidateProgram_(program)) return false;
|
||||
auto& prog = programs_[program];
|
||||
if (prog.linked && status != GL_TRUE) {
|
||||
return false;
|
||||
}
|
||||
if (status == GL_TRUE)
|
||||
prog.linked = true;
|
||||
else
|
||||
prog.linked = false;
|
||||
prog.linkStatus = status;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ProgramState::SetShaderStatus(GLuint shader, GLboolean status) {
|
||||
if (!ValidateShader_(shader)) return false;
|
||||
auto& obj = shaders_[shader];
|
||||
if (status == GL_TRUE)
|
||||
obj.compiled = true;
|
||||
else
|
||||
obj.compiled = false;
|
||||
obj.compileStatus = status;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ProgramState::ValidateShader_(GLuint shader) {
|
||||
return shaders_.count(shader) && !shaders_[shader].markedForDeletion;
|
||||
}
|
||||
|
||||
bool ProgramState::ValidateProgram_(GLuint program) {
|
||||
return programs_.count(program) && !programs_[program].markedForDeletion;
|
||||
}
|
||||
|
||||
void ProgramState::CleanupShaders_() {
|
||||
auto it = shaders_.begin();
|
||||
while (it != shaders_.end()) {
|
||||
if (it->second.markedForDeletion) {
|
||||
bool inUse = false;
|
||||
for (auto& [progId, program] : programs_) {
|
||||
if (std::find(program.attachedShaders.begin(),
|
||||
program.attachedShaders.end(), it->first)
|
||||
!= program.attachedShaders.end()) {
|
||||
inUse = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!inUse) {
|
||||
freeShaderIds_.insert(it->first);
|
||||
it = shaders_.erase(it);
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GLuint ProgramState::GetCurrentProgram() const {
|
||||
return currentProgram_;
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
//
|
||||
// Created by BZLZHH on 2025/5/1.
|
||||
//
|
||||
|
||||
#ifndef MOBILEGL_PROGRAMSTATE_H
|
||||
#define MOBILEGL_PROGRAMSTATE_H
|
||||
#define MOBILEGL_GLSTATE_H
|
||||
|
||||
#include "../../../Includes.h"
|
||||
|
||||
struct ShaderObject {
|
||||
GLenum type;
|
||||
std::string source;
|
||||
UncertainBool compiled;
|
||||
GLint compileStatus;
|
||||
std::string infoLog;
|
||||
bool markedForDeletion;
|
||||
};
|
||||
|
||||
struct ProgramObject {
|
||||
std::vector<GLuint> attachedShaders;
|
||||
UncertainBool linked;
|
||||
GLint linkStatus;
|
||||
std::string infoLog;
|
||||
std::unordered_map<std::string, GLint> attribBindings;
|
||||
std::unordered_map<std::string, GLint> attribLocations;
|
||||
std::unordered_map<std::string, GLint> uniformLocations;
|
||||
bool markedForDeletion;
|
||||
};
|
||||
|
||||
class ProgramState {
|
||||
private:
|
||||
std::unordered_map<GLuint, ShaderObject> shaders_;
|
||||
std::unordered_map<GLuint, ProgramObject> programs_;
|
||||
std::set<GLuint> freeShaderIds_;
|
||||
std::set<GLuint> freeProgramIds_;
|
||||
GLuint lastShaderId_ = 0;
|
||||
GLuint lastProgramId_ = 0;
|
||||
GLuint currentProgram_ = 0;
|
||||
|
||||
public:
|
||||
// Return: the validity of the operation, according to OpenGL 3 standard
|
||||
GLenum CreateShader(GLenum type, GLuint* shader);
|
||||
GLenum CreateProgram(GLuint* program);
|
||||
GLenum DeleteShader(GLuint shader);
|
||||
GLenum DeleteProgram(GLuint program);
|
||||
GLenum LinkShaderToProgram(GLuint program, GLuint shader);
|
||||
GLenum UploadShaderSource(GLuint shader, GLsizei count, const GLchar** string, const GLint* length);
|
||||
GLenum BuildShaderStage(GLuint shader);
|
||||
GLenum FinalizeProgramPipeline(GLuint program);
|
||||
GLenum ActivateRenderProgram(GLuint program);
|
||||
GLenum DefineProgramAttributeBinding(GLuint program, GLuint index, const GLchar* name);
|
||||
GLint QueryProgramAttributeBinding(GLuint program, const GLchar* name);
|
||||
GLint QueryProgramUniformLocation(GLuint program, const GLchar* name);
|
||||
GLenum QueryProgramStateIntVector(GLuint program, GLenum pname, GLint* params);
|
||||
GLenum QueryShaderStateIntVector(GLuint shader, GLenum pname, GLint* params);
|
||||
|
||||
GLuint GetCurrentProgram() const;
|
||||
bool SetProgramStatus(GLuint program, GLboolean status);
|
||||
bool SetShaderStatus(GLuint shader, GLboolean status);
|
||||
|
||||
private:
|
||||
bool ValidateShader_(GLuint shader);
|
||||
bool ValidateProgram_(GLuint program);
|
||||
void CleanupShaders_();
|
||||
};
|
||||
|
||||
#endif // MOBILEGL_PROGRAMSTATE_H
|
||||
@@ -38,7 +38,7 @@ TextureState::TextureState() {
|
||||
}
|
||||
|
||||
GLint TextureState::GetUnpackParam_(GLenum pname) {
|
||||
GLint result = MG_State::GetPixelStoreInt(pname);
|
||||
GLint result = MG_State::QueryPixelStoreInt(pname);
|
||||
MG_Util::Debug::LogD("MG_State: Texture: GetUnpackParam_ pname=0x%x, returns %d", pname, result);
|
||||
return result;
|
||||
}
|
||||
@@ -574,31 +574,31 @@ GLenum TextureState::DeleteN(GLsizei n, const GLuint* textures) {
|
||||
}
|
||||
|
||||
|
||||
GLenum TextureState::GetLevelPropertyIntVector(GLenum target, GLint level, GLenum pname, GLint* params) {
|
||||
MG_Util::Debug::LogD("MG_State: Texture: GetLevelPropertyIntVector called target=0x%x, level=%d, pname=0x%x", target, level, pname);
|
||||
GLenum TextureState::QueryLevelPropertyIntVector(GLenum target, GLint level, GLenum pname, GLint* params) {
|
||||
MG_Util::Debug::LogD("MG_State: Texture: QueryLevelPropertyIntVector called target=0x%x, level=%d, pname=0x%x", target, level, pname);
|
||||
if (MG_Constants::Texture::VALID_TARGETS.find(target) == MG_Constants::Texture::VALID_TARGETS.end()) {
|
||||
MG_Util::Debug::LogE("MG_State: Texture: GetLevelPropertyIntVector invalid target=0x%x", target);
|
||||
MG_Util::Debug::LogE("MG_State: Texture: QueryLevelPropertyIntVector invalid target=0x%x", target);
|
||||
return GL_INVALID_ENUM;
|
||||
}
|
||||
|
||||
if (level < 0) {
|
||||
MG_Util::Debug::LogE("MG_State: Texture: GetLevelPropertyIntVector invalid level=%d", level);
|
||||
MG_Util::Debug::LogE("MG_State: Texture: QueryLevelPropertyIntVector invalid level=%d", level);
|
||||
return GL_INVALID_VALUE;
|
||||
}
|
||||
|
||||
if (MG_Constants::Texture::VALID_QUERY_LEVEL_PROPERTY_PARAM_NAMES.find(pname) == MG_Constants::Texture::VALID_QUERY_LEVEL_PROPERTY_PARAM_NAMES.end()) {
|
||||
MG_Util::Debug::LogE("MG_State: Texture: GetLevelPropertyIntVector invalid pname=0x%x", pname);
|
||||
MG_Util::Debug::LogE("MG_State: Texture: QueryLevelPropertyIntVector invalid pname=0x%x", pname);
|
||||
return GL_INVALID_ENUM;
|
||||
}
|
||||
|
||||
if ((target == GL_TEXTURE_RECTANGLE || target == GL_PROXY_TEXTURE_RECTANGLE) && level != 0) {
|
||||
MG_Util::Debug::LogE("MG_State: Texture: GetLevelPropertyIntVector invalid level for rectangle texture");
|
||||
MG_Util::Debug::LogE("MG_State: Texture: QueryLevelPropertyIntVector invalid level for rectangle texture");
|
||||
return GL_INVALID_VALUE;
|
||||
}
|
||||
|
||||
GLuint activeUnit = activeTextureUnit_;
|
||||
if (activeUnit >= textureUnits_.size()) {
|
||||
MG_Util::Debug::LogE("MG_State: Texture: GetLevelPropertyIntVector active texture unit out of range");
|
||||
MG_Util::Debug::LogE("MG_State: Texture: QueryLevelPropertyIntVector active texture unit out of range");
|
||||
return GL_INVALID_OPERATION;
|
||||
}
|
||||
|
||||
@@ -614,7 +614,7 @@ GLenum TextureState::GetLevelPropertyIntVector(GLenum target, GLint level, GLenu
|
||||
if (!isProxyTexture && boundTexture == 0) {
|
||||
switch (pname) {
|
||||
case GL_TEXTURE_COMPRESSED_IMAGE_SIZE:
|
||||
MG_Util::Debug::LogE("MG_State: Texture: GetLevelPropertyIntVector no texture bound for compressed image size");
|
||||
MG_Util::Debug::LogE("MG_State: Texture: QueryLevelPropertyIntVector no texture bound for compressed image size");
|
||||
return GL_INVALID_OPERATION;
|
||||
case GL_TEXTURE_INTERNAL_FORMAT:
|
||||
*params = GL_NONE;
|
||||
@@ -626,7 +626,7 @@ GLenum TextureState::GetLevelPropertyIntVector(GLenum target, GLint level, GLenu
|
||||
*params = 0;
|
||||
break;
|
||||
}
|
||||
MG_Util::Debug::LogD("MG_State: Texture: GetLevelPropertyIntVector returns default value for unbound texture");
|
||||
MG_Util::Debug::LogD("MG_State: Texture: QueryLevelPropertyIntVector returns default value for unbound texture");
|
||||
return GL_NO_ERROR;
|
||||
}
|
||||
|
||||
@@ -637,7 +637,7 @@ GLenum TextureState::GetLevelPropertyIntVector(GLenum target, GLint level, GLenu
|
||||
if (texIt == textures.end()) {
|
||||
*params = 0;
|
||||
MG_Util::Debug::LogW(
|
||||
"MG_State: Texture: GetLevelPropertyIntVector texture %u not found",
|
||||
"MG_State: Texture: QueryLevelPropertyIntVector texture %u not found",
|
||||
boundTexture);
|
||||
return GL_NO_ERROR;
|
||||
}
|
||||
@@ -646,7 +646,7 @@ GLenum TextureState::GetLevelPropertyIntVector(GLenum target, GLint level, GLenu
|
||||
TextureObject& tex = isProxyTexture ? proxyTextures_[target] : texIt->second;
|
||||
|
||||
if (!isProxyTexture && tex.target != target && tex.target != GL_NONE) {
|
||||
MG_Util::Debug::LogE("MG_State: Texture: GetLevelPropertyIntVector texture target mismatch: texture target=0x%x, expected=0x%x", tex.target, target);
|
||||
MG_Util::Debug::LogE("MG_State: Texture: QueryLevelPropertyIntVector texture target mismatch: texture target=0x%x, expected=0x%x", tex.target, target);
|
||||
return GL_INVALID_OPERATION;
|
||||
}
|
||||
|
||||
@@ -654,7 +654,7 @@ GLenum TextureState::GetLevelPropertyIntVector(GLenum target, GLint level, GLenu
|
||||
if (mipIt == tex.params.mipmapData.end()) {
|
||||
switch (pname) {
|
||||
case GL_TEXTURE_COMPRESSED_IMAGE_SIZE:
|
||||
MG_Util::Debug::LogE("MG_State: Texture: GetLevelPropertyIntVector no mipmap level %d for compressed image size", level);
|
||||
MG_Util::Debug::LogE("MG_State: Texture: QueryLevelPropertyIntVector no mipmap level %d for compressed image size", level);
|
||||
return GL_INVALID_OPERATION;
|
||||
case GL_TEXTURE_INTERNAL_FORMAT:
|
||||
*params = GL_NONE;
|
||||
@@ -666,7 +666,7 @@ GLenum TextureState::GetLevelPropertyIntVector(GLenum target, GLint level, GLenu
|
||||
*params = 0;
|
||||
break;
|
||||
}
|
||||
MG_Util::Debug::LogD("MG_State: Texture: GetLevelPropertyIntVector returns default value for missing mipmap level");
|
||||
MG_Util::Debug::LogD("MG_State: Texture: QueryLevelPropertyIntVector returns default value for missing mipmap level");
|
||||
return GL_NO_ERROR;
|
||||
}
|
||||
|
||||
@@ -707,16 +707,16 @@ GLenum TextureState::GetLevelPropertyIntVector(GLenum target, GLint level, GLenu
|
||||
break;
|
||||
case GL_TEXTURE_COMPRESSED_IMAGE_SIZE:
|
||||
if (!sizes.isCompressed) {
|
||||
MG_Util::Debug::LogE("MG_State: Texture: GetLevelPropertyIntVector texture is not compressed");
|
||||
MG_Util::Debug::LogE("MG_State: Texture: QueryLevelPropertyIntVector texture is not compressed");
|
||||
return GL_INVALID_OPERATION;
|
||||
}
|
||||
*params = static_cast<GLint>(mip.pixelData.size());
|
||||
break;
|
||||
default:
|
||||
MG_Util::Debug::LogE("MG_State: Texture: GetLevelPropertyIntVector invalid pname=0x%x", pname);
|
||||
MG_Util::Debug::LogE("MG_State: Texture: QueryLevelPropertyIntVector invalid pname=0x%x", pname);
|
||||
return GL_INVALID_ENUM;
|
||||
}
|
||||
MG_Util::Debug::LogD("MG_State: Texture: GetLevelPropertyIntVector returns %d for pname=0x%x", *params, pname);
|
||||
MG_Util::Debug::LogD("MG_State: Texture: QueryLevelPropertyIntVector returns %d for pname=0x%x", *params, pname);
|
||||
return GL_NO_ERROR;
|
||||
}
|
||||
|
||||
|
||||
@@ -86,7 +86,7 @@ public:
|
||||
GLenum SetTexturePropertyFloat(GLenum target, GLenum pname, GLfloat param);
|
||||
GLenum Delete(GLuint texture);
|
||||
GLenum DeleteN(GLsizei n, const GLuint* textures);
|
||||
GLenum GetLevelPropertyIntVector(GLenum target, GLint level, GLenum pname, GLint* params);
|
||||
GLenum QueryLevelPropertyIntVector(GLenum target, GLint level, GLenum pname, GLint* params);
|
||||
|
||||
private:
|
||||
size_t CalculatePixelDataSize_(GLenum format, GLenum type, GLsizei width, GLsizei height);
|
||||
|
||||
Reference in New Issue
Block a user