fix: #75 GDXI screenshot crashes when screen is off
This commit is contained in:
@@ -40,64 +40,76 @@ 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;
|
|
||||||
d3dDevice->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgiDevice);
|
|
||||||
|
|
||||||
// 3. <20><>ȡ DXGI <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
||||||
IDXGIAdapter* dxgiAdapter = nullptr;
|
IDXGIAdapter* dxgiAdapter = nullptr;
|
||||||
dxgiDevice->GetAdapter(&dxgiAdapter);
|
|
||||||
|
|
||||||
// 4. <20><>ȡ DXGI <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ļ<EFBFBD><C4BB>
|
|
||||||
IDXGIOutput* dxgiOutput = nullptr;
|
IDXGIOutput* dxgiOutput = nullptr;
|
||||||
dxgiAdapter->EnumOutputs(0, &dxgiOutput);
|
|
||||||
|
|
||||||
// 5. <20><>ȡ DXGI <20><><EFBFBD><EFBFBD> 1
|
|
||||||
IDXGIOutput1* dxgiOutput1 = nullptr;
|
IDXGIOutput1* dxgiOutput1 = nullptr;
|
||||||
dxgiOutput->QueryInterface(__uuidof(IDXGIOutput1), (void**)&dxgiOutput1);
|
|
||||||
|
|
||||||
// 6. <20><><EFBFBD><EFBFBD> Desktop Duplication
|
do {
|
||||||
dxgiOutput1->DuplicateOutput(d3dDevice, &deskDupl);
|
// 2. <20><>ȡ DXGI <20>豸
|
||||||
|
d3dDevice->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgiDevice);
|
||||||
|
if(!dxgiDevice)break;
|
||||||
|
|
||||||
// 7. <20><>ȡ<EFBFBD><C8A1>Ļ<EFBFBD><EFBFBD>С
|
// 3. <20><>ȡ DXGI <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
DXGI_OUTDUPL_DESC duplDesc;
|
dxgiDevice->GetAdapter(&dxgiAdapter);
|
||||||
deskDupl->GetDesc(&duplDesc);
|
if (!dxgiAdapter)break;
|
||||||
m_ulFullWidth = duplDesc.ModeDesc.Width;
|
|
||||||
m_ulFullHeight = duplDesc.ModeDesc.Height;
|
|
||||||
|
|
||||||
// 8. <20><><EFBFBD><EFBFBD> CPU <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
// 4. <20><>ȡ DXGI <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ļ<EFBFBD><EFBFBD>
|
||||||
D3D11_TEXTURE2D_DESC desc = {};
|
dxgiAdapter->EnumOutputs(0, &dxgiOutput);
|
||||||
desc.Width = m_ulFullWidth;
|
if (!dxgiOutput)break;
|
||||||
desc.Height = m_ulFullHeight;
|
|
||||||
desc.MipLevels = 1;
|
|
||||||
desc.ArraySize = 1;
|
|
||||||
desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
|
|
||||||
desc.SampleDesc.Count = 1;
|
|
||||||
desc.Usage = D3D11_USAGE_STAGING;
|
|
||||||
desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
|
|
||||||
d3dDevice->CreateTexture2D(&desc, NULL, &cpuTexture);
|
|
||||||
|
|
||||||
// 9. <20><>ʼ<EFBFBD><EFBFBD> BITMAPINFO
|
// 5. <20><>ȡ DXGI <20><><EFBFBD><EFBFBD> 1
|
||||||
m_BitmapInfor_Full = (BITMAPINFO*)new char[sizeof(BITMAPINFO)];
|
dxgiOutput->QueryInterface(__uuidof(IDXGIOutput1), (void**)&dxgiOutput1);
|
||||||
memset(m_BitmapInfor_Full, 0, sizeof(BITMAPINFO));
|
if (!dxgiOutput1)break;
|
||||||
m_BitmapInfor_Full->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
|
||||||
m_BitmapInfor_Full->bmiHeader.biWidth = m_ulFullWidth;
|
|
||||||
m_BitmapInfor_Full->bmiHeader.biHeight = m_ulFullHeight;
|
|
||||||
m_BitmapInfor_Full->bmiHeader.biPlanes = 1;
|
|
||||||
m_BitmapInfor_Full->bmiHeader.biBitCount = 32;
|
|
||||||
m_BitmapInfor_Full->bmiHeader.biCompression = BI_RGB;
|
|
||||||
m_BitmapInfor_Full->bmiHeader.biSizeImage = m_ulFullWidth * m_ulFullHeight * 4;
|
|
||||||
|
|
||||||
// 10. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
// 6. <20><><EFBFBD><EFBFBD> Desktop Duplication
|
||||||
m_FirstBuffer = new BYTE[m_BitmapInfor_Full->bmiHeader.biSizeImage + 1];
|
dxgiOutput1->DuplicateOutput(d3dDevice, &deskDupl);
|
||||||
m_NextBuffer = new BYTE[m_BitmapInfor_Full->bmiHeader.biSizeImage + 1];
|
if (!deskDupl)break;
|
||||||
m_RectBuffer = new BYTE[m_BitmapInfor_Full->bmiHeader.biSizeImage * 2 + 12];
|
|
||||||
|
// 7. <20><>ȡ<EFBFBD><C8A1>Ļ<EFBFBD><C4BB>С
|
||||||
|
DXGI_OUTDUPL_DESC duplDesc;
|
||||||
|
deskDupl->GetDesc(&duplDesc);
|
||||||
|
m_ulFullWidth = duplDesc.ModeDesc.Width;
|
||||||
|
m_ulFullHeight = duplDesc.ModeDesc.Height;
|
||||||
|
|
||||||
|
// 8. <20><><EFBFBD><EFBFBD> CPU <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
D3D11_TEXTURE2D_DESC desc = {};
|
||||||
|
desc.Width = m_ulFullWidth;
|
||||||
|
desc.Height = m_ulFullHeight;
|
||||||
|
desc.MipLevels = 1;
|
||||||
|
desc.ArraySize = 1;
|
||||||
|
desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
|
||||||
|
desc.SampleDesc.Count = 1;
|
||||||
|
desc.Usage = D3D11_USAGE_STAGING;
|
||||||
|
desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
|
||||||
|
d3dDevice->CreateTexture2D(&desc, NULL, &cpuTexture);
|
||||||
|
|
||||||
|
// 9. <20><>ʼ<EFBFBD><CABC> BITMAPINFO
|
||||||
|
m_BitmapInfor_Full = (BITMAPINFO*)new char[sizeof(BITMAPINFO)];
|
||||||
|
memset(m_BitmapInfor_Full, 0, sizeof(BITMAPINFO));
|
||||||
|
m_BitmapInfor_Full->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
||||||
|
m_BitmapInfor_Full->bmiHeader.biWidth = m_ulFullWidth;
|
||||||
|
m_BitmapInfor_Full->bmiHeader.biHeight = m_ulFullHeight;
|
||||||
|
m_BitmapInfor_Full->bmiHeader.biPlanes = 1;
|
||||||
|
m_BitmapInfor_Full->bmiHeader.biBitCount = 32;
|
||||||
|
m_BitmapInfor_Full->bmiHeader.biCompression = BI_RGB;
|
||||||
|
m_BitmapInfor_Full->bmiHeader.biSizeImage = m_ulFullWidth * m_ulFullHeight * 4;
|
||||||
|
|
||||||
|
// 10. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ļ<EFBFBD><C4BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
m_FirstBuffer = 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];
|
||||||
|
} 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() {
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user