mirror of
https://github.com/comfyanonymous/ComfyUI.git
synced 2026-06-11 08:47:29 +08:00
globals -> concrete backend attribs
This commit is contained in:
parent
40fa050d3b
commit
d2d750d9c4
@ -18,8 +18,6 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
# OpenGL modules - initialized lazily when context is created
|
||||
gl = None
|
||||
glfw = None
|
||||
EGL = None
|
||||
|
||||
|
||||
def _check_opengl_availability():
|
||||
@ -322,49 +320,47 @@ class _GLContextGLFW(GLContext):
|
||||
return "GLFW"
|
||||
|
||||
def _init_backend_concrete(self):
|
||||
global glfw
|
||||
self._window, glfw = self.__init_glfw()
|
||||
|
||||
def _make_current_concrete(self):
|
||||
glfw.make_context_current(self._window)
|
||||
|
||||
@staticmethod
|
||||
def __init_glfw():
|
||||
"""Initialize GLFW. Returns (window, glfw_module). Raises RuntimeError on failure."""
|
||||
logger.debug("__init_glfw: starting")
|
||||
"""Initialize GLFW. Raises RuntimeError on failure."""
|
||||
logger.debug("_init_backend_concrete (GLFW): starting")
|
||||
# On macOS, glfw.init() must be called from main thread or it hangs forever
|
||||
if sys.platform == "darwin":
|
||||
logger.debug("__init_glfw: skipping on macOS")
|
||||
logger.debug("_init_backend_concrete (GLFW): skipping on macOS")
|
||||
raise RuntimeError("GLFW backend not supported on macOS")
|
||||
|
||||
logger.debug("__init_glfw: importing glfw module")
|
||||
import glfw as _glfw
|
||||
logger.debug("_init_backend_concrete (GLFW): importing glfw module")
|
||||
import glfw
|
||||
|
||||
logger.debug("__init_glfw: calling glfw.init()")
|
||||
if not _glfw.init():
|
||||
logger.debug("_init_backend_concrete (GLFW): calling glfw.init()")
|
||||
if not glfw.init():
|
||||
raise RuntimeError("glfw.init() failed")
|
||||
|
||||
try:
|
||||
logger.debug("__init_glfw: setting window hints")
|
||||
_glfw.window_hint(_glfw.VISIBLE, _glfw.FALSE)
|
||||
_glfw.window_hint(_glfw.CONTEXT_VERSION_MAJOR, 3)
|
||||
_glfw.window_hint(_glfw.CONTEXT_VERSION_MINOR, 3)
|
||||
_glfw.window_hint(_glfw.OPENGL_PROFILE, _glfw.OPENGL_CORE_PROFILE)
|
||||
logger.debug("_init_backend_concrete (GLFW): setting window hints")
|
||||
glfw.window_hint(glfw.VISIBLE, glfw.FALSE)
|
||||
glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 3)
|
||||
glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 3)
|
||||
glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE)
|
||||
|
||||
logger.debug("__init_glfw: calling create_window()")
|
||||
window = _glfw.create_window(64, 64, "ComfyUI GLSL", None, None)
|
||||
logger.debug("_init_backend_concrete (GLFW): calling create_window()")
|
||||
window = glfw.create_window(64, 64, "ComfyUI GLSL", None, None)
|
||||
if not window:
|
||||
raise RuntimeError("glfw.create_window() failed")
|
||||
|
||||
logger.debug("__init_glfw: calling make_context_current()")
|
||||
_glfw.make_context_current(window)
|
||||
logger.debug("__init_glfw: completed successfully")
|
||||
return window, _glfw
|
||||
logger.debug("_init_backend_concrete (GLFW): calling make_context_current()")
|
||||
glfw.make_context_current(window)
|
||||
except Exception:
|
||||
logger.debug("__init_glfw: failed, terminating glfw")
|
||||
_glfw.terminate()
|
||||
logger.debug("_init_backend_concrete (GLFW): failed, terminating glfw")
|
||||
glfw.terminate()
|
||||
raise
|
||||
|
||||
self._window = window
|
||||
self._glfw = glfw
|
||||
|
||||
logger.debug("_init_backend_concrete (GLFW): completed successfully")
|
||||
|
||||
def _make_current_concrete(self):
|
||||
self._glfw.make_context_current(self._window)
|
||||
|
||||
##########
|
||||
|
||||
class _GLContextEGL(GLContext):
|
||||
@ -374,97 +370,88 @@ class _GLContextEGL(GLContext):
|
||||
return "EGL"
|
||||
|
||||
def _init_backend_concrete(self):
|
||||
global EGL
|
||||
self._egl_display, self._egl_context, self._egl_surface, EGL = self.__init_egl()
|
||||
|
||||
def _make_current_concrete(self):
|
||||
from OpenGL.EGL import eglMakeCurrent
|
||||
eglMakeCurrent(self._egl_display, self._egl_surface, self._egl_surface, self._egl_context)
|
||||
|
||||
@staticmethod
|
||||
def __init_egl():
|
||||
"""Initialize EGL for headless rendering. Returns (display, context, surface, EGL_module). Raises RuntimeError on failure."""
|
||||
logger.debug("__init_egl: starting")
|
||||
from OpenGL import EGL as _EGL
|
||||
from OpenGL.EGL import (
|
||||
eglGetDisplay, eglInitialize, eglChooseConfig, eglCreateContext,
|
||||
eglMakeCurrent, eglCreatePbufferSurface, eglBindAPI,
|
||||
eglTerminate, eglDestroyContext, eglDestroySurface,
|
||||
EGL_DEFAULT_DISPLAY, EGL_NO_CONTEXT, EGL_NONE,
|
||||
EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
|
||||
EGL_RED_SIZE, EGL_GREEN_SIZE, EGL_BLUE_SIZE, EGL_ALPHA_SIZE, EGL_DEPTH_SIZE,
|
||||
EGL_WIDTH, EGL_HEIGHT, EGL_OPENGL_API,
|
||||
)
|
||||
logger.debug("__init_egl: imports completed")
|
||||
"""Initialize EGL for headless rendering. Raises RuntimeError on failure."""
|
||||
logger.debug("_init_backend_concrete (EGL): starting")
|
||||
from OpenGL import EGL
|
||||
logger.debug("_init_backend_concrete (EGL): imports completed")
|
||||
|
||||
display = None
|
||||
context = None
|
||||
surface = None
|
||||
|
||||
try:
|
||||
logger.debug("__init_egl: calling eglGetDisplay()")
|
||||
display = eglGetDisplay(EGL_DEFAULT_DISPLAY)
|
||||
if display == _EGL.EGL_NO_DISPLAY:
|
||||
logger.debug("_init_backend_concrete (EGL): calling eglGetDisplay()")
|
||||
display = EGL.eglGetDisplay(EGL.EGL_DEFAULT_DISPLAY)
|
||||
if display == EGL.EGL_NO_DISPLAY:
|
||||
raise RuntimeError("eglGetDisplay() failed")
|
||||
|
||||
logger.debug("__init_egl: calling eglInitialize()")
|
||||
major, minor = _EGL.EGLint(), _EGL.EGLint()
|
||||
if not eglInitialize(display, major, minor):
|
||||
logger.debug("_init_backend_concrete (EGL): calling eglInitialize()")
|
||||
major, minor = EGL.EGLint(), EGL.EGLint()
|
||||
if not EGL.eglInitialize(display, major, minor):
|
||||
display = None # Not initialized, don't terminate
|
||||
raise RuntimeError("eglInitialize() failed")
|
||||
logger.debug(f"__init_egl: EGL version {major.value}.{minor.value}")
|
||||
logger.debug(f"_init_backend_concrete (EGL): EGL version {major.value}.{minor.value}")
|
||||
|
||||
config_attribs = [
|
||||
EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
|
||||
EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
|
||||
EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_ALPHA_SIZE, 8,
|
||||
EGL_DEPTH_SIZE, 0, EGL_NONE
|
||||
EGL.EGL_SURFACE_TYPE, EGL.EGL_PBUFFER_BIT,
|
||||
EGL.EGL_RENDERABLE_TYPE, EGL.EGL_OPENGL_BIT,
|
||||
EGL.EGL_RED_SIZE, 8, EGL.EGL_GREEN_SIZE, 8, EGL.EGL_BLUE_SIZE, 8, EGL.EGL_ALPHA_SIZE, 8,
|
||||
EGL.EGL_DEPTH_SIZE, 0, EGL.EGL_NONE
|
||||
]
|
||||
configs = (_EGL.EGLConfig * 1)()
|
||||
num_configs = _EGL.EGLint()
|
||||
if not eglChooseConfig(display, config_attribs, configs, 1, num_configs) or num_configs.value == 0:
|
||||
configs = (EGL.EGLConfig * 1)()
|
||||
num_configs = EGL.EGLint()
|
||||
if not EGL.eglChooseConfig(display, config_attribs, configs, 1, num_configs) or num_configs.value == 0:
|
||||
raise RuntimeError("eglChooseConfig() failed")
|
||||
config = configs[0]
|
||||
logger.debug(f"__init_egl: config chosen, num_configs={num_configs.value}")
|
||||
logger.debug(f"_init_backend_concrete (EGL): config chosen, num_configs={num_configs.value}")
|
||||
|
||||
if not eglBindAPI(EGL_OPENGL_API):
|
||||
if not EGL.eglBindAPI(EGL.EGL_OPENGL_API):
|
||||
raise RuntimeError("eglBindAPI() failed")
|
||||
|
||||
logger.debug("__init_egl: calling eglCreateContext()")
|
||||
logger.debug("_init_backend_concrete (EGL): calling eglCreateContext()")
|
||||
context_attribs = [
|
||||
_EGL.EGL_CONTEXT_MAJOR_VERSION, 3,
|
||||
_EGL.EGL_CONTEXT_MINOR_VERSION, 3,
|
||||
_EGL.EGL_CONTEXT_OPENGL_PROFILE_MASK, _EGL.EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT,
|
||||
EGL_NONE
|
||||
EGL.EGL_CONTEXT_MAJOR_VERSION, 3,
|
||||
EGL.EGL_CONTEXT_MINOR_VERSION, 3,
|
||||
EGL.EGL_CONTEXT_OPENGL_PROFILE_MASK, EGL.EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT,
|
||||
EGL.EGL_NONE
|
||||
]
|
||||
context = eglCreateContext(display, config, EGL_NO_CONTEXT, context_attribs)
|
||||
if context == EGL_NO_CONTEXT:
|
||||
context = EGL.eglCreateContext(display, config, EGL.EGL_NO_CONTEXT, context_attribs)
|
||||
if context == EGL.EGL_NO_CONTEXT:
|
||||
raise RuntimeError("eglCreateContext() failed")
|
||||
|
||||
logger.debug("__init_egl: calling eglCreatePbufferSurface()")
|
||||
pbuffer_attribs = [EGL_WIDTH, 64, EGL_HEIGHT, 64, EGL_NONE]
|
||||
surface = eglCreatePbufferSurface(display, config, pbuffer_attribs)
|
||||
if surface == _EGL.EGL_NO_SURFACE:
|
||||
logger.debug("_init_backend_concrete (EGL): calling eglCreatePbufferSurface()")
|
||||
pbuffer_attribs = [EGL.EGL_WIDTH, 64, EGL.EGL_HEIGHT, 64, EGL.EGL_NONE]
|
||||
surface = EGL.eglCreatePbufferSurface(display, config, pbuffer_attribs)
|
||||
if surface == EGL.EGL_NO_SURFACE:
|
||||
raise RuntimeError("eglCreatePbufferSurface() failed")
|
||||
|
||||
logger.debug("__init_egl: calling eglMakeCurrent()")
|
||||
if not eglMakeCurrent(display, surface, surface, context):
|
||||
logger.debug("_init_backend_concrete (EGL): calling eglMakeCurrent()")
|
||||
if not EGL.eglMakeCurrent(display, surface, surface, context):
|
||||
raise RuntimeError("eglMakeCurrent() failed")
|
||||
|
||||
logger.debug("__init_egl: completed successfully")
|
||||
return display, context, surface, _EGL
|
||||
|
||||
except Exception:
|
||||
logger.debug("__init_egl: failed, cleaning up")
|
||||
logger.debug("_init_backend_concrete (EGL): failed, cleaning up")
|
||||
# Clean up any resources on failure
|
||||
if surface is not None:
|
||||
eglDestroySurface(display, surface)
|
||||
EGL.eglDestroySurface(display, surface)
|
||||
if context is not None:
|
||||
eglDestroyContext(display, context)
|
||||
EGL.eglDestroyContext(display, context)
|
||||
if display is not None:
|
||||
eglTerminate(display)
|
||||
EGL.eglTerminate(display)
|
||||
raise
|
||||
|
||||
self._egl_display = display
|
||||
self._egl_context = context
|
||||
self._egl_surface = surface
|
||||
|
||||
self._EGL = EGL
|
||||
self._eglMakeCurrent = EGL.eglMakeCurrent
|
||||
|
||||
logger.debug("_init_backend_concrete (EGL): completed successfully")
|
||||
|
||||
def _make_current_concrete(self):
|
||||
self._eglMakeCurrent(self._egl_display, self._egl_surface, self._egl_surface, self._egl_context)
|
||||
|
||||
##########
|
||||
|
||||
class _GLContextOSMesa(GLContext):
|
||||
@ -474,27 +461,19 @@ class _GLContextOSMesa(GLContext):
|
||||
return "OSMesa"
|
||||
|
||||
def _init_backend_concrete(self):
|
||||
self._osmesa_ctx, self._osmesa_buffer = self.__init_osmesa()
|
||||
|
||||
def _make_current_concrete(self):
|
||||
from OpenGL.osmesa import OSMesaMakeCurrent
|
||||
OSMesaMakeCurrent(self._osmesa_ctx, self._osmesa_buffer, gl.GL_UNSIGNED_BYTE, 64, 64)
|
||||
|
||||
@staticmethod
|
||||
def __init_osmesa():
|
||||
"""Initialize OSMesa for software rendering. Returns (context, buffer). Raises RuntimeError on failure."""
|
||||
import ctypes
|
||||
|
||||
logger.debug("__init_osmesa: starting")
|
||||
logger.debug("_init_backend_concrete (OSMesa): starting")
|
||||
os.environ["PYOPENGL_PLATFORM"] = "osmesa"
|
||||
|
||||
logger.debug("__init_osmesa: importing OpenGL.osmesa")
|
||||
logger.debug("_init_backend_concrete (OSMesa): importing OpenGL.osmesa")
|
||||
from OpenGL import GL as _gl
|
||||
from OpenGL.osmesa import (
|
||||
OSMesaCreateContextExt, OSMesaMakeCurrent, OSMesaDestroyContext,
|
||||
OSMESA_RGBA,
|
||||
)
|
||||
logger.debug("__init_osmesa: imports completed")
|
||||
logger.debug("_init_backend_concrete (OSMesa): imports completed")
|
||||
|
||||
ctx = OSMesaCreateContextExt(OSMESA_RGBA, 24, 0, 0, None)
|
||||
if not ctx:
|
||||
@ -503,13 +482,19 @@ class _GLContextOSMesa(GLContext):
|
||||
width, height = 64, 64
|
||||
buffer = (ctypes.c_ubyte * (width * height * 4))()
|
||||
|
||||
logger.debug("__init_osmesa: calling OSMesaMakeCurrent()")
|
||||
logger.debug("_init_backend_concrete (OSMesa): calling OSMesaMakeCurrent()")
|
||||
if not OSMesaMakeCurrent(ctx, buffer, _gl.GL_UNSIGNED_BYTE, width, height):
|
||||
OSMesaDestroyContext(ctx)
|
||||
raise RuntimeError("OSMesaMakeCurrent() failed")
|
||||
|
||||
logger.debug("__init_osmesa: completed successfully")
|
||||
return ctx, buffer
|
||||
self._osmesa_ctx = ctx
|
||||
self._osmesa_buffer = buffer
|
||||
|
||||
logger.debug("_init_backend_concrete (OSMesa): completed successfully")
|
||||
|
||||
def _make_current_concrete(self):
|
||||
from OpenGL.osmesa import OSMesaMakeCurrent
|
||||
OSMesaMakeCurrent(self._osmesa_ctx, self._osmesa_buffer, self._gl.GL_UNSIGNED_BYTE, 64, 64)
|
||||
|
||||
|
||||
# ----------------------------------------------------------
|
||||
|
||||
Loading…
Reference in New Issue
Block a user