Files
MobileGL/MobileGL/MG_State/GLState/ProgramState/ProgramState.h
T
BZLZHH 07fa84fb8d [Fix] (MG_State, MG_Impl): defer deletion of the program in use
glDeleteProgram on the current program now only flags it: the name (and
every glGetProgram* query) stays valid until the program stops being
current, at which point UseProgram frees the slot and releases orphaned
attached shaders. Previously the name died immediately, so a second
glDeleteProgram - as issued by common CTS utility teardown - recorded
GL_INVALID_VALUE that poisoned the next test iteration's build
(KHR-GL33.clip_distance.functional now passes its build phase).

glIsProgram/glIsShader piggyback on the same rule: a flagged name is
still a program/shader while it stays GL-visible, which resolves the
long-standing FIXMEs there.
2026-07-31 18:21:14 -04:00

64 lines
2.4 KiB
C++

// MobileGL - MobileGL/MG_State/GLState/ProgramState/ProgramState.h
// Copyright (c) 2025-2026 MobileGL-Dev
// Licensed under the GNU Lesser General Public License v3.0:
// https://www.gnu.org/licenses/gpl-3.0.txt
// https://www.gnu.org/licenses/lgpl-3.0.txt
// SPDX-License-Identifier: LGPL-3.0-only
// End of Source File Header
#pragma once
#include <Includes.h>
#include <MG_Util/Miscellany/IndexGenerator.h>
#include "ProgramObject.h"
namespace MobileGL::MG_State::GLState {
class ProgramState {
public:
// This function WILL actually create the program object.
// To retrieve created program object, use GetProgramObject()
Uint CreateProgram();
const SharedPtr<ProgramObject>& GetProgramObject(Uint id);
void MarkProgramObjectForDeletion(Uint program);
Bool ValidateProgramObject(Uint program) const;
void UseProgram(Uint program);
Uint CreateShader(ShaderStage stage);
const SharedPtr<ShaderObject>& GetShaderObject(Uint shader);
void MarkShaderObjectForDeletion(Uint shader);
// Frees a deletion-flagged shader's name once no program holds a GL-visible
// attachment to it (the deferred half of glDeleteShader-while-attached).
void ReleaseShaderNameIfOrphaned(Uint shader);
Bool ValidateShaderObject(Uint shader) const;
const SharedPtr<ProgramObject>& GetCurrentProgram() const { return m_currentProgram; }
private:
Bool ShaderHasGLVisibleAttachment(const SharedPtr<ShaderObject>& shaderObject) const;
// Frees the name slot and releases orphaned attached shaders; the immediate half
// of glDeleteProgram (deferred while the program is current).
void DestroyProgramSlot(Uint program);
template <typename T>
static Bool CheckIndexAvail(const SizeT idx, const Vector<T>& vec) {
return idx < vec.size();
}
template <typename T>
static void EnsureIndexAvail(const SizeT idx, Vector<T>& vec) {
if (CheckIndexAvail(idx, vec)) return;
vec.reserve(std::bit_ceil(idx));
vec.resize(idx + 1);
}
IndexGenerator<Uint> m_programIndexGenerator;
Vector<SharedPtr<ProgramObject>> m_programObjects;
IndexGenerator<Uint> m_shaderIndexGenerator;
Vector<SharedPtr<ShaderObject>> m_shaderObjects;
SharedPtr<ProgramObject> m_currentProgram;
};
} // namespace MobileGL::MG_State::GLState