Search in sources :

Example 31 with Unsafe

use of sun.misc.Unsafe in project lwjgl by LWJGL.

the class MappedObjectUnsafe method getUnsafeInstance.

private static Unsafe getUnsafeInstance() {
    final Field[] fields = Unsafe.class.getDeclaredFields();
    /*
		Different runtimes use different names for the Unsafe singleton,
		so we cannot use .getDeclaredField and we scan instead. For example:

		Oracle: theUnsafe
		PERC : m_unsafe_instance
		Android: THE_ONE
		*/
    for (Field field : fields) {
        if (!field.getType().equals(Unsafe.class))
            continue;
        final int modifiers = field.getModifiers();
        if (!(Modifier.isStatic(modifiers) && Modifier.isFinal(modifiers)))
            continue;
        field.setAccessible(true);
        try {
            return (Unsafe) field.get(null);
        } catch (IllegalAccessException e) {
        // ignore
        }
        break;
    }
    throw new UnsupportedOperationException();
}
Also used : Field(java.lang.reflect.Field) Unsafe(sun.misc.Unsafe)

Example 32 with Unsafe

use of sun.misc.Unsafe in project voltdb by VoltDB.

the class CrashJVM method getUnsafe.

private static Unsafe getUnsafe() throws NoSuchFieldException, IllegalAccessException {
    Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
    theUnsafe.setAccessible(true);
    return (Unsafe) theUnsafe.get(null);
}
Also used : Field(java.lang.reflect.Field) Unsafe(sun.misc.Unsafe)

Example 33 with Unsafe

use of sun.misc.Unsafe in project jdk8u_jdk by JetBrains.

the class JObjCRuntime method getUnsafe.

private static final Unsafe getUnsafe() {
    Unsafe inst = null;
    try {
        Field f = Unsafe.class.getDeclaredField("theUnsafe");
        f.setAccessible(true);
        inst = (Unsafe) f.get(null);
        if (inst == null)
            throw new NullPointerException("Unsafe.theUnsafe == null");
    } catch (Exception e) {
        throw new RuntimeException("Unable to get instance of Unsafe.", e);
    }
    return inst;
}
Also used : Field(java.lang.reflect.Field) Unsafe(sun.misc.Unsafe)

Example 34 with Unsafe

use of sun.misc.Unsafe in project jdk8u_jdk by JetBrains.

the class MarlinCache method copyAARowNoRLE.

/**
     * Copy the given alpha data into the rowAA cache
     * @param alphaRow alpha data to copy from
     * @param y y pixel coordinate
     * @param px0 first pixel inclusive x0
     * @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 + " (" + px1 + ") [ for y=" + y);
    }
    final int row = y - bboxY0;
    // update pixel range:
    // first pixel inclusive
    rowAAx0[row] = px0;
    //  last pixel exclusive
    rowAAx1[row] = px_bbox1;
    // raw encoding
    rowAAEnc[row] = 0;
    // get current position (bytes):
    final long pos = rowAAChunkPos;
    // update row index to current position:
    rowAAChunkIndex[row] = pos;
    // determine need array size:
    // for RLE encoding, position must be aligned to 4 bytes (int):
    // align - 1 = 3 so add +3 and round-off by mask ~3 = -4
    final long needSize = pos + ((px_bbox1 - px0 + 3) & -4);
    // update next position (bytes):
    rowAAChunkPos = needSize;
    // update row data:
    final OffHeapArray _rowAAChunk = rowAAChunk;
    // ensure rowAAChunk capacity:
    if (_rowAAChunk.length < needSize) {
        expandRowAAChunk(needSize);
    }
    if (DO_STATS) {
        rdrCtx.stats.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;
    // first pixel inclusive
    final int from = px0 - bboxX0;
    //  last pixel exclusive
    final int to = px_bbox1 - bboxX0;
    final Unsafe _unsafe = OffHeapArray.UNSAFE;
    final long SIZE_BYTE = 1L;
    final long addr_alpha = ALPHA_MAP_UNSAFE.address;
    long addr_off = _rowAAChunk.address + pos;
    // compute alpha sum into rowAA:
    for (int x = from, val = 0; x < to; x++) {
        // alphaRow is in [0; MAX_COVERAGE]
        // [from; to[
        val += alphaRow[x];
        // ensure values are in [0; MAX_AA_ALPHA] range
        if (DO_AA_RANGE_CHECK) {
            if (val < 0) {
                System.out.println("Invalid coverage = " + val);
                val = 0;
            }
            if (val > MAX_AA_ALPHA) {
                System.out.println("Invalid coverage = " + val);
                val = MAX_AA_ALPHA;
            }
        }
        // store alpha sum (as byte):
        if (val == 0) {
            // [0..255]
            _unsafe.putByte(addr_off, (byte) 0);
        } else {
            // [0..255]
            _unsafe.putByte(addr_off, _unsafe.getByte(addr_alpha + val));
            // update touchedTile
            _touchedTile[x >> _TILE_SIZE_LG] += val;
        }
        addr_off += SIZE_BYTE;
    }
    // update tile used marks:
    // inclusive
    int tx = from >> _TILE_SIZE_LG;
    if (tx < tileMin) {
        tileMin = tx;
    }
    // exclusive (+1 to be sure)
    tx = ((to - 1) >> _TILE_SIZE_LG) + 1;
    if (tx > tileMax) {
        tileMax = tx;
    }
    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();
    }
}
Also used : Unsafe(sun.misc.Unsafe)

Example 35 with Unsafe

use of sun.misc.Unsafe in project jdk8u_jdk by JetBrains.

the class Renderer method _endRendering.

private void _endRendering(final int ymin, final int ymax) {
    if (DISABLE_RENDER) {
        return;
    }
    // Get X bounds as true pixel boundaries to compute correct pixel coverage:
    final int bboxx0 = bbox_spminX;
    final int bboxx1 = bbox_spmaxX;
    final boolean windingRuleEvenOdd = (windingRule == WIND_EVEN_ODD);
    // Useful when processing tile line by tile line
    final int[] _alpha = alphaLine;
    // local vars (performance):
    final MarlinCache _cache = cache;
    final OffHeapArray _edges = edges;
    final int[] _edgeBuckets = edgeBuckets;
    final int[] _edgeBucketCounts = edgeBucketCounts;
    int[] _crossings = this.crossings;
    int[] _edgePtrs = this.edgePtrs;
    // merge sort auxiliary storage:
    int[] _aux_crossings = this.aux_crossings;
    int[] _aux_edgePtrs = this.aux_edgePtrs;
    // copy constants:
    final long _OFF_ERROR = OFF_ERROR;
    final long _OFF_BUMP_X = OFF_BUMP_X;
    final long _OFF_BUMP_ERR = OFF_BUMP_ERR;
    final long _OFF_NEXT = OFF_NEXT;
    final long _OFF_YMAX = OFF_YMAX;
    final int _ALL_BUT_LSB = ALL_BUT_LSB;
    final int _ERR_STEP_MAX = ERR_STEP_MAX;
    // unsafe I/O:
    final Unsafe _unsafe = OffHeapArray.UNSAFE;
    final long addr0 = _edges.address;
    long addr;
    final int _SUBPIXEL_LG_POSITIONS_X = SUBPIXEL_LG_POSITIONS_X;
    final int _SUBPIXEL_LG_POSITIONS_Y = SUBPIXEL_LG_POSITIONS_Y;
    final int _SUBPIXEL_MASK_X = SUBPIXEL_MASK_X;
    final int _SUBPIXEL_MASK_Y = SUBPIXEL_MASK_Y;
    final int _SUBPIXEL_POSITIONS_X = SUBPIXEL_POSITIONS_X;
    final int _MIN_VALUE = Integer.MIN_VALUE;
    final int _MAX_VALUE = Integer.MAX_VALUE;
    // Now we iterate through the scanlines. We must tell emitRow the coord
    // of the first non-transparent pixel, so we must keep accumulators for
    // the first and last pixels of the section of the current pixel row
    // that we will emit.
    // We also need to accumulate pix_bbox, but the iterator does it
    // for us. We will just get the values from it once this loop is done
    int minX = _MAX_VALUE;
    int maxX = _MIN_VALUE;
    int y = ymin;
    int bucket = y - boundsMinY;
    int numCrossings = this.edgeCount;
    int edgePtrsLen = _edgePtrs.length;
    int crossingsLen = _crossings.length;
    int _arrayMaxUsed = activeEdgeMaxUsed;
    int ptrLen = 0, newCount, ptrEnd;
    int bucketcount, i, j, ecur;
    int cross, lastCross;
    int x0, x1, tmp, sum, prev, curx, curxo, crorientation, err;
    int pix_x, pix_xmaxm1, pix_xmax;
    int low, high, mid, prevNumCrossings;
    boolean useBinarySearch;
    final int[] _blkFlags = blkFlags;
    final int _BLK_SIZE_LG = BLOCK_SIZE_LG;
    final int _BLK_SIZE = BLOCK_SIZE;
    final boolean _enableBlkFlagsHeuristics = ENABLE_BLOCK_FLAGS_HEURISTICS && this.enableBlkFlags;
    // Use block flags if large pixel span and few crossings:
    // ie mean(distance between crossings) is high
    boolean useBlkFlags = this.prevUseBlkFlags;
    final int stroking = rdrCtx.stroking;
    // last emited row
    int lastY = -1;
    // Iteration on scanlines
    for (; y < ymax; y++, bucket++) {
        // --- from former ScanLineIterator.next()
        bucketcount = _edgeBucketCounts[bucket];
        // marker on previously sorted edges:
        prevNumCrossings = numCrossings;
        // bucketCount indicates new edge / edge end:
        if (bucketcount != 0) {
            if (DO_STATS) {
                rdrCtx.stats.stat_rdr_activeEdges_updates.add(numCrossings);
            }
            // last bit set to 1 means that edges ends
            if ((bucketcount & 0x1) != 0) {
                // eviction in active edge list
                // cache edges[] address + offset
                addr = addr0 + _OFF_YMAX;
                for (i = 0, newCount = 0; i < numCrossings; i++) {
                    // get the pointer to the edge
                    ecur = _edgePtrs[i];
                    // random access so use unsafe:
                    if (_unsafe.getInt(addr + ecur) > y) {
                        _edgePtrs[newCount++] = ecur;
                    }
                }
                // update marker on sorted edges minus removed edges:
                prevNumCrossings = numCrossings = newCount;
            }
            // number of new edge
            ptrLen = bucketcount >> 1;
            if (ptrLen != 0) {
                if (DO_STATS) {
                    rdrCtx.stats.stat_rdr_activeEdges_adds.add(ptrLen);
                    if (ptrLen > 10) {
                        rdrCtx.stats.stat_rdr_activeEdges_adds_high.add(ptrLen);
                    }
                }
                ptrEnd = numCrossings + ptrLen;
                if (edgePtrsLen < ptrEnd) {
                    if (DO_STATS) {
                        rdrCtx.stats.stat_array_renderer_edgePtrs.add(ptrEnd);
                    }
                    this.edgePtrs = _edgePtrs = rdrCtx.widenDirtyIntArray(_edgePtrs, numCrossings, ptrEnd);
                    edgePtrsLen = _edgePtrs.length;
                    // Get larger auxiliary storage:
                    if (_aux_edgePtrs != aux_edgePtrs_initial) {
                        rdrCtx.putDirtyIntArray(_aux_edgePtrs);
                    }
                    // factor than widenDirtyIntArray():
                    if (DO_STATS) {
                        rdrCtx.stats.stat_array_renderer_aux_edgePtrs.add(ptrEnd);
                    }
                    this.aux_edgePtrs = _aux_edgePtrs = rdrCtx.getDirtyIntArray(ArrayCache.getNewSize(numCrossings, ptrEnd));
                }
                // cache edges[] address + offset
                addr = addr0 + _OFF_NEXT;
                // add new edges to active edge list:
                for (ecur = _edgeBuckets[bucket]; numCrossings < ptrEnd; numCrossings++) {
                    // store the pointer to the edge
                    _edgePtrs[numCrossings] = ecur;
                    // random access so use unsafe:
                    ecur = _unsafe.getInt(addr + ecur);
                }
                if (crossingsLen < numCrossings) {
                    // Get larger array:
                    if (_crossings != crossings_initial) {
                        rdrCtx.putDirtyIntArray(_crossings);
                    }
                    if (DO_STATS) {
                        rdrCtx.stats.stat_array_renderer_crossings.add(numCrossings);
                    }
                    this.crossings = _crossings = rdrCtx.getDirtyIntArray(numCrossings);
                    // Get larger auxiliary storage:
                    if (_aux_crossings != aux_crossings_initial) {
                        rdrCtx.putDirtyIntArray(_aux_crossings);
                    }
                    if (DO_STATS) {
                        rdrCtx.stats.stat_array_renderer_aux_crossings.add(numCrossings);
                    }
                    this.aux_crossings = _aux_crossings = rdrCtx.getDirtyIntArray(numCrossings);
                    crossingsLen = _crossings.length;
                }
                if (DO_STATS) {
                    // update max used mark
                    if (numCrossings > _arrayMaxUsed) {
                        _arrayMaxUsed = numCrossings;
                    }
                }
            }
        // ptrLen != 0
        }
        if (numCrossings != 0) {
            /*
                 * thresholds to switch to optimized merge sort
                 * for newly added edges + final merge pass.
                 */
            if ((ptrLen < 10) || (numCrossings < 40)) {
                if (DO_STATS) {
                    rdrCtx.stats.hist_rdr_crossings.add(numCrossings);
                    rdrCtx.stats.hist_rdr_crossings_adds.add(ptrLen);
                }
                /*
                     * threshold to use binary insertion sort instead of
                     * straight insertion sort (to reduce minimize comparisons).
                     */
                useBinarySearch = (numCrossings >= 20);
                // if small enough:
                lastCross = _MIN_VALUE;
                for (i = 0; i < numCrossings; i++) {
                    // get the pointer to the edge
                    ecur = _edgePtrs[i];
                    /* convert subpixel coordinates (float) into pixel
                            positions (int) for coming scanline */
                    /* note: it is faster to always update edges even
                           if it is removed from AEL for coming or last scanline */
                    // random access so use unsafe:
                    // ecur + OFF_F_CURX
                    addr = addr0 + ecur;
                    // get current crossing:
                    curx = _unsafe.getInt(addr);
                    // update crossing with orientation at last bit:
                    cross = curx;
                    // Increment x using DDA (fixed point):
                    curx += _unsafe.getInt(addr + _OFF_BUMP_X);
                    // Increment error:
                    err = _unsafe.getInt(addr + _OFF_ERROR) + _unsafe.getInt(addr + _OFF_BUMP_ERR);
                    // Manual carry handling:
                    // keep sign and carry bit only and ignore last bit (preserve orientation):
                    _unsafe.putInt(addr, curx - ((err >> 30) & _ALL_BUT_LSB));
                    _unsafe.putInt(addr + _OFF_ERROR, (err & _ERR_STEP_MAX));
                    if (DO_STATS) {
                        rdrCtx.stats.stat_rdr_crossings_updates.add(numCrossings);
                    }
                    // insertion sort of crossings:
                    if (cross < lastCross) {
                        if (DO_STATS) {
                            rdrCtx.stats.stat_rdr_crossings_sorts.add(i);
                        }
                        /* use binary search for newly added edges
                               in crossings if arrays are large enough */
                        if (useBinarySearch && (i >= prevNumCrossings)) {
                            if (DO_STATS) {
                                rdrCtx.stats.stat_rdr_crossings_bsearch.add(i);
                            }
                            low = 0;
                            high = i - 1;
                            do {
                                // note: use signed shift (not >>>) for performance
                                // as indices are small enough to exceed Integer.MAX_VALUE
                                mid = (low + high) >> 1;
                                if (_crossings[mid] < cross) {
                                    low = mid + 1;
                                } else {
                                    high = mid - 1;
                                }
                            } while (low <= high);
                            for (j = i - 1; j >= low; j--) {
                                _crossings[j + 1] = _crossings[j];
                                _edgePtrs[j + 1] = _edgePtrs[j];
                            }
                            _crossings[low] = cross;
                            _edgePtrs[low] = ecur;
                        } else {
                            j = i - 1;
                            _crossings[i] = _crossings[j];
                            _edgePtrs[i] = _edgePtrs[j];
                            while ((--j >= 0) && (_crossings[j] > cross)) {
                                _crossings[j + 1] = _crossings[j];
                                _edgePtrs[j + 1] = _edgePtrs[j];
                            }
                            _crossings[j + 1] = cross;
                            _edgePtrs[j + 1] = ecur;
                        }
                    } else {
                        _crossings[i] = lastCross = cross;
                    }
                }
            } else {
                if (DO_STATS) {
                    rdrCtx.stats.stat_rdr_crossings_msorts.add(numCrossings);
                    rdrCtx.stats.hist_rdr_crossings_ratio.add((1000 * ptrLen) / numCrossings);
                    rdrCtx.stats.hist_rdr_crossings_msorts.add(numCrossings);
                    rdrCtx.stats.hist_rdr_crossings_msorts_adds.add(ptrLen);
                }
                // Copy sorted data in auxiliary arrays
                // and perform insertion sort on almost sorted data
                // (ie i < prevNumCrossings):
                lastCross = _MIN_VALUE;
                for (i = 0; i < numCrossings; i++) {
                    // get the pointer to the edge
                    ecur = _edgePtrs[i];
                    /* convert subpixel coordinates (float) into pixel
                            positions (int) for coming scanline */
                    /* note: it is faster to always update edges even
                           if it is removed from AEL for coming or last scanline */
                    // random access so use unsafe:
                    // ecur + OFF_F_CURX
                    addr = addr0 + ecur;
                    // get current crossing:
                    curx = _unsafe.getInt(addr);
                    // update crossing with orientation at last bit:
                    cross = curx;
                    // Increment x using DDA (fixed point):
                    curx += _unsafe.getInt(addr + _OFF_BUMP_X);
                    // Increment error:
                    err = _unsafe.getInt(addr + _OFF_ERROR) + _unsafe.getInt(addr + _OFF_BUMP_ERR);
                    // Manual carry handling:
                    // keep sign and carry bit only and ignore last bit (preserve orientation):
                    _unsafe.putInt(addr, curx - ((err >> 30) & _ALL_BUT_LSB));
                    _unsafe.putInt(addr + _OFF_ERROR, (err & _ERR_STEP_MAX));
                    if (DO_STATS) {
                        rdrCtx.stats.stat_rdr_crossings_updates.add(numCrossings);
                    }
                    if (i >= prevNumCrossings) {
                        // simply store crossing as edgePtrs is in-place:
                        // will be copied and sorted efficiently by mergesort later:
                        _crossings[i] = cross;
                    } else if (cross < lastCross) {
                        if (DO_STATS) {
                            rdrCtx.stats.stat_rdr_crossings_sorts.add(i);
                        }
                        // (straight) insertion sort of crossings:
                        j = i - 1;
                        _aux_crossings[i] = _aux_crossings[j];
                        _aux_edgePtrs[i] = _aux_edgePtrs[j];
                        while ((--j >= 0) && (_aux_crossings[j] > cross)) {
                            _aux_crossings[j + 1] = _aux_crossings[j];
                            _aux_edgePtrs[j + 1] = _aux_edgePtrs[j];
                        }
                        _aux_crossings[j + 1] = cross;
                        _aux_edgePtrs[j + 1] = ecur;
                    } else {
                        // auxiliary storage:
                        _aux_crossings[i] = lastCross = cross;
                        _aux_edgePtrs[i] = ecur;
                    }
                }
                // use Mergesort using auxiliary arrays (sort only right part)
                MergeSort.mergeSortNoCopy(_crossings, _edgePtrs, _aux_crossings, _aux_edgePtrs, numCrossings, prevNumCrossings);
            }
            // reset ptrLen
            ptrLen = 0;
            // --- from former ScanLineIterator.next()
            /* note: bboxx0 and bboxx1 must be pixel boundaries
                   to have correct coverage computation */
            // right shift on crossings to get the x-coordinate:
            curxo = _crossings[0];
            x0 = curxo >> 1;
            if (x0 < minX) {
                // subpixel coordinate
                minX = x0;
            }
            x1 = _crossings[numCrossings - 1] >> 1;
            if (x1 > maxX) {
                // subpixel coordinate
                maxX = x1;
            }
            // compute pixel coverages
            prev = curx = x0;
            // to turn {0, 1} into {-1, 1}, multiply by 2 and subtract 1.
            // last bit contains orientation (0 or 1)
            crorientation = ((curxo & 0x1) << 1) - 1;
            if (windingRuleEvenOdd) {
                sum = crorientation;
                // Even Odd winding rule: take care of mask ie sum(orientations)
                for (i = 1; i < numCrossings; i++) {
                    curxo = _crossings[i];
                    curx = curxo >> 1;
                    // to turn {0, 1} into {-1, 1}, multiply by 2 and subtract 1.
                    // last bit contains orientation (0 or 1)
                    crorientation = ((curxo & 0x1) << 1) - 1;
                    if ((sum & 0x1) != 0) {
                        // TODO: perform line clipping on left-right sides
                        // to avoid such bound checks:
                        x0 = (prev > bboxx0) ? prev : bboxx0;
                        x1 = (curx < bboxx1) ? curx : bboxx1;
                        if (x0 < x1) {
                            // turn x0, x1 from coords to indices
                            x0 -= bboxx0;
                            // in the alpha array.
                            x1 -= bboxx0;
                            pix_x = x0 >> _SUBPIXEL_LG_POSITIONS_X;
                            pix_xmaxm1 = (x1 - 1) >> _SUBPIXEL_LG_POSITIONS_X;
                            if (pix_x == pix_xmaxm1) {
                                // Start and end in same pixel
                                // number of subpixels
                                tmp = (x1 - x0);
                                _alpha[pix_x] += tmp;
                                _alpha[pix_x + 1] -= tmp;
                                if (useBlkFlags) {
                                    // flag used blocks:
                                    _blkFlags[pix_x >> _BLK_SIZE_LG] = 1;
                                }
                            } else {
                                tmp = (x0 & _SUBPIXEL_MASK_X);
                                _alpha[pix_x] += (_SUBPIXEL_POSITIONS_X - tmp);
                                _alpha[pix_x + 1] += tmp;
                                pix_xmax = x1 >> _SUBPIXEL_LG_POSITIONS_X;
                                tmp = (x1 & _SUBPIXEL_MASK_X);
                                _alpha[pix_xmax] -= (_SUBPIXEL_POSITIONS_X - tmp);
                                _alpha[pix_xmax + 1] -= tmp;
                                if (useBlkFlags) {
                                    // flag used blocks:
                                    _blkFlags[pix_x >> _BLK_SIZE_LG] = 1;
                                    _blkFlags[pix_xmax >> _BLK_SIZE_LG] = 1;
                                }
                            }
                        }
                    }
                    sum += crorientation;
                    prev = curx;
                }
            } else {
                // and avoid processing intermediate crossings
                for (i = 1, sum = 0; ; i++) {
                    sum += crorientation;
                    if (sum != 0) {
                        // prev = min(curx)
                        if (prev > curx) {
                            prev = curx;
                        }
                    } else {
                        // TODO: perform line clipping on left-right sides
                        // to avoid such bound checks:
                        x0 = (prev > bboxx0) ? prev : bboxx0;
                        x1 = (curx < bboxx1) ? curx : bboxx1;
                        if (x0 < x1) {
                            // turn x0, x1 from coords to indices
                            x0 -= bboxx0;
                            // in the alpha array.
                            x1 -= bboxx0;
                            pix_x = x0 >> _SUBPIXEL_LG_POSITIONS_X;
                            pix_xmaxm1 = (x1 - 1) >> _SUBPIXEL_LG_POSITIONS_X;
                            if (pix_x == pix_xmaxm1) {
                                // Start and end in same pixel
                                // number of subpixels
                                tmp = (x1 - x0);
                                _alpha[pix_x] += tmp;
                                _alpha[pix_x + 1] -= tmp;
                                if (useBlkFlags) {
                                    // flag used blocks:
                                    _blkFlags[pix_x >> _BLK_SIZE_LG] = 1;
                                }
                            } else {
                                tmp = (x0 & _SUBPIXEL_MASK_X);
                                _alpha[pix_x] += (_SUBPIXEL_POSITIONS_X - tmp);
                                _alpha[pix_x + 1] += tmp;
                                pix_xmax = x1 >> _SUBPIXEL_LG_POSITIONS_X;
                                tmp = (x1 & _SUBPIXEL_MASK_X);
                                _alpha[pix_xmax] -= (_SUBPIXEL_POSITIONS_X - tmp);
                                _alpha[pix_xmax + 1] -= tmp;
                                if (useBlkFlags) {
                                    // flag used blocks:
                                    _blkFlags[pix_x >> _BLK_SIZE_LG] = 1;
                                    _blkFlags[pix_xmax >> _BLK_SIZE_LG] = 1;
                                }
                            }
                        }
                        prev = _MAX_VALUE;
                    }
                    if (i == numCrossings) {
                        break;
                    }
                    curxo = _crossings[i];
                    curx = curxo >> 1;
                    // to turn {0, 1} into {-1, 1}, multiply by 2 and subtract 1.
                    // last bit contains orientation (0 or 1)
                    crorientation = ((curxo & 0x1) << 1) - 1;
                }
            }
        }
        // maxX < minX, so no row will be emitted to the MarlinCache.
        if ((y & _SUBPIXEL_MASK_Y) == _SUBPIXEL_MASK_Y) {
            lastY = y >> _SUBPIXEL_LG_POSITIONS_Y;
            // convert subpixel to pixel coordinate within boundaries:
            minX = FloatMath.max(minX, bboxx0) >> _SUBPIXEL_LG_POSITIONS_X;
            maxX = FloatMath.min(maxX, bboxx1) >> _SUBPIXEL_LG_POSITIONS_X;
            if (maxX >= minX) {
                // note: alpha array will be zeroed by copyAARow()
                // +2 because alpha [pix_minX; pix_maxX+1]
                // fix range [x0; x1[
                copyAARow(_alpha, lastY, minX, maxX + 2, useBlkFlags);
                // speculative for next pixel row (scanline coherence):
                if (_enableBlkFlagsHeuristics) {
                    // Use block flags if large pixel span and few crossings:
                    // ie mean(distance between crossings) is larger than
                    // 1 block size;
                    // fast check width:
                    maxX -= minX;
                    // if stroking: numCrossings /= 2
                    // => shift numCrossings by 1
                    // condition = (width / (numCrossings - 1)) > blockSize
                    useBlkFlags = (maxX > _BLK_SIZE) && (maxX > (((numCrossings >> stroking) - 1) << _BLK_SIZE_LG));
                    if (DO_STATS) {
                        tmp = FloatMath.max(1, ((numCrossings >> stroking) - 1));
                        rdrCtx.stats.hist_tile_generator_encoding_dist.add(maxX / tmp);
                    }
                }
            } else {
                _cache.clearAARow(lastY);
            }
            minX = _MAX_VALUE;
            maxX = _MIN_VALUE;
        }
    }
    // scan line iterator
    // Emit final row
    y--;
    y >>= _SUBPIXEL_LG_POSITIONS_Y;
    // convert subpixel to pixel coordinate within boundaries:
    minX = FloatMath.max(minX, bboxx0) >> _SUBPIXEL_LG_POSITIONS_X;
    maxX = FloatMath.min(maxX, bboxx1) >> _SUBPIXEL_LG_POSITIONS_X;
    if (maxX >= minX) {
        // note: alpha array will be zeroed by copyAARow()
        // +2 because alpha [pix_minX; pix_maxX+1]
        // fix range [x0; x1[
        copyAARow(_alpha, y, minX, maxX + 2, useBlkFlags);
    } else if (y != lastY) {
        _cache.clearAARow(y);
    }
    // update member:
    edgeCount = numCrossings;
    prevUseBlkFlags = useBlkFlags;
    if (DO_STATS) {
        // update max used mark
        activeEdgeMaxUsed = _arrayMaxUsed;
    }
}
Also used : Unsafe(sun.misc.Unsafe)

Aggregations

Unsafe (sun.misc.Unsafe)39 Field (java.lang.reflect.Field)29 PrivilegedExceptionAction (java.security.PrivilegedExceptionAction)5 PrivilegedActionException (java.security.PrivilegedActionException)4 PrivilegedAction (java.security.PrivilegedAction)2 File (java.io.File)1 Options (org.rocksdb.Options)1 RocksDB (org.rocksdb.RocksDB)1 RocksIterator (org.rocksdb.RocksIterator)1 StringAppendOperator (org.rocksdb.StringAppendOperator)1 WriteOptions (org.rocksdb.WriteOptions)1