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 |