[PVR][Estuary] Timer settings dialog: Show client name in timer type selection dialog...
[xbmc.git] / xbmc / rendering / dx / ScreenshotSurfaceWindows.cpp
blob7a62ad60fef35becbac3703e9f2acf3518422638
1 /*
2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
9 #include "ScreenshotSurfaceWindows.h"
11 #include "ServiceBroker.h"
12 #include "guilib/GUIComponent.h"
13 #include "guilib/GUIWindowManager.h"
14 #include "rendering/dx/DeviceResources.h"
15 #include "utils/Screenshot.h"
16 #include "utils/log.h"
17 #include "windowing/GraphicContext.h"
19 #include <mutex>
21 #include <wrl/client.h>
23 using namespace Microsoft::WRL;
25 void CScreenshotSurfaceWindows::Register()
27 CScreenShot::Register(CScreenshotSurfaceWindows::CreateSurface);
30 std::unique_ptr<IScreenshotSurface> CScreenshotSurfaceWindows::CreateSurface()
32 return std::unique_ptr<CScreenshotSurfaceWindows>(new CScreenshotSurfaceWindows());
35 bool CScreenshotSurfaceWindows::Capture()
37 CWinSystemBase* winsystem = CServiceBroker::GetWinSystem();
38 if (!winsystem)
39 return false;
41 CGUIComponent* gui = CServiceBroker::GetGUI();
42 if (!gui)
43 return false;
45 std::unique_lock<CCriticalSection> lock(winsystem->GetGfxContext());
46 gui->GetWindowManager().Render();
48 auto deviceResources = DX::DeviceResources::Get();
49 deviceResources->FinishCommandList();
51 ComPtr<ID3D11DeviceContext> pImdContext = deviceResources->GetImmediateContext();
52 ComPtr<ID3D11Device> pDevice = deviceResources->GetD3DDevice();
53 CD3DTexture& backbuffer = deviceResources->GetBackBuffer();
54 if (!backbuffer.Get())
55 return false;
57 D3D11_TEXTURE2D_DESC desc = {};
58 backbuffer.GetDesc(&desc);
59 desc.Usage = D3D11_USAGE_STAGING;
60 desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
61 desc.BindFlags = 0;
63 ComPtr<ID3D11Texture2D> pCopyTexture = nullptr;
64 if (SUCCEEDED(pDevice->CreateTexture2D(&desc, nullptr, &pCopyTexture)))
66 // take copy
67 pImdContext->CopyResource(pCopyTexture.Get(), backbuffer.Get());
69 D3D11_MAPPED_SUBRESOURCE res;
70 if (SUCCEEDED(pImdContext->Map(pCopyTexture.Get(), 0, D3D11_MAP_READ, 0, &res)))
72 m_width = desc.Width;
73 m_height = desc.Height;
74 m_stride = res.RowPitch;
75 m_buffer = new unsigned char[m_height * m_stride];
76 if (desc.Format == DXGI_FORMAT_R10G10B10A2_UNORM)
78 // convert R10G10B10A2 -> B8G8R8A8
79 for (int y = 0; y < m_height; y++)
81 uint32_t* pixels10 = reinterpret_cast<uint32_t*>(static_cast<uint8_t*>(res.pData) + y * res.RowPitch);
82 uint8_t* pixels8 = m_buffer + y * m_stride;
84 for (int x = 0; x < m_width; x++, pixels10++, pixels8 += 4)
86 // actual bit per channel is A2B10G10R10
87 uint32_t pixel = *pixels10;
88 // R
89 pixels8[2] = static_cast<uint8_t>((pixel & 0x3FF) * 255 / 1023);
90 // G
91 pixel >>= 10;
92 pixels8[1] = static_cast<uint8_t>((pixel & 0x3FF) * 255 / 1023);
93 // B
94 pixel >>= 10;
95 pixels8[0] = static_cast<uint8_t>((pixel & 0x3FF) * 255 / 1023);
96 // A
97 pixels8[3] = 0xFF;
101 else
102 memcpy(m_buffer, res.pData, m_height * m_stride);
103 pImdContext->Unmap(pCopyTexture.Get(), 0);
105 else
106 CLog::LogF(LOGERROR, "MAP_READ failed.");
109 return m_buffer != nullptr;