diff --git a/gfx/layers/Layers.h b/gfx/layers/Layers.h index e42c201c238b..ae4be2e91df4 100644 --- a/gfx/layers/Layers.h +++ b/gfx/layers/Layers.h @@ -1148,7 +1148,6 @@ public: * Can be used anytime */ const nsIntRegion& GetValidRegion() const { return mValidRegion; } - virtual const nsIntRegion& GetValidLowPrecisionRegion() const { return mValidRegion; } virtual ThebesLayer* AsThebesLayer() { return this; } diff --git a/gfx/layers/TiledLayerBuffer.h b/gfx/layers/TiledLayerBuffer.h index 78b5c315f233..70f9f3c559e5 100644 --- a/gfx/layers/TiledLayerBuffer.h +++ b/gfx/layers/TiledLayerBuffer.h @@ -191,6 +191,12 @@ public: virtual void PaintedTiledLayerBuffer(const BasicTiledLayerBuffer* aTiledBuffer) = 0; virtual void MemoryPressure() = 0; + + /** + * If some part of the buffer is being rendered at a lower precision, this + * returns that region. If it is not, an empty region will be returned. + */ + virtual const nsIntRegion& GetValidLowPrecisionRegion() const = 0; }; // Normal integer division truncates towards zero, diff --git a/gfx/layers/opengl/LayerManagerOGL.cpp b/gfx/layers/opengl/LayerManagerOGL.cpp index 6914df82ee3e..767ff621fb7a 100644 --- a/gfx/layers/opengl/LayerManagerOGL.cpp +++ b/gfx/layers/opengl/LayerManagerOGL.cpp @@ -1684,8 +1684,21 @@ LayerManagerOGL::ComputeRenderIntegrityInternal(Layer* aLayer, SubtractTransformedRegion(aScreenRegion, incompleteRegion, transformToScreen); // See if there's any incomplete low-precision rendering - incompleteRegion.Sub(incompleteRegion, thebesLayer->GetValidLowPrecisionRegion()); - if (!incompleteRegion.IsEmpty()) { + TiledLayerComposer* composer = nullptr; + ShadowLayer* shadow = aLayer->AsShadowLayer(); + if (shadow) { + composer = shadow->AsTiledLayerComposer(); + if (composer) { + incompleteRegion.Sub(incompleteRegion, composer->GetValidLowPrecisionRegion()); + if (!incompleteRegion.IsEmpty()) { + SubtractTransformedRegion(aLowPrecisionScreenRegion, incompleteRegion, transformToScreen); + } + } + } + + // If we can't get a valid low precision region, assume it's the same as + // the high precision region. + if (!composer) { SubtractTransformedRegion(aLowPrecisionScreenRegion, incompleteRegion, transformToScreen); } } @@ -1748,7 +1761,6 @@ LayerManagerOGL::ComputeRenderIntegrity() #ifdef MOZ_ANDROID_OMTC // Use the transform on the primary scrollable layer and its FrameMetrics // to find out how much of the viewport the current displayport covers - bool hasLowPrecision = true; Layer* primaryScrollable = GetPrimaryScrollableLayer(); if (primaryScrollable) { // This is derived from the code in @@ -1768,17 +1780,39 @@ LayerManagerOGL::ComputeRenderIntegrity() GetDisplayportCoverage(metrics.mCriticalDisplayPort, transform, screenRect); } + // Clip the screen rect to the document bounds + gfxRect documentBounds = + transform.TransformBounds(gfxRect(metrics.mScrollableRect.x - metrics.mScrollOffset.x, + metrics.mScrollableRect.y - metrics.mScrollOffset.y, + metrics.mScrollableRect.width, + metrics.mScrollableRect.height)); + documentBounds.RoundOut(); + screenRect = screenRect.Intersect(nsIntRect(documentBounds.x, documentBounds.y, + documentBounds.width, documentBounds.height)); + + // If the screen rect is empty, the user has scrolled entirely into + // over-scroll and so we can be considered to have full integrity. + if (screenRect.IsEmpty()) { + return 1.0f; + } + // Work out how much of the display-port covers the screen + bool hasLowPrecision = false; if (!metrics.mDisplayPort.IsEmpty()) { if (hasLowPrecision) { lowPrecisionMultiplier = GetDisplayportCoverage(metrics.mDisplayPort, transform, screenRect); } else { - highPrecisionMultiplier = + lowPrecisionMultiplier = highPrecisionMultiplier = GetDisplayportCoverage(metrics.mDisplayPort, transform, screenRect); } } } + + // If none of the screen is covered, we have zero integrity. + if (highPrecisionMultiplier <= 0.0f && lowPrecisionMultiplier <= 0.0f) { + return 0.0f; + } #endif // MOZ_ANDROID_OMTC nsIntRegion screenRegion(screenRect); @@ -1798,7 +1832,7 @@ LayerManagerOGL::ComputeRenderIntegrity() } return ((highPrecisionIntegrity * highPrecisionMultiplier) + - (lowPrecisionIntegrity * lowPrecisionMultiplier)) / 2.f; + (lowPrecisionIntegrity * lowPrecisionMultiplier)) / 2; } return 1.f; diff --git a/gfx/layers/opengl/TiledThebesLayerOGL.h b/gfx/layers/opengl/TiledThebesLayerOGL.h index 21c4a053f805..3faf71db6027 100644 --- a/gfx/layers/opengl/TiledThebesLayerOGL.h +++ b/gfx/layers/opengl/TiledThebesLayerOGL.h @@ -113,9 +113,6 @@ public: TiledThebesLayerOGL(LayerManagerOGL *aManager); virtual ~TiledThebesLayerOGL(); - // Layer implementation - const nsIntRegion& GetValidLowPrecisionRegion() const { return mLowPrecisionVideoMemoryTiledBuffer.GetValidRegion(); } - // LayerOGL impl void Destroy() {} Layer* GetLayer() { return this; } @@ -135,6 +132,7 @@ public: void PaintedTiledLayerBuffer(const BasicTiledLayerBuffer* mTiledBuffer); void ProcessUploadQueue(); void ProcessLowPrecisionUploadQueue(); + const nsIntRegion& GetValidLowPrecisionRegion() const { return mLowPrecisionVideoMemoryTiledBuffer.GetValidRegion(); } void MemoryPressure(); diff --git a/mobile/android/base/gfx/PanningPerfAPI.java b/mobile/android/base/gfx/PanningPerfAPI.java index 89d0968fc224..d9ec5409ebfc 100644 --- a/mobile/android/base/gfx/PanningPerfAPI.java +++ b/mobile/android/base/gfx/PanningPerfAPI.java @@ -97,9 +97,9 @@ public class PanningPerfAPI { long lastTime = 0; float totalTime = mFrameTimes.get(mFrameTimes.size() - 1); for (int i = 0; i < mCheckerboardAmounts.size(); i++) { - long elapsedTime = mFrameTimes.get(i) - lastTime; - mCheckerboardAmounts.set(i, mCheckerboardAmounts.get(i) * elapsedTime / totalTime); - lastTime = mFrameTimes.get(i); + long elapsedTime = mFrameTimes.get(i) - lastTime; + mCheckerboardAmounts.set(i, mCheckerboardAmounts.get(i) * elapsedTime / totalTime); + lastTime = mFrameTimes.get(i); } return mCheckerboardAmounts;