Callback Video Texture
Shared base for JVM-side video textures whose source pushes decoded frames from a worker thread (libVLC, FFmpeg, JavaCV, JavaFX MediaView-snapshot, …):
Subclasses call submitFrame (ByteArray or ByteBuffer) on the decoder thread; the base atomically publishes a fresh FrameBuf to the GL thread — lock-free.
On every bindTexture (GL thread), if a new frame is pending, the base atomically consumes it via
getAndSet(null)and uploads viaglTexSubImage2D(orglTexImage2Don first frame / resolution change). With nothing pending the upload is skipped — the driver keeps the previous frame's storage live.
Optimizations vs. a naive blit:
GL_TEXTURE_SWIZZLE_A = GL_ONE— sampler returns alpha=1.0 regardless of the texture bytes; eliminates a per-frame CPU pass to force every 4th byte to0xFF.glTexSubImage2Dfor steady-state — re-uploads pixels into existing GPU storage instead of re-allocating withglTexImage2Devery frame.Optional PBO path (usePbo) — uploads route through
GL_PIXEL_UNPACK_BUFFERviaglMapBufferRange(... INVALIDATE_BUFFER | UNSYNCHRONIZED)+ memcpy +glUnmapBuffer. Driver hands back fresh staging memory directly while the previous transfer is still in flight; fewer driver round-trips than thebufferData(null) + bufferData(data)orphan idiom.Lock-free frame publish — no
synchronizedbetween decoder and GL threads. TwoAtomicReference<FrameBuf>slots (latest+recycled) serve as the producer / consumer queue; at steady state at most twoByteArrays exist in flight.
Internal format is GL_RGBA (which JoglKgl maps to renderable GL_RGBA8); upload pixel-format (uploadFormat) is whatever the decoder produces — GL_BGRA for libVLC RV32, FFmpeg/JavaCV after sws_scale, and JavaFX PixelFormat.byteBgra.