void D3D10Grab(ID3D10Texture2D* pBackBuffer) { D3D10_TEXTURE2D_DESC tex_desc; pBackBuffer->GetDesc(&tex_desc); ID3D10Device *pDev; pBackBuffer->GetDevice(&pDev); ID3D10Texture2D * pTexture; D3D10_MAPPED_TEXTURE2D mappedTexture; tex_desc.CPUAccessFlags = D3D10_CPU_ACCESS_READ; tex_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; tex_desc.ArraySize = 1; tex_desc.MipLevels = 1; tex_desc.BindFlags = 0; tex_desc.SampleDesc.Count = 1; tex_desc.SampleDesc.Quality = 0; tex_desc.Usage = D3D10_USAGE_STAGING; tex_desc.MiscFlags = 0; HRESULT hr = pDev->CreateTexture2D(&tex_desc, NULL, &pTexture); #ifdef DEBUG reportLog(EVENTLOG_INFORMATION_TYPE, L"pDev->CreateTexture2D 0x%x", hr); #endif pDev->CopyResource(pTexture, pBackBuffer); D3D10_BOX box = {0, 0, tex_desc.Width, tex_desc.Height, 0, 1}; pDev->CopySubresourceRegion(pTexture, 0, 0, 0, 0, pBackBuffer, 0, &box); DxgiFrameGrabber *dxgiFrameGrabber = DxgiFrameGrabber::getInstance(); IPCContext *ipcContext = dxgiFrameGrabber->m_ipcContext; Logger *logger = dxgiFrameGrabber->m_logger; if (S_OK != (hr = pTexture->Map(D3D10CalcSubresource(0, 0, 1), D3D10_MAP_READ, 0, &mappedTexture))) { logger->reportLogError(L"d3d10 couldn't map texture, hresult = 0x%x", hr); goto end; } ipcContext->m_memDesc.width = tex_desc.Width; ipcContext->m_memDesc.height = tex_desc.Height; ipcContext->m_memDesc.rowPitch = mappedTexture.RowPitch; ipcContext->m_memDesc.format = BufferFormatAbgr; ipcContext->m_memDesc.frameId++; // reportLog(EVENTLOG_INFORMATION_TYPE, L"d3d10 texture description. width: %u, height: %u, pitch: %u", tex_desc.Width, tex_desc.Height, mappedTexture.RowPitch); DWORD errorcode; if (WAIT_OBJECT_0 == (errorcode = WaitForSingleObject(ipcContext->m_hMutex, 0))) { // __asm__("int $3"); // reportLog(EVENTLOG_INFORMATION_TYPE, L"d3d10 writing description to mem mapped file"); memcpy(ipcContext->m_pMemMap, &ipcContext->m_memDesc, sizeof (ipcContext->m_memDesc)); // reportLog(EVENTLOG_INFORMATION_TYPE, L"d3d10 writing data to mem mapped file"); PVOID pMemDataMap = incPtr(ipcContext->m_pMemMap, sizeof (ipcContext->m_memDesc)); if (mappedTexture.RowPitch == tex_desc.Width * 4) { memcpy(pMemDataMap, mappedTexture.pData, tex_desc.Width * tex_desc.Height * 4); } else { UINT cleanOffset = 0, pitchOffset = 0, i = 0; while (i < tex_desc.Height) { memcpy(incPtr(pMemDataMap, cleanOffset), incPtr(mappedTexture.pData, pitchOffset), tex_desc.Width * 4); cleanOffset += tex_desc.Width * 4; pitchOffset += mappedTexture.RowPitch; i++; } } ReleaseMutex(ipcContext->m_hMutex); SetEvent(ipcContext->m_hFrameGrabbedEvent); } else { logger->reportLogError(L"d3d10 couldn't wait mutex. errocode = 0x%x", errorcode); } pTexture->Unmap(D3D10CalcSubresource(0, 0, 1)); end: pTexture->Release(); pDev->Release(); }
HRESULT WINAPI D3D9Present(IDirect3DDevice9 *pDev, CONST RECT* pSourceRect,CONST RECT* pDestRect,HWND hDestWindowOverride,CONST RGNDATA* pDirtyRegion) { D3D9FrameGrabber *d3d9FrameGrabber = D3D9FrameGrabber::getInstance(); Logger *logger = d3d9FrameGrabber->m_logger; DWORD errorcode; if (WAIT_OBJECT_0 == (errorcode = WaitForSingleObject(d3d9FrameGrabber->m_syncRunMutex, 0))) { IPCContext *ipcContext = d3d9FrameGrabber->m_ipcContext; logger->reportLogDebug(L"D3D9Present"); HRESULT hRes; RECT newRect = RECT(); IDirect3DSurface9 *pBackBuffer = NULL; IDirect3DSurface9 *pDemultisampledSurf = NULL; IDirect3DSurface9 *pOffscreenSurf = NULL; IDirect3DSwapChain9 *pSc = NULL; D3DPRESENT_PARAMETERS params; if(FAILED( hRes = pDev->GetSwapChain(0, &pSc))) { logger->reportLogError(L"d3d9present couldn't get swapchain. result 0x%x", hRes); goto end; } hRes = pSc->GetPresentParameters(¶ms); if (FAILED(hRes) || params.Windowed) { goto end; } if(FAILED( hRes = pDev->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer))) { goto end; } D3DSURFACE_DESC surfDesc; pBackBuffer->GetDesc(&surfDesc); hRes = pDev->CreateRenderTarget( surfDesc.Width, surfDesc.Height, surfDesc.Format, D3DMULTISAMPLE_NONE, 0, false, &pDemultisampledSurf, NULL ); if (FAILED(hRes)) { logger->reportLogError(L"GetFramePrep: FAILED to create demultisampled render target. 0x%x, width=%u, height=%u, format=%x", hRes, surfDesc.Width, surfDesc.Height, surfDesc.Format ); goto end; } hRes = pDev->StretchRect(pBackBuffer, NULL, pDemultisampledSurf, NULL, D3DTEXF_LINEAR ); if (FAILED(hRes)) { logger->reportLogError(L"GetFramePrep: StretchRect FAILED for image surfacee. 0x%x, width=%u, height=%u, format=%x", hRes, surfDesc.Width, surfDesc.Height, surfDesc.Format ); goto end; } hRes = pDev->CreateOffscreenPlainSurface( surfDesc.Width, surfDesc.Height, surfDesc.Format, D3DPOOL_SYSTEMMEM, &pOffscreenSurf, NULL ); if (FAILED(hRes)) { logger->reportLogError(L"GetFramePrep: FAILED to create image surface. 0x%x, width=%u, height=%u, format=%x", hRes, surfDesc.Width, surfDesc.Height, surfDesc.Format ); goto end; } hRes = pDev->GetRenderTargetData(pDemultisampledSurf, pOffscreenSurf ); if (FAILED(hRes)) { logger->reportLogError(L"GetFramePrep: GetRenderTargetData() FAILED for image surfacee. 0x%x, width=%u, height=%u, format=%x", hRes, surfDesc.Width, surfDesc.Height, surfDesc.Format ); goto end; } D3DLOCKED_RECT lockedSrcRect; newRect.right = surfDesc.Width; newRect.bottom = surfDesc.Height; hRes = pOffscreenSurf->LockRect( &lockedSrcRect, &newRect, 0); if (FAILED(hRes)) { logger->reportLogError(L"GetFramePrep: FAILED to lock source rect. (0x%x)", hRes ); goto end; } ipcContext->m_memDesc.width = surfDesc.Width; ipcContext->m_memDesc.height = surfDesc.Height; ipcContext->m_memDesc.rowPitch = lockedSrcRect.Pitch; ipcContext->m_memDesc.frameId++; ipcContext->m_memDesc.format = getCompatibleBufferFormat(surfDesc.Format); DWORD errorcode; if (WAIT_OBJECT_0 == (errorcode = WaitForSingleObject(ipcContext->m_hMutex, 0))) { // reportLog(EVENTLOG_INFORMATION_TYPE, L"d3d9 writing description to mem mapped file"); memcpy(ipcContext->m_pMemMap, &(ipcContext->m_memDesc), sizeof (ipcContext->m_memDesc)); // reportLog(EVENTLOG_INFORMATION_TYPE, L"d3d9 writing data to mem mapped file"); PVOID pMemDataMap = incPtr(ipcContext->m_pMemMap, sizeof (ipcContext->m_memDesc)); if (static_cast<UINT>(lockedSrcRect.Pitch) == surfDesc.Width * 4) { memcpy(pMemDataMap, lockedSrcRect.pBits, surfDesc.Width * surfDesc.Height * 4); } else { UINT i = 0, cleanOffset = 0, pitchOffset = 0; while (i < surfDesc.Height) { memcpy(incPtr(pMemDataMap, cleanOffset), incPtr(lockedSrcRect.pBits, pitchOffset), surfDesc.Width * 4); cleanOffset += surfDesc.Width * 4; pitchOffset += lockedSrcRect.Pitch; i++; } } ReleaseMutex(ipcContext->m_hMutex); SetEvent(ipcContext->m_hFrameGrabbedEvent); } else { logger->reportLogError(L"d3d9 couldn't wait mutex. errocode = 0x%x", errorcode); } end: if(pOffscreenSurf) pOffscreenSurf->Release(); if(pDemultisampledSurf) pDemultisampledSurf->Release(); if(pBackBuffer) pBackBuffer->Release(); if(pSc) pSc->Release(); ProxyFuncJmp *d3d9PresentProxyFuncJmp = d3d9FrameGrabber->m_d3d9PresentProxyFuncJmp; if(!d3d9PresentProxyFuncJmp->removeHook()) { int i = GetLastError(); logger->reportLogError(L"d3d9 error occured while trying to removeHook before original call0x%x", i); } HRESULT result = pDev->Present(pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion); if(!d3d9PresentProxyFuncJmp->installHook()) { int i = GetLastError(); logger->reportLogError(L"d3d9 error occured while trying to installHook after original call0x%x", i); } ReleaseMutex(d3d9FrameGrabber->m_syncRunMutex); return result; } else { logger->reportLogError(L"d3d9sc present is skipped because mutex is busy"); return S_FALSE; } }