aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnton Fedchin <anightik@gmail.com>2017-04-26 12:30:19 +0300
committerAnton Fedchin <anightik@gmail.com>2017-07-17 11:43:32 +0300
commitafe556aad6cf7c7a93bacfb644b57ca84e5c022b (patch)
tree3a2d513c71141e8e7cfe401aaf3481bfc2fbde18
parent6c6a46c2a95267ec9a525c817c9d8cec7b67b583 (diff)
[VideoPlayer] WinRenderer: load 3dlut asynchronous
-rw-r--r--system/shaders/output_d3d.fx11
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/WinVideoFilter.cpp23
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/VideoShaders/WinVideoFilter.h4
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/WinRenderer.cpp70
-rw-r--r--xbmc/cores/VideoPlayer/VideoRenderers/WinRenderer.h3
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 };