Files
plotter/include/plot/gl/loader.hpp
T
Martino Ferrari 6866457155 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.
2026-09-27 21:15:57 +02:00

36 lines
1.6 KiB
C++

#pragma once
#include <plot/gl/api.hpp>
namespace plot::gl {
/// Entry point resolver supplied by the caller, normally the *GetProcAddress
/// of the API that owns the current context: `eglGetProcAddress`,
/// `glXGetProcAddressARB` or `wglGetProcAddress`.
using ProcLoader = void* (*)(const char*);
/// Resolves every entry point of `PLOT_GL_FUNCS` (see api.hpp) into the global
/// table declared there, so the rest of the library can call `gl*` directly.
///
/// Returns false when any required name cannot be found; entries that did
/// resolve keep their pointers, so a failed load() never breaks a table that
/// was already usable. `loader` is consulted first; when it is null, or returns
/// null for a name, the fallback is `dlsym(RTLD_DEFAULT, name)` and then
/// `dlopen("libGL.so.1")` + `dlsym`. The fallback makes the library usable
/// without a caller-supplied resolver, but only a context-aware resolver is
/// guaranteed to return pointers valid for the *current* context — pass one
/// whenever a context is current.
///
/// A load() attempt invalidates the caps() cache. The table is process-global
/// and is not synchronised, so call from the thread that owns the current
/// context.
bool load(ProcLoader loader = nullptr) noexcept;
/// True once a `load()` has resolved every required entry point of the global
/// table. This is the gate superseding per-pointer null checks: while it is
/// false the table may be only partially populated (see load()), so no `gl*`
/// entry point may be called. The fallible handle constructors report
/// `ErrorCode::Unsupported` until it becomes true.
bool available() noexcept;
} // namespace plot::gl