[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