mirror of
https://github.com/gnif/LookingGlass.git
synced 2024-11-25 23:07:18 +00:00
[host] dxgi: re-send the last frame if capture times out
This change prevents the guest from stalling on startup if there are no frames being captured
This commit is contained in:
parent
758b7af754
commit
7c5b2b5c1c
@ -31,6 +31,7 @@ DXGI::DXGI() :
|
|||||||
m_deviceContext(),
|
m_deviceContext(),
|
||||||
m_dup(),
|
m_dup(),
|
||||||
m_texture(),
|
m_texture(),
|
||||||
|
m_surface(),
|
||||||
m_pointer(NULL)
|
m_pointer(NULL)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -190,6 +191,15 @@ void DXGI::DeInitialize()
|
|||||||
m_pointerBufSize = 0;
|
m_pointerBufSize = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_surfaceMapped)
|
||||||
|
{
|
||||||
|
m_surface->Unmap();
|
||||||
|
m_surfaceMapped = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_surface)
|
||||||
|
m_surface.Release();
|
||||||
|
|
||||||
if (m_texture)
|
if (m_texture)
|
||||||
m_texture.Release();
|
m_texture.Release();
|
||||||
|
|
||||||
@ -241,7 +251,22 @@ GrabStatus DXGI::GrabFrame(FrameInfo & frame)
|
|||||||
{
|
{
|
||||||
while(true)
|
while(true)
|
||||||
{
|
{
|
||||||
status = m_dup->AcquireNextFrame(INFINITE, &frameInfo, &res);
|
status = m_dup->AcquireNextFrame(1000, &frameInfo, &res);
|
||||||
|
if (status == DXGI_ERROR_WAIT_TIMEOUT)
|
||||||
|
{
|
||||||
|
if (!m_surfaceMapped)
|
||||||
|
break;
|
||||||
|
|
||||||
|
// send the last frame again if we timeout to prevent the client stalling on restart
|
||||||
|
frame.width = m_desc.Width;
|
||||||
|
frame.height = m_desc.Height;
|
||||||
|
frame.stride = m_rect.Pitch / 4;
|
||||||
|
|
||||||
|
unsigned int size = m_height * m_rect.Pitch;
|
||||||
|
memcpySSE(frame.buffer, m_rect.pBits, size < frame.bufferSize ? size : frame.bufferSize);
|
||||||
|
return GRAB_STATUS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
if (!SUCCEEDED(status))
|
if (!SUCCEEDED(status))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -371,8 +396,7 @@ GrabStatus DXGI::GrabFrame(FrameInfo & frame)
|
|||||||
return GRAB_STATUS_ERROR;
|
return GRAB_STATUS_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
D3D11_TEXTURE2D_DESC desc;
|
src->GetDesc(&m_desc);
|
||||||
src->GetDesc(&desc);
|
|
||||||
|
|
||||||
m_deviceContext->CopyResource(m_texture, src);
|
m_deviceContext->CopyResource(m_texture, src);
|
||||||
|
|
||||||
@ -380,38 +404,42 @@ GrabStatus DXGI::GrabFrame(FrameInfo & frame)
|
|||||||
res.Release();
|
res.Release();
|
||||||
src.Release();
|
src.Release();
|
||||||
|
|
||||||
IDXGISurface1Ptr surface(m_texture);
|
if (m_surfaceMapped)
|
||||||
if (!surface)
|
{
|
||||||
|
status = m_surface->Unmap();
|
||||||
|
if (FAILED(status))
|
||||||
|
{
|
||||||
|
DEBUG_ERROR("Failed to unmap surface: %08x", (int)status);
|
||||||
|
return GRAB_STATUS_ERROR;
|
||||||
|
}
|
||||||
|
m_surfaceMapped = false;
|
||||||
|
m_surface.Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_surface = m_texture;
|
||||||
|
if (!m_surface)
|
||||||
{
|
{
|
||||||
DEBUG_ERROR("Failed to get IDXGISurface1");
|
DEBUG_ERROR("Failed to get IDXGISurface1");
|
||||||
return GRAB_STATUS_ERROR;
|
return GRAB_STATUS_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
DXGI_MAPPED_RECT rect;
|
status = m_surface->Map(&m_rect, DXGI_MAP_READ);
|
||||||
status = surface->Map(&rect, DXGI_MAP_READ);
|
|
||||||
if (FAILED(status))
|
if (FAILED(status))
|
||||||
{
|
{
|
||||||
DEBUG_ERROR("Failed to map surface: %08x", (int)status);
|
DEBUG_ERROR("Failed to map surface: %08x", (int)status);
|
||||||
return GRAB_STATUS_ERROR;
|
return GRAB_STATUS_ERROR;
|
||||||
}
|
}
|
||||||
|
m_surfaceMapped = true;
|
||||||
|
|
||||||
m_width = desc.Width;
|
m_width = m_desc.Width;
|
||||||
m_height = desc.Height;
|
m_height = m_desc.Height;
|
||||||
|
|
||||||
frame.width = desc.Width;
|
frame.width = m_desc.Width;
|
||||||
frame.height = desc.Height;
|
frame.height = m_desc.Height;
|
||||||
frame.stride = rect.Pitch / 4;
|
frame.stride = m_rect.Pitch / 4;
|
||||||
|
|
||||||
unsigned int size = m_height * rect.Pitch;
|
unsigned int size = m_height * m_rect.Pitch;
|
||||||
memcpySSE(frame.buffer, rect.pBits, size < frame.bufferSize ? size : frame.bufferSize);
|
memcpySSE(frame.buffer, m_rect.pBits, size < frame.bufferSize ? size : frame.bufferSize);
|
||||||
|
|
||||||
status = surface->Unmap();
|
|
||||||
|
|
||||||
if (FAILED(status))
|
|
||||||
{
|
|
||||||
DEBUG_ERROR("Failed to unmap surface: %08x", (int)status);
|
|
||||||
return GRAB_STATUS_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
return GRAB_STATUS_OK;
|
return GRAB_STATUS_OK;
|
||||||
}
|
}
|
@ -80,6 +80,10 @@ namespace Capture
|
|||||||
IDXGIOutput1Ptr m_output;
|
IDXGIOutput1Ptr m_output;
|
||||||
IDXGIOutputDuplicationPtr m_dup;
|
IDXGIOutputDuplicationPtr m_dup;
|
||||||
ID3D11Texture2DPtr m_texture;
|
ID3D11Texture2DPtr m_texture;
|
||||||
|
IDXGISurface1Ptr m_surface;
|
||||||
|
D3D11_TEXTURE2D_DESC m_desc;
|
||||||
|
DXGI_MAPPED_RECT m_rect;
|
||||||
|
bool m_surfaceMapped;
|
||||||
BYTE * m_pointer;
|
BYTE * m_pointer;
|
||||||
UINT m_pointerBufSize;
|
UINT m_pointerBufSize;
|
||||||
UINT m_pointerSize;
|
UINT m_pointerSize;
|
||||||
|
Loading…
Reference in New Issue
Block a user