From 6bb153edb55ab424a1ca7580eb6afdfe3adb882b Mon Sep 17 00:00:00 2001 From: peak3d Date: Wed, 25 Dec 2019 18:29:51 +0100 Subject: [PATCH] [Backport][Android] Simplify / fix modechange --- xbmc/platform/android/activity/XBMCApp.cpp | 10 +-- xbmc/windowing/android/WinSystemAndroid.cpp | 84 ++++++++----------- xbmc/windowing/android/WinSystemAndroid.h | 19 +---- .../android/WinSystemAndroidGLESContext.cpp | 4 + 4 files changed, 44 insertions(+), 73 deletions(-) diff --git a/xbmc/platform/android/activity/XBMCApp.cpp b/xbmc/platform/android/activity/XBMCApp.cpp index 6975a1c870367..7eb51fe57efb8 100644 --- a/xbmc/platform/android/activity/XBMCApp.cpp +++ b/xbmc/platform/android/activity/XBMCApp.cpp @@ -577,8 +577,7 @@ void CXBMCApp::SetRefreshRate(float rate) { m_displayChangeEvent.WaitMSec(5000); if (m_hdmiSource && g_application.GetAppPlayer().IsPlaying()) - dynamic_cast(CServiceBroker::GetWinSystem()) - ->SetHDMIState(CWinSystemAndroid::HDMI_STATE_UNCONNECTED_TIMER); + dynamic_cast(CServiceBroker::GetWinSystem())->InitiateModeChange(); } } @@ -606,8 +605,7 @@ void CXBMCApp::SetDisplayMode(int mode, float rate) { m_displayChangeEvent.WaitMSec(5000); if (m_hdmiSource && g_application.GetAppPlayer().IsPlaying()) - dynamic_cast(CServiceBroker::GetWinSystem()) - ->SetHDMIState(CWinSystemAndroid::HDMI_STATE_UNCONNECTED_TIMER); + dynamic_cast(CServiceBroker::GetWinSystem())->InitiateModeChange(); } } @@ -1022,9 +1020,7 @@ void CXBMCApp::onReceive(CJNIIntent intent) { CWinSystemBase* winSystem = CServiceBroker::GetWinSystem(); if (winSystem && dynamic_cast(winSystem)) - dynamic_cast(winSystem)->SetHDMIState( - m_hdmiPlugged ? CWinSystemAndroid::HDMI_STATE_CONNECTED - : CWinSystemAndroid::HDMI_STATE_UNCONNECTED); + dynamic_cast(winSystem)->SetHdmiState(m_hdmiPlugged); } } else if (action == "android.intent.action.SCREEN_OFF") diff --git a/xbmc/windowing/android/WinSystemAndroid.cpp b/xbmc/windowing/android/WinSystemAndroid.cpp index 7fea058d22f47..f48de072cd33a 100644 --- a/xbmc/windowing/android/WinSystemAndroid.cpp +++ b/xbmc/windowing/android/WinSystemAndroid.cpp @@ -50,7 +50,6 @@ CWinSystemAndroid::CWinSystemAndroid() m_stereo_mode = RENDER_STEREO_MODE_OFF; - m_dispResetState = 0; m_dispResetTimer = new CTimer(this); m_android = nullptr; @@ -127,11 +126,8 @@ bool CWinSystemAndroid::CreateNewWindow(const std::string& name, return true; } - { - CSingleLock lock(m_resourceSection); - m_dispResetTimer->Stop(); - m_dispResetState = 0; - } + m_dispResetTimer->Stop(); + m_HdmiModeTriggered = false; m_stereo_mode = stereo_mode; m_bFullScreen = fullScreen; @@ -214,66 +210,52 @@ void CWinSystemAndroid::UpdateResolutions(bool bUpdateDesktopRes) void CWinSystemAndroid::OnTimeout() { - // 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); + m_HdmiModeTriggered = true; } -void CWinSystemAndroid::SetHDMIState(uint8_t state) +void CWinSystemAndroid::InitiateModeChange() { - CSingleLock lock(m_resourceSection); - 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) + + if (delay < 2000) + delay = 2000; + m_dispResetTimer->Stop(); + m_dispResetTimer->Start(delay); + + SetHdmiState(false); +} + +void CWinSystemAndroid::SetHdmiState(bool connected) +{ + CSingleLock lock(m_resourceSection); + CLog::Log(LOGDEBUG, "CWinSystemAndroid::SetHdmiState: state: %d", static_cast(connected)); + + if (connected) { - if (m_dispResetState & RESET_WAIT_HDMIPLUG) + if (m_dispResetTimer->IsRunning()) { - m_dispResetState &= ~RESET_WAIT_HDMIPLUG; - - if (m_dispResetTimer->GetElapsedMilliseconds() >= delay) - // Most probably a pseudo (2 sec) timer -> signal now + // We stop the timer if OS supports HDMI_AUDIO_PLUG intent + // and configured delay is smaller than the time HDMI_PLUG took. + // Note that timer is always started with minimum of 2 seconds + // regardless if the configured delay is smaller + if (m_dispResetTimer->GetElapsedMilliseconds() >= + CServiceBroker::GetSettingsComponent()->GetSettings()->GetInt( + "videoscreen.delayrefreshchange") * + 100) 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(); - } + + for (auto resource : m_resources) + resource->OnResetDisplay(); + m_dispResetTimer->Stop(); + m_HdmiModeTriggered = false; } else { - // Second call of !connected is called from HDMI_PLUG - if (m_dispResetState & RESET_WAIT_TIMER) - { - m_dispResetState |= RESET_WAIT_HDMIPLUG; - return; - } - m_dispResetState = RESET_WAIT_TIMER; - - 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 ab3143ff59070..72628b3816a94 100644 --- a/xbmc/windowing/android/WinSystemAndroid.h +++ b/xbmc/windowing/android/WinSystemAndroid.h @@ -35,7 +35,9 @@ class CWinSystemAndroid : public CWinSystemBase, public ITimerCallback bool DestroyWindow() override; void UpdateResolutions() override; - void SetHDMIState(uint8_t state); + void InitiateModeChange(); + bool IsHdmiModeTriggered() const { return m_HdmiModeTriggered; }; + void SetHdmiState(bool connected); void UpdateDisplayModes(); @@ -51,13 +53,6 @@ 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; @@ -72,13 +67,6 @@ class CWinSystemAndroid : public CWinSystemBase, public ITimerCallback RENDER_STEREO_MODE m_stereo_mode; - enum RESETSTATE : uint8_t - { - RESET_WAIT_TIMER = 1U << 0, - RESET_WAIT_HDMIPLUG = 1U << 1, - }; - - uint8_t m_dispResetState; CTimer *m_dispResetTimer; CCriticalSection m_resourceSection; @@ -86,5 +74,6 @@ class CWinSystemAndroid : public CWinSystemBase, public ITimerCallback CDecoderFilterManager *m_decoderFilterManager; private: + bool m_HdmiModeTriggered = false; void UpdateResolutions(bool bUpdateDesktopRes); }; diff --git a/xbmc/windowing/android/WinSystemAndroidGLESContext.cpp b/xbmc/windowing/android/WinSystemAndroidGLESContext.cpp index 755c94ed0e015..e4ae745db0038 100644 --- a/xbmc/windowing/android/WinSystemAndroidGLESContext.cpp +++ b/xbmc/windowing/android/WinSystemAndroidGLESContext.cpp @@ -102,6 +102,10 @@ void CWinSystemAndroidGLESContext::PresentRenderImpl(bool rendered) return; } + // Mode change finalization was triggered by timer + if (IsHdmiModeTriggered()) + SetHdmiState(true); + // Ignore EGL_BAD_SURFACE: It seems to happen during/after mode changes, but // we can't actually do anything about it if (rendered && !m_pGLContext.TrySwapBuffers())