2016-11-18 13:37:04 +03:00
|
|
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
2017-10-28 02:10:06 +03:00
|
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
2016-11-18 13:37:04 +03:00
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
|
|
|
|
#ifndef mozilla_layers_CompositorVsyncScheduler_h
|
|
|
|
#define mozilla_layers_CompositorVsyncScheduler_h
|
|
|
|
|
|
|
|
#include <stdint.h> // for uint64_t
|
|
|
|
|
|
|
|
#include "mozilla/Attributes.h" // for override
|
|
|
|
#include "mozilla/Monitor.h" // for Monitor
|
|
|
|
#include "mozilla/RefPtr.h" // for RefPtr
|
|
|
|
#include "mozilla/TimeStamp.h" // for TimeStamp
|
|
|
|
#include "mozilla/gfx/Point.h" // for IntSize
|
|
|
|
#include "mozilla/VsyncDispatcher.h"
|
|
|
|
#include "mozilla/widget/CompositorWidget.h"
|
|
|
|
#include "nsISupportsImpl.h"
|
|
|
|
|
|
|
|
|
|
|
|
class MessageLoop;
|
|
|
|
class nsIWidget;
|
|
|
|
|
|
|
|
namespace mozilla {
|
|
|
|
|
|
|
|
class CancelableRunnable;
|
2017-12-09 09:46:14 +03:00
|
|
|
class Runnable;
|
2016-11-18 13:37:04 +03:00
|
|
|
|
|
|
|
namespace gfx {
|
|
|
|
class DrawTarget;
|
|
|
|
} // namespace gfx
|
|
|
|
|
|
|
|
namespace layers {
|
|
|
|
|
2016-11-21 04:14:32 +03:00
|
|
|
class CompositorVsyncSchedulerOwner;
|
2016-11-18 13:37:04 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Manages the vsync (de)registration and tracking on behalf of the
|
|
|
|
* compositor when it need to paint.
|
|
|
|
* Turns vsync notifications into scheduled composites.
|
|
|
|
**/
|
|
|
|
class CompositorVsyncScheduler
|
|
|
|
{
|
|
|
|
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CompositorVsyncScheduler)
|
|
|
|
|
|
|
|
public:
|
|
|
|
explicit CompositorVsyncScheduler(CompositorVsyncSchedulerOwner* aVsyncSchedulerOwner,
|
|
|
|
widget::CompositorWidget* aWidget);
|
|
|
|
|
2018-02-02 00:28:53 +03:00
|
|
|
/**
|
|
|
|
* Notify this class of a vsync. This will trigger a composite if one is
|
|
|
|
* needed. This must be called from the vsync dispatch thread.
|
|
|
|
*/
|
2016-11-18 13:37:04 +03:00
|
|
|
bool NotifyVsync(TimeStamp aVsyncTimestamp);
|
|
|
|
|
2018-02-02 00:28:53 +03:00
|
|
|
/**
|
|
|
|
* Do cleanup. This must be called on the compositor thread.
|
|
|
|
*/
|
2016-11-18 13:37:04 +03:00
|
|
|
void Destroy();
|
2018-02-02 00:28:53 +03:00
|
|
|
|
2018-02-02 00:28:53 +03:00
|
|
|
/**
|
|
|
|
* Notify this class that a composition is needed. This will trigger a
|
|
|
|
* composition soon (likely at the next vsync). This must be called on the
|
|
|
|
* compositor thread.
|
|
|
|
*/
|
2016-11-18 13:37:04 +03:00
|
|
|
void ScheduleComposition();
|
2018-02-02 00:28:53 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Cancel any composite task that has been scheduled but hasn't run yet.
|
|
|
|
*/
|
2016-11-18 13:37:04 +03:00
|
|
|
void CancelCurrentCompositeTask();
|
2018-02-02 00:28:53 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Check if a composite is pending. This is generally true between a call
|
|
|
|
* to ScheduleComposition() and the time the composite happens.
|
|
|
|
*/
|
2016-11-18 13:37:04 +03:00
|
|
|
bool NeedsComposite();
|
2018-02-02 00:28:53 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Force a composite to happen right away, without waiting for the next vsync.
|
|
|
|
* This must be called on the compositor thread.
|
|
|
|
*/
|
2016-11-18 13:37:04 +03:00
|
|
|
void ForceComposeToTarget(gfx::DrawTarget* aTarget, const gfx::IntRect* aRect);
|
|
|
|
|
|
|
|
const TimeStamp& GetLastComposeTime()
|
|
|
|
{
|
|
|
|
return mLastCompose;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef COMPOSITOR_PERFORMANCE_WARNING
|
|
|
|
const TimeStamp& GetExpectedComposeStartTime()
|
|
|
|
{
|
|
|
|
return mExpectedComposeStartTime;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
private:
|
|
|
|
virtual ~CompositorVsyncScheduler();
|
|
|
|
|
2018-02-02 00:28:50 +03:00
|
|
|
// Schedule a task to run on the compositor thread.
|
|
|
|
void ScheduleTask(already_AddRefed<CancelableRunnable>);
|
2018-02-02 00:28:52 +03:00
|
|
|
|
|
|
|
// Post a task to run Composite() on the compositor thread, if there isn't
|
|
|
|
// such a task already queued. Can be called from any thread.
|
|
|
|
void PostCompositeTask(TimeStamp aCompositeTimestamp);
|
|
|
|
|
|
|
|
// Post a task to run DispatchVREvents() on the VR thread, if there isn't
|
|
|
|
// such a task already queued. Can be called from any thread.
|
|
|
|
void PostVRTask(TimeStamp aTimestamp);
|
|
|
|
|
2018-02-02 00:28:53 +03:00
|
|
|
// This gets run at vsync time and "does" a composite (which really means
|
|
|
|
// update internal state and call the owner to do the composite).
|
|
|
|
void Composite(TimeStamp aVsyncTimestamp);
|
|
|
|
|
2016-11-18 13:37:04 +03:00
|
|
|
void NotifyCompositeTaskExecuted();
|
|
|
|
void ObserveVsync();
|
|
|
|
void UnobserveVsync();
|
|
|
|
void DispatchTouchEvents(TimeStamp aVsyncTimestamp);
|
|
|
|
void DispatchVREvents(TimeStamp aVsyncTimestamp);
|
|
|
|
|
|
|
|
class Observer final : public VsyncObserver
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
explicit Observer(CompositorVsyncScheduler* aOwner);
|
|
|
|
virtual bool NotifyVsync(TimeStamp aVsyncTimestamp) override;
|
|
|
|
void Destroy();
|
|
|
|
private:
|
|
|
|
virtual ~Observer();
|
|
|
|
|
|
|
|
Mutex mMutex;
|
|
|
|
// Hold raw pointer to avoid mutual reference.
|
|
|
|
CompositorVsyncScheduler* mOwner;
|
|
|
|
};
|
|
|
|
|
|
|
|
CompositorVsyncSchedulerOwner* mVsyncSchedulerOwner;
|
|
|
|
TimeStamp mLastCompose;
|
|
|
|
|
|
|
|
#ifdef COMPOSITOR_PERFORMANCE_WARNING
|
|
|
|
TimeStamp mExpectedComposeStartTime;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
bool mAsapScheduling;
|
|
|
|
bool mIsObservingVsync;
|
|
|
|
uint32_t mNeedsComposite;
|
|
|
|
int32_t mVsyncNotificationsSkipped;
|
|
|
|
widget::CompositorWidget* mWidget;
|
|
|
|
RefPtr<CompositorVsyncScheduler::Observer> mVsyncObserver;
|
|
|
|
|
|
|
|
mozilla::Monitor mCurrentCompositeTaskMonitor;
|
|
|
|
RefPtr<CancelableRunnable> mCurrentCompositeTask;
|
|
|
|
|
2017-10-05 13:12:45 +03:00
|
|
|
mozilla::Monitor mCurrentVRListenerTaskMonitor;
|
2017-12-09 09:46:14 +03:00
|
|
|
RefPtr<Runnable> mCurrentVRListenerTask;
|
2016-11-18 13:37:04 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace layers
|
|
|
|
} // namespace mozilla
|
|
|
|
|
|
|
|
#endif // mozilla_layers_CompositorVsyncScheduler_h
|