// Owns the video-mirror pipeline and its UI. Two interchangeable sources feed the // same letterboxed renderer: Windows Graphics Capture (no injection, the default) // and the injected Present-hook's shared backbuffer texture (lower latency, needs // the video subsystem hooked). The target window/pid come from the injected hook. #pragma once #include #include #include #include "capture/frame_renderer.hpp" #include "capture/shared_texture.hpp" #include "capture/window_capture.hpp" #include "ui/app_chrome.hpp" namespace coop { class InjectionPanel; class CapturePanel { public: bool init(ID3D11Device* device); // The window to mirror via WGC (0 if none yet); typically the injected game's HWND. void set_target(HWND target) { target_ = target; } // The injection panel supplies the target pid + Present-hook video channel and // lets this panel install/remove the video subsystem when the source is Hooked. void set_injection(InjectionPanel* injection) { injection_ = injection; } // `stats` are the host's render frame-timing, drawn as the mirror's // frametime / FPS graphs (this window is what the mirror renders into). void draw_ui(const FrameStats& stats); // Render thread: draw the mirrored frame as the window background. void render(ID3D11DeviceContext* ctx, std::uint32_t dst_w, std::uint32_t dst_h); private: enum Source : int { Source_Wgc = 0, // Windows Graphics Capture Source_Hooked = 1, // injected Present-hook shared texture }; void draw_perf_graphs(const FrameStats& stats); ID3D11Device* device_ = nullptr; FrameRenderer renderer_; WindowCapture capture_; SharedTextureSource shared_; InjectionPanel* injection_ = nullptr; HWND target_ = nullptr; bool enabled_ = false; int source_ = Source_Wgc; }; } // namespace coop