From f18947727b81011719c7cb6c990b332be37e512b Mon Sep 17 00:00:00 2001 From: peak3d Date: Fri, 29 Nov 2019 00:47:46 +0100 Subject: [PATCH] [Android] Priorize timer instead HDMI_AUDIOPLUG on refreshrate switch --- xbmc/platform/android/activity/XBMCApp.cpp | 10 ++- xbmc/windowing/android/WinSystemAndroid.cpp | 80 +++++++++++++-------- xbmc/windowing/android/WinSystemAndroid.h | 18 +++-- 3 files changed, 71 insertions(+), 37 deletions(-) diff --git a/xbmc/platform/android/activity/XBMCApp.cpp b/xbmc/platform/android/activity/XBMCApp.cpp index a6bab84433c04..6975a1c870367 100644 --- a/xbmc/platform/android/activity/XBMCApp.cpp +++ b/xbmc/platform/android/activity/XBMCApp.cpp @@ -577,7 +577,8 @@ void CXBMCApp::SetRefreshRate(float rate) { m_displayChangeEvent.WaitMSec(5000); if (m_hdmiSource && g_application.GetAppPlayer().IsPlaying()) - dynamic_cast(CServiceBroker::GetWinSystem())->SetHDMIState(false); + dynamic_cast(CServiceBroker::GetWinSystem()) + ->SetHDMIState(CWinSystemAndroid::HDMI_STATE_UNCONNECTED_TIMER); } } @@ -605,7 +606,8 @@ void CXBMCApp::SetDisplayMode(int mode, float rate) { m_displayChangeEvent.WaitMSec(5000); if (m_hdmiSource && g_application.GetAppPlayer().IsPlaying()) - dynamic_cast(CServiceBroker::GetWinSystem())->SetHDMIState(false); + dynamic_cast(CServiceBroker::GetWinSystem()) + ->SetHDMIState(CWinSystemAndroid::HDMI_STATE_UNCONNECTED_TIMER); } } @@ -1020,7 +1022,9 @@ void CXBMCApp::onReceive(CJNIIntent intent) { CWinSystemBase* winSystem = CServiceBroker::GetWinSystem(); if (winSystem && dynamic_cast(winSystem)) - dynamic_cast(winSystem)->SetHDMIState(m_hdmiPlugged); + dynamic_cast(winSystem)->SetHDMIState( + m_hdmiPlugged ? CWinSystemAndroid::HDMI_STATE_CONNECTED + : CWinSystemAndroid::HDMI_STATE_UNCONNECTED); } } else if (action == "android.intent.action.SCREEN_OFF") diff --git a/xbmc/windowing/android/WinSystemAndroid.cpp b/xbmc/windowing/android/WinSystemAndroid.cpp index 7890f0437c7e3..7fea058d22f47 100644 --- a/xbmc/windowing/android/WinSystemAndroid.cpp +++ b/xbmc/windowing/android/WinSystemAndroid.cpp @@ -50,7 +50,7 @@ CWinSystemAndroid::CWinSystemAndroid() m_stereo_mode = RENDER_STEREO_MODE_OFF; - m_dispResetState = RESET_NOTWAITING; + m_dispResetState = 0; m_dispResetTimer = new CTimer(this); m_android = nullptr; @@ -127,10 +127,10 @@ bool CWinSystemAndroid::CreateNewWindow(const std::string& name, return true; } - if (m_dispResetState != RESET_NOTWAITING) { - CLog::Log(LOGERROR, "CWinSystemAndroid::CreateNewWindow: cannot create window while resetting"); - return false; + CSingleLock lock(m_resourceSection); + m_dispResetTimer->Stop(); + m_dispResetState = 0; } m_stereo_mode = stereo_mode; @@ -214,41 +214,65 @@ void CWinSystemAndroid::UpdateResolutions(bool bUpdateDesktopRes) void CWinSystemAndroid::OnTimeout() { - m_dispResetState = RESET_WAITEVENT; - SetHDMIState(true); + // We don't trigger OnResetDisplay if we wait for HDMI connect + { + CSingleLock lock(m_resourceSection); + if (m_dispResetState & RESET_WAIT_HDMIPLUG) + { + // Let HDMI_PLUG trigger the reset + m_dispResetState &= ~RESET_WAIT_HDMIPLUG; + return; + } + } + SetHDMIState(HDMI_STATE_CONNECTED); } -void CWinSystemAndroid::SetHDMIState(bool connected) +void CWinSystemAndroid::SetHDMIState(uint8_t state) { CSingleLock lock(m_resourceSection); - CLog::Log(LOGDEBUG, "CWinSystemAndroid::SetHDMIState: connected: %d, dispResetState: %d", static_cast(connected), m_dispResetState); - if (connected && m_dispResetState != RESET_NOTWAITING) + CLog::Log(LOGDEBUG, "CWinSystemAndroid::SetHDMIState: state: %d, dispResetState: %d", + static_cast(state), m_dispResetState); + int delay = CServiceBroker::GetSettingsComponent()->GetSettings()->GetInt( + "videoscreen.delayrefreshchange") * + 100; + if (state & HDMI_STATE_CONNECTED) { - for (auto resource : m_resources) - resource->OnResetDisplay(); - m_dispResetState = RESET_NOTWAITING; - m_dispResetTimer->Stop(); + if (m_dispResetState & RESET_WAIT_HDMIPLUG) + { + m_dispResetState &= ~RESET_WAIT_HDMIPLUG; + + if (m_dispResetTimer->GetElapsedMilliseconds() >= delay) + // Most probably a pseudo (2 sec) timer -> signal now + m_dispResetTimer->Stop(); + else + // Let the timer signal end of switch + return; + } + if (m_dispResetState == RESET_WAIT_TIMER) + { + for (auto resource : m_resources) + resource->OnResetDisplay(); + m_dispResetState = 0; + m_dispResetTimer->Stop(); + } } - else if (!connected) + else { - if (m_dispResetState == RESET_WAITTIMER) + // Second call of !connected is called from HDMI_PLUG + if (m_dispResetState & RESET_WAIT_TIMER) { - //HDMI_AUDIOPLUG arrived, use this - m_dispResetTimer->Stop(); - m_dispResetState = RESET_WAITEVENT; + m_dispResetState |= RESET_WAIT_HDMIPLUG; return; } - else if (m_dispResetState != RESET_NOTWAITING) - return; - - int delay = CServiceBroker::GetSettingsComponent()->GetSettings()->GetInt("videoscreen.delayrefreshchange") * 100; + m_dispResetState = RESET_WAIT_TIMER; - if (delay < 2000) - delay = 2000; - - m_dispResetState = RESET_WAITTIMER; - m_dispResetTimer->Stop(); - m_dispResetTimer->Start(delay); + if (state & HDMI_STATE_UNCONNECTED_TIMER) + { + if (delay < 2000) + delay = 2000; + m_dispResetTimer->Stop(); + m_dispResetTimer->Start(delay); + } for (auto resource : m_resources) resource->OnLostDisplay(); diff --git a/xbmc/windowing/android/WinSystemAndroid.h b/xbmc/windowing/android/WinSystemAndroid.h index 06822233489c9..ab3143ff59070 100644 --- a/xbmc/windowing/android/WinSystemAndroid.h +++ b/xbmc/windowing/android/WinSystemAndroid.h @@ -35,7 +35,7 @@ class CWinSystemAndroid : public CWinSystemBase, public ITimerCallback bool DestroyWindow() override; void UpdateResolutions() override; - void SetHDMIState(bool connected); + void SetHDMIState(uint8_t state); void UpdateDisplayModes(); @@ -51,6 +51,13 @@ class CWinSystemAndroid : public CWinSystemBase, public ITimerCallback // winevents override bool MessagePump() override; + enum HDMISTATE : uint8_t + { + HDMI_STATE_UNCONNECTED = 0, + HDMI_STATE_CONNECTED = 1, + HDMI_STATE_UNCONNECTED_TIMER = 2, + }; + protected: std::unique_ptr GetOSScreenSaverImpl() override; void OnTimeout() override; @@ -65,14 +72,13 @@ class CWinSystemAndroid : public CWinSystemBase, public ITimerCallback RENDER_STEREO_MODE m_stereo_mode; - enum RESETSTATE + enum RESETSTATE : uint8_t { - RESET_NOTWAITING, - RESET_WAITTIMER, - RESET_WAITEVENT + RESET_WAIT_TIMER = 1U << 0, + RESET_WAIT_HDMIPLUG = 1U << 1, }; - RESETSTATE m_dispResetState; + uint8_t m_dispResetState; CTimer *m_dispResetTimer; CCriticalSection m_resourceSection;