In the IDD UMDF driver, how to let the bitmap captured by DXGI AcquireNextFrame skip cursor? When running Microsoft's IddDriverSample, DXGI can capture the screen picture, but there contains cursor in the picture. I want to get cursor info through AcquireNextFrame API output frameInfo.LastMouseUpdateTime.QuadPart. Thanks!
I know there's something need to be done in SwapChainProcessor::RunCore. But I can't find any guidelines.
void SwapChainProcessor::RunCore()
{
// Get the DXGI device interface
ComPtr<IDXGIDevice> DxgiDevice;
HRESULT hr = m_Device->Device.As(&DxgiDevice);
if (FAILED(hr))
{
TraceEvents(TRACE_LEVEL_ERROR,
TRACE_DRIVER,
"%!FUNC! cannot convert dxgi device %!HRESULT!",
hr);
return;
}
IDARG_IN_SWAPCHAINSETDEVICE SetDevice = {};
SetDevice.pDevice = DxgiDevice.Get();
hr = IddCxSwapChainSetDevice(m_hSwapChain, &SetDevice);
if (FAILED(hr))
{
TraceEvents(TRACE_LEVEL_ERROR,
TRACE_DRIVER,
"%!FUNC! failed, swap chain set device %!HRESULT!",
hr);
return;
}
TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, "%!FUNC! begin acquire and release buffers in a loop");
// Acquire and release buffers in a loop
for (;;)
{
ComPtr<IDXGIResource> AcquiredBuffer;
// Ask for the next buffer from the producer
IDARG_OUT_RELEASEANDACQUIREBUFFER Buffer = {};
hr = IddCxSwapChainReleaseAndAcquireBuffer(m_hSwapChain, &Buffer);
// AcquireBuffer immediately returns STATUS_PENDING if no buffer is yet available
if (hr == E_PENDING)
{
// We must wait for a new buffer
HANDLE WaitHandles [] =
{
m_hAvailableBufferEvent,
m_hTerminateEvent.Get()
};
DWORD WaitResult = WaitForMultipleObjects(ARRAYSIZE(WaitHandles), WaitHandles, FALSE, 16);
if (WaitResult == WAIT_OBJECT_0 || WaitResult == WAIT_TIMEOUT)
{
// We have a new buffer, so try the AcquireBuffer again
continue;
}
else if (WaitResult == WAIT_OBJECT_0 + 1)
{
// We need to terminate
TraceEvents(TRACE_LEVEL_RESERVED7,
TRACE_DRIVER,
"%!FUNC! Terminate");
break;
}
else
{
// The wait was cancelled or something unexpected happened
hr = HRESULT_FROM_WIN32(WaitResult);
TraceEvents(TRACE_LEVEL_RESERVED6,
TRACE_DRIVER,
"%!FUNC! The wait was cancelled or something unexpected happened %!HRESULT!",
hr);
break;
}
}
else if (SUCCEEDED(hr))
{
// We have new frame to process, the surface has a reference on it that the driver has to release
AcquiredBuffer.Attach(Buffer.MetaData.pSurface);
// ==============================
// TODO: Process the frame here
//
// This is the most performance-critical section of code in an IddCx driver. It's important that whatever
// is done with the acquired surface be finished as quickly as possible. This operation could be:
// * a GPU copy to another buffer surface for later processing (such as a staging surface for mapping to CPU memory)
// * a GPU encode operation
// * a GPU VPBlt to another surface
// * a GPU custom compute shader encode operation
// ==============================
// We have finished processing this frame hence we release the reference on it.
// If the driver forgets to release the reference to the surface, it will be leaked which results in the
// surfaces being left around after swapchain is destroyed.
// NOTE: Although in this sample we release reference to the surface here; the driver still
// owns the Buffer.MetaData.pSurface surface until IddCxSwapChainReleaseAndAcquireBuffer returns
// S_OK and gives us a new frame, a driver may want to use the surface in future to re-encode the desktop
// for better quality if there is no new frame for a while
AcquiredBuffer.Reset();
// Indicate to OS that we have finished inital processing of the frame, it is a hint that
// OS could start preparing another frame
hr = IddCxSwapChainFinishedProcessingFrame(m_hSwapChain);
if (FAILED(hr))
{
TraceEvents(TRACE_LEVEL_ERROR,
TRACE_DRIVER,
"%!FUNC! cannot finish processing frame %!HRESULT!",
hr);
break;
}
// ==============================
// TODO: Report frame statistics once the asynchronous encode/send work is completed
//
// Drivers should report information about sub-frame timings, like encode time, send time, etc.
// ==============================
// IddCxSwapChainReportFrameStatistics(m_hSwapChain, ...);
}
else
{
// The swap-chain was likely abandoned (e.g. DXGI_ERROR_ACCESS_LOST), so exit the processing loop
TraceEvents(TRACE_LEVEL_ERROR,
TRACE_DRIVER,
"%!FUNC! The swap-chain was likely abandoned %!HRESULT!",
hr);
break;
}
}
}