// Host-side consumer of the injected Present-hook's shared backbuffer texture. // Opens the keyed-mutex texture the hook publishes (coop_video_) by name, // copies the latest frame into a private texture under the keyed mutex, and // exposes an SRV the FrameRenderer can draw -- the lower-latency alternative to // Windows Graphics Capture. See hook/src/present_hook.cpp and coop/protocol.hpp. #pragma once #include #include #include #include #include "ipc/ipc_server.hpp" namespace coop { class SharedTextureSource { public: // Binds to the host's device (must support ID3D11Device1). Returns false if not. bool init(ID3D11Device* device); // Polls the hook's video channel for `pid`. (Re)opens the shared texture when // the pid/dimensions/format change, and copies the newest frame into the // private texture under the keyed mutex. Returns true if a frame is available // to draw (sticky: keeps the last copy until a new one or a reset). bool update(const VideoShareView& share, unsigned long pid); // Drop the opened resources (target changed / mirror turned off). void reset(); // Read the RGBA8 pixel at (x,y) of the last copied frame into out[4]. For verification // (e.g. decoding the mock game's frame-number block in a capture test). Copies the // private texture to a CPU-readable staging texture and maps it -- not a hot path. // Returns false if no frame has been copied yet or the readback failed. bool read_pixel(std::uint32_t x, std::uint32_t y, std::uint8_t out[4]); [[nodiscard]] ID3D11ShaderResourceView* srv() const { return srv_.Get(); } [[nodiscard]] std::uint32_t width() const { return width_; } [[nodiscard]] std::uint32_t height() const { return height_; } [[nodiscard]] std::uint64_t frames_copied() const { return frames_copied_; } // Cumulative published frames the host never displayed because the generation // advanced by more than one between copies (host render rate < hook publish rate). [[nodiscard]] std::uint64_t frames_missed() const { return frames_missed_; } private: bool reopen(unsigned long pid, const VideoShareView& share); Microsoft::WRL::ComPtr device_; Microsoft::WRL::ComPtr ctx_; Microsoft::WRL::ComPtr shared_; // opened from the hook, by name Microsoft::WRL::ComPtr mutex_; Microsoft::WRL::ComPtr private_; // our sampled copy Microsoft::WRL::ComPtr srv_; unsigned long pid_ = 0; std::uint32_t width_ = 0; std::uint32_t height_ = 0; std::uint32_t format_ = 0; std::uint32_t last_generation_ = 0; std::uint64_t frames_copied_ = 0; std::uint64_t frames_missed_ = 0; }; } // namespace coop