Skip to content

Commit

Permalink
Merge pull request #25120 from neo1973/fix_25100
Browse files Browse the repository at this point in the history
[picture] Make picture viewer work with enabled smart redraw
  • Loading branch information
fuzzard committed May 9, 2024
2 parents dad1445 + d8c2cc7 commit 161ccd0
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 51 deletions.
13 changes: 13 additions & 0 deletions xbmc/pictures/GUIWindowSlideShow.cpp
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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);
Expand All @@ -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();
}
}

Expand All @@ -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));
Expand Down Expand Up @@ -980,6 +992,7 @@ bool CGUIWindowSlideShow::OnAction(const CAction &action)
default:
return CGUIDialog::OnAction(action);
}
MarkDirtyRegion();
return true;
}

Expand Down
129 changes: 80 additions & 49 deletions xbmc/pictures/SlideShowPicture.cpp
Expand Up @@ -16,6 +16,7 @@
#include "windowing/GraphicContext.h"
#include "windowing/WinSystem.h"

#include <cassert>
#include <mutex>

#ifndef _USE_MATH_DEFINES
Expand All @@ -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;

Expand All @@ -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;
Expand All @@ -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,
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -378,41 +377,15 @@ 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)
CLog::Log(LOGDEBUG, "Incrementing counter ({}) while not in slideshow (startlength={},endstart={},endlength={})", m_iCounter, m_transitionStart.length, m_transitionEnd.start, m_transitionEnd.length);
*/
m_iCounter++;
}
if (m_iCounter > m_transitionEnd.start + m_transitionEnd.length)
m_bIsFinished = true;

RESOLUTION_INFO info = CServiceBroker::GetWinSystem()->GetGfxContext().GetResInfo();

Expand Down Expand Up @@ -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;
Expand Down
5 changes: 3 additions & 2 deletions xbmc/pictures/SlideShowPicture.h
Expand Up @@ -50,7 +50,8 @@ class CSlideShowPic
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; }
Expand All @@ -65,6 +66,7 @@ class CSlideShowPic

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);
Expand Down Expand Up @@ -95,7 +97,6 @@ class CSlideShowPic
int m_iOriginalHeight;
int m_iSlideNumber;
bool m_bIsLoaded;
bool m_bIsFinished;
bool m_bDrawNextImage;
bool m_bIsDirty;
std::string m_strFileName;
Expand Down

0 comments on commit 161ccd0

Please sign in to comment.