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 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
198 } | 198 } |
199 | 199 |
200 bool SkPictureRecord::isDrawingToLayer() const { | 200 bool SkPictureRecord::isDrawingToLayer() const { |
201 return fFirstSavedLayerIndex != kNoSavedLayerIndex; | 201 return fFirstSavedLayerIndex != kNoSavedLayerIndex; |
202 } | 202 } |
203 | 203 |
204 /* | 204 /* |
205 * Read the op code from 'offset' in 'writer' and extract the size too. | 205 * Read the op code from 'offset' in 'writer' and extract the size too. |
206 */ | 206 */ |
207 static DrawType peek_op_and_size(SkWriter32* writer, int32_t offset, uint32_t* s
ize) { | 207 static DrawType peek_op_and_size(SkWriter32* writer, int32_t offset, uint32_t* s
ize) { |
208 uint32_t peek = writer->read32At(offset); | 208 uint32_t peek = writer->readTAt<uint32_t>(offset); |
209 | 209 |
210 uint32_t op; | 210 uint32_t op; |
211 UNPACK_8_24(peek, op, *size); | 211 UNPACK_8_24(peek, op, *size); |
212 if (MASK_24 == *size) { | 212 if (MASK_24 == *size) { |
213 // size required its own slot right after the op code | 213 // size required its own slot right after the op code |
214 *size = writer->read32At(offset+kUInt32Size); | 214 *size = writer->readTAt<uint32_t>(offset + kUInt32Size); |
215 } | 215 } |
216 return (DrawType) op; | 216 return (DrawType) op; |
217 } | 217 } |
218 | 218 |
219 #ifdef TRACK_COLLAPSE_STATS | 219 #ifdef TRACK_COLLAPSE_STATS |
220 static int gCollapseCount, gCollapseCalls; | 220 static int gCollapseCount, gCollapseCalls; |
221 #endif | 221 #endif |
222 | 222 |
223 // Is the supplied paint simply a color? | 223 // Is the supplied paint simply a color? |
224 static bool is_simple(const SkPaint& p) { | 224 static bool is_simple(const SkPaint& p) { |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
307 * SAVE_LAYER | 307 * SAVE_LAYER |
308 * DRAW_BITMAP|DRAW_BITMAP_MATRIX|DRAW_BITMAP_NINE|DRAW_BITMAP_RECT_TO_REC
T | 308 * DRAW_BITMAP|DRAW_BITMAP_MATRIX|DRAW_BITMAP_NINE|DRAW_BITMAP_RECT_TO_REC
T |
309 * RESTORE | 309 * RESTORE |
310 * where the saveLayer's color can be moved into the drawBitmap*'s paint | 310 * where the saveLayer's color can be moved into the drawBitmap*'s paint |
311 */ | 311 */ |
312 static bool remove_save_layer1(SkWriter32* writer, int32_t offset, | 312 static bool remove_save_layer1(SkWriter32* writer, int32_t offset, |
313 SkPaintDictionary* paintDict) { | 313 SkPaintDictionary* paintDict) { |
314 // back up to the save block | 314 // back up to the save block |
315 // TODO: add a stack to track save*/restore offsets rather than searching ba
ckwards | 315 // TODO: add a stack to track save*/restore offsets rather than searching ba
ckwards |
316 while (offset > 0) { | 316 while (offset > 0) { |
317 offset = writer->read32At(offset); | 317 offset = writer->readTAt<uint32_t>(offset); |
318 } | 318 } |
319 | 319 |
320 int pattern[] = { SAVE_LAYER, kDRAW_BITMAP_FLAVOR, /* RESTORE */ }; | 320 int pattern[] = { SAVE_LAYER, kDRAW_BITMAP_FLAVOR, /* RESTORE */ }; |
321 CommandInfo result[SK_ARRAY_COUNT(pattern)]; | 321 CommandInfo result[SK_ARRAY_COUNT(pattern)]; |
322 | 322 |
323 if (!match(writer, -offset, pattern, result, SK_ARRAY_COUNT(pattern))) { | 323 if (!match(writer, -offset, pattern, result, SK_ARRAY_COUNT(pattern))) { |
324 return false; | 324 return false; |
325 } | 325 } |
326 | 326 |
327 if (kSaveLayerWithBoundsSize == result[0].fSize) { | 327 if (kSaveLayerWithBoundsSize == result[0].fSize) { |
328 // The saveLayer's bound can offset where the dbm is drawn | 328 // The saveLayer's bound can offset where the dbm is drawn |
329 return false; | 329 return false; |
330 } | 330 } |
331 | 331 |
332 return merge_savelayer_paint_into_drawbitmp(writer, paintDict, | 332 return merge_savelayer_paint_into_drawbitmp(writer, paintDict, |
333 result[0], result[1]); | 333 result[0], result[1]); |
334 } | 334 } |
335 | 335 |
336 /* | 336 /* |
337 * Convert the command code located at 'offset' to a NOOP. Leave the size | 337 * Convert the command code located at 'offset' to a NOOP. Leave the size |
338 * field alone so the NOOP can be skipped later. | 338 * field alone so the NOOP can be skipped later. |
339 */ | 339 */ |
340 static void convert_command_to_noop(SkWriter32* writer, uint32_t offset) { | 340 static void convert_command_to_noop(SkWriter32* writer, uint32_t offset) { |
341 uint32_t command = writer->read32At(offset); | 341 uint32_t command = writer->readTAt<uint32_t>(offset); |
342 writer->write32At(offset, (command & MASK_24) | (NOOP << 24)); | 342 writer->overwriteTAt((command & MASK_24) | (NOOP << 24), offset); |
343 } | 343 } |
344 | 344 |
345 /* | 345 /* |
346 * Attempt to merge the saveLayer's paint into the drawBitmap*'s paint. | 346 * Attempt to merge the saveLayer's paint into the drawBitmap*'s paint. |
347 * Return true on success; false otherwise. | 347 * Return true on success; false otherwise. |
348 */ | 348 */ |
349 static bool merge_savelayer_paint_into_drawbitmp(SkWriter32* writer, | 349 static bool merge_savelayer_paint_into_drawbitmp(SkWriter32* writer, |
350 SkPaintDictionary* paintDict, | 350 SkPaintDictionary* paintDict, |
351 const CommandInfo& saveLayerInf
o, | 351 const CommandInfo& saveLayerInf
o, |
352 const CommandInfo& dbmInfo) { | 352 const CommandInfo& dbmInfo) { |
353 SkASSERT(SAVE_LAYER == saveLayerInfo.fActualOp); | 353 SkASSERT(SAVE_LAYER == saveLayerInfo.fActualOp); |
354 SkASSERT(DRAW_BITMAP == dbmInfo.fActualOp || | 354 SkASSERT(DRAW_BITMAP == dbmInfo.fActualOp || |
355 DRAW_BITMAP_MATRIX == dbmInfo.fActualOp || | 355 DRAW_BITMAP_MATRIX == dbmInfo.fActualOp || |
356 DRAW_BITMAP_NINE == dbmInfo.fActualOp || | 356 DRAW_BITMAP_NINE == dbmInfo.fActualOp || |
357 DRAW_BITMAP_RECT_TO_RECT == dbmInfo.fActualOp); | 357 DRAW_BITMAP_RECT_TO_RECT == dbmInfo.fActualOp); |
358 | 358 |
359 uint32_t dbmPaintOffset = getPaintOffset(dbmInfo.fActualOp, dbmInfo.fSize); | 359 uint32_t dbmPaintOffset = getPaintOffset(dbmInfo.fActualOp, dbmInfo.fSize); |
360 uint32_t slPaintOffset = getPaintOffset(SAVE_LAYER, saveLayerInfo.fSize); | 360 uint32_t slPaintOffset = getPaintOffset(SAVE_LAYER, saveLayerInfo.fSize); |
361 | 361 |
362 // we have a match, now we need to get the paints involved | 362 // we have a match, now we need to get the paints involved |
363 uint32_t dbmPaintId = writer->read32At(dbmInfo.fOffset+dbmPaintOffset); | 363 uint32_t dbmPaintId = writer->readTAt<uint32_t>(dbmInfo.fOffset + dbmPaintOf
fset); |
364 uint32_t saveLayerPaintId = writer->read32At(saveLayerInfo.fOffset+slPaintOf
fset); | 364 uint32_t saveLayerPaintId = writer->readTAt<uint32_t>(saveLayerInfo.fOffset
+ slPaintOffset); |
365 | 365 |
366 if (0 == saveLayerPaintId) { | 366 if (0 == saveLayerPaintId) { |
367 // In this case the saveLayer/restore isn't needed at all - just kill th
e saveLayer | 367 // In this case the saveLayer/restore isn't needed at all - just kill th
e saveLayer |
368 // and signal the caller (by returning true) to not add the RESTORE op | 368 // and signal the caller (by returning true) to not add the RESTORE op |
369 convert_command_to_noop(writer, saveLayerInfo.fOffset); | 369 convert_command_to_noop(writer, saveLayerInfo.fOffset); |
370 return true; | 370 return true; |
371 } | 371 } |
372 | 372 |
373 if (0 == dbmPaintId) { | 373 if (0 == dbmPaintId) { |
374 // In this case just make the DBM* use the saveLayer's paint, kill the s
aveLayer | 374 // In this case just make the DBM* use the saveLayer's paint, kill the s
aveLayer |
375 // and signal the caller (by returning true) to not add the RESTORE op | 375 // and signal the caller (by returning true) to not add the RESTORE op |
376 convert_command_to_noop(writer, saveLayerInfo.fOffset); | 376 convert_command_to_noop(writer, saveLayerInfo.fOffset); |
377 writer->write32At(dbmInfo.fOffset+dbmPaintOffset, saveLayerPaintId); | 377 writer->overwriteTAt(saveLayerPaintId, dbmInfo.fOffset + dbmPaintOffset)
; |
378 return true; | 378 return true; |
379 } | 379 } |
380 | 380 |
381 SkAutoTDelete<SkPaint> saveLayerPaint(paintDict->unflatten(saveLayerPaintId)
); | 381 SkAutoTDelete<SkPaint> saveLayerPaint(paintDict->unflatten(saveLayerPaintId)
); |
382 if (NULL == saveLayerPaint.get() || !is_simple(*saveLayerPaint)) { | 382 if (NULL == saveLayerPaint.get() || !is_simple(*saveLayerPaint)) { |
383 return false; | 383 return false; |
384 } | 384 } |
385 | 385 |
386 // For this optimization we only fold the saveLayer and drawBitmapRect | 386 // For this optimization we only fold the saveLayer and drawBitmapRect |
387 // together if the saveLayer's draw is simple (i.e., no fancy effects) and | 387 // together if the saveLayer's draw is simple (i.e., no fancy effects) and |
(...skipping 12 matching lines...) Expand all Loading... |
400 SkColorGetA(saveLayerPaint->getColor())); | 400 SkColorGetA(saveLayerPaint->getColor())); |
401 dbmPaint->setColor(newColor); | 401 dbmPaint->setColor(newColor); |
402 | 402 |
403 const SkFlatData* data = paintDict->findAndReturnFlat(*dbmPaint); | 403 const SkFlatData* data = paintDict->findAndReturnFlat(*dbmPaint); |
404 if (NULL == data) { | 404 if (NULL == data) { |
405 return false; | 405 return false; |
406 } | 406 } |
407 | 407 |
408 // kill the saveLayer and alter the DBMR2R's paint to be the modified one | 408 // kill the saveLayer and alter the DBMR2R's paint to be the modified one |
409 convert_command_to_noop(writer, saveLayerInfo.fOffset); | 409 convert_command_to_noop(writer, saveLayerInfo.fOffset); |
410 writer->write32At(dbmInfo.fOffset+dbmPaintOffset, data->index()); | 410 writer->overwriteTAt(data->index(), dbmInfo.fOffset + dbmPaintOffset); |
411 return true; | 411 return true; |
412 } | 412 } |
413 | 413 |
414 /* | 414 /* |
415 * Restore has just been called (but not recorded), look back at the | 415 * Restore has just been called (but not recorded), look back at the |
416 * matching save* and see if we are in the configuration: | 416 * matching save* and see if we are in the configuration: |
417 * SAVE_LAYER (with NULL == bounds) | 417 * SAVE_LAYER (with NULL == bounds) |
418 * SAVE | 418 * SAVE |
419 * CLIP_RECT | 419 * CLIP_RECT |
420 * DRAW_BITMAP|DRAW_BITMAP_MATRIX|DRAW_BITMAP_NINE|DRAW_BITMAP_RECT_TO_R
ECT | 420 * DRAW_BITMAP|DRAW_BITMAP_MATRIX|DRAW_BITMAP_NINE|DRAW_BITMAP_RECT_TO_R
ECT |
421 * RESTORE | 421 * RESTORE |
422 * RESTORE | 422 * RESTORE |
423 * where the saveLayer's color can be moved into the drawBitmap*'s paint | 423 * where the saveLayer's color can be moved into the drawBitmap*'s paint |
424 */ | 424 */ |
425 static bool remove_save_layer2(SkWriter32* writer, int32_t offset, | 425 static bool remove_save_layer2(SkWriter32* writer, int32_t offset, |
426 SkPaintDictionary* paintDict) { | 426 SkPaintDictionary* paintDict) { |
427 | 427 |
428 // back up to the save block | 428 // back up to the save block |
429 // TODO: add a stack to track save*/restore offsets rather than searching ba
ckwards | 429 // TODO: add a stack to track save*/restore offsets rather than searching ba
ckwards |
430 while (offset > 0) { | 430 while (offset > 0) { |
431 offset = writer->read32At(offset); | 431 offset = writer->readTAt<uint32_t>(offset); |
432 } | 432 } |
433 | 433 |
434 int pattern[] = { SAVE_LAYER, SAVE, CLIP_RECT, kDRAW_BITMAP_FLAVOR, RESTORE,
/* RESTORE */ }; | 434 int pattern[] = { SAVE_LAYER, SAVE, CLIP_RECT, kDRAW_BITMAP_FLAVOR, RESTORE,
/* RESTORE */ }; |
435 CommandInfo result[SK_ARRAY_COUNT(pattern)]; | 435 CommandInfo result[SK_ARRAY_COUNT(pattern)]; |
436 | 436 |
437 if (!match(writer, -offset, pattern, result, SK_ARRAY_COUNT(pattern))) { | 437 if (!match(writer, -offset, pattern, result, SK_ARRAY_COUNT(pattern))) { |
438 return false; | 438 return false; |
439 } | 439 } |
440 | 440 |
441 if (kSaveLayerWithBoundsSize == result[0].fSize) { | 441 if (kSaveLayerWithBoundsSize == result[0].fSize) { |
(...skipping 16 matching lines...) Expand all Loading... |
458 static bool collapse_save_clip_restore(SkWriter32* writer, int32_t offset, | 458 static bool collapse_save_clip_restore(SkWriter32* writer, int32_t offset, |
459 SkPaintDictionary* paintDict) { | 459 SkPaintDictionary* paintDict) { |
460 #ifdef TRACK_COLLAPSE_STATS | 460 #ifdef TRACK_COLLAPSE_STATS |
461 gCollapseCalls += 1; | 461 gCollapseCalls += 1; |
462 #endif | 462 #endif |
463 | 463 |
464 int32_t restoreOffset = (int32_t)writer->bytesWritten(); | 464 int32_t restoreOffset = (int32_t)writer->bytesWritten(); |
465 | 465 |
466 // back up to the save block | 466 // back up to the save block |
467 while (offset > 0) { | 467 while (offset > 0) { |
468 offset = writer->read32At(offset); | 468 offset = writer->readTAt<uint32_t>(offset); |
469 } | 469 } |
470 | 470 |
471 // now offset points to a save | 471 // now offset points to a save |
472 offset = -offset; | 472 offset = -offset; |
473 uint32_t opSize; | 473 uint32_t opSize; |
474 DrawType op = peek_op_and_size(writer, offset, &opSize); | 474 DrawType op = peek_op_and_size(writer, offset, &opSize); |
475 if (SAVE_LAYER == op) { | 475 if (SAVE_LAYER == op) { |
476 // not ready to cull these out yet (mrr) | 476 // not ready to cull these out yet (mrr) |
477 return false; | 477 return false; |
478 } | 478 } |
479 SkASSERT(SAVE == op); | 479 SkASSERT(SAVE == op); |
480 SkASSERT(kSaveSize == opSize); | 480 SkASSERT(kSaveSize == opSize); |
481 | 481 |
482 // get the save flag (last 4-bytes of the space allocated for the opSize) | 482 // get the save flag (last 4-bytes of the space allocated for the opSize) |
483 SkCanvas::SaveFlags saveFlags = (SkCanvas::SaveFlags) writer->read32At(offse
t+4); | 483 SkCanvas::SaveFlags saveFlags = (SkCanvas::SaveFlags) writer->readTAt<uint32
_t>(offset + 4); |
484 if (SkCanvas::kMatrixClip_SaveFlag != saveFlags) { | 484 if (SkCanvas::kMatrixClip_SaveFlag != saveFlags) { |
485 // This function's optimization is only correct for kMatrixClip style sa
ves. | 485 // This function's optimization is only correct for kMatrixClip style sa
ves. |
486 // TODO: set checkMatrix & checkClip booleans here and then check for th
e | 486 // TODO: set checkMatrix & checkClip booleans here and then check for th
e |
487 // offending operations in the following loop. | 487 // offending operations in the following loop. |
488 return false; | 488 return false; |
489 } | 489 } |
490 | 490 |
491 // Walk forward until we get back to either a draw-verb (abort) or we hit | 491 // Walk forward until we get back to either a draw-verb (abort) or we hit |
492 // our restore (success). | 492 // our restore (success). |
493 int32_t saveOffset = offset; | 493 int32_t saveOffset = offset; |
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
696 return false; | 696 return false; |
697 default: | 697 default: |
698 SkDEBUGFAIL("unknown region op"); | 698 SkDEBUGFAIL("unknown region op"); |
699 return false; | 699 return false; |
700 } | 700 } |
701 } | 701 } |
702 | 702 |
703 void SkPictureRecord::fillRestoreOffsetPlaceholdersForCurrentStackLevel(uint32_t
restoreOffset) { | 703 void SkPictureRecord::fillRestoreOffsetPlaceholdersForCurrentStackLevel(uint32_t
restoreOffset) { |
704 int32_t offset = fRestoreOffsetStack.top(); | 704 int32_t offset = fRestoreOffsetStack.top(); |
705 while (offset > 0) { | 705 while (offset > 0) { |
706 uint32_t peek = fWriter.read32At(offset); | 706 uint32_t peek = fWriter.readTAt<uint32_t>(offset); |
707 fWriter.write32At(offset, restoreOffset); | 707 fWriter.overwriteTAt(restoreOffset, offset); |
708 offset = peek; | 708 offset = peek; |
709 } | 709 } |
710 | 710 |
711 #ifdef SK_DEBUG | 711 #ifdef SK_DEBUG |
712 // assert that the final offset value points to a save verb | 712 // assert that the final offset value points to a save verb |
713 uint32_t opSize; | 713 uint32_t opSize; |
714 DrawType drawOp = peek_op_and_size(&fWriter, -offset, &opSize); | 714 DrawType drawOp = peek_op_and_size(&fWriter, -offset, &opSize); |
715 SkASSERT(SAVE == drawOp || SAVE_LAYER == drawOp); | 715 SkASSERT(SAVE == drawOp || SAVE_LAYER == drawOp); |
716 #endif | 716 #endif |
717 } | 717 } |
(...skipping 845 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1563 void SkPictureRecord::validateRegions() const { | 1563 void SkPictureRecord::validateRegions() const { |
1564 int count = fRegions.count(); | 1564 int count = fRegions.count(); |
1565 SkASSERT((unsigned) count < 0x1000); | 1565 SkASSERT((unsigned) count < 0x1000); |
1566 for (int index = 0; index < count; index++) { | 1566 for (int index = 0; index < count; index++) { |
1567 const SkFlatData* region = fRegions[index]; | 1567 const SkFlatData* region = fRegions[index]; |
1568 SkASSERT(region); | 1568 SkASSERT(region); |
1569 // region->validate(); | 1569 // region->validate(); |
1570 } | 1570 } |
1571 } | 1571 } |
1572 #endif | 1572 #endif |
OLD | NEW |