Kaydet (Commit) 9a51a1f4 authored tarafından Tomaž Vajngerl's avatar Tomaž Vajngerl Kaydeden (comit) Miklos Vajna

android: do tile reevaluation in LOKitThread

Currently the tile reevaluation was done in UI thread which could
cause UI stutters as reevaluation is not a simple task. The
result was also a lot of tile rendering requests to LOKitThread.
This changes turns this around and the tile reevaluation is done
in LOKitThread instead. Now the UI thread just sends a LOEvent
when the reevaluation should be done. This should also reduce
the amount of messages that are queued in LOKitThread, however
an execution time should increase.

Change-Id: I01ce911226a71607c06da6100de323ca555db474
üst f699de99
...@@ -16,7 +16,7 @@ public class LOEvent implements Comparable<LOEvent> { ...@@ -16,7 +16,7 @@ public class LOEvent implements Comparable<LOEvent> {
public static final int LOAD = 4; public static final int LOAD = 4;
public static final int CLOSE = 5; public static final int CLOSE = 5;
public static final int REDRAW = 6; public static final int REDRAW = 6;
public static final int TILE_REQUEST = 7; public static final int TILE_REEVALUATION_REQUEST = 7;
public static final int THUMBNAIL = 8; public static final int THUMBNAIL = 8;
public static final int TILE_INVALIDATION = 9; public static final int TILE_INVALIDATION = 9;
public static final int TOUCH = 10; public static final int TOUCH = 10;
...@@ -29,7 +29,6 @@ public class LOEvent implements Comparable<LOEvent> { ...@@ -29,7 +29,6 @@ public class LOEvent implements Comparable<LOEvent> {
public String mTypeString; public String mTypeString;
public int mPartIndex; public int mPartIndex;
public String mFilename; public String mFilename;
public SubTile mTile;
public ComposedTileLayer mComposedTileLayer; public ComposedTileLayer mComposedTileLayer;
public String mTouchType; public String mTouchType;
public MotionEvent mMotionEvent; public MotionEvent mMotionEvent;
...@@ -47,11 +46,10 @@ public class LOEvent implements Comparable<LOEvent> { ...@@ -47,11 +46,10 @@ public class LOEvent implements Comparable<LOEvent> {
mTypeString = "Size Changed: " + widthPixels + " " + heightPixels; mTypeString = "Size Changed: " + widthPixels + " " + heightPixels;
} }
public LOEvent(int type, ComposedTileLayer composedTileLayer, SubTile tile) { public LOEvent(int type, ComposedTileLayer composedTileLayer) {
mType = type; mType = type;
mTypeString = "Tile Request"; mTypeString = "Tile Reevaluation";
mComposedTileLayer = composedTileLayer; mComposedTileLayer = composedTileLayer;
mTile = tile;
} }
public LOEvent(int type, String filename) { public LOEvent(int type, String filename) {
......
...@@ -123,9 +123,7 @@ public class LOKitShell { ...@@ -123,9 +123,7 @@ public class LOKitShell {
LOKitShell.sendEvent(new LOEvent(LOEvent.REDRAW)); LOKitShell.sendEvent(new LOEvent(LOEvent.REDRAW));
} }
public static void sendTileRequestEvent(ComposedTileLayer composedTileLayer, SubTile tile, boolean forceRedraw, int priority) { public static void sendTileReevaluationRequest(ComposedTileLayer composedTileLayer) {
LOEvent event = new LOEvent(LOEvent.TILE_REQUEST, composedTileLayer, tile); LOKitShell.sendEvent(new LOEvent(LOEvent.TILE_REEVALUATION_REQUEST, composedTileLayer));
LOKitShell.sendEvent(event);
} }
} }
...@@ -44,23 +44,36 @@ public class LOKitThread extends Thread implements TileProvider.TileInvalidation ...@@ -44,23 +44,36 @@ public class LOKitThread extends Thread implements TileProvider.TileInvalidation
} }
} }
private void tileRequest(ComposedTileLayer composedTileLayer, SubTile tile) { /* Viewport changed, recheck if tiles need to be added / removed */
private void tileReevaluationRequest(ComposedTileLayer composedTileLayer) {
if (mTileProvider == null) { if (mTileProvider == null) {
return; return;
} }
List<SubTile> tiles = new ArrayList<SubTile>();
mLayerClient.beginDrawing();
composedTileLayer.addNewTiles(tiles);
mLayerClient.endDrawing();
if (composedTileLayer.isStillValid(tile.id)) { for (SubTile tile : tiles) {
TileIdentifier tileId = tile.id; TileIdentifier tileId = tile.id;
CairoImage image = mTileProvider.createTile(tileId.x, tileId.y, tileId.size, tileId.zoom); CairoImage image = mTileProvider.createTile(tileId.x, tileId.y, tileId.size, tileId.zoom);
mLayerClient.beginDrawing();
if (image != null) { if (image != null) {
mLayerClient.beginDrawing();
tile.setImage(image); tile.setImage(image);
mLayerClient.endDrawing();
mLayerClient.forceRender();
} }
mLayerClient.endDrawing();
mLayerClient.forceRender();
} }
mLayerClient.beginDrawing();
composedTileLayer.markTiles();
composedTileLayer.clearMarkedTiles();
mLayerClient.endDrawing();
mLayerClient.forceRender();
} }
/* Invalidate tiles that intersect the input rect */
private void tileInvalidation(RectF rect) { private void tileInvalidation(RectF rect) {
if (mLayerClient == null || mTileProvider == null) { if (mLayerClient == null || mTileProvider == null) {
return; return;
...@@ -171,9 +184,6 @@ public class LOKitThread extends Thread implements TileProvider.TileInvalidation ...@@ -171,9 +184,6 @@ public class LOKitThread extends Thread implements TileProvider.TileInvalidation
case LOEvent.CHANGE_PART: case LOEvent.CHANGE_PART:
changePart(event.mPartIndex); changePart(event.mPartIndex);
break; break;
case LOEvent.TILE_REQUEST:
tileRequest(event.mComposedTileLayer, event.mTile);
break;
case LOEvent.TILE_INVALIDATION: case LOEvent.TILE_INVALIDATION:
tileInvalidation(event.mInvalidationRect); tileInvalidation(event.mInvalidationRect);
break; break;
...@@ -186,6 +196,9 @@ public class LOKitThread extends Thread implements TileProvider.TileInvalidation ...@@ -186,6 +196,9 @@ public class LOKitThread extends Thread implements TileProvider.TileInvalidation
case LOEvent.KEY_EVENT: case LOEvent.KEY_EVENT:
keyEvent(event.mKeyEventType, event.mKeyEvent); keyEvent(event.mKeyEventType, event.mKeyEvent);
break; break;
case LOEvent.TILE_REEVALUATION_REQUEST:
tileReevaluationRequest(event.mComposedTileLayer);
break;
} }
} }
......
...@@ -29,7 +29,10 @@ public abstract class ComposedTileLayer extends Layer implements ComponentCallba ...@@ -29,7 +29,10 @@ public abstract class ComposedTileLayer extends Layer implements ComponentCallba
private final Lock tilesWriteLock = tilesReadWriteLock.writeLock(); private final Lock tilesWriteLock = tilesReadWriteLock.writeLock();
protected RectF currentViewport = new RectF(); protected RectF currentViewport = new RectF();
protected float currentZoom; protected float currentZoom = 1.0f;
protected RectF currentPageRect = new RectF();
private long reevaluationNanoTime = 0;
public ComposedTileLayer(Context context) { public ComposedTileLayer(Context context) {
context.registerComponentCallbacks(this); context.registerComponentCallbacks(this);
...@@ -149,12 +152,16 @@ public abstract class ComposedTileLayer extends Layer implements ComponentCallba ...@@ -149,12 +152,16 @@ public abstract class ComposedTileLayer extends Layer implements ComponentCallba
if (currentViewport.equals(newViewPort) && FloatUtils.fuzzyEquals(currentZoom, newZoom)) { if (currentViewport.equals(newViewPort) && FloatUtils.fuzzyEquals(currentZoom, newZoom)) {
return; return;
} }
currentViewport = newViewPort; currentViewport = newViewPort;
currentZoom = newZoom; currentZoom = newZoom;
currentPageRect = viewportMetrics.getPageRect();
clearMarkedTiles(); long currentReevaluationNanoTime = System.nanoTime();
addNewTiles(viewportMetrics.getPageRect()); if ((currentReevaluationNanoTime - reevaluationNanoTime) > 25 * 1000000) {
markTiles(); reevaluationNanoTime = currentReevaluationNanoTime;
LOKitShell.sendTileReevaluationRequest(this);
}
} }
protected abstract RectF getViewPort(ImmutableViewportMetrics viewportMetrics); protected abstract RectF getViewPort(ImmutableViewportMetrics viewportMetrics);
...@@ -177,27 +184,25 @@ public abstract class ComposedTileLayer extends Layer implements ComponentCallba ...@@ -177,27 +184,25 @@ public abstract class ComposedTileLayer extends Layer implements ComponentCallba
} }
} }
private void addNewTiles(RectF pageRect) { public void addNewTiles(List<SubTile> newTiles) {
beginTransaction();
for (float y = currentViewport.top; y < currentViewport.bottom; y += tileSize.height) { for (float y = currentViewport.top; y < currentViewport.bottom; y += tileSize.height) {
if (y > pageRect.height()) { if (y > currentPageRect.height()) {
continue; continue;
} }
for (float x = currentViewport.left; x < currentViewport.right; x += tileSize.width) { for (float x = currentViewport.left; x < currentViewport.right; x += tileSize.width) {
if (x > pageRect.width()) { if (x > currentPageRect.width()) {
continue; continue;
} }
if (!containsTilesMatching(x, y, currentZoom)) { if (!containsTilesMatching(x, y, currentZoom)) {
TileIdentifier tileId = new TileIdentifier((int) x, (int) y, currentZoom, tileSize); TileIdentifier tileId = new TileIdentifier((int) x, (int) y, currentZoom, tileSize);
SubTile tile = createNewTile(tileId); SubTile tile = createNewTile(tileId);
LOKitShell.sendTileRequestEvent(this, tile, true, getTilePriority()); newTiles.add(tile);
} }
} }
} }
endTransaction();
} }
private void clearMarkedTiles() { public void clearMarkedTiles() {
tilesWriteLock.lock(); tilesWriteLock.lock();
Iterator<SubTile> iterator = tiles.iterator(); Iterator<SubTile> iterator = tiles.iterator();
while (iterator.hasNext()) { while (iterator.hasNext()) {
...@@ -210,7 +215,7 @@ public abstract class ComposedTileLayer extends Layer implements ComponentCallba ...@@ -210,7 +215,7 @@ public abstract class ComposedTileLayer extends Layer implements ComponentCallba
tilesWriteLock.unlock(); tilesWriteLock.unlock();
} }
private void markTiles() { public void markTiles() {
tilesReadLock.lock(); tilesReadLock.lock();
for (SubTile tile : tiles) { for (SubTile tile : tiles) {
if (FloatUtils.fuzzyEquals(tile.id.zoom, currentZoom)) { if (FloatUtils.fuzzyEquals(tile.id.zoom, currentZoom)) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment