diff --git a/xbmc/cores/RetroPlayer/rendering/RPRenderManager.cpp b/xbmc/cores/RetroPlayer/rendering/RPRenderManager.cpp index 4943583a6be0a..e5753304f0863 100644 --- a/xbmc/cores/RetroPlayer/rendering/RPRenderManager.cpp +++ b/xbmc/cores/RetroPlayer/rendering/RPRenderManager.cpp @@ -216,9 +216,6 @@ void CRPRenderManager::AddFrame(const uint8_t* data, size_t size, unsigned int w void CRPRenderManager::SetSpeed(double speed) { m_speed = speed; - - for (const auto &renderer : m_renderers) - renderer->SetSpeed(speed); //! @todo Retroactive set speed for newly created renderers } void CRPRenderManager::FrameMove() @@ -362,13 +359,7 @@ bool CRPRenderManager::SupportsScalingMethod(SCALINGMETHOD method) const { CRenderVideoSettings renderSettings; renderSettings.SetScalingMethod(method); - bool hasAtLeastOneRenderer = !m_renderers.empty(); - bool bufferPoolSupport = bufferPool->IsCompatible(renderSettings); - bool renderersSupport = std::all_of(m_renderers.begin(), m_renderers.end(), - [method](const std::shared_ptr& renderer) { return renderer->Supports(method); }); - - // If method is supported by the buffer pool and all the renderers, the manager supports it - if (hasAtLeastOneRenderer && bufferPoolSupport && renderersSupport) + if (bufferPool->IsCompatible(renderSettings)) return true; } @@ -474,7 +465,7 @@ std::shared_ptr CRPRenderManager::GetRenderer(IRenderBufferPool // Try to create a renderer now, unless the shader preset has failed already if (shaderPreset.empty() || m_failedShaderPresets.find(shaderPreset) == m_failedShaderPresets.end()) renderer.reset(m_processInfo.CreateRenderer(bufferPool, renderSettings)); - if (renderer && renderer->Configure(m_format, m_width, m_height)) + if (renderer && renderer->Configure(m_format)) { // Ensure we have a render buffer for this renderer CreateRenderBuffer(renderer->GetBufferPool()); @@ -637,8 +628,6 @@ CRenderVideoSettings CRPRenderManager::GetEffectiveSettings(const IGUIRenderSett effectiveSettings.SetRenderStretchMode(settings->GetSettings().VideoSettings().GetRenderStretchMode()); if (settings->HasRotation()) effectiveSettings.SetRenderRotation(settings->GetSettings().VideoSettings().GetRenderRotation()); - if (settings->HasShaderPreset()) - effectiveSettings.SetShaderPreset(settings->GetSettings().VideoSettings().GetShaderPreset()); } // Sanitize settings @@ -647,12 +636,5 @@ CRenderVideoSettings CRPRenderManager::GetEffectiveSettings(const IGUIRenderSett effectiveSettings.SetScalingMethod(m_processInfo.GetDefaultScalingMethod()); } - if (!effectiveSettings.GetShaderPreset().empty()) - effectiveSettings.SetScalingMethod(VS_SCALINGMETHOD_AUTO); - ESCALINGMETHOD scalingMethod = effectiveSettings.GetScalingMethod(); - - // If the method is AUTO or unsupported by the manager, we need to set it to the default - if (scalingMethod == VS_SCALINGMETHOD_AUTO || !SupportsScalingMethod(scalingMethod)) - effectiveSettings.SetScalingMethod(m_processInfo.GetDefaultScalingMethod()); return effectiveSettings; } diff --git a/xbmc/cores/RetroPlayer/rendering/RPRenderManager.h b/xbmc/cores/RetroPlayer/rendering/RPRenderManager.h index 330b663f99bfb..7f4f575f507e4 100644 --- a/xbmc/cores/RetroPlayer/rendering/RPRenderManager.h +++ b/xbmc/cores/RetroPlayer/rendering/RPRenderManager.h @@ -200,8 +200,6 @@ namespace RETRO // Synchronization parameters CCriticalSection m_stateMutex; CCriticalSection m_bufferMutex; - - std::set m_failedShaderPresets; }; } } diff --git a/xbmc/cores/RetroPlayer/rendering/RenderVideoSettings.cpp b/xbmc/cores/RetroPlayer/rendering/RenderVideoSettings.cpp index d0dee3e692c60..de20d4978e4fe 100644 --- a/xbmc/cores/RetroPlayer/rendering/RenderVideoSettings.cpp +++ b/xbmc/cores/RetroPlayer/rendering/RenderVideoSettings.cpp @@ -8,12 +8,16 @@ #include "RenderVideoSettings.h" +#include "utils/log.h" + using namespace KODI; using namespace RETRO; #define VIDEO_FILTER_NEAREST "nearest" #define VIDEO_FILTER_LINEAR "linear" +#define VIDEO_FILTER_DEFAULT VIDEO_FILTER_NEAREST + void CRenderVideoSettings::Reset() { m_scalingMethod = SCALINGMETHOD::AUTO; @@ -49,6 +53,13 @@ bool CRenderVideoSettings::operator<(const CRenderVideoSettings &rhs) const std::string CRenderVideoSettings::GetVideoFilter() const { + // Sanity check + if (!m_shaderPreset.empty() && m_scalingMethod != SCALINGMETHOD::AUTO) + CLog::Log(LOGWARNING, "%s - Shader preset selected but scaling method is not AUTO", __FUNCTION__); + + if (UsesShaderPreset()) + return m_shaderPreset; + switch (m_scalingMethod) { case SCALINGMETHOD::NEAREST: @@ -75,5 +86,13 @@ void CRenderVideoSettings::SetVideoFilter(const std::string &videoFilter) else { m_scalingMethod = SCALINGMETHOD::AUTO; + + // Not a known video filter, assume it's a shader preset path + SetShaderPreset(videoFilter); } } + +bool CRenderVideoSettings::UsesShaderPreset() const +{ + return !m_shaderPreset.empty() && m_scalingMethod == SCALINGMETHOD::AUTO; +} diff --git a/xbmc/cores/RetroPlayer/rendering/RenderVideoSettings.h b/xbmc/cores/RetroPlayer/rendering/RenderVideoSettings.h index 9cd5d2a860c23..105ace2440e87 100644 --- a/xbmc/cores/RetroPlayer/rendering/RenderVideoSettings.h +++ b/xbmc/cores/RetroPlayer/rendering/RenderVideoSettings.h @@ -50,6 +50,8 @@ namespace RETRO void SetRenderRotation(unsigned int rotationDegCCW) { m_rotationDegCCW = rotationDegCCW; } private: + bool UsesShaderPreset() const; + SCALINGMETHOD m_scalingMethod; STRETCHMODE m_stretchMode; unsigned int m_rotationDegCCW; diff --git a/xbmc/cores/RetroPlayer/rendering/VideoRenderers/RPBaseRenderer.cpp b/xbmc/cores/RetroPlayer/rendering/VideoRenderers/RPBaseRenderer.cpp index feac9aa881fbc..14098d5e295d5 100644 --- a/xbmc/cores/RetroPlayer/rendering/VideoRenderers/RPBaseRenderer.cpp +++ b/xbmc/cores/RetroPlayer/rendering/VideoRenderers/RPBaseRenderer.cpp @@ -203,21 +203,28 @@ void CRPBaseRenderer::MarkDirty() //CServiceBroker::GetGUI()->GetWindowManager().MarkDirty(m_dimensions); //! @todo } +/** + * \brief Updates everything needed for video shaders (shader presets) + * Needs to be called after m_renderBuffer has been set + */ void CRPBaseRenderer::UpdateVideoShaders() { - if (m_shadersNeedUpdate && !m_renderSettings.VideoSettings().GetShaderPreset().empty()) + if (m_shadersNeedUpdate) { - m_shadersNeedUpdate = false; - if (m_shaderPreset) { - auto sourceWidth = static_cast(m_sourceRect.Width()); - auto sourceHeight = static_cast(m_sourceRect.Height()); + if (!m_renderBuffer) { + CLog::Log(LOGWARNING, "%s - Render buffer not set, can't update video shader source size!", __FUNCTION__); + return; + } + auto sourceWidth = m_renderBuffer->GetWidth(); + auto sourceHeight = m_renderBuffer->GetHeight(); // We need to set this here because m_sourceRect isn't valid on init/pre-init m_shaderPreset->SetVideoSize(sourceWidth, sourceHeight); m_bUseShaderPreset = m_shaderPreset->SetShaderPreset(m_renderSettings.VideoSettings().GetShaderPreset()); } + m_shadersNeedUpdate = false; } } @@ -230,9 +237,7 @@ void CRPBaseRenderer::PreRender(bool clear) if (clear) m_context.Clear(m_context.UseLimitedColor() ? 0x101010 : 0); - ManageRenderArea(); - - UpdateVideoShaders(); + //ManageRenderArea(*m_renderBuffer); } void CRPBaseRenderer::PostRender() diff --git a/xbmc/cores/RetroPlayer/rendering/VideoRenderers/RPRendererGuiTexture.cpp b/xbmc/cores/RetroPlayer/rendering/VideoRenderers/RPRendererGuiTexture.cpp index 8e5f759e47066..f209c3f2d5c3c 100644 --- a/xbmc/cores/RetroPlayer/rendering/VideoRenderers/RPRendererGuiTexture.cpp +++ b/xbmc/cores/RetroPlayer/rendering/VideoRenderers/RPRendererGuiTexture.cpp @@ -88,15 +88,6 @@ bool CRPRendererGuiTexture::Supports(RENDERFEATURE feature) const return false; } -bool CRPRendererGuiTexture::Supports(ESCALINGMETHOD method) const -{ - if (method == VS_SCALINGMETHOD_LINEAR || - method == VS_SCALINGMETHOD_NEAREST) - return true; - - return false; -} - void CRPRendererGuiTexture::RenderInternal(bool clear, uint8_t alpha) { CRenderBufferGuiTexture *renderBuffer = static_cast(m_renderBuffer); diff --git a/xbmc/cores/RetroPlayer/rendering/VideoRenderers/RPWinRenderer.cpp b/xbmc/cores/RetroPlayer/rendering/VideoRenderers/RPWinRenderer.cpp index 797a1efb7144f..55fe211f3ac1e 100644 --- a/xbmc/cores/RetroPlayer/rendering/VideoRenderers/RPWinRenderer.cpp +++ b/xbmc/cores/RetroPlayer/rendering/VideoRenderers/RPWinRenderer.cpp @@ -56,7 +56,7 @@ CWinRenderBuffer::CWinRenderBuffer(AVPixelFormat pixFormat, DXGI_FORMAT dxFormat bool CWinRenderBuffer::CreateTexture() { - if (!m_intermediateTarget->Create(m_width, m_height, 1, D3D11_USAGE_DYNAMIC, m_targetDxFormat)) + if (!m_intermediateTarget->GetPointer()->Create(m_width, m_height, 1, D3D11_USAGE_DYNAMIC, m_targetDxFormat)) { CLog::Log(LOGERROR, "WinRenderer: Intermediate render target creation failed"); return false; @@ -69,7 +69,7 @@ bool CWinRenderBuffer::GetTexture(uint8_t*& data, unsigned int& stride) { // Scale and upload texture D3D11_MAPPED_SUBRESOURCE destlr; - if (!m_intermediateTarget->LockRect(0, &destlr, D3D11_MAP_WRITE_DISCARD)) + if (!m_intermediateTarget->GetPointer()->LockRect(0, &destlr, D3D11_MAP_WRITE_DISCARD)) { CLog::Log(LOGERROR, "WinRenderer: Failed to lock swtarget texture into memory"); return false; @@ -83,7 +83,7 @@ bool CWinRenderBuffer::GetTexture(uint8_t*& data, unsigned int& stride) bool CWinRenderBuffer::ReleaseTexture() { - if (!m_intermediateTarget->UnlockRect(0)) + if (!m_intermediateTarget->GetPointer()->UnlockRect(0)) { CLog::Log(LOGERROR, "WinRenderer: Failed to unlock swtarget texture"); return false; @@ -284,6 +284,13 @@ bool CRPWinRenderer::SupportsScalingMethod(SCALINGMETHOD method) void CRPWinRenderer::Render(CD3DTexture *target) { + const CPoint destPoints[4] = { + m_rotatedDestCoords[0], + m_rotatedDestCoords[1], + m_rotatedDestCoords[2], + m_rotatedDestCoords[3] + }; + CWinRenderBuffer *renderBuffer = static_cast(m_renderBuffer); if (renderBuffer == nullptr) return; @@ -292,11 +299,14 @@ void CRPWinRenderer::Render(CD3DTexture *target) if (renderBufferTarget == nullptr) return; + UpdateVideoShaders(); + // Are we using video shaders? - if (m_bUseShaderPreset && m_renderBuffer != nullptr) + if (m_bUseShaderPreset) { + // TODO: Orientation? + /* CPoint destPoints[4]; - // select destination rectangle if (m_renderOrientation) { @@ -311,8 +321,8 @@ void CRPWinRenderer::Render(CD3DTexture *target) destPoints[2] = { destRect.x2, destRect.y2 }; destPoints[3] = { destRect.x1, destRect.y2 }; } + */ - CD3DTexture *intermediateTarget = renderBufferTarget->GetPointer(); // Render shaders and ouput to display m_targetTexture.SetTexture(target); if (!m_shaderPreset->RenderUpdate(destPoints, renderBufferTarget, &m_targetTexture)) @@ -345,3 +355,4 @@ void CRPWinRenderer::Render(CD3DTexture *target) } } } +} diff --git a/xbmc/cores/RetroPlayer/rendering/VideoShaders/IVideoShaderPreset.h b/xbmc/cores/RetroPlayer/rendering/VideoShaders/IVideoShaderPreset.h index edea7024f0444..69bf7de2ba978 100644 --- a/xbmc/cores/RetroPlayer/rendering/VideoShaders/IVideoShaderPreset.h +++ b/xbmc/cores/RetroPlayer/rendering/VideoShaders/IVideoShaderPreset.h @@ -128,7 +128,7 @@ namespace SHADER * \param target The target texture. The texture that the final result will be rendered in. * \return Returns false if updating or rendering failed, true if both succeeded. */ - virtual bool RenderUpdate(CPoint dest[], IShaderTexture* source, IShaderTexture* target) = 0; + virtual bool RenderUpdate(const CPoint dest[], IShaderTexture* source, IShaderTexture* target) = 0; /*! * \brief Informs about the speed of playback diff --git a/xbmc/cores/RetroPlayer/rendering/VideoShaders/windows/VideoShaderDX.cpp b/xbmc/cores/RetroPlayer/rendering/VideoShaders/windows/VideoShaderDX.cpp index aa1e46ef91d36..7c834cafe3f77 100644 --- a/xbmc/cores/RetroPlayer/rendering/VideoShaders/windows/VideoShaderDX.cpp +++ b/xbmc/cores/RetroPlayer/rendering/VideoShaders/windows/VideoShaderDX.cpp @@ -87,7 +87,7 @@ void CVideoShaderDX::Render(IShaderTexture* source, IShaderTexture* target) auto* sourceDX = static_cast(source); auto* targetDX = static_cast(target); - // TODO: Doesn't work. Investigate calling this in Execute or binding the SRV first + // TODO: Doesn't work. Another PSSetSamplers gets called by FX11 right before rendering, overriding this /* CRenderSystemDX *renderingDx = static_cast(m_context.Rendering()); renderingDx->Get3D11Context()->PSSetSamplers(2, 1, &m_pSampler); diff --git a/xbmc/cores/RetroPlayer/rendering/VideoShaders/windows/VideoShaderPresetDX.cpp b/xbmc/cores/RetroPlayer/rendering/VideoShaders/windows/VideoShaderPresetDX.cpp index b3dd1c545dce8..609b489a083c4 100644 --- a/xbmc/cores/RetroPlayer/rendering/VideoShaders/windows/VideoShaderPresetDX.cpp +++ b/xbmc/cores/RetroPlayer/rendering/VideoShaders/windows/VideoShaderPresetDX.cpp @@ -90,7 +90,7 @@ bool CVideoShaderPresetDX::ReadPresetFile(const std::string& presetPath) return CServiceBroker::GetGameServices().VideoShaders().LoadPreset(presetPath, *this); } -bool CVideoShaderPresetDX::RenderUpdate(CPoint dest[], IShaderTexture* source, IShaderTexture* target) +bool CVideoShaderPresetDX::RenderUpdate(const CPoint dest[], IShaderTexture* source, IShaderTexture* target) { // Save the viewport CRect viewPort; @@ -422,7 +422,7 @@ bool CVideoShaderPresetDX::CreateBuffers() return true; } -void CVideoShaderPresetDX::PrepareParameters(const IShaderTexture* texture, CPoint dest[]) +void CVideoShaderPresetDX::PrepareParameters(const IShaderTexture* texture, const CPoint dest[]) { // prepare params for all shaders except the last (needs special flag) for (unsigned shaderIdx = 0; shaderIdx < m_pVideoShaders.size() - 1; ++shaderIdx) diff --git a/xbmc/cores/RetroPlayer/rendering/VideoShaders/windows/VideoShaderPresetDX.h b/xbmc/cores/RetroPlayer/rendering/VideoShaders/windows/VideoShaderPresetDX.h index efa06cb4152c2..d1e3f847a43e5 100644 --- a/xbmc/cores/RetroPlayer/rendering/VideoShaders/windows/VideoShaderPresetDX.h +++ b/xbmc/cores/RetroPlayer/rendering/VideoShaders/windows/VideoShaderPresetDX.h @@ -55,7 +55,7 @@ class CVideoShaderPresetDX : public IVideoShaderPreset // implementation of IVideoShaderPreset bool ReadPresetFile(const std::string& presetPath) override; - bool RenderUpdate(CPoint dest[], IShaderTexture* source, IShaderTexture* target) override; + bool RenderUpdate(const CPoint dest[], IShaderTexture* source, IShaderTexture* target) override; void SetSpeed(double speed) override { m_speed = speed; } void SetVideoSize(const unsigned videoWidth, const unsigned videoHeight) override; bool SetShaderPreset(const std::string& shaderPresetPath) override; @@ -75,7 +75,7 @@ class CVideoShaderPresetDX : public IVideoShaderPreset void UpdateViewPort(CRect viewPort); void UpdateMVPs(); void DisposeVideoShaders(); - void PrepareParameters(const IShaderTexture* texture, CPoint dest[]); + void PrepareParameters(const IShaderTexture* texture, const CPoint dest[]); void RenderShader(IVideoShader* shader, IShaderTexture* source, IShaderTexture* target) const; bool HasPathFailed(const std::string& path) const; diff --git a/xbmc/games/GameServices.cpp b/xbmc/games/GameServices.cpp index 62cc508d5a2c7..0d5aa8f1e93cc 100644 --- a/xbmc/games/GameServices.cpp +++ b/xbmc/games/GameServices.cpp @@ -25,7 +25,7 @@ CGameServices::CGameServices(CControllerManager &controllerManager, m_controllerManager(controllerManager), m_gameRenderManager(renderManager), m_profileManager(profileManager), - m_gameSettings(new CGameSettings()) + m_gameSettings(new CGameSettings()), m_videoShaders(new SHADER::CVideoShaderPresetFactory(addons, binaryAddons)) { } diff --git a/xbmc/games/dialogs/DialogGameDefines.h b/xbmc/games/dialogs/DialogGameDefines.h index a014286f72af6..81165811eaa10 100644 --- a/xbmc/games/dialogs/DialogGameDefines.h +++ b/xbmc/games/dialogs/DialogGameDefines.h @@ -20,4 +20,4 @@ #pragma once // String of list item property "game.videofilter" when no filter is set -#define PROPERTY_NO_VIDEO_FILTER "-" +#define PROPERTY_NO_VIDEO_FILTER "" diff --git a/xbmc/games/dialogs/osd/DialogGameVideoFilter.cpp b/xbmc/games/dialogs/osd/DialogGameVideoFilter.cpp index c8d3a4f1ca55c..a1121f96b9254 100644 --- a/xbmc/games/dialogs/osd/DialogGameVideoFilter.cpp +++ b/xbmc/games/dialogs/osd/DialogGameVideoFilter.cpp @@ -62,6 +62,7 @@ void CDialogGameVideoFilter::PreInit() { m_items.Clear(); + InitScalingMethods(); InitVideoFilters(); if (m_items.Size() == 0) @@ -73,7 +74,7 @@ void CDialogGameVideoFilter::PreInit() m_bHasDescription = false; } -void CDialogGameVideoFilter::InitVideoFilters() +void CDialogGameVideoFilter::InitScalingMethods() { if (m_gameVideoHandle) { @@ -81,12 +82,10 @@ void CDialogGameVideoFilter::InitVideoFilters() { if (m_gameVideoHandle->SupportsScalingMethod(scalingMethodProps.scalingMethod)) { - RETRO::CRenderVideoSettings videoSettings; - videoSettings.SetScalingMethod(scalingMethodProps.scalingMethod); - CFileItemPtr item = std::make_shared(g_localizeStrings.Get(scalingMethodProps.nameIndex)); item->SetLabel2(g_localizeStrings.Get(scalingMethodProps.categoryIndex)); - item->SetProperty("game.videofilter", CVariant{ videoSettings.GetVideoFilter() }); + item->SetProperty("game.videofilter", CVariant{ PROPERTY_NO_VIDEO_FILTER }); + item->SetProperty("game.scalingmethod", CVariant((int)scalingMethodProps.scalingMethod)); item->SetProperty("game.videofilterdescription", CVariant{ g_localizeStrings.Get(scalingMethodProps.descriptionIndex) }); m_items.Add(std::move(item)); } @@ -221,6 +220,11 @@ void CDialogGameVideoFilter::PostExit() m_items.Clear(); } +std::string CDialogGameVideoFilter::GetLocalizedString(uint32_t code) +{ + return g_localizeStrings.GetAddonString(PRESETS_ADDON_NAME, code); +} + void CDialogGameVideoFilter::GetProperties(const CFileItem &item, std::string &videoFilter, std::string &description) { videoFilter = item.GetProperty("game.videofilter").asString(); diff --git a/xbmc/games/dialogs/osd/DialogGameVideoFilter.h b/xbmc/games/dialogs/osd/DialogGameVideoFilter.h index 00ff9861ec74b..1603b022e582e 100644 --- a/xbmc/games/dialogs/osd/DialogGameVideoFilter.h +++ b/xbmc/games/dialogs/osd/DialogGameVideoFilter.h @@ -32,12 +32,23 @@ namespace GAME void PostExit() override; private: + void InitScalingMethods(); void InitVideoFilters(); static void GetProperties(const CFileItem &item, std::string &videoFilter, std::string &description); CFileItemList m_items; + static std::string GetLocalizedString(uint32_t code); + + struct VideoFilterProperties + { + std::string path; + int nameIndex; + int categoryIndex; + int descriptionIndex; + }; + //! \brief Set to true when a description has first been set bool m_bHasDescription = false; };