Phase 2: Present-hook video path (shared-texture mirror)
Add an injected IDXGISwapChain::Present / Present1 hook as a lower-latency, border-free alternative to WGC. The hook copies the swapchain backbuffer into a shared keyed-mutex texture (coop_video_<pid>); the host opens it by name and samples it. New opt-in HookSubsys_Video (protocol v6 -> v7); the Video mirror panel gains a WGC vs Hooked source toggle that installs/removes the subsystem. Verified by present_hook_test (drives a real D3D11 swapchain end-to-end and reads the rendered pixels back through the shared texture) and against Phantom Brave (D3D9: hook installs cleanly and stays idle, WGC fallback). All 5 tests pass. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
// Owns the video-mirror pipeline (WGC capture + frame renderer) and its UI.
|
||||
// The target window comes from the injected hook's reported game HWND.
|
||||
// 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 <cstdint>
|
||||
@@ -8,23 +10,33 @@
|
||||
#include <windows.h>
|
||||
|
||||
#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 (0 if none yet); typically the injected game's HWND.
|
||||
// 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);
|
||||
@@ -33,13 +45,22 @@ public:
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user