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.vajng...@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.vajng...@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.vajng...@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 */
_______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits