Bug 1226826 - Record if painted displayport updates were due to repaints from the relevant layer tree or not. r?botond
--- a/gfx/layers/apz/src/APZCTreeManager.cpp
+++ b/gfx/layers/apz/src/APZCTreeManager.cpp
@@ -450,18 +450,18 @@ APZCTreeManager::PrepareNodeForLayer(con
// to be destroyed, because it's going to remain active.
aState.mNodesToDestroy.RemoveElement(node);
node->SetPrevSibling(nullptr);
node->SetLastChild(nullptr);
}
APZCTM_LOG("Using APZC %p for layer %p with identifiers %" PRId64 " %" PRId64 "\n", apzc, aLayer.GetLayer(), aLayersId, aMetrics.GetScrollId());
- apzc->NotifyLayersUpdated(aMetrics,
- aState.mIsFirstPaint && (aLayersId == aState.mOriginatingLayersId));
+ apzc->NotifyLayersUpdated(aMetrics, aState.mIsFirstPaint,
+ aLayersId == aState.mOriginatingLayersId);
// Since this is the first time we are encountering an APZC with this guid,
// the node holding it must be the primary holder. It may be newly-created
// or not, depending on whether it went through the newApzc branch above.
MOZ_ASSERT(node->IsPrimaryHolder() && node->GetApzc() && node->GetApzc()->Matches(guid));
ParentLayerIntRegion clipRegion = ComputeClipRegion(state->mController, aLayer);
node->SetHitTestData(
--- a/gfx/layers/apz/src/AsyncPanZoomController.cpp
+++ b/gfx/layers/apz/src/AsyncPanZoomController.cpp
@@ -3126,34 +3126,50 @@ bool AsyncPanZoomController::IsCurrently
if (painted.Contains(visible)) {
return false;
}
APZC_LOG_FM(mFrameMetrics, "%p is currently checkerboarding (painted %s visble %s)",
this, Stringify(painted).c_str(), Stringify(visible).c_str());
return true;
}
-void AsyncPanZoomController::NotifyLayersUpdated(const FrameMetrics& aLayerMetrics, bool aIsFirstPaint) {
+void AsyncPanZoomController::NotifyLayersUpdated(const FrameMetrics& aLayerMetrics,
+ bool aIsFirstPaint,
+ bool aThisLayerTreeUpdated)
+{
APZThreadUtils::AssertOnCompositorThread();
ReentrantMonitorAutoEnter lock(mMonitor);
bool isDefault = mFrameMetrics.IsDefault();
mLastContentPaintMetrics = aLayerMetrics;
mFrameMetrics.SetScrollParentId(aLayerMetrics.GetScrollParentId());
- APZC_LOG_FM(aLayerMetrics, "%p got a NotifyLayersUpdated with aIsFirstPaint=%d", this, aIsFirstPaint);
+ APZC_LOG_FM(aLayerMetrics, "%p got a NotifyLayersUpdated with aIsFirstPaint=%d, aThisLayerTreeUpdated=%d",
+ this, aIsFirstPaint, aThisLayerTreeUpdated);
if (mCheckerboardEvent) {
std::string str;
- if (!aLayerMetrics.GetPaintRequestTime().IsNull()) {
- TimeDuration paintTime = TimeStamp::Now() - aLayerMetrics.GetPaintRequestTime();
- std::stringstream info;
- info << " painttime " << paintTime.ToMilliseconds();
- str = info.str();
+ if (aThisLayerTreeUpdated) {
+ if (!aLayerMetrics.GetPaintRequestTime().IsNull()) {
+ // Note that we might get the paint request time as non-null, but with
+ // aThisLayerTreeUpdated false. That can happen if we get a layer transaction
+ // from a different process right after we get the layer transaction with
+ // aThisLayerTreeUpdated == true. In this case we want to ignore the
+ // paint request time because it was already dumped in the previous layer
+ // transaction.
+ TimeDuration paintTime = TimeStamp::Now() - aLayerMetrics.GetPaintRequestTime();
+ std::stringstream info;
+ info << " painttime " << paintTime.ToMilliseconds();
+ str = info.str();
+ } else {
+ // This might be indicative of a wasted paint particularly if it happens
+ // during a checkerboard event.
+ str = " (this layertree updated)";
+ }
}
mCheckerboardEvent->UpdateRendertraceProperty(
CheckerboardEvent::Page, aLayerMetrics.GetScrollableRect());
mCheckerboardEvent->UpdateRendertraceProperty(
CheckerboardEvent::PaintedDisplayPort,
aLayerMetrics.GetDisplayPort() + aLayerMetrics.GetScrollOffset(),
str);
if (!aLayerMetrics.GetCriticalDisplayPort().IsEmpty()) {
@@ -3185,17 +3201,17 @@ void AsyncPanZoomController::NotifyLayer
&& (aLayerMetrics.GetScrollGeneration() != mFrameMetrics.GetScrollGeneration());
bool smoothScrollRequested = aLayerMetrics.GetDoSmoothScroll()
&& (aLayerMetrics.GetScrollGeneration() != mFrameMetrics.GetScrollGeneration());
// TODO if we're in a drag and scrollOffsetUpdated is set then we want to
// ignore it
- if (aIsFirstPaint || isDefault) {
+ if ((aIsFirstPaint && aThisLayerTreeUpdated) || isDefault) {
// Initialize our internal state to something sane when the content
// that was just painted is something we knew nothing about previously
CancelAnimation();
mFrameMetrics = aLayerMetrics;
if (scrollOffsetUpdated) {
AcknowledgeScrollUpdate();
}
--- a/gfx/layers/apz/src/AsyncPanZoomController.h
+++ b/gfx/layers/apz/src/AsyncPanZoomController.h
@@ -178,17 +178,18 @@ public:
/**
* A shadow layer update has arrived. |aLayerMetrics| is the new FrameMetrics
* for the container layer corresponding to this APZC.
* |aIsFirstPaint| is a flag passed from the shadow
* layers code indicating that the frame metrics being sent with this call are
* the initial metrics and the initial paint of the frame has just happened.
*/
- void NotifyLayersUpdated(const FrameMetrics& aLayerMetrics, bool aIsFirstPaint);
+ void NotifyLayersUpdated(const FrameMetrics& aLayerMetrics, bool aIsFirstPaint,
+ bool aThisLayerTreeUpdated);
/**
* The platform implementation must set the compositor parent so that we can
* request composites.
*/
void SetCompositorParent(CompositorParent* aCompositorParent);
/**
--- a/gfx/layers/apz/test/gtest/TestAsyncPanZoomController.cpp
+++ b/gfx/layers/apz/test/gtest/TestAsyncPanZoomController.cpp
@@ -1176,23 +1176,23 @@ TEST_F(APZCBasicTester, ComplexTransform
ParentLayerPoint pointOut;
AsyncTransform viewTransformOut;
// Both the parent and child layer should behave exactly the same here, because
// the CSS transform on the child layer does not affect the SampleContentTransformForFrame code
// initial transform
apzc->SetFrameMetrics(metrics);
- apzc->NotifyLayersUpdated(metrics, true);
+ apzc->NotifyLayersUpdated(metrics, true, true);
apzc->SampleContentTransformForFrame(&viewTransformOut, pointOut);
EXPECT_EQ(AsyncTransform(LayerToParentLayerScale(1), ParentLayerPoint()), viewTransformOut);
EXPECT_EQ(ParentLayerPoint(60, 60), pointOut);
childApzc->SetFrameMetrics(childMetrics);
- childApzc->NotifyLayersUpdated(childMetrics, true);
+ childApzc->NotifyLayersUpdated(childMetrics, true, true);
childApzc->SampleContentTransformForFrame(&viewTransformOut, pointOut);
EXPECT_EQ(AsyncTransform(LayerToParentLayerScale(1), ParentLayerPoint()), viewTransformOut);
EXPECT_EQ(ParentLayerPoint(60, 60), pointOut);
// do an async scroll by 5 pixels and check the transform
metrics.ScrollBy(CSSPoint(5, 0));
apzc->SetFrameMetrics(metrics);
apzc->SampleContentTransformForFrame(&viewTransformOut, pointOut);