< prev index next >

src/java.desktop/share/classes/sun/java2d/marlin/MarlinCache.java

Print this page

        

@@ -43,11 +43,11 @@
     // values are stored as int [x|alpha] where alpha is 8 bits
     static final int RLE_MAX_WIDTH = 1 << (24 - 1);
 
     // 2048 (pixelSize) alpha values (width) x 32 rows (tile) = 64K bytes
     // x1 instead of 4 bytes (RLE) ie 1/4 capacity or average good RLE compression
-    static final long INITIAL_CHUNK_ARRAY = TILE_SIZE * INITIAL_PIXEL_DIM; // 64K
+    static final long INITIAL_CHUNK_ARRAY = TILE_H * INITIAL_PIXEL_DIM; // 64K
 
     // The alpha map used by this object (taken out of our map cache) to convert
     // pixel coverage counts gotten from MarlinCache (which are in the range
     // [0, maxalpha]) into alpha values, which are in [0,256).
     static final byte[] ALPHA_MAP;

@@ -70,21 +70,21 @@
 
     int bboxX0, bboxY0, bboxX1, bboxY1;
 
     // 1D dirty arrays
     // row index in rowAAChunk[]
-    final long[] rowAAChunkIndex = new long[TILE_SIZE];
+    final long[] rowAAChunkIndex = new long[TILE_H];
     // first pixel (inclusive) for each row
-    final int[] rowAAx0 = new int[TILE_SIZE];
+    final int[] rowAAx0 = new int[TILE_H];
     // last pixel (exclusive) for each row
-    final int[] rowAAx1 = new int[TILE_SIZE];
+    final int[] rowAAx1 = new int[TILE_H];
     // encoding mode (0=raw, 1=RLE encoding) for each row
-    final int[] rowAAEnc = new int[TILE_SIZE];
+    final int[] rowAAEnc = new int[TILE_H];
     // coded length (RLE encoding) for each row
-    final long[] rowAALen = new long[TILE_SIZE];
+    final long[] rowAALen = new long[TILE_H];
     // last position in RLE decoding for each row (getAlpha):
-    final long[] rowAAPos = new long[TILE_SIZE];
+    final long[] rowAAPos = new long[TILE_H];
 
     // dirty off-heap array containing pixel coverages for (32) rows (packed)
     // if encoding=raw, it contains alpha coverage values (val) as integer
     // if encoding=RLE, it contains tuples (val, last x-coordinate exclusive)
     // use rowAAx0/rowAAx1 to get row indices within this chunk

@@ -95,22 +95,22 @@
 
     // touchedTile[i] is the sum of all the alphas in the tile with
     // x=j*TILE_SIZE+bboxX0.
     int[] touchedTile;
 
-    // per-thread renderer context
-    final RendererContext rdrCtx;
+    // per-thread renderer stats
+    final RendererStats rdrStats;
 
     // touchedTile ref (clean)
     private final IntArrayCache.Reference touchedTile_ref;
 
     int tileMin, tileMax;
 
     boolean useRLE = false;
 
-    MarlinCache(final RendererContext rdrCtx) {
-        this.rdrCtx = rdrCtx;
+    MarlinCache(final IRendererContext rdrCtx) {
+        this.rdrStats = rdrCtx.stats();
 
         rowAAChunk = rdrCtx.newOffHeapArray(INITIAL_CHUNK_ARRAY); // 64K
 
         touchedTile_ref = rdrCtx.newCleanIntArrayRef(INITIAL_ARRAY); // 1K = 1 tile line
         touchedTile     = touchedTile_ref.initial;

@@ -118,11 +118,11 @@
         // tile used marks:
         tileMin = Integer.MAX_VALUE;
         tileMax = Integer.MIN_VALUE;
     }
 
-    void init(int minx, int miny, int maxx, int maxy, int edgeSumDeltaY)
+    void init(int minx, int miny, int maxx, int maxy)
     {
         // assert maxy >= miny && maxx >= minx;
         bboxX0 = minx;
         bboxY0 = miny;
         bboxX1 = maxx;

@@ -140,51 +140,20 @@
 
             // fast check min and max width (maxx < 23bits):
             if (width <= RLE_MIN_WIDTH || width >= RLE_MAX_WIDTH) {
                 useRLE = false;
             } else {
-                // perimeter approach: how fit the total length into given height:
-
-                // if stroking: meanCrossings /= 2 => divide edgeSumDeltaY by 2
-                final int heightSubPixel
-                    = (((maxy - miny) << SUBPIXEL_LG_POSITIONS_Y) << rdrCtx.stroking);
-
-                // check meanDist > block size:
-                // check width / (meanCrossings - 1) >= RLE_THRESHOLD
-
-                // fast case: (meanCrossingPerPixel <= 2) means 1 span only
-                useRLE = (edgeSumDeltaY <= (heightSubPixel << 1))
-                    // note: already checked (meanCrossingPerPixel <= 2)
-                    // rewritten to avoid division:
-                    || (width * heightSubPixel) >
-                            ((edgeSumDeltaY - heightSubPixel) << BLOCK_SIZE_LG);
-
-                if (DO_TRACE && !useRLE) {
-                    final float meanCrossings
-                        = ((float) edgeSumDeltaY) / heightSubPixel;
-                    final float meanDist = width / (meanCrossings - 1);
-
-                    System.out.println("High complexity: "
-                        + " for bbox[width = " + width
-                        + " height = " + (maxy - miny)
-                        + "] edgeSumDeltaY = " + edgeSumDeltaY
-                        + " heightSubPixel = " + heightSubPixel
-                        + " meanCrossings = "+ meanCrossings
-                        + " meanDist = " + meanDist
-                        + " width =  " + (width * heightSubPixel)
-                        + " <= criteria:  " + ((edgeSumDeltaY - heightSubPixel) << BLOCK_SIZE_LG)
-                    );
-                }
+                useRLE = true;
             }
         }
 
         // the ceiling of (maxy - miny + 1) / TILE_SIZE;
-        final int nxTiles = (width + TILE_SIZE) >> TILE_SIZE_LG;
+        final int nxTiles = (width + TILE_W) >> TILE_W_LG;
 
         if (nxTiles > INITIAL_ARRAY) {
             if (DO_STATS) {
-                rdrCtx.stats.stat_array_marlincache_touchedTile.add(nxTiles);
+                rdrStats.stat_array_marlincache_touchedTile.add(nxTiles);
             }
             touchedTile = touchedTile_ref.getArray(nxTiles);
         }
     }
 

@@ -195,11 +164,11 @@
     void dispose() {
         // Reset touchedTile if needed:
         resetTileLine(0);
 
         if (DO_STATS) {
-            rdrCtx.stats.totalOffHeap += rowAAChunk.length;
+            rdrStats.totalOffHeap += rowAAChunk.length;
         }
 
         // Return arrays:
         touchedTile = touchedTile_ref.putArray(touchedTile, 0, 0); // already zero filled
 

@@ -218,18 +187,18 @@
         // update bboxY0 to process a complete tile line [0 - 32]
         bboxY0 = pminY;
 
         // reset current pos
         if (DO_STATS) {
-            rdrCtx.stats.stat_cache_rowAAChunk.add(rowAAChunkPos);
+            rdrStats.stat_cache_rowAAChunk.add(rowAAChunkPos);
         }
         rowAAChunkPos = 0L;
 
         // Reset touchedTile:
         if (tileMin != Integer.MAX_VALUE) {
             if (DO_STATS) {
-                rdrCtx.stats.stat_cache_tiles.add(tileMax - tileMin);
+                rdrStats.stat_cache_tiles.add(tileMax - tileMin);
             }
             // clean only dirty touchedTile:
             if (tileMax == 1) {
                 touchedTile[0] = 0;
             } else {

@@ -267,14 +236,10 @@
      * @param px1 last pixel exclusive x1
      */
     void copyAARowNoRLE(final int[] alphaRow, final int y,
                    final int px0, final int px1)
     {
-        if (DO_MONITORS) {
-            rdrCtx.stats.mon_rdr_copyAARow.start();
-        }
-
         // skip useless pixels above boundary
         final int px_bbox1 = FloatMath.min(px1, bboxX1);
 
         if (DO_LOG_BOUNDS) {
             MarlinUtils.logInfo("row = [" + px0 + " ... " + px_bbox1

@@ -306,16 +271,16 @@
         // ensure rowAAChunk capacity:
         if (_rowAAChunk.length < needSize) {
             expandRowAAChunk(needSize);
         }
         if (DO_STATS) {
-            rdrCtx.stats.stat_cache_rowAA.add(px_bbox1 - px0);
+            rdrStats.stat_cache_rowAA.add(px_bbox1 - px0);
         }
 
         // rowAA contains only alpha values for range[x0; x1[
         final int[] _touchedTile = touchedTile;
-        final int _TILE_SIZE_LG = TILE_SIZE_LG;
+        final int _TILE_SIZE_LG = TILE_W_LG;
 
         final int from = px0      - bboxX0; // first pixel inclusive
         final int to   = px_bbox1 - bboxX0; //  last pixel exclusive
 
         final Unsafe _unsafe = OffHeapArray.UNSAFE;

@@ -340,13 +305,13 @@
                 }
             }
 
             // store alpha sum (as byte):
             if (val == 0) {
-                _unsafe.putByte(addr_off, (byte)0); // [0..255]
+                _unsafe.putByte(addr_off, (byte)0); // [0-255]
             } else {
-                _unsafe.putByte(addr_off, _unsafe.getByte(addr_alpha + val)); // [0..255]
+                _unsafe.putByte(addr_off, _unsafe.getByte(addr_alpha + val)); // [0-255]
 
                 // update touchedTile
                 _touchedTile[x >> _TILE_SIZE_LG] += val;
             }
             addr_off += SIZE_BYTE;

@@ -366,29 +331,21 @@
         if (DO_LOG_BOUNDS) {
             MarlinUtils.logInfo("clear = [" + from + " ... " + to + "[");
         }
 
         // Clear alpha row for reuse:
-        IntArrayCache.fill(alphaRow, from, px1 - bboxX0, 0);
-
-        if (DO_MONITORS) {
-            rdrCtx.stats.mon_rdr_copyAARow.stop();
-        }
+        IntArrayCache.fill(alphaRow, from, px1 + 1 - bboxX0, 0);
     }
 
     void copyAARowRLE_WithBlockFlags(final int[] blkFlags, final int[] alphaRow,
                       final int y, final int px0, final int px1)
     {
-        if (DO_MONITORS) {
-            rdrCtx.stats.mon_rdr_copyAARow.start();
-        }
-
         // Copy rowAA data into the piscesCache if one is present
         final int _bboxX0 = bboxX0;
 
         // process tile line [0 - 32]
-        final int row  = y - bboxY0;
+        final int row  =   y -  bboxY0;
         final int from = px0 - _bboxX0; // first pixel inclusive
 
         // skip useless pixels above boundary
         final int px_bbox1 = FloatMath.min(px1, bboxX1);
         final int to       = px_bbox1 - _bboxX0; //  last pixel exclusive

@@ -416,16 +373,18 @@
         final long SIZE_INT = 4L;
         final long addr_alpha = ALPHA_MAP_UNSAFE.address;
         long addr_off = _rowAAChunk.address + initialPos;
 
         final int[] _touchedTile = touchedTile;
-        final int _TILE_SIZE_LG = TILE_SIZE_LG;
+        final int _TILE_SIZE_LG = TILE_W_LG;
         final int _BLK_SIZE_LG  = BLOCK_SIZE_LG;
 
         // traverse flagged blocks:
         final int blkW = (from >> _BLK_SIZE_LG);
         final int blkE = (to   >> _BLK_SIZE_LG) + 1;
+        // ensure last block flag = 0 to process final block:
+        blkFlags[blkE] = 0;
 
         // Perform run-length encoding and store results in the piscesCache
         int val = 0;
         int cx0 = from;
         int runLen;

@@ -479,11 +438,11 @@
                                     ((_bboxX0 + cx) << 8)
                                 );
                             } else {
                                 _unsafe.putInt(addr_off,
                                     ((_bboxX0 + cx) << 8)
-                                    | (((int) _unsafe.getByte(addr_alpha + val)) & 0xFF) // [0..255]
+                                    | (((int) _unsafe.getByte(addr_alpha + val)) & 0xFF) // [0-255]
                                 );
 
                                 if (runLen == 1) {
                                     _touchedTile[cx0 >> _TILE_SIZE_LG] += val;
                                 } else {

@@ -491,11 +450,11 @@
                                 }
                             }
                             addr_off += SIZE_INT;
 
                             if (DO_STATS) {
-                                rdrCtx.stats.hist_tile_generator_encoding_runLen
+                                rdrStats.hist_tile_generator_encoding_runLen
                                     .add(runLen);
                             }
                             cx0 = cx;
                         }
 

@@ -542,11 +501,11 @@
                 ((_bboxX0 + to) << 8)
             );
         } else {
             _unsafe.putInt(addr_off,
                 ((_bboxX0 + to) << 8)
-                | (((int) _unsafe.getByte(addr_alpha + val)) & 0xFF) // [0..255]
+                | (((int) _unsafe.getByte(addr_alpha + val)) & 0xFF) // [0-255]
             );
 
             if (runLen == 1) {
                 _touchedTile[cx0 >> _TILE_SIZE_LG] += val;
             } else {

@@ -554,11 +513,11 @@
             }
         }
         addr_off += SIZE_INT;
 
         if (DO_STATS) {
-            rdrCtx.stats.hist_tile_generator_encoding_runLen.add(runLen);
+            rdrStats.hist_tile_generator_encoding_runLen.add(runLen);
         }
 
         long len = (addr_off - _rowAAChunk.address);
 
         // update coded length as bytes:

@@ -566,12 +525,12 @@
 
         // update current position:
         rowAAChunkPos = len;
 
         if (DO_STATS) {
-            rdrCtx.stats.stat_cache_rowAA.add(rowAALen[row]);
-            rdrCtx.stats.hist_tile_generator_encoding_ratio.add(
+            rdrStats.stat_cache_rowAA.add(rowAALen[row]);
+            rdrStats.hist_tile_generator_encoding_ratio.add(
                 (100 * skip) / (blkE - blkW)
             );
         }
 
         // update tile used marks:

@@ -584,21 +543,14 @@
         if (tx > tileMax) {
             tileMax = tx;
         }
 
         // Clear alpha row for reuse:
-        if (px1 > bboxX1) {
-            alphaRow[to    ] = 0;
-            alphaRow[to + 1] = 0;
-        }
+        alphaRow[to] = 0;
         if (DO_CHECKS) {
             IntArrayCache.check(blkFlags, blkW, blkE, 0);
-            IntArrayCache.check(alphaRow, from, px1 - bboxX0, 0);
-        }
-
-        if (DO_MONITORS) {
-            rdrCtx.stats.mon_rdr_copyAARow.stop();
+            IntArrayCache.check(alphaRow, from, px1 + 1 - bboxX0, 0);
         }
     }
 
     long startRLERow(final int row, final int x0, final int x1) {
         // rows are supposed to be added by increasing y.

@@ -611,11 +563,11 @@
         return (rowAAChunkIndex[row] = rowAAChunkPos);
     }
 
     private void expandRowAAChunk(final long needSize) {
         if (DO_STATS) {
-            rdrCtx.stats.stat_array_marlincache_rowAAChunk.add(needSize);
+            rdrStats.stat_array_marlincache_rowAAChunk.add(needSize);
         }
 
         // note: throw IOOB if neededSize > 2Gb:
         final long newSize = ArrayCacheConst.getNewLargeSize(rowAAChunk.length,
                                                              needSize);

@@ -627,11 +579,11 @@
                            final int runLen,
                            final int[] _touchedTile)
     {
         // the x and y of the current row, minus bboxX0, bboxY0
         // process tile line [0 - 32]
-        final int _TILE_SIZE_LG = TILE_SIZE_LG;
+        final int _TILE_SIZE_LG = TILE_W_LG;
 
         // update touchedTile
         int tx = (x0 >> _TILE_SIZE_LG);
 
         // handle trivial case: same tile (x0, x0+runLen)

@@ -664,11 +616,11 @@
             _touchedTile[tx] += val * (lastXCoord - txXCoord);
         }
     }
 
     int alphaSumInTile(final int x) {
-        return touchedTile[(x - bboxX0) >> TILE_SIZE_LG];
+        return touchedTile[(x - bboxX0) >> TILE_W_LG];
     }
 
     @Override
     public String toString() {
         return "bbox = ["
< prev index next >