#pragma once #include "GLExtensions.h" #include "VideoIOTypes.h" #include #include class OpenGLRenderer; class HealthTelemetry; class RuntimeSnapshotProvider; struct RenderPipelineFrameContext { VideoIOState videoState; VideoIOCompletion completion; }; class OpenGLRenderPipeline { public: using RenderEffectCallback = std::function; using OutputReadyCallback = std::function; using PaintCallback = std::function; OpenGLRenderPipeline( OpenGLRenderer& renderer, RuntimeSnapshotProvider& runtimeSnapshotProvider, HealthTelemetry& healthTelemetry, RenderEffectCallback renderEffect, OutputReadyCallback outputReady, PaintCallback paint); ~OpenGLRenderPipeline(); bool RenderFrame(const RenderPipelineFrameContext& context, VideoIOOutputFrame& outputFrame); private: enum class OutputReadbackMode { AsyncPbo, Synchronous, CachedOnly }; struct AsyncReadbackSlot { GLuint pixelPackBuffer = 0; GLsync fence = nullptr; std::size_t sizeBytes = 0; bool inFlight = false; }; struct OutputReadbackTiming { double fenceWaitMilliseconds = 0.0; double mapMilliseconds = 0.0; double copyMilliseconds = 0.0; double cachedCopyMilliseconds = 0.0; double asyncQueueMilliseconds = 0.0; double asyncQueueBufferMilliseconds = 0.0; double asyncQueueSetupMilliseconds = 0.0; double asyncQueueReadPixelsMilliseconds = 0.0; double asyncQueueFenceMilliseconds = 0.0; double syncReadMilliseconds = 0.0; bool asyncReadbackMissed = false; bool cachedFallbackUsed = false; bool syncFallbackUsed = false; }; bool EnsureAsyncReadbackBuffers(std::size_t requiredBytes); void ResetAsyncReadbackState(); void FlushAsyncReadbackPipeline(); bool QueueAsyncReadback(const VideoIOState& state, OutputReadbackTiming& timing); bool TryConsumeAsyncReadback(VideoIOOutputFrame& outputFrame, GLuint64 timeoutNanoseconds, OutputReadbackTiming& timing); void CacheOutputFrame(const VideoIOOutputFrame& outputFrame); bool TryCopyCachedOutputFrame(VideoIOOutputFrame& outputFrame, OutputReadbackTiming& timing) const; void ReadOutputFrameSynchronously(const VideoIOState& state, void* destinationBytes, OutputReadbackTiming& timing); void PackOutputForBgra8(const VideoIOState& state); void PackOutputFor10Bit(const VideoIOState& state); OutputReadbackTiming ReadOutputFrame(const VideoIOState& state, VideoIOOutputFrame& outputFrame); static OutputReadbackMode ReadOutputReadbackModeFromEnvironment(); static std::size_t ReadAsyncReadbackDepthFromEnvironment(); OpenGLRenderer& mRenderer; RuntimeSnapshotProvider& mRuntimeSnapshotProvider; HealthTelemetry& mHealthTelemetry; RenderEffectCallback mRenderEffect; OutputReadyCallback mOutputReady; PaintCallback mPaint; OutputReadbackMode mOutputReadbackMode = OutputReadbackMode::AsyncPbo; std::vector mAsyncReadbackSlots; std::size_t mAsyncReadbackDepth = 0; std::size_t mAsyncReadbackWriteIndex = 0; std::size_t mAsyncReadbackReadIndex = 0; std::size_t mAsyncReadbackBytes = 0; GLenum mAsyncReadbackFormat = GL_BGRA; GLenum mAsyncReadbackType = GL_UNSIGNED_INT_8_8_8_8_REV; GLuint mAsyncReadbackFramebuffer = 0; std::vector mCachedOutputFrame; };