Bug 1425262 - 1. Implement GeckoDisplay as a class managed by GeckoSession; r?rbarker draft
authorJim Chen <nchen@mozilla.com>
Tue, 19 Dec 2017 17:17:37 -0500
changeset 713231 fd9857c5a75eaeffbddd921b6acbd67dcf55dd39
parent 713072 c9ce08c45635d29120d5360fb9306125af7bc1ca
child 713232 52024cef10ad8f20efdbbe464a421781bd712aaa
push id93589
push userbmo:nchen@mozilla.com
push dateTue, 19 Dec 2017 22:17:52 +0000
reviewersrbarker
bugs1425262
milestone59.0a1
Bug 1425262 - 1. Implement GeckoDisplay as a class managed by GeckoSession; r?rbarker Implement GeckoDisplay as a class managed by GeckoSession and used by GeckoSession clients. Also add `acquireDisplay` and `releaseDisplay` methods to manage the GeckoDisplay instance. MozReview-Commit-ID: 6yTdXmx4yIO
mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/GeckoDisplay.java
mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/LayerSession.java
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/GeckoDisplay.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/GeckoDisplay.java
@@ -4,68 +4,55 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 package org.mozilla.gecko.gfx;
 
 import android.view.Surface;
 
 /**
- * Displays implement this interface to provide GeckoSession
- * with a Surface for displaying content.
+ * Applications use a GeckoDisplay instance to provide GeckoSession with a Surface for
+ * displaying content. To ensure drawing only happens on a valid Surface, GeckoSession
+ * will only use the provided Surface after {@link #surfaceChanged(Surface, int, int)} is
+ * called and before {@link #surfaceDestroyed()} returns.
  */
-public interface GeckoDisplay {
-    /**
-     * Displays notify GeckoSession of changes to its Surface through this interface that
-     * GeckoSession implements. To ensure drawing only happens on a valid Surface,
-     * GeckoSession will only use the provided Surface after {@link
-     * #surfaceChanged(Surface, int, int)} is called and before {@link
-     * #surfaceDestroyed()} returns.
-     */
-    interface Listener {
-        /**
-         * Required callback. The display's Surface has been created or changed. Must be
-         * called on the application main thread. GeckoSession may block this call to
-         * ensure the Surface is valid while resuming drawing.
-         *
-         * @param surface The new Surface.
-         * @param width New width of the Surface.
-         * @param height New height of the Surface.
-         */
-        void surfaceChanged(Surface surface, int width, int height);
+public class GeckoDisplay {
+    private final LayerSession mSession;
 
-        /**
-         * Required callback. The display's Surface has been destroyed. Must be called on
-         * the application main thread. GeckoSession may block this call to ensure the
-         * Surface is valid while pausing drawing.
-         */
-        void surfaceDestroyed();
-
-        /**
-         * Optional callback. The display's coordinates on the screen has changed. Must be
-         * called on the application main thread.
-         *
-         * @param left The X coordinate of the display on the screen, in screen pixels.
-         * @param top The Y coordinate of the display on the screen, in screen pixels.
-         */
-        void screenOriginChanged(int left, int top);
+    /* package */ GeckoDisplay(final LayerSession session) {
+        mSession = session;
     }
 
     /**
-     * Get the current listener attached to this display. Must be called on the
-     * application main thread.
+     * Required callback. The display's Surface has been created or changed. Must be
+     * called on the application main thread. GeckoSession may block this call to ensure
+     * the Surface is valid while resuming drawing.
      *
-     * @return Current listener or null if there is no listener.
+     * @param surface The new Surface.
+     * @param width New width of the Surface.
+     * @param height New height of the Surface.
      */
-    Listener getListener();
+    public void surfaceChanged(Surface surface, int width, int height) {
+        mSession.onSurfaceChanged(surface, width, height);
+    }
 
     /**
-     * Set a new listener attached to this display. Must be called on the application main
-     * thread. When attaching a new listener, and there is an existing valid Surface, the
-     * display must call {@link Listener#surfaceChanged(Surface, int, int)} (and other
-     * optional callbacks, if implemented) on the new listener. Similarly, when detaching
-     * a previous listener, and there is an existing valid Surface, the display must call
-     * {@link Listener#surfaceDestroyed()} on the previous listener.
+     * Required callback. The display's Surface has been destroyed. Must be called on the
+     * application main thread. GeckoSession may block this call to ensure the Surface is
+     * valid while pausing drawing.
+     */
+    public void surfaceDestroyed() {
+        mSession.onSurfaceDestroyed();
+    }
+
+    /**
+     * Optional callback. The display's coordinates on the screen has changed. Must be
+     * called on the application main thread. Together with the transformation matrix, the
+     * screen origin determines how a point on the display maps to a point on the screen.
      *
-     * @param listener New listener or null if detaching previous listener.
+     * @param left The X coordinate of the display on the screen, in screen pixels.
+     * @param top The Y coordinate of the display on the screen, in screen pixels.
+     * @see #transformationMatrixChanged(Matrix)
      */
-    void setListener(Listener listener);
+    public void screenOriginChanged(final int left, final int top) {
+        mSession.onScreenOriginChanged(left, top);
+    }
 }
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/LayerSession.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/LayerSession.java
@@ -153,17 +153,17 @@ public class LayerSession {
             // avoid unwanted scroll interactions.
             LayerSession.this.onSelectionCaretDrag(dragging);
         }
     }
 
     protected final Compositor mCompositor = new Compositor();
 
     // All fields are accessed on UI thread only.
-    private GeckoDisplay mDisplay;
+    private final GeckoDisplay mDisplay = new GeckoDisplay(this);
     private NativePanZoomController mNPZC;
     private OverscrollEdgeEffect mOverscroll;
     private DynamicToolbarAnimator mToolbar;
     private CompositorController mController;
 
     private boolean mAttachedCompositor;
     private boolean mCalledCreateCompositor;
     private boolean mCompositorReady;
@@ -588,48 +588,38 @@ public class LayerSession {
             return;
         }
 
         mLeft = left;
         mTop = top;
         onWindowBoundsChanged();
     }
 
-    public void addDisplay(final GeckoDisplay display) {
+    /**
+     * Acquire the GeckoDisplay instance for providing the session with a drawing Surface.
+     * Be sure to call {@link GeckoDisplay#surfaceChanged(Surface, int, int)} on the
+     * acquired display if there is already a valid Surface.
+     *
+     * @return GeckoDisplay instance.
+     * @see #releaseDisplay(GeckoDisplay)
+     */
+    public @NonNull GeckoDisplay acquireDisplay() {
         ThreadUtils.assertOnUiThread();
 
-        if (display.getListener() != null) {
-            throw new IllegalArgumentException("Display already attached");
-        } else if (mDisplay != null) {
-            throw new IllegalArgumentException("Only one display supported");
-        }
-
-        mDisplay = display;
-        display.setListener(new GeckoDisplay.Listener() {
-            @Override
-            public void surfaceChanged(final Surface surface, final int width,
-                                       final int height) {
-                onSurfaceChanged(surface, width, height);
-            }
-
-            @Override
-            public void surfaceDestroyed() {
-                onSurfaceDestroyed();
-            }
-
-            @Override
-            public void screenOriginChanged(final int left, final int top) {
-                onScreenOriginChanged(left, top);
-            }
-        });
+        return mDisplay;
     }
 
-    public void removeDisplay(final GeckoDisplay display) {
+    /**
+     * Release an acquired GeckoDisplay instance. Be sure to call {@link
+     * GeckoDisplay#surfaceDestroyed()} before releasing the display if it still has a
+     * valid Surface.
+     *
+     * @param display Acquired GeckoDisplay instance.
+     * @see #acquireDisplay()
+     */
+    public void releaseDisplay(final @NonNull GeckoDisplay display) {
         ThreadUtils.assertOnUiThread();
 
-        if (mDisplay != display) {
+        if (display != mDisplay) {
             throw new IllegalArgumentException("Display not attached");
         }
-
-        display.setListener(null);
-        mDisplay = null;
     }
 }