123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234 |
- // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
- // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
- // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
- // PARTICULAR PURPOSE.
- //
- // Copyright (c) Microsoft Corporation. All rights reserved
- #include "ThreadManager.h"
- DWORD WINAPI DDProc(_In_ void* Param);
- THREADMANAGER::THREADMANAGER() : m_ThreadCount(0),
- m_ThreadHandles(nullptr),
- m_ThreadData(nullptr)
- {
- RtlZeroMemory(&m_PtrInfo, sizeof(m_PtrInfo));
- }
- THREADMANAGER::~THREADMANAGER()
- {
- Clean();
- }
- //
- // Clean up resources
- //
- void THREADMANAGER::Clean()
- {
- if (m_PtrInfo.PtrShapeBuffer) {
- delete [] m_PtrInfo.PtrShapeBuffer;
- m_PtrInfo.PtrShapeBuffer = nullptr;
- }
- RtlZeroMemory(&m_PtrInfo, sizeof(m_PtrInfo));
- if (m_ThreadHandles) {
- for (UINT i = 0; i < m_ThreadCount; ++i) {
- if (m_ThreadHandles[i]) {
- CloseHandle(m_ThreadHandles[i]);
- }
- }
- delete [] m_ThreadHandles;
- m_ThreadHandles = nullptr;
- }
- if (m_ThreadData) {
- for (UINT i = 0; i < m_ThreadCount; ++i) {
- CleanDx(&m_ThreadData[i].DxRes);
- }
- delete [] m_ThreadData;
- m_ThreadData = nullptr;
- }
- m_ThreadCount = 0;
- }
- //
- // Clean up DX_RESOURCES
- //
- void THREADMANAGER::CleanDx(_Inout_ DX_RESOURCES* Data)
- {
- if (Data->Device) {
- Data->Device->Release();
- Data->Device = nullptr;
- }
- if (Data->Context) {
- Data->Context->Release();
- Data->Context = nullptr;
- }
- if (Data->VertexShader) {
- Data->VertexShader->Release();
- Data->VertexShader = nullptr;
- }
- if (Data->PixelShader) {
- Data->PixelShader->Release();
- Data->PixelShader = nullptr;
- }
- if (Data->InputLayout) {
- Data->InputLayout->Release();
- Data->InputLayout = nullptr;
- }
- if (Data->SamplerLinear) {
- Data->SamplerLinear->Release();
- Data->SamplerLinear = nullptr;
- }
- }
- //
- // Start up threads for DDA
- //
- DUPL_RETURN THREADMANAGER::Initialize(INT SingleOutput, UINT OutputCount, HANDLE UnexpectedErrorEvent, HANDLE ExpectedErrorEvent, HANDLE TerminateThreadsEvent, HANDLE SharedHandle, _In_ const struct tmedia_producer_s* Producer, _In_ RECT* DesktopDim)
- {
- m_ThreadCount = OutputCount;
- m_ThreadHandles = new (std::nothrow) HANDLE[m_ThreadCount];
- m_ThreadData = new (std::nothrow) THREAD_DATA[m_ThreadCount];
- if (!m_ThreadHandles || !m_ThreadData) {
- return ProcessFailure(nullptr, L"Failed to allocate array for threads", L"Error", E_OUTOFMEMORY);
- }
- // Create appropriate # of threads for duplication
- DUPL_RETURN Ret = DUPL_RETURN_SUCCESS;
- for (UINT i = 0; i < m_ThreadCount; ++i) {
- m_ThreadData[i].UnexpectedErrorEvent = UnexpectedErrorEvent;
- m_ThreadData[i].ExpectedErrorEvent = ExpectedErrorEvent;
- m_ThreadData[i].TerminateThreadsEvent = TerminateThreadsEvent;
- m_ThreadData[i].Output = (SingleOutput < 0) ? i : SingleOutput;
- m_ThreadData[i].TexSharedHandle = SharedHandle;
- m_ThreadData[i].OffsetX = DesktopDim->left;
- m_ThreadData[i].OffsetY = DesktopDim->top;
- m_ThreadData[i].PtrInfo = &m_PtrInfo;
- m_ThreadData[i].Producer = Producer;
- RtlZeroMemory(&m_ThreadData[i].DxRes, sizeof(DX_RESOURCES));
- Ret = InitializeDx(&m_ThreadData[i].DxRes);
- if (Ret != DUPL_RETURN_SUCCESS) {
- return Ret;
- }
- DWORD ThreadId;
- m_ThreadHandles[i] = CreateThread(nullptr, 0, DDProc, &m_ThreadData[i], 0, &ThreadId);
- if (m_ThreadHandles[i] == nullptr) {
- return ProcessFailure(nullptr, L"Failed to create thread", L"Error", E_FAIL);
- }
- }
- return Ret;
- }
- //
- // Get DX_RESOURCES
- //
- DUPL_RETURN THREADMANAGER::InitializeDx(_Out_ DX_RESOURCES* Data)
- {
- HRESULT hr = S_OK;
- // Driver types supported
- D3D_DRIVER_TYPE DriverTypes[] = {
- D3D_DRIVER_TYPE_HARDWARE,
- D3D_DRIVER_TYPE_WARP,
- D3D_DRIVER_TYPE_REFERENCE,
- };
- UINT NumDriverTypes = ARRAYSIZE(DriverTypes);
- // Feature levels supported
- D3D_FEATURE_LEVEL FeatureLevels[] = {
- D3D_FEATURE_LEVEL_11_0,
- D3D_FEATURE_LEVEL_10_1,
- D3D_FEATURE_LEVEL_10_0,
- D3D_FEATURE_LEVEL_9_1
- };
- UINT NumFeatureLevels = ARRAYSIZE(FeatureLevels);
- D3D_FEATURE_LEVEL FeatureLevel;
- // Create device
- for (UINT DriverTypeIndex = 0; DriverTypeIndex < NumDriverTypes; ++DriverTypeIndex) {
- hr = D3D11CreateDevice(nullptr, DriverTypes[DriverTypeIndex], nullptr, 0, FeatureLevels, NumFeatureLevels,
- D3D11_SDK_VERSION, &Data->Device, &FeatureLevel, &Data->Context);
- if (SUCCEEDED(hr)) {
- // Device creation success, no need to loop anymore
- break;
- }
- }
- if (FAILED(hr)) {
- return ProcessFailure(nullptr, L"Failed to create device in InitializeDx", L"Error", hr);
- }
- // VERTEX shader
- UINT Size = ARRAYSIZE(g_VS);
- hr = Data->Device->CreateVertexShader(g_VS, Size, nullptr, &Data->VertexShader);
- if (FAILED(hr)) {
- return ProcessFailure(Data->Device, L"Failed to create vertex shader in InitializeDx", L"Error", hr, SystemTransitionsExpectedErrors);
- }
- // Input layout
- D3D11_INPUT_ELEMENT_DESC Layout[] = {
- {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
- {"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0}
- };
- UINT NumElements = ARRAYSIZE(Layout);
- hr = Data->Device->CreateInputLayout(Layout, NumElements, g_VS, Size, &Data->InputLayout);
- if (FAILED(hr)) {
- return ProcessFailure(Data->Device, L"Failed to create input layout in InitializeDx", L"Error", hr, SystemTransitionsExpectedErrors);
- }
- Data->Context->IASetInputLayout(Data->InputLayout);
- // Pixel shader
- Size = ARRAYSIZE(g_PS);
- hr = Data->Device->CreatePixelShader(g_PS, Size, nullptr, &Data->PixelShader);
- if (FAILED(hr)) {
- return ProcessFailure(Data->Device, L"Failed to create pixel shader in InitializeDx", L"Error", hr, SystemTransitionsExpectedErrors);
- }
- // Set up sampler
- D3D11_SAMPLER_DESC SampDesc;
- RtlZeroMemory(&SampDesc, sizeof(SampDesc));
- SampDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
- SampDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
- SampDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
- SampDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
- SampDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
- SampDesc.MinLOD = 0;
- SampDesc.MaxLOD = D3D11_FLOAT32_MAX;
- hr = Data->Device->CreateSamplerState(&SampDesc, &Data->SamplerLinear);
- if (FAILED(hr)) {
- return ProcessFailure(Data->Device, L"Failed to create sampler state in InitializeDx", L"Error", hr, SystemTransitionsExpectedErrors);
- }
- return DUPL_RETURN_SUCCESS;
- }
- //
- // Getter for the PTR_INFO structure
- //
- PTR_INFO* THREADMANAGER::GetPointerInfo()
- {
- return &m_PtrInfo;
- }
- //
- // Waits infinitely for all spawned threads to terminate
- //
- bool THREADMANAGER::WaitForThreadTermination(DWORD timeout /*= INFINITE*/)
- {
- bool bRet = true;
- if (m_ThreadCount != 0) {
- bRet = (WaitForMultipleObjectsEx(m_ThreadCount, m_ThreadHandles, TRUE, timeout, FALSE) != WAIT_TIMEOUT);
- }
- return bRet;
- }
|