This is an automated email from the ASF dual-hosted git repository. desruisseaux pushed a commit to branch geoapi-4.0 in repository https://gitbox.apache.org/repos/asf/sis.git
commit 43dead50600f25e6fca1a44a72a4964e465f5c4e Author: Martin Desruisseaux <martin.desruisse...@geomatys.com> AuthorDate: Tue Feb 15 15:54:52 2022 +0100 Tune the use of tile cache in `TiledGridCoverage`. Remove the hack about `WritableRaster`, replaced by `RenderingWorkaround` class. --- .../sis/internal/coverage/j2d/TilePlaceholder.java | 3 -- .../sis/internal/storage/TiledGridCoverage.java | 49 ++++++++++++---------- 2 files changed, 28 insertions(+), 24 deletions(-) diff --git a/core/sis-feature/src/main/java/org/apache/sis/internal/coverage/j2d/TilePlaceholder.java b/core/sis-feature/src/main/java/org/apache/sis/internal/coverage/j2d/TilePlaceholder.java index 45d4411..4ac4214 100644 --- a/core/sis-feature/src/main/java/org/apache/sis/internal/coverage/j2d/TilePlaceholder.java +++ b/core/sis-feature/src/main/java/org/apache/sis/internal/coverage/j2d/TilePlaceholder.java @@ -193,9 +193,6 @@ public class TilePlaceholder { // Else prefer read-only tile (created below) if we do not need to draw anything. } } - if (PENDING_JDK_FIX) { - return Raster.createWritableRaster(model, buffer, location); - } // Reuse same `DataBuffer` with only a different location. return Raster.createRaster(model, buffer, location); } diff --git a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/TiledGridCoverage.java b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/TiledGridCoverage.java index 2b2a802..766c43e 100644 --- a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/TiledGridCoverage.java +++ b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/TiledGridCoverage.java @@ -34,6 +34,7 @@ import org.apache.sis.coverage.grid.DisjointExtentException; import org.apache.sis.internal.coverage.j2d.DeferredProperty; import org.apache.sis.internal.coverage.j2d.TiledImage; import org.apache.sis.storage.DataStoreException; +import org.apache.sis.util.collection.WeakValueHashMap; import org.apache.sis.util.resources.Errors; import static java.lang.Math.addExact; @@ -176,7 +177,7 @@ public abstract class TiledGridCoverage extends GridCoverage { * @see AOI#getCachedTile() * @see #createCacheKey(int) */ - private final Map<TiledGridResource.CacheKey, Raster> rasters; + private final WeakValueHashMap<TiledGridResource.CacheKey, Raster> rasters; /** * The sample model for all rasters. The width and height of this sample model are the two first elements @@ -614,16 +615,25 @@ public abstract class TiledGridCoverage extends GridCoverage { } return tile.createTranslatedChild(x, y); } - if (tile.getWidth() == model.getWidth() && tile.getHeight() == model.getHeight()) { + /* + * If the sample model is not the same (e.g. different bands), it must at least have the same size. + * Having a sample model of different size would probably be a bug, but we check anyway for safety. + * Note that the tile size is not necessarily equals to the sample model size. + */ + final SampleModel sm = tile.getSampleModel(); + if (sm.getWidth() == model.getWidth() && sm.getHeight() == model.getHeight()) { + final int width = tile.getWidth(); // May be smaller than sample model width. + final int height = tile.getHeight(); // Idem. /* * It is okay to have a different number of bands if the sample model is * a view created by `SampleModel.createSubsetSampleModel(int[] bands)`. * Bands can also be in a different order and still share the same buffer. */ - if (org.apache.sis.internal.coverage.j2d.TilePlaceholder.PENDING_JDK_FIX) { - return Raster.createWritableRaster(model, tile.getDataBuffer(), new Point(x, y)); + Raster r = Raster.createRaster(model, tile.getDataBuffer(), new Point(x, y)); + if (r.getWidth() != width || r.getHeight() != height) { + r = r.createChild(x, y, width, height, x, y, null); } - return Raster.createRaster(model, tile.getDataBuffer(), new Point(x, y)); + return r; } } return null; @@ -826,27 +836,24 @@ public abstract class TiledGridCoverage extends GridCoverage { public Raster cache(final Raster tile) { final TiledGridResource.CacheKey key = coverage.createCacheKey(indexInTileVector); Raster existing = coverage.rasters.put(key, tile); - if (existing != null) { - /* - * If a tile already exists, verify if its layout is compatible with the given tile. - * If yes, we assume that the two tiles have the same content. We do this check as a - * safety but it should not happen if the caller synchronized the tile read actions. - */ - Raster sentinel = tile; - while (existing.getSampleModel().equals(tile.getSampleModel()) - && existing.getWidth() == tile.getWidth() - && existing.getHeight() == tile.getHeight()) - { + /* + * If a tile already exists, verify if its layout is compatible with the given tile. + * If yes, we assume that the two tiles have the same content. We do this check as a + * safety but it should not happen if the caller synchronized the tile read actions. + */ + if (existing != null + && existing.getSampleModel().equals(tile.getSampleModel()) + && existing.getWidth() == tile.getWidth() + && existing.getHeight() == tile.getHeight()) + { + // Restore the existing tile in the cache, with its original position. + if (coverage.rasters.replace(key, tile, existing)) { final int x = tile.getMinX(); final int y = tile.getMinY(); if (existing.getMinX() != x || existing.getMinY() != y) { existing = existing.createTranslatedChild(x, y); } - final Raster c = coverage.rasters.put(key, existing); - if (c == null || c == sentinel) { - return existing; - } - sentinel = existing = c; // Cache content changed concurrently. + return existing; } } return tile;