diff options
author | Anton Fedchin <anightik@gmail.com> | 2017-04-26 12:30:19 +0300 |
---|---|---|
committer | Anton Fedchin <anightik@gmail.com> | 2017-07-17 11:43:32 +0300 |
commit | afe556aad6cf7c7a93bacfb644b57ca84e5c022b (patch) | |
tree | 3a2d513c71141e8e7cfe401aaf3481bfc2fbde18 | |
parent | 6c6a46c2a95267ec9a525c817c9d8cec7b67b583 (diff) |
[VideoPlayer] WinRenderer: load 3dlut asynchronous
5 files changed, 73 insertions, 38 deletions
diff --git a/system/shaders/output_d3d.fx b/system/shaders/output_d3d.fx index 6f3f1a3890..40d6252697 100644 --- a/system/shaders/output_d3d.fx +++ b/system/shaders/output_d3d.fx @@ -19,7 +19,7 @@ */ #if defined(KODI_3DLUT) -float m_CLUTsize; +float2 m_CLUTParams; // x- scale, y- offset texture3D m_CLUT; SamplerState LutSampler : IMMUTABLE @@ -45,9 +45,10 @@ SamplerState DitherSampler : IMMUTABLE float4 output4(float4 color, float2 uv) { #if defined(KODI_3DLUT) - half3 scale = (m_CLUTsize - 1.0) / m_CLUTsize; - half3 offset = 1.0 / (2.0 * m_CLUTsize); - color.rgb = m_CLUT.Sample(LutSampler, color.rgb*scale + offset).rgb; + half3 scale = m_CLUTParams.x; + half3 offset = m_CLUTParams.y; + float3 lutRGB = m_CLUT.Sample(LutSampler, color.rgb*scale + offset).rgb; + color.rgb = scale.x ? lutRGB : color.rgb; #endif #if defined(KODI_DITHER) half2 ditherpos = uv * m_ditherParams.xy; @@ -70,7 +71,7 @@ float3 m_params; // 0 - range (0 - full, 1 - limited), 1 - contrast, 2 - brightn float4 OUTPUT_PS(VS_OUTPUT In) : SV_TARGET { float4 color = g_Texture.Sample(KernelSampler, In.TextureUV); - if (m_params.x) + [flatten] if (m_params.x) color = saturate(0.0625 + color * 219.0 / 255.0); color *= m_params.y * 2.0; diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/WinVideoFilter.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/WinVideoFilter.cpp index e9063be2a2..9128d24273 100644 --- a/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/WinVideoFilter.cpp +++ b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/WinVideoFilter.cpp @@ -255,10 +255,16 @@ COutputShader::~COutputShader() void COutputShader::ApplyEffectParameters(CD3DEffect &effect, unsigned sourceWidth, unsigned sourceHeight) { - if (HasCLUT()) + if (m_useCLUT) { + float clut_params[2] = { 0.0f, 0.0f }; + if (HasCLUT()) + { + clut_params[0] = (m_clutSize - 1) / static_cast<float>(m_clutSize); + clut_params[1] = 0.5f / static_cast<float>(m_clutSize); + }; effect.SetResources("m_CLUT", &m_pCLUTView, 1); - effect.SetScalar("m_CLUTsize", m_clutSize); + effect.SetFloatArray("m_CLUTParams", clut_params, 2); } if (m_useDithering) { @@ -275,7 +281,7 @@ void COutputShader::ApplyEffectParameters(CD3DEffect &effect, unsigned sourceWid void COutputShader::GetDefines(DefinesMap& map) const { - if (HasCLUT()) + if (m_useCLUT) { map["KODI_3DLUT"] = ""; } @@ -285,10 +291,9 @@ void COutputShader::GetDefines(DefinesMap& map) const } } -bool COutputShader::Create(int clutSize, ID3D11ShaderResourceView* pCLUTView, bool useDithering, int ditherDepth) +bool COutputShader::Create(bool useCLUT, bool useDithering, int ditherDepth) { - m_clutSize = clutSize; - m_pCLUTView = pCLUTView; + m_useCLUT = useCLUT; m_ditherDepth = ditherDepth; CWinShader::CreateVertexBuffer(4, sizeof(CUSTOMVERTEX)); @@ -338,6 +343,12 @@ void COutputShader::Render(CD3DTexture &sourceTexture, unsigned sourceWidth, uns Render(sourceTexture, sourceWidth, sourceHeight, sourceRect, points, range, contrast, brightness); } +void COutputShader::SetCLUT(int clutSize, ID3D11ShaderResourceView* pCLUTView) +{ + m_clutSize = clutSize; + m_pCLUTView = pCLUTView; +} + bool COutputShader::CreateCLUTView(int clutSize, uint16_t* clutData, ID3D11ShaderResourceView** ppCLUTView) { if (!clutSize || !clutData) diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/WinVideoFilter.h b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/WinVideoFilter.h index be3c6a8754..4fbbd4bbe4 100644 --- a/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/WinVideoFilter.h +++ b/xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/WinVideoFilter.h @@ -80,11 +80,12 @@ public: void ApplyEffectParameters(CD3DEffect &effect, unsigned sourceWidth, unsigned sourceHeight); void GetDefines(DefinesMap &map) const; - bool Create(int clutSize, ID3D11ShaderResourceView *pCLUTView, bool useDithering, int ditherDepth); + bool Create(bool useCLUT, bool useDithering, int ditherDepth); void Render(CD3DTexture &sourceTexture, unsigned sourceWidth, unsigned sourceHeight, CRect sourceRect, const CPoint points[4] , unsigned range = 0, float contrast = 0.5f, float brightness = 0.5f); void Render(CD3DTexture &sourceTexture, unsigned sourceWidth, unsigned sourceHeight, CRect sourceRect, CRect destRect , unsigned range = 0, float contrast = 0.5f, float brightness = 0.5f); + void SetCLUT(int clutSize, ID3D11ShaderResourceView *pCLUTView); static bool CreateCLUTView(int clutSize, uint16_t* clutData, ID3D11ShaderResourceView** ppCLUTView); @@ -94,6 +95,7 @@ private: void SetShaderParameters(CD3DTexture &sourceTexture, unsigned range, float contrast, float brightness); void CreateDitherView(); + bool m_useCLUT{ false }; unsigned m_sourceWidth{ 0 }; unsigned m_sourceHeight{ 0 }; CRect m_sourceRect{ 0.f, 0.f, 0.f, 0.f }; diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/WinRenderer.cpp b/xbmc/cores/VideoPlayer/VideoRenderers/WinRenderer.cpp index 4664d65857..182841066e 100644 --- a/xbmc/cores/VideoPlayer/VideoRenderers/WinRenderer.cpp +++ b/xbmc/cores/VideoPlayer/VideoRenderers/WinRenderer.cpp @@ -30,7 +30,6 @@ #include "settings/MediaSettings.h" #include "settings/Settings.h" #include "threads/SingleLock.h" -#include "utils/CPUInfo.h" #include "utils/log.h" #include "utils/win32/gpu_memcpy_sse4.h" #include "VideoShaders/WinVideoFilter.h" @@ -101,7 +100,7 @@ CWinRenderer::CWinRenderer() m_processor = nullptr; m_neededBuffers = 0; m_colorManager.reset(new CColorManager()); - m_outputShader = nullptr; + m_outputShader.reset(); m_useDithering = CServiceBroker::GetSettings().GetBool("videoscreen.dither"); m_ditherDepth = CServiceBroker::GetSettings().GetInt("videoscreen.ditherdepth"); @@ -362,7 +361,7 @@ void CWinRenderer::UnInit() SAFE_DELETE(m_processor); } SAFE_RELEASE(m_pCLUTView); - SAFE_DELETE(m_outputShader); + m_outputShader.reset(); } void CWinRenderer::Flush() @@ -541,7 +540,7 @@ void CWinRenderer::UpdatePSVideoFilter() // First try the more efficient two pass convolution scaler m_scalerShader = new CConvolutionShaderSeparable(); - if (!m_scalerShader->Create(m_scalingMethod, m_outputShader)) + if (!m_scalerShader->Create(m_scalingMethod, m_outputShader.get())) { SAFE_DELETE(m_scalerShader); CLog::Log(LOGNOTICE, "%s: two pass convolution shader init problem, falling back to one pass.", __FUNCTION__); @@ -552,7 +551,7 @@ void CWinRenderer::UpdatePSVideoFilter() { m_scalerShader = new CConvolutionShader1Pass(); - if (!m_scalerShader->Create(m_scalingMethod, m_outputShader)) + if (!m_scalerShader->Create(m_scalingMethod, m_outputShader.get())) { SAFE_DELETE(m_scalerShader); CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Error, g_localizeStrings.Get(34400), g_localizeStrings.Get(34401)); @@ -579,7 +578,7 @@ void CWinRenderer::UpdatePSVideoFilter() } m_colorShader = new CYUV2RGBShader(); - if (!m_colorShader->Create(m_bufferFormat, m_bUseHQScaler ? nullptr : m_outputShader)) + if (!m_colorShader->Create(m_bufferFormat, m_bUseHQScaler ? nullptr : m_outputShader.get())) { if (m_bUseHQScaler) { @@ -603,7 +602,9 @@ void CWinRenderer::UpdatePSVideoFilter() void CWinRenderer::UpdateVideoFilter() { bool cmsChanged = m_cmsOn != m_colorManager->IsEnabled() - || m_cmsOn && !m_colorManager->CheckConfiguration(m_cmsToken, m_iFlags); + || m_cmsOn && !m_colorManager->CheckConfiguration(m_cmsToken, m_iFlags); + cmsChanged &= m_clutLoaded; + if (m_scalingMethodGui == CMediaSettings::GetInstance().GetCurrentVideoSettings().m_ScalingMethod && m_bFilterInitialized && !cmsChanged) return; @@ -623,13 +624,14 @@ void CWinRenderer::UpdateVideoFilter() if (cmsChanged || !m_outputShader) { - SAFE_DELETE(m_outputShader); - m_outputShader = new COutputShader(); - if (!m_outputShader->Create(m_CLUTSize, m_pCLUTView, m_useDithering, m_ditherDepth)) + m_outputShader.reset(new COutputShader()); + if (!m_outputShader->Create(m_cmsOn, m_useDithering, m_ditherDepth)) { CLog::Log(LOGDEBUG, "%s: Unable to create output shader.", __FUNCTION__); - SAFE_DELETE(m_outputShader); + m_outputShader.reset(); } + else if (m_pCLUTView && m_CLUTSize) + m_outputShader->SetCLUT(m_CLUTSize, m_pCLUTView); } RESOLUTION_INFO res = g_graphicsContext.GetResInfo(); @@ -1159,20 +1161,38 @@ void CWinRenderer::ColorManagmentUpdate() bool CWinRenderer::LoadCLUT() { + if (m_outputShader) + m_outputShader->SetCLUT(0, nullptr); + m_CLUTSize = 0; SAFE_RELEASE(m_pCLUTView); - // load 3DLUT data - uint16_t* pCLUT; - if (!m_colorManager->GetVideo3dLut(m_iFlags, &m_cmsToken, &m_CLUTSize, &pCLUT)) - { - CLog::Log(LOGERROR, "%s: Error loading the 3DLUT data.", __FUNCTION__); - return false; - } - // create 3DLUT shader view - if (!COutputShader::CreateCLUTView(m_CLUTSize, pCLUT, &m_pCLUTView)) - { - CLog::Log(LOGERROR, "%s: Unable to create 3DLUT texture.", __FUNCTION__); - SAFE_DELETE(m_pCLUTView); - } - free(pCLUT); + m_clutLoaded = false; + + auto loadLutTask = Concurrency::create_task([this]{ + // load 3DLUT data + uint16_t* pCLUT; + int clutSize; + if (!m_colorManager->GetVideo3dLut(m_iFlags, &m_cmsToken, &clutSize, &pCLUT)) + { + CLog::Log(LOGERROR, "%s: Error loading the 3DLUT data.", __FUNCTION__); + return 0; + } + // create 3DLUT shader view + bool success = COutputShader::CreateCLUTView(clutSize, pCLUT, &m_pCLUTView); + free(pCLUT); + if (!success) + { + CLog::Log(LOGERROR, "%s: Unable to create 3DLUT texture.", __FUNCTION__); + SAFE_RELEASE(m_pCLUTView); + return 0; + } + return clutSize; + }); + + loadLutTask.then([this](int clutSize){ + m_CLUTSize = clutSize; + if (m_outputShader) + m_outputShader->SetCLUT(m_CLUTSize, m_pCLUTView); + m_clutLoaded = true; + }); return true; } diff --git a/xbmc/cores/VideoPlayer/VideoRenderers/WinRenderer.h b/xbmc/cores/VideoPlayer/VideoRenderers/WinRenderer.h index 8c10a508c7..5f0cae05a9 100644 --- a/xbmc/cores/VideoPlayer/VideoRenderers/WinRenderer.h +++ b/xbmc/cores/VideoPlayer/VideoRenderers/WinRenderer.h @@ -146,6 +146,7 @@ protected: bool m_bUseHQScaler; bool m_bFilterInitialized; bool m_cmsOn{ false }; + bool m_clutLoaded{ true }; bool m_useDithering; unsigned int m_destWidth; @@ -173,7 +174,7 @@ protected: struct SwsContext *m_sw_scale_ctx; CYUV2RGBShader* m_colorShader; CConvolutionShader* m_scalerShader; - COutputShader* m_outputShader; + std::unique_ptr<COutputShader> m_outputShader; CRenderCapture* m_capture = nullptr; std::unique_ptr<CColorManager> m_colorManager; ID3D11ShaderResourceView *m_pCLUTView{ nullptr }; |