fix(gl): gate fallible constructors on a complete loader table
- loader: add available(), true only after load() has resolved every required entry point (false at the start of load()). Program::from_source and the other fallible constructors return ErrorCode::Unsupported while it is false, so a failed load() with a partially populated table can no longer fault on an unresolved entry point. - caps: GL_CONTEXT_PROFILE_MASK only exists from 3.2, so query it only on 3.2+ contexts. A 3.0/3.1 query latches GL_INVALID_ENUM in the context, which the next unrelated glGetError() (e.g. read_pixel) then reports as failure. - tests: gate the dlsym/libGL.so.1 fallback assertions on libGL being resolvable, so the GL suite also passes on a GLES-only host.
This commit is contained in:
1 parent
258caa38a7
commit
6866457155
4 files changed
+59
-12
No files matched your search
@@ -1,5 +1,7 @@
|
||||
#include <plot/gl/handle.hpp>
|
||||
|
||||
#include <plot/gl/loader.hpp>
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstdio>
|
||||
|
||||
@@ -78,6 +80,9 @@ GLuint alloc_texture(GLenum internal_format, GLenum format, u32 width, u32 heigh
|
||||
// ------------------------------------------------------------------- Buffer
|
||||
|
||||
bool Buffer::create(Status* st) noexcept {
|
||||
if (!available()) {
|
||||
return fail(st, ErrorCode::Unsupported, kNoLoader);
|
||||
}
|
||||
if (glGenBuffers == nullptr) {
|
||||
return fail(st, ErrorCode::Unsupported, kNoLoader);
|
||||
}
|
||||
@@ -109,6 +114,9 @@ void Buffer::destroy(GLuint id) noexcept { glDeleteBuffers(1, &id); }
|
||||
// -------------------------------------------------------------- VertexArray
|
||||
|
||||
bool VertexArray::create(Status* st) noexcept {
|
||||
if (!available()) {
|
||||
return fail(st, ErrorCode::Unsupported, kNoLoader);
|
||||
}
|
||||
if (glGenVertexArrays == nullptr) {
|
||||
return fail(st, ErrorCode::Unsupported, kNoLoader);
|
||||
}
|
||||
@@ -139,6 +147,10 @@ void VertexArray::destroy(GLuint id) noexcept { glDeleteVertexArrays(1, &id); }
|
||||
Program Program::from_source(const char* vertex_src, const char* fragment_src,
|
||||
Status* st) noexcept {
|
||||
Program program;
|
||||
if (!available()) {
|
||||
fail(st, ErrorCode::Unsupported, kNoLoader);
|
||||
return program;
|
||||
}
|
||||
if (glCreateShader == nullptr || glCreateProgram == nullptr) {
|
||||
fail(st, ErrorCode::Unsupported, kNoLoader);
|
||||
return program;
|
||||
@@ -219,6 +231,9 @@ void Program::destroy(GLuint id) noexcept { glDeleteProgram(id); }
|
||||
// ------------------------------------------------------------------ Texture
|
||||
|
||||
bool Texture::create_rgba(u32 width, u32 height, Status* st) noexcept {
|
||||
if (!available()) {
|
||||
return fail(st, ErrorCode::Unsupported, kNoLoader);
|
||||
}
|
||||
if (glGenTextures == nullptr) {
|
||||
return fail(st, ErrorCode::Unsupported, kNoLoader);
|
||||
}
|
||||
@@ -235,6 +250,9 @@ bool Texture::create_rgba(u32 width, u32 height, Status* st) noexcept {
|
||||
}
|
||||
|
||||
bool Texture::create_r8(u32 width, u32 height, Status* st) noexcept {
|
||||
if (!available()) {
|
||||
return fail(st, ErrorCode::Unsupported, kNoLoader);
|
||||
}
|
||||
if (glGenTextures == nullptr) {
|
||||
return fail(st, ErrorCode::Unsupported, kNoLoader);
|
||||
}
|
||||
@@ -280,6 +298,9 @@ void Texture::destroy(GLuint id) noexcept { glDeleteTextures(1, &id); }
|
||||
// -------------------------------------------------------------- Framebuffer
|
||||
|
||||
bool Framebuffer::create(Status* st) noexcept {
|
||||
if (!available()) {
|
||||
return fail(st, ErrorCode::Unsupported, kNoLoader);
|
||||
}
|
||||
if (glGenFramebuffers == nullptr) {
|
||||
return fail(st, ErrorCode::Unsupported, kNoLoader);
|
||||
}
|
||||
@@ -310,6 +331,9 @@ void Framebuffer::destroy(GLuint id) noexcept { glDeleteFramebuffers(1, &id); }
|
||||
// -------------------------------------------------------------------- Fence
|
||||
|
||||
bool Fence::create(Status* st) noexcept {
|
||||
if (!available()) {
|
||||
return fail(st, ErrorCode::Unsupported, kNoLoader);
|
||||
}
|
||||
if (glFenceSync == nullptr) {
|
||||
return fail(st, ErrorCode::Unsupported, kNoLoader);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user