Bug 814437 - Address review comments that were missed. r=bgirard
authorChris Lord <chrislord.net@gmail.com>
Fri, 30 Nov 2012 23:11:37 +0000
changeset 114663 1b666ab33a92eb35381d99b6b7303b18062eb816
parent 114662 cd51ab1d33f59cd8a2961291c62a200c25dcf3fe
child 114664 e418cb281a3a72a7f233d93270620c28fa1b6525
push id23926
push userryanvm@gmail.com
push dateSat, 01 Dec 2012 15:27:30 +0000
treeherdermozilla-central@ecdf0e332f17 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbgirard
bugs814437
milestone20.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 814437 - Address review comments that were missed. r=bgirard In my haste, I forgot to address review comments before pushing. This corrects indentation in PanningPerf.java, moves GetValidLowPrecisionRegion from Layer to TiledLayerComposer and corrects checkerboard measurement when there isn't a low precision buffer and when the display ports don't cover the screen.
gfx/layers/Layers.h
gfx/layers/TiledLayerBuffer.h
gfx/layers/opengl/LayerManagerOGL.cpp
gfx/layers/opengl/TiledThebesLayerOGL.h
mobile/android/base/gfx/PanningPerfAPI.java
--- a/gfx/layers/Layers.h
+++ b/gfx/layers/Layers.h
@@ -1143,17 +1143,16 @@ public:
    * performance.
    */
   void SetAllowResidualTranslation(bool aAllow) { mAllowResidualTranslation = aAllow; }
 
   /**
    * Can be used anytime
    */
   const nsIntRegion& GetValidRegion() const { return mValidRegion; }
-  virtual const nsIntRegion& GetValidLowPrecisionRegion() const { return mValidRegion; }
 
   virtual ThebesLayer* AsThebesLayer() { return this; }
 
   MOZ_LAYER_DECL_NAME("ThebesLayer", TYPE_THEBES)
 
   virtual void ComputeEffectiveTransforms(const gfx3DMatrix& aTransformToSurface)
   {
     // The default implementation just snaps 0,0 to pixels.
--- a/gfx/layers/TiledLayerBuffer.h
+++ b/gfx/layers/TiledLayerBuffer.h
@@ -186,16 +186,22 @@ public:
    * Update the current retained layer with the updated layer data.
    * The BasicTiledLayerBuffer is expected to be in the ReadLock state
    * prior to this being called. aTiledBuffer is copy constructed and
    * is retained until it has been uploaded/copyed and unlocked.
    */
   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,
 // we instead want to floor to hangle negative numbers.
 static inline int floor_div(int a, int b)
 {
   int rem = a % b;
   int div = a/b;
--- a/gfx/layers/opengl/LayerManagerOGL.cpp
+++ b/gfx/layers/opengl/LayerManagerOGL.cpp
@@ -1679,18 +1679,31 @@ LayerManagerOGL::ComputeRenderIntegrityI
   if (!incompleteRegion.IsEmpty()) {
     // Calculate the transform to get between screen and layer space
     gfx3DMatrix transformToScreen = aLayer->GetEffectiveTransform();
     transformToScreen.PreMultiply(aTransform);
 
     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);
     }
   }
 }
 
 static int
 GetRegionArea(const nsIntRegion& aRegion)
 {
@@ -1743,47 +1756,68 @@ LayerManagerOGL::ComputeRenderIntegrity(
                        rootMetrics.mCompositionBounds.width,
                        rootMetrics.mCompositionBounds.height);
 
   float lowPrecisionMultiplier = 1.0f;
   float highPrecisionMultiplier = 1.0f;
 #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
     // gfx/layers/ipc/CompositorParent.cpp::TransformShadowTree.
     const gfx3DMatrix& rootTransform = root->GetTransform();
     float devPixelRatioX = 1 / rootTransform.GetXScale();
     float devPixelRatioY = 1 / rootTransform.GetYScale();
 
     gfx3DMatrix transform = primaryScrollable->GetEffectiveTransform();
     transform.ScalePost(devPixelRatioX, devPixelRatioY, 1);
     const FrameMetrics& metrics = primaryScrollable->AsContainerLayer()->GetFrameMetrics();
 
+    // 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 critical display-port covers the screen
+    bool hasLowPrecision = false;
     if (!metrics.mCriticalDisplayPort.IsEmpty()) {
       hasLowPrecision = true;
       highPrecisionMultiplier =
         GetDisplayportCoverage(metrics.mCriticalDisplayPort, transform, screenRect);
     }
 
     // Work out how much of the display-port covers the screen
     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);
   nsIntRegion lowPrecisionScreenRegion(screenRect);
   gfx3DMatrix transform;
   ComputeRenderIntegrityInternal(root, screenRegion,
                                  lowPrecisionScreenRegion, transform);
 
@@ -1793,16 +1827,16 @@ LayerManagerOGL::ComputeRenderIntegrity(
     float screenArea = screenRect.width * screenRect.height;
     float highPrecisionIntegrity = GetRegionArea(screenRegion) / screenArea;
     float lowPrecisionIntegrity = 1.f;
     if (!lowPrecisionScreenRegion.IsEqual(screenRect)) {
       lowPrecisionIntegrity = GetRegionArea(lowPrecisionScreenRegion) / screenArea;
     }
 
     return ((highPrecisionIntegrity * highPrecisionMultiplier) +
-            (lowPrecisionIntegrity * lowPrecisionMultiplier)) / 2.f;
+            (lowPrecisionIntegrity * lowPrecisionMultiplier)) / 2;
   }
 
   return 1.f;
 }
 
 } /* layers */
 } /* mozilla */
--- a/gfx/layers/opengl/TiledThebesLayerOGL.h
+++ b/gfx/layers/opengl/TiledThebesLayerOGL.h
@@ -108,19 +108,16 @@ private:
 class TiledThebesLayerOGL : public ShadowThebesLayer,
                             public LayerOGL,
                             public TiledLayerComposer
 {
 public:
   TiledThebesLayerOGL(LayerManagerOGL *aManager);
   virtual ~TiledThebesLayerOGL();
 
-  // Layer implementation
-  const nsIntRegion& GetValidLowPrecisionRegion() const { return mLowPrecisionVideoMemoryTiledBuffer.GetValidRegion(); }
-
   // LayerOGL impl
   void Destroy() {}
   Layer* GetLayer() { return this; }
   virtual void RenderLayer(int aPreviousFrameBuffer,
                            const nsIntPoint& aOffset);
   virtual void CleanupResources() { }
 
   // Shadow
@@ -130,16 +127,17 @@ public:
        OptionalThebesBuffer* aNewBack, nsIntRegion* aNewBackValidRegion,
        OptionalThebesBuffer* aReadOnlyFront, nsIntRegion* aFrontUpdatedRegion)
   {
     NS_ABORT_IF_FALSE(false, "Not supported");
   }
   void PaintedTiledLayerBuffer(const BasicTiledLayerBuffer* mTiledBuffer);
   void ProcessUploadQueue();
   void ProcessLowPrecisionUploadQueue();
+  const nsIntRegion& GetValidLowPrecisionRegion() const { return mLowPrecisionVideoMemoryTiledBuffer.GetValidRegion(); }
 
   void MemoryPressure();
 
   // Renders a single given tile.
   void RenderTile(const TiledTexture& aTile,
                   const gfx3DMatrix& aTransform,
                   const nsIntPoint& aOffset,
                   const nsIntRegion& aScreenRegion,
--- a/mobile/android/base/gfx/PanningPerfAPI.java
+++ b/mobile/android/base/gfx/PanningPerfAPI.java
@@ -92,19 +92,19 @@ public class PanningPerfAPI {
         mRecordingCheckerboard = false;
 
         // The score will be the sum of all the values in mCheckerboardAmounts,
         // so weight the checkerboard values by time so that frame-rate and
         // run-length don't affect score.
         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;
     }
 
     public static void recordCheckerboard(float amount) {
         // this will be called often, so try to make it as quick as possible
         if (mRecordingCheckerboard) {