import changes from `dev' branch of rmottola/Arctic-Fox:

- Bug 1152509. Use Mask with alpha to avoid allocating a surface. r=bas (ddab7594e3)
- Bug 1155881 follow-up: Make gfxAndroidPlatform::SupportsApzTouchInput const (a31194495e)
- Bug 1193481 - Prefer "Firefox Emoji" font for emoji characters in GetCommonFallbackFonts on B2G. r=jdaggett (e94e0eb718)
- Bug 1139253. Reuse the same thread for the software vsync thread. r=kats (fe7f6849bf)
- Bug 1147390. Enable / disable vsync on the vsync thread only. r=kats (fd485f8ec4)
- Bug 1146691 - Create tests to check that the RefreshDriverVsyncObservers get vsync notifications. r=kats (7a8527b378)
- Bug 1197201. Delete hardware vsync and vsync compositor prefs. r=kats (e8f0ef3258)
- Bug 1175530 - Log using gfxDebugOnce when enabling vsync compositor. r=mchang (81a48aebae)
- Bug 1196308 - Delete Software Compositor Scheduler. r=sotaro (d0e9620ddb)
- Don't run the compositor:created notification from within unsafer callers. (bug 1201684, r=mattwoodrow) (83d585749a)
- Bug 1160216 - Add a preference to force software vsync and set software vsync rate. r=kats (850d3ce7ab)
- Bug 1132966 - use relaxed Atomic integers for tracking graphics surface memory usage; r=njn (aca764781f)
- bug 1180012 remove unused GetPrefFonts() r=jdaggett (80a5a99f7f)
- Bug 1139726 - Assert gfxPlatform::Init is called on the main thread. r=kats (dd1ad58304)
- Bug 1208945 - Rename Color::{To,From}ARGB() so they aren't easily confused with {To,From}ABGR(). r=Bas. (8e83d44741)
- Bug 1199885 - Part 1: Add MouseInput InputData. r=kats (67764c13a6)
This commit is contained in:
2022-09-21 12:18:01 +08:00
parent 22f768afa7
commit 0484be0c56
22 changed files with 410 additions and 382 deletions
+6 -2
View File
@@ -246,7 +246,9 @@ public:
return newColor;
}
static Color FromARGB(uint32_t aColor)
// The "Unusual" prefix is to avoid unintentionally using this function when
// FromABGR(), which is much more common, is needed.
static Color UnusualFromARGB(uint32_t aColor)
{
Color newColor(((aColor >> 16) & 0xff) * (1.0f / 255.0f),
((aColor >> 8) & 0xff) * (1.0f / 255.0f),
@@ -262,7 +264,9 @@ public:
uint32_t(b * 255.0f) << 16 | uint32_t(a * 255.0f) << 24;
}
uint32_t ToARGB() const
// The "Unusual" prefix is to avoid unintentionally using this function when
// ToABGR(), which is much more common, is needed.
uint32_t UnusualToARGB() const
{
return uint32_t(b * 255.0f) | uint32_t(g * 255.0f) << 8 |
uint32_t(r * 255.0f) << 16 | uint32_t(a * 255.0f) << 24;
+1 -6
View File
@@ -44,13 +44,8 @@ PaintWithMask(gfxContext* aContext, float aOpacity, Layer* aMaskLayer)
{
AutoMoz2DMaskData mask;
if (GetMaskData(aMaskLayer, Point(), &mask)) {
if (aOpacity < 1.0) {
aContext->PushGroup(gfxContentType::COLOR_ALPHA);
aContext->Paint(aOpacity);
aContext->PopGroupToSource();
}
aContext->SetMatrix(ThebesMatrix(mask.GetTransform()));
aContext->Mask(mask.GetSurface());
aContext->Mask(mask.GetSurface(), aOpacity);
return;
}
+62 -161
View File
@@ -221,81 +221,14 @@ static void SetThreadPriority()
hal::SetCurrentThreadPriority(hal::THREAD_PRIORITY_COMPOSITOR);
}
CompositorScheduler::CompositorScheduler(CompositorParent* aCompositorParent)
: mCompositorParent(aCompositorParent)
, mCurrentCompositeTask(nullptr)
{
}
CompositorScheduler::~CompositorScheduler()
{
MOZ_ASSERT(!mCompositorParent);
}
void
CompositorScheduler::CancelCurrentCompositeTask()
{
if (mCurrentCompositeTask) {
mCurrentCompositeTask->Cancel();
mCurrentCompositeTask = nullptr;
}
}
void
CompositorScheduler::ScheduleTask(CancelableTask* aTask, int aTime)
{
MOZ_ASSERT(CompositorParent::CompositorLoop());
MOZ_ASSERT(aTime >= 0);
CompositorParent::CompositorLoop()->PostDelayedTask(FROM_HERE, aTask, aTime);
}
void
CompositorScheduler::ResumeComposition()
{
mLastCompose = TimeStamp::Now();
ComposeToTarget(nullptr);
}
void
CompositorScheduler::ForceComposeToTarget(gfx::DrawTarget* aTarget, const IntRect* aRect)
{
mLastCompose = TimeStamp::Now();
ComposeToTarget(aTarget, aRect);
}
void
CompositorScheduler::ComposeToTarget(gfx::DrawTarget* aTarget, const IntRect* aRect)
{
MOZ_ASSERT(CompositorParent::IsInCompositorThread());
MOZ_ASSERT(mCompositorParent);
mCompositorParent->CompositeToTarget(aTarget, aRect);
}
void
CompositorScheduler::Destroy()
{
MOZ_ASSERT(CompositorParent::IsInCompositorThread());
CancelCurrentCompositeTask();
mCompositorParent = nullptr;
}
CompositorSoftwareTimerScheduler::CompositorSoftwareTimerScheduler(CompositorParent* aCompositorParent)
: CompositorScheduler(aCompositorParent)
{
}
CompositorSoftwareTimerScheduler::~CompositorSoftwareTimerScheduler()
{
MOZ_ASSERT(!mCurrentCompositeTask);
}
// Used when layout.frame_rate is -1. Needs to be kept in sync with
// DEFAULT_FRAME_RATE in nsRefreshDriver.cpp.
static const int32_t kDefaultFrameRate = 60;
#ifdef COMPOSITOR_PERFORMANCE_WARNING
static int32_t
CalculateCompositionFrameRate()
{
// Used when layout.frame_rate is -1. Needs to be kept in sync with
// DEFAULT_FRAME_RATE in nsRefreshDriver.cpp.
// TODO: This should actually return the vsync rate.
const int32_t defaultFrameRate = 60;
int32_t compositionFrameRatePref = gfxPrefs::LayersCompositionFrameRate();
if (compositionFrameRatePref < 0) {
// Use the same frame rate for composition as for layout.
@@ -303,68 +236,13 @@ CalculateCompositionFrameRate()
if (layoutFrameRatePref < 0) {
// TODO: The main thread frame scheduling code consults the actual
// monitor refresh rate in this case. We should do the same.
return kDefaultFrameRate;
return defaultFrameRate;
}
return layoutFrameRatePref;
}
return compositionFrameRatePref;
}
void
CompositorSoftwareTimerScheduler::ScheduleComposition()
{
if (mCurrentCompositeTask) {
return;
}
bool initialComposition = mLastCompose.IsNull();
TimeDuration delta;
if (!initialComposition) {
delta = TimeStamp::Now() - mLastCompose;
}
int32_t rate = CalculateCompositionFrameRate();
// If rate == 0 (ASAP mode), minFrameDelta must be 0 so there's no delay.
TimeDuration minFrameDelta = TimeDuration::FromMilliseconds(
rate == 0 ? 0.0 : std::max(0.0, 1000.0 / rate));
mCurrentCompositeTask = NewRunnableMethod(this,
&CompositorSoftwareTimerScheduler::CallComposite);
if (!initialComposition && delta < minFrameDelta) {
TimeDuration delay = minFrameDelta - delta;
#ifdef COMPOSITOR_PERFORMANCE_WARNING
mExpectedComposeStartTime = TimeStamp::Now() + delay;
#endif
ScheduleTask(mCurrentCompositeTask, delay.ToMilliseconds());
} else {
#ifdef COMPOSITOR_PERFORMANCE_WARNING
mExpectedComposeStartTime = TimeStamp::Now();
#endif
ScheduleTask(mCurrentCompositeTask, 0);
}
}
bool
CompositorSoftwareTimerScheduler::NeedsComposite()
{
return mCurrentCompositeTask ? true : false;
}
void
CompositorSoftwareTimerScheduler::CallComposite()
{
Composite(TimeStamp::Now());
}
void
CompositorSoftwareTimerScheduler::Composite(TimeStamp aTimestamp)
{
mCurrentCompositeTask = nullptr;
mLastCompose = aTimestamp;
ComposeToTarget(nullptr);
}
CompositorVsyncScheduler::Observer::Observer(CompositorVsyncScheduler* aOwner)
: mMutex("CompositorVsyncScheduler.Observer.Mutex")
@@ -395,11 +273,12 @@ CompositorVsyncScheduler::Observer::Destroy()
}
CompositorVsyncScheduler::CompositorVsyncScheduler(CompositorParent* aCompositorParent, nsIWidget* aWidget)
: CompositorScheduler(aCompositorParent)
: mCompositorParent(aCompositorParent)
, mLastCompose(TimeStamp::Now())
, mCurrentCompositeTask(nullptr)
, mNeedsComposite(false)
, mIsObservingVsync(false)
, mVsyncNotificationsSkipped(0)
, mCompositorParent(aCompositorParent)
, mCurrentCompositeTaskMonitor("CurrentCompositeTaskMonitor")
, mSetNeedsCompositeMonitor("SetNeedsCompositeMonitor")
, mSetNeedsCompositeTask(nullptr)
@@ -411,6 +290,11 @@ CompositorVsyncScheduler::CompositorVsyncScheduler(CompositorParent* aCompositor
#ifdef MOZ_WIDGET_GONK
GeckoTouchDispatcher::GetInstance()->SetCompositorVsyncScheduler(this);
#endif
// mAsapScheduling is set on the main thread during init,
// but is only accessed after on the compositor thread.
mAsapScheduling = gfxPrefs::LayersCompositionFrameRate() == 0 ||
gfxPlatform::IsInLayoutAsapMode();
}
CompositorVsyncScheduler::~CompositorVsyncScheduler()
@@ -430,13 +314,32 @@ CompositorVsyncScheduler::Destroy()
mVsyncObserver->Destroy();
mVsyncObserver = nullptr;
CancelCurrentSetNeedsCompositeTask();
CompositorScheduler::Destroy();
CancelCurrentCompositeTask();
}
void
CompositorVsyncScheduler::PostCompositeTask(TimeStamp aCompositeTimestamp)
{
// can be called from the compositor or vsync thread
MonitorAutoLock lock(mCurrentCompositeTaskMonitor);
if (mCurrentCompositeTask == nullptr) {
mCurrentCompositeTask = NewRunnableMethod(this,
&CompositorVsyncScheduler::Composite,
aCompositeTimestamp);
ScheduleTask(mCurrentCompositeTask, 0);
}
}
void
CompositorVsyncScheduler::ScheduleComposition()
{
SetNeedsComposite(true);
MOZ_ASSERT(CompositorParent::IsInCompositorThread());
if (mAsapScheduling) {
// Used only for performance testing purposes
PostCompositeTask(TimeStamp::Now());
} else {
SetNeedsComposite(true);
}
}
void
@@ -485,14 +388,7 @@ CompositorVsyncScheduler::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,
&CompositorVsyncScheduler::Composite,
aVsyncTimestamp);
ScheduleTask(mCurrentCompositeTask, 0);
}
PostCompositeTask(aVsyncTimestamp);
return true;
}
@@ -501,7 +397,10 @@ CompositorVsyncScheduler::CancelCurrentCompositeTask()
{
MOZ_ASSERT(CompositorParent::IsInCompositorThread() || NS_IsMainThread());
MonitorAutoLock lock(mCurrentCompositeTaskMonitor);
CompositorScheduler::CancelCurrentCompositeTask();
if (mCurrentCompositeTask) {
mCurrentCompositeTask->Cancel();
mCurrentCompositeTask = nullptr;
}
}
void
@@ -515,7 +414,7 @@ CompositorVsyncScheduler::Composite(TimeStamp aVsyncTimestamp)
DispatchTouchEvents(aVsyncTimestamp);
if (mNeedsComposite) {
if (mNeedsComposite || mAsapScheduling) {
mNeedsComposite = false;
mLastCompose = aVsyncTimestamp;
ComposeToTarget(nullptr);
@@ -546,7 +445,8 @@ void
CompositorVsyncScheduler::ForceComposeToTarget(gfx::DrawTarget* aTarget, const IntRect* aRect)
{
OnForceComposeToTarget();
CompositorScheduler::ForceComposeToTarget(aTarget, aRect);
mLastCompose = TimeStamp::Now();
ComposeToTarget(aTarget, aRect);
}
bool
@@ -610,22 +510,27 @@ MessageLoop* CompositorParent::CompositorLoop()
return CompositorThread() ? CompositorThread()->message_loop() : nullptr;
}
static bool
IsInCompositorAsapMode()
void
CompositorVsyncScheduler::ScheduleTask(CancelableTask* aTask, int aTime)
{
// Returns true if the compositor is allowed to be in ASAP mode
// and layout is not in ASAP mode
return gfxPrefs::LayersCompositionFrameRate() == 0 &&
!gfxPlatform::IsInLayoutAsapMode();
MOZ_ASSERT(CompositorParent::CompositorLoop());
MOZ_ASSERT(aTime >= 0);
CompositorParent::CompositorLoop()->PostDelayedTask(FROM_HERE, aTask, aTime);
}
static bool
UseVsyncComposition()
void
CompositorVsyncScheduler::ResumeComposition()
{
return gfxPrefs::VsyncAlignedCompositor()
&& gfxPrefs::HardwareVsyncEnabled()
&& !IsInCompositorAsapMode()
&& !gfxPlatform::IsInLayoutAsapMode();
mLastCompose = TimeStamp::Now();
ComposeToTarget(nullptr);
}
void
CompositorVsyncScheduler::ComposeToTarget(gfx::DrawTarget* aTarget, const IntRect* aRect)
{
MOZ_ASSERT(CompositorParent::IsInCompositorThread());
MOZ_ASSERT(mCompositorParent);
mCompositorParent->CompositeToTarget(aTarget, aRect);
}
CompositorParent::CompositorParent(nsIWidget* aWidget,
@@ -672,12 +577,8 @@ CompositorParent::CompositorParent(nsIWidget* aWidget,
mApzcTreeManager = new APZCTreeManager();
}
if (UseVsyncComposition()) {
NS_WARNING("Enabling vsync compositor");
mCompositorScheduler = new CompositorVsyncScheduler(this, aWidget);
} else {
mCompositorScheduler = new CompositorSoftwareTimerScheduler(this);
}
gfxDebugOnce() << "Enabling vsync compositor";
mCompositorScheduler = new CompositorVsyncScheduler(this, aWidget);
LayerScope::SetPixelScale(mWidget->GetDefaultScale().scale);
}
+35 -66
View File
@@ -88,21 +88,31 @@ private:
friend class CompositorParent;
};
class CompositorScheduler
/**
* 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
{
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CompositorScheduler)
explicit CompositorScheduler(CompositorParent* aCompositorParent);
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CompositorVsyncScheduler)
virtual void ScheduleComposition() = 0;
virtual void CancelCurrentCompositeTask();
virtual bool NeedsComposite() = 0;
virtual void Composite(TimeStamp aTimestamp) = 0;
virtual void ScheduleTask(CancelableTask*, int);
virtual void ResumeComposition();
virtual void ForceComposeToTarget(gfx::DrawTarget* aTarget, const gfx::IntRect* aRect);
virtual void ComposeToTarget(gfx::DrawTarget* aTarget, const gfx::IntRect* aRect = nullptr);
virtual void Destroy();
public:
explicit CompositorVsyncScheduler(CompositorParent* aCompositorParent, nsIWidget* aWidget);
bool NotifyVsync(TimeStamp aVsyncTimestamp);
void SetNeedsComposite(bool aSchedule);
void OnForceComposeToTarget();
void ScheduleTask(CancelableTask*, int);
void ResumeComposition();
void ComposeToTarget(gfx::DrawTarget* aTarget, const gfx::IntRect* aRect = nullptr);
void PostCompositeTask(TimeStamp aCompositeTimestamp);
void Destroy();
void ScheduleComposition();
void CancelCurrentCompositeTask();
bool NeedsComposite();
void Composite(TimeStamp aVsyncTimestamp);
void ForceComposeToTarget(gfx::DrawTarget* aTarget, const gfx::IntRect* aRect);
const TimeStamp& GetLastComposeTime()
{
@@ -115,56 +125,7 @@ public:
return mExpectedComposeStartTime;
}
#endif
protected:
virtual ~CompositorScheduler();
CompositorParent* mCompositorParent;
TimeStamp mLastCompose;
CancelableTask* mCurrentCompositeTask;
#ifdef COMPOSITOR_PERFORMANCE_WARNING
TimeStamp mExpectedComposeStartTime;
#endif
};
class CompositorSoftwareTimerScheduler final : public CompositorScheduler
{
public:
explicit CompositorSoftwareTimerScheduler(CompositorParent* aCompositorParent);
// from CompositorScheduler
virtual void ScheduleComposition() override;
virtual bool NeedsComposite() override;
virtual void Composite(TimeStamp aTimestamp) override;
void CallComposite();
private:
virtual ~CompositorSoftwareTimerScheduler();
};
/**
* 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 final : public CompositorScheduler
{
public:
explicit CompositorVsyncScheduler(CompositorParent* aCompositorParent, nsIWidget* aWidget);
bool NotifyVsync(TimeStamp aVsyncTimestamp);
void SetNeedsComposite(bool aSchedule);
void OnForceComposeToTarget();
// from CompositorScheduler
virtual void ScheduleComposition() override;
virtual void CancelCurrentCompositeTask() override;
virtual bool NeedsComposite() override;
virtual void Composite(TimeStamp aVsyncTimestamp) override;
virtual void ForceComposeToTarget(gfx::DrawTarget* aTarget, const gfx::IntRect* aRect) override;
virtual void Destroy() override;
private:
virtual ~CompositorVsyncScheduler();
@@ -188,10 +149,18 @@ private:
CompositorVsyncScheduler* mOwner;
};
CompositorParent* mCompositorParent;
TimeStamp mLastCompose;
CancelableTask* mCurrentCompositeTask;
#ifdef COMPOSITOR_PERFORMANCE_WARNING
TimeStamp mExpectedComposeStartTime;
#endif
bool mAsapScheduling;
bool mNeedsComposite;
bool mIsObservingVsync;
int32_t mVsyncNotificationsSkipped;
CompositorParent* mCompositorParent;
nsRefPtr<CompositorVsyncDispatcher> mCompositorVsyncDispatcher;
nsRefPtr<CompositorVsyncScheduler::Observer> mVsyncObserver;
@@ -216,7 +185,7 @@ class CompositorParent final : public PCompositorParent,
public ShadowLayersManager
{
NS_INLINE_DECL_THREADSAFE_REFCOUNTING_WITH_MAIN_THREAD_DESTRUCTION(CompositorParent)
friend class CompositorScheduler;
friend class CompositorVsyncScheduler;
public:
explicit CompositorParent(nsIWidget* aWidget,
@@ -498,7 +467,7 @@ protected:
nsRefPtr<APZCTreeManager> mApzcTreeManager;
nsRefPtr<CompositorThreadHolder> mCompositorThreadHolder;
nsRefPtr<CompositorScheduler> mCompositorScheduler;
nsRefPtr<CompositorVsyncScheduler> mCompositorScheduler;
DISALLOW_EVIL_CONSTRUCTORS(CompositorParent);
};
+68 -11
View File
@@ -59,6 +59,12 @@ public:
return mDidGetVsyncNotification;
}
void ResetVsyncNotification()
{
MonitorAutoLock lock(mVsyncMonitor);
mDidGetVsyncNotification = false;
}
private:
bool mDidGetVsyncNotification;
@@ -72,9 +78,8 @@ protected:
{
gfxPlatform::GetPlatform();
gfxPrefs::GetSingleton();
if (gfxPrefs::HardwareVsyncEnabled() ) {
mVsyncSource = gfxPlatform::GetPlatform()->GetHardwareVsync();
}
mVsyncSource = gfxPlatform::GetPlatform()->GetHardwareVsync();
MOZ_RELEASE_ASSERT(mVsyncSource);
}
virtual ~VsyncTester()
@@ -105,10 +110,6 @@ FlushMainThreadLoop()
// Tests that we can enable/disable vsync notifications
TEST_F(VsyncTester, EnableVsync)
{
if (!gfxPrefs::HardwareVsyncEnabled()) {
return;
}
VsyncSource::Display& globalDisplay = mVsyncSource->GetGlobalDisplay();
globalDisplay.DisableVsync();
ASSERT_FALSE(globalDisplay.IsVsyncEnabled());
@@ -123,10 +124,6 @@ TEST_F(VsyncTester, EnableVsync)
// Test that if we have vsync enabled, the display should get vsync notifications
TEST_F(VsyncTester, CompositorGetVsyncNotifications)
{
if (!gfxPrefs::HardwareVsyncEnabled() || !gfxPrefs::VsyncAlignedCompositor()) {
return;
}
CompositorVsyncDispatcher::SetThreadAssertionsEnabled(false);
VsyncSource::Display& globalDisplay = mVsyncSource->GetGlobalDisplay();
@@ -146,3 +143,63 @@ TEST_F(VsyncTester, CompositorGetVsyncNotifications)
vsyncDispatcher = nullptr;
testVsyncObserver = nullptr;
}
// Test that if we have vsync enabled, the parent refresh driver should get notifications
TEST_F(VsyncTester, ParentRefreshDriverGetVsyncNotifications)
{
if (!gfxPrefs::VsyncAlignedRefreshDriver()) {
return;
}
VsyncSource::Display& globalDisplay = mVsyncSource->GetGlobalDisplay();
globalDisplay.DisableVsync();
ASSERT_FALSE(globalDisplay.IsVsyncEnabled());
nsRefPtr<RefreshTimerVsyncDispatcher> vsyncDispatcher = globalDisplay.GetRefreshTimerVsyncDispatcher();
ASSERT_TRUE(vsyncDispatcher != nullptr);
nsRefPtr<TestVsyncObserver> testVsyncObserver = new TestVsyncObserver();
vsyncDispatcher->SetParentRefreshTimer(testVsyncObserver);
ASSERT_TRUE(globalDisplay.IsVsyncEnabled());
testVsyncObserver->WaitForVsyncNotification();
ASSERT_TRUE(testVsyncObserver->DidGetVsyncNotification());
vsyncDispatcher->SetParentRefreshTimer(nullptr);
testVsyncObserver->ResetVsyncNotification();
testVsyncObserver->WaitForVsyncNotification();
ASSERT_FALSE(testVsyncObserver->DidGetVsyncNotification());
vsyncDispatcher = nullptr;
testVsyncObserver = nullptr;
}
// Test that child refresh vsync observers get vsync notifications
TEST_F(VsyncTester, ChildRefreshDriverGetVsyncNotifications)
{
if (!gfxPrefs::VsyncAlignedRefreshDriver()) {
return;
}
VsyncSource::Display& globalDisplay = mVsyncSource->GetGlobalDisplay();
globalDisplay.DisableVsync();
ASSERT_FALSE(globalDisplay.IsVsyncEnabled());
nsRefPtr<RefreshTimerVsyncDispatcher> vsyncDispatcher = globalDisplay.GetRefreshTimerVsyncDispatcher();
ASSERT_TRUE(vsyncDispatcher != nullptr);
nsRefPtr<TestVsyncObserver> testVsyncObserver = new TestVsyncObserver();
vsyncDispatcher->AddChildRefreshTimer(testVsyncObserver);
ASSERT_TRUE(globalDisplay.IsVsyncEnabled());
testVsyncObserver->WaitForVsyncNotification();
ASSERT_TRUE(testVsyncObserver->DidGetVsyncNotification());
vsyncDispatcher->RemoveChildRefreshTimer(testVsyncObserver);
testVsyncObserver->ResetVsyncNotification();
testVsyncObserver->WaitForVsyncNotification();
ASSERT_FALSE(testVsyncObserver->DidGetVsyncNotification());
vsyncDispatcher = nullptr;
testVsyncObserver = nullptr;
}
+37 -36
View File
@@ -6,77 +6,81 @@
#include "SoftwareVsyncSource.h"
#include "base/task.h"
#include "gfxPlatform.h"
#include "nsThreadUtils.h"
SoftwareVsyncSource::SoftwareVsyncSource()
{
MOZ_ASSERT(NS_IsMainThread());
mGlobalDisplay = new SoftwareDisplay();
}
SoftwareVsyncSource::~SoftwareVsyncSource()
{
MOZ_ASSERT(NS_IsMainThread());
// Ensure we disable vsync on the main thread here
mGlobalDisplay->DisableVsync();
mGlobalDisplay->Shutdown();
mGlobalDisplay = nullptr;
}
SoftwareDisplay::SoftwareDisplay()
: mVsyncEnabled(false)
, mCurrentTaskMonitor("SoftwareVsyncCurrentTaskMonitor")
: mCurrentVsyncTask(nullptr)
, mVsyncEnabled(false)
{
// Mimic 60 fps
MOZ_ASSERT(NS_IsMainThread());
const double rate = 1000 / 60.0;
const double rate = 1000.0 / (double) gfxPlatform::GetSoftwareVsyncRate();
mVsyncRate = mozilla::TimeDuration::FromMilliseconds(rate);
mVsyncThread = new base::Thread("SoftwareVsyncThread");
MOZ_RELEASE_ASSERT(mVsyncThread->Start(), "Could not start software vsync thread");
}
SoftwareDisplay::~SoftwareDisplay() {}
void
SoftwareDisplay::EnableVsync()
{
MOZ_ASSERT(NS_IsMainThread());
if (IsVsyncEnabled()) {
MOZ_ASSERT(mVsyncThread->IsRunning());
if (NS_IsMainThread()) {
if (mVsyncEnabled) {
return;
}
mVsyncEnabled = true;
mVsyncThread->message_loop()->PostTask(FROM_HERE,
NewRunnableMethod(this, &SoftwareDisplay::EnableVsync));
return;
}
{ // scope lock
mozilla::MonitorAutoLock lock(mCurrentTaskMonitor);
mVsyncEnabled = true;
MOZ_ASSERT(!mVsyncThread->IsRunning());
MOZ_RELEASE_ASSERT(mVsyncThread->Start(), "Could not start software vsync thread");
mCurrentVsyncTask = NewRunnableMethod(this,
&SoftwareDisplay::NotifyVsync,
mozilla::TimeStamp::Now());
mVsyncThread->message_loop()->PostTask(FROM_HERE, mCurrentVsyncTask);
}
MOZ_ASSERT(IsInSoftwareVsyncThread());
NotifyVsync(mozilla::TimeStamp::Now());
}
void
SoftwareDisplay::DisableVsync()
{
MOZ_ASSERT(NS_IsMainThread());
if (!IsVsyncEnabled()) {
MOZ_ASSERT(mVsyncThread->IsRunning());
if (NS_IsMainThread()) {
if (!mVsyncEnabled) {
return;
}
mVsyncEnabled = false;
mVsyncThread->message_loop()->PostTask(FROM_HERE,
NewRunnableMethod(this, &SoftwareDisplay::DisableVsync));
return;
}
MOZ_ASSERT(mVsyncThread->IsRunning());
{ // scope lock
mozilla::MonitorAutoLock lock(mCurrentTaskMonitor);
mVsyncEnabled = false;
if (mCurrentVsyncTask) {
mCurrentVsyncTask->Cancel();
mCurrentVsyncTask = nullptr;
}
MOZ_ASSERT(IsInSoftwareVsyncThread());
if (mCurrentVsyncTask) {
mCurrentVsyncTask->Cancel();
mCurrentVsyncTask = nullptr;
}
mVsyncThread->Stop();
}
bool
SoftwareDisplay::IsVsyncEnabled()
{
MOZ_ASSERT(NS_IsMainThread());
mozilla::MonitorAutoLock lock(mCurrentTaskMonitor);
return mVsyncEnabled;
}
@@ -118,12 +122,6 @@ SoftwareDisplay::ScheduleNextVsync(mozilla::TimeStamp aVsyncTimestamp)
delay = mozilla::TimeDuration::FromMilliseconds(0);
}
mozilla::MonitorAutoLock lock(mCurrentTaskMonitor);
// We could've disabled vsync between this posted task and when it actually
// executes
if (!mVsyncEnabled) {
return;
}
mCurrentVsyncTask = NewRunnableMethod(this,
&SoftwareDisplay::NotifyVsync,
nextVsync);
@@ -133,8 +131,11 @@ SoftwareDisplay::ScheduleNextVsync(mozilla::TimeStamp aVsyncTimestamp)
delay.ToMilliseconds());
}
SoftwareDisplay::~SoftwareDisplay()
void
SoftwareDisplay::Shutdown()
{
MOZ_ASSERT(NS_IsMainThread());
DisableVsync();
mVsyncThread->Stop();
delete mVsyncThread;
}
+3 -4
View File
@@ -28,6 +28,7 @@ public:
bool IsInSoftwareVsyncThread();
virtual void NotifyVsync(mozilla::TimeStamp aVsyncTimestamp) override;
void ScheduleNextVsync(mozilla::TimeStamp aVsyncTimestamp);
void Shutdown();
protected:
~SoftwareDisplay();
@@ -36,10 +37,8 @@ private:
mozilla::TimeDuration mVsyncRate;
// Use a chromium thread because nsITimers* fire on the main thread
base::Thread* mVsyncThread;
bool mVsyncEnabled;
CancelableTask* mCurrentVsyncTask;
// Locks against both mCurrentVsyncTask and mVsyncEnabled
mozilla::Monitor mCurrentTaskMonitor;
CancelableTask* mCurrentVsyncTask; // only access on vsync thread
bool mVsyncEnabled; // Only access on main thread
}; // SoftwareDisplay
// Fallback option to use a software timer to mimic vsync. Useful for gtests
+19 -5
View File
@@ -564,13 +564,25 @@ PR_STATIC_ASSERT(uint32_t(CAIRO_SURFACE_TYPE_SKIA) ==
/* Surface size memory reporting */
static int64_t gSurfaceMemoryUsed[size_t(gfxSurfaceType::Max)] = { 0 };
class SurfaceMemoryReporter final : public nsIMemoryReporter
{
~SurfaceMemoryReporter() {}
// We can touch this array on several different threads, and we don't
// want to introduce memory barriers when recording the memory used. To
// assure dynamic race checkers like TSan that this is OK, we use
// relaxed memory ordering here.
static Atomic<size_t, Relaxed> sSurfaceMemoryUsed[size_t(gfxSurfaceType::Max)];
public:
static void AdjustUsedMemory(gfxSurfaceType aType, int32_t aBytes)
{
// A read-modify-write operation like += would require a memory barrier
// here, which would defeat the purpose of using relaxed memory
// ordering. So separate out the read and write operations.
sSurfaceMemoryUsed[size_t(aType)] = sSurfaceMemoryUsed[size_t(aType)] + aBytes;
};
NS_DECL_ISUPPORTS
NS_IMETHOD CollectReports(nsIMemoryReporterCallback *aCb,
@@ -578,7 +590,7 @@ public:
{
const size_t len = ArrayLength(sSurfaceMemoryReporterAttrs);
for (size_t i = 0; i < len; i++) {
int64_t amount = gSurfaceMemoryUsed[i];
int64_t amount = sSurfaceMemoryUsed[i];
if (amount != 0) {
const char *path = sSurfaceMemoryReporterAttrs[i].path;
@@ -589,7 +601,7 @@ public:
nsresult rv = aCb->Callback(EmptyCString(), nsCString(path),
KIND_OTHER, UNITS_BYTES,
gSurfaceMemoryUsed[i],
amount,
nsCString(desc), aClosure);
NS_ENSURE_SUCCESS(rv, rv);
}
@@ -599,6 +611,8 @@ public:
}
};
Atomic<size_t, Relaxed> SurfaceMemoryReporter::sSurfaceMemoryUsed[size_t(gfxSurfaceType::Max)];
NS_IMPL_ISUPPORTS(SurfaceMemoryReporter, nsIMemoryReporter)
void
@@ -616,7 +630,7 @@ gfxASurface::RecordMemoryUsedForSurfaceType(gfxSurfaceType aType,
registered = true;
}
gSurfaceMemoryUsed[size_t(aType)] += aBytes;
SurfaceMemoryReporter::AdjustUsedMemory(aType, aBytes);
}
void
+19 -2
View File
@@ -175,13 +175,30 @@ gfxAndroidPlatform::GetCommonFallbackFonts(uint32_t aCh, uint32_t aNextCh,
{
static const char kDroidSansJapanese[] = "Droid Sans Japanese";
static const char kMotoyaLMaru[] = "MotoyaLMaru";
static const char kNotoColorEmoji[] = "Noto Color Emoji";
#ifdef MOZ_WIDGET_GONK
static const char kFirefoxEmoji[] = "Firefox Emoji";
#endif
if (aNextCh == 0xfe0fu) {
// if char is followed by VS16, try for a color emoji glyph
aFontList.AppendElement("Noto Color Emoji");
#ifdef MOZ_WIDGET_GONK
aFontList.AppendElement(kFirefoxEmoji);
#endif
aFontList.AppendElement(kNotoColorEmoji);
}
if (IS_IN_BMP(aCh)) {
if (!IS_IN_BMP(aCh)) {
uint32_t p = aCh >> 16;
if (p == 1) { // try color emoji font, unless VS15 (text style) present
if (aNextCh != 0xfe0fu && aNextCh != 0xfe0eu) {
#ifdef MOZ_WIDGET_GONK
aFontList.AppendElement(kFirefoxEmoji);
#endif
aFontList.AppendElement(kNotoColorEmoji);
}
}
} else {
// try language-specific "Droid Sans *" and "Noto Sans *" fonts for
// certain blocks, as most devices probably have these
uint8_t block = (aCh >> 8) & 0xff;
+1 -1
View File
@@ -92,7 +92,7 @@ public:
virtual bool IsInGonkEmulator() const { return mIsInGonkEmulator; }
#endif
virtual bool SupportsApzTouchInput() override {
virtual bool SupportsApzTouchInput() const override {
return true;
}
+3 -3
View File
@@ -817,17 +817,17 @@ gfxContext::Mask(gfxASurface *surface, const gfxPoint& offset)
gfxPoint pt = surface->GetDeviceOffset();
Mask(sourceSurf, Point(offset.x - pt.x, offset.y - pt.y));
Mask(sourceSurf, 1.0f, Point(offset.x - pt.x, offset.y - pt.y));
}
void
gfxContext::Mask(SourceSurface *surface, const Point& offset)
gfxContext::Mask(SourceSurface *surface, float alpha, const Point& offset)
{
// We clip here to bind to the mask surface bounds, see above.
mDT->MaskSurface(PatternFromState(this),
surface,
offset,
DrawOptions(1.0f, CurrentState().op, CurrentState().aaMode));
DrawOptions(alpha, CurrentState().op, CurrentState().aaMode));
}
void
+1 -1
View File
@@ -322,7 +322,7 @@ public:
*/
void Mask(gfxASurface *surface, const gfxPoint& offset = gfxPoint(0.0, 0.0));
void Mask(mozilla::gfx::SourceSurface *surface, const mozilla::gfx::Point& offset = mozilla::gfx::Point());
void Mask(mozilla::gfx::SourceSurface *surface, float alpha = 1.0f, const mozilla::gfx::Point& offset = mozilla::gfx::Point());
/**
** Line Properties
+44 -59
View File
@@ -464,6 +464,7 @@ void RecordingPrefChanged(const char *aPrefName, void *aClosure)
void
gfxPlatform::Init()
{
MOZ_RELEASE_ASSERT(NS_IsMainThread());
if (gEverInitialized) {
NS_RUNTIMEABORT("Already started???");
}
@@ -591,8 +592,12 @@ gfxPlatform::Init()
RegisterStrongMemoryReporter(new GfxMemoryImageReporter());
if (XRE_IsParentProcess() && gfxPrefs::HardwareVsyncEnabled()) {
gPlatform->mVsyncSource = gPlatform->CreateHardwareVsyncSource();
if (XRE_IsParentProcess()) {
if (gfxPlatform::ForceSoftwareVsync()) {
gPlatform->mVsyncSource = (gPlatform)->gfxPlatform::CreateHardwareVsyncSource();
} else {
gPlatform->mVsyncSource = gPlatform->CreateHardwareVsyncSource();
}
}
}
@@ -1359,58 +1364,6 @@ gfxPlatform::MakePlatformFont(const nsAString& aFontName,
return nullptr;
}
static void
AppendGenericFontFromPref(nsString& aFonts, nsIAtom *aLangGroup, const char *aGenericName)
{
NS_ENSURE_TRUE_VOID(Preferences::GetRootBranch());
nsAutoCString prefName, langGroupString;
aLangGroup->ToUTF8String(langGroupString);
nsAutoCString genericDotLang;
if (aGenericName) {
genericDotLang.Assign(aGenericName);
} else {
prefName.AssignLiteral("font.default.");
prefName.Append(langGroupString);
genericDotLang = Preferences::GetCString(prefName.get());
}
genericDotLang.Append('.');
genericDotLang.Append(langGroupString);
// fetch font.name.xxx value
prefName.AssignLiteral("font.name.");
prefName.Append(genericDotLang);
nsAdoptingString nameValue = Preferences::GetString(prefName.get());
if (nameValue) {
if (!aFonts.IsEmpty())
aFonts.AppendLiteral(", ");
aFonts += nameValue;
}
// fetch font.name-list.xxx value
prefName.AssignLiteral("font.name-list.");
prefName.Append(genericDotLang);
nsAdoptingString nameListValue = Preferences::GetString(prefName.get());
if (nameListValue && !nameListValue.Equals(nameValue)) {
if (!aFonts.IsEmpty())
aFonts.AppendLiteral(", ");
aFonts += nameListValue;
}
}
void
gfxPlatform::GetPrefFonts(nsIAtom *aLanguage, nsString& aFonts, bool aAppendUnicode)
{
aFonts.Truncate();
AppendGenericFontFromPref(aFonts, aLanguage, nullptr);
if (aAppendUnicode)
AppendGenericFontFromPref(aFonts, nsGkAtoms::Unicode, nullptr);
}
bool gfxPlatform::ForEachPrefFont(eFontPrefLang aLangArray[], uint32_t aLangArrayLen, PrefFontCallback aCallback,
void *aClosure)
{
@@ -1863,12 +1816,12 @@ gfxPlatform::TransformPixel(const Color& in, Color& out, qcms_transform *transfo
out = Color::FromABGR(packed);
#else
/* ARGB puts the bytes in |ARGB| order on big endian */
uint32_t packed = in.ToARGB();
uint32_t packed = in.UnusualToARGB();
/* add one to move past the alpha byte */
qcms_transform_data(transform,
(uint8_t *)&packed + 1, (uint8_t *)&packed + 1,
1);
out = Color::FromARGB(packed);
out = Color::UnusualFromARGB(packed);
#endif
}
@@ -2401,6 +2354,13 @@ gfxPlatform::UsesOffMainThreadCompositing()
}
/***
* The preference "layout.frame_rate" has 3 meanings depending on the value:
*
* -1 = Auto (default), use hardware vsync or software vsync @ 60 hz if hw vsync fails.
* 0 = ASAP mode - used during talos testing.
* X = Software vsync at a rate of X times per second.
*/
already_AddRefed<mozilla::gfx::VsyncSource>
gfxPlatform::CreateHardwareVsyncSource()
{
@@ -2420,6 +2380,29 @@ gfxPlatform::IsInLayoutAsapMode()
return Preferences::GetInt("layout.frame_rate", -1) == 0;
}
/* static */ bool
gfxPlatform::ForceSoftwareVsync()
{
return Preferences::GetInt("layout.frame_rate", -1) > 0;
}
/* static */ int
gfxPlatform::GetSoftwareVsyncRate()
{
int preferenceRate = Preferences::GetInt("layout.frame_rate",
gfxPlatform::GetDefaultFrameRate());
if (preferenceRate <= 0) {
return gfxPlatform::GetDefaultFrameRate();
}
return preferenceRate;
}
/* static */ int
gfxPlatform::GetDefaultFrameRate()
{
return 60;
}
static nsString
DetectBadApzWheelInputPrefs()
{
@@ -2557,9 +2540,11 @@ gfxPlatform::NotifyCompositorCreated(LayersBackend aBackend)
mCompositorBackend = aBackend;
// Notify that we created a compositor, so telemetry can update.
if (nsCOMPtr<nsIObserverService> obsvc = services::GetObserverService()) {
obsvc->NotifyObservers(nullptr, "compositor:created", nullptr);
}
NS_DispatchToMainThread(NS_NewRunnableFunction([] {
if (nsCOMPtr<nsIObserverService> obsvc = services::GetObserverService()) {
obsvc->NotifyObservers(nullptr, "compositor:created", nullptr);
}
}));
}
void
+15 -2
View File
@@ -427,8 +427,6 @@ public:
virtual bool DidRenderingDeviceReset(DeviceResetReason* aResetReason = nullptr) { return false; }
void GetPrefFonts(nsIAtom *aLanguage, nsString& array, bool aAppendUnicode = true);
// in some situations, need to make decisions about ambiguous characters, may need to look at multiple pref langs
void GetLangPrefs(eFontPrefLang aPrefLangs[], uint32_t &aLen, eFontPrefLang aCharLang, eFontPrefLang aPageLang);
@@ -610,6 +608,21 @@ public:
*/
static bool IsInLayoutAsapMode();
/**
* Returns the software vsync rate to use.
*/
static int GetSoftwareVsyncRate();
/**
* Returns whether or not a custom vsync rate is set.
*/
static bool ForceSoftwareVsync();
/**
* Returns the default frame rate for the refresh driver / software vsync.
*/
static int GetDefaultFrameRate();
/**
* Used to test which input types are handled via APZ.
*/
-2
View File
@@ -263,12 +263,10 @@ private:
DECL_GFX_PREF(Once, "gfx.vr.mirror-textures", VRMirrorTextures, bool, false);
DECL_GFX_PREF(Live, "gfx.vsync.collect-scroll-transforms", CollectScrollTransforms, bool, false);
DECL_GFX_PREF(Once, "gfx.vsync.compositor", VsyncAlignedCompositor, bool, false);
// On b2g, in really bad cases, I've seen up to 80 ms delays between touch events and the main thread
// processing them. So 80 ms / 16 = 5 vsync events. Double it up just to be on the safe side, so 10.
DECL_GFX_PREF(Once, "gfx.vsync.compositor.unobserve-count", CompositorUnobserveCount, int32_t, 10);
// Use vsync events generated by hardware
DECL_GFX_PREF(Once, "gfx.vsync.hw-vsync.enabled", HardwareVsyncEnabled, bool, false);
DECL_GFX_PREF(Once, "gfx.vsync.refreshdriver", VsyncAlignedRefreshDriver, bool, false);
DECL_GFX_PREF(Once, "gfx.work-around-driver-bugs", WorkAroundDriverBugs, bool, true);
DECL_GFX_PREF(Once, "gfx.screen-mirroring.enabled", ScreenMirroringEnabled, bool, false);
+2 -4
View File
@@ -77,7 +77,6 @@ using namespace mozilla::layout;
static PRLogModuleInfo *gLog = nullptr;
#define LOG(...) MOZ_LOG(gLog, mozilla::LogLevel::Debug, (__VA_ARGS__))
#define DEFAULT_FRAME_RATE 60
#define DEFAULT_THROTTLED_FRAME_RATE 1
#define DEFAULT_RECOMPUTE_VISIBILITY_INTERVAL_MS 1000
// after 10 minutes, stop firing off inactive timers
@@ -856,7 +855,6 @@ CreateVsyncRefreshTimer()
gfxPrefs::GetSingleton();
if (!gfxPrefs::VsyncAlignedRefreshDriver()
|| !gfxPrefs::HardwareVsyncEnabled()
|| gfxPlatform::IsInLayoutAsapMode()) {
return;
}
@@ -933,7 +931,7 @@ nsRefreshDriver::Shutdown()
/* static */ int32_t
nsRefreshDriver::DefaultInterval()
{
return NSToIntRound(1000.0 / DEFAULT_FRAME_RATE);
return NSToIntRound(1000.0 / gfxPlatform::GetDefaultFrameRate());
}
// Compute the interval to use for the refresh driver timer, in milliseconds.
@@ -949,7 +947,7 @@ nsRefreshDriver::GetRegularTimerInterval(bool *outIsDefault) const
{
int32_t rate = Preferences::GetInt("layout.frame_rate", -1);
if (rate < 0) {
rate = DEFAULT_FRAME_RATE;
rate = gfxPlatform::GetDefaultFrameRate();
if (outIsDefault) {
*outIsDefault = true;
}
-2
View File
@@ -5262,8 +5262,6 @@ pref("dom.audiochannel.mutedByDefault", false);
// Hardware vsync supported on windows, os x, and b2g.
// Linux and fennec will use software vsync.
#if defined(XP_MACOSX) || defined(XP_WIN) || defined(XP_LINUX)
pref("gfx.vsync.hw-vsync.enabled", false);
pref("gfx.vsync.compositor", true);
pref("gfx.vsync.refreshdriver", true);
#endif
+43
View File
@@ -28,6 +28,49 @@ already_AddRefed<Touch> SingleTouchData::ToNewDOMTouch() const
return touch.forget();
}
MouseInput::MouseInput(const WidgetMouseEventBase& aMouseEvent)
: InputData(MOUSE_INPUT, aMouseEvent.time, aMouseEvent.timeStamp,
aMouseEvent.modifiers)
{
MOZ_ASSERT(NS_IsMainThread(),
"Can only copy from WidgetTouchEvent on main thread");
mButtonType = NONE;
switch (aMouseEvent.button) {
case WidgetMouseEventBase::eLeftButton:
mButtonType = MouseInput::LEFT_BUTTON;
break;
case WidgetMouseEventBase::eMiddleButton:
mButtonType = MouseInput::MIDDLE_BUTTON;
break;
case WidgetMouseEventBase::eRightButton:
mButtonType = MouseInput::RIGHT_BUTTON;
break;
}
switch (aMouseEvent.mMessage) {
case eMouseMove:
mType = MOUSE_MOVE;
break;
case eMouseUp:
mType = MOUSE_UP;
break;
case eMouseDown:
mType = MOUSE_DOWN;
break;
case eDragStart:
mType = MOUSE_DRAG_START;
break;
case eDragEnd:
mType = MOUSE_DRAG_END;
break;
default:
MOZ_ASSERT_UNREACHABLE("Mouse event type not supported");
break;
}
}
MultiTouchInput::MultiTouchInput(const WidgetTouchEvent& aTouchEvent)
: InputData(MULTITOUCH_INPUT, aTouchEvent.time, aTouchEvent.timeStamp,
aTouchEvent.modifiers)
+44
View File
@@ -30,6 +30,7 @@ class Matrix4x4;
enum InputType
{
MULTITOUCH_INPUT,
MOUSE_INPUT,
PANGESTURE_INPUT,
PINCHGESTURE_INPUT,
TAPGESTURE_INPUT,
@@ -37,6 +38,7 @@ enum InputType
};
class MultiTouchInput;
class MouseInput;
class PanGestureInput;
class PinchGestureInput;
class TapGestureInput;
@@ -76,6 +78,7 @@ public:
Modifiers modifiers;
INPUTDATA_AS_CHILD_TYPE(MultiTouchInput, MULTITOUCH_INPUT)
INPUTDATA_AS_CHILD_TYPE(MouseInput, MOUSE_INPUT)
INPUTDATA_AS_CHILD_TYPE(PanGestureInput, PANGESTURE_INPUT)
INPUTDATA_AS_CHILD_TYPE(PinchGestureInput, PINCHGESTURE_INPUT)
INPUTDATA_AS_CHILD_TYPE(TapGestureInput, TAPGESTURE_INPUT)
@@ -245,6 +248,47 @@ public:
nsTArray<SingleTouchData> mTouches;
};
class MouseInput : public InputData
{
public:
enum MouseType
{
MOUSE_MOVE,
MOUSE_DOWN,
MOUSE_UP,
MOUSE_DRAG_START,
MOUSE_DRAG_END,
};
enum ButtonType
{
LEFT_BUTTON,
MIDDLE_BUTTON,
RIGHT_BUTTON,
NONE
};
MouseInput(MouseType aType, ButtonType aButtonType, uint32_t aTime,
TimeStamp aTimeStamp, Modifiers aModifiers)
: InputData(MOUSE_INPUT, aTime, aTimeStamp, aModifiers)
, mType(aType)
, mButtonType(aButtonType)
{}
MouseInput()
: InputData(MOUSE_INPUT)
{}
explicit MouseInput(const WidgetMouseEventBase& aMouseEvent);
bool IsLeftButton() const { return mButtonType == LEFT_BUTTON; }
MouseType mType;
ButtonType mButtonType;
ScreenPoint mOrigin;
ParentLayerPoint mLocalOrigin;
};
/**
* Encapsulation class for pan events, can be used off-main-thread.
* These events are currently only used for scrolling on desktop.
+1 -2
View File
@@ -154,8 +154,7 @@ HwcComposer2D::RegisterHwcEventCallback()
&HookVsync, // 2nd: void (*vsync)(...)
&HookHotplug // 3rd: void (*hotplug)(...)
};
mHasHWVsync = mHal->RegisterHwcEventCallback(cHWCProcs) &&
gfxPrefs::HardwareVsyncEnabled();
mHasHWVsync = mHal->RegisterHwcEventCallback(cHWCProcs);
return mHasHWVsync;
}
+1 -6
View File
@@ -563,10 +563,7 @@ nsScreenManagerGonk::Initialize()
void
nsScreenManagerGonk::DisplayEnabled(bool aEnabled)
{
if (gfxPrefs::HardwareVsyncEnabled()) {
VsyncControl(aEnabled);
}
VsyncControl(aEnabled);
NS_DispatchToMainThread(aEnabled ? mScreenOnEvent : mScreenOffEvent);
}
@@ -635,8 +632,6 @@ nsScreenManagerGonk::GetSystemDefaultScale(float *aDefaultScale)
void
nsScreenManagerGonk::VsyncControl(bool aEnabled)
{
MOZ_ASSERT(gfxPrefs::HardwareVsyncEnabled());
if (!NS_IsMainThread()) {
NS_DispatchToMainThread(
NS_NewRunnableMethodWithArgs<bool>(this,
+5 -7
View File
@@ -1050,13 +1050,11 @@ nsBaseWidget::GetDocument() const
void nsBaseWidget::CreateCompositorVsyncDispatcher()
{
if (gfxPrefs::HardwareVsyncEnabled()) {
// Parent directly listens to the vsync source whereas
// child process communicate via IPC
// Should be called AFTER gfxPlatform is initialized
if (XRE_IsParentProcess()) {
mCompositorVsyncDispatcher = new CompositorVsyncDispatcher();
}
// Parent directly listens to the vsync source whereas
// child process communicate via IPC
// Should be called AFTER gfxPlatform is initialized
if (XRE_IsParentProcess()) {
mCompositorVsyncDispatcher = new CompositorVsyncDispatcher();
}
}