[Libreoffice-commits] core.git: Branch 'feature/tiled-editing' - 3 commits - android/experimental
Tomaž Vajngerl
tomaz.vajngerl at collabora.co.uk
Mon Feb 16 19:34:37 PST 2015
android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/ComposedTileLayer.java | 75 +++++++---
android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/GeckoLayerClient.java | 7
2 files changed, 57 insertions(+), 25 deletions(-)
New commits:
commit c289ee5d5f1b50c949f79525dce97cfa27dd1a00
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
Date: Tue Feb 17 12:15:27 2015 +0900
android: restructure reevaluateTiles
Change-Id: I97bcc19571858fd3a43f7d5a9290a5dace7d97dc
diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/ComposedTileLayer.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/ComposedTileLayer.java
index ac1ffad..1dee5de 100644
--- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/ComposedTileLayer.java
+++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/ComposedTileLayer.java
@@ -145,15 +145,15 @@ public abstract class ComposedTileLayer extends Layer implements ComponentCallba
RectF newViewPort = getViewPort(viewportMetrics);
float newZoom = getZoom(viewportMetrics);
- if (!currentViewport.equals(newViewPort) || currentZoom != newZoom) {
- currentViewport = newViewPort;
- currentZoom = newZoom;
- RectF pageRect = viewportMetrics.getPageRect();
-
- clearMarkedTiles();
- addNewTiles(pageRect);
- markTiles();
+ if (currentViewport.equals(newViewPort) && FloatUtils.fuzzyEquals(currentZoom, newZoom)) {
+ return;
}
+ currentViewport = newViewPort;
+ currentZoom = newZoom;
+
+ clearMarkedTiles();
+ addNewTiles(viewportMetrics.getPageRect());
+ markTiles();
}
protected abstract RectF getViewPort(ImmutableViewportMetrics viewportMetrics);
commit 0421b7e87605996b440594be6641a9cab2d972e6
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
Date: Tue Feb 17 12:12:23 2015 +0900
android: use locking to make tile redraw more predictable
CopyOnWriteList is a good thread safe container to store tiles,
however any change to the list makes a internal copy of the
underlaying array which contains the changes. The effect of this
is that this changes aren't immediately shown or only partially
in the other (UI) thread. So they are sometimes partially drawn or
drawn with a delay. This replaces the CopyOnWriteList with a
simple thread unsafe ArrayList and introduces Read/Write locking
to all ArrayList operations. Read operations don't lock, only
a write operation locks access.
Change-Id: I5783c6cde96360a6fd47faa801eec35e4debb792
diff --git a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/ComposedTileLayer.java b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/ComposedTileLayer.java
index 8bbcb2b..ac1ffad 100644
--- a/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/ComposedTileLayer.java
+++ b/android/experimental/LOAndroid3/src/java/org/mozilla/gecko/gfx/ComposedTileLayer.java
@@ -7,88 +7,106 @@ import android.graphics.RectF;
import android.graphics.Region;
import android.util.Log;
-import org.libreoffice.LOEvent;
import org.libreoffice.LOKitShell;
import org.libreoffice.TileIdentifier;
import org.mozilla.gecko.util.FloatUtils;
import java.util.ArrayList;
import java.util.List;
-import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
public abstract class ComposedTileLayer extends Layer implements ComponentCallbacks2 {
private static final String LOGTAG = ComposedTileLayer.class.getSimpleName();
- protected final List<SubTile> tiles = new CopyOnWriteArrayList<SubTile>();
+ protected final List<SubTile> tiles = new ArrayList<SubTile>();
protected final IntSize tileSize;
protected RectF currentViewport = new RectF();
protected float currentZoom;
+ private final ReadWriteLock tilesReadWriteLock = new ReentrantReadWriteLock();
+ private final Lock tilesReadLock = tilesReadWriteLock.readLock();
+ private final Lock tilesWriteLock = tilesReadWriteLock.writeLock();
+
public ComposedTileLayer(Context context) {
context.registerComponentCallbacks(this);
this.tileSize = new IntSize(256, 256);
}
public void invalidate() {
+ tilesReadLock.lock();
for (SubTile tile : tiles) {
tile.invalidate();
}
+ tilesReadLock.unlock();
}
@Override
public void beginTransaction() {
super.beginTransaction();
+ tilesReadLock.lock();
for (SubTile tile : tiles) {
tile.beginTransaction();
}
+ tilesReadLock.unlock();
}
@Override
public void endTransaction() {
+ tilesReadLock.lock();
for (SubTile tile : tiles) {
tile.endTransaction();
}
+ tilesReadLock.unlock();
super.endTransaction();
}
@Override
public void draw(RenderContext context) {
+ tilesReadLock.lock();
for (SubTile tile : tiles) {
if (RectF.intersects(tile.getBounds(context), context.viewport)) {
tile.draw(context);
}
}
+ tilesReadLock.unlock();
}
@Override
protected void performUpdates(RenderContext context) {
super.performUpdates(context);
+ tilesReadLock.lock();
for (SubTile tile : tiles) {
tile.beginTransaction();
tile.refreshTileMetrics();
tile.endTransaction();
tile.performUpdates(context);
}
+ tilesReadLock.unlock();
}
@Override
public Region getValidRegion(RenderContext context) {
Region validRegion = new Region();
+ tilesReadLock.lock();
for (SubTile tile : tiles) {
validRegion.op(tile.getValidRegion(context), Region.Op.UNION);
}
-
+ tilesReadLock.unlock();
return validRegion;
}
@Override
public void setResolution(float newResolution) {
super.setResolution(newResolution);
+ tilesReadLock.lock();
for (SubTile tile : tiles) {
tile.setResolution(newResolution);
}
+ tilesReadLock.unlock();
}
protected RectF roundToTileSize(RectF input, IntSize tileSize) {
@@ -144,6 +162,20 @@ public abstract class ComposedTileLayer extends Layer implements ComponentCallba
protected abstract int getTilePriority();
+ private boolean containsTilesMatching(float x, float y, float currentZoom) {
+ tilesReadLock.lock();
+ try {
+ for (SubTile tile : tiles) {
+ if (tile.id.x == x && tile.id.y == y && tile.id.zoom == currentZoom) {
+ return true;
+ }
+ }
+ return false;
+ } finally {
+ tilesReadLock.unlock();
+ }
+ }
+
private void addNewTiles(RectF pageRect) {
for (float y = currentViewport.top; y < currentViewport.bottom; y += tileSize.height) {
if (y > pageRect.height()) {
@@ -153,13 +185,7 @@ public abstract class ComposedTileLayer extends Layer implements ComponentCallba
if (x > pageRect.width()) {
continue;
}
- boolean contains = false;
- for (SubTile tile : tiles) {
- if (tile.id.x == x && tile.id.y == y && tile.id.zoom == currentZoom) {
- contains = true;
- }
- }
- if (!contains) {
+ if (!containsTilesMatching(x, y, currentZoom)) {
TileIdentifier tileId = new TileIdentifier((int) x, (int) y, currentZoom, tileSize);
LOKitShell.sendTileRequestEvent(this, tileId, true, getTilePriority());
}
@@ -169,6 +195,7 @@ public abstract class ComposedTileLayer extends Layer implements ComponentCallba
private void clearMarkedTiles() {
List<SubTile> tilesToRemove = new ArrayList<SubTile>();
+ tilesWriteLock.lock();
for (SubTile tile : tiles) {
if (tile.markedForRemoval) {
tile.destroy();
@@ -176,9 +203,11 @@ public abstract class ComposedTileLayer extends Layer implements ComponentCallba
}
}
tiles.removeAll(tilesToRemove);
+ tilesWriteLock.unlock();
}
private void markTiles() {
+ tilesReadLock.lock();
for (SubTile tile : tiles) {
if (FloatUtils.fuzzyEquals(tile.id.zoom, currentZoom)) {
RectF tileRect = tile.id.getRectF();
@@ -189,16 +218,21 @@ public abstract class ComposedTileLayer extends Layer implements ComponentCallba
tile.markForRemoval();
}
}
+ tilesReadLock.unlock();
}
public void clearAndReset() {
+ tilesWriteLock.lock();
tiles.clear();
+ tilesWriteLock.unlock();
currentViewport = new RectF();
}
public void addTile(SubTile tile) {
tile.beginTransaction();
+ tilesWriteLock.lock();
tiles.add(tile);
+ tilesWriteLock.unlock();
}
public boolean isStillValid(TileIdentifier tileId) {
@@ -210,12 +244,13 @@ public abstract class ComposedTileLayer extends Layer implements ComponentCallba
*/
public void invalidateTiles(List<SubTile> tilesToInvalidate, RectF cssRect) {
RectF zoomedRect = RectUtils.scale(cssRect, currentZoom);
-
+ tilesReadLock.lock();
for (SubTile tile : tiles) {
if (!tile.markedForRemoval && RectF.intersects(zoomedRect, tile.id.getRectF())) {
tilesToInvalidate.add(tile);
}
}
+ tilesReadLock.unlock();
}
@Override
commit 75c27365d0f9a778ec775a96166b40add855325f
Author: Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
Date: Mon Feb 16 19:31:10 2015 +0900
android: directly call renderFrame, force render on initialization
Change-Id: I8395bae805a89558dd6c7517ea6c6a20b943ebff
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 e975bf9..35f0b20 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
@@ -85,6 +85,7 @@ public class GeckoLayerClient implements PanZoomTarget {
mView.setLayerRenderer(mLayerRenderer);
sendResizeEventIfNecessary();
+ mView.requestRender();
}
public void destroy() {
@@ -335,11 +336,7 @@ public class GeckoLayerClient implements PanZoomTarget {
}
public void forceRender() {
- post(new Runnable() {
- public void run() {
- mView.requestRender();
- }
- });
+ mView.requestRender();
}
/* Root Layer Access */
More information about the Libreoffice-commits
mailing list