[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
+15
View File
@@ -1139,6 +1139,21 @@ namespace MobileGL {
return EGL_NO_SURFACE;
}
Bool EGLContext::IsDoubleBufferedSurface(EGLSurfaceHandle surface) const {
const std::lock_guard<std::recursive_mutex> lock(m_mutex);
const auto* surfaceObject = TryGetSurface(surface);
if (!surfaceObject) {
return false;
}
if (surfaceObject->RenderBuffer != EGL_BACK_BUFFER) {
return false;
}
return surfaceObject->Type == SurfaceType::Window ||
surfaceObject->Type == SurfaceType::PlatformWindow;
}
EGLContext::EGLSyncHandle EGLContext::CreateSync(EGLDisplayHandle display, EGLenum type,
const EGLAttrib* attribList) {
const std::lock_guard<std::recursive_mutex> lock(m_mutex);
+1
View File
@@ -87,6 +87,7 @@ namespace MobileGL {
EGLContextHandle GetCurrentContext() const;
EGLDisplayHandle GetCurrentDisplay() const;
EGLSurfaceHandle GetCurrentSurface(EGLint readdraw) const;
Bool IsDoubleBufferedSurface(EGLSurfaceHandle surface) const;
// Sync
EGLSyncHandle CreateSync(EGLDisplayHandle display, EGLenum type, const EGLAttrib* attribList);
@@ -120,10 +120,13 @@ namespace MobileGL::MG_State::GLState {
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 (write) {
m_change.Bits |= BufferChangeBits::ForbidInvalidationBit;
m_change.Bits |= BufferChangeBits::ForbidUnsynchronizationBit;
}
if (m_mappingAccess & BufferMappingAccessBit::Write) {
m_stagingData.resize(m_size);
@@ -148,6 +151,13 @@ namespace MobileGL::MG_State::GLState {
m_isMapped = true;
m_mappingAccess = access;
m_mappedRange = range;
m_change.Bits |=
!(access & BufferMappingAccessBit::InvalidateBuffer || access & BufferMappingAccessBit::InvalidateRange)
? BufferChangeBits::ForbidInvalidationBit
: BufferChangeBits::None;
m_change.Bits |= !(access & BufferMappingAccessBit::Unsynchronized)
? BufferChangeBits::ForbidUnsynchronizationBit
: BufferChangeBits::None;
if (access & BufferMappingAccessBit::Write) {
m_stagingData.resize(range.end - range.start);
@@ -162,14 +172,6 @@ namespace MobileGL::MG_State::GLState {
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 {
@@ -209,6 +211,18 @@ namespace MobileGL::MG_State::GLState {
return m_isMapped ? m_mappedRange : Range1D{0, 0};
}
void* BufferObject::GetMappedPointer() {
if (!m_isMapped) {
return nullptr;
}
if (m_ownsStagingData) {
return m_stagingData.data();
}
return m_dataPtr->data() + m_mappedRange.start;
}
Flags<BufferMappingAccessBit> BufferObject::GetMappingAccess() const {
return m_isMapped ? m_mappingAccess : BufferMappingAccessBit::Null;
}
@@ -94,6 +94,7 @@ namespace MobileGL {
SizeT GetSize() const;
BufferUsage GetUsage() const;
Range1D GetMappedRange() const;
void* GetMappedPointer();
const SharedPtr<Data>& GetDataReadOnly() const;
Flags<BufferMappingAccessBit> GetMappingAccess() const;
Uint GetExternalIndex() const;
@@ -56,6 +56,14 @@ namespace MobileGL::MG_State::GLState {
bindingSlot.Bind(nullptr);
}
}
for (auto& bindingPointArray : m_bufferBindPointTargets) {
for (auto& bindingPoint : bindingPointArray) {
if (bindingPoint.GetBoundObject() == it->second) {
bindingPoint.Bind(nullptr);
bindingPoint.ClearRange();
}
}
}
m_bufferObjects.erase(it);
}
m_indexGenerator.Delete(index);
+92 -3
View File
@@ -285,6 +285,34 @@ namespace MobileGL::MG_State {
return m_renderState.GetViewport();
}
void GLContext::SetLineWidth(Float width) {
m_renderState.SetLineWidth(width);
}
Float GLContext::GetLineWidth() const {
return m_renderState.GetLineWidth();
}
void GLContext::SetPointSize(Float size) {
m_renderState.SetPointSize(size);
}
Float GLContext::GetPointSize() const {
return m_renderState.GetPointSize();
}
void GLContext::SetPolygonOffset(Float factor, Float units) {
m_renderState.SetPolygonOffset(factor, units);
}
Float GLContext::GetPolygonOffsetFactor() const {
return m_renderState.GetPolygonOffsetFactor();
}
Float GLContext::GetPolygonOffsetUnits() const {
return m_renderState.GetPolygonOffsetUnits();
}
void GLContext::SetCapability(CapabilityInput cap, Bool enabled) {
m_renderState.SetCapability(cap, enabled);
}
@@ -337,6 +365,14 @@ namespace MobileGL::MG_State {
m_renderState.GetBlendEquationIndexed(index, color, alpha);
}
void GLContext::SetLogicOp(LogicOperation logicOp) {
m_renderState.SetLogicOp(logicOp);
}
LogicOperation GLContext::GetLogicOp() const {
return m_renderState.GetLogicOp();
}
void GLContext::SetDepthFunc(DepthTestFunc func) {
m_renderState.SetDepthFunc(func);
}
@@ -353,6 +389,23 @@ namespace MobileGL::MG_State {
return m_renderState.GetDepthMask();
}
void GLContext::SetStencilFunc(StencilFace face, DepthTestFunc func, Int ref, Uint32 mask) {
m_renderState.SetStencilFunc(face, func, ref, mask);
}
void GLContext::SetStencilMask(StencilFace face, Uint32 mask) {
m_renderState.SetStencilMask(face, mask);
}
void GLContext::SetStencilOp(StencilFace face, StencilOperation fail, StencilOperation depthFail,
StencilOperation depthPass) {
m_renderState.SetStencilOp(face, fail, depthFail, depthPass);
}
const StencilFaceState& GLContext::GetStencilState(StencilFace face) const {
return m_renderState.GetStencilState(face);
}
void GLContext::SetColorMask(BoolVec4 mask) {
m_renderState.SetColorMask(mask);
}
@@ -381,9 +434,45 @@ namespace MobileGL::MG_State {
m_renderState.SetClearStencil(stencil);
}
Uint32 GLContext::GetClearStencil() const {
return m_renderState.GetClearStencil();
}
Uint32 GLContext::GetClearStencil() const {
return m_renderState.GetClearStencil();
}
void GLContext::SetBlendColor(FloatVec4 color) {
m_renderState.SetBlendColor(color);
}
const FloatVec4& GLContext::GetBlendColor() const {
return m_renderState.GetBlendColor();
}
void GLContext::SetDepthRange(FloatVec2 range) {
m_renderState.SetDepthRange(range);
}
const FloatVec2& GLContext::GetDepthRange() const {
return m_renderState.GetDepthRange();
}
void GLContext::SetSampleCoverage(Float value, Bool invert) {
m_renderState.SetSampleCoverage(value, invert);
}
Float GLContext::GetSampleCoverageValue() const {
return m_renderState.GetSampleCoverageValue();
}
Bool GLContext::GetSampleCoverageInvert() const {
return m_renderState.GetSampleCoverageInvert();
}
void GLContext::SetSampleMaskValue(Uint32 mask) {
m_renderState.SetSampleMaskValue(mask);
}
Uint32 GLContext::GetSampleMaskValue() const {
return m_renderState.GetSampleMaskValue();
}
void GLContext::SetPixelStoreParam(PixelStoreParam param, Int value) {
m_renderState.SetPixelStoreParam(param, value);
+23
View File
@@ -102,6 +102,13 @@ namespace MobileGL {
const RenderStateParameters& GetRenderStateParameters() const;
void SetViewport(IntVec4 viewport); // x, y, width, height
const IntVec4& GetViewport() const; // x, y, width, height
void SetLineWidth(Float width);
Float GetLineWidth() const;
void SetPointSize(Float size);
Float GetPointSize() const;
void SetPolygonOffset(Float factor, Float units);
Float GetPolygonOffsetFactor() const;
Float GetPolygonOffsetUnits() const;
void SetCapability(CapabilityInput cap, Bool enabled);
Bool IsCapabilityEnabled(CapabilityInput cap) const;
void SetCapabilityIndexed(CapabilityInput cap, Uint index, Bool enabled);
@@ -117,10 +124,17 @@ namespace MobileGL {
void GetBlendEquation(BlendEquation& color, BlendEquation& alpha) const;
void SetBlendEquationIndexed(Uint index, BlendEquation color, BlendEquation alpha);
void GetBlendEquationIndexed(Uint index, BlendEquation& color, BlendEquation& alpha) const;
void SetLogicOp(LogicOperation logicOp);
LogicOperation GetLogicOp() const;
void SetDepthFunc(DepthTestFunc func);
DepthTestFunc GetDepthFunc() const;
void SetDepthMask(Bool flag);
Bool GetDepthMask() const;
void SetStencilFunc(StencilFace face, DepthTestFunc func, Int ref, Uint32 mask);
void SetStencilMask(StencilFace face, Uint32 mask);
void SetStencilOp(StencilFace face, StencilOperation fail, StencilOperation depthFail,
StencilOperation depthPass);
const StencilFaceState& GetStencilState(StencilFace face) const;
void SetColorMask(BoolVec4 mask);
BoolVec4 GetColorMask() const;
void SetClearColor(FloatVec4 color);
@@ -129,6 +143,15 @@ namespace MobileGL {
Float GetClearDepth() const;
void SetClearStencil(Int stencil);
Uint32 GetClearStencil() const;
void SetBlendColor(FloatVec4 color);
const FloatVec4& GetBlendColor() const;
void SetDepthRange(FloatVec2 range);
const FloatVec2& GetDepthRange() const;
void SetSampleCoverage(Float value, Bool invert);
Float GetSampleCoverageValue() const;
Bool GetSampleCoverageInvert() const;
void SetSampleMaskValue(Uint32 mask);
Uint32 GetSampleMaskValue() const;
void SetPixelStoreParam(PixelStoreParam param, Int value);
Int GetPixelStoreParam(PixelStoreParam param) const;
PixelStoreParameters GetPixelStoreParameters(Bool isUnpack) const;
@@ -12,8 +12,8 @@
namespace MobileGL::MG_State::GLState {
// FramebufferAttachmentObject
FramebufferAttachmentObject::FramebufferAttachmentObject(
const SharedPtr<MG_State::GLState::ITextureObject>& texture, Int level)
: m_texture(texture), m_textureLevel(level) {}
const SharedPtr<MG_State::GLState::ITextureObject>& texture, TextureUploadTarget textureUploadTarget, Int level)
: m_texture(texture), m_textureUploadTarget(textureUploadTarget), m_textureLevel(level) {}
FramebufferAttachmentObject::FramebufferAttachmentObject(const SharedPtr<RenderbufferObject>& renderbuffer)
: m_renderbuffer(renderbuffer) {}
FramebufferAttachmentObject::FramebufferAttachmentObject(Bool IsValid)
@@ -45,6 +45,10 @@ namespace MobileGL::MG_State::GLState {
return m_textureLevel;
}
TextureUploadTarget FramebufferAttachmentObject::GetTextureUploadTarget() const {
return m_textureUploadTarget;
}
Bool FramebufferAttachmentObject::IsComplete() const {
if (IsTexture()) {
Bool complete = m_texture->IsComplete();
@@ -59,11 +63,18 @@ namespace MobileGL::MG_State::GLState {
IntVec3 FramebufferAttachmentObject::GetSize() const {
if (IsTexture()) {
// TODO: get correct upload target
MOBILEGL_ASSERT(nullptr != static_cast<MG_State::GLState::TextureObjectMipmap*>(m_texture.get()),
"Texture object here should always be an object with mipmap");
auto textureMipmapObject = static_cast<MG_State::GLState::TextureObjectMipmap*>(m_texture.get());
return textureMipmapObject->GetMipmapTexelSize(TextureUploadTarget::Texture2D, m_textureLevel);
TextureUploadTarget resolvedTarget = m_textureUploadTarget;
if (resolvedTarget == TextureUploadTarget::Unknown) {
const auto& uploadTargets = m_texture->GetUploadTargets();
MOBILEGL_ASSERT(!uploadTargets.empty(),
"FramebufferAttachmentObject::GetSize: textureId=%u exposes no upload targets",
m_texture->GetExternalIndex());
resolvedTarget = uploadTargets[0];
}
return textureMipmapObject->GetMipmapTexelSize(resolvedTarget, m_textureLevel);
} else if (IsRenderbuffer()) {
return {m_renderbuffer->GetWidth(), m_renderbuffer->GetHeight(), 1};
}
@@ -79,13 +90,16 @@ namespace MobileGL::MG_State::GLState {
: m_externalIndex(externalIndex), m_attachmentVersions{}, m_drawBuffers{} {
m_attachmentObjects.fill(FramebufferAttachmentObject(false));
m_drawBuffers.fill(FramebufferAttachmentType::None);
m_drawBuffers[0] = FramebufferAttachmentType::Color0;
const FramebufferAttachmentType defaultColorBuffer =
(externalIndex == 0) ? FramebufferAttachmentType::BackLeft : FramebufferAttachmentType::Color0;
m_drawBuffers[0] = defaultColorBuffer;
m_readBuffer = defaultColorBuffer;
m_attachmentVersions.fill(0);
}
void FramebufferObject::AttachTexture(FramebufferAttachmentType type, const SharedPtr<ITextureObject>& texture,
int level) {
m_attachmentObjects[static_cast<SizeT>(type)] = FramebufferAttachmentObject(texture, level);
TextureUploadTarget textureUploadTarget, int level) {
m_attachmentObjects[static_cast<SizeT>(type)] = FramebufferAttachmentObject(texture, textureUploadTarget, level);
BumpAttachmentVersion(type);
}
@@ -150,6 +164,12 @@ namespace MobileGL::MG_State::GLState {
return m_drawBuffers;
}
void FramebufferObject::SetReadBuffer(FramebufferAttachmentType buf) {
if (m_readBuffer == buf) return;
m_readBuffer = buf;
++m_objectVersion;
}
Uint FramebufferObject::GetExternalIndex() const {
return m_externalIndex;
}
@@ -73,6 +73,7 @@ namespace MobileGL {
class FramebufferAttachmentObject {
public:
explicit FramebufferAttachmentObject(const SharedPtr<MG_State::GLState::ITextureObject>& texture,
TextureUploadTarget textureUploadTarget,
Int level = 0);
explicit FramebufferAttachmentObject(const SharedPtr<RenderbufferObject>& renderbuffer);
explicit FramebufferAttachmentObject(Bool IsValid = true);
@@ -83,6 +84,7 @@ namespace MobileGL {
const SharedPtr<MG_State::GLState::ITextureObject>& GetTexture() const;
const SharedPtr<RenderbufferObject>& GetRenderbuffer() const;
Int GetTextureLevel() const;
TextureUploadTarget GetTextureUploadTarget() const;
Bool IsComplete() const;
IntVec3 GetSize() const;
Bool IsValid() const;
@@ -90,6 +92,7 @@ namespace MobileGL {
private:
SharedPtr<MG_State::GLState::ITextureObject> m_texture = nullptr;
SharedPtr<RenderbufferObject> m_renderbuffer = nullptr;
TextureUploadTarget m_textureUploadTarget = TextureUploadTarget::Unknown;
Int m_textureLevel = 0;
Bool m_isValid = true;
};
@@ -108,7 +111,8 @@ namespace MobileGL {
FramebufferObject(Uint externalIndex);
void AttachTexture(FramebufferAttachmentType type, const SharedPtr<ITextureObject>& texture, int level = 0);
void AttachTexture(FramebufferAttachmentType type, const SharedPtr<ITextureObject>& texture,
TextureUploadTarget textureUploadTarget = TextureUploadTarget::Unknown, int level = 0);
void AttachRenderbuffer(FramebufferAttachmentType type, const SharedPtr<RenderbufferObject>& renderbuffer);
void Detach(FramebufferAttachmentType type);
const FramebufferAttachmentObject& GetAttachment(FramebufferAttachmentType type) const;
@@ -117,7 +121,7 @@ namespace MobileGL {
// aka. `buffer` as in glDrawBuffers/glReadBuffers
void SetDrawBuffer(Uint index, FramebufferAttachmentType buffer);
const FramebufferAttachmentArray& GetDrawBuffers() const;
void SetReadBuffer(FramebufferAttachmentType buf) { m_readBuffer = buf; }
void SetReadBuffer(FramebufferAttachmentType buf);
FramebufferAttachmentType GetReadBuffer() const { return m_readBuffer; }
FramebufferAttachmentVersionArray GetAllFramebufferAttachmentVersions() const {
@@ -136,7 +140,7 @@ namespace MobileGL {
FramebufferAttachmentVersionArray m_attachmentVersions;
FramebufferAttachmentArray m_drawBuffers; // Probably no versioning needed for this, just check equality
FramebufferAttachmentType m_readBuffer = FramebufferAttachmentType::Color0; // ditto
FramebufferAttachmentType m_readBuffer = FramebufferAttachmentType::None;
// This version will bump when draw/read buffer changes (by `glDrawBuffer(s)`/`glReadBuffer`)
Uint16 m_objectVersion = 0;
@@ -62,7 +62,7 @@ namespace MobileGL::MG_State::GLState {
if (it != m_framebufferObjects.end()) {
for (auto& bindingSlot : m_bindingSlots) {
if (bindingSlot.GetBoundObject() == it->second) {
bindingSlot.Bind(nullptr);
bindingSlot.Bind(GetFramebufferObject(0));
}
}
m_framebufferObjects.erase(it);
@@ -60,6 +60,27 @@ namespace {
}
namespace MobileGL::MG_State::GLState {
void ProgramObject::ResetLinkArtifacts() {
m_program.reset();
m_generatedSpirv.clear();
m_uniformLocations.clear();
m_uniformIndexInTProgram.clear();
m_uniformSamplerOrImageUnitIndex.clear();
m_uniformBlockIndexByName.clear();
m_uniformBlockBinding.clear();
m_uniformOffsets.clear();
m_uniformSizesInBytes.clear();
m_globalUboScratch.clear();
m_attribs.clear();
m_attribTypes.clear();
m_activeUniformCount = 0;
m_maxUniformLocation = 0;
m_uniformNameMaxLength = 0;
m_attribInNameMaxLength = 0;
m_uniformBlockNameMaxLength = 0;
m_linkStatus = false;
}
bool ProgramObject::ShaderIsAttached(const SharedPtr<ShaderObject>& shader) {
MGLOG_D("ProgramObject %u: ShaderIsAttached check for shader %p", m_externalIndex, shader.get());
auto it = std::find_if(m_shaders.begin(), m_shaders.end(),
@@ -135,6 +156,8 @@ namespace MobileGL::MG_State::GLState {
void ProgramObject::Link(Bool addDefaultFSIfMissingForRenderingPipelineProgram) {
MGLOG_D("ProgramObject %u: Link start, shaders to link: %zu", m_externalIndex, m_shaders.size());
++m_backendStateVersion;
ResetLinkArtifacts();
m_infoLog.clear();
// Remove detached shaders first
for (const auto& detachedShader : m_detachedShaders) {
RemoveShader(detachedShader);
@@ -163,7 +186,6 @@ namespace MobileGL::MG_State::GLState {
"log:\n{}\nShader src:\n{}",
MG_Util::ConvertGLEnumToString(shaderTypes[i]), m_shaders[i]->GetInfoLog(),
m_shaders[i]->GetShaderSource());
m_linkStatus = false;
MGLOG_E("ProgramObject %u: Link failed - shader[%zu] compile status false. InfoLog:\n%s",
m_externalIndex, i, m_infoLog.c_str());
return;
@@ -186,9 +208,9 @@ namespace MobileGL::MG_State::GLState {
m_program = result.value();
MGLOG_D("ProgramObject %u: LinkProgram succeeded, TProgram ptr %p", m_externalIndex, m_program.get());
} else {
m_linkStatus = false;
m_infoLog = result.error().log;
MGLOG_E("ProgramObject %u: LinkProgram failed. InfoLog:\n%s", m_externalIndex, m_infoLog.c_str());
return;
}
MGLOG_D("ProgramObject %u: Starting reflection", m_externalIndex);
@@ -40,11 +40,40 @@ namespace MobileGL::MG_State::GLState {
return (Int)it->second;
}
Int GetActiveUniformIndex(const String& name) const {
const Int uniformIndex = m_program->getUniformIndex(name.c_str());
if (uniformIndex < 0 || uniformIndex >= m_activeUniformCount) return -1;
return m_program->getUniform(uniformIndex).name == name ? uniformIndex : -1;
}
Bool IsValidUniformLocation(Int location) const {
if (location < 0 || location > static_cast<Int>(m_maxUniformLocation)) return false;
if (static_cast<SizeT>(location) >= m_uniformIndexInTProgram.size()) return false;
const Int uniformIndexInProgram = m_uniformIndexInTProgram[location];
return uniformIndexInProgram != glslang::TQualifier::layoutLocationEnd &&
uniformIndexInProgram >= 0 && uniformIndexInProgram < m_activeUniformCount;
}
GLenum GetUniformType(Uint location) const {
auto& uniform = m_program->getUniform(m_uniformIndexInTProgram[location]);
return uniform.glDefineType;
}
GLenum GetActiveUniformType(Uint index) const {
auto& uniform = m_program->getUniform(static_cast<Int>(index));
return uniform.glDefineType;
}
GLint GetActiveUniformArraySize(Uint index) const {
auto& uniform = m_program->getUniform(static_cast<Int>(index));
return uniform.size;
}
Int GetActiveUniformBlockIndex(Uint index) const {
auto& uniform = m_program->getUniform(static_cast<Int>(index));
return uniform.index;
}
const glslang::TType* GetUniformTType(Uint location) const {
auto& uniform = m_program->getUniform(m_uniformIndexInTProgram[location]);
return uniform.getType();
@@ -56,6 +85,11 @@ namespace MobileGL::MG_State::GLState {
auto& uniform = m_program->getUniform(m_uniformIndexInTProgram[location]);
return uniform.name;
}
const String& GetActiveUniformName(Uint index) const {
auto& uniform = m_program->getUniform(static_cast<Int>(index));
return uniform.name;
}
Uint GetUniformOffset(Uint location) const { return m_uniformOffsets[location]; }
Uint GetUniformSizesInBytes(Uint location) const { return MG_Util::GetGLTypeSize(GetUniformType(location)); }
@@ -107,6 +141,9 @@ namespace MobileGL::MG_State::GLState {
}
GLenum GetAttribType(Uint index) const { return m_attribTypes[index]; }
const String& GetAttribName(Uint index) const { return m_attribs[index]; }
GLenum GetActiveAttribType(Uint index) const { return m_program->getPipeInput(static_cast<Int>(index)).glDefineType; }
GLint GetActiveAttribArraySize(Uint index) const { return m_program->getPipeInput(static_cast<Int>(index)).size; }
const String& GetActiveAttribName(Uint index) const { return m_program->getPipeInput(static_cast<Int>(index)).name; }
void* MapUBO() { return m_globalUboScratch.data(); }
const void* GetUBOData() const { return m_globalUboScratch.data(); }
Uint GetUBOSize() const { return static_cast<Uint>(m_globalUboScratch.size()); }
@@ -126,6 +163,7 @@ namespace MobileGL::MG_State::GLState {
Int GetActiveAtomicCounterCount() const { return m_program->getNumAtomicCounters(); }
Int GetActiveAttributesCount() const { return m_program->getNumPipeInputs(); }
Int GetActiveUniformBlocksCount() const { return m_program->getNumUniformBlocks(); }
GLuint GetComputeLocalSize(Uint dim) const { return m_program->getLocalSize(static_cast<Int>(dim)); }
Int GetActiveAttributesMaxLength() const { return m_attribInNameMaxLength; }
Int GetActiveUniformBlocksMaxNameLength() const { return m_uniformBlockNameMaxLength; }
Uint GetUniformBlockIndex(const char* name) const {
@@ -147,6 +185,16 @@ namespace MobileGL::MG_State::GLState {
return ubo.name;
}
Int GetUniformBlockActiveUniformCount(Uint index) const {
return m_program->getUniformBlock((Int)index).numMembers;
}
Bool IsUniformBlockReferencedByStage(Uint index, EShLanguage stage) const {
const auto& ubo = m_program->getUniformBlock((Int)index);
const auto stageMask = static_cast<EShLanguageMask>(1 << stage);
return (ubo.stages & stageMask) != 0;
}
// Set by glUniformBlockBinding
void SetUniformBlockBinding(Uint index, Uint binding) {
if (index >= m_uniformBlockBinding.size() || m_uniformBlockBinding[index] == static_cast<Int>(binding)) {
@@ -171,6 +219,7 @@ namespace MobileGL::MG_State::GLState {
Uint GetExternalIndex() const { return m_externalIndex; }
private:
void ResetLinkArtifacts();
void DoReflection();
void GenerateBinary();
void WaitUntilGenerationCompleted() const;
@@ -16,10 +16,16 @@
namespace MobileGL::MG_State::GLState {
void ShaderObject::SetShaderSource(const String& source) {
m_source = source;
m_shader.reset();
m_compileStatus = false;
m_infoLog.clear();
}
void ShaderObject::SetShaderSource(String&& source) {
m_source = Move(source);
m_shader.reset();
m_compileStatus = false;
m_infoLog.clear();
}
void ShaderObject::Compile() {
@@ -38,8 +44,10 @@ namespace MobileGL::MG_State::GLState {
if (result) {
m_compileStatus = true;
m_shader = result.value();
m_infoLog.clear();
} else {
m_compileStatus = false;
m_shader.reset();
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.",
@@ -12,6 +12,20 @@
namespace MobileGL {
namespace MG_State {
namespace GLState {
namespace {
SizeT GetStencilFaceIndex(StencilFace face) {
switch (face) {
case StencilFace::Front:
return 0;
case StencilFace::Back:
return 1;
default:
MOBILEGL_ASSERT(false, "Invalid stencil face enum: %d", static_cast<int>(face));
return 0;
}
}
} // namespace
RenderState::RenderState() {}
Uint RenderState::GetVersion() const {
@@ -34,6 +48,44 @@ namespace MobileGL {
return m_parameters.Viewport;
}
void RenderState::SetLineWidth(Float width) {
if (m_parameters.LineWidth == width) return;
m_parameters.LineWidth = width;
++m_version;
}
Float RenderState::GetLineWidth() const {
return m_parameters.LineWidth;
}
void RenderState::SetPointSize(Float size) {
if (m_parameters.PointSize == size) return;
m_parameters.PointSize = size;
++m_version;
}
Float RenderState::GetPointSize() const {
return m_parameters.PointSize;
}
void RenderState::SetPolygonOffset(Float factor, Float units) {
if (m_parameters.PolygonOffsetFactor == factor && m_parameters.PolygonOffsetUnits == units) return;
m_parameters.PolygonOffsetFactor = factor;
m_parameters.PolygonOffsetUnits = units;
++m_version;
}
Float RenderState::GetPolygonOffsetFactor() const {
return m_parameters.PolygonOffsetFactor;
}
Float RenderState::GetPolygonOffsetUnits() const {
return m_parameters.PolygonOffsetUnits;
}
// -------------------- Capabilities --------------------
void RenderState::SetCapability(CapabilityInput cap, Bool enabled) {
#define SET_CAPABILITY(capability, flag) \
@@ -44,9 +96,28 @@ namespace MobileGL {
break;
switch (cap) {
SET_CAPABILITY(ColorLogicOp, enabled);
SET_CAPABILITY(DebugOutput, enabled);
SET_CAPABILITY(DebugOutputSynchronous, enabled);
SET_CAPABILITY(DepthTest, enabled);
SET_CAPABILITY(CullFace, enabled);
SET_CAPABILITY(Dither, enabled);
SET_CAPABILITY(LineSmooth, enabled);
SET_CAPABILITY(Multisample, enabled);
SET_CAPABILITY(PolygonOffsetFill, enabled);
SET_CAPABILITY(PolygonOffsetLine, enabled);
SET_CAPABILITY(PolygonOffsetPoint, enabled);
SET_CAPABILITY(PolygonSmooth, enabled);
SET_CAPABILITY(PrimitiveRestart, enabled);
SET_CAPABILITY(PrimitiveRestartFixedIndex, enabled);
SET_CAPABILITY(RasterizerDiscard, enabled);
SET_CAPABILITY(SampleAlphaToCoverage, enabled);
SET_CAPABILITY(SampleAlphaToOne, enabled);
SET_CAPABILITY(SampleCoverage, enabled);
SET_CAPABILITY(SampleMask, enabled);
SET_CAPABILITY(ScissorTest, enabled);
SET_CAPABILITY(StencilTest, enabled);
SET_CAPABILITY(ProgramPointSize, enabled);
case CapabilityInput::Blend: {
Bool stateChanged = false;
for (auto& blendState : m_parameters.BlendStates) {
@@ -68,9 +139,28 @@ namespace MobileGL {
case CapabilityInput::capability: \
return m_parameters.capability##Enabled;
switch (cap) {
RETURN_CAPABILITY(ColorLogicOp);
RETURN_CAPABILITY(DebugOutput);
RETURN_CAPABILITY(DebugOutputSynchronous);
RETURN_CAPABILITY(DepthTest);
RETURN_CAPABILITY(CullFace);
RETURN_CAPABILITY(Dither);
RETURN_CAPABILITY(LineSmooth);
RETURN_CAPABILITY(Multisample);
RETURN_CAPABILITY(PolygonOffsetFill);
RETURN_CAPABILITY(PolygonOffsetLine);
RETURN_CAPABILITY(PolygonOffsetPoint);
RETURN_CAPABILITY(PolygonSmooth);
RETURN_CAPABILITY(PrimitiveRestart);
RETURN_CAPABILITY(PrimitiveRestartFixedIndex);
RETURN_CAPABILITY(RasterizerDiscard);
RETURN_CAPABILITY(SampleAlphaToCoverage);
RETURN_CAPABILITY(SampleAlphaToOne);
RETURN_CAPABILITY(SampleCoverage);
RETURN_CAPABILITY(SampleMask);
RETURN_CAPABILITY(ScissorTest);
RETURN_CAPABILITY(StencilTest);
RETURN_CAPABILITY(ProgramPointSize);
case CapabilityInput::Blend:
return m_parameters.BlendStates[0].Enabled;
default:
@@ -206,6 +296,17 @@ namespace MobileGL {
alpha = m_parameters.BlendStates[index].AlphaEquation;
}
void RenderState::SetLogicOp(LogicOperation logicOp) {
if (m_parameters.LogicOp == logicOp) return;
m_parameters.LogicOp = logicOp;
++m_version;
}
LogicOperation RenderState::GetLogicOp() const {
return m_parameters.LogicOp;
}
// -------------------- Depth --------------------
void RenderState::SetDepthFunc(DepthTestFunc func) {
if (m_parameters.DepthFunc == func) return;
@@ -229,6 +330,42 @@ namespace MobileGL {
return m_parameters.DepthMask;
}
void RenderState::SetStencilFunc(StencilFace face, DepthTestFunc func, Int ref, Uint32 mask) {
StencilFaceState& state = m_parameters.StencilStates[GetStencilFaceIndex(face)];
if (state.Func == func && state.Ref == ref && state.ValueMask == mask) return;
state.Func = func;
state.Ref = ref;
state.ValueMask = mask;
++m_version;
}
void RenderState::SetStencilMask(StencilFace face, Uint32 mask) {
StencilFaceState& state = m_parameters.StencilStates[GetStencilFaceIndex(face)];
if (state.WriteMask == mask) return;
state.WriteMask = mask;
++m_version;
}
void RenderState::SetStencilOp(StencilFace face, StencilOperation fail, StencilOperation depthFail,
StencilOperation depthPass) {
StencilFaceState& state = m_parameters.StencilStates[GetStencilFaceIndex(face)];
if (state.FailOp == fail && state.PassDepthFailOp == depthFail &&
state.PassDepthPassOp == depthPass) {
return;
}
state.FailOp = fail;
state.PassDepthFailOp = depthFail;
state.PassDepthPassOp = depthPass;
++m_version;
}
const StencilFaceState& RenderState::GetStencilState(StencilFace face) const {
return m_parameters.StencilStates[GetStencilFaceIndex(face)];
}
// -------------------- Color Mask --------------------
void RenderState::SetColorMask(BoolVec4 mask) {
if (m_parameters.ColorMask == mask) return;
@@ -275,6 +412,55 @@ namespace MobileGL {
return m_parameters.ClearStencil;
}
void RenderState::SetBlendColor(FloatVec4 color) {
if (m_parameters.BlendColor == color) return;
m_parameters.BlendColor = color;
++m_version;
}
const FloatVec4& RenderState::GetBlendColor() const {
return m_parameters.BlendColor;
}
void RenderState::SetDepthRange(FloatVec2 range) {
if (m_parameters.DepthRange == range) return;
m_parameters.DepthRange = range;
++m_version;
}
const FloatVec2& RenderState::GetDepthRange() const {
return m_parameters.DepthRange;
}
void RenderState::SetSampleCoverage(Float value, Bool invert) {
if (m_parameters.SampleCoverageValue == value && m_parameters.SampleCoverageInvert == invert) return;
m_parameters.SampleCoverageValue = value;
m_parameters.SampleCoverageInvert = invert;
++m_version;
}
Float RenderState::GetSampleCoverageValue() const {
return m_parameters.SampleCoverageValue;
}
Bool RenderState::GetSampleCoverageInvert() const {
return m_parameters.SampleCoverageInvert;
}
void RenderState::SetSampleMaskValue(Uint32 mask) {
if (m_parameters.SampleMaskValue == mask) return;
m_parameters.SampleMaskValue = mask;
++m_version;
}
Uint32 RenderState::GetSampleMaskValue() const {
return m_parameters.SampleMaskValue;
}
// -------------------- Pixel Store --------------------
void RenderState::SetPixelStoreParam(PixelStoreParam param, Int value) {
#define SET_PIXEL_STORE_PARAM(paramNameHead, paramNameTail, val) \
@@ -41,6 +41,27 @@ namespace MobileGL {
Unknown = -1
};
enum class LogicOperation {
Clear,
And,
AndReverse,
Copy,
AndInverted,
Noop,
Xor,
Or,
Nor,
Equiv,
Invert,
OrReverse,
CopyInverted,
OrInverted,
Nand,
Set,
LogicOperationCount,
Unknown = -1
};
enum class DepthTestFunc {
Never,
Less,
@@ -54,6 +75,26 @@ namespace MobileGL {
Unknown = -1
};
enum class StencilOperation {
Keep,
Zero,
Replace,
IncrementClamp,
DecrementClamp,
Invert,
IncrementWrap,
DecrementWrap,
StencilOperationCount,
Unknown = -1
};
enum class StencilFace {
Front,
Back,
StencilFaceCount,
Unknown = -1
};
enum class PixelStoreParam {
// Pack Parameters
PackAlignment,
@@ -155,12 +196,27 @@ namespace MobileGL {
BlendEquation AlphaEquation = BlendEquation::Add;
};
struct StencilFaceState {
DepthTestFunc Func = DepthTestFunc::Always;
Int Ref = 0;
Uint32 ValueMask = 0xffffffffu;
Uint32 WriteMask = 0xffffffffu;
StencilOperation FailOp = StencilOperation::Keep;
StencilOperation PassDepthFailOp = StencilOperation::Keep;
StencilOperation PassDepthPassOp = StencilOperation::Keep;
};
struct RenderStateParameters {
// Rasterization
IntVec4 Viewport = IntVec4(0, 0, 0, 0); // x, y, width, height
Float LineWidth = 1.0f;
Float PointSize = 1.0f;
Float PolygonOffsetFactor = 0.0f;
Float PolygonOffsetUnits = 0.0f;
// Blending
Array<PerBufferBlendState, MG_State::GLState::FramebufferObject::MAX_DRAW_BUFFERS> BlendStates;
LogicOperation LogicOp = LogicOperation::Copy;
// Depth
Bool DepthTestEnabled = false;
@@ -174,6 +230,12 @@ namespace MobileGL {
FloatVec4 ClearColor = FloatVec4(0.0f, 0.0f, 0.0f, 1.0f);
Float ClearDepth = 1.0f;
Uint32 ClearStencil = 0;
FloatVec4 BlendColor = FloatVec4(0.0f, 0.0f, 0.0f, 0.0f);
FloatVec2 DepthRange = FloatVec2(0.0f, 1.0f);
Float SampleCoverageValue = 1.0f;
Bool SampleCoverageInvert = false;
Uint32 SampleMaskValue = 0xffffffffu;
Array<StencilFaceState, 2> StencilStates{};
// Cull Face
Bool CullFaceEnabled = false;
@@ -181,7 +243,26 @@ namespace MobileGL {
FrontFaceMode FrontFaceModeSetting = FrontFaceMode::CounterClockwise;
// Scissor
Bool ColorLogicOpEnabled = false;
Bool DebugOutputEnabled = false;
Bool DebugOutputSynchronousEnabled = false;
Bool DitherEnabled = true;
Bool LineSmoothEnabled = false;
Bool MultisampleEnabled = true;
Bool PolygonOffsetFillEnabled = false;
Bool PolygonOffsetLineEnabled = false;
Bool PolygonOffsetPointEnabled = false;
Bool PolygonSmoothEnabled = false;
Bool PrimitiveRestartEnabled = false;
Bool PrimitiveRestartFixedIndexEnabled = false;
Bool RasterizerDiscardEnabled = false;
Bool SampleAlphaToCoverageEnabled = false;
Bool SampleAlphaToOneEnabled = false;
Bool SampleCoverageEnabled = false;
Bool SampleMaskEnabled = false;
Bool ScissorTestEnabled = false;
Bool StencilTestEnabled = false;
Bool ProgramPointSizeEnabled = false;
IntVec4 ScissorBox = IntVec4(0, 0, 0, 0); // x, y, width, height
};
@@ -197,6 +278,13 @@ namespace MobileGL {
// Rasterization
void SetViewport(IntVec4 viewport); // x, y, width, height
const IntVec4& GetViewport() const; // x, y, width, height
void SetLineWidth(Float width);
Float GetLineWidth() const;
void SetPointSize(Float size);
Float GetPointSize() const;
void SetPolygonOffset(Float factor, Float units);
Float GetPolygonOffsetFactor() const;
Float GetPolygonOffsetUnits() const;
// Capabilities
void SetCapability(CapabilityInput cap, Bool enabled);
@@ -216,12 +304,19 @@ namespace MobileGL {
void GetBlendEquation(BlendEquation& color, BlendEquation& alpha) const;
void SetBlendEquationIndexed(Uint index, BlendEquation color, BlendEquation alpha);
void GetBlendEquationIndexed(Uint index, BlendEquation& color, BlendEquation& alpha) const;
void SetLogicOp(LogicOperation logicOp);
LogicOperation GetLogicOp() const;
// Depth
void SetDepthFunc(DepthTestFunc func);
DepthTestFunc GetDepthFunc() const;
void SetDepthMask(Bool flag);
Bool GetDepthMask() const;
void SetStencilFunc(StencilFace face, DepthTestFunc func, Int ref, Uint32 mask);
void SetStencilMask(StencilFace face, Uint32 mask);
void SetStencilOp(StencilFace face, StencilOperation fail, StencilOperation depthFail,
StencilOperation depthPass);
const StencilFaceState& GetStencilState(StencilFace face) const;
// Color Mask
void SetColorMask(BoolVec4 mask);
@@ -234,6 +329,15 @@ namespace MobileGL {
Float GetClearDepth() const;
void SetClearStencil(Int stencil);
Uint32 GetClearStencil() const;
void SetBlendColor(FloatVec4 color);
const FloatVec4& GetBlendColor() const;
void SetDepthRange(FloatVec2 range);
const FloatVec2& GetDepthRange() const;
void SetSampleCoverage(Float value, Bool invert);
Float GetSampleCoverageValue() const;
Bool GetSampleCoverageInvert() const;
void SetSampleMaskValue(Uint32 mask);
Uint32 GetSampleMaskValue() const;
// Pixel Store
void SetPixelStoreParam(PixelStoreParam param, Int value);
@@ -76,6 +76,10 @@ namespace MobileGL {
m_height = size.y();
m_allocated = true;
}
void RenderbufferObject::SetSamples(Int samples) {
m_samples = samples;
}
} // namespace GLState
} // namespace MG_State
} // namespace MobileGL
@@ -29,6 +29,7 @@ namespace MobileGL {
Uint GetExternalIndex() const;
void SetInternalFormat(TextureInternalFormat format);
void AllocateStorage(IntVec2 size);
void SetSamples(Int samples);
Int GetWidth() const;
Int GetHeight() const;
TextureInternalFormat GetInternalFormat() const;
@@ -47,7 +48,7 @@ namespace MobileGL {
TextureInternalFormat m_internalFormat;
Int m_width = 0;
Int m_height = 0;
Int m_samples = 0; // TODO: multisampling support
Int m_samples = 0;
Bool m_allocated = false;
ComponentSizes m_componentSizes;
};
@@ -57,10 +57,6 @@ namespace MobileGL {
void SamplerObject::SetLodRange(Float minLod, Float maxLod) {
if (minLod == m_samplerParameters.minLod && maxLod == m_samplerParameters.maxLod) return;
if (minLod > maxLod) {
THROW_EXCEPTION("minLod cannot be greater than maxLod");
}
m_samplerParameters.minLod = minLod;
m_samplerParameters.maxLod = maxLod;
++m_version;
@@ -50,7 +50,7 @@ namespace MobileGL {
Uint TextureObject2DCube::GetIndexOfTextureUploadTarget(TextureUploadTarget target) const {
MOBILEGL_ASSERT(TextureUploadTarget::CubeMapPositiveX <= target &&
target <= TextureUploadTarget::ProxyCubeMap,
target <= TextureUploadTarget::CubeMapNegativeZ,
"Invalid TextureUploadTarget!");
return (Uint)target - (Uint)TextureUploadTarget::CubeMapPositiveX;
}
@@ -50,8 +50,8 @@ namespace MobileGL::MG_State::GLState {
void VertexArrayState::MarkVertexArrayForDeletion(Uint index) {
if (m_indexGenerator.IsValid(index)) {
if (m_boundVertexArray) {
m_boundVertexArray = nullptr;
if (m_boundVertexArray && m_boundVertexArray->GetExternalIndex() == index) {
m_boundVertexArray = GetVertexArrayObject(0);
}
if (ValidateVertexArrayObject(index)) {