Bug 1231042 - clean current composition task and related flag when screen off. r=mchang

This commit is contained in:
Jerry Shih 2016-01-19 20:58:00 +01:00
Родитель 3f4e1ec831
Коммит 1638c560e9
4 изменённых файлов: 135 добавлений и 3 удалений

Просмотреть файл

@ -75,6 +75,7 @@
#ifdef MOZ_WIDGET_GONK
#include "GeckoTouchDispatcher.h"
#include "nsScreenManagerGonk.h"
#endif
#include "LayerScope.h"
@ -286,13 +287,20 @@ CompositorVsyncScheduler::Observer::Destroy()
CompositorVsyncScheduler::CompositorVsyncScheduler(CompositorParent* aCompositorParent, nsIWidget* aWidget)
: mCompositorParent(aCompositorParent)
, mLastCompose(TimeStamp::Now())
, mCurrentCompositeTask(nullptr)
, mIsObservingVsync(false)
, mNeedsComposite(0)
, mVsyncNotificationsSkipped(0)
, mCurrentCompositeTaskMonitor("CurrentCompositeTaskMonitor")
, mCurrentCompositeTask(nullptr)
, mSetNeedsCompositeMonitor("SetNeedsCompositeMonitor")
, mSetNeedsCompositeTask(nullptr)
#ifdef MOZ_WIDGET_GONK
#if ANDROID_VERSION >= 19
, mDisplayEnabled(false)
, mSetDisplayMonitor("SetDisplayMonitor")
, mSetDisplayTask(nullptr)
#endif
#endif
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aWidget != nullptr);
@ -300,6 +308,11 @@ CompositorVsyncScheduler::CompositorVsyncScheduler(CompositorParent* aCompositor
mCompositorVsyncDispatcher = aWidget->GetCompositorVsyncDispatcher();
#ifdef MOZ_WIDGET_GONK
GeckoTouchDispatcher::GetInstance()->SetCompositorVsyncScheduler(this);
#if ANDROID_VERSION >= 19
RefPtr<nsScreenManagerGonk> screenManager = nsScreenManagerGonk::GetInstance();
screenManager->SetCompositorVsyncScheduler(this);
#endif
#endif
// mAsapScheduling is set on the main thread during init,
@ -317,6 +330,54 @@ CompositorVsyncScheduler::~CompositorVsyncScheduler()
mCompositorVsyncDispatcher = nullptr;
}
#ifdef MOZ_WIDGET_GONK
#if ANDROID_VERSION >= 19
void
CompositorVsyncScheduler::SetDisplay(bool aDisplayEnable)
{
// SetDisplay() is usually called from nsScreenManager at main thread. Post
// to compositor thread if needs.
if (!CompositorParent::IsInCompositorThread()) {
MOZ_ASSERT(NS_IsMainThread());
MonitorAutoLock lock(mSetDisplayMonitor);
mSetDisplayTask = NewRunnableMethod(this,
&CompositorVsyncScheduler::SetDisplay,
aDisplayEnable);
ScheduleTask(mSetDisplayTask, 0);
return;
} else {
MonitorAutoLock lock(mSetDisplayMonitor);
mSetDisplayTask = nullptr;
}
if (mDisplayEnabled == aDisplayEnable) {
return;
}
mDisplayEnabled = aDisplayEnable;
if (!mDisplayEnabled) {
CancelCurrentSetNeedsCompositeTask();
CancelCurrentCompositeTask();
}
}
void
CompositorVsyncScheduler::CancelSetDisplayTask()
{
MOZ_ASSERT(CompositorParent::IsInCompositorThread());
MonitorAutoLock lock(mSetDisplayMonitor);
if (mSetDisplayTask) {
mSetDisplayTask->Cancel();
mSetDisplayTask = nullptr;
}
// CancelSetDisplayTask is only be called in clean-up process, so
// mDisplayEnabled could be false there.
mDisplayEnabled = false;
}
#endif //ANDROID_VERSION >= 19
#endif //MOZ_WIDGET_GONK
void
CompositorVsyncScheduler::Destroy()
{
@ -324,6 +385,12 @@ CompositorVsyncScheduler::Destroy()
UnobserveVsync();
mVsyncObserver->Destroy();
mVsyncObserver = nullptr;
#ifdef MOZ_WIDGET_GONK
#if ANDROID_VERSION >= 19
CancelSetDisplayTask();
#endif
#endif
CancelCurrentSetNeedsCompositeTask();
CancelCurrentCompositeTask();
}
@ -396,6 +463,15 @@ CompositorVsyncScheduler::SetNeedsComposite()
mSetNeedsCompositeTask = nullptr;
}
#ifdef MOZ_WIDGET_GONK
#if ANDROID_VERSION >= 19
// Skip composition when display off.
if (!mDisplayEnabled) {
return;
}
#endif
#endif
mNeedsComposite++;
if (!mIsObservingVsync && mNeedsComposite) {
ObserveVsync();

Просмотреть файл

@ -100,6 +100,20 @@ class CompositorVsyncScheduler
public:
explicit CompositorVsyncScheduler(CompositorParent* aCompositorParent, nsIWidget* aWidget);
#ifdef MOZ_WIDGET_GONK
// emulator-ics never trigger the display on/off, so compositor will always
// skip composition request at that device. Only check the display status
// with kk device and upon.
#if ANDROID_VERSION >= 19
// SetDisplay() and CancelSetDisplayTask() are used for the display on/off.
// It will clear all composition related task and flag, and skip another
// composition task during the display off. That could prevent the problem
// that compositor might show the old content at the first frame of display on.
void SetDisplay(bool aDisplayEnable);
#endif
#endif
bool NotifyVsync(TimeStamp aVsyncTimestamp);
void SetNeedsComposite();
void OnForceComposeToTarget();
@ -128,7 +142,7 @@ public:
return mExpectedComposeStartTime;
}
#endif
private:
virtual ~CompositorVsyncScheduler();
@ -138,6 +152,11 @@ private:
void DispatchTouchEvents(TimeStamp aVsyncTimestamp);
void DispatchVREvents(TimeStamp aVsyncTimestamp);
void CancelCurrentSetNeedsCompositeTask();
#ifdef MOZ_WIDGET_GONK
#if ANDROID_VERSION >= 19
void CancelSetDisplayTask();
#endif
#endif
class Observer final : public VsyncObserver
{
@ -155,7 +174,6 @@ private:
CompositorParent* mCompositorParent;
TimeStamp mLastCompose;
CancelableTask* mCurrentCompositeTask;
#ifdef COMPOSITOR_PERFORMANCE_WARNING
TimeStamp mExpectedComposeStartTime;
@ -169,9 +187,18 @@ private:
RefPtr<CompositorVsyncScheduler::Observer> mVsyncObserver;
mozilla::Monitor mCurrentCompositeTaskMonitor;
CancelableTask* mCurrentCompositeTask;
mozilla::Monitor mSetNeedsCompositeMonitor;
CancelableTask* mSetNeedsCompositeTask;
#ifdef MOZ_WIDGET_GONK
#if ANDROID_VERSION >= 19
bool mDisplayEnabled;
mozilla::Monitor mSetDisplayMonitor;
CancelableTask* mSetDisplayTask;
#endif
#endif
};
class CompositorUpdateObserver

Просмотреть файл

@ -744,6 +744,12 @@ nsScreenManagerGonk::Initialize()
void
nsScreenManagerGonk::DisplayEnabled(bool aEnabled)
{
#if ANDROID_VERSION >= 19
if (mCompositorVsyncScheduler) {
mCompositorVsyncScheduler->SetDisplay(aEnabled);
}
#endif
VsyncControl(aEnabled);
NS_DispatchToMainThread(aEnabled ? mScreenOnEvent : mScreenOffEvent);
}
@ -976,3 +982,15 @@ nsScreenManagerGonk::RemoveScreen(GonkDisplay::DisplayType aDisplayType)
}
return NS_OK;
}
#if ANDROID_VERSION >= 19
void
nsScreenManagerGonk::SetCompositorVsyncScheduler(mozilla::layers::CompositorVsyncScheduler *aObserver)
{
MOZ_ASSERT(NS_IsMainThread());
// We assume on b2g that there is only 1 CompositorParent
MOZ_ASSERT(mCompositorVsyncScheduler == nullptr);
mCompositorVsyncScheduler = aObserver;
}
#endif

Просмотреть файл

@ -42,6 +42,9 @@ namespace mozilla {
namespace gl {
class GLContext;
}
namespace layers {
class CompositorVsyncScheduler;
}
}
enum class NotifyDisplayChangedEvent : int8_t {
@ -193,6 +196,10 @@ public:
nsresult RemoveScreen(GonkDisplay::DisplayType aDisplayType);
#if ANDROID_VERSION >= 19
void SetCompositorVsyncScheduler(mozilla::layers::CompositorVsyncScheduler* aObserver);
#endif
protected:
~nsScreenManagerGonk();
void VsyncControl(bool aEnabled);
@ -203,6 +210,10 @@ protected:
nsTArray<RefPtr<nsScreenGonk>> mScreens;
RefPtr<nsRunnable> mScreenOnEvent;
RefPtr<nsRunnable> mScreenOffEvent;
#if ANDROID_VERSION >= 19
RefPtr<mozilla::layers::CompositorVsyncScheduler> mCompositorVsyncScheduler;
#endif
};
#endif /* nsScreenManagerGonk_h___ */