Bug 1250517 - Differentiate between no critical display port and empty critical display port in ClientTiledPaintedLayer; r=kats

Currently the logic in ClientTiledPaintedLayer treats an empty critical
display port to mean that there is no critical display port, i.e. that
the entire visible region should be painted. However, the critical
displayport should be, and is, empty if either the display port or
composition bounds are entirely outwith the layer's bounds. We want to
render none of the layer in this case, not all of it.

Change BasicTiledLayerPaintData::mCriticalDisplayPort's type to a
Maybe<LayerIntRect>, and differentiate between it being not set and it
being an empty rect.

MozReview-Commit-ID: Gi1iZOQcOVL

--HG--
extra : transplant_source : %D5M%3A%D2lN%08%3Dnhy%F3%92%A6%03%FB%85%E2%D4%AB
This commit is contained in:
Jamie Nicol 2016-02-23 15:38:29 +00:00
parent b3029a86f3
commit bdba733905
3 changed files with 28 additions and 25 deletions

View File

@ -178,13 +178,15 @@ ClientTiledPaintedLayer::BeginPaint()
+ displayportMetrics.GetCompositionBounds().TopLeft();
Maybe<LayerRect> criticalDisplayPortTransformed =
ApplyParentLayerToLayerTransform(transformDisplayPortToLayer, criticalDisplayPort, layerBounds);
if (!criticalDisplayPortTransformed) {
mPaintData.ResetPaintData();
return;
if (criticalDisplayPortTransformed) {
mPaintData.mCriticalDisplayPort = Some(RoundedToInt(*criticalDisplayPortTransformed));
} else {
mPaintData.mCriticalDisplayPort = Some(LayerIntRect(0, 0, 0, 0));
}
mPaintData.mCriticalDisplayPort = RoundedToInt(*criticalDisplayPortTransformed);
}
TILING_LOG("TILING %p: Critical displayport %s\n", this, Stringify(mPaintData.mCriticalDisplayPort).c_str());
TILING_LOG("TILING %p: Critical displayport %s\n", this,
mPaintData.mCriticalDisplayPort ?
Stringify(*mPaintData.mCriticalDisplayPort).c_str() : "not set");
// Store the resolution from the displayport ancestor layer. Because this is Gecko-side,
// before any async transforms have occurred, we can use the zoom for this.
@ -197,11 +199,11 @@ ClientTiledPaintedLayer::BeginPaint()
ParentLayerToLayerMatrix4x4 transformToBounds = mPaintData.mTransformToCompBounds.Inverse();
Maybe<LayerRect> compositionBoundsTransformed = ApplyParentLayerToLayerTransform(
transformToBounds, scrollMetrics.GetCompositionBounds(), layerBounds);
if (!compositionBoundsTransformed) {
mPaintData.ResetPaintData();
return;
if (compositionBoundsTransformed) {
mPaintData.mCompositionBounds = *compositionBoundsTransformed;
} else {
mPaintData.mCompositionBounds.SetEmpty();
}
mPaintData.mCompositionBounds = *compositionBoundsTransformed;
TILING_LOG("TILING %p: Composition bounds %s\n", this, Stringify(mPaintData.mCompositionBounds).c_str());
// Calculate the scroll offset since the last transaction
@ -257,7 +259,7 @@ ClientTiledPaintedLayer::UseProgressiveDraw() {
return false;
}
if (mPaintData.mCriticalDisplayPort.IsEmpty()) {
if (!mPaintData.mCriticalDisplayPort) {
// This catches three scenarios:
// 1) This layer doesn't have a scrolling ancestor
// 2) This layer is subject to OMTA transforms
@ -276,7 +278,7 @@ ClientTiledPaintedLayer::UseProgressiveDraw() {
if (ClientManager()->AsyncPanZoomEnabled()) {
LayerMetricsWrapper scrollAncestor;
GetAncestorLayers(&scrollAncestor, nullptr, nullptr);
MOZ_ASSERT(scrollAncestor); // because mPaintData.mCriticalDisplayPort is non-empty
MOZ_ASSERT(scrollAncestor); // because mPaintData.mCriticalDisplayPort is set
const FrameMetrics& parentMetrics = scrollAncestor.Metrics();
if (!IsScrollingOnCompositor(parentMetrics)) {
return false;
@ -306,8 +308,8 @@ ClientTiledPaintedLayer::RenderHighPrecision(nsIntRegion& aInvalidRegion,
// used to decide stale content (currently valid and previously visible)
nsIntRegion oldValidRegion = mContentClient->GetTiledBuffer()->GetValidRegion();
oldValidRegion.And(oldValidRegion, aVisibleRegion);
if (!mPaintData.mCriticalDisplayPort.IsEmpty()) {
oldValidRegion.And(oldValidRegion, mPaintData.mCriticalDisplayPort.ToUnknownRect());
if (mPaintData.mCriticalDisplayPort) {
oldValidRegion.And(oldValidRegion, mPaintData.mCriticalDisplayPort->ToUnknownRect());
}
TILING_LOG("TILING %p: Progressive update with old valid region %s\n", this, Stringify(oldValidRegion).c_str());
@ -319,8 +321,8 @@ ClientTiledPaintedLayer::RenderHighPrecision(nsIntRegion& aInvalidRegion,
// Otherwise do a non-progressive paint
mValidRegion = aVisibleRegion;
if (!mPaintData.mCriticalDisplayPort.IsEmpty()) {
mValidRegion.And(mValidRegion, mPaintData.mCriticalDisplayPort.ToUnknownRect());
if (mPaintData.mCriticalDisplayPort) {
mValidRegion.And(mValidRegion, mPaintData.mCriticalDisplayPort->ToUnknownRect());
}
TILING_LOG("TILING %p: Non-progressive paint invalid region %s\n", this, Stringify(aInvalidRegion).c_str());
@ -341,7 +343,8 @@ ClientTiledPaintedLayer::RenderLowPrecision(nsIntRegion& aInvalidRegion,
{
// Render the low precision buffer, if the visible region is larger than the
// critical display port.
if (!nsIntRegion(mPaintData.mCriticalDisplayPort.ToUnknownRect()).Contains(aVisibleRegion)) {
if (!mPaintData.mCriticalDisplayPort ||
!nsIntRegion(mPaintData.mCriticalDisplayPort->ToUnknownRect()).Contains(aVisibleRegion)) {
nsIntRegion oldValidRegion = mContentClient->GetLowPrecisionTiledBuffer()->GetValidRegion();
oldValidRegion.And(oldValidRegion, aVisibleRegion);
@ -495,16 +498,16 @@ ClientTiledPaintedLayer::RenderLayer()
// critical displayport are discarded on the first update. Also make sure that we
// only draw stuff inside the critical displayport on the first update.
mValidRegion.And(mValidRegion, neededRegion);
if (!mPaintData.mCriticalDisplayPort.IsEmpty()) {
mValidRegion.And(mValidRegion, mPaintData.mCriticalDisplayPort.ToUnknownRect());
invalidRegion.And(invalidRegion, mPaintData.mCriticalDisplayPort.ToUnknownRect());
if (mPaintData.mCriticalDisplayPort) {
mValidRegion.And(mValidRegion, mPaintData.mCriticalDisplayPort->ToUnknownRect());
invalidRegion.And(invalidRegion, mPaintData.mCriticalDisplayPort->ToUnknownRect());
}
TILING_LOG("TILING %p: First-transaction valid region %s\n", this, Stringify(mValidRegion).c_str());
TILING_LOG("TILING %p: First-transaction invalid region %s\n", this, Stringify(invalidRegion).c_str());
} else {
if (!mPaintData.mCriticalDisplayPort.IsEmpty()) {
invalidRegion.And(invalidRegion, mPaintData.mCriticalDisplayPort.ToUnknownRect());
if (mPaintData.mCriticalDisplayPort) {
invalidRegion.And(invalidRegion, mPaintData.mCriticalDisplayPort->ToUnknownRect());
}
TILING_LOG("TILING %p: Repeat-transaction invalid region %s\n", this, Stringify(invalidRegion).c_str());
}

View File

@ -1696,7 +1696,7 @@ BasicTiledLayerPaintData::ResetPaintData()
mLowPrecisionPaintCount = 0;
mPaintFinished = false;
mCompositionBounds.SetEmpty();
mCriticalDisplayPort.SetEmpty();
mCriticalDisplayPort = Nothing();
}
} // namespace layers

View File

@ -318,10 +318,10 @@ struct BasicTiledLayerPaintData {
/*
* The critical displayport of the content from the nearest ancestor layer
* that represents scrollable content with a display port set. Empty if a
* critical displayport is not set.
* that represents scrollable content with a display port set. isNothing()
* if a critical displayport is not set.
*/
LayerIntRect mCriticalDisplayPort;
Maybe<LayerIntRect> mCriticalDisplayPort;
/*
* The render resolution of the document that the content this layer