From 3cd152c9d59fc45a609fba4cb77958d01d6c8800 Mon Sep 17 00:00:00 2001 From: Geoffrey McRae Date: Wed, 26 Sep 2018 21:20:17 +1000 Subject: [PATCH] [host] DXGI capture improvements --- host/Capture/DXGI.cpp | 32 ++++++++++++++++++++++++-------- host/Service.cpp | 18 +++++++++++++++--- host/Service.h | 2 ++ 3 files changed, 41 insertions(+), 11 deletions(-) diff --git a/host/Capture/DXGI.cpp b/host/Capture/DXGI.cpp index 47371702..b8e7eea5 100644 --- a/host/Capture/DXGI.cpp +++ b/host/Capture/DXGI.cpp @@ -86,8 +86,18 @@ bool DXGI::Initialize(CaptureOptions * options) return false; } + DXGI_ADAPTER_DESC1 adapterDesc; + adapter->GetDesc1(&adapterDesc); + DEBUG_INFO("Device Descripion: %ls" , adapterDesc.Description); + DEBUG_INFO("Device Vendor ID : 0x%x" , adapterDesc.VendorId); + DEBUG_INFO("Device Device ID : 0x%x" , adapterDesc.DeviceId); + DEBUG_INFO("Device Video Mem : %5u MB", adapterDesc.DedicatedVideoMemory / 1048576); + DEBUG_INFO("Device Sys Mem : %5u MB", adapterDesc.DedicatedSystemMemory / 1048576); + DEBUG_INFO("Shared Sys Mem : %5u MB", adapterDesc.SharedSystemMemory / 1048576); + m_width = outputDesc.DesktopCoordinates.right - outputDesc.DesktopCoordinates.left; m_height = outputDesc.DesktopCoordinates.bottom - outputDesc.DesktopCoordinates.top; + DEBUG_INFO("Capture Size : %u x %u", m_width, m_height); done = true; break; @@ -116,7 +126,7 @@ bool DXGI::Initialize(CaptureOptions * options) D3D_FEATURE_LEVEL_9_1 }; - #if DEBUG + #ifdef _DEBUG #define CREATE_FLAGS (D3D11_CREATE_DEVICE_DEBUG) #else #define CREATE_FLAGS (0) @@ -142,6 +152,7 @@ bool DXGI::Initialize(CaptureOptions * options) return false; } + DEBUG_INFO("Feature Level : 0x%x", m_featureLevel); m_frameType = FRAME_TYPE_ARGB; for(CaptureOptions::const_iterator it = m_options->cbegin(); it != m_options->cend(); ++it) @@ -342,6 +353,8 @@ GrabStatus Capture::DXGI::GrabFrameTexture(struct FrameInfo & frame, struct Curs if (!m_initialized) return GRAB_STATUS_ERROR; + ReleaseFrame(); + timeout = false; DXGI_OUTDUPL_FRAME_INFO frameInfo; IDXGIResourcePtr res; @@ -429,9 +442,7 @@ GrabStatus Capture::DXGI::GrabFrameTexture(struct FrameInfo & frame, struct Curs if (frameInfo.LastPresentTime.QuadPart != 0) break; - // no frame data, clean up res = NULL; - ReleaseFrame(); // if the cursor has been updated if (cursor.updated) @@ -527,12 +538,17 @@ GrabStatus Capture::DXGI::GrabFrameRaw(FrameInfo & frame, struct CursorInfo & cu DeInitialize(); return GRAB_STATUS_ERROR; } + + frame.pitch = m_width * 4; + frame.stride = m_width; + + for(unsigned int y = 0; y < m_height; ++y) + memcpySSE( + (uint32_t*)frame.buffer + (m_width * y), + (uint8_t *)mapping.pData + (mapping.RowPitch * y), + m_width * 4 + ); - frame.pitch = mapping.RowPitch; - frame.stride = mapping.RowPitch >> 2; - - const unsigned int size = m_height * mapping.RowPitch; - memcpySSE(frame.buffer, mapping.pData, LG_MIN(size, frame.bufferSize)); m_deviceContext->Unmap(m_texture[0], 0); return GRAB_STATUS_OK; diff --git a/host/Service.cpp b/host/Service.cpp index d2830713..4e9ea4f3 100644 --- a/host/Service.cpp +++ b/host/Service.cpp @@ -51,6 +51,7 @@ bool Service::Initialize(ICapture * captureDevice) if (m_initialized) DeInitialize(); + m_tryTarget = 0; m_capture = captureDevice; if (!m_ivshmem->Initialize()) { @@ -171,6 +172,7 @@ bool Service::Process() return false; volatile uint8_t *flags = &m_shmHeader->flags; + int tryCount = 0; // wait for the host to notify that is it is ready to proceed while (true) @@ -187,7 +189,7 @@ bool Service::Process() if (m_capture->GetMaxFrameSize() > m_frameSize) { - DEBUG_ERROR("Maximum frame size of %zd bytes excceds maximum space available", m_capture->GetMaxFrameSize()); + DEBUG_ERROR("Maximum frame size of %zd bytes exceeds maximum space available", m_capture->GetMaxFrameSize()); return false; } @@ -199,10 +201,20 @@ bool Service::Process() if (!(m_shmHeader->frame.flags & KVMFR_FRAME_FLAG_UPDATE)) break; - // wait for 2ms before polling again - Sleep(2); + // save CPU if the client has stopped polling for updates + if (++tryCount > m_tryTarget * 400) + { + m_tryTarget = 250; + Sleep(100); + } } + int diff = (tryCount - m_lastTryCount) / 200; + m_lastTryCount = tryCount; + m_tryTarget += diff; + if (m_tryTarget < 250) + m_tryTarget = 250; + struct FrameInfo frame = {0}; struct CursorInfo cursor = {0}; frame.buffer = m_frame[m_frameIndex]; diff --git a/host/Service.h b/host/Service.h index 9fc85585..05cf49d7 100644 --- a/host/Service.h +++ b/host/Service.h @@ -46,6 +46,8 @@ private: bool InitPointers(); static Service * m_instance; + int m_tryTarget; + int m_lastTryCount; Service(); ~Service();