mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 13:51:41 +00:00
Bug 1055050 - Add visual warning if the transaction latency is > 100 ms. r=mwoodrow
--HG-- extra : rebase_source : 23140892b8e598c7073dd1b8c83fbddfa0bf52ee
This commit is contained in:
parent
643c02ae7c
commit
d83f3e3d33
@ -7,6 +7,7 @@
|
||||
#define GFX_TRANSACTION_ID_ALLOCATOR_H
|
||||
|
||||
#include "nsISupportsImpl.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
@ -44,6 +45,11 @@ public:
|
||||
* return ordering issues.
|
||||
*/
|
||||
virtual void RevokeTransactionId(uint64_t aTransactionId) = 0;
|
||||
|
||||
/**
|
||||
* Get the start time of the current refresh tick.
|
||||
*/
|
||||
virtual mozilla::TimeStamp GetTransactionStart() = 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -129,6 +129,7 @@ void
|
||||
ClientLayerManager::BeginTransactionWithTarget(gfxContext* aTarget)
|
||||
{
|
||||
mInTransaction = true;
|
||||
mTransactionStart = TimeStamp::Now();
|
||||
|
||||
#ifdef MOZ_LAYERS_HAVE_LOG
|
||||
MOZ_LAYERS_LOG(("[----- BeginTransaction"));
|
||||
@ -184,7 +185,6 @@ ClientLayerManager::BeginTransactionWithTarget(gfxContext* aTarget)
|
||||
void
|
||||
ClientLayerManager::BeginTransaction()
|
||||
{
|
||||
mInTransaction = true;
|
||||
BeginTransactionWithTarget(nullptr);
|
||||
}
|
||||
|
||||
@ -260,6 +260,9 @@ ClientLayerManager::EndTransaction(DrawThebesLayerCallback aCallback,
|
||||
for (size_t i = 0; i < mTexturePools.Length(); i++) {
|
||||
mTexturePools[i]->ReturnDeferredClients();
|
||||
}
|
||||
|
||||
mInTransaction = false;
|
||||
mTransactionStart = TimeStamp();
|
||||
}
|
||||
|
||||
bool
|
||||
@ -448,13 +451,19 @@ ClientLayerManager::ForwardTransaction(bool aScheduleComposite)
|
||||
mPhase = PHASE_FORWARD;
|
||||
|
||||
mLatestTransactionId = mTransactionIdAllocator->GetTransactionId();
|
||||
TimeStamp transactionStart;
|
||||
if (!mTransactionIdAllocator->GetTransactionStart().IsNull()) {
|
||||
transactionStart = mTransactionIdAllocator->GetTransactionStart();
|
||||
} else {
|
||||
transactionStart = mTransactionStart;
|
||||
}
|
||||
|
||||
// forward this transaction's changeset to our LayerManagerComposite
|
||||
bool sent;
|
||||
AutoInfallibleTArray<EditReply, 10> replies;
|
||||
if (mForwarder->EndTransaction(&replies, mRegionToClear,
|
||||
mLatestTransactionId, aScheduleComposite, mPaintSequenceNumber,
|
||||
mIsRepeatTransaction, &sent)) {
|
||||
mIsRepeatTransaction, transactionStart, &sent)) {
|
||||
for (nsTArray<EditReply>::size_type i = 0; i < replies.Length(); ++i) {
|
||||
const EditReply& reply = replies[i];
|
||||
|
||||
|
@ -300,6 +300,7 @@ private:
|
||||
RefPtr<ShadowLayerForwarder> mForwarder;
|
||||
nsAutoTArray<RefPtr<TextureClientPool>,2> mTexturePools;
|
||||
nsAutoTArray<dom::OverfillCallback*,0> mOverfillCallbacks;
|
||||
mozilla::TimeStamp mTransactionStart;
|
||||
|
||||
// indexed by gfx::SurfaceFormat
|
||||
nsTArray<RefPtr<SimpleTextureClientPool> > mSimpleTilePools;
|
||||
|
@ -339,13 +339,53 @@ LayerManagerComposite::RenderDebugOverlay(const Rect& aBounds)
|
||||
bool drawFrameCounter = gfxPrefs::DrawFrameCounter();
|
||||
bool drawFrameColorBars = gfxPrefs::CompositorDrawColorBars();
|
||||
|
||||
TimeStamp now = TimeStamp::Now();
|
||||
|
||||
if (drawFps) {
|
||||
if (!mFPS) {
|
||||
mFPS = MakeUnique<FPSState>();
|
||||
}
|
||||
|
||||
#ifdef ANDROID
|
||||
// Draw a translation delay warning overlay
|
||||
int width;
|
||||
int border;
|
||||
float alpha = 1;
|
||||
if ((now - mWarnTime).ToMilliseconds() < 150) {
|
||||
printf_stderr("Draw\n");
|
||||
EffectChain effects;
|
||||
|
||||
// Black blorder
|
||||
border = 4;
|
||||
width = 6;
|
||||
effects.mPrimaryEffect = new EffectSolidColor(gfx::Color(0, 0, 0, 1));
|
||||
mCompositor->DrawQuad(gfx::Rect(border, border, aBounds.width - 2 * border, width),
|
||||
aBounds, effects, alpha, gfx::Matrix4x4());
|
||||
mCompositor->DrawQuad(gfx::Rect(border, aBounds.height - border - width, aBounds.width - 2 * border, width),
|
||||
aBounds, effects, alpha, gfx::Matrix4x4());
|
||||
mCompositor->DrawQuad(gfx::Rect(border, border + width, width, aBounds.height - 2 * border - width * 2),
|
||||
aBounds, effects, alpha, gfx::Matrix4x4());
|
||||
mCompositor->DrawQuad(gfx::Rect(aBounds.width - border - width, border + width, width, aBounds.height - 2 * border - 2 * width),
|
||||
aBounds, effects, alpha, gfx::Matrix4x4());
|
||||
|
||||
// Content
|
||||
border = 5;
|
||||
width = 4;
|
||||
effects.mPrimaryEffect = new EffectSolidColor(gfx::Color(1, 1.f - mWarningLevel, 0, 1));
|
||||
mCompositor->DrawQuad(gfx::Rect(border, border, aBounds.width - 2 * border, width),
|
||||
aBounds, effects, alpha, gfx::Matrix4x4());
|
||||
mCompositor->DrawQuad(gfx::Rect(border, aBounds.height - border - width, aBounds.width - 2 * border, width),
|
||||
aBounds, effects, alpha, gfx::Matrix4x4());
|
||||
mCompositor->DrawQuad(gfx::Rect(border, border + width, width, aBounds.height - 2 * border - width * 2),
|
||||
aBounds, effects, alpha, gfx::Matrix4x4());
|
||||
mCompositor->DrawQuad(gfx::Rect(aBounds.width - border - width, border + width, width, aBounds.height - 2 * border - 2 * width),
|
||||
aBounds, effects, alpha, gfx::Matrix4x4());
|
||||
SetDebugOverlayWantsNextFrame(true);
|
||||
}
|
||||
#endif
|
||||
|
||||
float fillRatio = mCompositor->GetFillRatio();
|
||||
mFPS->DrawFPS(TimeStamp::Now(), drawFrameColorBars ? 10 : 0, 0, unsigned(fillRatio), mCompositor);
|
||||
mFPS->DrawFPS(now, drawFrameColorBars ? 10 : 0, 0, unsigned(fillRatio), mCompositor);
|
||||
} else {
|
||||
mFPS = nullptr;
|
||||
}
|
||||
|
@ -239,6 +239,19 @@ public:
|
||||
|
||||
TextRenderer* GetTextRenderer() { return mTextRenderer; }
|
||||
|
||||
/**
|
||||
* Add an on frame warning.
|
||||
* @param severity ranges from 0 to 1. It's used to compute the warning color.
|
||||
*/
|
||||
void VisualFrameWarning(float severity) {
|
||||
mozilla::TimeStamp now = TimeStamp::Now();
|
||||
if (severity > mWarningLevel ||
|
||||
mWarnTime + TimeDuration::FromMilliseconds(1500) < now) {
|
||||
mWarnTime = now;
|
||||
mWarningLevel = severity;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
/** Region we're clipping our current drawing to. */
|
||||
nsIntRegion mClippingRegion;
|
||||
@ -277,6 +290,8 @@ private:
|
||||
bool aInvertEffect,
|
||||
float aContrastEffect);
|
||||
|
||||
float mWarningLevel;
|
||||
mozilla::TimeStamp mWarnTime;
|
||||
RefPtr<Compositor> mCompositor;
|
||||
UniquePtr<LayerProperties> mClonedLayerTreeProperties;
|
||||
|
||||
|
@ -185,10 +185,12 @@ LayerTransactionParent::RecvUpdateNoSwap(const InfallibleTArray<Edit>& cset,
|
||||
const bool& isFirstPaint,
|
||||
const bool& scheduleComposite,
|
||||
const uint32_t& paintSequenceNumber,
|
||||
const bool& isRepeatTransaction)
|
||||
const bool& isRepeatTransaction,
|
||||
const mozilla::TimeStamp& aTransactionStart)
|
||||
{
|
||||
return RecvUpdate(cset, aTransactionId, targetConfig, isFirstPaint,
|
||||
scheduleComposite, paintSequenceNumber, isRepeatTransaction, nullptr);
|
||||
scheduleComposite, paintSequenceNumber, isRepeatTransaction,
|
||||
aTransactionStart, nullptr);
|
||||
}
|
||||
|
||||
bool
|
||||
@ -199,6 +201,7 @@ LayerTransactionParent::RecvUpdate(const InfallibleTArray<Edit>& cset,
|
||||
const bool& scheduleComposite,
|
||||
const uint32_t& paintSequenceNumber,
|
||||
const bool& isRepeatTransaction,
|
||||
const mozilla::TimeStamp& aTransactionStart,
|
||||
InfallibleTArray<EditReply>* reply)
|
||||
{
|
||||
profiler_tracing("Paint", "Composite", TRACING_INTERVAL_START);
|
||||
@ -569,6 +572,16 @@ LayerTransactionParent::RecvUpdate(const InfallibleTArray<Edit>& cset,
|
||||
}
|
||||
#endif
|
||||
|
||||
TimeDuration latency = TimeStamp::Now() - aTransactionStart;
|
||||
// Theshold is 200ms to trigger, 1000ms to hit red
|
||||
if (latency > TimeDuration::FromMilliseconds(200)) {
|
||||
float severity = (latency - TimeDuration::FromMilliseconds(200)).ToMilliseconds() / 800;
|
||||
if (severity > 1.f) {
|
||||
severity = 1.f;
|
||||
}
|
||||
mLayerManager->VisualFrameWarning(severity);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -105,6 +105,7 @@ protected:
|
||||
const bool& scheduleComposite,
|
||||
const uint32_t& paintSequenceNumber,
|
||||
const bool& isRepeatTransaction,
|
||||
const mozilla::TimeStamp& aTransactionStart,
|
||||
EditReplyArray* reply) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool RecvUpdateNoSwap(const EditArray& cset,
|
||||
@ -113,7 +114,8 @@ protected:
|
||||
const bool& isFirstPaint,
|
||||
const bool& scheduleComposite,
|
||||
const uint32_t& paintSequenceNumber,
|
||||
const bool& isRepeatTransaction) MOZ_OVERRIDE;
|
||||
const bool& isRepeatTransaction,
|
||||
const mozilla::TimeStamp& aTransactionStart) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool RecvClearCachedResources() MOZ_OVERRIDE;
|
||||
virtual bool RecvForceComposite() MOZ_OVERRIDE;
|
||||
|
@ -55,14 +55,14 @@ parent:
|
||||
// for a particular document.
|
||||
sync Update(Edit[] cset, uint64_t id, TargetConfig targetConfig, bool isFirstPaint,
|
||||
bool scheduleComposite, uint32_t paintSequenceNumber,
|
||||
bool isRepeatTransaction)
|
||||
bool isRepeatTransaction, TimeStamp transactionStart)
|
||||
returns (EditReply[] reply);
|
||||
|
||||
// We don't need to send a sync transaction if
|
||||
// no transaction operate require a swap.
|
||||
async UpdateNoSwap(Edit[] cset, uint64_t id, TargetConfig targetConfig, bool isFirstPaint,
|
||||
bool scheduleComposite, uint32_t paintSequenceNumber,
|
||||
bool isRepeatTransaction);
|
||||
bool isRepeatTransaction, TimeStamp transactionStart);
|
||||
|
||||
// Testing APIs
|
||||
|
||||
|
@ -529,6 +529,7 @@ ShadowLayerForwarder::EndTransaction(InfallibleTArray<EditReply>* aReplies,
|
||||
bool aScheduleComposite,
|
||||
uint32_t aPaintSequenceNumber,
|
||||
bool aIsRepeatTransaction,
|
||||
const mozilla::TimeStamp& aTransactionStart,
|
||||
bool* aSent)
|
||||
{
|
||||
*aSent = false;
|
||||
@ -653,7 +654,8 @@ ShadowLayerForwarder::EndTransaction(InfallibleTArray<EditReply>* aReplies,
|
||||
!mShadowManager->IPCOpen() ||
|
||||
!mShadowManager->SendUpdate(cset, aId, targetConfig, mIsFirstPaint,
|
||||
aScheduleComposite, aPaintSequenceNumber,
|
||||
aIsRepeatTransaction, aReplies)) {
|
||||
aIsRepeatTransaction, aTransactionStart,
|
||||
aReplies)) {
|
||||
MOZ_LAYERS_LOG(("[LayersForwarder] WARNING: sending transaction failed!"));
|
||||
return false;
|
||||
}
|
||||
@ -666,7 +668,7 @@ ShadowLayerForwarder::EndTransaction(InfallibleTArray<EditReply>* aReplies,
|
||||
!mShadowManager->IPCOpen() ||
|
||||
!mShadowManager->SendUpdateNoSwap(cset, aId, targetConfig, mIsFirstPaint,
|
||||
aScheduleComposite, aPaintSequenceNumber,
|
||||
aIsRepeatTransaction)) {
|
||||
aIsRepeatTransaction, aTransactionStart)) {
|
||||
MOZ_LAYERS_LOG(("[LayersForwarder] WARNING: sending transaction failed!"));
|
||||
return false;
|
||||
}
|
||||
|
@ -306,6 +306,7 @@ public:
|
||||
bool aScheduleComposite,
|
||||
uint32_t aPaintSequenceNumber,
|
||||
bool aIsRepeatTransaction,
|
||||
const mozilla::TimeStamp& aTransactionStart,
|
||||
bool* aSent);
|
||||
|
||||
/**
|
||||
|
@ -1108,6 +1108,9 @@ nsRefreshDriver::Tick(int64_t aNowEpoch, TimeStamp aNowTime)
|
||||
AutoRestore<bool> restoreInRefresh(mInRefresh);
|
||||
mInRefresh = true;
|
||||
|
||||
AutoRestore<TimeStamp> restoreTickStart(mTickStart);
|
||||
mTickStart = TimeStamp::Now();
|
||||
|
||||
/*
|
||||
* The timer holds a reference to |this| while calling |Notify|.
|
||||
* However, implementations of |WillRefresh| are permitted to destroy
|
||||
@ -1432,6 +1435,12 @@ nsRefreshDriver::RevokeTransactionId(uint64_t aTransactionId)
|
||||
mPendingTransaction--;
|
||||
}
|
||||
|
||||
mozilla::TimeStamp
|
||||
nsRefreshDriver::GetTransactionStart()
|
||||
{
|
||||
return mTickStart;
|
||||
}
|
||||
|
||||
void
|
||||
nsRefreshDriver::NotifyTransactionCompleted(uint64_t aTransactionId)
|
||||
{
|
||||
|
@ -275,6 +275,7 @@ public:
|
||||
virtual uint64_t GetTransactionId() MOZ_OVERRIDE;
|
||||
void NotifyTransactionCompleted(uint64_t aTransactionId) MOZ_OVERRIDE;
|
||||
void RevokeTransactionId(uint64_t aTransactionId) MOZ_OVERRIDE;
|
||||
mozilla::TimeStamp GetTransactionStart() MOZ_OVERRIDE;
|
||||
|
||||
bool IsWaitingForPaint(mozilla::TimeStamp aTime);
|
||||
|
||||
@ -360,6 +361,7 @@ private:
|
||||
int64_t mMostRecentRefreshEpochTime;
|
||||
mozilla::TimeStamp mMostRecentRefresh;
|
||||
mozilla::TimeStamp mMostRecentTick;
|
||||
mozilla::TimeStamp mTickStart;
|
||||
|
||||
// separate arrays for each flush type we support
|
||||
ObserverArray mObservers[3];
|
||||
|
Loading…
Reference in New Issue
Block a user