[client] dxgi: persistant map the texture memory

This commit is contained in:
Geoffrey McRae 2017-12-18 17:18:37 +11:00
parent 9e75c7ab34
commit e298f9169c
2 changed files with 31 additions and 46 deletions

View file

@ -31,7 +31,6 @@ DXGI::DXGI() :
m_deviceContext(), m_deviceContext(),
m_dup(), m_dup(),
m_texture(), m_texture(),
m_surface(),
m_pointer(NULL) m_pointer(NULL)
{ {
} }
@ -139,6 +138,16 @@ bool DXGI::Initialize(CaptureOptions * options)
return false; return false;
} }
IDXGIDevicePtr dxgi;
if (FAILED(m_device->QueryInterface(__uuidof(IDXGIDevice), (void **)&dxgi)))
{
DEBUG_ERROR("Failed to obtain the IDXGIDevice interface from the D3D11 device");
DeInitialize();
return false;
}
dxgi->SetGPUThreadPriority(7);
// we try this twice just incase we still get an error // we try this twice just incase we still get an error
// on re-initialization // on re-initialization
for(int i = 0; i < 2; ++i) for(int i = 0; i < 2; ++i)
@ -178,6 +187,15 @@ bool DXGI::Initialize(CaptureOptions * options)
return false; return false;
} }
status = m_deviceContext->Map(m_texture, 0, D3D11_MAP_READ, 0, &m_mapping);
if (FAILED(status))
{
DEBUG_ERROR("Failed to map the texture: %08x", (int)status);
DeInitialize();
return false;
}
m_surfaceMapped = true;
m_initialized = true; m_initialized = true;
return true; return true;
} }
@ -199,13 +217,10 @@ void DXGI::DeInitialize()
if (m_surfaceMapped) if (m_surfaceMapped)
{ {
m_surface->Unmap(); m_deviceContext->Unmap(m_texture, 0);
m_surfaceMapped = false; m_surfaceMapped = false;
} }
if (m_surface)
m_surface.Release();
if (m_texture) if (m_texture)
m_texture.Release(); m_texture.Release();
@ -299,11 +314,11 @@ GrabStatus DXGI::GrabFrame(FrameInfo & frame)
// send the last frame again if we timeout to prevent the client stalling on restart // send the last frame again if we timeout to prevent the client stalling on restart
frame.width = m_desc.Width; frame.width = m_desc.Width;
frame.height = m_desc.Height; frame.height = m_desc.Height;
frame.pitch = m_rect.Pitch; frame.pitch = m_mapping.RowPitch;
frame.stride = m_rect.Pitch / 4; frame.stride = m_mapping.RowPitch / 4;
unsigned int size = m_height * m_rect.Pitch; unsigned int size = m_height * m_mapping.RowPitch;
memcpySSE(frame.buffer, m_rect.pBits, size < frame.bufferSize ? size : frame.bufferSize); memcpySSE(frame.buffer, m_mapping.pData, size < frame.bufferSize ? size : frame.bufferSize);
return GRAB_STATUS_OK; return GRAB_STATUS_OK;
} }
@ -410,6 +425,7 @@ GrabStatus DXGI::GrabFrame(FrameInfo & frame)
} }
ID3D11Texture2DPtr src(res); ID3D11Texture2DPtr src(res);
res.Release();
if (!src) if (!src)
{ {
DEBUG_ERROR("Failed to get src ID3D11Texture2D"); DEBUG_ERROR("Failed to get src ID3D11Texture2D");
@ -417,49 +433,19 @@ GrabStatus DXGI::GrabFrame(FrameInfo & frame)
} }
src->GetDesc(&m_desc); src->GetDesc(&m_desc);
m_deviceContext->CopyResource(m_texture, src); m_deviceContext->CopyResource(m_texture, src);
res.Release();
src.Release(); src.Release();
if (m_surfaceMapped)
{
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");
return GRAB_STATUS_ERROR;
}
status = m_surface->Map(&m_rect, DXGI_MAP_READ);
if (FAILED(status))
{
DEBUG_ERROR("Failed to map surface: %08x", (int)status);
return GRAB_STATUS_ERROR;
}
m_surfaceMapped = true;
m_width = m_desc.Width; m_width = m_desc.Width;
m_height = m_desc.Height; m_height = m_desc.Height;
frame.width = m_desc.Width; frame.width = m_desc.Width;
frame.height = m_desc.Height; frame.height = m_desc.Height;
frame.pitch = m_rect.Pitch; frame.pitch = m_mapping.RowPitch;
frame.stride = m_rect.Pitch / 4; frame.stride = m_mapping.RowPitch / 4;
unsigned int size = m_height * m_rect.Pitch; unsigned int size = m_height * m_mapping.RowPitch;
memcpySSE(frame.buffer, m_rect.pBits, size < frame.bufferSize ? size : frame.bufferSize); memcpySSE(frame.buffer, m_mapping.pData, size < frame.bufferSize ? size : frame.bufferSize);
return GRAB_STATUS_OK; return GRAB_STATUS_OK;
} }

View file

@ -31,13 +31,13 @@ Place, Suite 330, Boston, MA 02111-1307 USA
_COM_SMARTPTR_TYPEDEF(IDXGIFactory1 , __uuidof(IDXGIFactory1 )); _COM_SMARTPTR_TYPEDEF(IDXGIFactory1 , __uuidof(IDXGIFactory1 ));
_COM_SMARTPTR_TYPEDEF(ID3D11Device , __uuidof(ID3D11Device )); _COM_SMARTPTR_TYPEDEF(ID3D11Device , __uuidof(ID3D11Device ));
_COM_SMARTPTR_TYPEDEF(ID3D11DeviceContext , __uuidof(ID3D11DeviceContext )); _COM_SMARTPTR_TYPEDEF(ID3D11DeviceContext , __uuidof(ID3D11DeviceContext ));
_COM_SMARTPTR_TYPEDEF(IDXGIDevice , __uuidof(IDXGIDevice ));
_COM_SMARTPTR_TYPEDEF(IDXGIOutput1 , __uuidof(IDXGIOutput1 )); _COM_SMARTPTR_TYPEDEF(IDXGIOutput1 , __uuidof(IDXGIOutput1 ));
_COM_SMARTPTR_TYPEDEF(IDXGIOutput , __uuidof(IDXGIOutput )); _COM_SMARTPTR_TYPEDEF(IDXGIOutput , __uuidof(IDXGIOutput ));
_COM_SMARTPTR_TYPEDEF(IDXGIAdapter1 , __uuidof(IDXGIAdapter1 )); _COM_SMARTPTR_TYPEDEF(IDXGIAdapter1 , __uuidof(IDXGIAdapter1 ));
_COM_SMARTPTR_TYPEDEF(IDXGIOutputDuplication, __uuidof(IDXGIOutputDuplication)); _COM_SMARTPTR_TYPEDEF(IDXGIOutputDuplication, __uuidof(IDXGIOutputDuplication));
_COM_SMARTPTR_TYPEDEF(ID3D11Texture2D , __uuidof(ID3D11Texture2D )); _COM_SMARTPTR_TYPEDEF(ID3D11Texture2D , __uuidof(ID3D11Texture2D ));
_COM_SMARTPTR_TYPEDEF(IDXGIResource , __uuidof(IDXGIResource )); _COM_SMARTPTR_TYPEDEF(IDXGIResource , __uuidof(IDXGIResource ));
_COM_SMARTPTR_TYPEDEF(IDXGISurface1 , __uuidof(IDXGISurface1 ));
namespace Capture namespace Capture
{ {
@ -83,9 +83,8 @@ namespace Capture
IDXGIOutputDuplicationPtr m_dup; IDXGIOutputDuplicationPtr m_dup;
bool m_releaseFrame; bool m_releaseFrame;
ID3D11Texture2DPtr m_texture; ID3D11Texture2DPtr m_texture;
IDXGISurface1Ptr m_surface;
D3D11_TEXTURE2D_DESC m_desc; D3D11_TEXTURE2D_DESC m_desc;
DXGI_MAPPED_RECT m_rect; D3D11_MAPPED_SUBRESOURCE m_mapping;
bool m_surfaceMapped; bool m_surfaceMapped;
BYTE * m_pointer; BYTE * m_pointer;
UINT m_pointerBufSize; UINT m_pointerBufSize;