o
    iG                     @   s   d dl Z d dlZd dlZd dlZd dlZd dlZd dlm	Z	 d dl
Zd dlZd dlZd dlmZmZmZ d dlmZ d dlmZ eeZdd Zed e  dadadad	d
 ZG dd de	ZdZ dZ!dZ"dZ#dZ$dZ%dZ&de'de'fddZ(de'de)fddZ*de'de)fddZ+dd Z,dd Z-dd  Z.G d!d" d"Z/de'd#e)de)fd$d%Z0d&e'd'e'de)fd(d)Z1		d:d*e'd+e)d,e)d-e2e2ej3  d.e2e4 d/e2e) d0e2e5 dB d1e2ej3 dB de2e2ej3  fd2d3Z6G d4d5 d5ej7Z8G d6d7 d7eZ9de9fd8d9Z:dS );    N)	TypedDict)ComfyExtensionioui)override) get_missing_requirements_messagec                  C   s  t d g } t d tjddu r| d t d tjddu r+| d | r6tdt  d	t d
tj	  tj	
drtjdpPtjd}t dt|  |st d tjd}t d tjd}t d|rzdnd d|rdnd  t d dS )zMEarly check for OpenGL availability. Raises RuntimeError if unlikely to work.z$_check_opengl_availability: startingz5_check_opengl_availability: checking for glfw packageglfwNz7_check_opengl_availability: checking for OpenGL packageOpenGLPyOpenGLz#OpenGL dependencies not available.

z%_check_opengl_availability: platform=linuxDISPLAYWAYLAND_DISPLAYz(_check_opengl_availability: has_display=z4_check_opengl_availability: checking for EGL libraryEGLz7_check_opengl_availability: checking for OSMesa libraryOSMesazHeadless mode: EGL=yesnoz	, OSMesa=z%_check_opengl_availability: completed)loggerdebug	importlibutil	find_specappendRuntimeErrorr   sysplatform
startswithosenvirongetboolctypesfind_library)missinghas_displayhas_egl
has_osmesa r'   5/mnt/c/Users/fbmor/ComfyUI/comfy_extras/nodes_glsl.py_check_opengl_availability   s.   






&r)   z=nodes_glsl: running _check_opengl_availability at import timec                  C   s0   t du rtd ddlm}  | a td t S )z6Import OpenGL module. Called after context is created.Nz#_import_opengl: importing OpenGL.GLr   z _import_opengl: import completed)glr   r   	OpenGL.GLGL)_glr'   r'   r(   _import_openglH   s   

r.   c                   @   s&   e Zd ZU eed< eed< eed< dS )SizeModeInput	size_modewidthheightN)__name__
__module____qualname__str__annotations__intr'   r'   r'   r(   r/   S   s   
 r/         
      z#version 330 core
out vec2 v_texCoord;
void main() {
    vec2 verts[3] = vec2[](vec2(-1, -1), vec2(3, -1), vec2(-1, 3));
    v_texCoord = verts[gl_VertexID] * 0.5 + 0.5;
    gl_Position = vec4(verts[gl_VertexID], 0, 1);
}
z#version 300 es
precision highp float;

uniform sampler2D u_image0;
uniform vec2 u_resolution;

in vec2 v_texCoord;
layout(location = 0) out vec4 fragColor0;

void main() {
    fragColor0 = texture(u_image0, v_texCoord);
}
sourcereturnc                 C   s*   t jdd| t jd} t dd| } d|  S )z?Convert GLSL ES (WebGL) shader source to desktop GLSL 330 core.z#version\s+\d+(\s+es)?\s*\n? )flagsz0precision\s+(lowp|mediump|highp)\s+\w+\s*;\s*\n?z#version 330 core
)resub
IGNORECASE)r=   r'   r'   r(   _convert_es_to_desktop   s   rD   c                 C   s4   t d| }|s
dS tdd |D }t|d tS )z{Detect how many fragColor outputs are used in the shader.

    Returns the count of outputs needed (1 to MAX_OUTPUTS).
    zfragColor(\d+)   c                 s   s    | ]}t |V  qd S N)r8   ).0mr'   r'   r(   	<genexpr>   s    z'_detect_output_count.<locals>.<genexpr>)rA   findallmaxminMAX_OUTPUTS)r=   matches	max_indexr'   r'   r(   _detect_output_count   s
   rP   c                 C   s(   t d| }|rtdt|dS dS )zyDetect multi-pass rendering from #pragma passes N directive.

    Returns the number of passes (1 if not specified).
    z#pragma\s+passes\s+(\d+)rE   )rA   searchrK   r8   group)r=   matchr'   r'   r(   _detect_pass_count   s   rT   c                  C   s  t d tjdkrt d tdt d ddl} t d |  s)td	zKt d
 | | j| j	 | | j
d | | jd | | j| j t d | ddddd}|satdt d | | t d || fW S  ty   t d |    w )zOInitialize GLFW. Returns (window, glfw_module). Raises RuntimeError on failure.z_init_glfw: startingdarwinz_init_glfw: skipping on macOSz#GLFW backend not supported on macOSz!_init_glfw: importing glfw moduler   Nz_init_glfw: calling glfw.init()zglfw.init() failedz _init_glfw: setting window hints   z#_init_glfw: calling create_window()@   zComfyUI GLSLzglfw.create_window() failedz*_init_glfw: calling make_context_current()z"_init_glfw: completed successfullyz$_init_glfw: failed, terminating glfw)r   r   r   r   r   r   initwindow_hintVISIBLEFALSECONTEXT_VERSION_MAJORCONTEXT_VERSION_MINOROPENGL_PROFILEOPENGL_CORE_PROFILEcreate_windowmake_context_current	Exception	terminate)_glfwwindowr'   r'   r(   
_init_glfw   s8   











rf   c            %      C   s  t d ddlm}  ddlm}m}m}m}m	}m
}m}m}m}	m}
m}m}m}m}m}m}m}m}m}m}m}m}m}m}m} t d d}d}d}zt d ||}|| jkr_tdt d	 |   |   }}||||syd}td
t d|j! d|j!  |||||d|d|d|d|d|g}| j"d  } |   }!|||| d|!r|!j!dkrtd| d }"t d|!j!  ||stdt d | j#d| j$d| j%| j&|g}#|||"||#}||krtdt d |d|d|g}$|||"|$}|| j'krtdt d |||||stdt d |||| fW S  t(yK   t d |dur7|
|| |durA|	|| |durJ||  w )zwInitialize EGL for headless rendering. Returns (display, context, surface, EGL_module). Raises RuntimeError on failure.z_init_egl: startingr   )r   )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_APIz_init_egl: imports completedNz"_init_egl: calling eglGetDisplay()zeglGetDisplay() failedz"_init_egl: calling eglInitialize()zeglInitialize() failedz_init_egl: EGL version .   rE   zeglChooseConfig() failedz&_init_egl: config chosen, num_configs=zeglBindAPI() failedz%_init_egl: calling eglCreateContext()rV   zeglCreateContext() failedz,_init_egl: calling eglCreatePbufferSurface()rW   z eglCreatePbufferSurface() failedz#_init_egl: calling eglMakeCurrent()zeglMakeCurrent() failedz!_init_egl: completed successfullyz_init_egl: failed, cleaning up))r   r   r	   r   
OpenGL.EGLrg   rh   ri   rj   rk   rl   rm   rn   ro   rp   rq   rr   rs   rt   ru   rv   rw   rx   ry   rz   r{   r|   r}   r~   r   EGL_NO_DISPLAYr   EGLintvalue	EGLConfigEGL_CONTEXT_MAJOR_VERSIONEGL_CONTEXT_MINOR_VERSIONEGL_CONTEXT_OPENGL_PROFILE_MASK#EGL_CONTEXT_OPENGL_CORE_PROFILE_BITEGL_NO_SURFACErb   )%_EGLrg   rh   ri   rj   rk   rl   rm   rn   ro   rp   rq   rr   rs   rt   ru   rv   rw   rx   ry   rz   r{   r|   r}   r~   r   displaycontextsurfacemajorminorconfig_attribsconfigsnum_configsconfigcontext_attribspbuffer_attribsr'   r'   r(   	_init_egl   sx   
l
	












r   c            
      C   s   ddl } td dtjd< td ddlm} ddlm}m	}m
}m} td	 ||d
ddd}|s8tdd\}}| j|| d   }	td |||	|j||s\|| tdtd ||	fS )zdInitialize OSMesa for software rendering. Returns (context, buffer). Raises RuntimeError on failure.r   Nz_init_osmesa: startingosmesaPYOPENGL_PLATFORMz%_init_osmesa: importing OpenGL.osmesa)r,   )OSMesaCreateContextExtOSMesaMakeCurrentOSMesaDestroyContextOSMESA_RGBAz_init_osmesa: imports completed   zOSMesaCreateContextExt() failed)rW   rW   r<   z)_init_osmesa: calling OSMesaMakeCurrent()zOSMesaMakeCurrent() failedz$_init_osmesa: completed successfully)r!   r   r   r   r   r	   r,   OpenGL.osmesar   r   r   r   r   c_ubyteGL_UNSIGNED_BYTE)
r!   r-   r   r   r   r   ctxr1   r2   bufferr'   r'   r(   _init_osmesa  s$   





r   c                       s8   e Zd ZdZdZdZ fddZdd Zdd	 Z  Z	S )
	GLContextu   Manages OpenGL context and resources for shader execution.

    Tries backends in order: GLFW (desktop) → EGL (headless GPU) → OSMesa (software).
    NFc                    s   | j d u rt | | _ | j S rF   )	_instancesuper__new__)cls	__class__r'   r(   r   C  s   
zGLContext.__new__c                 C   sj  t jr
td d S td dd l}| }d | _d | _d | _d | _	d | _
d | _d | _d | _g }td zt \| _ad| _td W n! tyg } ztd|  |d|f W Y d }~nd }~ww | jd u rtd	 zt \| _| _	| _
ad
| _td W n! ty } ztd|  |d|f W Y d }~nd }~ww | jd u rtd zt \| _| _d| _td W n! ty } ztd|  |d|f W Y d }~nd }~ww | jd u rtjdkrd}n
tjdkrd}nd}ddd |D }td| d| td t  td ztd}t| || _td  W n2 tyd } z%td!|  |rZz	td|g W n
 tyY   Y nw W Y d }~nd }~ww | | d" }ttj}	ttj }
ttj!}|	r|	" nd#}	|
r|
" nd#}
|r|" nd#}d$t _t#d%|d&d'| j d(|	 d)|
 d*| 
 d S )+Nz1GLContext.__init__: already initialized, skippingz+GLContext.__init__: starting initializationr   z'GLContext.__init__: trying GLFW backendr   z*GLContext.__init__: GLFW backend succeededz)GLContext.__init__: GLFW backend failed: GLFWz&GLContext.__init__: trying EGL backendeglz)GLContext.__init__: EGL backend succeededz(GLContext.__init__: EGL backend failed: r   z)GLContext.__init__: trying OSMesa backendr   z,GLContext.__init__: OSMesa backend succeededz+GLContext.__init__: OSMesa backend failed: r   win32zWindows: Ensure GPU drivers are installed and display is available.
         CPU-only/headless mode is not supported on Windows.rU   zmacOS: GLFW is not supported.
  Install OSMesa via Homebrew: brew install mesa
  Then: pip install PyOpenGL PyOpenGL-acceleratezLinux: Install one of these backends:
  Desktop:           sudo apt install libgl1-mesa-glx libglfw3
  Headless with GPU: sudo apt install libegl1-mesa libgl1-mesa-dri
  Headless (CPU):    sudo apt install libosmesa6r   c                 s   s$    | ]\}}d | d| V  qdS )z  z: Nr'   )rG   nameerrr'   r'   r(   rI     s   " z%GLContext.__init__.<locals>.<genexpr>z2Failed to create OpenGL context.

Backend errors:
z

z'GLContext.__init__: importing OpenGL.GLz GLContext.__init__: creating VAOrE   z,GLContext.__init__: VAO created successfullyzFGLContext.__init__: VAO creation failed (may be expected for OSMesa):   UnknownTzGLSL context initialized in .1fms (z) - z (z), GL )$r   _initializedr   r   timeperf_counter_backend_window_egl_display_egl_context_egl_surface_osmesa_ctx_osmesa_buffer_vaorf   r   rb   r   r   r   r   r   r   joinr   r.   r*   glGenVertexArraysglBindVertexArrayglDeleteVertexArraysglGetStringGL_RENDERER	GL_VENDOR
GL_VERSIONdecodeinfo)selfr   starterrorseplatform_helperror_detailsvaoelapsedrenderervendorversionr'   r'   r(   __init__H  s   













0zGLContext.__init__c                 C   s   | j dkrt| j n-| j dkr#ddlm} || j| j| j| j n| j dkr9ddl	m
} || j| jtjdd | jd urFt| j d S d S )Nr   r   r   )rk   r   )r   rW   )r   r   ra   r   r   rk   r   r   r   r   r   r   r   r*   r   r   r   )r   rk   r   r'   r'   r(   make_current  s   



zGLContext.make_current)
r3   r4   r5   __doc__r   r   r   r   r   __classcell__r'   r'   r   r(   r   :  s    rr   shader_typec                 C   s^   t |}t ||  t | t |t jt jkr-t | }t 	| t
d| |S )z#Compile a shader and return its ID.zShader compilation failed:
)r*   glCreateShaderglShaderSourceglCompileShaderglGetShaderivGL_COMPILE_STATUSGL_TRUEglGetShaderInfoLogr   glDeleteShaderr   )r=   r   shadererrorr'   r'   r(   _compile_shader  s   


r   vertex_sourcefragment_sourcec                 C   s   t | tj}zt |tj}W n ty   t|  w t }t|| t|| t| t| t| t	|tj
tjkrXt| }t| td| |S )z!Create and link a shader program.zProgram linking failed:
)r   r*   GL_VERTEX_SHADERGL_FRAGMENT_SHADERr   r   glCreateProgramglAttachShaderglLinkProgramglGetProgramivGL_LINK_STATUSr   glGetProgramInfoLogr   glDeleteProgram)r   r   vertex_shaderfragment_shaderprogramr   r'   r'   r(   _create_program  s$   




r   fragment_coder1   r2   image_batchesfloatsintsboolscurvesc           2      C   sZ
  ddl }| }	|sg S t }
|
  t| }t| }t| }|du r%g }|du r+g }d}d}g }g }g }g }g }t|d }zztt	|}W n t
yX   td|   w t| td}ttj| g }t|D ]N}td}|| ttj| ttjdtj||dtjtjd	 ttjtjtj ttjtjtj ttjtj | tj|d |tj |  qpt!|| t"tjtj#krt
d|dkr[tdD ]}td}|| ttj| ttjdtj||dtjtjd	 ttjtjtj ttjtjtj ttjtj$tj% ttjtj&tj% td}|| ttj| ttjtj tj|d t!dtj g t"tjtj#krZt
dqt|D ]X}td}|| t'tj(|  ttj| ttjtjtj ttjtjtj ttjtj$tj% ttjtj&tj% t)|d| }|dkrt*|| q_t)|d	}|dkrt+|t,|t,| t-|D ]\}}t)|d
| }|dkrt.|| qt-|D ]\}}t)|d| }|dkrt*|| qt-|D ]\}}t)|d| }|dkr+t*||r(dnd qt-|D ]q\}}td}|| t/| }t'tj(|  ttj| ttjdtj0t|ddtj1tj|	 ttjtjtj ttjtjtj ttjtj$tj% ttjtj&tj% t)|d| }|dkrt*|| q1t)|d} t2dd|| t3tj4 g }!|D ]l}"t-|"D ]s\}}#t'tj(|  ttj||  |#j5\}$}%}&|&dkrt6j7|$|%dft6j8d}'|#dddddddf |'ddddddf< d|'dddddf< nt69|#dddddddf }'ttjdtj|%|$dtjtj|'	 q|dkrdttj| | dkrMt*| d t:dddd t;tj< t=tj>dd nkt|D ]f}(|(|d k})| dkr{t*| |( |)rttj| n||(d  }*ttj|* t'tj( |(dkrttj|d  n||(d d  }+ttj|+ t:dddd t;tj< t=tj>dd qhg },|D ]5}ttj| t?tjdtjtj}-t6j@|-t6j8dA||d}#|,|#dddddddf B  qt6jC||dft6j8d}.t|tDD ]}|,|. q|!|, q| |	 d }/t|}0|dkr@d| dnd}1tEd|/dd|0 d|0dkrSdnd d| d| |1 d |!W ttjd td |D ]
}tFtG| qq|D ]
}tFtG| q~|D ]
}tFtG| q|D ]
}tFtG| q|durtHd|g |D ]
}tHd|g q|durtI| S S ttjd td |D ]
}tFtG| q|D ]
}tFtG| q|D ]
}tFtG| q|D ]
}tFtG| q|durtHd|g |D ]
}tHd|g q|dur,tI| w w )a  
    Render a fragment shader for multiple batches efficiently.

    Compiles shader once, reuses framebuffer/textures across batches.
    Supports multi-pass rendering via #pragma passes N directive.

    Args:
        fragment_code: User's fragment shader code
        width: Output width
        height: Output height
        image_batches: List of batches, each batch is a list of input images (H, W, C) float32 [0,1]
        floats: List of float uniforms
        ints: List of int uniforms
        bools: List of bool uniforms (passed as int 0/1 to GLSL bool uniforms)
        curves: List of 1D LUT arrays (float32) of arbitrary size for u_curve0-N

    Returns:
        List of batch outputs, each is a list of output images (H, W, 4) float32 [0,1]
    r   NzFragment shader:
rE   zFramebuffer is not complete   z%Ping-pong framebuffer is not completeu_imageu_resolutionu_floatu_intu_boolu_curveu_passrV   r<   )dtypeg      ?r   z, z passesr?   zGLSL shader executed in r   r   z batchesx))Jr   r   r   r   rD   rP   rT   lenr   VERTEX_SHADERr   r   r   r*   glUseProgramglGenFramebuffersglBindFramebufferGL_FRAMEBUFFERrangeglGenTexturesr   glBindTextureGL_TEXTURE_2DglTexImage2D
GL_RGBA32FGL_RGBAGL_FLOATglTexParameteriGL_TEXTURE_MIN_FILTER	GL_LINEARGL_TEXTURE_MAG_FILTERglFramebufferTexture2DGL_COLOR_ATTACHMENT0glDrawBuffersglCheckFramebufferStatusGL_FRAMEBUFFER_COMPLETEGL_TEXTURE_WRAP_SGL_CLAMP_TO_EDGEGL_TEXTURE_WRAP_TglActiveTextureGL_TEXTURE0glGetUniformLocationglUniform1iglUniform2ffloat	enumerateglUniform1f
MAX_IMAGESGL_R32FGL_RED
glViewport	glDisableGL_BLENDshapenpemptyfloat32ascontiguousarrayglClearColorglClearGL_COLOR_BUFFER_BITglDrawArraysGL_TRIANGLESglGetTexImage
frombufferreshapecopyzerosrM   r   glDeleteTexturesr8   glDeleteFramebuffersr   )2r   r1   r2   r   r   r   r   r   r   
start_timer   r   num_outputs
num_passesr   fbooutput_texturesinput_texturescurve_texturesping_pong_texturesping_pong_fbos
num_inputsdraw_buffersitex_pp_texpp_fbolocvlutunitpass_locall_batch_outputsimagesimghwc
img_uploadpis_last_pass
target_fbo
source_texbatch_outputsdata	black_imgr   num_batches	pass_infor'   r'   r(   _render_shader_batch  s  



"


"










&


2"&



*>





rf  c                   @   s   e Zd ZedejfddZe				ddededej	j
dej	j
d	ej	j
d
ej	j
dej	j
dejfddZedeej dejdeeef fddZdS )
GLSLShaderr>   c                 C   s  t jjt jdddtd}t jjt jjdddddtd}t jjt jjd	ddd
dtd}t jjt j	jdddddt
d}t jjt jdddtd}t jddddddt jjdtdddt jjdt jdg t jdt jjdddtjdt jjdddtjdggdd t jjd!|d"td  d#d$t jjd%|d&td  d'd$t jjd(|d)td  d'd$t jjd*|d+t
d  d,d$t jjd-|d.td  d/d$gt jjd0d1d2t jjd3d4d2t jjd5d6d2t jjd7d8d2gd9S ):NimagerE   )prefixrL   rK   r'          )defaultr   r   r8   r   r    Fr   curver  rg  zGLSL Shaderzimage/shaderzRApply GLSL ES fragment shaders to images. u_resolution (vec2) is always available.Tr   zFGLSL fragment shader source code (GLSL ES 3.00 / WebGL 2.0 compatible))rk  	multilinetooltipr0   
from_inputcustomr1   i   )rk  rL   rK   r2   zXOutput size: 'from_input' uses first input image dimensions, 'custom' allows manual size)optionsrn  rW  z!Images are available as u_image0-z (sampler2D) in the shader code)templatern  r   z!Floats are available as u_float0-z in the shader coder   zInts are available as u_int0-r   z"Booleans are available as u_bool0-z (bool) in the shader coder   z!Curves are available as u_curve0-zV (sampler2D, 1D LUT) in the shader code. Sample with texture(u_curve0, vec2(x, 0.5)).rIMAGE0zIAvailable via layout(location = 0) out vec4 fragColor0 in the shader code)display_namern  IMAGE1zIAvailable via layout(location = 1) out vec4 fragColor1 in the shader codeIMAGE2zIAvailable via layout(location = 2) out vec4 fragColor2 in the shader codeIMAGE3zIAvailable via layout(location = 3) out vec4 fragColor3 in the shader code)node_idrt  categorydescriptionis_experimentalhas_intermediate_outputinputsoutputs)r   AutogrowTemplatePrefixImageInputr*  FloatMAX_UNIFORMSIntBoolean	MAX_BOOLSCurve
MAX_CURVESSchemaStringDEFAULT_FRAGMENT_SHADERDynamicComboOptionnodesMAX_RESOLUTIONOutput)r   image_templatefloat_templateint_templatebool_templatecurve_templater'   r'   r(   define_schema  s   

&zGLSLShader.define_schemaNr   r0   rW  r   r   r   r   c              	      s  dd |  D }	|rdd |  D ng }
|r!dd |  D ng }|r.dd |  D ng }|r;dd |  D ng }|	sCtd|d d	krR|d
 }|d }n|	d jdd \}}|	d jd }g }t|D ]fdd|	D }|| qjt|||||
|||}dd ttD  |D ]}t|D ]\}} | t	| qq fddttD }t
j|d| |	|d iS )Nc                 S   s   g | ]}|d ur|qS rF   r'   rG   rR  r'   r'   r(   
<listcomp>k  s    z&GLSLShader.execute.<locals>.<listcomp>c                 S      g | ]
}|d ur
|ndqS )Nrj  r'   r  r'   r'   r(   r  m      c                 S   r  )Nr   r'   r  r'   r'   r(   r  o  r  c                 S   r  )NFr'   r  r'   r'   r(   r  p  r  c                 S   s$   g | ]}|d ur|  tjqS rF   )to_lutastyper1  r3  r  r'   r'   r(   r  r     $ z$At least one input image is requiredr0   rp  r1   r2   r   rE   rV   c                    s$   g | ]}|     tjqS r'   )cpunumpyr  r1  r3  )rG   
img_tensor)	batch_idxr'   r(   r    r  c                 S   s   g | ]}g qS r'   r'   )rG   rN  r'   r'   r(   r    s    c                    s   g | ]}t j | d dqS )r   )dim)torchstack)rG   rL  )all_outputsr'   r(   r    s    r   )values
ValueErrorr0  r  r   rf  rM   r(  r  
from_numpyr   
NodeOutput_build_ui_output)r   r   r0   rW  r   r   r   r   kwargs
image_list
float_listint_list	bool_list
curve_luts	out_width
out_height
batch_sizer   batch_imagesrV  ra  rL  out_imgoutput_tensorsr'   )r  r  r(   execute^  sL   
zGLSLShader.executer  output_batchc              
   C   sR   g }|D ]}| tjj|dtjjddd qtjj|dtjjddd}||dS )zNBuild UI output with input and output images for client-side shader execution.GLSLShader_inputNrE   )filename_prefixfolder_typer   compress_levelGLSLShader_output)input_imagesrW  )extendr   ImageSaveHelpersave_imagesr   
FolderTypetemp)r   r  r  input_images_uirX  output_images_uir'   r'   r(   r    s"   


zGLSLShader._build_ui_output)NNNN)r3   r4   r5   classmethodr   r  r  r6   r/   r  Typer  r  listr  Tensordictr  r'   r'   r'   r(   rg     sB    [
>
rg  c                   @   s(   e Zd Zedeeej  fddZdS )GLSLExtensionr>   c                    s   t gS rF   )rg  )r   r'   r'   r(   get_node_list  s   zGLSLExtension.get_node_listN)	r3   r4   r5   r   r  typer   	ComfyNoder  r'   r'   r'   r(   r    s    r  c                      s   t  S rF   )r  r'   r'   r'   r(   comfy_entrypoint  s   r  )NN);r   r   rA   loggingctypes.utilr!   importlib.utilr   typingr   r  r1  r  r  comfy_api.latestr   r   r   typing_extensionsr   utils.install_utilr   	getLoggerr3   r   r)   r   r*   r   r   r.   r/   r*  r  r  r  rM   r	  r  r6   rD   r8   rP   rT   rf   r   r   r   r   r   r  ndarrayr'  r    rf  r  rg  r  r  r'   r'   r'   r(   <module>   s    

+	
%T  
	
   8