Context Events API
Declared in include/metagl/ContextEvents.hpp. Added in v0.2.0.
The Context Events API provides an observer interface for GL context-lost and
context-restored lifecycle events.
Overview
On mobile (Android) and in browsers (WebGL / Emscripten), the GPU context can be taken away at any time — the system kills it to free resources, or the browser tab loses focus. When this happens all GL handles (textures, buffers, shaders, programs, VAOs) become invalid. The context events system lets any object register a callback so it can clean up and later re-upload its GPU resources.
The context event system is separate from the raw MarkContextLost()
/ MarkContextRestored() functions in Context.hpp.
The event system dispatches to all registered listeners; the raw functions only update
the internal state flag.
ContextListener Interface
class ContextListener { public: virtual ~ContextListener() = default; // Called when the GL context has been lost. // WARNING: Do NOT call any metagl::gl* function from this callback. virtual void OnContextLost() {} // Called after the GL context has been restored and function pointers reloaded. // Safe to call metagl::gl* functions here to recreate GPU resources. virtual void OnContextRestored() {} };
Warning: Inside OnContextLost() you must not call any
metagl::gl* function. The context is already gone; all function pointers may
be null or point to a dead context.
Registration
| Function | Description |
|---|---|
AddContextListener(ContextListener*) |
Register a listener. The caller retains ownership; pointer must stay valid until removed. |
RemoveContextListener(ContextListener*) |
Unregister. No-op if not found. Call before the listener is destroyed. |
Event Dispatch
| Function | Description |
|---|---|
NotifyContextLost() |
Dispatches OnContextLost() to all registered listeners, then calls MarkContextLost(). |
NotifyContextRestored() |
Dispatches OnContextRestored() to all registered listeners, then calls MarkContextRestored(). |
Required Call Order on Context Restore
After a context-restore event, you must follow this order:
- Call
metagl::LoadCurrentContext(getProcAddress)— reloads all GL function pointers and redetects capabilities. Nometagl::gl*call is safe before this step. - Call
metagl::NotifyContextRestored()— firesOnContextRestored()on all registered listeners so they can recreate GPU resources.
Undefined behaviour: calling NotifyContextRestored() before
LoadCurrentContext() means listeners may invoke GL functions through stale
or null function pointers.
Full Example
#include <metagl/metagl.hpp> class MyRenderer : public metagl::ContextListener { public: bool init() { metagl::AddContextListener(this); return uploadResources(); } ~MyRenderer() { metagl::RemoveContextListener(this); } void OnContextLost() override { // Don't call GL — just reset handles to 0 texture_ = metagl::TextureId{}; vao_ = metagl::VertexArrayId{}; vbo_ = metagl::BufferId{}; program_ = metagl::ProgramId{}; } void OnContextRestored() override { // GL pointers are valid again — recreate everything uploadResources(); } private: bool uploadResources() { metagl::glGenTextures(1, &texture_.value); metagl::glBindTexture(metagl::TextureTarget::Texture2D, texture_); // ... upload pixel data ... return true; } metagl::TextureId texture_; metagl::VertexArrayId vao_; metagl::BufferId vbo_; metagl::ProgramId program_; }; // In main / application setup: MyRenderer renderer; metagl::Initialize(SDL_GL_GetProcAddress); renderer.init(); // Platform context-loss path (e.g. Android onSurfaceDestroyed): metagl::NotifyContextLost(); // Platform context-restore path (e.g. Android onSurfaceCreated): metagl::LoadCurrentContext(SDL_GL_GetProcAddress); // step 1 metagl::NotifyContextRestored(); // step 2
Android
On Android, context loss fires when the app goes to background (the EGL surface is destroyed).
Wire up the callbacks from your GLSurfaceView.Renderer JNI calls:
// onSurfaceDestroyed (context lost): metagl::NotifyContextLost(); // onSurfaceCreated (context restored or first-time creation): bool ok = metagl::Initialize(eglGetProcAddress); // first time // or: metagl::LoadCurrentContext(eglGetProcAddress); // on restore metagl::NotifyContextRestored();
WebGL / Emscripten
Use metagl/Emscripten.hpp to install browser event handlers automatically.
After that, call NotifyContextLost / NotifyContextRestored
from your own handler, or rely on the Emscripten callbacks to call
MarkContextLost / MarkContextRestored directly.
#include <metagl/metagl.hpp> // Emscripten.hpp included automatically metagl::Initialize(emscripten_webgl_get_proc_address); metagl::InstallEmscriptenContextLossCallbacks("#canvas"); // When context is restored, the browser fires webglcontextrestored. // Inside your handler: metagl::LoadCurrentContext(emscripten_webgl_get_proc_address); metagl::NotifyContextRestored();