231 final int w = width; 232 final int off = (pix_y - y) * w; 233 234 final Unsafe _unsafe = OffHeapArray.UNSAFE; 235 final long addr_alpha = ALPHA_MAP_USED.address; 236 237 final int from = pix_from - x; 238 239 // skip useless pixels above boundary 240 final int to = pix_to - x; 241 final int ato = Math.min(to, width); 242 243 // fast fill ? 244 final boolean fast = useFastFill && ((ato - from) < fastFillThreshold); 245 246 final int _BLK_SIZE_LG = MarlinConst.BLOCK_SIZE_LG; 247 248 // traverse flagged blocks: 249 final int blkW = (from >> _BLK_SIZE_LG); 250 final int blkE = (ato >> _BLK_SIZE_LG) + 1; 251 252 // Perform run-length encoding and store results in the piscesCache 253 int curAlpha = 0; 254 255 final int _MAX_VALUE = Integer.MAX_VALUE; 256 int last_t0 = _MAX_VALUE; 257 byte val; 258 259 if (fast) { 260 int i = from; 261 262 // Zero-fill complete row: 263 Arrays.fill(out, off, off + w, (byte) 0); 264 265 for (int t = blkW, blk_x0, blk_x1, cx, delta; t <= blkE; t++) { 266 if (blkFlags[t] != 0) { 267 blkFlags[t] = 0; 268 269 if (last_t0 == _MAX_VALUE) { 270 last_t0 = t; 273 } 274 if (last_t0 != _MAX_VALUE) { 275 // emit blocks: 276 blk_x0 = FloatMath.max(last_t0 << _BLK_SIZE_LG, from); 277 last_t0 = _MAX_VALUE; 278 279 // (last block pixel+1) inclusive => +1 280 blk_x1 = FloatMath.min((t << _BLK_SIZE_LG) + 1, ato); 281 282 for (cx = blk_x0; cx < blk_x1; cx++) { 283 if ((delta = alphaDeltas[cx]) != 0) { 284 alphaDeltas[cx] = 0; 285 286 // fill span: 287 if (cx != i) { 288 // skip alpha = 0 289 if (curAlpha == 0) { 290 i = cx; 291 } else { 292 val = _unsafe.getByte(addr_alpha + curAlpha); 293 294 do { 295 out[off + i] = val; 296 i++; 297 } while (i < cx); 298 } 299 } 300 301 // alpha value = running sum of coverage delta: 302 curAlpha += delta; 303 } 304 } 305 } 306 } 307 308 // Process remaining span: 309 val = _unsafe.getByte(addr_alpha + curAlpha); 310 311 do { 312 out[off + i] = val; 313 i++; 314 } while (i < ato); 315 316 } else { 317 int i = 0; 318 319 while (i < from) { 320 out[off + i] = 0; 321 i++; 322 } 323 324 for (int t = blkW, blk_x0, blk_x1, cx, delta; t <= blkE; t++) { 325 if (blkFlags[t] != 0) { 326 blkFlags[t] = 0; 327 328 if (last_t0 == _MAX_VALUE) { 329 last_t0 = t; 330 } 331 continue; 332 } 333 if (last_t0 != _MAX_VALUE) { 334 // emit blocks: 335 blk_x0 = FloatMath.max(last_t0 << _BLK_SIZE_LG, from); 336 last_t0 = _MAX_VALUE; 337 338 // (last block pixel+1) inclusive => +1 339 blk_x1 = FloatMath.min((t << _BLK_SIZE_LG) + 1, ato); 340 341 for (cx = blk_x0; cx < blk_x1; cx++) { 342 if ((delta = alphaDeltas[cx]) != 0) { 343 alphaDeltas[cx] = 0; 344 345 // fill span: 346 if (cx != i) { 347 val = _unsafe.getByte(addr_alpha + curAlpha); 348 349 do { 350 out[off + i] = val; 351 i++; 352 } while (i < cx); 353 } 354 355 // alpha value = running sum of coverage delta: 356 curAlpha += delta; 357 } 358 } 359 } 360 } 361 362 // Process remaining span: 363 val = _unsafe.getByte(addr_alpha + curAlpha); 364 365 do { 366 out[off + i] = val; 367 i++; 368 } while (i < ato); 369 370 while (i < w) { 371 out[off + i] = 0; 372 i++; 373 } 374 } 375 376 // Clear alpha row for reuse: 377 alphaDeltas[ato] = 0; 378 379 if (MarlinConst.DO_CHECKS) { 380 IntArrayCache.check(blkFlags, blkW, blkE, 0); 381 IntArrayCache.check(alphaDeltas, from, to + 1, 0); 382 } 383 } 384 } | 231 final int w = width; 232 final int off = (pix_y - y) * w; 233 234 final Unsafe _unsafe = OffHeapArray.UNSAFE; 235 final long addr_alpha = ALPHA_MAP_USED.address; 236 237 final int from = pix_from - x; 238 239 // skip useless pixels above boundary 240 final int to = pix_to - x; 241 final int ato = Math.min(to, width); 242 243 // fast fill ? 244 final boolean fast = useFastFill && ((ato - from) < fastFillThreshold); 245 246 final int _BLK_SIZE_LG = MarlinConst.BLOCK_SIZE_LG; 247 248 // traverse flagged blocks: 249 final int blkW = (from >> _BLK_SIZE_LG); 250 final int blkE = (ato >> _BLK_SIZE_LG) + 1; 251 // ensure last block flag = 0 to process final block: 252 blkFlags[blkE] = 0; 253 254 // Perform run-length encoding and store results in the piscesCache 255 int curAlpha = 0; 256 257 final int _MAX_VALUE = Integer.MAX_VALUE; 258 int last_t0 = _MAX_VALUE; 259 byte val; 260 261 if (fast) { 262 int i = from; 263 264 // Zero-fill complete row: 265 Arrays.fill(out, off, off + w, (byte) 0); 266 267 for (int t = blkW, blk_x0, blk_x1, cx, delta; t <= blkE; t++) { 268 if (blkFlags[t] != 0) { 269 blkFlags[t] = 0; 270 271 if (last_t0 == _MAX_VALUE) { 272 last_t0 = t; 275 } 276 if (last_t0 != _MAX_VALUE) { 277 // emit blocks: 278 blk_x0 = FloatMath.max(last_t0 << _BLK_SIZE_LG, from); 279 last_t0 = _MAX_VALUE; 280 281 // (last block pixel+1) inclusive => +1 282 blk_x1 = FloatMath.min((t << _BLK_SIZE_LG) + 1, ato); 283 284 for (cx = blk_x0; cx < blk_x1; cx++) { 285 if ((delta = alphaDeltas[cx]) != 0) { 286 alphaDeltas[cx] = 0; 287 288 // fill span: 289 if (cx != i) { 290 // skip alpha = 0 291 if (curAlpha == 0) { 292 i = cx; 293 } else { 294 val = _unsafe.getByte(addr_alpha + curAlpha); 295 do { 296 out[off + i] = val; 297 i++; 298 } while (i < cx); 299 } 300 } 301 302 // alpha value = running sum of coverage delta: 303 curAlpha += delta; 304 } 305 } 306 } 307 } 308 309 // Process remaining span: 310 if (curAlpha != 0) { 311 val = _unsafe.getByte(addr_alpha + curAlpha); 312 while (i < ato) { 313 out[off + i] = val; 314 i++; 315 } 316 } 317 318 } else { 319 int i = 0; 320 321 while (i < from) { 322 out[off + i] = 0; 323 i++; 324 } 325 326 for (int t = blkW, blk_x0, blk_x1, cx, delta; t <= blkE; t++) { 327 if (blkFlags[t] != 0) { 328 blkFlags[t] = 0; 329 330 if (last_t0 == _MAX_VALUE) { 331 last_t0 = t; 332 } 333 continue; 334 } 335 if (last_t0 != _MAX_VALUE) { 336 // emit blocks: 337 blk_x0 = FloatMath.max(last_t0 << _BLK_SIZE_LG, from); 338 last_t0 = _MAX_VALUE; 339 340 // (last block pixel+1) inclusive => +1 341 blk_x1 = FloatMath.min((t << _BLK_SIZE_LG) + 1, ato); 342 343 for (cx = blk_x0; cx < blk_x1; cx++) { 344 if ((delta = alphaDeltas[cx]) != 0) { 345 alphaDeltas[cx] = 0; 346 347 // fill span: 348 if (cx != i) { 349 val = _unsafe.getByte(addr_alpha + curAlpha); 350 do { 351 out[off + i] = val; 352 i++; 353 } while (i < cx); 354 } 355 356 // alpha value = running sum of coverage delta: 357 curAlpha += delta; 358 } 359 } 360 } 361 } 362 363 // Process remaining span: 364 if (curAlpha != 0) { 365 val = _unsafe.getByte(addr_alpha + curAlpha); 366 while (i < ato) { 367 out[off + i] = val; 368 i++; 369 } 370 } 371 372 while (i < w) { 373 out[off + i] = 0; 374 i++; 375 } 376 } 377 378 // Clear alpha row for reuse: 379 alphaDeltas[ato] = 0; 380 381 if (MarlinConst.DO_CHECKS) { 382 IntArrayCache.check(blkFlags, blkW, blkE, 0); 383 IntArrayCache.check(alphaDeltas, from, to + 1, 0); 384 } 385 } 386 } |