Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ Config ParseConfig(const std::string& text) {
else if (key == "vsync") c.vsync = std::stoi(val);
else if (key == "dwmFlush") c.dwmFlush = std::stoi(val);
else if (key == "present") c.present = val;
else if (key == "gpuPriority") c.gpuPriority = std::stoi(val);
else if (key == "diagnostics") c.diagnostics = std::stoi(val);
else if (key == "cursorSensitivity") c.cursorSensitivity = std::stod(val);
else if (key == "cursorSmoothing") c.cursorSmoothing = std::stod(val);
Expand Down Expand Up @@ -78,6 +79,9 @@ Config LoadConfig(const std::wstring& path) {
"; present: blt=default (blt swapchain + DwmFlush); dcomp=flip-model via DirectComposition\n"
"; (experimental, vsync-paced; restart to change)\n"
"present=blt\n"
"; gpuPriority: GPU scheduling priority (-7..7). Higher keeps the zoom responsive when a\n"
"; game runs in the background; lower if it hurts a foreground game (restart to apply)\n"
"gpuPriority=7\n"
"; diagnostics=1 logs frame timing to %TEMP%\\wind_diag.log (restart to apply)\n"
"diagnostics=0\n"
"; cursorSensitivity: pan speed per raw count\n"
Expand Down
5 changes: 5 additions & 0 deletions src/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ struct Config {
// (default); "dcomp" = flip-model swapchain via DirectComposition, paced by vsync Present
// (experimental A/B - native flip pacing + lower latency, still click-through via layered).
std::string present = "blt";
// GPU scheduling priority for the magnifier's device (IDXGIDevice::SetGPUThreadPriority,
// clamped to [-7,7]). Higher = the GPU scheduler favors us over other apps, so the zoom
// stays responsive when a GPU-heavy app (a game) runs in the background. 0 = OS default.
// Lower it if it hurts a foreground game while zoomed.
int gpuPriority = 7;
int diagnostics = 0; // 1 = log frame-timing to wind_diag.log

// --- Own GPU renderer ---------------------------------------------------
Expand Down
2 changes: 1 addition & 1 deletion src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ int WINAPI wWinMain(HINSTANCE hInst, HINSTANCE, PWSTR, int) {

// --- Own GPU renderer (DXGI Desktop Duplication + D3D11) ---
RenderEngine renderEngine;
if (!renderEngine.initialize(sw, sh, cfg.zorderBand, cfg.hdrTonemap != 0, cfg.present == "dcomp")) {
if (!renderEngine.initialize(sw, sh, cfg.zorderBand, cfg.hdrTonemap != 0, cfg.present == "dcomp", cfg.gpuPriority)) {
MessageBoxW(nullptr, L"Could not start the renderer (Direct3D 11 / Desktop Duplication "
L"unavailable on this system).", L"Wind", MB_ICONERROR);
g_input.stop();
Expand Down
7 changes: 6 additions & 1 deletion src/render_engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -447,7 +447,7 @@ void RenderEngine::debugHdr(unsigned& ddaFormat, int& colorSpace, int& bitsPerCo
ddaFormat = s_->ddaFormat; colorSpace = s_->outColorSpace; bitsPerColor = s_->outBitsPerColor;
}

bool RenderEngine::initialize(int screenW, int screenH, int zorderBand, bool hdrTonemap, bool useDComp) {
bool RenderEngine::initialize(int screenW, int screenH, int zorderBand, bool hdrTonemap, bool useDComp, int gpuPriority) {
s_->sw = screenW;
s_->sh = screenH;
s_->wantHdrTonemap = hdrTonemap; // read before recreateDupl decides the capture format
Expand Down Expand Up @@ -513,6 +513,11 @@ bool RenderEngine::initialize(int screenW, int screenH, int zorderBand, bool hdr
IDXGIDevice1* dxgiDev = nullptr;
if (FAILED(s_->device->QueryInterface(__uuidof(IDXGIDevice1), (void**)&dxgiDev))) return false;
dxgiDev->SetMaximumFrameLatency(1); // cap input-to-photon latency to ~1 frame
if (gpuPriority != 0) { // favor the magnifier on the GPU vs background apps
int p = gpuPriority < -7 ? -7 : (gpuPriority > 7 ? 7 : gpuPriority);
dxgiDev->SetGPUThreadPriority(p);
RLog("SetGPUThreadPriority(%d)", p);
}
IDXGIAdapter* adapter = nullptr;
dxgiDev->GetAdapter(&adapter);

Expand Down
3 changes: 2 additions & 1 deletion src/render_engine.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ class RenderEngine {
// useDComp: false = blt-model swapchain on the layered HWND (default, paced by DwmFlush);
// true = flip-model swapchain composed via DirectComposition (still WS_EX_LAYERED for
// click-through), paced by vsync Present. Opt-in A/B backend.
bool initialize(int screenW, int screenH, int zorderBand = 0, bool hdrTonemap = false, bool useDComp = false);
bool initialize(int screenW, int screenH, int zorderBand = 0, bool hdrTonemap = false,
bool useDComp = false, int gpuPriority = 0);
bool renderFrame(const RenderFrameParams& p); // capture (if changed) + scale + cursor + present
void setVisible(bool visible); // show/hide the overlay (hidden at 1x)
// Force the next frame to grab a fresh full-desktop capture (release+recreate the
Expand Down
5 changes: 4 additions & 1 deletion tests/test_config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,13 @@ TEST_CASE("renderer knobs have sane defaults") {
CHECK(c.dwmFlush == 1); // DwmFlush pacing on by default (the smooth path)
CHECK(c.tickHzCap == 0); // 0 = auto-detect display refresh rate
CHECK(c.present == "blt"); // blt+DwmFlush backend by default
CHECK(c.gpuPriority == 7); // favor the magnifier on the GPU by default
}
TEST_CASE("present backend selects blt or dcomp") {
TEST_CASE("present backend and gpuPriority parse") {
CHECK(ParseConfig("present=dcomp\n").present == "dcomp");
CHECK(ParseConfig("present=blt\n").present == "blt");
CHECK(ParseConfig("gpuPriority=0\n").gpuPriority == 0);
CHECK(ParseConfig("gpuPriority=-7\n").gpuPriority == -7);
}
TEST_CASE("vsync, dwmFlush, tickHzCap can be set") {
CHECK(ParseConfig("vsync=0\n").vsync == 0);
Expand Down
Loading