From f241bfca816a3411c06561b1b751aed8ad1ed384 Mon Sep 17 00:00:00 2001 From: "Lex Darlog (DRL)" <3897975+Lex-DRL@users.noreply.github.com> Date: Sun, 22 Feb 2026 22:44:34 -0300 Subject: [PATCH] `GLContext` singleton factory: scaffolding concrete classes --- comfy_extras/nodes_glsl.py | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/comfy_extras/nodes_glsl.py b/comfy_extras/nodes_glsl.py index 1a9180933..e4dc3a43c 100644 --- a/comfy_extras/nodes_glsl.py +++ b/comfy_extras/nodes_glsl.py @@ -4,7 +4,7 @@ import re import logging import ctypes.util import importlib.util -from typing import TypedDict +from typing import Type, TypedDict import numpy as np import torch @@ -309,10 +309,15 @@ def _init_osmesa(): return ctx, buffer +# ---------------------------------------------------------- + + class GLContext: """Manages OpenGL context and resources for shader execution. - Tries backends in order: GLFW (desktop) → EGL (headless GPU) → OSMesa (software). + Acts as a singleton factory: ``GLContext`` itself is an "abstract" class (not a true ABC though) and never instantiates itself directly. Instead, its instance is always one of "concrete backend" contexts - a first valid subclass in the fallback sequence. ``GLContext`` doesn't inherit from ABC just to prevent IDE warnings caused by this polymorphism. For all intents and purposes, it **IS** a singleton-ABC. + + Backends fallback order: GLFW (desktop) → EGL (headless GPU) → OSMesa (software). See ``__subclass_fallback_order()``. """ __instance: 'GLContext' = None # The singleton @@ -325,6 +330,11 @@ class GLContext: assert isinstance(GLContext.__instance, GLContext) return GLContext.__instance + @staticmethod + def __concrete_class_fallback_order() -> tuple[Type['GLContext'], ...]: + """The order concrete subclasses are tried in: GLFW → EGL → OSMesa.""" + return _GLContextGLFW, _GLContextEGL, _GLContextOSMesa + def __init__(self): if GLContext.__instance is not None: logger.debug("GLContext.__init__: already initialized, skipping") @@ -462,6 +472,21 @@ class GLContext: gl.glBindVertexArray(self._vao) +class _GLContextGLFW(GLContext): + pass + + +class _GLContextEGL(GLContext): + pass + + +class _GLContextOSMesa(GLContext): + pass + + +# ---------------------------------------------------------- + + def _compile_shader(source: str, shader_type: int) -> int: """Compile a shader and return its ID.""" shader = gl.glCreateShader(shader_type)