summaryrefslogtreecommitdiffstats
path: root/Graphics/GraphicsTools
diff options
context:
space:
mode:
authorEgor Yusov <egor.yusov@gmail.com>2019-04-01 04:07:47 +0000
committerEgor Yusov <egor.yusov@gmail.com>2019-04-01 04:07:47 +0000
commit1e6fb84e7da0201adcce7b534102c7219f128b60 (patch)
treef6b6fa48853803360c96e1f2cac7728bb3859054 /Graphics/GraphicsTools
parentAdded swap chain usage flags (diff)
downloadDiligentCore-1e6fb84e7da0201adcce7b534102c7219f128b60.tar.gz
DiligentCore-1e6fb84e7da0201adcce7b534102c7219f128b60.zip
Added ScreenCapture class
Diffstat (limited to 'Graphics/GraphicsTools')
-rw-r--r--Graphics/GraphicsTools/CMakeLists.txt2
-rw-r--r--Graphics/GraphicsTools/include/ScreenCapture.h91
-rw-r--r--Graphics/GraphicsTools/src/ScreenCapture.cpp111
3 files changed, 204 insertions, 0 deletions
diff --git a/Graphics/GraphicsTools/CMakeLists.txt b/Graphics/GraphicsTools/CMakeLists.txt
index 94847222..c6f2144e 100644
--- a/Graphics/GraphicsTools/CMakeLists.txt
+++ b/Graphics/GraphicsTools/CMakeLists.txt
@@ -7,6 +7,7 @@ set(INCLUDE
include/CommonlyUsedStates.h
include/GraphicsUtilities.h
include/pch.h
+ include/ScreenCapture.h
include/ShaderMacroHelper.h
include/TextureUploader.h
include/TextureUploaderBase.h
@@ -15,6 +16,7 @@ set(INCLUDE
set(SOURCE
src/BasicShaderSourceStreamFactory.cpp
src/GraphicsUtilities.cpp
+ src/ScreenCapture.cpp
src/pch.cpp
src/TextureUploader.cpp
)
diff --git a/Graphics/GraphicsTools/include/ScreenCapture.h b/Graphics/GraphicsTools/include/ScreenCapture.h
new file mode 100644
index 00000000..ac894ae2
--- /dev/null
+++ b/Graphics/GraphicsTools/include/ScreenCapture.h
@@ -0,0 +1,91 @@
+/* Copyright 2015-2019 Egor Yusov
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS.
+ *
+ * In no event and under no legal theory, whether in tort (including negligence),
+ * contract, or otherwise, unless required by applicable law (such as deliberate
+ * and grossly negligent acts) or agreed to in writing, shall any Contributor be
+ * liable for any damages, including any direct, indirect, special, incidental,
+ * or consequential damages of any character arising as a result of this License or
+ * out of the use or inability to use the software (including but not limited to damages
+ * for loss of goodwill, work stoppage, computer failure or malfunction, or any and
+ * all other commercial damages or losses), even if such Contributor has been advised
+ * of the possibility of such damages.
+ */
+
+#pragma once
+
+#include <mutex>
+#include <vector>
+#include <deque>
+
+#include "../../GraphicsEngine/interface/SwapChain.h"
+#include "../../GraphicsEngine/interface/RenderDevice.h"
+#include "../../GraphicsEngine/interface/DeviceContext.h"
+#include "../../../Common/interface/RefCntAutoPtr.h"
+
+namespace Diligent
+{
+
+class ScreenCapture
+{
+public:
+ ScreenCapture(IRenderDevice* pDevice);
+
+ void Capture(ISwapChain* pSwapChain, IDeviceContext* pContext, Uint32 FrameId);
+
+ struct CaptureInfo
+ {
+ RefCntAutoPtr<ITexture> pTexture;
+ Uint32 Id = 0;
+
+ operator bool() const
+ {
+ return pTexture != nullptr;
+ }
+ };
+
+ CaptureInfo GetCapture();
+ void RecycleStagingTexture(RefCntAutoPtr<ITexture>&& pTexture);
+
+ size_t GetNumPendingCaptures()
+ {
+ std::lock_guard<std::mutex> Lock(m_PendingTexturesMtx);
+ return m_PendingTextures.size();
+ }
+
+private:
+ RefCntAutoPtr<IFence> m_pFence;
+ RefCntAutoPtr<IRenderDevice> m_pDevice;
+
+ std::mutex m_AvailableTexturesMtx;
+ std::vector<RefCntAutoPtr<ITexture>> m_AvailableTextures;
+
+ std::mutex m_PendingTexturesMtx;
+ struct PendingTextureInfo
+ {
+ PendingTextureInfo(RefCntAutoPtr<ITexture>&& _pTex, Uint32 _Id, Uint64 _Fence) :
+ pTex (std::move(_pTex)),
+ Id (_Id),
+ Fence (_Fence)
+ {
+ }
+
+ RefCntAutoPtr<ITexture> pTex;
+ const Uint32 Id;
+ const Uint64 Fence;
+ };
+ std::deque<PendingTextureInfo> m_PendingTextures;
+
+ Uint64 m_CurrentFenceValue = 1;
+};
+
+}
diff --git a/Graphics/GraphicsTools/src/ScreenCapture.cpp b/Graphics/GraphicsTools/src/ScreenCapture.cpp
new file mode 100644
index 00000000..f4fd9c74
--- /dev/null
+++ b/Graphics/GraphicsTools/src/ScreenCapture.cpp
@@ -0,0 +1,111 @@
+/* Copyright 2015-2019 Egor Yusov
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS.
+ *
+ * In no event and under no legal theory, whether in tort (including negligence),
+ * contract, or otherwise, unless required by applicable law (such as deliberate
+ * and grossly negligent acts) or agreed to in writing, shall any Contributor be
+ * liable for any damages, including any direct, indirect, special, incidental,
+ * or consequential damages of any character arising as a result of this License or
+ * out of the use or inability to use the software (including but not limited to damages
+ * for loss of goodwill, work stoppage, computer failure or malfunction, or any and
+ * all other commercial damages or losses), even if such Contributor has been advised
+ * of the possibility of such damages.
+ */
+
+#include "pch.h"
+#include "ScreenCapture.h"
+
+namespace Diligent
+{
+
+ScreenCapture::ScreenCapture(IRenderDevice* pDevice) :
+ m_pDevice(pDevice)
+{
+ FenceDesc fenceDesc;
+ fenceDesc.Name = "Screen capture fence";
+ m_pDevice->CreateFence(fenceDesc, &m_pFence);
+}
+
+void ScreenCapture::Capture(ISwapChain* pSwapChain, IDeviceContext* pContext, Uint32 FrameId)
+{
+ auto* pCurrentRTV = pSwapChain->GetCurrentBackBufferRTV();
+ auto* pCurrentBackBuffer = pCurrentRTV->GetTexture();
+ const auto& SCDesc = pSwapChain->GetDesc();
+
+ RefCntAutoPtr<ITexture> pStagingTexture;
+
+ {
+ std::lock_guard<std::mutex> Lock(m_AvailableTexturesMtx);
+ while (!m_AvailableTextures.empty() && !pStagingTexture)
+ {
+ pStagingTexture = std::move(m_AvailableTextures.back());
+ m_AvailableTextures.pop_back();
+ const auto& TexDesc = pStagingTexture->GetDesc();
+ if ( !(TexDesc.Width == SCDesc.Width &&
+ TexDesc.Height == SCDesc.Height &&
+ TexDesc.Format == SCDesc.ColorBufferFormat) )
+ {
+ pStagingTexture.Release();
+ }
+ }
+ }
+
+ if (!pStagingTexture)
+ {
+ TextureDesc TexDesc;
+ TexDesc.Type = RESOURCE_DIM_TEX_2D;
+ TexDesc.Width = SCDesc.Width;
+ TexDesc.Height = SCDesc.Height;
+ TexDesc.Format = SCDesc.ColorBufferFormat;
+ TexDesc.Usage = USAGE_STAGING;
+ TexDesc.CPUAccessFlags = CPU_ACCESS_READ;
+ m_pDevice->CreateTexture(TexDesc, nullptr, &pStagingTexture);
+ }
+
+ CopyTextureAttribs CopyAttribs(pCurrentBackBuffer, RESOURCE_STATE_TRANSITION_MODE_TRANSITION, pStagingTexture, RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
+ pContext->CopyTexture(CopyAttribs);
+ pContext->SignalFence(m_pFence, m_CurrentFenceValue);
+
+ {
+ std::lock_guard<std::mutex> Lock(m_PendingTexturesMtx);
+ m_PendingTextures.emplace_back(std::move(pStagingTexture), FrameId, m_CurrentFenceValue);
+ }
+
+ ++m_CurrentFenceValue;
+}
+
+
+ScreenCapture::CaptureInfo ScreenCapture::GetCapture()
+{
+ CaptureInfo Capture;
+ std::lock_guard<std::mutex> Lock(m_PendingTexturesMtx);
+ if (!m_PendingTextures.empty())
+ {
+ auto& OldestCapture = m_PendingTextures.front();
+ auto CompletedFenceValue = m_pFence->GetCompletedValue();
+ if (OldestCapture.Fence <= CompletedFenceValue)
+ {
+ Capture.pTexture = std::move(OldestCapture.pTex);
+ Capture.Id = OldestCapture.Id;
+ m_PendingTextures.pop_front();
+ }
+ }
+ return Capture;
+}
+
+void ScreenCapture::RecycleStagingTexture(RefCntAutoPtr<ITexture>&& pTexture)
+{
+ std::lock_guard<std::mutex> Lock(m_AvailableTexturesMtx);
+ m_AvailableTextures.emplace_back(std::move(pTexture));
+}
+
+}