Kaydet (Commit) 12dcf5e6 authored tarafından Michael Meeks's avatar Michael Meeks

slideshow: cleanup main-loop usage, post-yield listeners, etc.

    This removes several attempts at reducing jitter in slideshow
animations. Now we have high-resolution (ie. not clamped to 10ms)
timers on Windows and a cleaner and simpler main-loop, we should
be able to use generic timer code-paths for all of this.

    This also allows us to further cleanup and simplify the main-loop
removing the now redundent post-yield handler concept. If there is a
short enough timeout, we will take just 1ms of delay before executing
a short timer anyway.

    Also removed some lingering comments from an old attempt to boost
priorities which broken audio playback.

    Tested: tdf#32861 - still works, audio still plays, no new jitter
            in animations that I tested.

Change-Id: Iadc5e2a48828a18a599a86a8df14cb2b75dd425e
Reviewed-on: https://gerrit.libreoffice.org/19947Tested-by: 's avatarJenkins <ci@libreoffice.org>
Reviewed-by: 's avatarMichael Meeks <michael.meeks@collabora.com>
üst ea6857f8
......@@ -460,8 +460,6 @@ public:
@see Quit, Reschedule, Yield, EndYield, GetSolarMutex,
GetMainThreadIdentifier, ReleaseSolarMutex, AcquireSolarMutex,
EnableNoYieldMode, DisableNoYieldMode, AddPostYieldListener,
RemovePostYieldListener
*/
static void Execute();
......@@ -469,8 +467,6 @@ public:
@see Execute, Reschedule, Yield, EndYield, GetSolarMutex,
GetMainThreadIdentifier, ReleaseSolarMutex, AcquireSolarMutex,
EnableNoYieldMode, DisableNoYieldMode, AddPostYieldListener,
RemovePostYieldListener
*/
static void Quit();
......@@ -482,8 +478,6 @@ public:
@see Execute, Quit, Yield, EndYield, GetSolarMutex,
GetMainThreadIdentifier, ReleaseSolarMutex, AcquireSolarMutex,
EnableNoYieldMode, DisableNoYieldMode, AddPostYieldListener,
RemovePostYieldListener
*/
static void Reschedule( bool bAllEvents = false );
......@@ -491,8 +485,6 @@ public:
@see Execute, Quit, Reschedule, EndYield, GetSolarMutex,
GetMainThreadIdentifier, ReleaseSolarMutex, AcquireSolarMutex,
EnableNoYieldMode, DisableNoYieldMode, AddPostYieldListener,
RemovePostYieldListener
*/
static void Yield();
......@@ -500,8 +492,6 @@ public:
@see Execute, Quit, Reschedule, Yield, GetSolarMutex,
GetMainThreadIdentifier, ReleaseSolarMutex, AcquireSolarMutex,
EnableNoYieldMode, DisableNoYieldMode, AddPostYieldListener,
RemovePostYieldListener
*/
static void EndYield();
......@@ -520,8 +510,6 @@ public:
@see Execute, Quit, Reschedule, Yield, EndYield,
GetMainThreadIdentifier, ReleaseSolarMutex, AcquireSolarMutex,
EnableNoYieldMode, DisableNoYieldMode, AddPostYieldListener,
RemovePostYieldListener
*/
static comphelper::SolarMutex& GetSolarMutex();
......@@ -531,8 +519,6 @@ public:
@see Execute, Quit, Reschedule, Yield, EndYield, GetSolarMutex,
ReleaseSolarMutex, AcquireSolarMutex,
EnableNoYieldMode, DisableNoYieldMode, AddPostYieldListener,
RemovePostYieldListener
*/
static oslThreadIdentifier GetMainThreadIdentifier();
......@@ -545,8 +531,6 @@ public:
@see Execute, Quit, Reschedule, Yield, EndYield, GetSolarMutex,
GetMainThreadIdentifier, AcquireSolarMutex,
EnableNoYieldMode, DisableNoYieldMode, AddPostYieldListener,
RemovePostYieldListener
*/
static sal_uLong ReleaseSolarMutex();
......@@ -557,59 +541,9 @@ public:
@see Execute, Quit, Reschedule, Yield, EndYield, GetSolarMutex,
GetMainThreadIdentifier, ReleaseSolarMutex,
EnableNoYieldMode, DisableNoYieldMode, AddPostYieldListener,
RemovePostYieldListener
*/
static void AcquireSolarMutex( sal_uLong nCount );
/** @brief Enables "no yield" mode
"No yield" mode prevents Yield() from waiting for events.
@remarks This was originally implemented in OOo bug 98792 to improve
Impress slideshows.
@see DisableNoYieldMode, Execute, Quit, Reschedule, Yield, EndYield, GetSolarMutex,
GetMainThreadIdentifier, ReleaseSolarMutex, AcquireSolarMutex,
DisableNoYield, AddPostYieldListener, RemovePostYieldListener
*/
static void EnableNoYieldMode();
/** @brief Disables "no yield" mode
"No yield" mode prevents Yield() from waiting for events.
@remarks This was originally implemented in OOo bug 98792 to improve
Impress slideshows.
@see EnableNoYieldMode, Execute, Quit, Reschedule, Yield, EndYield, GetSolarMutex,
GetMainThreadIdentifier, ReleaseSolarMutex, AcquireSolarMutex,
EnableNoYield, AddPostYieldListener, RemovePostYieldListener
*/
static void DisableNoYieldMode();
/** Add a listener for yield events
@param i_rListener Listener to add
@see Execute, Quit, Reschedule, Yield, EndYield, GetSolarMutex,
GetMainThreadIdentifier, ReleaseSolarMutex, AcquireSolarMutex,
EnableNoYieldMode, DisableNoYieldMode, RemovePostYieldListener
*/
static void AddPostYieldListener( const Link<LinkParamNone*,void>& i_rListener );
/** Remove listener for yield events
@param i_rListener Listener to remove
@see Execute, Quit, Reschedule, Yield, EndYield, GetSolarMutex,
GetMainThreadIdentifier, ReleaseSolarMutex, AcquireSolarMutex,
AddPostYieldListener, EnableNoYieldMode, DisableNoYieldMode
*/
static void RemovePostYieldListener( const Link<LinkParamNone*,void>& i_rListener );
/** Queries whether the application is in "main", i.e. not yet in
the event loop
......
......@@ -746,9 +746,6 @@ void SAL_CALL SlideshowImpl::disposing()
setActiveXToolbarsVisible( true );
Application::DisableNoYieldMode();
Application::RemovePostYieldListener(LINK(this, SlideshowImpl, PostYieldListener));
mbDisposed = true;
}
......@@ -1788,22 +1785,6 @@ IMPL_LINK_NOARG_TYPED(SlideshowImpl, updateHdl, Timer *, void)
updateSlideShow();
}
IMPL_LINK_NOARG_TYPED(SlideshowImpl, PostYieldListener, LinkParamNone*, void)
{
// prevent me from deletion when recursing (App::Reschedule does)
const rtl::Reference<SlideshowImpl> this_(this);
Application::DisableNoYieldMode();
Application::RemovePostYieldListener(LINK(this, SlideshowImpl, PostYieldListener));
Application::Reschedule(true); // fix for fdo#32861 - process
// *all* outstanding events after
// yield is done.
if (mbDisposed)
return;
Application::Reschedule(true);
updateSlideShow();
}
sal_Int32 SlideshowImpl::updateSlideShow()
{
// prevent me from deletion when recursing (App::EnableYieldMode does)
......@@ -1815,26 +1796,13 @@ sal_Int32 SlideshowImpl::updateSlideShow()
try
{
// TODO(Q3): Evaluate under various systems and setups,
// whether this is really necessary. Under WinXP and Matrox
// G550, the frame rates were much more steadier with this
// tweak, although.
// currently no solution, because this kills sound (at least on Windows)
double fUpdate = 0.0;
if( !xShow->update(fUpdate) )
fUpdate = -1.0;
if (mxShow.is() && (fUpdate >= 0.0))
{
if (::basegfx::fTools::equalZero(fUpdate))
{
// Use post yield listener for short update intervalls.
Application::EnableNoYieldMode();
Application::AddPostYieldListener(LINK(this, SlideshowImpl, PostYieldListener));
}
else
if (!::basegfx::fTools::equalZero(fUpdate))
{
// Avoid busy loop when the previous call to update()
// returns a small positive number but not 0 (which is
......@@ -1851,14 +1819,11 @@ sal_Int32 SlideshowImpl::updateSlideShow()
// too high (only then conversion to milliseconds and long
// integer may lead to zero value.)
OSL_ASSERT(static_cast<sal_uLong>(fUpdate * 1000.0) > 0);
Application::DisableNoYieldMode();
Application::RemovePostYieldListener(LINK(this, SlideshowImpl, PostYieldListener));
// Use a timer for the asynchronous callback.
maUpdateTimer.SetTimeout(static_cast<sal_uLong>(fUpdate * 1000.0));
maUpdateTimer.Start();
}
// Use our high resolution timers for the asynchronous callback.
maUpdateTimer.SetTimeout(static_cast<sal_uLong>(fUpdate * 1000.0));
maUpdateTimer.Start();
}
}
catch( Exception& )
......
......@@ -275,7 +275,6 @@ private:
void setActiveXToolbarsVisible( bool bVisible );
DECL_LINK_TYPED( updateHdl, Timer *, void );
DECL_LINK_TYPED( PostYieldListener, LinkParamNone*, void );
DECL_LINK_TYPED( ReadyForNextInputHdl, Timer *, void );
DECL_LINK_TYPED( endPresentationHdl, void*, void );
DECL_LINK_TYPED( ContextMenuSelectHdl, Menu *, bool );
......@@ -311,7 +310,7 @@ private:
static void setAutoSaveState( bool bOn );
void gotoPreviousSlide (const bool bSkipAllMainSequenceEffects);
/** Called by PostYieldListener and updateHdl handlers this method is
/** Called by our maUpdateTimer's updateHdl handler this method is
responsible to call the slideshow update() method and, depending on
its return value, wait for a certain amount of time before another
call to update() is scheduled.
......
......@@ -105,11 +105,6 @@ public:
typedef std::vector<Link<VclWindowEvent&,bool> > SVAppKeyListeners;
struct SVAppPostYieldListeners : public vcl::DeletionNotifier
{
std::vector<Link<LinkParamNone*,void>> m_aListeners;
};
struct ImplSVAppData
{
enum ImeStatusWindowMode
......@@ -134,7 +129,6 @@ struct ImplSVAppData
VclPtr<ImplWheelWindow> mpWheelWindow; // WheelWindow
ImplHotKey* mpFirstHotKey; // HotKey-Verwaltung
ImplEventHook* mpFirstEventHook; // Event-Hooks
SVAppPostYieldListeners* mpPostYieldListeners; // post yield listeners
sal_uInt64 mnLastInputTime; // GetLastInputTime()
sal_uInt16 mnDispatchLevel; // DispatchLevel
sal_uInt16 mnModalMode; // ModalMode Count
......@@ -146,8 +140,6 @@ struct ImplSVAppData
bool mbInAppExecute; // is Application::Execute() on stack
bool mbAppQuit; // is Application::Quit() called
bool mbSettingsInit; // true: Settings are initialized
bool mbNoYield; // Application::Yield will not wait for events if the queue is empty
// essentially that makes it the same as Application::Reschedule
Application::DialogCancelMode meDialogCancel; // true: All Dialog::Execute() calls will be terminated immediately with return false
/** Controls whether showing any IME status window is toggled on or off.
......
......@@ -492,7 +492,7 @@ inline void ImplYield(bool i_bWait, bool i_bAllEvents, sal_uLong const nReleased
// do not wait for events either if the app decided that it is too busy for timers
// (feature added for the slideshow)
pSVData->mpDefInst->DoYield(
i_bWait && !pSVData->maAppData.mbAppQuit && !pSVData->maAppData.mbNoYield,
i_bWait && !pSVData->maAppData.mbAppQuit,
i_bAllEvents, nReleased);
pSVData->maAppData.mnDispatchLevel--;
......@@ -501,31 +501,6 @@ inline void ImplYield(bool i_bWait, bool i_bAllEvents, sal_uLong const nReleased
// flush lazy deleted objects
if( pSVData->maAppData.mnDispatchLevel == 0 )
vcl::LazyDelete::flush();
// the system timer events will not necessarily come in non waiting mode
// e.g. on OS X; need to trigger timer checks manually
if( pSVData->maAppData.mbNoYield )
{
//Process all timers
Scheduler::ProcessTaskScheduling(true);
}
// call post yield listeners
if( pSVData->maAppData.mpPostYieldListeners )
{
vcl::DeletionListener aDel( pSVData->maAppData.mpPostYieldListeners );
auto& rYieldListeners = pSVData->maAppData.mpPostYieldListeners->m_aListeners;
// Copy the list, because this can be destroyed when calling a Link...
std::vector<Link<LinkParamNone*,void>> aCopy( rYieldListeners );
for( Link<LinkParamNone*,void>& rLink : aCopy )
{
if (aDel.isDeleted()) break;
// check this hasn't been removed in some re-enterancy scenario fdo#47368
if( std::find(rYieldListeners.begin(), rYieldListeners.end(), rLink) != rYieldListeners.end() )
rLink.Call( nullptr );
}
}
}
void Application::Reschedule( bool i_bAllEvents )
......@@ -1096,39 +1071,6 @@ void Application::RemoveIdleHdl( const Link<Application*,void>& rLink )
pSVData->maAppData.mpIdleMgr->RemoveIdleHdl( rLink );
}
void Application::EnableNoYieldMode()
{
ImplSVData* pSVData = ImplGetSVData();
pSVData->maAppData.mbNoYield = true;
}
void Application::DisableNoYieldMode()
{
ImplSVData* pSVData = ImplGetSVData();
pSVData->maAppData.mbNoYield = false;
}
void Application::AddPostYieldListener( const Link<LinkParamNone*,void>& i_rListener )
{
ImplSVData* pSVData = ImplGetSVData();
if( ! pSVData->maAppData.mpPostYieldListeners )
pSVData->maAppData.mpPostYieldListeners = new SVAppPostYieldListeners();
// ensure uniqueness
auto& rYieldListeners = pSVData->maAppData.mpPostYieldListeners->m_aListeners;
if (std::find(rYieldListeners.begin(), rYieldListeners.end(), i_rListener) == rYieldListeners.end())
rYieldListeners.push_back( i_rListener );
}
void Application::RemovePostYieldListener( const Link<LinkParamNone*,void>& i_rListener )
{
ImplSVData* pSVData = ImplGetSVData();
if( pSVData->maAppData.mpPostYieldListeners )
{
auto& rYieldListeners = pSVData->maAppData.mpPostYieldListeners->m_aListeners;
rYieldListeners.erase( std::remove(rYieldListeners.begin(), rYieldListeners.end(), i_rListener ), rYieldListeners.end() );
}
}
WorkWindow* Application::GetAppWindow()
{
return ImplGetSVData()->maWinData.mpAppWin;
......
......@@ -508,11 +508,6 @@ void DeInitVCL()
delete pSVData->maAppData.mpKeyListeners;
pSVData->maAppData.mpKeyListeners = nullptr;
}
if ( pSVData->maAppData.mpPostYieldListeners )
{
delete pSVData->maAppData.mpPostYieldListeners;
pSVData->maAppData.mpPostYieldListeners = nullptr;
}
if ( pSVData->maAppData.mpFirstHotKey )
ImplFreeHotKeyData();
......
......@@ -849,7 +849,7 @@ atk_object_wrapper_new( const ::com::sun::star::uno::Reference< ::com::sun::star
uno::Reference< accessibility::XAccessibleEventBroadcaster > xBroadcaster(xContext, uno::UNO_QUERY);
if( xBroadcaster.is() )
xBroadcaster->addAccessibleEventListener( static_cast< accessibility::XAccessibleEventListener * > ( new AtkListener(pWrap) ) );
else
else
OSL_ASSERT( false );
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment