Advertisement
Guest User

Untitled

a guest
Jul 25th, 2017
515
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.20 KB | None | 0 0
  1.  
  2. template <typename T>
  3. class CComPtrCustom
  4. {
  5. public:
  6.  
  7.     CComPtrCustom(T *aPtrElement)
  8.         :element(aPtrElement)
  9.     {
  10.     }
  11.  
  12.     CComPtrCustom()
  13.         :element(nullptr)
  14.     {
  15.     }
  16.  
  17.     virtual ~CComPtrCustom()
  18.     {
  19.         Release();
  20.     }
  21.  
  22.     T* Detach()
  23.     {
  24.         auto lOutPtr = element;
  25.  
  26.         element = nullptr;
  27.  
  28.         return lOutPtr;
  29.     }
  30.  
  31.     T* detach()
  32.     {
  33.         return Detach();
  34.     }
  35.  
  36.     void Release()
  37.     {
  38.         if (element == nullptr)
  39.             return;
  40.  
  41.         auto k = element->Release();
  42.  
  43.         element = nullptr;
  44.     }
  45.  
  46.     CComPtrCustom& operator = (T *pElement)
  47.     {
  48.         Release();
  49.  
  50.         if (pElement == nullptr)
  51.             return *this;
  52.  
  53.         auto k = pElement->AddRef();
  54.  
  55.         element = pElement;
  56.  
  57.         return *this;
  58.     }
  59.  
  60.     void Swap(CComPtrCustom& other)
  61.     {
  62.         T* pTemp = element;
  63.         element = other.element;
  64.         other.element = pTemp;
  65.     }
  66.  
  67.     T* operator->()
  68.     {
  69.         return element;
  70.     }
  71.  
  72.     operator T*()
  73.     {
  74.         return element;
  75.     }
  76.  
  77.     operator T*() const
  78.     {
  79.         return element;
  80.     }
  81.  
  82.  
  83.     T* get()
  84.     {
  85.         return element;
  86.     }
  87.  
  88.     T* get() const
  89.     {
  90.         return element;
  91.     }
  92.  
  93.     T** operator &()
  94.     {
  95.         return &element;
  96.     }
  97.  
  98.     bool operator !()const
  99.     {
  100.         return element == nullptr;
  101.     }
  102.  
  103.     operator bool()const
  104.     {
  105.         return element != nullptr;
  106.     }
  107.  
  108.     bool operator == (const T *pElement)const
  109.     {
  110.         return element == pElement;
  111.     }
  112.  
  113.  
  114.     CComPtrCustom(const CComPtrCustom& aCComPtrCustom)
  115.     {
  116.         if (aCComPtrCustom.operator!())
  117.         {
  118.             element = nullptr;
  119.  
  120.             return;
  121.         }
  122.  
  123.         element = aCComPtrCustom;
  124.  
  125.         auto h = element->AddRef();
  126.  
  127.         h++;
  128.     }
  129.  
  130.     CComPtrCustom& operator = (const CComPtrCustom& aCComPtrCustom)
  131.     {
  132.         Release();
  133.  
  134.         element = aCComPtrCustom;
  135.  
  136.         auto k = element->AddRef();
  137.  
  138.         return *this;
  139.     }
  140.  
  141.     _Check_return_ HRESULT CopyTo(T** ppT) throw()
  142.     {
  143.         if (ppT == NULL)
  144.             return E_POINTER;
  145.  
  146.         *ppT = element;
  147.  
  148.         if (element)
  149.             element->AddRef();
  150.  
  151.         return S_OK;
  152.     }
  153.  
  154.     HRESULT CoCreateInstance(const CLSID aCLSID)
  155.     {
  156.         T* lPtrTemp;
  157.  
  158.         auto lresult = ::CoCreateInstance(aCLSID, NULL, CLSCTX_INPROC, IID_PPV_ARGS(&lPtrTemp));
  159.  
  160.         if (SUCCEEDED(lresult))
  161.         {
  162.             if (lPtrTemp != nullptr)
  163.             {
  164.                 Release();
  165.  
  166.                 element = lPtrTemp;
  167.             }
  168.  
  169.         }
  170.  
  171.         return lresult;
  172.     }
  173.  
  174. protected:
  175.  
  176.     T* element;
  177. };
  178.  
  179.  
  180. // Driver types supported
  181. D3D_DRIVER_TYPE gDriverTypes[] =
  182. {
  183.     D3D_DRIVER_TYPE_HARDWARE
  184. };
  185.  
  186. UINT gNumDriverTypes = ARRAYSIZE(gDriverTypes);
  187.  
  188. // Feature levels supported
  189. D3D_FEATURE_LEVEL gFeatureLevels[] =
  190. {
  191.     D3D_FEATURE_LEVEL_11_0,
  192.     D3D_FEATURE_LEVEL_10_1,
  193.     D3D_FEATURE_LEVEL_10_0,
  194.     D3D_FEATURE_LEVEL_9_1
  195. };
  196.  
  197. UINT gNumFeatureLevels = ARRAYSIZE(gFeatureLevels);
  198.  
  199.  
  200.  
  201. void main()
  202. {
  203.     for (int i = 0; i < 20; i++)
  204.     {
  205.         auto start = std::chrono::high_resolution_clock::now();
  206.  
  207.         HRESULT hr;
  208.  
  209.         CComPtrCustom<ID3D11Device> pDevice;
  210.         CComPtrCustom<ID3D11DeviceContext> pImmediateContext;
  211.         CComPtrCustom<IDXGIOutputDuplication> pDeskDupl;
  212.         DXGI_OUTDUPL_DESC OutputDuplDesc;
  213.         CComPtrCustom<ID3D11Texture2D> AcquiredDesktopImage;
  214.         CComPtrCustom<ID3D11Texture2D> pGdiImg;
  215.         CComPtrCustom<ID3D11Texture2D> pDestImg;
  216.         DXGI_OUTPUT_DESC OutputDesc;
  217.         D3D_FEATURE_LEVEL FeatureLevel;
  218.  
  219.         // Create device
  220.         hr = D3D11CreateDevice(NULL,
  221.             gDriverTypes[0], NULL, 0,
  222.             gFeatureLevels, gNumFeatureLevels,
  223.             D3D11_SDK_VERSION,
  224.             &pDevice, &FeatureLevel,
  225.             &pImmediateContext);
  226.  
  227.         EXIT_(hr);
  228.  
  229.         // Get DXGI device
  230.         CComPtrCustom<IDXGIDevice> lDxgiDevice;
  231.         hr = pDevice->QueryInterface(IID_PPV_ARGS(&lDxgiDevice));
  232.  
  233.         EXIT_(hr);
  234.  
  235.         // Get DXGI adapter
  236.         CComPtrCustom<IDXGIAdapter> lDxgiAdapter;
  237.         hr = lDxgiDevice->GetParent(__uuidof(IDXGIAdapter), reinterpret_cast<void**>(&lDxgiAdapter));
  238.         EXIT_(hr);
  239.         lDxgiDevice.Release();
  240.  
  241.         // Get output
  242.         CComPtrCustom<IDXGIOutput> lDxgiOutput;
  243.         hr = lDxgiAdapter->EnumOutputs(0, &lDxgiOutput);
  244.         EXIT_(hr);
  245.         lDxgiAdapter.Release();
  246.  
  247.         hr = lDxgiOutput->GetDesc(&OutputDesc);
  248.         EXIT_(hr);
  249.  
  250.         // QI for Output 1
  251.         CComPtrCustom<IDXGIOutput1> lDxgiOutput1;
  252.         hr = lDxgiOutput->QueryInterface(IID_PPV_ARGS(&lDxgiOutput1));
  253.         EXIT_(hr);
  254.  
  255.         lDxgiOutput.Release();
  256.  
  257.         // Create desktop duplication
  258.         hr = lDxgiOutput1->DuplicateOutput(pDevice, &pDeskDupl);
  259.         EXIT_(hr);
  260.  
  261.         lDxgiOutput1.Release();
  262.  
  263.         pDeskDupl->GetDesc(&OutputDuplDesc);
  264.  
  265.         // Create GUI drawing texture
  266.  
  267.         D3D11_TEXTURE2D_DESC desc;
  268.         desc.Width = OutputDuplDesc.ModeDesc.Width;
  269.         desc.Height = OutputDuplDesc.ModeDesc.Height;
  270.         desc.Format = OutputDuplDesc.ModeDesc.Format;
  271.         desc.ArraySize = 1;
  272.         desc.BindFlags = D3D11_BIND_FLAG::D3D11_BIND_RENDER_TARGET;
  273.         desc.MiscFlags = D3D11_RESOURCE_MISC_GDI_COMPATIBLE;
  274.         desc.SampleDesc.Count = 1;
  275.         desc.SampleDesc.Quality = 0;
  276.         desc.MipLevels = 1;
  277.         desc.CPUAccessFlags = 0;
  278.         desc.Usage = D3D11_USAGE_DEFAULT;
  279.  
  280.         hr = pDevice->CreateTexture2D(&desc, NULL, &pGdiImg);
  281.         EXIT_(hr);
  282.  
  283.         // Create CPU access texture
  284.  
  285.         desc.Width = OutputDuplDesc.ModeDesc.Width;
  286.         desc.Height = OutputDuplDesc.ModeDesc.Height;
  287.         desc.Format = OutputDuplDesc.ModeDesc.Format;
  288.         desc.ArraySize = 1;
  289.         desc.BindFlags = 0;
  290.         desc.MiscFlags = 0;
  291.         desc.SampleDesc.Count = 1;
  292.         desc.SampleDesc.Quality = 0;
  293.         desc.MipLevels = 1;
  294.         desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
  295.         desc.Usage = D3D11_USAGE_STAGING;
  296.  
  297.         hr = pDevice->CreateTexture2D(&desc, NULL, &pDestImg);
  298.         EXIT_(hr);
  299.  
  300.         CComPtrCustom<IDXGIResource> lDesktopResource;
  301.         DXGI_OUTDUPL_FRAME_INFO lFrameInfo;
  302.  
  303.         // Get new frame
  304.         hr = pDeskDupl->AcquireNextFrame(
  305.             250,
  306.             &lFrameInfo,
  307.             &lDesktopResource);
  308.  
  309.         // QI for ID3D11Texture2D
  310.         hr = lDesktopResource->QueryInterface(IID_PPV_ARGS(&AcquiredDesktopImage));
  311.         EXIT_(hr);
  312.         lDesktopResource.Release();
  313.  
  314.         // Copy image into GDI drawing texture
  315.         pImmediateContext->CopyResource(pGdiImg, AcquiredDesktopImage);
  316.  
  317.         // Draw cursor image into GDI drawing texture
  318.         CComPtrCustom<IDXGISurface1> lIDXGISurface1;
  319.         hr = pGdiImg->QueryInterface(IID_PPV_ARGS(&lIDXGISurface1));
  320.         EXIT_(hr);
  321.  
  322.         // Copy image into CPU access texture
  323.         pImmediateContext->CopyResource(pDestImg, pGdiImg);
  324.  
  325.         // Copy from CPU access texture to bitmap buffer
  326.         D3D11_MAPPED_SUBRESOURCE resource;
  327.         UINT subresource = D3D11CalcSubresource(0, 0, 0);
  328.         pImmediateContext->Map(pDestImg, subresource, D3D11_MAP_READ_WRITE, 0, &resource);
  329.  
  330.         auto finish = std::chrono::high_resolution_clock::now();
  331.         std::cout << "Time: " << std::chrono::duration_cast<std::chrono::microseconds>(finish - start).count() << std::endl;
  332.  
  333.         // BMP 32 bpp
  334.         BITMAPINFO lBmpInfo;
  335.  
  336.         ZeroMemory(&lBmpInfo, sizeof(BITMAPINFO));
  337.  
  338.         lBmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  339.         lBmpInfo.bmiHeader.biBitCount = 32;
  340.         lBmpInfo.bmiHeader.biCompression = BI_RGB;
  341.         lBmpInfo.bmiHeader.biWidth = OutputDuplDesc.ModeDesc.Width;
  342.         lBmpInfo.bmiHeader.biHeight = OutputDuplDesc.ModeDesc.Height;
  343.         lBmpInfo.bmiHeader.biPlanes = 1;
  344.         lBmpInfo.bmiHeader.biSizeImage = OutputDuplDesc.ModeDesc.Width * OutputDuplDesc.ModeDesc.Height * 4;
  345.  
  346.         std::unique_ptr<BYTE> pBuf(new BYTE[lBmpInfo.bmiHeader.biSizeImage]);
  347.         UINT lBmpRowPitch = OutputDuplDesc.ModeDesc.Width * 4;
  348.         BYTE* sptr = reinterpret_cast<BYTE*>(resource.pData);
  349.         BYTE* dptr = pBuf.get() + lBmpInfo.bmiHeader.biSizeImage - lBmpRowPitch;
  350.         UINT lRowPitch = std::min<UINT>(lBmpRowPitch, resource.RowPitch);
  351.  
  352.         for (size_t h = 0; h < OutputDuplDesc.ModeDesc.Height; ++h)
  353.         {
  354.             memcpy_s(dptr, lBmpRowPitch, sptr, lRowPitch);
  355.             sptr += resource.RowPitch;
  356.             dptr -= lBmpRowPitch;
  357.         }
  358.  
  359.         // Save bitmap buffer into the file ScreenShot.bmp
  360.  
  361.         FILE* lfile = NULL;
  362.         TCHAR name[100];
  363.         swprintf(name, L"cap%i.bmp", i);
  364.         auto lerr = _wfopen_s(&lfile, name, L"wb");
  365.  
  366.         if (lfile != NULL && lerr == 0)
  367.         {
  368.             BITMAPFILEHEADER bmpFileHeader;
  369.  
  370.             bmpFileHeader.bfReserved1 = 0;
  371.             bmpFileHeader.bfReserved2 = 0;
  372.             bmpFileHeader.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + lBmpInfo.bmiHeader.biSizeImage;
  373.             bmpFileHeader.bfType = 'MB';
  374.             bmpFileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
  375.  
  376.             fwrite(&bmpFileHeader, sizeof(BITMAPFILEHEADER), 1, lfile);
  377.             fwrite(&lBmpInfo.bmiHeader, sizeof(BITMAPINFOHEADER), 1, lfile);
  378.             fwrite(pBuf.get(), lBmpInfo.bmiHeader.biSizeImage, 1, lfile);
  379.  
  380.             fclose(lfile);
  381.         }
  382.  
  383.         wprintf(name);
  384.         printf("\n");
  385.     }
  386.  
  387.     system("pause");
  388. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement