Bug 743800 - Ensure all metrics used during one frame of composition are consistent. r=jrmuizel a=blocking-fennec
authorKartikaya Gupta <kgupta@mozilla.com>
Wed, 18 Apr 2012 01:34:05 -0400
changeset 91887 17d247638c4b277a94d64ffc00cd8659538deb4d
parent 91886 680493f701d93e4a35dd55d6333ab92d02ae23b0
child 91888 c209b10216fb5add1f06bd37ceca5770cda30cd1
push id8449
push userkgupta@mozilla.com
push dateWed, 18 Apr 2012 05:35:26 +0000
treeherdermozilla-inbound@17d247638c4b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjrmuizel, blocking-fennec
bugs743800
milestone14.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 743800 - Ensure all metrics used during one frame of composition are consistent. r=jrmuizel a=blocking-fennec
mobile/android/base/gfx/GeckoLayerClient.java
mobile/android/base/gfx/LayerRenderer.java
--- a/mobile/android/base/gfx/GeckoLayerClient.java
+++ b/mobile/android/base/gfx/GeckoLayerClient.java
@@ -400,20 +400,17 @@ public class GeckoLayerClient implements
     public LayerRenderer.Frame createFrame() {
         // Create the shaders and textures if necessary.
         if (!mLayerRendererInitialized) {
             mLayerRenderer.checkMonitoringEnabled();
             mLayerRenderer.createDefaultProgram();
             mLayerRendererInitialized = true;
         }
 
-        // Build the contexts and create the frame.
-        Layer.RenderContext pageContext = mLayerRenderer.createPageContext(mFrameMetrics);
-        Layer.RenderContext screenContext = mLayerRenderer.createScreenContext();
-        return mLayerRenderer.createFrame(pageContext, screenContext);
+        return mLayerRenderer.createFrame(mFrameMetrics);
     }
 
     /** This function is invoked by Gecko via JNI; be careful when modifying signature. */
     public void activateProgram() {
         mLayerRenderer.activateDefaultProgram();
     }
 
     /** This function is invoked by Gecko via JNI; be careful when modifying signature. */
--- a/mobile/android/base/gfx/LayerRenderer.java
+++ b/mobile/android/base/gfx/LayerRenderer.java
@@ -263,19 +263,17 @@ public class LayerRenderer implements GL
     }
 
     /**
      * Called whenever a new frame is about to be drawn.
      */
     public void onDrawFrame(GL10 gl) {
 	/* This code is causing crashes when the surface changes. (bug 738188)
 	 * I'm not sure if it actually works, so I'm disabling it now to avoid the crash.
-        RenderContext pageContext = createPageContext(mView.getController().getViewportMetrics());
-        RenderContext screenContext = createScreenContext();
-        Frame frame = createFrame(pageContext, screenContext);
+        Frame frame = createFrame(mView.getController().getViewportMetrics());
         synchronized (mView.getController()) {
             frame.beginDrawing();
             frame.drawBackground();
             frame.drawRootLayer();
             frame.drawForeground();
             frame.endDrawing();
         }
 	*/
@@ -297,61 +295,34 @@ public class LayerRenderer implements GL
                 pixelBuffer.wait();
             } catch (InterruptedException ie) {
             }
             mPixelBuffer = null;
         }
         return pixelBuffer;
     }
 
-    public RenderContext createScreenContext() {
-        LayerController layerController = mView.getController();
-        IntSize viewportSize = new IntSize(layerController.getViewportSize());
-        RectF viewport = new RectF(0.0f, 0.0f, viewportSize.width, viewportSize.height);
-        FloatSize pageSize = new FloatSize(layerController.getPageSize());
+    private RenderContext createScreenContext(ImmutableViewportMetrics metrics) {
+        RectF viewport = new RectF(0.0f, 0.0f, metrics.getWidth(), metrics.getHeight());
+        FloatSize pageSize = new FloatSize(metrics.getPageSize());
         return createContext(viewport, pageSize, 1.0f);
     }
 
-    public RenderContext createPageContext(ImmutableViewportMetrics metrics) {
+    private RenderContext createPageContext(ImmutableViewportMetrics metrics) {
         Rect viewport = RectUtils.round(metrics.getViewport());
         FloatSize pageSize = metrics.getPageSize();
         float zoomFactor = metrics.zoomFactor;
         return createContext(new RectF(viewport), pageSize, zoomFactor);
     }
 
     private RenderContext createContext(RectF viewport, FloatSize pageSize, float zoomFactor) {
         return new RenderContext(viewport, pageSize, zoomFactor, mPositionHandle, mTextureHandle,
                                  mCoordBuffer);
     }
 
-    private Rect getPageRect() {
-        LayerController controller = mView.getController();
-
-        Point origin = PointUtils.round(controller.getOrigin());
-        IntSize pageSize = new IntSize(controller.getPageSize());
-
-        origin.negate();
-
-        return new Rect(origin.x, origin.y,
-                        origin.x + pageSize.width, origin.y + pageSize.height);
-    }
-
-    private Rect transformToScissorRect(Rect rect) {
-        LayerController controller = mView.getController();
-        IntSize screenSize = new IntSize(controller.getViewportSize());
-
-        int left = Math.max(0, rect.left);
-        int top = Math.max(0, rect.top);
-        int right = Math.min(screenSize.width, rect.right);
-        int bottom = Math.min(screenSize.height, rect.bottom);
-
-        return new Rect(left, screenSize.height - bottom, right,
-                        (screenSize.height - bottom) + (bottom - top));
-    }
-
     public void onSurfaceChanged(GL10 gl, final int width, final int height) {
         GLES20.glViewport(0, 0, width, height);
 
         if (mFrameRateLayer != null) {
             moveFrameRateLayer(width, height);
         }
 
         // updating the state in the view/controller/client should be
@@ -440,18 +411,18 @@ public class LayerRenderer implements GL
      */
     public static int loadShader(int type, String shaderCode) {
         int shader = GLES20.glCreateShader(type);
         GLES20.glShaderSource(shader, shaderCode);
         GLES20.glCompileShader(shader);
         return shader;
     }
 
-    public Frame createFrame(RenderContext pageContext, RenderContext screenContext) {
-        return new Frame(pageContext, screenContext);
+    public Frame createFrame(ImmutableViewportMetrics metrics) {
+        return new Frame(metrics);
     }
 
     class FadeRunnable implements Runnable {
         private boolean mStarted;
         private long mRunAt;
 
         void scheduleStartFade(long delay) {
             mRunAt = SystemClock.elapsedRealtime() + delay;
@@ -483,46 +454,70 @@ public class LayerRenderer implements GL
                 mView.requestRender();
             }
         }
     }
 
     public class Frame {
         // The timestamp recording the start of this frame.
         private long mFrameStartTime;
+        // A fixed snapshot of the viewport metrics that this frame is using to render content.
+        private ImmutableViewportMetrics mFrameMetrics;
         // A rendering context for page-positioned layers, and one for screen-positioned layers.
         private RenderContext mPageContext, mScreenContext;
         // Whether a layer was updated.
         private boolean mUpdated;
         private final Rect mPageRect;
 
-        public Frame(RenderContext pageContext, RenderContext screenContext) {
-            mPageContext = pageContext;
-            mScreenContext = screenContext;
+        public Frame(ImmutableViewportMetrics metrics) {
+            mFrameMetrics = metrics;
+            mPageContext = createPageContext(metrics);
+            mScreenContext = createScreenContext(metrics);
             mPageRect = getPageRect();
         }
 
         private void setScissorRect() {
             Rect scissorRect = transformToScissorRect(mPageRect);
             GLES20.glEnable(GLES20.GL_SCISSOR_TEST);
             GLES20.glScissor(scissorRect.left, scissorRect.top,
                              scissorRect.width(), scissorRect.height());
         }
 
+        private Rect transformToScissorRect(Rect rect) {
+            IntSize screenSize = new IntSize(mFrameMetrics.getSize());
+
+            int left = Math.max(0, rect.left);
+            int top = Math.max(0, rect.top);
+            int right = Math.min(screenSize.width, rect.right);
+            int bottom = Math.min(screenSize.height, rect.bottom);
+
+            return new Rect(left, screenSize.height - bottom, right,
+                            (screenSize.height - bottom) + (bottom - top));
+        }
+
+        private Rect getPageRect() {
+            Point origin = PointUtils.round(mFrameMetrics.getOrigin());
+            IntSize pageSize = new IntSize(mFrameMetrics.getPageSize());
+
+            origin.negate();
+
+            return new Rect(origin.x, origin.y,
+                            origin.x + pageSize.width, origin.y + pageSize.height);
+        }
+
         /** This function is invoked via JNI; be careful when modifying signature. */
         public void beginDrawing() {
             mFrameStartTime = SystemClock.uptimeMillis();
 
             TextureReaper.get().reap();
             TextureGenerator.get().fill();
 
             mUpdated = true;
 
-            LayerController controller = mView.getController();
-            Layer rootLayer = controller.getRoot();
+            Layer rootLayer = mView.getController().getRoot();
 
             if (!mPageContext.fuzzyEquals(mLastPageContext)) {
                 // the viewport or page changed, so show the scrollbars again
                 // as per UX decision
                 mVertScrollLayer.unfade();
                 mHorizScrollLayer.unfade();
                 mFadeRunnable.scheduleStartFade(ScrollbarLayer.FADE_DELAY);
             } else if (mFadeRunnable.timeToFade()) {
@@ -585,42 +580,39 @@ public class LayerRenderer implements GL
                 return;
             }
 
             rootLayer.draw(mPageContext);
         }
 
         /** This function is invoked via JNI; be careful when modifying signature. */
         public void drawForeground() {
-            LayerController controller = mView.getController();
-
             /* Draw any extra layers that were added (likely plugins) */
             if (mExtraLayers.size() > 0) {
                 // This is a hack. SurfaceTextureLayer draws with its own program, so disable ours here
                 // and re-enable when done. If we end up adding other types of Layer here we'll need
                 // to do something different.
                 deactivateDefaultProgram();
                 
                 for (Layer layer : mExtraLayers)
                     layer.draw(mPageContext);
 
                 activateDefaultProgram();
             }
 
             /* Draw the vertical scrollbar. */
-            IntSize screenSize = new IntSize(controller.getViewportSize());
-            if (mPageRect.height() > screenSize.height)
+            if (mPageRect.height() > mFrameMetrics.getHeight())
                 mVertScrollLayer.draw(mPageContext);
 
             /* Draw the horizontal scrollbar. */
-            if (mPageRect.width() > screenSize.width)
+            if (mPageRect.width() > mFrameMetrics.getWidth())
                 mHorizScrollLayer.draw(mPageContext);
 
             /* Measure how much of the screen is checkerboarding */
-            Layer rootLayer = controller.getRoot();
+            Layer rootLayer = mView.getController().getRoot();
             if ((rootLayer != null) &&
                 (mProfileRender || PanningPerfAPI.isRecordingCheckerboard())) {
                 // Find out how much of the viewport area is valid
                 Rect viewport = RectUtils.round(mPageContext.viewport);
                 Region validRegion = rootLayer.getValidRegion(mPageContext);
                 validRegion.op(viewport, Region.Op.INTERSECT);
 
                 float checkerboard = 0.0f;