Beispiel #1
0
int win_shadow_dxgi_fetch_frame_data(winShadowSubsystem* subsystem,
	BYTE** ppDstData, int* pnDstStep, int x, int y, int width, int height)
{
	int status;
	HRESULT hr;
	D3D11_BOX Box;
	DXGI_MAPPED_RECT mappedRect;

	if ((width * height) < 1)
		return 0;

	Box.top = x;
	Box.left = y;
	Box.right = x + width;
	Box.bottom = y + height;
	Box.front = 0;
	Box.back = 1;

	subsystem->dxgiDeviceContext->lpVtbl->CopySubresourceRegion(subsystem->dxgiDeviceContext,
		(ID3D11Resource*) subsystem->dxgiStage, 0, 0, 0, 0, (ID3D11Resource*) subsystem->dxgiDesktopImage, 0, &Box);	 

	hr = subsystem->dxgiStage->lpVtbl->QueryInterface(subsystem->dxgiStage,
		&IID_IDXGISurface, (void**) &(subsystem->dxgiSurface));

	if (FAILED(hr))
	{
		WLog_ERR(TAG, "ID3D11Texture2D::QueryInterface(IDXGISurface) failure: %s 0x%04X",
			GetDxgiErrorString(hr), hr);
		return -1;
	}

	hr = subsystem->dxgiSurface->lpVtbl->Map(subsystem->dxgiSurface, &mappedRect, DXGI_MAP_READ);

	if (FAILED(hr))
	{
		WLog_ERR(TAG, "IDXGISurface::Map failure: %s 0x%04X",
			GetDxgiErrorString(hr), hr);

		if (hr == DXGI_ERROR_DEVICE_REMOVED)
		{
			win_shadow_dxgi_uninit(subsystem);

			status = win_shadow_dxgi_init(subsystem);

			if (status < 0)
				return -1;

			return 0;
		}

		return -1;
	}

	subsystem->dxgiSurfaceMapped = TRUE;
		
	*ppDstData = mappedRect.pBits;
	*pnDstStep = mappedRect.Pitch;

	return 1;
}
Beispiel #2
0
int win_shadow_subsystem_uninit(winShadowSubsystem* subsystem)
{
	if (!subsystem)
		return -1;

#if defined(WITH_WDS_API)
	win_shadow_wds_uninit(subsystem);
#elif defined(WITH_DXGI_1_2)
	win_shadow_dxgi_uninit(subsystem);
#endif
	return 1;
}
Beispiel #3
0
int win_shadow_dxgi_get_next_frame(winShadowSubsystem* subsystem)
{
	UINT i = 0;
	int status;
	HRESULT hr = 0;
	UINT timeout = 15;
	UINT DataBufferSize = 0;
	BYTE* DataBuffer = NULL;

	if (subsystem->dxgiFrameAcquired)
	{
		win_shadow_dxgi_release_frame_data(subsystem);
	}

	if (subsystem->dxgiDesktopImage)
	{
		subsystem->dxgiDesktopImage->lpVtbl->Release(subsystem->dxgiDesktopImage);
		subsystem->dxgiDesktopImage = NULL;
	}

	hr = subsystem->dxgiOutputDuplication->lpVtbl->AcquireNextFrame(subsystem->dxgiOutputDuplication,
		timeout, &(subsystem->dxgiFrameInfo), &(subsystem->dxgiResource));

	if (SUCCEEDED(hr))
	{
		subsystem->dxgiFrameAcquired = TRUE;
		subsystem->pendingFrames = subsystem->dxgiFrameInfo.AccumulatedFrames;
	}

	if (hr == DXGI_ERROR_WAIT_TIMEOUT)
		return 0;

	if (FAILED(hr))
	{
		WLog_ERR(TAG, "IDXGIOutputDuplication::AcquireNextFrame failure: %s (0x%04X)",
				GetDxgiErrorString(hr), hr);

		if (hr == DXGI_ERROR_ACCESS_LOST)
		{
			win_shadow_dxgi_release_frame_data(subsystem);

			if (subsystem->dxgiDesktopImage)
			{
				subsystem->dxgiDesktopImage->lpVtbl->Release(subsystem->dxgiDesktopImage);
				subsystem->dxgiDesktopImage = NULL;
			}

			if (subsystem->dxgiOutputDuplication)
			{
				subsystem->dxgiOutputDuplication->lpVtbl->Release(subsystem->dxgiOutputDuplication);
				subsystem->dxgiOutputDuplication = NULL;
			} 

			status = win_shadow_dxgi_init_duplication(subsystem);

			if (status < 0)
				return -1;

			return 0;
		}
		else if (hr == DXGI_ERROR_INVALID_CALL)
		{
			win_shadow_dxgi_uninit(subsystem);

			status = win_shadow_dxgi_init(subsystem);

			if (status < 0)
				return -1;

			return 0;
		}

		return -1;
	}
		
	hr = subsystem->dxgiResource->lpVtbl->QueryInterface(subsystem->dxgiResource,
		&IID_ID3D11Texture2D, (void**) &(subsystem->dxgiDesktopImage));

	if (subsystem->dxgiResource)
	{
		subsystem->dxgiResource->lpVtbl->Release(subsystem->dxgiResource);
		subsystem->dxgiResource = NULL;
	}

	if (FAILED(hr))
	{
		WLog_ERR(TAG, "IDXGIResource::QueryInterface(ID3D11Texture2D) failure: %s (0x%04X)",
			GetDxgiErrorString(hr), hr);
		return -1;
	}

	return 1;
}