mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-04-20 14:30:41 +00:00
## Summary replacement for https://github.com/Comfy-Org/ComfyUI_frontend/pull/9201 the first commit squashed https://github.com/Comfy-Org/ComfyUI_frontend/pull/9201 and fixed conflict. the second commit change needed by: - Enable GLSL live preview on SubgraphNodes by detecting the inner GLSLShader and rendering its preview directly on the parent SubgraphNode - Previously, SubgraphNodes containing a GLSLShader showed no live preview at all To achieve this: - Read shader source, uniform values, and renderer config from the inner GLSLShader's widgets - Trace IMAGE inputs through the subgraph boundary so the inner shader can use images connected to the SubgraphNode's outer inputs - Set preview output using the inner node's locator ID so the promoted preview system picks it up on the SubgraphNode - Extract setNodePreviewsByLocatorId from nodeOutputStore to support setting previews by locator ID directly - Fix graphId to use rootGraph.id for widget store lookups (was using graph.id, which broke lookups for nodes inside subgraphs) - Read uniform values from connected upstream nodes, not just local widgets - Fix blob URL lifecycle: use the store's createSharedObjectUrl/releaseSharedObjectUrl reference-counting system instead of manual revoke, preventing leaks on composable re-creation ## Screenshot https://github.com/user-attachments/assets/9623fa32-de39-4a3a-b8b3-28688851390b ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-10349-Feat-glsl-live-preview-3296d73d3650814b83aef52ab1962a77) by [Unito](https://www.unito.io)
62 lines
2.1 KiB
TypeScript
62 lines
2.1 KiB
TypeScript
import { describe, expect, it, vi } from 'vitest'
|
|
|
|
import type { GLSLRendererConfig } from '@/renderer/glsl/useGLSLRenderer'
|
|
|
|
vi.mock('vue', async () => {
|
|
const actual = await vi.importActual('vue')
|
|
return {
|
|
...actual,
|
|
onScopeDispose: vi.fn()
|
|
}
|
|
})
|
|
|
|
describe('useGLSLRenderer', () => {
|
|
it('returns renderer API with expected methods', async () => {
|
|
const { useGLSLRenderer } = await import('@/renderer/glsl/useGLSLRenderer')
|
|
const renderer = useGLSLRenderer()
|
|
|
|
expect(renderer).toHaveProperty('init')
|
|
expect(renderer).toHaveProperty('compileFragment')
|
|
expect(renderer).toHaveProperty('setResolution')
|
|
expect(renderer).toHaveProperty('setFloatUniform')
|
|
expect(renderer).toHaveProperty('setIntUniform')
|
|
expect(renderer).toHaveProperty('bindInputImage')
|
|
expect(renderer).toHaveProperty('render')
|
|
expect(renderer).toHaveProperty('readPixels')
|
|
expect(renderer).toHaveProperty('toBlob')
|
|
expect(renderer).toHaveProperty('dispose')
|
|
})
|
|
|
|
it('init returns false when WebGL2 is unavailable', async () => {
|
|
const { useGLSLRenderer } = await import('@/renderer/glsl/useGLSLRenderer')
|
|
const renderer = useGLSLRenderer()
|
|
expect(renderer.init(256, 256)).toBe(false)
|
|
})
|
|
|
|
it('compileFragment reports error before initialization', async () => {
|
|
const { useGLSLRenderer } = await import('@/renderer/glsl/useGLSLRenderer')
|
|
const renderer = useGLSLRenderer()
|
|
const result = renderer.compileFragment('void main() {}')
|
|
expect(result.success).toBe(false)
|
|
})
|
|
|
|
it('toBlob rejects before initialization', async () => {
|
|
const { useGLSLRenderer } = await import('@/renderer/glsl/useGLSLRenderer')
|
|
const renderer = useGLSLRenderer()
|
|
await expect(renderer.toBlob()).rejects.toThrow('Renderer not initialized')
|
|
})
|
|
|
|
it('accepts custom config without error', async () => {
|
|
const { useGLSLRenderer } = await import('@/renderer/glsl/useGLSLRenderer')
|
|
const config: GLSLRendererConfig = {
|
|
maxInputs: 3,
|
|
maxFloatUniforms: 2,
|
|
maxIntUniforms: 1,
|
|
maxBoolUniforms: 1,
|
|
maxCurves: 2
|
|
}
|
|
const renderer = useGLSLRenderer(config)
|
|
expect(renderer.init(256, 256)).toBe(false)
|
|
})
|
|
})
|