| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "SkPictureRecord.h" | 8 #include "SkPictureRecord.h" |
| 9 #include "SkTSearch.h" | 9 #include "SkTSearch.h" |
| 10 #include "SkPixelRef.h" | 10 #include "SkPixelRef.h" |
| (...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 219 return fMCMgr.isDrawingToLayer(); | 219 return fMCMgr.isDrawingToLayer(); |
| 220 #else | 220 #else |
| 221 return fFirstSavedLayerIndex != kNoSavedLayerIndex; | 221 return fFirstSavedLayerIndex != kNoSavedLayerIndex; |
| 222 #endif | 222 #endif |
| 223 } | 223 } |
| 224 | 224 |
| 225 /* | 225 /* |
| 226 * Read the op code from 'offset' in 'writer' and extract the size too. | 226 * Read the op code from 'offset' in 'writer' and extract the size too. |
| 227 */ | 227 */ |
| 228 static DrawType peek_op_and_size(SkWriter32* writer, int32_t offset, uint32_t* s
ize) { | 228 static DrawType peek_op_and_size(SkWriter32* writer, int32_t offset, uint32_t* s
ize) { |
| 229 uint32_t peek = writer->read32At(offset); | 229 uint32_t peek = writer->readTAt<uint32_t>(offset); |
| 230 | 230 |
| 231 uint32_t op; | 231 uint32_t op; |
| 232 UNPACK_8_24(peek, op, *size); | 232 UNPACK_8_24(peek, op, *size); |
| 233 if (MASK_24 == *size) { | 233 if (MASK_24 == *size) { |
| 234 // size required its own slot right after the op code | 234 // size required its own slot right after the op code |
| 235 *size = writer->read32At(offset+kUInt32Size); | 235 *size = writer->readTAt<uint32_t>(offset + kUInt32Size); |
| 236 } | 236 } |
| 237 return (DrawType) op; | 237 return (DrawType) op; |
| 238 } | 238 } |
| 239 | 239 |
| 240 #ifdef TRACK_COLLAPSE_STATS | 240 #ifdef TRACK_COLLAPSE_STATS |
| 241 static int gCollapseCount, gCollapseCalls; | 241 static int gCollapseCount, gCollapseCalls; |
| 242 #endif | 242 #endif |
| 243 | 243 |
| 244 // Is the supplied paint simply a color? | 244 // Is the supplied paint simply a color? |
| 245 static bool is_simple(const SkPaint& p) { | 245 static bool is_simple(const SkPaint& p) { |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 328 * SAVE_LAYER | 328 * SAVE_LAYER |
| 329 * DRAW_BITMAP|DRAW_BITMAP_MATRIX|DRAW_BITMAP_NINE|DRAW_BITMAP_RECT_TO_REC
T | 329 * DRAW_BITMAP|DRAW_BITMAP_MATRIX|DRAW_BITMAP_NINE|DRAW_BITMAP_RECT_TO_REC
T |
| 330 * RESTORE | 330 * RESTORE |
| 331 * where the saveLayer's color can be moved into the drawBitmap*'s paint | 331 * where the saveLayer's color can be moved into the drawBitmap*'s paint |
| 332 */ | 332 */ |
| 333 static bool remove_save_layer1(SkWriter32* writer, int32_t offset, | 333 static bool remove_save_layer1(SkWriter32* writer, int32_t offset, |
| 334 SkPaintDictionary* paintDict) { | 334 SkPaintDictionary* paintDict) { |
| 335 // back up to the save block | 335 // back up to the save block |
| 336 // TODO: add a stack to track save*/restore offsets rather than searching ba
ckwards | 336 // TODO: add a stack to track save*/restore offsets rather than searching ba
ckwards |
| 337 while (offset > 0) { | 337 while (offset > 0) { |
| 338 offset = writer->read32At(offset); | 338 offset = writer->readTAt<uint32_t>(offset); |
| 339 } | 339 } |
| 340 | 340 |
| 341 int pattern[] = { SAVE_LAYER, kDRAW_BITMAP_FLAVOR, /* RESTORE */ }; | 341 int pattern[] = { SAVE_LAYER, kDRAW_BITMAP_FLAVOR, /* RESTORE */ }; |
| 342 CommandInfo result[SK_ARRAY_COUNT(pattern)]; | 342 CommandInfo result[SK_ARRAY_COUNT(pattern)]; |
| 343 | 343 |
| 344 if (!match(writer, -offset, pattern, result, SK_ARRAY_COUNT(pattern))) { | 344 if (!match(writer, -offset, pattern, result, SK_ARRAY_COUNT(pattern))) { |
| 345 return false; | 345 return false; |
| 346 } | 346 } |
| 347 | 347 |
| 348 if (kSaveLayerWithBoundsSize == result[0].fSize) { | 348 if (kSaveLayerWithBoundsSize == result[0].fSize) { |
| 349 // The saveLayer's bound can offset where the dbm is drawn | 349 // The saveLayer's bound can offset where the dbm is drawn |
| 350 return false; | 350 return false; |
| 351 } | 351 } |
| 352 | 352 |
| 353 return merge_savelayer_paint_into_drawbitmp(writer, paintDict, | 353 return merge_savelayer_paint_into_drawbitmp(writer, paintDict, |
| 354 result[0], result[1]); | 354 result[0], result[1]); |
| 355 } | 355 } |
| 356 | 356 |
| 357 /* | 357 /* |
| 358 * Convert the command code located at 'offset' to a NOOP. Leave the size | 358 * Convert the command code located at 'offset' to a NOOP. Leave the size |
| 359 * field alone so the NOOP can be skipped later. | 359 * field alone so the NOOP can be skipped later. |
| 360 */ | 360 */ |
| 361 static void convert_command_to_noop(SkWriter32* writer, uint32_t offset) { | 361 static void convert_command_to_noop(SkWriter32* writer, uint32_t offset) { |
| 362 uint32_t command = writer->read32At(offset); | 362 uint32_t command = writer->readTAt<uint32_t>(offset); |
| 363 writer->write32At(offset, (command & MASK_24) | (NOOP << 24)); | 363 writer->overwriteTAt(offset, (command & MASK_24) | (NOOP << 24)); |
| 364 } | 364 } |
| 365 | 365 |
| 366 /* | 366 /* |
| 367 * Attempt to merge the saveLayer's paint into the drawBitmap*'s paint. | 367 * Attempt to merge the saveLayer's paint into the drawBitmap*'s paint. |
| 368 * Return true on success; false otherwise. | 368 * Return true on success; false otherwise. |
| 369 */ | 369 */ |
| 370 static bool merge_savelayer_paint_into_drawbitmp(SkWriter32* writer, | 370 static bool merge_savelayer_paint_into_drawbitmp(SkWriter32* writer, |
| 371 SkPaintDictionary* paintDict, | 371 SkPaintDictionary* paintDict, |
| 372 const CommandInfo& saveLayerInf
o, | 372 const CommandInfo& saveLayerInf
o, |
| 373 const CommandInfo& dbmInfo) { | 373 const CommandInfo& dbmInfo) { |
| 374 SkASSERT(SAVE_LAYER == saveLayerInfo.fActualOp); | 374 SkASSERT(SAVE_LAYER == saveLayerInfo.fActualOp); |
| 375 SkASSERT(DRAW_BITMAP == dbmInfo.fActualOp || | 375 SkASSERT(DRAW_BITMAP == dbmInfo.fActualOp || |
| 376 DRAW_BITMAP_MATRIX == dbmInfo.fActualOp || | 376 DRAW_BITMAP_MATRIX == dbmInfo.fActualOp || |
| 377 DRAW_BITMAP_NINE == dbmInfo.fActualOp || | 377 DRAW_BITMAP_NINE == dbmInfo.fActualOp || |
| 378 DRAW_BITMAP_RECT_TO_RECT == dbmInfo.fActualOp); | 378 DRAW_BITMAP_RECT_TO_RECT == dbmInfo.fActualOp); |
| 379 | 379 |
| 380 uint32_t dbmPaintOffset = getPaintOffset(dbmInfo.fActualOp, dbmInfo.fSize); | 380 uint32_t dbmPaintOffset = getPaintOffset(dbmInfo.fActualOp, dbmInfo.fSize); |
| 381 uint32_t slPaintOffset = getPaintOffset(SAVE_LAYER, saveLayerInfo.fSize); | 381 uint32_t slPaintOffset = getPaintOffset(SAVE_LAYER, saveLayerInfo.fSize); |
| 382 | 382 |
| 383 // we have a match, now we need to get the paints involved | 383 // we have a match, now we need to get the paints involved |
| 384 uint32_t dbmPaintId = writer->read32At(dbmInfo.fOffset+dbmPaintOffset); | 384 uint32_t dbmPaintId = writer->readTAt<uint32_t>(dbmInfo.fOffset + dbmPaintOf
fset); |
| 385 uint32_t saveLayerPaintId = writer->read32At(saveLayerInfo.fOffset+slPaintOf
fset); | 385 uint32_t saveLayerPaintId = writer->readTAt<uint32_t>(saveLayerInfo.fOffset
+ slPaintOffset); |
| 386 | 386 |
| 387 if (0 == saveLayerPaintId) { | 387 if (0 == saveLayerPaintId) { |
| 388 // In this case the saveLayer/restore isn't needed at all - just kill th
e saveLayer | 388 // In this case the saveLayer/restore isn't needed at all - just kill th
e saveLayer |
| 389 // and signal the caller (by returning true) to not add the RESTORE op | 389 // and signal the caller (by returning true) to not add the RESTORE op |
| 390 convert_command_to_noop(writer, saveLayerInfo.fOffset); | 390 convert_command_to_noop(writer, saveLayerInfo.fOffset); |
| 391 return true; | 391 return true; |
| 392 } | 392 } |
| 393 | 393 |
| 394 if (0 == dbmPaintId) { | 394 if (0 == dbmPaintId) { |
| 395 // In this case just make the DBM* use the saveLayer's paint, kill the s
aveLayer | 395 // In this case just make the DBM* use the saveLayer's paint, kill the s
aveLayer |
| 396 // and signal the caller (by returning true) to not add the RESTORE op | 396 // and signal the caller (by returning true) to not add the RESTORE op |
| 397 convert_command_to_noop(writer, saveLayerInfo.fOffset); | 397 convert_command_to_noop(writer, saveLayerInfo.fOffset); |
| 398 writer->write32At(dbmInfo.fOffset+dbmPaintOffset, saveLayerPaintId); | 398 writer->overwriteTAt(dbmInfo.fOffset + dbmPaintOffset, saveLayerPaintId)
; |
| 399 return true; | 399 return true; |
| 400 } | 400 } |
| 401 | 401 |
| 402 SkAutoTDelete<SkPaint> saveLayerPaint(paintDict->unflatten(saveLayerPaintId)
); | 402 SkAutoTDelete<SkPaint> saveLayerPaint(paintDict->unflatten(saveLayerPaintId)
); |
| 403 if (NULL == saveLayerPaint.get() || !is_simple(*saveLayerPaint)) { | 403 if (NULL == saveLayerPaint.get() || !is_simple(*saveLayerPaint)) { |
| 404 return false; | 404 return false; |
| 405 } | 405 } |
| 406 | 406 |
| 407 // For this optimization we only fold the saveLayer and drawBitmapRect | 407 // For this optimization we only fold the saveLayer and drawBitmapRect |
| 408 // together if the saveLayer's draw is simple (i.e., no fancy effects) and | 408 // together if the saveLayer's draw is simple (i.e., no fancy effects) and |
| (...skipping 12 matching lines...) Expand all Loading... |
| 421 SkColorGetA(saveLayerPaint->getColor())); | 421 SkColorGetA(saveLayerPaint->getColor())); |
| 422 dbmPaint->setColor(newColor); | 422 dbmPaint->setColor(newColor); |
| 423 | 423 |
| 424 const SkFlatData* data = paintDict->findAndReturnFlat(*dbmPaint); | 424 const SkFlatData* data = paintDict->findAndReturnFlat(*dbmPaint); |
| 425 if (NULL == data) { | 425 if (NULL == data) { |
| 426 return false; | 426 return false; |
| 427 } | 427 } |
| 428 | 428 |
| 429 // kill the saveLayer and alter the DBMR2R's paint to be the modified one | 429 // kill the saveLayer and alter the DBMR2R's paint to be the modified one |
| 430 convert_command_to_noop(writer, saveLayerInfo.fOffset); | 430 convert_command_to_noop(writer, saveLayerInfo.fOffset); |
| 431 writer->write32At(dbmInfo.fOffset+dbmPaintOffset, data->index()); | 431 writer->overwriteTAt(dbmInfo.fOffset + dbmPaintOffset, data->index()); |
| 432 return true; | 432 return true; |
| 433 } | 433 } |
| 434 | 434 |
| 435 /* | 435 /* |
| 436 * Restore has just been called (but not recorded), look back at the | 436 * Restore has just been called (but not recorded), look back at the |
| 437 * matching save* and see if we are in the configuration: | 437 * matching save* and see if we are in the configuration: |
| 438 * SAVE_LAYER (with NULL == bounds) | 438 * SAVE_LAYER (with NULL == bounds) |
| 439 * SAVE | 439 * SAVE |
| 440 * CLIP_RECT | 440 * CLIP_RECT |
| 441 * DRAW_BITMAP|DRAW_BITMAP_MATRIX|DRAW_BITMAP_NINE|DRAW_BITMAP_RECT_TO_R
ECT | 441 * DRAW_BITMAP|DRAW_BITMAP_MATRIX|DRAW_BITMAP_NINE|DRAW_BITMAP_RECT_TO_R
ECT |
| 442 * RESTORE | 442 * RESTORE |
| 443 * RESTORE | 443 * RESTORE |
| 444 * where the saveLayer's color can be moved into the drawBitmap*'s paint | 444 * where the saveLayer's color can be moved into the drawBitmap*'s paint |
| 445 */ | 445 */ |
| 446 static bool remove_save_layer2(SkWriter32* writer, int32_t offset, | 446 static bool remove_save_layer2(SkWriter32* writer, int32_t offset, |
| 447 SkPaintDictionary* paintDict) { | 447 SkPaintDictionary* paintDict) { |
| 448 | 448 |
| 449 // back up to the save block | 449 // back up to the save block |
| 450 // TODO: add a stack to track save*/restore offsets rather than searching ba
ckwards | 450 // TODO: add a stack to track save*/restore offsets rather than searching ba
ckwards |
| 451 while (offset > 0) { | 451 while (offset > 0) { |
| 452 offset = writer->read32At(offset); | 452 offset = writer->readTAt<uint32_t>(offset); |
| 453 } | 453 } |
| 454 | 454 |
| 455 int pattern[] = { SAVE_LAYER, SAVE, CLIP_RECT, kDRAW_BITMAP_FLAVOR, RESTORE,
/* RESTORE */ }; | 455 int pattern[] = { SAVE_LAYER, SAVE, CLIP_RECT, kDRAW_BITMAP_FLAVOR, RESTORE,
/* RESTORE */ }; |
| 456 CommandInfo result[SK_ARRAY_COUNT(pattern)]; | 456 CommandInfo result[SK_ARRAY_COUNT(pattern)]; |
| 457 | 457 |
| 458 if (!match(writer, -offset, pattern, result, SK_ARRAY_COUNT(pattern))) { | 458 if (!match(writer, -offset, pattern, result, SK_ARRAY_COUNT(pattern))) { |
| 459 return false; | 459 return false; |
| 460 } | 460 } |
| 461 | 461 |
| 462 if (kSaveLayerWithBoundsSize == result[0].fSize) { | 462 if (kSaveLayerWithBoundsSize == result[0].fSize) { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 479 static bool collapse_save_clip_restore(SkWriter32* writer, int32_t offset, | 479 static bool collapse_save_clip_restore(SkWriter32* writer, int32_t offset, |
| 480 SkPaintDictionary* paintDict) { | 480 SkPaintDictionary* paintDict) { |
| 481 #ifdef TRACK_COLLAPSE_STATS | 481 #ifdef TRACK_COLLAPSE_STATS |
| 482 gCollapseCalls += 1; | 482 gCollapseCalls += 1; |
| 483 #endif | 483 #endif |
| 484 | 484 |
| 485 int32_t restoreOffset = (int32_t)writer->bytesWritten(); | 485 int32_t restoreOffset = (int32_t)writer->bytesWritten(); |
| 486 | 486 |
| 487 // back up to the save block | 487 // back up to the save block |
| 488 while (offset > 0) { | 488 while (offset > 0) { |
| 489 offset = writer->read32At(offset); | 489 offset = writer->readTAt<uint32_t>(offset); |
| 490 } | 490 } |
| 491 | 491 |
| 492 // now offset points to a save | 492 // now offset points to a save |
| 493 offset = -offset; | 493 offset = -offset; |
| 494 uint32_t opSize; | 494 uint32_t opSize; |
| 495 DrawType op = peek_op_and_size(writer, offset, &opSize); | 495 DrawType op = peek_op_and_size(writer, offset, &opSize); |
| 496 if (SAVE_LAYER == op) { | 496 if (SAVE_LAYER == op) { |
| 497 // not ready to cull these out yet (mrr) | 497 // not ready to cull these out yet (mrr) |
| 498 return false; | 498 return false; |
| 499 } | 499 } |
| 500 SkASSERT(SAVE == op); | 500 SkASSERT(SAVE == op); |
| 501 SkASSERT(kSaveSize == opSize); | 501 SkASSERT(kSaveSize == opSize); |
| 502 | 502 |
| 503 // get the save flag (last 4-bytes of the space allocated for the opSize) | 503 // get the save flag (last 4-bytes of the space allocated for the opSize) |
| 504 SkCanvas::SaveFlags saveFlags = (SkCanvas::SaveFlags) writer->read32At(offse
t+4); | 504 SkCanvas::SaveFlags saveFlags = (SkCanvas::SaveFlags) writer->readTAt<uint32
_t>(offset + 4); |
| 505 if (SkCanvas::kMatrixClip_SaveFlag != saveFlags) { | 505 if (SkCanvas::kMatrixClip_SaveFlag != saveFlags) { |
| 506 // This function's optimization is only correct for kMatrixClip style sa
ves. | 506 // This function's optimization is only correct for kMatrixClip style sa
ves. |
| 507 // TODO: set checkMatrix & checkClip booleans here and then check for th
e | 507 // TODO: set checkMatrix & checkClip booleans here and then check for th
e |
| 508 // offending operations in the following loop. | 508 // offending operations in the following loop. |
| 509 return false; | 509 return false; |
| 510 } | 510 } |
| 511 | 511 |
| 512 // Walk forward until we get back to either a draw-verb (abort) or we hit | 512 // Walk forward until we get back to either a draw-verb (abort) or we hit |
| 513 // our restore (success). | 513 // our restore (success). |
| 514 int32_t saveOffset = offset; | 514 int32_t saveOffset = offset; |
| (...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 762 } | 762 } |
| 763 | 763 |
| 764 #ifdef SK_COLLAPSE_MATRIX_CLIP_STATE | 764 #ifdef SK_COLLAPSE_MATRIX_CLIP_STATE |
| 765 void SkPictureRecord::fillRestoreOffsetPlaceholdersForCurrentStackLevel(uint32_t
restoreOffset) { | 765 void SkPictureRecord::fillRestoreOffsetPlaceholdersForCurrentStackLevel(uint32_t
restoreOffset) { |
| 766 fMCMgr.fillInSkips(&fWriter, restoreOffset); | 766 fMCMgr.fillInSkips(&fWriter, restoreOffset); |
| 767 } | 767 } |
| 768 #else | 768 #else |
| 769 void SkPictureRecord::fillRestoreOffsetPlaceholdersForCurrentStackLevel(uint32_t
restoreOffset) { | 769 void SkPictureRecord::fillRestoreOffsetPlaceholdersForCurrentStackLevel(uint32_t
restoreOffset) { |
| 770 int32_t offset = fRestoreOffsetStack.top(); | 770 int32_t offset = fRestoreOffsetStack.top(); |
| 771 while (offset > 0) { | 771 while (offset > 0) { |
| 772 uint32_t peek = fWriter.read32At(offset); | 772 uint32_t peek = fWriter.readTAt<uint32_t>(offset); |
| 773 fWriter.write32At(offset, restoreOffset); | 773 fWriter.overwriteTAt(offset, restoreOffset); |
| 774 offset = peek; | 774 offset = peek; |
| 775 } | 775 } |
| 776 | 776 |
| 777 #ifdef SK_DEBUG | 777 #ifdef SK_DEBUG |
| 778 // assert that the final offset value points to a save verb | 778 // assert that the final offset value points to a save verb |
| 779 uint32_t opSize; | 779 uint32_t opSize; |
| 780 DrawType drawOp = peek_op_and_size(&fWriter, -offset, &opSize); | 780 DrawType drawOp = peek_op_and_size(&fWriter, -offset, &opSize); |
| 781 SkASSERT(SAVE == drawOp || SAVE_LAYER == drawOp); | 781 SkASSERT(SAVE == drawOp || SAVE_LAYER == drawOp); |
| 782 #endif | 782 #endif |
| 783 } | 783 } |
| (...skipping 994 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1778 void SkPictureRecord::validateRegions() const { | 1778 void SkPictureRecord::validateRegions() const { |
| 1779 int count = fRegions.count(); | 1779 int count = fRegions.count(); |
| 1780 SkASSERT((unsigned) count < 0x1000); | 1780 SkASSERT((unsigned) count < 0x1000); |
| 1781 for (int index = 0; index < count; index++) { | 1781 for (int index = 0; index < count; index++) { |
| 1782 const SkFlatData* region = fRegions[index]; | 1782 const SkFlatData* region = fRegions[index]; |
| 1783 SkASSERT(region); | 1783 SkASSERT(region); |
| 1784 // region->validate(); | 1784 // region->validate(); |
| 1785 } | 1785 } |
| 1786 } | 1786 } |
| 1787 #endif | 1787 #endif |
| OLD | NEW |