summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomaž Vajngerl <tomaz.vajngerl@collabora.com>2014-09-26 13:56:13 +0200
committerTomaž Vajngerl <tomaz.vajngerl@collabora.com>2014-09-26 23:17:21 +0200
commitfd08f4fc4be60c99e83ea6e0aafc5c617c2c6ac0 (patch)
tree395b97ca1af15a56526a2b8a572ca18ef7f99e30
parent91d9276a1288121a126af1d67b7d5f09db7f5101 (diff)
android: rerender tiles when the zoom changes
Initial implementation which needs a lots of polish. Sometimes the app crashes (for yet unknown reasons). Sometimes a gap between tiles is visible probably because of rounding errors. Tile handling and releasing after zoom is quite naive for now (just clearing all the tiles) which needs to be improved to be more seamless. Other changes: The responsibility of LOKitThread to handle tiles was moved to MultiTileLayer. TileProvider now takes into account the current zoom level when requesting tile rerendering. Change-Id: Ic188c03bfadf3a3dd2f79b04f07668eb63b705fb
-rw-r--r--android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java93
-rw-r--r--android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java30
-rw-r--r--android/experimental/LOAndroid3/src/java/org/libreoffice/MockTileProvider.java11
-rw-r--r--android/experimental/LOAndroid3/src/java/org/libreoffice/TileProvider.java4
-rw-r--r--android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/GeckoLayerClient.java64
-rw-r--r--android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/MultiTileLayer.java118
-rw-r--r--android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/SubTile.java8
7 files changed, 156 insertions, 172 deletions
diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java
index 8ba5156225bf..2b7714372cee 100644
--- a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java
+++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitThread.java
@@ -2,123 +2,42 @@ package org.libreoffice;
import android.graphics.Bitmap;
import android.graphics.Rect;
-import android.graphics.RectF;
import android.util.Log;
import org.mozilla.gecko.gfx.FloatSize;
import org.mozilla.gecko.gfx.GeckoLayerClient;
-import org.mozilla.gecko.gfx.ImmutableViewportMetrics;
-import org.mozilla.gecko.gfx.SubTile;
import org.mozilla.gecko.gfx.ViewportMetrics;
-import java.util.ArrayList;
import java.util.concurrent.LinkedBlockingQueue;
public class LOKitThread extends Thread {
private static final String LOGTAG = LOKitThread.class.getSimpleName();
- private static final int TILE_SIZE = 256;
public LinkedBlockingQueue<LOEvent> mEventQueue = new LinkedBlockingQueue<LOEvent>();
private LibreOfficeMainActivity mApplication;
private TileProvider mTileProvider;
private ViewportMetrics mViewportMetrics;
- private Rect mOldRect;
private boolean mCheckboardImageSet = false;
public LOKitThread() {
TileProviderFactory.initialize();
}
- private RectF normlizeRect(ImmutableViewportMetrics metrics) {
- RectF rect = metrics.getViewport();
- float zoomFactor = metrics.zoomFactor;
- return new RectF(rect.left / zoomFactor, rect.top / zoomFactor, rect.right / zoomFactor, rect.bottom / zoomFactor);
- }
-
- private Rect roundToTileSize(RectF input, int tileSize) {
- int minX = (Math.round(input.left) / tileSize) * tileSize;
- int minY = (Math.round(input.top) / tileSize) * tileSize;
- int maxX = ((Math.round(input.right) / tileSize) + 1) * tileSize;
- int maxY = ((Math.round(input.bottom) / tileSize) + 1) * tileSize;
- return new Rect(minX, minY, maxX, maxY);
- }
-
- private Rect inflate(Rect rect, int inflateSize) {
- Rect newRect = new Rect(rect);
- newRect.left -= inflateSize;
- newRect.left = newRect.left < 0 ? 0 : newRect.left;
-
- newRect.top -= inflateSize;
- newRect.top = newRect.top < 0 ? 0 : newRect.top;
-
- newRect.right += inflateSize;
- newRect.bottom += inflateSize;
-
- return newRect;
- }
-
private boolean draw() throws InterruptedException {
int pageWidth = mTileProvider.getPageWidth();
int pageHeight = mTileProvider.getPageHeight();
- mViewportMetrics = new ViewportMetrics();
FloatSize size = new FloatSize(pageWidth, pageHeight);
+ mViewportMetrics = new ViewportMetrics();
mViewportMetrics.setPageSize(size, size);
GeckoLayerClient layerClient = mApplication.getLayerClient();
- layerClient.beginDrawing(mViewportMetrics);
- ImmutableViewportMetrics metrics = mApplication.getLayerController().getViewportMetrics();
- RectF viewport = normlizeRect(metrics);
- Rect rect = inflate(roundToTileSize(viewport, TILE_SIZE), TILE_SIZE);
+ layerClient.beginDrawing();
- mOldRect = rect;
+ layerClient.reevaluateTiles();
- Log.i(LOGTAG, "tilerender RECT: " + rect);
-
- long start = System.currentTimeMillis();
- int noOfRemoved = 0;
-
- ArrayList<SubTile> removeTiles = new ArrayList<SubTile>();
- for (SubTile tile : layerClient.getTiles()) {
- Rect tileRect = new Rect(tile.x, tile.y, tile.x + TILE_SIZE, tile.y + TILE_SIZE);
- if (!Rect.intersects(rect, tileRect)) {
- tile.destroy();
- removeTiles.add(tile);
- noOfRemoved++;
- }
- }
-
- layerClient.getTiles().removeAll(removeTiles);
-
- Log.i(LOGTAG, "TileRendering Clear: " + noOfRemoved + " in " + (System.currentTimeMillis() - start) + "ms");
- start = System.currentTimeMillis();
- int noOfAdded = 0;
- for (int y = rect.top; y < rect.bottom; y += TILE_SIZE) {
- for (int x = rect.left; x < rect.right; x += TILE_SIZE) {
- if (x > pageWidth) {
- continue;
- }
- if (y > pageHeight) {
- continue;
- }
- boolean contains = false;
- for (SubTile tile : layerClient.getTiles()) {
- if (tile.x == x && tile.y == y) {
- contains = true;
- }
- }
- if (!contains) {
- SubTile tile = mTileProvider.createTile(x, y);
- layerClient.addTile(tile);
- noOfAdded++;
- }
- }
- }
-
- layerClient.endDrawing();
-
- Log.i(LOGTAG, "TileRendering Add: " + noOfAdded + " in " + (System.currentTimeMillis() - start) + "ms");
+ layerClient.endDrawing(mViewportMetrics);
return true;
}
@@ -126,7 +45,6 @@ public class LOKitThread extends Thread {
private void changePart(int partIndex) throws InterruptedException {
mTileProvider.changePart(partIndex);
GeckoLayerClient layerClient = mApplication.getLayerClient();
- layerClient.getTiles().clear();
updateCheckbardImage();
LOKitShell.sendEvent(LOEvent.draw(new Rect()));
}
@@ -138,7 +56,10 @@ public class LOKitThread extends Thread {
if (mTileProvider != null) {
mTileProvider.close();
}
+ GeckoLayerClient layerClient = mApplication.getLayerClient();
mTileProvider = TileProviderFactory.create(mApplication.getLayerController(), filename);
+ layerClient.setTileProvider(mTileProvider);
+
boolean isReady = mTileProvider.isReady();
if (isReady) {
updateCheckbardImage();
diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java
index 8a07641d245e..5b1b718cd309 100644
--- a/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java
+++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/LOKitTileProvider.java
@@ -9,7 +9,6 @@ import org.libreoffice.kit.Office;
import org.mozilla.gecko.gfx.BufferedCairoImage;
import org.mozilla.gecko.gfx.CairoImage;
import org.mozilla.gecko.gfx.LayerController;
-import org.mozilla.gecko.gfx.SubTile;
import java.nio.ByteBuffer;
@@ -19,17 +18,17 @@ public class LOKitTileProvider implements TileProvider {
public final Office mOffice;
public final Document mDocument;
private final LayerController mLayerController;
- private final double mTileWidth;
- private final double mTileHeight;
+ private final float mTileWidth;
+ private final float mTileHeight;
private final String mInputFile;
- private double mDPI;
- private double mWidthTwip;
- private double mHeightTwip;
+ private float mDPI;
+ private float mWidthTwip;
+ private float mHeightTwip;
public LOKitTileProvider(LayerController layerController, String input) {
mLayerController = layerController;
- mDPI = (double) LOKitShell.getDpi();
+ mDPI = (float) LOKitShell.getDpi();
mTileWidth = pixelToTwip(TILE_SIZE, mDPI);
mTileHeight = pixelToTwip(TILE_SIZE, mDPI);
@@ -66,12 +65,12 @@ public class LOKitTileProvider implements TileProvider {
}
}
- private double twipToPixel(double input, double dpi) {
- return input / 1440.0 * dpi;
+ private float twipToPixel(float input, float dpi) {
+ return input / 1440.0f * dpi;
}
- private double pixelToTwip(double input, double dpi) {
- return (input / dpi) * 1440.0;
+ private float pixelToTwip(float input, float dpi) {
+ return (input / dpi) * 1440.0f;
}
private boolean checkDocument() {
@@ -108,12 +107,12 @@ public class LOKitTileProvider implements TileProvider {
}
@Override
- public SubTile createTile(int x, int y) {
+ public CairoImage createTile(float x, float y, float zoom) {
ByteBuffer buffer = ByteBuffer.allocateDirect(TILE_SIZE * TILE_SIZE * 4);
Bitmap bitmap = Bitmap.createBitmap(TILE_SIZE, TILE_SIZE, Bitmap.Config.ARGB_8888);
if (mDocument != null) {
- mDocument.paintTile(buffer, TILE_SIZE, TILE_SIZE, (int) pixelToTwip(x, mDPI), (int) pixelToTwip(y, mDPI), (int) mTileWidth, (int) mTileHeight);
+ mDocument.paintTile(buffer, TILE_SIZE, TILE_SIZE, Math.round(pixelToTwip(x, mDPI)/zoom), Math.round(pixelToTwip(y, mDPI)/ zoom), Math.round(mTileWidth / zoom), Math.round(mTileHeight/zoom));
} else {
Log.e(LOGTAG, "Document is null!!");
}
@@ -121,9 +120,8 @@ public class LOKitTileProvider implements TileProvider {
bitmap.copyPixelsFromBuffer(buffer);
CairoImage image = new BufferedCairoImage(bitmap);
- SubTile tile = new SubTile(image, x, y);
- tile.beginTransaction();
- return tile;
+
+ return image;
}
@Override
diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/MockTileProvider.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/MockTileProvider.java
index aa8957adac28..4d1506625b38 100644
--- a/android/experimental/LOAndroid3/src/java/org/libreoffice/MockTileProvider.java
+++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/MockTileProvider.java
@@ -5,7 +5,6 @@ import android.graphics.Bitmap;
import org.mozilla.gecko.gfx.BufferedCairoImage;
import org.mozilla.gecko.gfx.CairoImage;
import org.mozilla.gecko.gfx.LayerController;
-import org.mozilla.gecko.gfx.SubTile;
public class MockTileProvider implements TileProvider {
private static final int TILE_SIZE = 256;
@@ -45,9 +44,9 @@ public class MockTileProvider implements TileProvider {
}
@Override
- public SubTile createTile(int x, int y) {
- int tiles = (getPageWidth() / TILE_SIZE) + 1;
- int tileNumber = (y / TILE_SIZE) * tiles + (x / TILE_SIZE);
+ public CairoImage createTile(float x, float y, float zoom) {
+ int tiles = (int) (getPageWidth() / TILE_SIZE) + 1;
+ int tileNumber = (int) ((y / TILE_SIZE) * tiles + (x / TILE_SIZE));
tileNumber %= 9;
tileNumber += 1; // 0 to 1 based numbering
@@ -55,10 +54,8 @@ public class MockTileProvider implements TileProvider {
Bitmap bitmap = layerController.getDrawable(imageName);
CairoImage image = new BufferedCairoImage(bitmap);
- SubTile tile = new SubTile(image, x, y);
- tile.beginTransaction();
- return tile;
+ return image;
}
@Override
diff --git a/android/experimental/LOAndroid3/src/java/org/libreoffice/TileProvider.java b/android/experimental/LOAndroid3/src/java/org/libreoffice/TileProvider.java
index 40fa51208dc4..d2a9ddd90c54 100644
--- a/android/experimental/LOAndroid3/src/java/org/libreoffice/TileProvider.java
+++ b/android/experimental/LOAndroid3/src/java/org/libreoffice/TileProvider.java
@@ -3,7 +3,7 @@ package org.libreoffice;
import android.graphics.Bitmap;
-import org.mozilla.gecko.gfx.SubTile;
+import org.mozilla.gecko.gfx.CairoImage;
public interface TileProvider {
int getPageWidth();
@@ -12,7 +12,7 @@ public interface TileProvider {
boolean isReady();
- SubTile createTile(int x, int y);
+ CairoImage createTile(float x, float y, float zoom);
void changePart(int partIndex);
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 f826b26ef9c0..d9c594e773be 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,7 +39,6 @@
package org.mozilla.gecko.gfx;
import android.content.Context;
-import android.graphics.PointF;
import android.graphics.RectF;
import android.os.SystemClock;
import android.util.DisplayMetrics;
@@ -49,17 +48,13 @@ import android.view.View;
import org.libreoffice.LOEvent;
import org.libreoffice.LOKitShell;
import org.libreoffice.LibreOfficeMainActivity;
+import org.libreoffice.TileProvider;
import org.mozilla.gecko.util.FloatUtils;
-import java.util.List;
-import java.util.regex.Pattern;
-
public class GeckoLayerClient implements LayerView.Listener {
private static final String LOGTAG = "GeckoLayerClient";
private LayerController mLayerController;
- private LayerRenderer mLayerRenderer;
- private boolean mLayerRendererInitialized;
private IntSize mScreenSize;
private IntSize mWindowSize;
@@ -75,26 +70,8 @@ public class GeckoLayerClient implements LayerView.Listener {
/* The viewport that Gecko will display when drawing is finished */
private ViewportMetrics mNewGeckoViewport;
private Context mContext;
- private static final long MIN_VIEWPORT_CHANGE_DELAY = 25L;
- private long mLastViewportChangeTime;
private boolean mPendingViewportAdjust;
private boolean mViewportSizeChanged;
- private boolean mIgnorePaintsPendingViewportSizeChange;
- private boolean mFirstPaint = true;
-
- // mUpdateViewportOnEndDraw is used to indicate that we received a
- // viewport update notification while drawing. therefore, when the
- // draw finishes, we need to update the entire viewport rather than
- // just the page size. this boolean should always be accessed from
- // inside a transaction, so no synchronization is needed.
- private boolean mUpdateViewportOnEndDraw;
-
- private String mLastCheckerboardColor;
-
- private static Pattern sColorPattern;
-
- /* Used as a temporary ViewTransform by syncViewportInfo */
- private ViewTransform mCurrentViewTransform;
public GeckoLayerClient(Context context) {
mContext = context;
@@ -103,7 +80,6 @@ public class GeckoLayerClient implements LayerView.Listener {
mDisplayPort = new DisplayPortMetrics();
mRecordDrawTimes = true;
mDrawTimingQueue = new DrawTimingQueue();
- mCurrentViewTransform = new ViewTransform(0, 0, 1);
}
/** Attaches the root layer to the layer controller so that Gecko appears. */
@@ -128,21 +104,17 @@ public class GeckoLayerClient implements LayerView.Listener {
return mDisplayPort;
}
- protected void updateLayerAfterDraw() {
- mRootLayer.invalidate();
- }
-
- public void beginDrawing(ViewportMetrics viewportMetrics) {
- mNewGeckoViewport = viewportMetrics;
+ public void beginDrawing() {
mRootLayer.beginTransaction();
+
}
- public void endDrawing() {
+ public void endDrawing(ViewportMetrics viewportMetrics) {
synchronized (mLayerController) {
try {
- updateViewport(!mUpdateViewportOnEndDraw);
- mUpdateViewportOnEndDraw = false;
- updateLayerAfterDraw();
+ mNewGeckoViewport = viewportMetrics;
+ updateViewport(true);
+ mRootLayer.invalidate();
} finally {
mRootLayer.endTransaction();
}
@@ -159,7 +131,6 @@ public class GeckoLayerClient implements LayerView.Listener {
mGeckoViewport = mNewGeckoViewport;
mGeckoViewport.setSize(viewportSize);
- PointF displayportOrigin = mGeckoViewport.getOrigin();
RectF position = mGeckoViewport.getViewport();
mRootLayer.setPosition(RectUtils.round(position));
mRootLayer.setResolution(mGeckoViewport.getZoomFactor());
@@ -252,7 +223,7 @@ public class GeckoLayerClient implements LayerView.Listener {
float ourZoom = mLayerController.getZoomFactor();
pageWidth = pageWidth * ourZoom / zoom;
pageHeight = pageHeight * ourZoom /zoom;
- mLayerController.setPageSize(new FloatSize(pageWidth, pageHeight), new FloatSize(pageWidth, pageHeight));
+ mLayerController.setPageSize(new FloatSize(pageWidth, pageHeight), new FloatSize(cssPageWidth, cssPageHeight));
// 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
@@ -262,22 +233,15 @@ public class GeckoLayerClient implements LayerView.Listener {
public void geometryChanged() {
sendResizeEventIfNecessary(false);
- if (mLayerController.getRedrawHint())
+ if (mLayerController.getRedrawHint()) {
adjustViewport(null);
+ }
}
public ViewportMetrics getGeckoViewportMetrics() {
return mGeckoViewport;
}
- public List<SubTile> getTiles() {
- return mRootLayer.getTiles();
- }
-
- public void addTile(SubTile tile) {
- mRootLayer.addTile(tile);
- }
-
@Override
public void renderRequested() {
@@ -299,6 +263,14 @@ public class GeckoLayerClient implements LayerView.Listener {
renderRequested();
}
+ public void setTileProvider(TileProvider tileProvider) {
+ mRootLayer.setTileProvider(tileProvider);
+ }
+
+ public void reevaluateTiles() {
+ mRootLayer.reevaluateTiles(mLayerController.getViewportMetrics());
+ }
+
private class AdjustRunnable implements Runnable {
public void run() {
mPendingViewportAdjust = false;
diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/MultiTileLayer.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/MultiTileLayer.java
index c6c1befe04a5..eafbf32b28b6 100644
--- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/MultiTileLayer.java
+++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/MultiTileLayer.java
@@ -39,9 +39,14 @@
package org.mozilla.gecko.gfx;
import android.graphics.Point;
+import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Region;
+import android.util.Log;
+import org.libreoffice.TileProvider;
+
+import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
@@ -49,9 +54,15 @@ import java.util.concurrent.CopyOnWriteArrayList;
* Encapsulates the logic needed to draw a layer made of multiple tiles.
*/
public class MultiTileLayer extends Layer {
- private static final String LOGTAG = "GeckoMultiTileLayer";
+ private static final String LOGTAG = "MultiTileLayer";
+ private static int TILE_SIZE = 256;
private final List<SubTile> mTiles;
+ private TileProvider tileProvider;
+ private float currentZoomFactor;
+ private RectF tileViewPort = new RectF();
+ private FloatSize currentPageSize = new FloatSize(0, 0);
+ private boolean shouldRefreshZoom = true;
public MultiTileLayer() {
super();
@@ -118,7 +129,12 @@ public class MultiTileLayer extends Layer {
}
if (origin != null) {
- layer.getPosition().offsetTo(origin.x + layer.x, origin.y + layer.y);
+ Rect position = layer.getPosition();
+ int positionX = origin.x + Math.round(layer.x / layer.zoom);
+ int positionY = origin.y + Math.round(layer.y / layer.zoom);
+ int tileSize = Math.round(256.0f / layer.zoom);
+ position.set(positionX, positionY, positionX + tileSize, positionY + tileSize);
+ layer.setPosition(position);
}
if (resolution >= 0.0f) {
layer.setResolution(resolution);
@@ -130,11 +146,6 @@ public class MultiTileLayer extends Layer {
}
}
- public void setPosition(Point newOrigin) {
- super.getPosition().offsetTo(newOrigin.x, newOrigin.y);
- refreshTileMetrics(newOrigin, -1, true);
- }
-
@Override
public void setResolution(float newResolution) {
super.setResolution(newResolution);
@@ -155,15 +166,47 @@ public class MultiTileLayer extends Layer {
for (SubTile layer : mTiles) {
layer.endTransaction();
}
-
super.endTransaction();
}
+ private RectF normlizeRect(RectF rect, FloatSize pageSize) {
+ return new RectF(rect.left / pageSize.width, rect.top / pageSize.height, rect.right / pageSize.width, rect.bottom / pageSize.height);
+ }
+
+ private RectF roundToTileSize(RectF input, int tileSize) {
+ float minX = (Math.round(input.left) / tileSize) * tileSize;
+ float minY = (Math.round(input.top) / tileSize) * tileSize;
+ float maxX = ((Math.round(input.right) / tileSize) + 1) * tileSize;
+ float maxY = ((Math.round(input.bottom) / tileSize) + 1) * tileSize;
+ return new RectF(minX, minY, maxX, maxY);
+ }
+
+ private RectF inflate(RectF rect, float inflateSize) {
+ RectF newRect = new RectF(rect);
+ newRect.left -= inflateSize;
+ newRect.left = newRect.left < 0.0f ? 0.0f : newRect.left;
+
+ newRect.top -= inflateSize;
+ newRect.top = newRect.top < 0.0f ? 0.0f : newRect.top;
+
+ newRect.right += inflateSize;
+ newRect.bottom += inflateSize;
+
+ return newRect;
+ }
+
@Override
public void draw(RenderContext context) {
+ if (tileProvider == null) {
+ return;
+ }
+
+ currentPageSize = context.pageSize;
+
for (SubTile layer : mTiles) {
// Avoid work, only draw tiles that intersect with the viewport
RectF layerBounds = layer.getBounds(context);
+
if (RectF.intersects(layerBounds, context.viewport)) {
layer.draw(context);
}
@@ -180,12 +223,63 @@ public class MultiTileLayer extends Layer {
return validRegion;
}
- public void addTile(SubTile tile) {
- mTiles.add(tile);
+ public void setTileProvider(TileProvider tileProvider) {
+ this.tileProvider = tileProvider;
+ }
+
+ public void reevaluateTiles(ImmutableViewportMetrics viewportMetrics) {
+ if (currentZoomFactor != viewportMetrics.zoomFactor) {
+ currentZoomFactor = viewportMetrics.zoomFactor;
+ mTiles.clear();
+ }
+
+ RectF newTileViewPort = inflate(roundToTileSize(viewportMetrics.getViewport(), TILE_SIZE), TILE_SIZE);
+
+ Log.i(LOGTAG, "reevaluateTiles ( " + viewportMetrics + " )");
+
+ if (tileViewPort != newTileViewPort) {
+ tileViewPort = newTileViewPort;
+ clearTiles();
+ addNewTiles();
+ }
+ }
+
+ private void addNewTiles() {
+ for (float y = tileViewPort.top; y < tileViewPort.bottom; y += TILE_SIZE) {
+ if (y > currentPageSize.height) {
+ continue;
+ }
+ for (float x = tileViewPort.left; x < tileViewPort.right; x += TILE_SIZE) {
+ if (x > currentPageSize.width) {
+ continue;
+ }
+ boolean contains = false;
+ for (SubTile tile : mTiles) {
+ if (tile.x == x && tile.y == y) {
+ contains = true;
+ }
+ }
+ if (!contains) {
+ CairoImage image = tileProvider.createTile(x, y, currentZoomFactor);
+ SubTile tile = new SubTile(image, (int)x, (int)y, currentZoomFactor);
+ tile.beginTransaction();
+ mTiles.add(tile);
+ }
+ }
+ }
}
- public List<SubTile> getTiles() {
- return mTiles;
+ private void clearTiles() {
+ ArrayList<SubTile> removeTiles = new ArrayList<SubTile>();
+ for (SubTile tile : mTiles) {
+ RectF tileRect = new RectF(tile.x, tile.y, tile.x + TILE_SIZE, tile.y + TILE_SIZE);
+ if (!RectF.intersects(tileViewPort, tileRect)) {
+ tile.destroy();
+ removeTiles.add(tile);
+ }
+ }
+
+ mTiles.removeAll(removeTiles);
}
}
diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/SubTile.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/SubTile.java
index 87d492d9ad5d..9ec98ec4bdda 100644
--- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/SubTile.java
+++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/SubTile.java
@@ -8,10 +8,12 @@ package org.mozilla.gecko.gfx;
public class SubTile extends SingleTileLayer {
public int x;
public int y;
+ public float zoom;
- public SubTile(CairoImage mImage, int mX, int mY) {
+ public SubTile(CairoImage mImage, int x, int y, float zoom) {
super(mImage);
- x = mX;
- y = mY;
+ this.x = x;
+ this.y = y;
+ this.zoom = zoom;
}
}