OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2007 The Android Open Source Project | 3 * Copyright 2007 The Android Open Source Project |
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 | 8 |
9 | 9 |
10 #include "SkPictureFlat.h" | 10 #include "SkPictureFlat.h" |
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
255 #ifdef SK_SUPPORT_LEGACY_DEFAULT_PICTURE_CTOR | 255 #ifdef SK_SUPPORT_LEGACY_DEFAULT_PICTURE_CTOR |
256 // fRecord OK | 256 // fRecord OK |
257 SkPicture::SkPicture() | 257 SkPicture::SkPicture() |
258 : fWidth(0) | 258 : fWidth(0) |
259 , fHeight(0) { | 259 , fHeight(0) { |
260 this->needsNewGenID(); | 260 this->needsNewGenID(); |
261 } | 261 } |
262 #endif | 262 #endif |
263 | 263 |
264 // fRecord OK | 264 // fRecord OK |
265 SkPicture::SkPicture(int width, int height, | 265 SkPicture::SkPicture(SkScalar width, SkScalar height, |
266 const SkPictureRecord& record, | 266 const SkPictureRecord& record, |
267 bool deepCopyOps) | 267 bool deepCopyOps) |
268 : fWidth(width) | 268 : fCullWidth(width) |
269 , fHeight(height) | 269 , fCullHeight(height) |
270 , fAnalysis() { | 270 , fAnalysis() { |
271 this->needsNewGenID(); | 271 this->needsNewGenID(); |
272 | 272 |
273 SkPictInfo info; | 273 SkPictInfo info; |
274 this->createHeader(&info); | 274 this->createHeader(&info); |
275 fData.reset(SkNEW_ARGS(SkPictureData, (record, info, deepCopyOps))); | 275 fData.reset(SkNEW_ARGS(SkPictureData, (record, info, deepCopyOps))); |
276 } | 276 } |
277 | 277 |
278 // Create an SkPictureData-backed SkPicture from an SkRecord. | 278 // Create an SkPictureData-backed SkPicture from an SkRecord. |
279 // This for compatibility with serialization code only. This is not cheap. | 279 // This for compatibility with serialization code only. This is not cheap. |
280 static SkPicture* backport(const SkRecord& src, int width, int height) { | 280 static SkPicture* backport(const SkRecord& src, const SkRect& cullRect) { |
281 SkPictureRecorder recorder; | 281 SkPictureRecorder recorder; |
282 SkRecordDraw(src, | 282 SkRecordDraw(src, |
283 recorder.DEPRECATED_beginRecording(width, height), NULL/*bbh*/,
NULL/*callback*/); | 283 recorder.DEPRECATED_beginRecording(cullRect.width(), cullRect.h
eight()), |
| 284 NULL/*bbh*/, NULL/*callback*/); |
284 return recorder.endRecording(); | 285 return recorder.endRecording(); |
285 } | 286 } |
286 | 287 |
287 // fRecord OK | 288 // fRecord OK |
288 SkPicture::~SkPicture() { | 289 SkPicture::~SkPicture() { |
289 this->callDeletionListeners(); | 290 this->callDeletionListeners(); |
290 } | 291 } |
291 | 292 |
292 // fRecord OK | 293 // fRecord OK |
293 #ifdef SK_SUPPORT_LEGACY_PICTURE_CLONE | 294 #ifdef SK_SUPPORT_LEGACY_PICTURE_CLONE |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
344 } | 345 } |
345 | 346 |
346 // fRecord OK | 347 // fRecord OK |
347 void SkPicture::draw(SkCanvas* canvas, SkDrawPictureCallback* callback) const { | 348 void SkPicture::draw(SkCanvas* canvas, SkDrawPictureCallback* callback) const { |
348 SkASSERT(NULL != canvas); | 349 SkASSERT(NULL != canvas); |
349 SkASSERT(NULL != fData.get() || NULL != fRecord.get()); | 350 SkASSERT(NULL != fData.get() || NULL != fRecord.get()); |
350 | 351 |
351 // If the query contains the whole picture, don't bother with the BBH. | 352 // If the query contains the whole picture, don't bother with the BBH. |
352 SkRect clipBounds = { 0, 0, 0, 0 }; | 353 SkRect clipBounds = { 0, 0, 0, 0 }; |
353 (void)canvas->getClipBounds(&clipBounds); | 354 (void)canvas->getClipBounds(&clipBounds); |
354 const bool useBBH = !clipBounds.contains(SkRect::MakeWH(this->width(), this-
>height())); | 355 const bool useBBH = !clipBounds.contains(this->cullRect()); |
355 | 356 |
356 if (NULL != fData.get()) { | 357 if (NULL != fData.get()) { |
357 SkPicturePlayback playback(this); | 358 SkPicturePlayback playback(this); |
358 playback.setUseBBH(useBBH); | 359 playback.setUseBBH(useBBH); |
359 playback.draw(canvas, callback); | 360 playback.draw(canvas, callback); |
360 } | 361 } |
361 if (NULL != fRecord.get()) { | 362 if (NULL != fRecord.get()) { |
362 SkRecordDraw(*fRecord, canvas, useBBH ? fBBH.get() : NULL, callback); | 363 SkRecordDraw(*fRecord, canvas, useBBH ? fBBH.get() : NULL, callback); |
363 } | 364 } |
364 } | 365 } |
(...skipping 20 matching lines...) Expand all Loading... |
385 | 386 |
386 // fRecord OK | 387 // fRecord OK |
387 bool SkPicture::InternalOnly_StreamIsSKP(SkStream* stream, SkPictInfo* pInfo) { | 388 bool SkPicture::InternalOnly_StreamIsSKP(SkStream* stream, SkPictInfo* pInfo) { |
388 if (NULL == stream) { | 389 if (NULL == stream) { |
389 return false; | 390 return false; |
390 } | 391 } |
391 | 392 |
392 // Check magic bytes. | 393 // Check magic bytes. |
393 SkPictInfo info; | 394 SkPictInfo info; |
394 SkASSERT(sizeof(kMagic) == sizeof(info.fMagic)); | 395 SkASSERT(sizeof(kMagic) == sizeof(info.fMagic)); |
395 if (!stream->read(&info, sizeof(info)) || !IsValidPictInfo(info)) { | 396 |
| 397 if (!stream->read(&info.fMagic, sizeof(kMagic))) { |
396 return false; | 398 return false; |
397 } | 399 } |
398 | 400 |
| 401 info.fVersion = stream->readU32(); |
| 402 |
| 403 #ifndef V35_COMPATIBILITY_CODE |
| 404 if (info.fVersion < 35) { |
| 405 info.fCullRect.fLeft = 0; |
| 406 info.fCullRect.fTop = 0; |
| 407 info.fCullRect.fRight = SkIntToScalar(stream->readU32()); |
| 408 info.fCullRect.fBottom = SkIntToScalar(stream->readU32()); |
| 409 } else { |
| 410 #endif |
| 411 info.fCullRect.fLeft = stream->readScalar(); |
| 412 info.fCullRect.fTop = stream->readScalar(); |
| 413 info.fCullRect.fRight = stream->readScalar(); |
| 414 info.fCullRect.fBottom = stream->readScalar(); |
| 415 #ifndef V35_COMPATIBILITY_CODE |
| 416 } |
| 417 #endif |
| 418 |
| 419 info.fFlags = stream->readU32(); |
| 420 |
| 421 if (!IsValidPictInfo(info)) { |
| 422 return false; |
| 423 } |
| 424 |
399 if (pInfo != NULL) { | 425 if (pInfo != NULL) { |
400 *pInfo = info; | 426 *pInfo = info; |
401 } | 427 } |
402 return true; | 428 return true; |
403 } | 429 } |
404 | 430 |
405 // fRecord OK | 431 // fRecord OK |
406 bool SkPicture::InternalOnly_BufferIsSKP(SkReadBuffer& buffer, SkPictInfo* pInfo
) { | 432 bool SkPicture::InternalOnly_BufferIsSKP(SkReadBuffer* buffer, SkPictInfo* pInfo
) { |
407 // Check magic bytes. | 433 // Check magic bytes. |
408 SkPictInfo info; | 434 SkPictInfo info; |
409 SkASSERT(sizeof(kMagic) == sizeof(info.fMagic)); | 435 SkASSERT(sizeof(kMagic) == sizeof(info.fMagic)); |
410 if (!buffer.readByteArray(&info, sizeof(info)) || !IsValidPictInfo(info)) { | 436 |
| 437 if (!buffer->readByteArray(&info.fMagic, sizeof(kMagic))) { |
411 return false; | 438 return false; |
412 } | 439 } |
413 | 440 |
| 441 info.fVersion = buffer->readUInt(); |
| 442 |
| 443 #ifndef V35_COMPATIBILITY_CODE |
| 444 if (info.fVersion < 35) { |
| 445 info.fCullRect.fLeft = 0; |
| 446 info.fCullRect.fTop = 0; |
| 447 info.fCullRect.fRight = SkIntToScalar(buffer->readUInt()); |
| 448 info.fCullRect.fBottom = SkIntToScalar(buffer->readUInt()); |
| 449 } else { |
| 450 #endif |
| 451 buffer->readRect(&info.fCullRect); |
| 452 #ifndef V35_COMPATIBILITY_CODE |
| 453 } |
| 454 #endif |
| 455 |
| 456 info.fFlags = buffer->readUInt(); |
| 457 |
| 458 if (!IsValidPictInfo(info)) { |
| 459 return false; |
| 460 } |
| 461 |
414 if (pInfo != NULL) { | 462 if (pInfo != NULL) { |
415 *pInfo = info; | 463 *pInfo = info; |
416 } | 464 } |
417 return true; | 465 return true; |
418 } | 466 } |
419 | 467 |
420 // fRecord OK | 468 // fRecord OK |
421 SkPicture::SkPicture(SkPictureData* data, int width, int height) | 469 SkPicture::SkPicture(SkPictureData* data, SkScalar width, SkScalar height) |
422 : fData(data) | 470 : fData(data) |
423 , fWidth(width) | 471 , fCullWidth(width) |
424 , fHeight(height) | 472 , fCullHeight(height) |
425 , fAnalysis() { | 473 , fAnalysis() { |
426 this->needsNewGenID(); | 474 this->needsNewGenID(); |
427 } | 475 } |
428 | 476 |
429 SkPicture* SkPicture::Forwardport(const SkPicture& src) { | 477 SkPicture* SkPicture::Forwardport(const SkPicture& src) { |
430 SkAutoTDelete<SkRecord> record(SkNEW(SkRecord)); | 478 SkAutoTDelete<SkRecord> record(SkNEW(SkRecord)); |
431 SkRecorder canvas(record.get(), src.width(), src.height()); | 479 SkRecorder canvas(record.get(), src.cullRect().width(), src.cullRect().heigh
t()); |
432 src.draw(&canvas); | 480 src.draw(&canvas); |
433 return SkNEW_ARGS(SkPicture, (src.width(), src.height(), record.detach(), NU
LL/*bbh*/)); | 481 return SkNEW_ARGS(SkPicture, (src.cullRect().width(), src.cullRect().height(
), |
| 482 record.detach(), NULL/*bbh*/)); |
434 } | 483 } |
435 | 484 |
436 // fRecord OK | 485 // fRecord OK |
437 SkPicture* SkPicture::CreateFromStream(SkStream* stream, InstallPixelRefProc pro
c) { | 486 SkPicture* SkPicture::CreateFromStream(SkStream* stream, InstallPixelRefProc pro
c) { |
438 SkPictInfo info; | 487 SkPictInfo info; |
439 | 488 |
440 if (!InternalOnly_StreamIsSKP(stream, &info)) { | 489 if (!InternalOnly_StreamIsSKP(stream, &info)) { |
441 return NULL; | 490 return NULL; |
442 } | 491 } |
443 | 492 |
444 // Check to see if there is a playback to recreate. | 493 // Check to see if there is a playback to recreate. |
445 if (stream->readBool()) { | 494 if (stream->readBool()) { |
446 SkPictureData* data = SkPictureData::CreateFromStream(stream, info, proc
); | 495 SkPictureData* data = SkPictureData::CreateFromStream(stream, info, proc
); |
447 if (NULL == data) { | 496 if (NULL == data) { |
448 return NULL; | 497 return NULL; |
449 } | 498 } |
450 const SkPicture src(data, info.fWidth, info.fHeight); | 499 const SkPicture src(data, info.fCullRect.width(), info.fCullRect.height(
)); |
451 return Forwardport(src); | 500 return Forwardport(src); |
452 } | 501 } |
453 | 502 |
454 return NULL; | 503 return NULL; |
455 } | 504 } |
456 | 505 |
457 // fRecord OK | 506 // fRecord OK |
458 SkPicture* SkPicture::CreateFromBuffer(SkReadBuffer& buffer) { | 507 SkPicture* SkPicture::CreateFromBuffer(SkReadBuffer& buffer) { |
459 SkPictInfo info; | 508 SkPictInfo info; |
460 | 509 |
461 if (!InternalOnly_BufferIsSKP(buffer, &info)) { | 510 if (!InternalOnly_BufferIsSKP(&buffer, &info)) { |
462 return NULL; | 511 return NULL; |
463 } | 512 } |
464 | 513 |
465 // Check to see if there is a playback to recreate. | 514 // Check to see if there is a playback to recreate. |
466 if (buffer.readBool()) { | 515 if (buffer.readBool()) { |
467 SkPictureData* data = SkPictureData::CreateFromBuffer(buffer, info); | 516 SkPictureData* data = SkPictureData::CreateFromBuffer(buffer, info); |
468 if (NULL == data) { | 517 if (NULL == data) { |
469 return NULL; | 518 return NULL; |
470 } | 519 } |
471 const SkPicture src(data, info.fWidth, info.fHeight); | 520 const SkPicture src(data, info.fCullRect.width(), info.fCullRect.height(
)); |
472 return Forwardport(src); | 521 return Forwardport(src); |
473 } | 522 } |
474 | 523 |
475 return NULL; | 524 return NULL; |
476 } | 525 } |
477 | 526 |
478 // fRecord OK | 527 // fRecord OK |
479 void SkPicture::createHeader(SkPictInfo* info) const { | 528 void SkPicture::createHeader(SkPictInfo* info) const { |
480 // Copy magic bytes at the beginning of the header | 529 // Copy magic bytes at the beginning of the header |
481 SkASSERT(sizeof(kMagic) == 8); | 530 SkASSERT(sizeof(kMagic) == 8); |
482 SkASSERT(sizeof(kMagic) == sizeof(info->fMagic)); | 531 SkASSERT(sizeof(kMagic) == sizeof(info->fMagic)); |
483 memcpy(info->fMagic, kMagic, sizeof(kMagic)); | 532 memcpy(info->fMagic, kMagic, sizeof(kMagic)); |
484 | 533 |
485 // Set picture info after magic bytes in the header | 534 // Set picture info after magic bytes in the header |
486 info->fVersion = CURRENT_PICTURE_VERSION; | 535 info->fVersion = CURRENT_PICTURE_VERSION; |
487 info->fWidth = fWidth; | 536 info->fCullRect = this->cullRect(); |
488 info->fHeight = fHeight; | |
489 info->fFlags = SkPictInfo::kCrossProcess_Flag; | 537 info->fFlags = SkPictInfo::kCrossProcess_Flag; |
490 // TODO: remove this flag, since we're always float (now) | 538 // TODO: remove this flag, since we're always float (now) |
491 info->fFlags |= SkPictInfo::kScalarIsFloat_Flag; | 539 info->fFlags |= SkPictInfo::kScalarIsFloat_Flag; |
492 | 540 |
493 if (8 == sizeof(void*)) { | 541 if (8 == sizeof(void*)) { |
494 info->fFlags |= SkPictInfo::kPtrIs64Bit_Flag; | 542 info->fFlags |= SkPictInfo::kPtrIs64Bit_Flag; |
495 } | 543 } |
496 } | 544 } |
497 | 545 |
498 // fRecord OK | 546 // fRecord OK |
499 void SkPicture::serialize(SkWStream* stream, EncodeBitmap encoder) const { | 547 void SkPicture::serialize(SkWStream* stream, EncodeBitmap encoder) const { |
500 const SkPictureData* data = fData.get(); | 548 const SkPictureData* data = fData.get(); |
501 | 549 |
502 // If we're a new-format picture, backport to old format for serialization. | 550 // If we're a new-format picture, backport to old format for serialization. |
503 SkAutoTDelete<SkPicture> oldFormat; | 551 SkAutoTDelete<SkPicture> oldFormat; |
504 if (NULL == data && NULL != fRecord.get()) { | 552 if (NULL == data && NULL != fRecord.get()) { |
505 oldFormat.reset(backport(*fRecord, fWidth, fHeight)); | 553 oldFormat.reset(backport(*fRecord, this->cullRect())); |
506 data = oldFormat->fData.get(); | 554 data = oldFormat->fData.get(); |
507 SkASSERT(NULL != data); | 555 SkASSERT(NULL != data); |
508 } | 556 } |
509 | 557 |
510 SkPictInfo info; | 558 SkPictInfo info; |
511 this->createHeader(&info); | 559 this->createHeader(&info); |
| 560 SkASSERT(sizeof(SkPictInfo) == 32); |
512 stream->write(&info, sizeof(info)); | 561 stream->write(&info, sizeof(info)); |
513 | 562 |
514 if (NULL != data) { | 563 if (NULL != data) { |
515 stream->writeBool(true); | 564 stream->writeBool(true); |
516 data->serialize(stream, encoder); | 565 data->serialize(stream, encoder); |
517 } else { | 566 } else { |
518 stream->writeBool(false); | 567 stream->writeBool(false); |
519 } | 568 } |
520 } | 569 } |
521 | 570 |
522 // fRecord OK | 571 // fRecord OK |
523 void SkPicture::flatten(SkWriteBuffer& buffer) const { | 572 void SkPicture::flatten(SkWriteBuffer& buffer) const { |
524 const SkPictureData* data = fData.get(); | 573 const SkPictureData* data = fData.get(); |
525 | 574 |
526 // If we're a new-format picture, backport to old format for serialization. | 575 // If we're a new-format picture, backport to old format for serialization. |
527 SkAutoTDelete<SkPicture> oldFormat; | 576 SkAutoTDelete<SkPicture> oldFormat; |
528 if (NULL == data && NULL != fRecord.get()) { | 577 if (NULL == data && NULL != fRecord.get()) { |
529 oldFormat.reset(backport(*fRecord, fWidth, fHeight)); | 578 oldFormat.reset(backport(*fRecord, this->cullRect())); |
530 data = oldFormat->fData.get(); | 579 data = oldFormat->fData.get(); |
531 SkASSERT(NULL != data); | 580 SkASSERT(NULL != data); |
532 } | 581 } |
533 | 582 |
534 SkPictInfo info; | 583 SkPictInfo info; |
535 this->createHeader(&info); | 584 this->createHeader(&info); |
536 buffer.writeByteArray(&info, sizeof(info)); | 585 buffer.writeByteArray(&info.fMagic, sizeof(info.fMagic)); |
| 586 buffer.writeUInt(info.fVersion); |
| 587 buffer.writeRect(info.fCullRect); |
| 588 buffer.writeUInt(info.fFlags); |
537 | 589 |
538 if (NULL != data) { | 590 if (NULL != data) { |
539 buffer.writeBool(true); | 591 buffer.writeBool(true); |
540 data->flatten(buffer); | 592 data->flatten(buffer); |
541 } else { | 593 } else { |
542 buffer.writeBool(false); | 594 buffer.writeBool(false); |
543 } | 595 } |
544 } | 596 } |
545 | 597 |
546 #if SK_SUPPORT_GPU | 598 #if SK_SUPPORT_GPU |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
598 | 650 |
599 // fRecord OK | 651 // fRecord OK |
600 uint32_t SkPicture::uniqueID() const { | 652 uint32_t SkPicture::uniqueID() const { |
601 if (SK_InvalidGenID == fUniqueID) { | 653 if (SK_InvalidGenID == fUniqueID) { |
602 fUniqueID = next_picture_generation_id(); | 654 fUniqueID = next_picture_generation_id(); |
603 } | 655 } |
604 return fUniqueID; | 656 return fUniqueID; |
605 } | 657 } |
606 | 658 |
607 // fRecord OK | 659 // fRecord OK |
608 SkPicture::SkPicture(int width, int height, SkRecord* record, SkBBoxHierarchy* b
bh) | 660 SkPicture::SkPicture(SkScalar width, SkScalar height, SkRecord* record, SkBBoxHi
erarchy* bbh) |
609 : fWidth(width) | 661 : fCullWidth(width) |
610 , fHeight(height) | 662 , fCullHeight(height) |
611 , fRecord(record) | 663 , fRecord(record) |
612 , fBBH(SkSafeRef(bbh)) | 664 , fBBH(SkSafeRef(bbh)) |
613 , fAnalysis(*record) { | 665 , fAnalysis(*record) { |
614 // TODO: delay as much of this work until just before first playback? | 666 // TODO: delay as much of this work until just before first playback? |
615 if (fBBH.get()) { | 667 if (fBBH.get()) { |
616 SkRecordFillBounds(*record, fBBH.get()); | 668 SkRecordFillBounds(*record, fBBH.get()); |
617 } | 669 } |
618 this->needsNewGenID(); | 670 this->needsNewGenID(); |
619 } | 671 } |
620 | 672 |
(...skipping 19 matching lines...) Expand all Loading... |
640 int SkPicture::approximateOpCount() const { | 692 int SkPicture::approximateOpCount() const { |
641 SkASSERT(fRecord.get() || fData.get()); | 693 SkASSERT(fRecord.get() || fData.get()); |
642 if (fRecord.get()) { | 694 if (fRecord.get()) { |
643 return fRecord->count(); | 695 return fRecord->count(); |
644 } | 696 } |
645 if (fData.get()) { | 697 if (fData.get()) { |
646 return fData->opCount(); | 698 return fData->opCount(); |
647 } | 699 } |
648 return 0; | 700 return 0; |
649 } | 701 } |
OLD | NEW |