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