diff options
author | fuzzard <fuzzard@users.noreply.github.com> | 2024-05-09 19:30:34 +1000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-05-09 19:30:34 +1000 |
commit | 161ccd09dca7980500bccc06e5b6012c11ea9a8b (patch) | |
tree | ea0dab33f02d9799cd9c92b80afb1e8267ffff28 | |
parent | dad1445ba04d5a3d4709b61af5fdd9dbe5c9db8c (diff) | |
parent | d8c2cc727a4e9830d1346af740f3a36cc58ba247 (diff) | |
download | xbmc-161ccd09dca7980500bccc06e5b6012c11ea9a8b.tar.xz |
Merge pull request #25120 from neo1973/fix_25100
[picture] Make picture viewer work with enabled smart redraw
-rw-r--r-- | xbmc/pictures/GUIWindowSlideShow.cpp | 13 | ||||
-rw-r--r-- | xbmc/pictures/SlideShowPicture.cpp | 129 | ||||
-rw-r--r-- | xbmc/pictures/SlideShowPicture.h | 5 |
3 files changed, 96 insertions, 51 deletions
diff --git a/xbmc/pictures/GUIWindowSlideShow.cpp b/xbmc/pictures/GUIWindowSlideShow.cpp index 4a47726dc8..b1fe3d56c5 100644 --- a/xbmc/pictures/GUIWindowSlideShow.cpp +++ b/xbmc/pictures/GUIWindowSlideShow.cpp @@ -408,9 +408,12 @@ void CGUIWindowSlideShow::Process(unsigned int currentTime, CDirtyRegionList &re // if we haven't processed yet, we should mark the whole screen if (!HasProcessed()) + { regions.emplace_back(CRect( 0.0f, 0.0f, static_cast<float>(CServiceBroker::GetWinSystem()->GetGfxContext().GetWidth()), static_cast<float>(CServiceBroker::GetWinSystem()->GetGfxContext().GetHeight()))); + MarkDirtyRegion(); + } if (m_iCurrentSlide < 0 || m_iCurrentSlide >= static_cast<int>(m_slides.size())) m_iCurrentSlide = 0; @@ -496,6 +499,7 @@ void CGUIWindowSlideShow::Process(unsigned int currentTime, CDirtyRegionList &re regions.emplace_back(CRect( 0.0f, 0.0f, static_cast<float>(CServiceBroker::GetWinSystem()->GetGfxContext().GetWidth()), static_cast<float>(CServiceBroker::GetWinSystem()->GetGfxContext().GetHeight()))); + MarkDirtyRegion(); return; } @@ -558,6 +562,9 @@ void CGUIWindowSlideShow::Process(unsigned int currentTime, CDirtyRegionList &re // render the current image if (m_Image[m_iCurrentPic]->IsLoaded()) { + if (m_Image[m_iCurrentPic]->IsAnimating()) + MarkDirtyRegion(); + m_Image[m_iCurrentPic]->SetInSlideshow(bSlideShow); m_Image[m_iCurrentPic]->Pause(!bSlideShow); m_Image[m_iCurrentPic]->Process(currentTime, regions); @@ -572,6 +579,7 @@ void CGUIWindowSlideShow::Process(unsigned int currentTime, CDirtyRegionList &re { m_Image[m_iCurrentPic]->SetTransitionTime(1, IMMEDIATE_TRANSITION_TIME); m_bLoadNextPic = false; + MarkDirtyRegion(); } } @@ -598,6 +606,10 @@ void CGUIWindowSlideShow::Process(unsigned int currentTime, CDirtyRegionList &re if (m_Image[1 - m_iCurrentPic]->DisplayEffectNeedChange(effect)) m_Image[1 - m_iCurrentPic]->Reset(effect); } + + if (m_Image[1 - m_iCurrentPic]->IsAnimating()) + MarkDirtyRegion(); + // set the appropriate transition time m_Image[1 - m_iCurrentPic]->SetTransitionTime(0, m_Image[m_iCurrentPic]->GetTransitionTime(1)); @@ -980,6 +992,7 @@ bool CGUIWindowSlideShow::OnAction(const CAction &action) default: return CGUIDialog::OnAction(action); } + MarkDirtyRegion(); return true; } diff --git a/xbmc/pictures/SlideShowPicture.cpp b/xbmc/pictures/SlideShowPicture.cpp index fd0fd2cdd6..b66c27520e 100644 --- a/xbmc/pictures/SlideShowPicture.cpp +++ b/xbmc/pictures/SlideShowPicture.cpp @@ -16,6 +16,7 @@ #include "windowing/GraphicContext.h" #include "windowing/WinSystem.h" +#include <cassert> #include <mutex> #ifndef _USE_MATH_DEFINES @@ -38,7 +39,6 @@ static float zoomamount[10] = { 1.0f, 1.2f, 1.5f, 2.0f, 2.8f, 4.0f, 6.0f, 9.0f, CSlideShowPic::CSlideShowPic() : m_pImage(nullptr) { m_bIsLoaded = false; - m_bIsFinished = false; m_bDrawNextImage = false; m_bTransitionImmediately = false; @@ -56,7 +56,6 @@ void CSlideShowPic::Close() std::unique_lock<CCriticalSection> lock(m_textureAccess); m_pImage.reset(); m_bIsLoaded = false; - m_bIsFinished = false; m_bDrawNextImage = false; m_bTransitionImmediately = false; m_bIsDirty = true; @@ -81,6 +80,21 @@ bool CSlideShowPic::DisplayEffectNeedChange(DISPLAY_EFFECT newDispEffect) const return true; } +bool CSlideShowPic::IsFinished() const +{ + return IsLoaded() && m_iCounter >= m_transitionEnd.start + m_transitionEnd.length; +} + +bool CSlideShowPic::IsAnimating() const +{ + return !IsFinished() && + (m_displayEffect != EFFECT_NO_TIMEOUT || // Special snowflake, doesn't work without this + m_iCounter < m_transitionStart.length || // Inside start transition + m_iCounter >= m_transitionEnd.start || // Inside end transition + (m_iCounter >= m_transitionTemp.start && + m_iCounter < m_transitionTemp.start + m_transitionTemp.length)); // Inside display effect +} + void CSlideShowPic::SetTexture(int iSlideNumber, std::unique_ptr<CTexture> pTexture, DISPLAY_EFFECT dispEffect, @@ -207,7 +221,6 @@ void CSlideShowPic::SetTexture_Internal(int iSlideNumber, m_transitionEnd.start = m_transitionStart.length + iFrames; - m_bIsFinished = false; m_bDrawNextImage = false; m_bIsLoaded = true; } @@ -272,25 +285,11 @@ void CSlideShowPic::UpdateVertices(float cur_x[4], float cur_y[4], const float n void CSlideShowPic::Process(unsigned int currentTime, CDirtyRegionList &dirtyregions) { - if (!m_pImage || !m_bIsLoaded || m_bIsFinished) return ; - UTILS::COLOR::Color alpha = m_alpha; - if (m_iCounter <= m_transitionStart.length) - { // do start transition - if (m_transitionStart.type == CROSSFADE) - { // fade in at 1x speed - alpha = (UTILS::COLOR::Color)((float)m_iCounter / (float)m_transitionStart.length * 255.0f); - } - else if (m_transitionStart.type == FADEIN_FADEOUT) - { // fade in at 2x speed, then keep solid - alpha = - (UTILS::COLOR::Color)((float)m_iCounter / (float)m_transitionStart.length * 255.0f * 2); - if (alpha > 255) alpha = 255; - } - else // m_transitionEffect == TRANSITION_NONE - { - alpha = 0xFF; // opaque - } - } + if (!m_pImage || !m_bIsLoaded || IsFinished()) + return; + + UpdateAlpha(); + bool bPaused = m_bPause | (m_fZoomAmount != 1.0f); // check if we're doing a temporary effect (such as rotate + zoom) if (m_transitionTemp.type != TRANSITION_NONE) @@ -378,32 +377,8 @@ void CSlideShowPic::Process(unsigned int currentTime, CDirtyRegionList &dirtyreg m_transitionEnd.start++; } if (m_iCounter >= m_transitionEnd.start) - { // do end transition -// CLog::Log(LOGDEBUG,"Transitioning"); m_bDrawNextImage = true; - if (m_transitionEnd.type == CROSSFADE) - { // fade out at 1x speed - alpha = 255 - (UTILS::COLOR::Color)((float)(m_iCounter - m_transitionEnd.start) / - (float)m_transitionEnd.length * 255.0f); - } - else if (m_transitionEnd.type == FADEIN_FADEOUT) - { // keep solid, then fade out at 2x speed - alpha = (UTILS::COLOR::Color)( - (float)(m_transitionEnd.length - m_iCounter + m_transitionEnd.start) / - (float)m_transitionEnd.length * 255.0f * 2); - if (alpha > 255) alpha = 255; - } - else // m_transitionEffect == TRANSITION_NONE - { - alpha = 0xFF; // opaque - } - } - if (alpha != m_alpha) - { - m_alpha = alpha; - m_bIsDirty = true; - } - if (m_displayEffect != EFFECT_NO_TIMEOUT || m_iCounter < m_transitionStart.length || m_iCounter >= m_transitionEnd.start || (m_iCounter >= m_transitionTemp.start && m_iCounter < m_transitionTemp.start + m_transitionTemp.length)) + if (IsAnimating()) { /* this really annoying. there's non-stop logging when viewing a pic outside of the slideshow if (m_displayEffect == EFFECT_NO_TIMEOUT) @@ -411,8 +386,6 @@ void CSlideShowPic::Process(unsigned int currentTime, CDirtyRegionList &dirtyreg */ m_iCounter++; } - if (m_iCounter > m_transitionEnd.start + m_transitionEnd.length) - m_bIsFinished = true; RESOLUTION_INFO info = CServiceBroker::GetWinSystem()->GetGfxContext().GetResInfo(); @@ -717,6 +690,64 @@ void CSlideShowPic::Zoom(float fZoom, bool immediate /* = false */) m_bNoEffect = true; } +void CSlideShowPic::UpdateAlpha() +{ + assert(m_iCounter >= 0); + + UTILS::COLOR::Color alpha = m_alpha; + + if (m_iCounter < m_transitionStart.length) + { // do start transition + switch (m_transitionStart.type) + { + case CROSSFADE: + // fade in at 1x speed + alpha = + static_cast<UTILS::COLOR::Color>(static_cast<float>(m_iCounter + 1) / + static_cast<float>(m_transitionStart.length) * 255.0f); + break; + case FADEIN_FADEOUT: + // fade in at 2x speed, then keep solid + alpha = std::min(static_cast<UTILS::COLOR::Color>( + static_cast<float>(m_iCounter + 1) / + static_cast<float>(m_transitionStart.length) * 255.0f * 2), + UTILS::COLOR::Color{255}); + break; + default: + alpha = 255; // opaque + } + } + + if (m_iCounter >= m_transitionEnd.start) + { // do end transition + switch (m_transitionEnd.type) + { + case CROSSFADE: + // fade in at 1x speed + alpha = 255 - static_cast<UTILS::COLOR::Color>( + static_cast<float>(m_iCounter - m_transitionEnd.start + 1) / + static_cast<float>(m_transitionEnd.length) * 255.0f); + break; + case FADEIN_FADEOUT: + // fade in at 2x speed, then keep solid + alpha = std::min(static_cast<UTILS::COLOR::Color>( + static_cast<float>(m_transitionEnd.length - m_iCounter + + m_transitionEnd.start + 1) / + static_cast<float>(m_transitionEnd.length) * 255.0f * 2), + UTILS::COLOR::Color{255}); + break; + default: + alpha = 255; // opaque + } + } + + if (alpha != m_alpha) + { + m_alpha = alpha; + m_bIsDirty = true; + } +} + void CSlideShowPic::Move(float fDeltaX, float fDeltaY) { m_fZoomLeft += fDeltaX; diff --git a/xbmc/pictures/SlideShowPicture.h b/xbmc/pictures/SlideShowPicture.h index 9e2a5d9323..6b480fb166 100644 --- a/xbmc/pictures/SlideShowPicture.h +++ b/xbmc/pictures/SlideShowPicture.h @@ -50,7 +50,8 @@ public: DISPLAY_EFFECT DisplayEffect() const { return m_displayEffect; } bool DisplayEffectNeedChange(DISPLAY_EFFECT newDispEffect) const; bool IsStarted() const { return m_iCounter > 0; } - bool IsFinished() const { return m_bIsFinished; } + bool IsFinished() const; + bool IsAnimating() const; bool DrawNextImage() const { return m_bDrawNextImage; } int GetWidth() const { return (int)m_fWidth; } @@ -65,6 +66,7 @@ public: void Zoom(float fZoomAmount, bool immediate = false); void Rotate(float fRotateAngle, bool immediate = false); + void UpdateAlpha(); void Pause(bool bPause); void SetInSlideshow(bool slideshow); void SetOriginalSize(int iOriginalWidth, int iOriginalHeight, bool bFullSize); @@ -95,7 +97,6 @@ private: int m_iOriginalHeight; int m_iSlideNumber; bool m_bIsLoaded; - bool m_bIsFinished; bool m_bDrawNextImage; bool m_bIsDirty; std::string m_strFileName; |