Skip to content

Commit

Permalink
Backout vsync
Browse files Browse the repository at this point in the history
  • Loading branch information
tmeshkova committed Nov 16, 2014
1 parent 0d7df7b commit 68f5a69
Show file tree
Hide file tree
Showing 5 changed files with 16 additions and 224 deletions.
1 change: 1 addition & 0 deletions embedding/embedlite/embedding.js
@@ -1,4 +1,5 @@
pref("dom.w3c_touch_events.enabled", 1);
pref("apz.overscroll.enabled", false);
pref("plugins.force.wmode", "opaque");
pref("browser.xul.error_pages.enabled", true);
pref("nglayout.debug.paint_flashing", false);
Expand Down
193 changes: 12 additions & 181 deletions gfx/layers/ipc/CompositorParent.cpp
Expand Up @@ -63,11 +63,6 @@
#ifdef MOZ_ENABLE_PROFILER_SPS
#include "ProfilerMarkers.h"
#endif
#include "mozilla/VsyncDispatcher.h"

#ifdef MOZ_WIDGET_GONK
#include "GeckoTouchDispatcher.h"
#endif

namespace mozilla {
namespace layers {
Expand Down Expand Up @@ -195,129 +190,6 @@ static void SetThreadPriority()
hal::SetCurrentThreadPriority(hal::THREAD_PRIORITY_COMPOSITOR);
}

CompositorVsyncObserver::CompositorVsyncObserver(CompositorParent* aCompositorParent)
: mNeedsComposite(false)
, mIsObservingVsync(false)
, mCompositorParent(aCompositorParent)
, mCurrentCompositeTaskMonitor("CurrentCompositeTaskMonitor")
, mCurrentCompositeTask(nullptr)
{

}

CompositorVsyncObserver::~CompositorVsyncObserver()
{
MOZ_ASSERT(NS_IsMainThread());
UnobserveVsync();
mCompositorParent = nullptr;
mNeedsComposite = false;
CancelCurrentCompositeTask();
}

/**
* TODO Potential performance heuristics:
* If a composite takes 17 ms, do we composite ASAP or wait until next vsync?
* If a layer transaction comes after vsync, do we composite ASAP or wait until
* next vsync?
* How many skipped vsync events until we stop listening to vsync events?
*/
void
CompositorVsyncObserver::SetNeedsComposite(bool aNeedsComposite)
{
MOZ_ASSERT(CompositorParent::IsInCompositorThread());
mNeedsComposite = aNeedsComposite;

if (!mIsObservingVsync && mNeedsComposite) {
ObserveVsync();
}
}

bool
CompositorVsyncObserver::NotifyVsync(TimeStamp aVsyncTimestamp)
{
// Called from the vsync dispatch thread
MOZ_ASSERT(!CompositorParent::IsInCompositorThread());
MOZ_ASSERT(!NS_IsMainThread());

MonitorAutoLock lock(mCurrentCompositeTaskMonitor);
if (mCurrentCompositeTask == nullptr) {
mCurrentCompositeTask = NewRunnableMethod(this,
&CompositorVsyncObserver::Composite,
aVsyncTimestamp);
CompositorParent::CompositorLoop()->PostTask(FROM_HERE, mCurrentCompositeTask);
}
return true;
}

void
CompositorVsyncObserver::CancelCurrentCompositeTask()
{
MOZ_ASSERT(CompositorParent::IsInCompositorThread() || NS_IsMainThread());
MonitorAutoLock lock(mCurrentCompositeTaskMonitor);
if (mCurrentCompositeTask) {
mCurrentCompositeTask->Cancel();
mCurrentCompositeTask = nullptr;
}
}

void
CompositorVsyncObserver::Composite(TimeStamp aVsyncTimestamp)
{
MOZ_ASSERT(CompositorParent::IsInCompositorThread());
{
MonitorAutoLock lock(mCurrentCompositeTaskMonitor);
mCurrentCompositeTask = nullptr;
}

if (mNeedsComposite && mCompositorParent) {
mNeedsComposite = false;
mCompositorParent->CompositeCallback(aVsyncTimestamp);
} else {
// We're getting vsync notifications but we don't need to composite so
// unregister the vsync.
UnobserveVsync();
}

DispatchTouchEvents(aVsyncTimestamp);
}

bool
CompositorVsyncObserver::NeedsComposite()
{
MOZ_ASSERT(CompositorParent::IsInCompositorThread());
return mNeedsComposite;
}

/**
* Since the vsync thread has its own locks before notifying us of vsync
* we can't register/unregister from the vsync thread. Any other thread is fine
*/
void
CompositorVsyncObserver::ObserveVsync()
{
MOZ_ASSERT(CompositorParent::IsInCompositorThread());
VsyncDispatcher::GetInstance()->AddCompositorVsyncObserver(this);
mIsObservingVsync = true;
}

void
CompositorVsyncObserver::UnobserveVsync()
{
MOZ_ASSERT(CompositorParent::IsInCompositorThread() || NS_IsMainThread());
VsyncDispatcher::GetInstance()->RemoveCompositorVsyncObserver(this);
mIsObservingVsync = false;
}

void
CompositorVsyncObserver::DispatchTouchEvents(TimeStamp aVsyncTimestamp)
{
#ifdef MOZ_WIDGET_GONK
if (gfxPrefs::TouchResampling()) {
GeckoTouchDispatcher::NotifyVsync(aVsyncTimestamp);
}
#endif
}

void CompositorParent::StartUp()
{
MOZ_ASSERT(NS_IsMainThread(), "Should be on the main Thread!");
Expand Down Expand Up @@ -382,10 +254,6 @@ CompositorParent::CompositorParent(nsIWidget* aWidget,
if (gfxPrefs::AsyncPanZoomEnabled()) {
mApzcTreeManager = new APZCTreeManager();
}

if (gfxPrefs::VsyncAlignedCompositor()) {
mCompositorVsyncObserver = new CompositorVsyncObserver(this);
}
}

bool
Expand Down Expand Up @@ -425,7 +293,6 @@ CompositorParent::Destroy()
mApzcTreeManager = nullptr;
}
sIndirectLayerTrees.erase(mRootLayerTreeID);
mCompositorVsyncObserver = nullptr;
}

void
Expand Down Expand Up @@ -507,17 +374,12 @@ CompositorParent::RecvMakeSnapshot(const SurfaceDescriptor& aInSnapshot,
bool
CompositorParent::RecvFlushRendering()
{
if (gfxPrefs::VsyncAlignedCompositor() && mCompositorVsyncObserver->NeedsComposite()) {
mCompositorVsyncObserver->SetNeedsComposite(false);
CancelCurrentCompositeTask();
ForceComposeToTarget(nullptr);
} else if (mCurrentCompositeTask) {
// If we're waiting to do a composite, then cancel it
// and do it immediately instead.
// If we're waiting to do a composite, then cancel it
// and do it immediately instead.
if (mCurrentCompositeTask) {
CancelCurrentCompositeTask();
ForceComposeToTarget(nullptr);
}

return true;
}

Expand Down Expand Up @@ -636,9 +498,7 @@ CompositorParent::ForceComposition()
void
CompositorParent::CancelCurrentCompositeTask()
{
if (gfxPrefs::VsyncAlignedCompositor()) {
mCompositorVsyncObserver->CancelCurrentCompositeTask();
} else if (mCurrentCompositeTask) {
if (mCurrentCompositeTask) {
mCurrentCompositeTask->Cancel();
mCurrentCompositeTask = nullptr;
}
Expand Down Expand Up @@ -745,10 +605,8 @@ CalculateCompositionFrameRate()
}

void
CompositorParent::ScheduleSoftwareTimerComposition()
CompositorParent::ScheduleComposition()
{
MOZ_ASSERT(!gfxPrefs::VsyncAlignedCompositor());

if (mCurrentCompositeTask || mPaused) {
return;
}
Expand All @@ -764,9 +622,8 @@ CompositorParent::ScheduleSoftwareTimerComposition()
TimeDuration minFrameDelta = TimeDuration::FromMilliseconds(
rate == 0 ? 0.0 : std::max(0.0, 1000.0 / rate));

mCurrentCompositeTask = NewRunnableMethod(this,
&CompositorParent::CompositeCallback,
TimeStamp::Now());

mCurrentCompositeTask = NewRunnableMethod(this, &CompositorParent::CompositeCallback);

if (!initialComposition && delta < minFrameDelta) {
TimeDuration delay = minFrameDelta - delta;
Expand All @@ -783,28 +640,8 @@ CompositorParent::ScheduleSoftwareTimerComposition()
}

void
CompositorParent::ScheduleComposition()
CompositorParent::CompositeCallback()
{
MOZ_ASSERT(IsInCompositorThread());
if (gfxPrefs::VsyncAlignedCompositor()) {
mCompositorVsyncObserver->SetNeedsComposite(true);
} else {
ScheduleSoftwareTimerComposition();
}
}

void
CompositorParent::CompositeCallback(TimeStamp aScheduleTime)
{
if (gfxPrefs::VsyncAlignedCompositor()) {
// Align OMTA to vsync time.
// TODO: ensure it aligns with the refresh / start time of
// animations
mLastCompose = aScheduleTime;
} else {
mLastCompose = TimeStamp::Now();
}

mCurrentCompositeTask = nullptr;
CompositeToTarget(nullptr);
}
Expand Down Expand Up @@ -848,6 +685,8 @@ CompositorParent::CompositeToTarget(DrawTarget* aTarget, const nsIntRect* aRect)
}
#endif

mLastCompose = TimeStamp::Now();

if (!CanComposite()) {
DidComposite();
return;
Expand Down Expand Up @@ -1005,11 +844,7 @@ CompositorParent::ShadowLayersUpdated(LayerTransactionParent* aLayerTree,
// However, we only do this update when a composite operation is already
// scheduled in order to better match the behavior under regular sampling
// conditions.
bool needTestComposite = mIsTesting && root &&
(mCurrentCompositeTask ||
(gfxPrefs::VsyncAlignedCompositor() &&
mCompositorVsyncObserver->NeedsComposite()));
if (needTestComposite) {
if (mIsTesting && root && mCurrentCompositeTask) {
AutoResolveRefLayers resolve(mCompositionManager);
bool requestNextFrame =
mCompositionManager->TransformShadowTree(mTestTime);
Expand Down Expand Up @@ -1040,12 +875,8 @@ CompositorParent::SetTestSampleTime(LayerTransactionParent* aLayerTree,
mIsTesting = true;
mTestTime = aTime;

bool testComposite = mCompositionManager && (mCurrentCompositeTask ||
(gfxPrefs::VsyncAlignedCompositor()
&& mCompositorVsyncObserver->NeedsComposite()));

// Update but only if we were already scheduled to animate
if (testComposite) {
if (mCompositionManager && mCurrentCompositeTask) {
AutoResolveRefLayers resolve(mCompositionManager);
bool requestNextFrame = mCompositionManager->TransformShadowTree(aTime);
if (!requestNextFrame) {
Expand Down
41 changes: 1 addition & 40 deletions gfx/layers/ipc/CompositorParent.h
Expand Up @@ -35,7 +35,6 @@
#include "nsISupportsImpl.h"
#include "nsSize.h" // for nsIntSize
#include "ThreadSafeRefcountingWithMainThreadDestruction.h"
#include "mozilla/VsyncDispatcher.h"

class CancelableTask;
class MessageLoop;
Expand All @@ -52,7 +51,6 @@ namespace layers {
class APZCTreeManager;
class AsyncCompositionManager;
class Compositor;
class CompositorParent;
class LayerManagerComposite;
class LayerTransactionParent;

Expand Down Expand Up @@ -89,45 +87,10 @@ class CompositorThreadHolder MOZ_FINAL
friend class CompositorParent;
};

/**
* Manages the vsync (de)registration and tracking on behalf of the
* compositor when it need to paint.
* Turns vsync notifications into scheduled composites.
**/

class CompositorVsyncObserver MOZ_FINAL : public VsyncObserver
{
friend class CompositorParent;

public:
CompositorVsyncObserver(CompositorParent* aCompositorParent);
virtual bool NotifyVsync(TimeStamp aVsyncTimestamp) MOZ_OVERRIDE;
void SetNeedsComposite(bool aSchedule);
bool NeedsComposite();
void CancelCurrentCompositeTask();

private:
virtual ~CompositorVsyncObserver();

void Composite(TimeStamp aVsyncTimestamp);
void NotifyCompositeTaskExecuted();
void ObserveVsync();
void UnobserveVsync();
void DispatchTouchEvents(TimeStamp aVsyncTimestamp);

bool mNeedsComposite;
bool mIsObservingVsync;
nsRefPtr<CompositorParent> mCompositorParent;

mozilla::Monitor mCurrentCompositeTaskMonitor;
CancelableTask* mCurrentCompositeTask;
};

class CompositorParent : public PCompositorParent,
public ShadowLayersManager
{
NS_INLINE_DECL_THREADSAFE_REFCOUNTING_WITH_MAIN_THREAD_DESTRUCTION(CompositorParent)
friend class CompositorVsyncObserver;

public:
explicit CompositorParent(nsIWidget* aWidget,
Expand Down Expand Up @@ -324,7 +287,7 @@ class CompositorParent : public PCompositorParent,
bool* aSuccess) MOZ_OVERRIDE;
virtual bool DeallocPLayerTransactionParent(PLayerTransactionParent* aLayers) MOZ_OVERRIDE;
virtual void ScheduleTask(CancelableTask*, int);
void CompositeCallback(TimeStamp aScheduleTime);
void CompositeCallback();
void CompositeToTarget(gfx::DrawTarget* aTarget, const nsIntRect* aRect = nullptr);
void ForceComposeToTarget(gfx::DrawTarget* aTarget, const nsIntRect* aRect = nullptr);

Expand All @@ -336,7 +299,6 @@ class CompositorParent : public PCompositorParent,
void ResumeCompositionAndResize(int width, int height);
void ForceComposition();
void CancelCurrentCompositeTask();
void ScheduleSoftwareTimerComposition();

/**
* Add a compositor to the global compositor map.
Expand Down Expand Up @@ -386,7 +348,6 @@ class CompositorParent : public PCompositorParent,
nsRefPtr<APZCTreeManager> mApzcTreeManager;

nsRefPtr<CompositorThreadHolder> mCompositorThreadHolder;
nsRefPtr<CompositorVsyncObserver> mCompositorVsyncObserver;

DISALLOW_EVIL_CONSTRUCTORS(CompositorParent);
};
Expand Down
3 changes: 1 addition & 2 deletions gfx/thebes/gfxPrefs.h
Expand Up @@ -207,8 +207,7 @@ class gfxPrefs MOZ_FINAL
DECL_GFX_PREF(Live, "gfx.draw-color-bars", CompositorDrawColorBars, bool, false);

// Use vsync events generated by hardware
DECL_GFX_PREF(Once, "gfx.vsync.hw-vsync.enabled", HardwareVsyncEnabled, bool, false);
DECL_GFX_PREF(Once, "gfx.vsync.compositor", VsyncAlignedCompositor, bool, false);
DECL_GFX_PREF(Once, "gfx.frameuniformity.hw-vsync", FrameUniformityHWVsyncEnabled, bool, false);
DECL_GFX_PREF(Once, "gfx.touch.resample", TouchResampling, bool, false);
// These times should be in milliseconds
DECL_GFX_PREF(Once, "gfx.touch.resample.max-predict", TouchResampleMaxPredict, int32_t, 8);
Expand Down
2 changes: 1 addition & 1 deletion widget/VsyncDispatcher.cpp
Expand Up @@ -57,7 +57,7 @@ void
VsyncDispatcher::NotifyVsync(TimeStamp aVsyncTimestamp)
{
bool notifiedCompositors = false;
if (gfxPrefs::VsyncAlignedCompositor()) {
if (false) {
MutexAutoLock lock(mCompositorObserverLock);
notifiedCompositors = NotifyVsyncObservers(aVsyncTimestamp, mCompositorObservers);
}
Expand Down

0 comments on commit 68f5a69

Please sign in to comment.