jdk/src/java.desktop/share/classes/sun/java2d/marlin/MarlinTileGenerator.java
changeset 47126 188ef162f019
parent 39519 21bfc4452441
equal deleted inserted replaced
45093:c42dc7b58b4d 47126:188ef162f019
     1 /*
     1 /*
     2  * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     7  * published by the Free Software Foundation.  Oracle designates this
    23  * questions.
    23  * questions.
    24  */
    24  */
    25 
    25 
    26 package sun.java2d.marlin;
    26 package sun.java2d.marlin;
    27 
    27 
       
    28 import java.util.Arrays;
    28 import sun.java2d.pipe.AATileGenerator;
    29 import sun.java2d.pipe.AATileGenerator;
    29 import jdk.internal.misc.Unsafe;
    30 import jdk.internal.misc.Unsafe;
    30 
    31 
    31 final class MarlinTileGenerator implements AATileGenerator, MarlinConst {
    32 final class MarlinTileGenerator implements AATileGenerator, MarlinConst {
    32 
    33 
    33     private static final int MAX_TILE_ALPHA_SUM = TILE_SIZE * TILE_SIZE
    34     private static final int MAX_TILE_ALPHA_SUM = TILE_W * TILE_H * MAX_AA_ALPHA;
    34                                                       * MAX_AA_ALPHA;
    35 
    35 
    36     private static final int TH_AA_ALPHA_FILL_EMPTY = ((MAX_AA_ALPHA + 1) / 3); // 33%
    36     private final Renderer rdr;
    37     private static final int TH_AA_ALPHA_FILL_FULL  = ((MAX_AA_ALPHA + 1) * 2 / 3); // 66%
       
    38 
       
    39     private static final int FILL_TILE_W = TILE_W >> 1; // half tile width
       
    40 
       
    41     static {
       
    42         if (MAX_TILE_ALPHA_SUM <= 0) {
       
    43             throw new IllegalStateException("Invalid MAX_TILE_ALPHA_SUM: " + MAX_TILE_ALPHA_SUM);
       
    44         }
       
    45         if (DO_TRACE) {
       
    46             System.out.println("MAX_AA_ALPHA           : " + MAX_AA_ALPHA);
       
    47             System.out.println("TH_AA_ALPHA_FILL_EMPTY : " + TH_AA_ALPHA_FILL_EMPTY);
       
    48             System.out.println("TH_AA_ALPHA_FILL_FULL  : " + TH_AA_ALPHA_FILL_FULL);
       
    49             System.out.println("FILL_TILE_W            : " + FILL_TILE_W);
       
    50         }
       
    51     }
       
    52 
       
    53     private final Renderer rdrF;
       
    54     private final DRenderer rdrD;
    37     private final MarlinCache cache;
    55     private final MarlinCache cache;
    38     private int x, y;
    56     private int x, y;
    39 
    57 
    40     // per-thread renderer context
    58     // per-thread renderer stats
    41     final RendererContext rdrCtx;
    59     final RendererStats rdrStats;
    42 
    60 
    43     MarlinTileGenerator(Renderer r) {
    61     MarlinTileGenerator(final RendererStats stats, final MarlinRenderer r,
    44         this.rdr = r;
    62                         final MarlinCache cache)
    45         this.cache = r.cache;
    63     {
    46         this.rdrCtx = r.rdrCtx;
    64         this.rdrStats = stats;
       
    65         if (r instanceof Renderer) {
       
    66             this.rdrF = (Renderer)r;
       
    67             this.rdrD = null;
       
    68         } else {
       
    69             this.rdrF = null;
       
    70             this.rdrD = (DRenderer)r;
       
    71         }
       
    72         this.cache = cache;
    47     }
    73     }
    48 
    74 
    49     MarlinTileGenerator init() {
    75     MarlinTileGenerator init() {
    50         this.x = cache.bboxX0;
    76         this.x = cache.bboxX0;
    51         this.y = cache.bboxY0;
    77         this.y = cache.bboxY0;
    59      */
    85      */
    60     @Override
    86     @Override
    61     public void dispose() {
    87     public void dispose() {
    62         if (DO_MONITORS) {
    88         if (DO_MONITORS) {
    63             // called from AAShapePipe.renderTiles() (render tiles end):
    89             // called from AAShapePipe.renderTiles() (render tiles end):
    64             rdrCtx.stats.mon_pipe_renderTiles.stop();
    90             rdrStats.mon_pipe_renderTiles.stop();
    65         }
    91         }
    66         // dispose cache:
    92         // dispose cache:
    67         cache.dispose();
    93         cache.dispose();
    68         // dispose renderer:
    94         // dispose renderer and recycle the RendererContext instance:
    69         rdr.dispose();
    95         // bimorphic call optimization:
    70         // recycle the RendererContext instance
    96         if (rdrF != null) {
    71         MarlinRenderingEngine.returnRendererContext(rdrCtx);
    97             rdrF.dispose();
       
    98         } else if (rdrD != null) {
       
    99             rdrD.dispose();
       
   100         }
    72     }
   101     }
    73 
   102 
    74     void getBbox(int[] bbox) {
   103     void getBbox(int[] bbox) {
    75         bbox[0] = cache.bboxX0;
   104         bbox[0] = cache.bboxX0;
    76         bbox[1] = cache.bboxY0;
   105         bbox[1] = cache.bboxY0;
    84      */
   113      */
    85     @Override
   114     @Override
    86     public int getTileWidth() {
   115     public int getTileWidth() {
    87         if (DO_MONITORS) {
   116         if (DO_MONITORS) {
    88             // called from AAShapePipe.renderTiles() (render tiles start):
   117             // called from AAShapePipe.renderTiles() (render tiles start):
    89             rdrCtx.stats.mon_pipe_renderTiles.start();
   118             rdrStats.mon_pipe_renderTiles.start();
    90         }
   119         }
    91         return TILE_SIZE;
   120         return TILE_W;
    92     }
   121     }
    93 
   122 
    94     /**
   123     /**
    95      * Gets the height of the tiles that the generator batches output into.
   124      * Gets the height of the tiles that the generator batches output into.
    96      * @return the height of the standard alpha tile
   125      * @return the height of the standard alpha tile
    97      */
   126      */
    98     @Override
   127     @Override
    99     public int getTileHeight() {
   128     public int getTileHeight() {
   100         return TILE_SIZE;
   129         return TILE_H;
   101     }
   130     }
   102 
   131 
   103     /**
   132     /**
   104      * Gets the typical alpha value that will characterize the current
   133      * Gets the typical alpha value that will characterize the current
   105      * tile.
   134      * tile.
   129         // would be needed here, since our caller needs to compute these 2
   158         // would be needed here, since our caller needs to compute these 2
   130         // values anyway.
   159         // values anyway.
   131         final int alpha = (al == 0x00 ? 0x00
   160         final int alpha = (al == 0x00 ? 0x00
   132                               : (al == MAX_TILE_ALPHA_SUM ? 0xff : 0x80));
   161                               : (al == MAX_TILE_ALPHA_SUM ? 0xff : 0x80));
   133         if (DO_STATS) {
   162         if (DO_STATS) {
   134             rdrCtx.stats.hist_tile_generator_alpha.add(alpha);
   163             rdrStats.hist_tile_generator_alpha.add(alpha);
   135         }
   164         }
   136         return alpha;
   165         return alpha;
   137     }
   166     }
   138 
   167 
   139     /**
   168     /**
   141      * Either this method, or the getAlpha() method should be called
   170      * Either this method, or the getAlpha() method should be called
   142      * once per tile, but not both.
   171      * once per tile, but not both.
   143      */
   172      */
   144     @Override
   173     @Override
   145     public void nextTile() {
   174     public void nextTile() {
   146         if ((x += TILE_SIZE) >= cache.bboxX1) {
   175         if ((x += TILE_W) >= cache.bboxX1) {
   147             x = cache.bboxX0;
   176             x = cache.bboxX0;
   148             y += TILE_SIZE;
   177             y += TILE_H;
   149 
   178 
   150             if (y < cache.bboxY1) {
   179             if (y < cache.bboxY1) {
   151                 // compute for the tile line
   180                 // compute for the tile line
   152                 // [ y; max(y + TILE_SIZE, bboxY1) ]
   181                 // [ y; max(y + TILE_SIZE, bboxY1) ]
   153                 this.rdr.endRendering(y);
   182                 // bimorphic call optimization:
       
   183                 if (rdrF != null) {
       
   184                     rdrF.endRendering(y);
       
   185                 } else if (rdrD != null) {
       
   186                     rdrD.endRendering(y);
       
   187                 }
   154             }
   188             }
   155         }
   189         }
   156     }
   190     }
   157 
   191 
   158     /**
   192     /**
   178      */
   212      */
   179     private void getAlphaNoRLE(final byte[] tile, final int offset,
   213     private void getAlphaNoRLE(final byte[] tile, final int offset,
   180                                final int rowstride)
   214                                final int rowstride)
   181     {
   215     {
   182         if (DO_MONITORS) {
   216         if (DO_MONITORS) {
   183             rdrCtx.stats.mon_ptg_getAlpha.start();
   217             rdrStats.mon_ptg_getAlpha.start();
   184         }
   218         }
   185 
   219 
   186         // local vars for performance:
   220         // local vars for performance:
   187         final MarlinCache _cache = this.cache;
   221         final MarlinCache _cache = this.cache;
   188         final long[] rowAAChunkIndex = _cache.rowAAChunkIndex;
   222         final long[] rowAAChunkIndex = _cache.rowAAChunkIndex;
   189         final int[] rowAAx0 = _cache.rowAAx0;
   223         final int[] rowAAx0 = _cache.rowAAx0;
   190         final int[] rowAAx1 = _cache.rowAAx1;
   224         final int[] rowAAx1 = _cache.rowAAx1;
   191 
   225 
   192         final int x0 = this.x;
   226         final int x0 = this.x;
   193         final int x1 = FloatMath.min(x0 + TILE_SIZE, _cache.bboxX1);
   227         final int x1 = FloatMath.min(x0 + TILE_W, _cache.bboxX1);
   194 
   228 
   195         // note: process tile line [0 - 32[
   229         // note: process tile line [0 - 32[
   196         final int y0 = 0;
   230         final int y0 = 0;
   197         final int y1 = FloatMath.min(this.y + TILE_SIZE, _cache.bboxY1) - this.y;
   231         final int y1 = FloatMath.min(this.y + TILE_H, _cache.bboxY1) - this.y;
   198 
   232 
   199         if (DO_LOG_BOUNDS) {
   233         if (DO_LOG_BOUNDS) {
   200             MarlinUtils.logInfo("getAlpha = [" + x0 + " ... " + x1
   234             MarlinUtils.logInfo("getAlpha = [" + x0 + " ... " + x1
   201                                 + "[ [" + y0 + " ... " + y1 + "[");
   235                                 + "[ [" + y0 + " ... " + y1 + "[");
   202         }
   236         }
   235                         for (end = x0; end < cx; end++) {
   269                         for (end = x0; end < cx; end++) {
   236                             tile[idx++] = 0;
   270                             tile[idx++] = 0;
   237                         }
   271                         }
   238                     }
   272                     }
   239 
   273 
   240                     // now: cx >= x0 but cx < aax0 (x1 < aax0)
   274                     // now: cx >= x0 and cx >= aax0
   241 
   275 
   242                     // Copy AA data (sum alpha data):
   276                     // Copy AA data (sum alpha data):
   243                     addr = addr_rowAA + rowAAChunkIndex[cy] + (cx - aax0);
   277                     addr = addr_rowAA + rowAAChunkIndex[cy] + (cx - aax0);
   244 
   278 
   245                     for (end = (aax1 <= x1) ? aax1 : x1; cx < end; cx++) {
   279                     for (end = (aax1 <= x1) ? aax1 : x1; cx < end; cx++) {
   246                         // cx inside tile[x0; x1[ :
   280                         // cx inside tile[x0; x1[ :
   247                         tile[idx++] = _unsafe.getByte(addr); // [0..255]
   281                         tile[idx++] = _unsafe.getByte(addr); // [0-255]
   248                         addr += SIZE;
   282                         addr += SIZE;
   249                     }
   283                     }
   250                 }
   284                 }
   251             }
   285             }
   252 
   286 
   267         }
   301         }
   268 
   302 
   269         nextTile();
   303         nextTile();
   270 
   304 
   271         if (DO_MONITORS) {
   305         if (DO_MONITORS) {
   272             rdrCtx.stats.mon_ptg_getAlpha.stop();
   306             rdrStats.mon_ptg_getAlpha.stop();
   273         }
   307         }
   274     }
   308     }
   275 
   309 
   276     /**
   310     /**
   277      * Gets the alpha coverage values for the current tile.
   311      * Gets the alpha coverage values for the current tile.
   280      */
   314      */
   281     private void getAlphaRLE(final byte[] tile, final int offset,
   315     private void getAlphaRLE(final byte[] tile, final int offset,
   282                              final int rowstride)
   316                              final int rowstride)
   283     {
   317     {
   284         if (DO_MONITORS) {
   318         if (DO_MONITORS) {
   285             rdrCtx.stats.mon_ptg_getAlpha.start();
   319             rdrStats.mon_ptg_getAlpha.start();
   286         }
   320         }
   287 
   321 
   288         // Decode run-length encoded alpha mask data
   322         // Decode run-length encoded alpha mask data
   289         // The data for row j begins at cache.rowOffsetsRLE[j]
   323         // The data for row j begins at cache.rowOffsetsRLE[j]
   290         // and is encoded as a set of 2-byte pairs (val, runLen)
   324         // and is encoded as a set of 2-byte pairs (val, runLen)
   298         final int[] rowAAEnc = _cache.rowAAEnc;
   332         final int[] rowAAEnc = _cache.rowAAEnc;
   299         final long[] rowAALen = _cache.rowAALen;
   333         final long[] rowAALen = _cache.rowAALen;
   300         final long[] rowAAPos = _cache.rowAAPos;
   334         final long[] rowAAPos = _cache.rowAAPos;
   301 
   335 
   302         final int x0 = this.x;
   336         final int x0 = this.x;
   303         final int x1 = FloatMath.min(x0 + TILE_SIZE, _cache.bboxX1);
   337         final int x1 = FloatMath.min(x0 + TILE_W, _cache.bboxX1);
       
   338         final int w  = x1 - x0;
   304 
   339 
   305         // note: process tile line [0 - 32[
   340         // note: process tile line [0 - 32[
   306         final int y0 = 0;
   341         final int y0 = 0;
   307         final int y1 = FloatMath.min(this.y + TILE_SIZE, _cache.bboxY1) - this.y;
   342         final int y1 = FloatMath.min(this.y + TILE_H, _cache.bboxY1) - this.y;
   308 
   343 
   309         if (DO_LOG_BOUNDS) {
   344         if (DO_LOG_BOUNDS) {
   310             MarlinUtils.logInfo("getAlpha = [" + x0 + " ... " + x1
   345             MarlinUtils.logInfo("getAlpha = [" + x0 + " ... " + x1
   311                                 + "[ [" + y0 + " ... " + y1 + "[");
   346                                 + "[ [" + y0 + " ... " + y1 + "[");
       
   347         }
       
   348 
       
   349         // avoid too small area: fill is not faster !
       
   350         final int clearTile;
       
   351         final byte refVal;
       
   352         final int area;
       
   353 
       
   354         if ((w >= FILL_TILE_W) && (area = w * y1) > 64) { // 64 / 4 ie 16 words min (faster)
       
   355             final int alphaSum = cache.alphaSumInTile(x0);
       
   356 
       
   357             if (alphaSum < area * TH_AA_ALPHA_FILL_EMPTY) {
       
   358                 clearTile = 1;
       
   359                 refVal = 0;
       
   360             } else if (alphaSum > area * TH_AA_ALPHA_FILL_FULL) {
       
   361                 clearTile = 2;
       
   362                 refVal = (byte)0xff;
       
   363             } else {
       
   364                 clearTile = 0;
       
   365                 refVal = 0;
       
   366             }
       
   367         } else {
       
   368             clearTile = 0;
       
   369             refVal = 0;
   312         }
   370         }
   313 
   371 
   314         final Unsafe _unsafe = OffHeapArray.UNSAFE;
   372         final Unsafe _unsafe = OffHeapArray.UNSAFE;
   315         final long SIZE_BYTE = 1L;
   373         final long SIZE_BYTE = 1L;
   316         final long SIZE_INT = 4L;
   374         final long SIZE_INT = 4L;
   317         final long addr_rowAA = _cache.rowAAChunk.address;
   375         final long addr_rowAA = _cache.rowAAChunk.address;
   318         long addr, addr_row, last_addr, addr_end;
   376         long addr, addr_row, last_addr, addr_end;
   319 
   377 
   320         final int skipRowPixels = (rowstride - (x1 - x0));
   378         final int skipRowPixels = (rowstride - w);
   321 
   379 
   322         int cx, cy, cx1;
   380         int cx, cy, cx1;
   323         int rx0, rx1, runLen, end;
   381         int rx0, rx1, runLen, end;
   324         int packed;
   382         int packed;
   325         byte val;
   383         byte val;
   326         int idx = offset;
   384         int idx = offset;
   327 
   385 
   328         for (cy = y0; cy < y1; cy++) {
   386         switch (clearTile) {
   329             // empty line (default)
   387         case 1: // 0x00
   330             cx = x0;
   388             // Clear full tile rows:
   331 
   389             Arrays.fill(tile, offset, offset + (y1 * rowstride), refVal);
   332             if (rowAAEnc[cy] == 0) {
   390 
   333                 // Raw encoding:
   391             for (cy = y0; cy < y1; cy++) {
   334 
   392                 // empty line (default)
   335                 final int aax1 = rowAAx1[cy]; // exclusive
   393                 cx = x0;
   336 
   394 
   337                 // quick check if there is AA data
   395                 if (rowAAEnc[cy] == 0) {
   338                 // corresponding to this tile [x0; x1[
   396                     // Raw encoding:
   339                 if (aax1 > x0) {
   397 
   340                     final int aax0 = rowAAx0[cy]; // inclusive
   398                     final int aax1 = rowAAx1[cy]; // exclusive
   341 
   399 
   342                     if (aax0 < x1) {
   400                     // quick check if there is AA data
   343                         // note: cx is the cursor pointer in the tile array
   401                     // corresponding to this tile [x0; x1[
   344                         // (left to right)
   402                     if (aax1 > x0) {
   345                         cx = aax0;
   403                         final int aax0 = rowAAx0[cy]; // inclusive
   346 
   404 
   347                         // ensure cx >= x0
   405                         if (aax0 < x1) {
   348                         if (cx <= x0) {
   406                             // note: cx is the cursor pointer in the tile array
   349                             cx = x0;
   407                             // (left to right)
   350                         } else {
   408                             cx = aax0;
   351                             // fill line start until first AA pixel rowAA exclusive:
   409 
   352                             for (end = x0; end < cx; end++) {
   410                             // ensure cx >= x0
   353                                 tile[idx++] = 0;
   411                             if (cx <= x0) {
   354                             }
   412                                 cx = x0;
   355                         }
   413                             } else {
   356 
   414                                 // skip line start until first AA pixel rowAA exclusive:
   357                         // now: cx >= x0 but cx < aax0 (x1 < aax0)
   415                                 idx += (cx - x0); // > 0
   358 
   416                             }
   359                         // Copy AA data (sum alpha data):
   417 
   360                         addr = addr_rowAA + rowAAChunkIndex[cy] + (cx - aax0);
   418                             // now: cx >= x0 and cx >= aax0
   361 
   419 
   362                         for (end = (aax1 <= x1) ? aax1 : x1; cx < end; cx++) {
   420                             // Copy AA data (sum alpha data):
   363                             tile[idx++] = _unsafe.getByte(addr); // [0..255]
   421                             addr = addr_rowAA + rowAAChunkIndex[cy] + (cx - aax0);
   364                             addr += SIZE_BYTE;
   422 
   365                         }
   423                             for (end = (aax1 <= x1) ? aax1 : x1; cx < end; cx++) {
   366                     }
   424                                 tile[idx++] = _unsafe.getByte(addr); // [0-255]
   367                 }
   425                                 addr += SIZE_BYTE;
   368             } else {
   426                             }
   369                 // RLE encoding:
   427                         }
   370 
   428                     }
   371                 // quick check if there is AA data
   429                 } else {
   372                 // corresponding to this tile [x0; x1[
   430                     // RLE encoding:
   373                 if (rowAAx1[cy] > x0) { // last pixel exclusive
   431 
   374 
   432                     // quick check if there is AA data
   375                     cx = rowAAx0[cy]; // inclusive
   433                     // corresponding to this tile [x0; x1[
   376                     if (cx > x1) {
   434                     if (rowAAx1[cy] > x0) { // last pixel exclusive
   377                         cx = x1;
   435 
   378                     }
   436                         cx = rowAAx0[cy]; // inclusive
   379 
   437                         if (cx > x1) {
   380                     // fill line start until first AA pixel rowAA exclusive:
   438                             cx = x1;
   381                     for (int i = x0; i < cx; i++) {
   439                         }
   382                         tile[idx++] = 0;
   440 
   383                     }
   441                         // skip line start until first AA pixel rowAA exclusive:
   384 
   442                         if (cx > x0) {
   385                     // get row address:
   443                             idx += (cx - x0); // > 0
   386                     addr_row = addr_rowAA + rowAAChunkIndex[cy];
   444                         }
   387                     // get row end address:
   445 
   388                     addr_end = addr_row + rowAALen[cy]; // coded length
   446                         // get row address:
   389 
   447                         addr_row = addr_rowAA + rowAAChunkIndex[cy];
   390                     // reuse previous iteration position:
   448                         // get row end address:
   391                     addr = addr_row + rowAAPos[cy];
   449                         addr_end = addr_row + rowAALen[cy]; // coded length
   392 
   450 
   393                     last_addr = 0L;
   451                         // reuse previous iteration position:
   394 
   452                         addr = addr_row + rowAAPos[cy];
   395                     while ((cx < x1) && (addr < addr_end)) {
   453 
   396                         // keep current position:
   454                         last_addr = 0L;
   397                         last_addr = addr;
   455 
   398 
   456                         while ((cx < x1) && (addr < addr_end)) {
   399                         // packed value:
   457                             // keep current position:
   400                         packed = _unsafe.getInt(addr);
   458                             last_addr = addr;
   401 
   459 
   402                         // last exclusive pixel x-coordinate:
   460                             // packed value:
   403                         cx1 = (packed >> 8);
   461                             packed = _unsafe.getInt(addr);
   404                         // as bytes:
   462 
   405                         addr += SIZE_INT;
   463                             // last exclusive pixel x-coordinate:
   406 
   464                             cx1 = (packed >> 8);
   407                         rx0 = cx;
   465                             // as bytes:
   408                         if (rx0 < x0) {
   466                             addr += SIZE_INT;
   409                             rx0 = x0;
   467 
   410                         }
   468                             rx0 = cx;
   411                         rx1 = cx = cx1;
   469                             if (rx0 < x0) {
   412                         if (rx1 > x1) {
   470                                 rx0 = x0;
   413                             rx1 = x1;
   471                             }
   414                             cx  = x1; // fix last x
   472                             rx1 = cx = cx1;
   415                         }
   473                             if (rx1 > x1) {
   416                         // adjust runLen:
   474                                 rx1 = x1;
   417                         runLen = rx1 - rx0;
   475                                 cx  = x1; // fix last x
   418 
   476                             }
   419                         // ensure rx1 > rx0:
   477                             // adjust runLen:
   420                         if (runLen > 0) {
   478                             runLen = rx1 - rx0;
   421                             val = (byte)(packed & 0xFF); // [0..255]
   479 
   422 
   480                             // ensure rx1 > rx0:
   423                             do {
   481                             if (runLen > 0) {
   424                                 tile[idx++] = val;
   482                                 packed &= 0xFF; // [0-255]
   425                             } while (--runLen > 0);
   483 
   426                         }
   484                                 if (packed == 0)
   427                     }
   485                                 {
   428 
   486                                     idx += runLen;
   429                     // Update last position in RLE entries:
   487                                     continue;
   430                     if (last_addr != 0L) {
   488                                 }
   431                         // Fix x0:
   489                                 val = (byte) packed; // [0-255]
   432                         rowAAx0[cy]  = cx; // inclusive
   490                                 do {
   433                         // Fix position:
   491                                     tile[idx++] = val;
   434                         rowAAPos[cy] = (last_addr - addr_row);
   492                                 } while (--runLen > 0);
   435                     }
   493                             }
   436                 }
   494                         }
       
   495 
       
   496                         // Update last position in RLE entries:
       
   497                         if (last_addr != 0L) {
       
   498                             // Fix x0:
       
   499                             rowAAx0[cy]  = cx; // inclusive
       
   500                             // Fix position:
       
   501                             rowAAPos[cy] = (last_addr - addr_row);
       
   502                         }
       
   503                     }
       
   504                 }
       
   505 
       
   506                 // skip line end
       
   507                 if (cx < x1) {
       
   508                     idx += (x1 - cx); // > 0
       
   509                 }
       
   510 
       
   511                 if (DO_TRACE) {
       
   512                     for (int i = idx - (x1 - x0); i < idx; i++) {
       
   513                         System.out.print(hex(tile[i], 2));
       
   514                     }
       
   515                     System.out.println();
       
   516                 }
       
   517 
       
   518                 idx += skipRowPixels;
   437             }
   519             }
   438 
   520         break;
   439             // fill line end
   521 
   440             while (cx < x1) {
   522         case 0:
   441                 tile[idx++] = 0;
   523         default:
   442                 cx++;
   524             for (cy = y0; cy < y1; cy++) {
       
   525                 // empty line (default)
       
   526                 cx = x0;
       
   527 
       
   528                 if (rowAAEnc[cy] == 0) {
       
   529                     // Raw encoding:
       
   530 
       
   531                     final int aax1 = rowAAx1[cy]; // exclusive
       
   532 
       
   533                     // quick check if there is AA data
       
   534                     // corresponding to this tile [x0; x1[
       
   535                     if (aax1 > x0) {
       
   536                         final int aax0 = rowAAx0[cy]; // inclusive
       
   537 
       
   538                         if (aax0 < x1) {
       
   539                             // note: cx is the cursor pointer in the tile array
       
   540                             // (left to right)
       
   541                             cx = aax0;
       
   542 
       
   543                             // ensure cx >= x0
       
   544                             if (cx <= x0) {
       
   545                                 cx = x0;
       
   546                             } else {
       
   547                                 for (end = x0; end < cx; end++) {
       
   548                                     tile[idx++] = 0;
       
   549                                 }
       
   550                             }
       
   551 
       
   552                             // now: cx >= x0 and cx >= aax0
       
   553 
       
   554                             // Copy AA data (sum alpha data):
       
   555                             addr = addr_rowAA + rowAAChunkIndex[cy] + (cx - aax0);
       
   556 
       
   557                             for (end = (aax1 <= x1) ? aax1 : x1; cx < end; cx++) {
       
   558                                 tile[idx++] = _unsafe.getByte(addr); // [0-255]
       
   559                                 addr += SIZE_BYTE;
       
   560                             }
       
   561                         }
       
   562                     }
       
   563                 } else {
       
   564                     // RLE encoding:
       
   565 
       
   566                     // quick check if there is AA data
       
   567                     // corresponding to this tile [x0; x1[
       
   568                     if (rowAAx1[cy] > x0) { // last pixel exclusive
       
   569 
       
   570                         cx = rowAAx0[cy]; // inclusive
       
   571                         if (cx > x1) {
       
   572                             cx = x1;
       
   573                         }
       
   574 
       
   575                         // fill line start until first AA pixel rowAA exclusive:
       
   576                         for (end = x0; end < cx; end++) {
       
   577                             tile[idx++] = 0;
       
   578                         }
       
   579 
       
   580                         // get row address:
       
   581                         addr_row = addr_rowAA + rowAAChunkIndex[cy];
       
   582                         // get row end address:
       
   583                         addr_end = addr_row + rowAALen[cy]; // coded length
       
   584 
       
   585                         // reuse previous iteration position:
       
   586                         addr = addr_row + rowAAPos[cy];
       
   587 
       
   588                         last_addr = 0L;
       
   589 
       
   590                         while ((cx < x1) && (addr < addr_end)) {
       
   591                             // keep current position:
       
   592                             last_addr = addr;
       
   593 
       
   594                             // packed value:
       
   595                             packed = _unsafe.getInt(addr);
       
   596 
       
   597                             // last exclusive pixel x-coordinate:
       
   598                             cx1 = (packed >> 8);
       
   599                             // as bytes:
       
   600                             addr += SIZE_INT;
       
   601 
       
   602                             rx0 = cx;
       
   603                             if (rx0 < x0) {
       
   604                                 rx0 = x0;
       
   605                             }
       
   606                             rx1 = cx = cx1;
       
   607                             if (rx1 > x1) {
       
   608                                 rx1 = x1;
       
   609                                 cx  = x1; // fix last x
       
   610                             }
       
   611                             // adjust runLen:
       
   612                             runLen = rx1 - rx0;
       
   613 
       
   614                             // ensure rx1 > rx0:
       
   615                             if (runLen > 0) {
       
   616                                 packed &= 0xFF; // [0-255]
       
   617 
       
   618                                 val = (byte) packed; // [0-255]
       
   619                                 do {
       
   620                                     tile[idx++] = val;
       
   621                                 } while (--runLen > 0);
       
   622                             }
       
   623                         }
       
   624 
       
   625                         // Update last position in RLE entries:
       
   626                         if (last_addr != 0L) {
       
   627                             // Fix x0:
       
   628                             rowAAx0[cy]  = cx; // inclusive
       
   629                             // Fix position:
       
   630                             rowAAPos[cy] = (last_addr - addr_row);
       
   631                         }
       
   632                     }
       
   633                 }
       
   634 
       
   635                 // fill line end
       
   636                 while (cx < x1) {
       
   637                     tile[idx++] = 0;
       
   638                     cx++;
       
   639                 }
       
   640 
       
   641                 if (DO_TRACE) {
       
   642                     for (int i = idx - (x1 - x0); i < idx; i++) {
       
   643                         System.out.print(hex(tile[i], 2));
       
   644                     }
       
   645                     System.out.println();
       
   646                 }
       
   647 
       
   648                 idx += skipRowPixels;
   443             }
   649             }
   444 
   650         break;
   445             if (DO_TRACE) {
   651 
   446                 for (int i = idx - (x1 - x0); i < idx; i++) {
   652         case 2: // 0xFF
   447                     System.out.print(hex(tile[i], 2));
   653             // Fill full tile rows:
   448                 }
   654             Arrays.fill(tile, offset, offset + (y1 * rowstride), refVal);
   449                 System.out.println();
   655 
       
   656             for (cy = y0; cy < y1; cy++) {
       
   657                 // empty line (default)
       
   658                 cx = x0;
       
   659 
       
   660                 if (rowAAEnc[cy] == 0) {
       
   661                     // Raw encoding:
       
   662 
       
   663                     final int aax1 = rowAAx1[cy]; // exclusive
       
   664 
       
   665                     // quick check if there is AA data
       
   666                     // corresponding to this tile [x0; x1[
       
   667                     if (aax1 > x0) {
       
   668                         final int aax0 = rowAAx0[cy]; // inclusive
       
   669 
       
   670                         if (aax0 < x1) {
       
   671                             // note: cx is the cursor pointer in the tile array
       
   672                             // (left to right)
       
   673                             cx = aax0;
       
   674 
       
   675                             // ensure cx >= x0
       
   676                             if (cx <= x0) {
       
   677                                 cx = x0;
       
   678                             } else {
       
   679                                 // fill line start until first AA pixel rowAA exclusive:
       
   680                                 for (end = x0; end < cx; end++) {
       
   681                                     tile[idx++] = 0;
       
   682                                 }
       
   683                             }
       
   684 
       
   685                             // now: cx >= x0 and cx >= aax0
       
   686 
       
   687                             // Copy AA data (sum alpha data):
       
   688                             addr = addr_rowAA + rowAAChunkIndex[cy] + (cx - aax0);
       
   689 
       
   690                             for (end = (aax1 <= x1) ? aax1 : x1; cx < end; cx++) {
       
   691                                 tile[idx++] = _unsafe.getByte(addr); // [0-255]
       
   692                                 addr += SIZE_BYTE;
       
   693                             }
       
   694                         }
       
   695                     }
       
   696                 } else {
       
   697                     // RLE encoding:
       
   698 
       
   699                     // quick check if there is AA data
       
   700                     // corresponding to this tile [x0; x1[
       
   701                     if (rowAAx1[cy] > x0) { // last pixel exclusive
       
   702 
       
   703                         cx = rowAAx0[cy]; // inclusive
       
   704                         if (cx > x1) {
       
   705                             cx = x1;
       
   706                         }
       
   707 
       
   708                         // fill line start until first AA pixel rowAA exclusive:
       
   709                         for (end = x0; end < cx; end++) {
       
   710                             tile[idx++] = 0;
       
   711                         }
       
   712 
       
   713                         // get row address:
       
   714                         addr_row = addr_rowAA + rowAAChunkIndex[cy];
       
   715                         // get row end address:
       
   716                         addr_end = addr_row + rowAALen[cy]; // coded length
       
   717 
       
   718                         // reuse previous iteration position:
       
   719                         addr = addr_row + rowAAPos[cy];
       
   720 
       
   721                         last_addr = 0L;
       
   722 
       
   723                         while ((cx < x1) && (addr < addr_end)) {
       
   724                             // keep current position:
       
   725                             last_addr = addr;
       
   726 
       
   727                             // packed value:
       
   728                             packed = _unsafe.getInt(addr);
       
   729 
       
   730                             // last exclusive pixel x-coordinate:
       
   731                             cx1 = (packed >> 8);
       
   732                             // as bytes:
       
   733                             addr += SIZE_INT;
       
   734 
       
   735                             rx0 = cx;
       
   736                             if (rx0 < x0) {
       
   737                                 rx0 = x0;
       
   738                             }
       
   739                             rx1 = cx = cx1;
       
   740                             if (rx1 > x1) {
       
   741                                 rx1 = x1;
       
   742                                 cx  = x1; // fix last x
       
   743                             }
       
   744                             // adjust runLen:
       
   745                             runLen = rx1 - rx0;
       
   746 
       
   747                             // ensure rx1 > rx0:
       
   748                             if (runLen > 0) {
       
   749                                 packed &= 0xFF; // [0-255]
       
   750 
       
   751                                 if (packed == 0xFF)
       
   752                                 {
       
   753                                     idx += runLen;
       
   754                                     continue;
       
   755                                 }
       
   756                                 val = (byte) packed; // [0-255]
       
   757                                 do {
       
   758                                     tile[idx++] = val;
       
   759                                 } while (--runLen > 0);
       
   760                             }
       
   761                         }
       
   762 
       
   763                         // Update last position in RLE entries:
       
   764                         if (last_addr != 0L) {
       
   765                             // Fix x0:
       
   766                             rowAAx0[cy]  = cx; // inclusive
       
   767                             // Fix position:
       
   768                             rowAAPos[cy] = (last_addr - addr_row);
       
   769                         }
       
   770                     }
       
   771                 }
       
   772 
       
   773                 // fill line end
       
   774                 while (cx < x1) {
       
   775                     tile[idx++] = 0;
       
   776                     cx++;
       
   777                 }
       
   778 
       
   779                 if (DO_TRACE) {
       
   780                     for (int i = idx - (x1 - x0); i < idx; i++) {
       
   781                         System.out.print(hex(tile[i], 2));
       
   782                     }
       
   783                     System.out.println();
       
   784                 }
       
   785 
       
   786                 idx += skipRowPixels;
   450             }
   787             }
   451 
       
   452             idx += skipRowPixels;
       
   453         }
   788         }
   454 
   789 
   455         nextTile();
   790         nextTile();
   456 
   791 
   457         if (DO_MONITORS) {
   792         if (DO_MONITORS) {
   458             rdrCtx.stats.mon_ptg_getAlpha.stop();
   793             rdrStats.mon_ptg_getAlpha.stop();
   459         }
   794         }
   460     }
   795     }
   461 
   796 
   462     static String hex(int v, int d) {
   797     static String hex(int v, int d) {
   463         String s = Integer.toHexString(v);
   798         String s = Integer.toHexString(v);