fix: #75 GDXI screenshot crashes when screen is off

This commit is contained in:
yuanyuanxiang
2025-04-07 14:21:42 +08:00
parent 2d54b0f63d
commit db76967a37
2 changed files with 76 additions and 49 deletions

View File

@@ -40,24 +40,31 @@ public:
// 1. <20><><EFBFBD><EFBFBD> D3D11 <20> // 1. <20><><EFBFBD><EFBFBD> D3D11 <20>
D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, nullptr, 0, D3D11_SDK_VERSION, &d3dDevice, nullptr, &d3dContext); D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, nullptr, 0, D3D11_SDK_VERSION, &d3dDevice, nullptr, &d3dContext);
// 2. <20><>ȡ DXGI <20>
IDXGIDevice * dxgiDevice = nullptr; IDXGIDevice * dxgiDevice = nullptr;
IDXGIAdapter* dxgiAdapter = nullptr;
IDXGIOutput* dxgiOutput = nullptr;
IDXGIOutput1* dxgiOutput1 = nullptr;
do {
// 2. <20><>ȡ DXGI <20>
d3dDevice->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgiDevice); d3dDevice->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgiDevice);
if(!dxgiDevice)break;
// 3. <20><>ȡ DXGI <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // 3. <20><>ȡ DXGI <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
IDXGIAdapter* dxgiAdapter = nullptr;
dxgiDevice->GetAdapter(&dxgiAdapter); dxgiDevice->GetAdapter(&dxgiAdapter);
if (!dxgiAdapter)break;
// 4. <20><>ȡ DXGI <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ļ<EFBFBD><C4BB> // 4. <20><>ȡ DXGI <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ļ<EFBFBD><C4BB>
IDXGIOutput* dxgiOutput = nullptr;
dxgiAdapter->EnumOutputs(0, &dxgiOutput); dxgiAdapter->EnumOutputs(0, &dxgiOutput);
if (!dxgiOutput)break;
// 5. <20><>ȡ DXGI <20><><EFBFBD><EFBFBD> 1 // 5. <20><>ȡ DXGI <20><><EFBFBD><EFBFBD> 1
IDXGIOutput1* dxgiOutput1 = nullptr;
dxgiOutput->QueryInterface(__uuidof(IDXGIOutput1), (void**)&dxgiOutput1); dxgiOutput->QueryInterface(__uuidof(IDXGIOutput1), (void**)&dxgiOutput1);
if (!dxgiOutput1)break;
// 6. <20><><EFBFBD><EFBFBD> Desktop Duplication // 6. <20><><EFBFBD><EFBFBD> Desktop Duplication
dxgiOutput1->DuplicateOutput(d3dDevice, &deskDupl); dxgiOutput1->DuplicateOutput(d3dDevice, &deskDupl);
if (!deskDupl)break;
// 7. <20><>ȡ<EFBFBD><C8A1>Ļ<EFBFBD><C4BB>С // 7. <20><>ȡ<EFBFBD><C8A1>Ļ<EFBFBD><C4BB>С
DXGI_OUTDUPL_DESC duplDesc; DXGI_OUTDUPL_DESC duplDesc;
@@ -92,12 +99,17 @@ public:
m_FirstBuffer = new BYTE[m_BitmapInfor_Full->bmiHeader.biSizeImage + 1]; m_FirstBuffer = new BYTE[m_BitmapInfor_Full->bmiHeader.biSizeImage + 1];
m_NextBuffer = new BYTE[m_BitmapInfor_Full->bmiHeader.biSizeImage + 1]; m_NextBuffer = new BYTE[m_BitmapInfor_Full->bmiHeader.biSizeImage + 1];
m_RectBuffer = new BYTE[m_BitmapInfor_Full->bmiHeader.biSizeImage * 2 + 12]; m_RectBuffer = new BYTE[m_BitmapInfor_Full->bmiHeader.biSizeImage * 2 + 12];
} while (false);
// <20>ͷ<EFBFBD> DXGI <20><>Դ // <20>ͷ<EFBFBD> DXGI <20><>Դ
dxgiOutput1->Release(); if (dxgiOutput1) dxgiOutput1->Release();
dxgiOutput->Release(); if (dxgiOutput) dxgiOutput->Release();
dxgiAdapter->Release(); if (dxgiAdapter) dxgiAdapter->Release();
dxgiDevice->Release(); if (dxgiDevice) dxgiDevice->Release();
}
bool IsInitSucceed() const {
return cpuTexture;
} }
void CleanupDXGI() { void CleanupDXGI() {

View File

@@ -57,7 +57,22 @@ CScreenManager::CScreenManager(IOCPClient* ClientObject, int n, void* user):CMan
DXGI = user; DXGI = user;
} }
Mprintf("CScreenManager: DXGI %s Algorithm: %d\n", DXGI ? "On":"Off", int(algo)); Mprintf("CScreenManager: DXGI %s Algorithm: %d\n", DXGI ? "On":"Off", int(algo));
m_ScreenSpyObject = (DXGI && IsWindows8orHigher()) ? (ScreenCapture*) new ScreenCapturerDXGI(algo) : new CScreenSpy(32, algo); if ((DXGI && IsWindows8orHigher()))
{
auto s = new ScreenCapturerDXGI(algo);
if (s->IsInitSucceed()) {
m_ScreenSpyObject = s;
}
else {
SAFE_DELETE(s);
m_ScreenSpyObject = new CScreenSpy(32, algo);
Mprintf("CScreenManager: DXGI SPY init failed!!! Using GDI instead.\n");
}
}
else
{
m_ScreenSpyObject = new CScreenSpy(32, algo);
}
m_hWorkThread = CreateThread(NULL,0, WorkThreadProc,this,0,NULL); m_hWorkThread = CreateThread(NULL,0, WorkThreadProc,this,0,NULL);
} }