Mirror: A frag-canvas custom element to apply Shadertoy fragment shaders to a canvas or image/video element

feat: Skip texture copying for image elements that haven't changed (#6)

* Skip image texture copying for <img> elements

* Add changeset

authored by kitten.sh and committed by GitHub 8306c46c 0ca26333

Changed files
+27 -1
.changeset
src
+5
.changeset/lazy-onions-tan.md
··· 1 + --- 2 + 'frag-canvas': patch 3 + --- 4 + 5 + Skip loading `<img>` as texture on every frame and skip on repeats
+22 -1
src/frag-canvas-element.ts
··· 25 25 return [year, month, day, time] as const; 26 26 }; 27 27 28 + const isImageElement = (tex: TexImageSource): tex is HTMLImageElement => 29 + (tex as Element).tagName === 'IMG'; 30 + 28 31 const preprocessShader = (source: string) => { 29 32 let header = ''; 30 33 let output = source.trim(); ··· 126 129 127 130 let frameCount = 0; 128 131 let prevTimestamp: DOMHighResTimeStamp; 132 + let prevSource: string | null; 129 133 130 134 const state = { 131 135 draw(source: TexImageSource, timestamp: DOMHighResTimeStamp) { ··· 133 137 134 138 gl.useProgram(program); 135 139 136 - if (source) { 140 + if (isImageElement(source)) { 141 + if (source.complete) { 142 + const { currentSrc } = source; 143 + if (prevSource !== currentSrc) { 144 + prevSource = currentSrc; 145 + gl.texImage2D( 146 + gl.TEXTURE_2D, 147 + 0, 148 + gl.RGBA, 149 + gl.RGBA, 150 + gl.UNSIGNED_BYTE, 151 + source 152 + ); 153 + } 154 + } 155 + } else if (source) { 156 + prevSource = null; 137 157 gl.texImage2D( 138 158 gl.TEXTURE_2D, 139 159 0, ··· 145 165 if (iChannelResolution) 146 166 gl.uniform3fv(iChannelResolution, [width, height, 0]); 147 167 } else { 168 + prevSource = null; 148 169 if (iChannelResolution) gl.uniform3fv(iChannelResolution, [0, 0, 0]); 149 170 } 150 171