summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomaž Vajngerl <tomaz.vajngerl@collabora.com>2014-11-27 22:47:42 +0100
committerTomaž Vajngerl <tomaz.vajngerl@collabora.com>2014-12-04 23:04:28 +0100
commit74eae6786334cdf3a456b52b10fd285e2a589813 (patch)
tree3e072164d6a462bf5ad631925426038e9707d0b0
parentdaa20c9a7f602828927a5f8833bdaf54185f160e (diff)
android: Fold LayerController into GeckoLayerClient
Change-Id: I6a6e702e243b389f1c487b6b5390f28a4292cc74
-rw-r--r--android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java17
-rw-r--r--android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java8
-rw-r--r--android/experimental/LOAndroid3/src/java/org/libreoffice/LibreOfficeMainActivity.java17
-rw-r--r--android/experimental/LOAndroid3/src/java/org/libreoffice/MockTileProvider.java14
-rw-r--r--android/experimental/LOAndroid3/src/java/org/libreoffice/TileProviderFactory.java8
-rw-r--r--android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/GeckoLayerClient.java323
-rw-r--r--android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/LayerController.java265
-rw-r--r--android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/LayerRenderer.java18
-rw-r--r--android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/LayerView.java14
-rw-r--r--android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/TouchEventHandler.java10
10 files changed, 335 insertions, 359 deletions
diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java
index 4c5509a3ac4b..e9c2877e2445 100644
--- a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java
+++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java
@@ -6,8 +6,7 @@ import android.util.DisplayMetrics;
import android.util.Log;
import org.mozilla.gecko.gfx.GeckoLayerClient;
-import org.mozilla.gecko.gfx.ImmutableViewportMetrics;
-import org.mozilla.gecko.gfx.LayerController;
+import org.mozilla.gecko.gfx.ImmutableViewportMetrics;;
import java.util.concurrent.LinkedBlockingQueue;
@@ -19,7 +18,6 @@ public class LOKitThread extends Thread {
private TileProvider mTileProvider;
private ImmutableViewportMetrics mViewportMetrics;
private GeckoLayerClient mLayerClient;
- private LayerController mController;
public LOKitThread() {
TileProviderFactory.initialize();
@@ -47,7 +45,7 @@ public class LOKitThread extends Thread {
/** Handle the geometry change + draw. */
private void redraw() {
- if (mController == null || mTileProvider == null) {
+ if (mLayerClient == null || mTileProvider == null) {
// called too early...
return;
}
@@ -55,16 +53,16 @@ public class LOKitThread extends Thread {
draw();
RectF rect = new RectF(0, 0, mTileProvider.getPageWidth(), mTileProvider.getPageHeight());
- mController.setPageRect(rect, rect);
- mController.setViewportMetrics(mController.getViewportMetrics());
- mController.setForceRedraw();
+ mLayerClient.setPageRect(rect, rect);
+ mLayerClient.setViewportMetrics(mLayerClient.getViewportMetrics());
+ mLayerClient.setForceRedraw();
}
/** Invalidate everything + handle the geometry change + draw. */
private void refresh() {
Bitmap bitmap = mTileProvider.thumbnail(1000);
if (bitmap != null) {
- mApplication.getLayerController().getView().changeCheckerboardBitmap(bitmap, mTileProvider.getPageWidth(), mTileProvider.getPageHeight());
+ mApplication.getLayerClient().getView().changeCheckerboardBitmap(bitmap, mTileProvider.getPageWidth(), mTileProvider.getPageHeight());
}
mLayerClient.clearAndResetlayers();
@@ -83,10 +81,9 @@ public class LOKitThread extends Thread {
mApplication = LibreOfficeMainActivity.mAppContext;
}
- mController = mApplication.getLayerController();
mLayerClient = mApplication.getLayerClient();
- mTileProvider = TileProviderFactory.create(mController, filename);
+ mTileProvider = TileProviderFactory.create(mLayerClient, filename);
boolean isReady = mTileProvider.isReady();
if (isReady) {
mLayerClient.setTileProvider(mTileProvider);
diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java
index 0d404414c546..ec6d1d1237c3 100644
--- a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java
+++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java
@@ -8,8 +8,8 @@ import org.libreoffice.kit.LibreOfficeKit;
import org.libreoffice.kit.Office;
import org.mozilla.gecko.gfx.BufferedCairoImage;
import org.mozilla.gecko.gfx.CairoImage;
+import org.mozilla.gecko.gfx.GeckoLayerClient;
import org.mozilla.gecko.gfx.IntSize;
-import org.mozilla.gecko.gfx.LayerController;
import java.nio.ByteBuffer;
@@ -18,7 +18,7 @@ public class LOKitTileProvider implements TileProvider {
private static int TILE_SIZE = 256;
private Office mOffice;
private Document mDocument;
- private final LayerController mLayerController;
+ private final GeckoLayerClient mLayerClient;
private final float mTileWidth;
private final float mTileHeight;
private final String mInputFile;
@@ -30,8 +30,8 @@ public class LOKitTileProvider implements TileProvider {
private long objectCreationTime = System.currentTimeMillis();
- public LOKitTileProvider(LayerController layerController, String input) {
- mLayerController = layerController;
+ public LOKitTileProvider(GeckoLayerClient layerClient, String input) {
+ mLayerClient = layerClient;
mDPI = (float) LOKitShell.getDpi();
mTileWidth = pixelToTwip(TILE_SIZE, mDPI);
mTileHeight = pixelToTwip(TILE_SIZE, mDPI);
diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/LibreOfficeMainActivity.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/LibreOfficeMainActivity.java
index 6ca7b4dcf778..991a1533a674 100644
--- a/android/experimental/LOAndroid3/src/java/org/libreoffice/LibreOfficeMainActivity.java
+++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/LibreOfficeMainActivity.java
@@ -3,8 +3,6 @@ package org.libreoffice;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
-import android.content.Intent;
-import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.widget.DrawerLayout;
@@ -15,14 +13,12 @@ import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
-import android.widget.Button;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import org.mozilla.gecko.ZoomConstraints;
import org.mozilla.gecko.gfx.GeckoLayerClient;
-import org.mozilla.gecko.gfx.LayerController;
import org.mozilla.gecko.gfx.LayerView;
import java.util.ArrayList;
@@ -35,7 +31,6 @@ public class LibreOfficeMainActivity extends Activity {
public static LibreOfficeMainActivity mAppContext;
- private static LayerController mLayerController;
private static GeckoLayerClient mLayerClient;
private static LOKitThread sLOKitThread;
@@ -52,10 +47,6 @@ public class LibreOfficeMainActivity extends Activity {
return mLayerClient;
}
- public static LayerController getLayerController() {
- return mLayerController;
- }
-
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
@@ -130,12 +121,11 @@ public class LibreOfficeMainActivity extends Activity {
sLOKitThread.clearQueue();
}
- mLayerController = new LayerController(this);
- mLayerController.setZoomConstraints(new ZoomConstraints(true));
mLayerClient = new GeckoLayerClient(this);
+ mLayerClient.setZoomConstraints(new ZoomConstraints(true));
LayerView layerView = (LayerView) findViewById(R.id.layer_view);
- mLayerController.setView(layerView);
- mLayerController.setLayerClient(mLayerClient);
+ mLayerClient.setView(layerView);
+ mLayerClient.notifyReady();
}
@Override
@@ -167,6 +157,7 @@ public class LibreOfficeMainActivity extends Activity {
@Override
protected void onDestroy() {
Log.i(LOGTAG, "onDestroy..");
+ mLayerClient.destroy();
super.onDestroy();
}
diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/MockTileProvider.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/MockTileProvider.java
index eba732fea95b..8fd51b8ca8c6 100644
--- a/android/experimental/LOAndroid3/src/java/org/libreoffice/MockTileProvider.java
+++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/MockTileProvider.java
@@ -4,17 +4,17 @@ import android.graphics.Bitmap;
import org.mozilla.gecko.gfx.BufferedCairoImage;
import org.mozilla.gecko.gfx.CairoImage;
+import org.mozilla.gecko.gfx.GeckoLayerClient;
import org.mozilla.gecko.gfx.IntSize;
-import org.mozilla.gecko.gfx.LayerController;
public class MockTileProvider implements TileProvider {
private static final int TILE_SIZE = 256;
- private final LayerController layerController;
+ private final GeckoLayerClient mLayerClient;
private final String inputFile;
- public MockTileProvider(LayerController layerController, String inputFile) {
- this.layerController = layerController;
- this.inputFile = inputFile;
+ public MockTileProvider(GeckoLayerClient layerClient, String input) {
+ mLayerClient = layerClient;
+ this.inputFile = input;
for (int i = 0; i < 5; i++) {
String partName = "Part " + i;
@@ -52,7 +52,7 @@ public class MockTileProvider implements TileProvider {
tileNumber += 1; // 0 to 1 based numbering
String imageName = "d" + tileNumber;
- Bitmap bitmap = layerController.getView().getDrawable(imageName);
+ Bitmap bitmap = mLayerClient.getView().getDrawable(imageName);
CairoImage image = new BufferedCairoImage(bitmap);
@@ -61,7 +61,7 @@ public class MockTileProvider implements TileProvider {
@Override
public Bitmap thumbnail(int size) {
- return layerController.getView().getDrawable("dummy_page");
+ return mLayerClient.getView().getDrawable("dummy_page");
}
@Override
diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/TileProviderFactory.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/TileProviderFactory.java
index 3bfe0b7febf5..b79e56e9414e 100644
--- a/android/experimental/LOAndroid3/src/java/org/libreoffice/TileProviderFactory.java
+++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/TileProviderFactory.java
@@ -2,7 +2,7 @@ package org.libreoffice;
import org.libreoffice.kit.LibreOfficeKit;
-import org.mozilla.gecko.gfx.LayerController;
+import org.mozilla.gecko.gfx.GeckoLayerClient;
public class TileProviderFactory {
private static TileProviderID currentTileProvider = TileProviderID.LOKIT;
@@ -17,11 +17,11 @@ public class TileProviderFactory {
}
}
- public static TileProvider create(LayerController layerController, String filename) {
+ public static TileProvider create(GeckoLayerClient layerClient, String filename) {
if (currentTileProvider == TileProviderID.LOKIT) {
- return new LOKitTileProvider(layerController, filename);
+ return new LOKitTileProvider(layerClient, filename);
} else {
- return new MockTileProvider(layerController, filename);
+ return new MockTileProvider(layerClient, filename);
}
}
diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/GeckoLayerClient.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/GeckoLayerClient.java
index b5bb73d1985d..508fb9f12a9c 100644
--- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/GeckoLayerClient.java
+++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/GeckoLayerClient.java
@@ -39,62 +39,110 @@
package org.mozilla.gecko.gfx;
import android.content.Context;
+import android.graphics.Color;
+import android.graphics.PointF;
import android.graphics.RectF;
import android.util.DisplayMetrics;
import android.util.Log;
+import android.view.GestureDetector;
import org.libreoffice.LOEvent;
import org.libreoffice.LOEventFactory;
import org.libreoffice.LOKitShell;
-import org.libreoffice.LibreOfficeMainActivity;
import org.libreoffice.TileProvider;
+import org.mozilla.gecko.ZoomConstraints;
+import org.mozilla.gecko.ui.PanZoomController;
+import org.mozilla.gecko.ui.PanZoomTarget;
+import org.mozilla.gecko.ui.SimpleScaleGestureDetector;
import org.mozilla.gecko.util.FloatUtils;
-public class GeckoLayerClient implements LayerView.Listener {
- private static final String LOGTAG = "GeckoLayerClient";
+public class GeckoLayerClient implements PanZoomTarget, LayerView.Listener {
+ private static final String LOGTAG = GeckoLayerClient.class.getSimpleName();
- private LayerController mLayerController;
+ private LayerRenderer mLayerRenderer;
+ private boolean mLayerRendererInitialized;
+ private Context mContext;
private IntSize mScreenSize;
private IntSize mWindowSize;
private DisplayPortMetrics mDisplayPort;
+
private boolean mRecordDrawTimes;
private DrawTimingQueue mDrawTimingQueue;
private DynamicTileLayer mRootLayer;
- /* The viewport that Gecko is currently displaying. */
+ /* The Gecko viewport as per the UI thread. Must be touched only on the UI thread. */
private ImmutableViewportMetrics mGeckoViewport;
- /* The viewport that Gecko will display when drawing is finished */
+ /*
+ * The viewport metrics being used to draw the current frame. This is only
+ * accessed by the compositor thread, and so needs no synchronisation.
+ */
+ private ImmutableViewportMetrics mFrameMetrics;
+
private ImmutableViewportMetrics mNewGeckoViewport;
- private Context mContext;
+
private boolean mPendingViewportAdjust;
+ /* The current viewport metrics.
+ * This is volatile so that we can read and write to it from different threads.
+ * We avoid synchronization to make getting the viewport metrics from
+ * the compositor as cheap as possible. The viewport is immutable so
+ * we don't need to worry about anyone mutating it while we're reading from it.
+ * Specifically:
+ * 1) reading mViewportMetrics from any thread is fine without synchronization
+ * 2) writing to mViewportMetrics requires synchronizing on the layer controller object
+ * 3) whenver reading multiple fields from mViewportMetrics without synchronization (i.e. in
+ * case 1 above) you should always frist grab a local copy of the reference, and then use
+ * that because mViewportMetrics might get reassigned in between reading the different
+ * fields. */
+ private volatile ImmutableViewportMetrics mViewportMetrics;
+
+ private ZoomConstraints mZoomConstraints;
+
+ private boolean mGeckoIsReady;
+
+ /* The new color for the checkerboard. */
+ private int mCheckerboardColor = Color.WHITE;
+ private boolean mCheckerboardShouldShowChecks;
+
+ private final PanZoomController mPanZoomController;
+
+ private LayerView mView;
+
+ private boolean mForceRedraw;
+
public GeckoLayerClient(Context context) {
mContext = context;
mScreenSize = new IntSize(0, 0);
mWindowSize = new IntSize(0, 0);
mDisplayPort = new DisplayPortMetrics();
- mRecordDrawTimes = true;
+ mRecordDrawTimes = false;
mDrawTimingQueue = new DrawTimingQueue();
- }
- /** Attaches the root layer to the layer controller so that Gecko appears. */
- public void setLayerController(LayerController layerController) {
- LayerView view = layerController.getView();
+ mForceRedraw = true;
+ DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
+ mViewportMetrics = new ImmutableViewportMetrics(displayMetrics);
+ mZoomConstraints = new ZoomConstraints(false);
+ mCheckerboardShouldShowChecks = true;
+
+ mPanZoomController = new PanZoomController(this);
+ }
- mLayerController = layerController;
+ public void setView(LayerView v) {
+ mView = v;
+ mView.connect(this);
+ }
+ public void notifyReady() {
+ mGeckoIsReady = true;
mRootLayer = new DynamicTileLayer();
- view.setListener(this);
- layerController.setRoot(mRootLayer);
-
- if (mGeckoViewport != null) {
- layerController.setViewportMetrics(mGeckoViewport);
- }
+ mLayerRenderer = new LayerRenderer(mView);
+ mView.setListener(this);
+ mView.setLayerRenderer(mLayerRenderer);
sendResizeEventIfNecessary(true);
}
@@ -108,7 +156,7 @@ public class GeckoLayerClient implements LayerView.Listener {
}
public void endDrawing(ImmutableViewportMetrics viewportMetrics) {
- synchronized (mLayerController) {
+ synchronized (this) {
try {
mNewGeckoViewport = viewportMetrics;
updateViewport(true);
@@ -124,7 +172,7 @@ public class GeckoLayerClient implements LayerView.Listener {
// JS-side viewport dimensions override the java-side ones because
// java is the One True Source of this information, and allowing JS
// to override can lead to race conditions where this data gets clobbered.
- FloatSize viewportSize = mLayerController.getViewportSize();
+ FloatSize viewportSize = getViewportSize();
mGeckoViewport = mNewGeckoViewport.setViewportSize(viewportSize.width, viewportSize.height);
RectF position = mGeckoViewport.getViewport();
@@ -134,12 +182,12 @@ public class GeckoLayerClient implements LayerView.Listener {
if (onlyUpdatePageSize) {
// Don't adjust page size when zooming unless zoom levels are
// approximately equal.
- if (FloatUtils.fuzzyEquals(mLayerController.getViewportMetrics().zoomFactor, mGeckoViewport.zoomFactor)) {
- mLayerController.setPageRect(mGeckoViewport.getPageRect(), mGeckoViewport.getCssPageRect());
+ if (FloatUtils.fuzzyEquals(getViewportMetrics().zoomFactor, mGeckoViewport.zoomFactor)) {
+ setPageRect(mGeckoViewport.getPageRect(), mGeckoViewport.getCssPageRect());
}
} else {
- mLayerController.setViewportMetrics(mGeckoViewport);
- mLayerController.abortPanZoomAnimation();
+ setViewportMetrics(mGeckoViewport);
+ abortPanZoomAnimation();
}
}
@@ -171,13 +219,12 @@ public class GeckoLayerClient implements LayerView.Listener {
}
void adjustViewport(DisplayPortMetrics displayPort) {
- ImmutableViewportMetrics metrics = mLayerController.getViewportMetrics();
+ ImmutableViewportMetrics metrics = getViewportMetrics();
ImmutableViewportMetrics clampedMetrics = metrics.clamp();
if (displayPort == null) {
- displayPort = DisplayPortCalculator.calculate(metrics,
- mLayerController.getPanZoomController().getVelocityVector());
+ displayPort = DisplayPortCalculator.calculate(metrics, getPanZoomController().getVelocityVector());
}
mDisplayPort = displayPort;
@@ -190,21 +237,22 @@ public class GeckoLayerClient implements LayerView.Listener {
LOKitShell.sendEvent(LOEventFactory.viewport(clampedMetrics));
}
- /** This function is invoked by Gecko via JNI; be careful when modifying signature.
+ /**
+ * This function is invoked by Gecko via JNI; be careful when modifying signature.
* The compositor invokes this function whenever it determines that the page size
* has changed (based on the information it gets from layout). If setFirstPaintViewport
* is invoked on a frame, then this function will not be. For any given frame, this
* function will be invoked before syncViewportInfo.
*/
public void setPageSize(float zoom, float pageWidth, float pageHeight, float cssPageWidth, float cssPageHeight) {
- synchronized (mLayerController) {
+ synchronized (this) {
// adjust the page dimensions to account for differences in zoom
// between the rendered content (which is what the compositor tells us)
// and our zoom level (which may have diverged).
RectF pageRect = new RectF(0.0f, 0.0f, pageWidth, pageHeight);
RectF cssPageRect = new RectF(0.0f, 0.0f, cssPageWidth, cssPageHeight);
- float ourZoom = mLayerController.getViewportMetrics().zoomFactor;
- mLayerController.setPageRect(RectUtils.scale(pageRect, ourZoom / zoom), cssPageRect);
+ float ourZoom = getViewportMetrics().zoomFactor;
+ setPageRect(RectUtils.scale(pageRect, ourZoom / zoom), cssPageRect);
// Here the page size of the document has changed, but the document being displayed
// is still the same. Therefore, we don't need to send anything to browser.js; any
// changes we need to make to the display port will get sent the next time we call
@@ -214,7 +262,7 @@ public class GeckoLayerClient implements LayerView.Listener {
public void geometryChanged() {
sendResizeEventIfNecessary(false);
- if (mLayerController.getRedrawHint()) {
+ if (getRedrawHint()) {
adjustViewport(null);
}
}
@@ -249,17 +297,224 @@ public class GeckoLayerClient implements LayerView.Listener {
}
public void reevaluateTiles() {
- mRootLayer.reevaluateTiles(mLayerController.getViewportMetrics());
+ mRootLayer.reevaluateTiles(getViewportMetrics());
}
public void clearAndResetlayers() {
mRootLayer.clearAndReset();
}
+ public void destroy() {
+ mPanZoomController.destroy();
+ }
+
+ public void setForceRedraw() {
+ mForceRedraw = true;
+ notifyLayerClientOfGeometryChange();
+ }
+
+ public LayerView getView() {
+ return mView;
+ }
+
+ public Context getContext() {
+ return mContext;
+ }
+
+ public ImmutableViewportMetrics getViewportMetrics() {
+ return mViewportMetrics;
+ }
+
+ /**
+ * Sets the entire viewport metrics at once.
+ * You must hold the monitor while calling this.
+ */
+ public void setViewportMetrics(ImmutableViewportMetrics viewport) {
+ mViewportMetrics = viewport;
+ mView.requestRender();
+ notifyLayerClientOfGeometryChange();
+ }
+
+ public Object getLock() {
+ return this;
+ }
+
+ public FloatSize getViewportSize() {
+ return mViewportMetrics.getSize();
+ }
+
+ /**
+ * The view calls this function to indicate that the viewport changed size. It must hold the
+ * monitor while calling it.
+ * <p/>
+ * TODO: Refactor this to use an interface. Expose that interface only to the view and not
+ * to the layer client. That way, the layer client won't be tempted to call this, which might
+ * result in an infinite loop.
+ */
+ public void setViewportSize(FloatSize size) {
+ mViewportMetrics = mViewportMetrics.setViewportSize(size.width, size.height);
+ viewportSizeChanged();
+ }
+
+ public PanZoomController getPanZoomController() {
+ return mPanZoomController;
+ }
+
+ public GestureDetector.OnGestureListener getGestureListener() {
+ return mPanZoomController;
+ }
+
+ public SimpleScaleGestureDetector.SimpleScaleGestureListener getScaleGestureListener() {
+ return mPanZoomController;
+ }
+
+ public GestureDetector.OnDoubleTapListener getDoubleTapListener() {
+ return mPanZoomController;
+ }
+
+ /**
+ * Sets the current page rect. You must hold the monitor while calling this.
+ */
+ public void setPageRect(RectF rect, RectF cssRect) {
+ // Since the "rect" is always just a multiple of "cssRect" we don't need to
+ // check both; this function assumes that both "rect" and "cssRect" are relative
+ // the zoom factor in mViewportMetrics.
+ if (mViewportMetrics.getCssPageRect().equals(cssRect))
+ return;
+
+ mViewportMetrics = mViewportMetrics.setPageRect(rect, cssRect);
+
+ // Page size is owned by the layer client, so no need to notify it of
+ // this change.
+
+ mView.post(new Runnable() {
+ public void run() {
+ mPanZoomController.pageRectUpdated();
+ mView.requestRender();
+ }
+ });
+ }
+
+ public void setAnimationTarget(ImmutableViewportMetrics viewport) {
+ // We know what the final viewport of the animation is going to be, so
+ // immediately request a draw of that area by setting the display port
+ // accordingly. This way we should have the content pre-rendered by the
+ // time the animation is done.
+ DisplayPortMetrics displayPort = DisplayPortCalculator.calculate(viewport, null);
+ adjustViewport(displayPort);
+ }
+
+ public boolean post(Runnable action) {
+ return mView.post(action);
+ }
+
+ private void notifyLayerClientOfGeometryChange() {
+ geometryChanged();
+ }
+
+ /**
+ * Aborts any pan/zoom animation that is currently in progress.
+ */
+ public void abortPanZoomAnimation() {
+ if (mPanZoomController != null) {
+ mView.post(new Runnable() {
+ public void run() {
+ mPanZoomController.abortAnimation();
+ }
+ });
+ }
+ }
+
+ /**
+ * Returns true if this controller is fine with performing a redraw operation or false if it
+ * would prefer that the action didn't take place.
+ */
+ public boolean getRedrawHint() {
+ if (mForceRedraw) {
+ mForceRedraw = false;
+ return true;
+ }
+
+ if (!mPanZoomController.getRedrawHint()) {
+ return false;
+ }
+
+ return DisplayPortCalculator.aboutToCheckerboard(mViewportMetrics, mPanZoomController.getVelocityVector(), getDisplayPort());
+ }
+
+ /**
+ * Converts a point from layer view coordinates to layer coordinates. In other words, given a
+ * point measured in pixels from the top left corner of the layer view, returns the point in
+ * pixels measured from the last scroll position we sent to Gecko, in CSS pixels. Assuming the
+ * events being sent to Gecko are processed in FIFO order, this calculation should always be
+ * correct.
+ */
+ public PointF convertViewPointToLayerPoint(PointF viewPoint) {
+ ImmutableViewportMetrics viewportMetrics = mViewportMetrics;
+ PointF origin = viewportMetrics.getOrigin();
+ float zoom = viewportMetrics.zoomFactor;
+ ImmutableViewportMetrics geckoViewport = getGeckoViewportMetrics();
+ PointF geckoOrigin = geckoViewport.getOrigin();
+ float geckoZoom = geckoViewport.zoomFactor;
+
+ // viewPoint + origin gives the coordinate in device pixels from the top-left corner of the page.
+ // Divided by zoom, this gives us the coordinate in CSS pixels from the top-left corner of the page.
+ // geckoOrigin / geckoZoom is where Gecko thinks it is (scrollTo position) in CSS pixels from
+ // the top-left corner of the page. Subtracting the two gives us the offset of the viewPoint from
+ // the current Gecko coordinate in CSS pixels.
+ PointF layerPoint = new PointF(
+ ((viewPoint.x + origin.x) / zoom) - (geckoOrigin.x / geckoZoom),
+ ((viewPoint.y + origin.y) / zoom) - (geckoOrigin.y / geckoZoom));
+
+ return layerPoint;
+ }
+
+ /**
+ * Retrieves whether we should show checkerboard checks or not.
+ */
+ public boolean checkerboardShouldShowChecks() {
+ return mCheckerboardShouldShowChecks;
+ }
+
+ /**
+ * Retrieves the color that the checkerboard should be.
+ */
+ public int getCheckerboardColor() {
+ return mCheckerboardColor;
+ }
+
+ /**
+ * Sets a new color for the checkerboard.
+ */
+ public void setCheckerboardColor(int newColor) {
+ mCheckerboardColor = newColor;
+ mView.requestRender();
+ }
+
+ /**
+ * Sets whether or not the checkerboard should show checkmarks.
+ */
+ public void setCheckerboardShowChecks(boolean showChecks) {
+ mCheckerboardShouldShowChecks = showChecks;
+ mView.requestRender();
+ }
+
+ public ZoomConstraints getZoomConstraints() {
+ return mZoomConstraints;
+ }
+
+ public void setZoomConstraints(ZoomConstraints constraints) {
+ mZoomConstraints = constraints;
+ }
+
private class AdjustRunnable implements Runnable {
public void run() {
mPendingViewportAdjust = false;
adjustViewport(null);
}
}
+
+ public Layer getRoot() {
+ return mRootLayer;
+ }
} \ No newline at end of file
diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/LayerController.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/LayerController.java
deleted file mode 100644
index c641c756eb47..000000000000
--- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/LayerController.java
+++ /dev/null
@@ -1,265 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
- * This Source Code Form is subject to the terms of the Mozilla Public
- * 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.content.Context;
-import android.graphics.Color;
-import android.graphics.PointF;
-import android.graphics.RectF;
-import android.util.DisplayMetrics;
-import android.view.GestureDetector;
-
-import org.mozilla.gecko.ZoomConstraints;
-import org.mozilla.gecko.ui.PanZoomController;
-import org.mozilla.gecko.ui.PanZoomTarget;
-import org.mozilla.gecko.ui.SimpleScaleGestureDetector;
-
-/**
- * The layer controller manages a tile that represents the visible page. It does panning and
- * zooming natively by delegating to a panning/zooming controller. Touch events can be dispatched
- * to a higher-level view.
- *
- * Many methods require that the monitor be held, with a synchronized (controller) { ... } block.
- */
-public class LayerController implements PanZoomTarget {
- private static final String LOGTAG = "GeckoLayerController";
-
- private Layer mRootLayer; /* The root layer. */
- private LayerView mView; /* The main rendering view. */
- private Context mContext; /* The current context. */
-
- /* This is volatile so that we can read and write to it from different threads.
- * We avoid synchronization to make getting the viewport metrics from
- * the compositor as cheap as possible. The viewport is immutable so
- * we don't need to worry about anyone mutating it while we're reading from it.
- * Specifically:
- * 1) reading mViewportMetrics from any thread is fine without synchronization
- * 2) writing to mViewportMetrics requires synchronizing on the layer controller object
- * 3) whenver reading multiple fields from mViewportMetrics without synchronization (i.e. in
- * case 1 above) you should always frist grab a local copy of the reference, and then use
- * that because mViewportMetrics might get reassigned in between reading the different
- * fields. */
- private volatile ImmutableViewportMetrics mViewportMetrics; /* The current viewport metrics. */
-
- /*
- * The panning and zooming controller, which interprets pan and zoom gestures for us and
- * updates our visible rect appropriately.
- */
- private PanZoomController mPanZoomController;
-
- private GeckoLayerClient mLayerClient; /* The layer client. */
-
- /* The new color for the checkerboard. */
- private int mCheckerboardColor = Color.WHITE;
- private boolean mCheckerboardShouldShowChecks;
-
- private ZoomConstraints mZoomConstraints;
-
- private boolean mForceRedraw;
-
- public LayerController(Context context) {
- mContext = context;
- mForceRedraw = true;
- DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
- mViewportMetrics = new ImmutableViewportMetrics(displayMetrics);
- mPanZoomController = new PanZoomController(this);
- mCheckerboardShouldShowChecks = true;
- mZoomConstraints = new ZoomConstraints(false);
- }
-
- public void setView(LayerView v) {
- mView = v;
- mView.connect(this);
- }
-
- public void setRoot(Layer layer) { mRootLayer = layer; }
-
- public void setLayerClient(GeckoLayerClient layerClient) {
- mLayerClient = layerClient;
- layerClient.setLayerController(this);
- }
-
- public void destroy() {
- mPanZoomController.destroy();
- }
-
- public void setForceRedraw() {
- mForceRedraw = true;
- notifyLayerClientOfGeometryChange();
- }
-
- public Layer getRoot() { return mRootLayer; }
- public LayerView getView() { return mView; }
- public Context getContext() { return mContext; }
- public ImmutableViewportMetrics getViewportMetrics() { return mViewportMetrics; }
- public Object getLock() { return this; }
-
- public FloatSize getViewportSize() {
- return mViewportMetrics.getSize();
- }
-
- public PanZoomController getPanZoomController() { return mPanZoomController; }
- public GestureDetector.OnGestureListener getGestureListener() { return mPanZoomController; }
- public SimpleScaleGestureDetector.SimpleScaleGestureListener getScaleGestureListener() {
- return mPanZoomController;
- }
- public GestureDetector.OnDoubleTapListener getDoubleTapListener() { return mPanZoomController; }
-
- /**
- * The view calls this function to indicate that the viewport changed size. It must hold the
- * monitor while calling it.
- *
- * TODO: Refactor this to use an interface. Expose that interface only to the view and not
- * to the layer client. That way, the layer client won't be tempted to call this, which might
- * result in an infinite loop.
- */
- public void setViewportSize(FloatSize size) {
- mViewportMetrics = mViewportMetrics.setViewportSize(size.width, size.height);
-
- if (mLayerClient != null) {
- mLayerClient.viewportSizeChanged();
- }
- }
-
- /** Sets the current page rect. You must hold the monitor while calling this. */
- public void setPageRect(RectF rect, RectF cssRect) {
- // Since the "rect" is always just a multiple of "cssRect" we don't need to
- // check both; this function assumes that both "rect" and "cssRect" are relative
- // the zoom factor in mViewportMetrics.
- if (mViewportMetrics.getCssPageRect().equals(cssRect))
- return;
-
- mViewportMetrics = mViewportMetrics.setPageRect(rect, cssRect);
-
- // Page size is owned by the layer client, so no need to notify it of
- // this change.
-
- mView.post(new Runnable() {
- public void run() {
- mPanZoomController.pageRectUpdated();
- mView.requestRender();
- }
- });
- }
-
- /**
- * Sets the entire viewport metrics at once.
- * You must hold the monitor while calling this.
- */
- public void setViewportMetrics(ImmutableViewportMetrics viewport) {
- mViewportMetrics = viewport;
- mView.requestRender();
- notifyLayerClientOfGeometryChange();
- }
-
- public void setAnimationTarget(ImmutableViewportMetrics viewport) {
- if (mLayerClient != null) {
- // We know what the final viewport of the animation is going to be, so
- // immediately request a draw of that area by setting the display port
- // accordingly. This way we should have the content pre-rendered by the
- // time the animation is done.
- DisplayPortMetrics displayPort = DisplayPortCalculator.calculate(viewport, null);
- mLayerClient.adjustViewport(displayPort);
- }
- }
-
- public boolean post(Runnable action) { return mView.post(action); }
-
- private void notifyLayerClientOfGeometryChange() {
- if (mLayerClient != null)
- mLayerClient.geometryChanged();
- }
-
- /** Aborts any pan/zoom animation that is currently in progress. */
- public void abortPanZoomAnimation() {
- if (mPanZoomController != null) {
- mView.post(new Runnable() {
- public void run() {
- mPanZoomController.abortAnimation();
- }
- });
- }
- }
-
- /**
- * Returns true if this controller is fine with performing a redraw operation or false if it
- * would prefer that the action didn't take place.
- */
- public boolean getRedrawHint() {
- if (mForceRedraw) {
- mForceRedraw = false;
- return true;
- }
-
- if (!mPanZoomController.getRedrawHint()) {
- return false;
- }
-
- return DisplayPortCalculator.aboutToCheckerboard(mViewportMetrics,
- mPanZoomController.getVelocityVector(), mLayerClient.getDisplayPort());
- }
-
- /**
- * Converts a point from layer view coordinates to layer coordinates. In other words, given a
- * point measured in pixels from the top left corner of the layer view, returns the point in
- * pixels measured from the last scroll position we sent to Gecko, in CSS pixels. Assuming the
- * events being sent to Gecko are processed in FIFO order, this calculation should always be
- * correct.
- */
- public PointF convertViewPointToLayerPoint(PointF viewPoint) {
- if (mLayerClient == null) {
- return null;
- }
-
- ImmutableViewportMetrics viewportMetrics = mViewportMetrics;
- PointF origin = viewportMetrics.getOrigin();
- float zoom = viewportMetrics.zoomFactor;
- ImmutableViewportMetrics geckoViewport = mLayerClient.getGeckoViewportMetrics();
- PointF geckoOrigin = geckoViewport.getOrigin();
- float geckoZoom = geckoViewport.zoomFactor;
-
- // viewPoint + origin gives the coordinate in device pixels from the top-left corner of the page.
- // Divided by zoom, this gives us the coordinate in CSS pixels from the top-left corner of the page.
- // geckoOrigin / geckoZoom is where Gecko thinks it is (scrollTo position) in CSS pixels from
- // the top-left corner of the page. Subtracting the two gives us the offset of the viewPoint from
- // the current Gecko coordinate in CSS pixels.
- PointF layerPoint = new PointF(
- ((viewPoint.x + origin.x) / zoom) - (geckoOrigin.x / geckoZoom),
- ((viewPoint.y + origin.y) / zoom) - (geckoOrigin.y / geckoZoom));
-
- return layerPoint;
- }
-
- /** Retrieves whether we should show checkerboard checks or not. */
- public boolean checkerboardShouldShowChecks() {
- return mCheckerboardShouldShowChecks;
- }
-
- /** Retrieves the color that the checkerboard should be. */
- public int getCheckerboardColor() {
- return mCheckerboardColor;
- }
-
- /** Sets whether or not the checkerboard should show checkmarks. */
- public void setCheckerboardShowChecks(boolean showChecks) {
- mCheckerboardShouldShowChecks = showChecks;
- mView.requestRender();
- }
-
- /** Sets a new color for the checkerboard. */
- public void setCheckerboardColor(int newColor) {
- mCheckerboardColor = newColor;
- mView.requestRender();
- }
-
- public void setZoomConstraints(ZoomConstraints constraints) {
- mZoomConstraints = constraints;
- }
-
- public ZoomConstraints getZoomConstraints() {
- return mZoomConstraints;
- }
-}
diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/LayerRenderer.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/LayerRenderer.java
index 9dd3f499f4d0..feb9c09e824a 100644
--- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/LayerRenderer.java
+++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/LayerRenderer.java
@@ -158,8 +158,6 @@ public class LayerRenderer implements GLSurfaceView.Renderer {
public LayerRenderer(LayerView view) {
mView = view;
- LayerController controller = view.getController();
-
CairoImage backgroundImage = new BufferedCairoImage(view.getBackgroundPattern());
mBackgroundLayer = new SingleTileLayer(true, backgroundImage);
@@ -283,8 +281,8 @@ public class LayerRenderer implements GLSurfaceView.Renderer {
* Called whenever a new frame is about to be drawn.
*/
public void onDrawFrame(GL10 gl) {
- Frame frame = createFrame(mView.getController().getViewportMetrics());
- synchronized (mView.getController()) {
+ Frame frame = createFrame(mView.getLayerClient().getViewportMetrics());
+ synchronized (mView.getLayerClient()) {
frame.beginDrawing();
frame.drawBackground();
frame.drawRootLayer();
@@ -498,7 +496,7 @@ public class LayerRenderer implements GLSurfaceView.Renderer {
mUpdated = true;
- Layer rootLayer = mView.getController().getRoot();
+ Layer rootLayer = mView.getLayerClient().getRoot();
if (!mPageContext.fuzzyEquals(mLastPageContext)) {
// the viewport or page changed, so show the scrollbars again
@@ -571,7 +569,7 @@ public class LayerRenderer implements GLSurfaceView.Renderer {
GLES20.glDisable(GLES20.GL_SCISSOR_TEST);
/* Update background color. */
- mBackgroundColor = mView.getController().getCheckerboardColor();
+ mBackgroundColor = mView.getLayerClient().getCheckerboardColor();
/* Clear to the page background colour. The bits set here need to
* match up with those used in gfx/layers/opengl/LayerManagerOGL.cpp.
@@ -596,9 +594,9 @@ public class LayerRenderer implements GLSurfaceView.Renderer {
/* Draw the 'checkerboard'. We use gfx.show_checkerboard_pattern to
* determine whether to draw the screenshot layer.
*/
- if (mView.getController().checkerboardShouldShowChecks()) {
+ if (mView.getLayerClient().checkerboardShouldShowChecks()) {
/* Find the area the root layer will render into, to mask the checkerboard layer */
- Rect rootMask = getMaskForLayer(mView.getController().getRoot());
+ Rect rootMask = getMaskForLayer(mView.getLayerClient().getRoot());
mScreenshotLayer.setMask(rootMask);
/* Scissor around the page-rect, in case the page has shrunk
@@ -611,7 +609,7 @@ public class LayerRenderer implements GLSurfaceView.Renderer {
// Draws the layer the client added to us.
void drawRootLayer() {
- Layer rootLayer = mView.getController().getRoot();
+ Layer rootLayer = mView.getLayerClient().getRoot();
if (rootLayer == null) {
return;
}
@@ -643,7 +641,7 @@ public class LayerRenderer implements GLSurfaceView.Renderer {
mHorizScrollLayer.draw(mPageContext);
/* Measure how much of the screen is checkerboarding */
- Layer rootLayer = mView.getController().getRoot();
+ Layer rootLayer = mView.getLayerClient().getRoot();
if ((rootLayer != null) &&
(mProfileRender || PanningPerfAPI.isRecordingCheckerboard())) {
// Find out how much of the viewport area is valid
diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/LayerView.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/LayerView.java
index 863157aa252c..4d23cf42d68f 100644
--- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/LayerView.java
+++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/LayerView.java
@@ -42,7 +42,7 @@ import java.nio.IntBuffer;
public class LayerView extends FrameLayout {
private static String LOGTAG = "GeckoLayerView";
- private LayerController mController;
+ private GeckoLayerClient mLayerClient;
private TouchEventHandler mTouchEventHandler;
private GLController mGLController;
private InputConnectionHandler mInputConnectionHandler;
@@ -100,9 +100,9 @@ public class LayerView extends FrameLayout {
mGLController = new GLController(this);
}
- void connect(LayerController controller) {
- mController = controller;
- mTouchEventHandler = new TouchEventHandler(getContext(), this, mController);
+ void connect(GeckoLayerClient layerClient) {
+ mLayerClient = layerClient;
+ mTouchEventHandler = new TouchEventHandler(getContext(), this, layerClient);
mRenderer = new LayerRenderer(this);
mInputConnectionHandler = null;
@@ -124,12 +124,12 @@ public class LayerView extends FrameLayout {
return mTouchEventHandler.handleEvent(event);
}
- public LayerController getController() { return mController; }
+ public GeckoLayerClient getLayerClient() { return mLayerClient; }
public TouchEventHandler getTouchEventHandler() { return mTouchEventHandler; }
/** The LayerRenderer calls this to indicate that the window has changed size. */
public void setViewportSize(IntSize size) {
- mController.setViewportSize(new FloatSize(size));
+ mLayerClient.setViewportSize(new FloatSize(size));
}
@Override
@@ -307,7 +307,7 @@ public class LayerView extends FrameLayout {
/** This function is invoked by Gecko (compositor thread) via JNI; be careful when modifying signature. */
public static GLController registerCxxCompositor() {
try {
- LayerView layerView = LibreOfficeMainActivity.mAppContext.getLayerController().getView();
+ LayerView layerView = LibreOfficeMainActivity.mAppContext.getLayerClient().getView();
layerView.mListener.compositorCreated();
return layerView.getGLController();
} catch (Exception e) {
diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/TouchEventHandler.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/TouchEventHandler.java
index b93b5f0a1ff6..f0fe21baf0c4 100644
--- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/TouchEventHandler.java
+++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/TouchEventHandler.java
@@ -123,17 +123,17 @@ public final class TouchEventHandler {
// processed. (n is the absolute value of the balance.)
private int mProcessingBalance;
- TouchEventHandler(Context context, LayerView view, LayerController controller) {
+ TouchEventHandler(Context context, LayerView view, GeckoLayerClient layerClient) {
mView = view;
mEventQueue = new LinkedList<MotionEvent>();
- mGestureDetector = new GestureDetector(context, controller.getGestureListener());
- mScaleGestureDetector = new SimpleScaleGestureDetector(controller.getScaleGestureListener());
- mPanZoomController = controller.getPanZoomController();
+ mGestureDetector = new GestureDetector(context, layerClient.getGestureListener());
+ mScaleGestureDetector = new SimpleScaleGestureDetector(layerClient.getScaleGestureListener());
+ mPanZoomController = layerClient.getPanZoomController();
mListenerTimeoutProcessor = new ListenerTimeoutProcessor();
mDispatchEvents = true;
- mGestureDetector.setOnDoubleTapListener(controller.getDoubleTapListener());
+ mGestureDetector.setOnDoubleTapListener(layerClient.getDoubleTapListener());
}
/* This function MUST be called on the UI thread */