Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(399)

Side by Side Diff: src/core/SkPictureData.cpp

Issue 377623002: Split SkPicturePlayback out of SkPictureData (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Add virtual dtor for SkPicturePlayback Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/core/SkPictureData.h ('k') | src/core/SkPicturePlayback.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 #include <new> 7 #include <new>
8 #include "SkBBoxHierarchy.h" 8 #include "SkBBoxHierarchy.h"
9 #include "SkDrawPictureCallback.h" 9 #include "SkDrawPictureCallback.h"
10 #include "SkPictureData.h" 10 #include "SkPictureData.h"
(...skipping 10 matching lines...) Expand all
21 21
22 template <typename T> int SafeCount(const T* obj) { 22 template <typename T> int SafeCount(const T* obj) {
23 return obj ? obj->count() : 0; 23 return obj ? obj->count() : 0;
24 } 24 }
25 25
26 /* Define this to spew out a debug statement whenever we skip the remainder of 26 /* Define this to spew out a debug statement whenever we skip the remainder of
27 a save/restore block because a clip... command returned false (empty). 27 a save/restore block because a clip... command returned false (empty).
28 */ 28 */
29 #define SPEW_CLIP_SKIPPINGx 29 #define SPEW_CLIP_SKIPPINGx
30 30
31 SkPictureData::PlaybackReplacements::ReplacementInfo*
32 SkPictureData::PlaybackReplacements::push() {
33 SkDEBUGCODE(this->validate());
34 return fReplacements.push();
35 }
36
37 void SkPictureData::PlaybackReplacements::freeAll() {
38 for (int i = 0; i < fReplacements.count(); ++i) {
39 SkDELETE(fReplacements[i].fBM);
40 }
41 fReplacements.reset();
42 }
43
44 #ifdef SK_DEBUG
45 void SkPictureData::PlaybackReplacements::validate() const {
46 // Check that the ranges are monotonically increasing and non-overlapping
47 if (fReplacements.count() > 0) {
48 SkASSERT(fReplacements[0].fStart < fReplacements[0].fStop);
49
50 for (int i = 1; i < fReplacements.count(); ++i) {
51 SkASSERT(fReplacements[i].fStart < fReplacements[i].fStop);
52 SkASSERT(fReplacements[i-1].fStop < fReplacements[i].fStart);
53 }
54 }
55 }
56 #endif
57
58 SkPictureData::SkPictureData(const SkPictInfo& info) 31 SkPictureData::SkPictureData(const SkPictInfo& info)
59 : fInfo(info) { 32 : fInfo(info) {
60 this->init(); 33 this->init();
61 } 34 }
62 35
63 void SkPictureData::initForPlayback() const { 36 void SkPictureData::initForPlayback() const {
64 // ensure that the paths bounds are pre-computed 37 // ensure that the paths bounds are pre-computed
65 if (NULL != fPathHeap.get()) { 38 if (NULL != fPathHeap.get()) {
66 for (int i = 0; i < fPathHeap->count(); i++) { 39 for (int i = 0; i < fPathHeap->count(); i++) {
67 (*fPathHeap.get())[i].updateBoundsCache(); 40 (*fPathHeap.get())[i].updateBoundsCache();
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
253 226
254 void SkPictureData::init() { 227 void SkPictureData::init() {
255 fBitmaps = NULL; 228 fBitmaps = NULL;
256 fPaints = NULL; 229 fPaints = NULL;
257 fPictureRefs = NULL; 230 fPictureRefs = NULL;
258 fPictureCount = 0; 231 fPictureCount = 0;
259 fOpData = NULL; 232 fOpData = NULL;
260 fFactoryPlayback = NULL; 233 fFactoryPlayback = NULL;
261 fBoundingHierarchy = NULL; 234 fBoundingHierarchy = NULL;
262 fStateTree = NULL; 235 fStateTree = NULL;
263 fCachedActiveOps = NULL;
264 fCurOffset = 0;
265 fUseBBH = true;
266 fStart = 0;
267 fStop = 0;
268 fReplacements = NULL;
269 } 236 }
270 237
271 SkPictureData::~SkPictureData() { 238 SkPictureData::~SkPictureData() {
272 SkSafeUnref(fOpData); 239 SkSafeUnref(fOpData);
273 240
274 SkSafeUnref(fBitmaps); 241 SkSafeUnref(fBitmaps);
275 SkSafeUnref(fPaints); 242 SkSafeUnref(fPaints);
276 SkSafeUnref(fBoundingHierarchy); 243 SkSafeUnref(fBoundingHierarchy);
277 SkSafeUnref(fStateTree); 244 SkSafeUnref(fStateTree);
278 245
279 SkDELETE(fCachedActiveOps);
280
281 for (int i = 0; i < fPictureCount; i++) { 246 for (int i = 0; i < fPictureCount; i++) {
282 fPictureRefs[i]->unref(); 247 fPictureRefs[i]->unref();
283 } 248 }
284 SkDELETE_ARRAY(fPictureRefs); 249 SkDELETE_ARRAY(fPictureRefs);
285 250
286 SkDELETE(fFactoryPlayback); 251 SkDELETE(fFactoryPlayback);
287 } 252 }
288 253
289 void SkPictureData::dumpSize() const { 254 void SkPictureData::dumpSize() const {
290 SkDebugf("--- picture size: ops=%d bitmaps=%d [%d] paints=%d [%d]\n", 255 SkDebugf("--- picture size: ops=%d bitmaps=%d [%d] paints=%d [%d]\n",
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
468 uint32_t rbMask = 0; 433 uint32_t rbMask = 0;
469 for (size_t i = 0; i < SK_ARRAY_COUNT(gSD); ++i) { 434 for (size_t i = 0; i < SK_ARRAY_COUNT(gSD); ++i) {
470 if (pictInfoFlags & gSD[i].fSrc) { 435 if (pictInfoFlags & gSD[i].fSrc) {
471 rbMask |= gSD[i].fDst; 436 rbMask |= gSD[i].fDst;
472 } 437 }
473 } 438 }
474 return rbMask; 439 return rbMask;
475 } 440 }
476 441
477 bool SkPictureData::parseStreamTag(SkStream* stream, 442 bool SkPictureData::parseStreamTag(SkStream* stream,
478 uint32_t tag, 443 uint32_t tag,
479 uint32_t size, 444 uint32_t size,
480 SkPicture::InstallPixelRefProc proc) { 445 SkPicture::InstallPixelRefProc proc) {
481 /* 446 /*
482 * By the time we encounter BUFFER_SIZE_TAG, we need to have already seen 447 * By the time we encounter BUFFER_SIZE_TAG, we need to have already seen
483 * its dependents: FACTORY_TAG and TYPEFACE_TAG. These two are not required 448 * its dependents: FACTORY_TAG and TYPEFACE_TAG. These two are not required
484 * but if they are present, they need to have been seen before the buffer. 449 * but if they are present, they need to have been seen before the buffer.
485 * 450 *
486 * We assert that if/when we see either of these, that we have not yet seen 451 * We assert that if/when we see either of these, that we have not yet seen
487 * the buffer tag, because if we have, then its too-late to deal with the 452 * the buffer tag, because if we have, then its too-late to deal with the
488 * factories or typefaces. 453 * factories or typefaces.
489 */ 454 */
490 SkDEBUGCODE(bool haveBuffer = false;) 455 SkDEBUGCODE(bool haveBuffer = false;)
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
580 return false; 545 return false;
581 } 546 }
582 } 547 }
583 SkDEBUGCODE(haveBuffer = true;) 548 SkDEBUGCODE(haveBuffer = true;)
584 } break; 549 } break;
585 } 550 }
586 return true; // success 551 return true; // success
587 } 552 }
588 553
589 bool SkPictureData::parseBufferTag(SkReadBuffer& buffer, 554 bool SkPictureData::parseBufferTag(SkReadBuffer& buffer,
590 uint32_t tag, uint32_t size) { 555 uint32_t tag, uint32_t size) {
591 switch (tag) { 556 switch (tag) {
592 case SK_PICT_BITMAP_BUFFER_TAG: { 557 case SK_PICT_BITMAP_BUFFER_TAG: {
593 const int count = SkToInt(size); 558 const int count = SkToInt(size);
594 fBitmaps = SkTRefArray<SkBitmap>::Create(size); 559 fBitmaps = SkTRefArray<SkBitmap>::Create(size);
595 for (int i = 0; i < count; ++i) { 560 for (int i = 0; i < count; ++i) {
596 SkBitmap* bm = &fBitmaps->writableAt(i); 561 SkBitmap* bm = &fBitmaps->writableAt(i);
597 buffer.readBitmap(bm); 562 buffer.readBitmap(bm);
598 bm->setImmutable(); 563 bm->setImmutable();
599 } 564 }
600 } break; 565 } break;
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
718 fSize = 0; 683 fSize = 0;
719 } 684 }
720 685
721 void recordSkip(size_t bytes) { 686 void recordSkip(size_t bytes) {
722 fCount += 1; 687 fCount += 1;
723 fSize += bytes; 688 fSize += bytes;
724 } 689 }
725 }; 690 };
726 #endif 691 #endif
727 692
728 #ifdef SK_DEVELOPER 693 uint32_t SkPictureData::OperationList::offset(int index) const {
729 bool SkPictureData::preDraw(int opIndex, int type) {
730 return false;
731 }
732
733 void SkPictureData::postDraw(int opIndex) {
734 }
735 #endif
736
737 /*
738 * Read the next op code and chunk size from 'reader'. The returned size
739 * is the entire size of the chunk (including the opcode). Thus, the
740 * offset just prior to calling read_op_and_size + 'size' is the offset
741 * to the next chunk's op code. This also means that the size of a chunk
742 * with no arguments (just an opcode) will be 4.
743 */
744 static DrawType read_op_and_size(SkReader32* reader, uint32_t* size) {
745 uint32_t temp = reader->readInt();
746 uint32_t op;
747 if (((uint8_t) temp) == temp) {
748 // old skp file - no size information
749 op = temp;
750 *size = 0;
751 } else {
752 UNPACK_8_24(temp, op, *size);
753 if (MASK_24 == *size) {
754 *size = reader->readInt();
755 }
756 }
757 return (DrawType) op;
758 }
759
760 uint32_t SkPictureData::CachedOperationList::offset(int index) const {
761 SkASSERT(index < fOps.count()); 694 SkASSERT(index < fOps.count());
762 return ((SkPictureStateTree::Draw*)fOps[index])->fOffset; 695 return ((SkPictureStateTree::Draw*)fOps[index])->fOffset;
763 } 696 }
764 697
765 const SkMatrix& SkPictureData::CachedOperationList::matrix(int index) const { 698 const SkMatrix& SkPictureData::OperationList::matrix(int index) const {
766 SkASSERT(index < fOps.count()); 699 SkASSERT(index < fOps.count());
767 return *((SkPictureStateTree::Draw*)fOps[index])->fMatrix; 700 return *((SkPictureStateTree::Draw*)fOps[index])->fMatrix;
768 } 701 }
769 702
770 const SkPicture::OperationList& SkPictureData::getActiveOps(const SkIRect& query ) { 703 const SkPicture::OperationList* SkPictureData::getActiveOps(const SkIRect& query ) const {
771 if (NULL == fStateTree || NULL == fBoundingHierarchy) { 704 if (NULL == fStateTree || NULL == fBoundingHierarchy) {
772 return SkPicture::OperationList::InvalidList(); 705 return NULL;
773 } 706 }
774 707
775 if (NULL == fCachedActiveOps) { 708 OperationList* activeOps = SkNEW(OperationList);
776 fCachedActiveOps = SkNEW(CachedOperationList); 709
710 fBoundingHierarchy->search(query, &(activeOps->fOps));
711 if (0 != activeOps->fOps.count()) {
712 SkTQSort<SkPictureStateTree::Draw>(
713 reinterpret_cast<SkPictureStateTree::Draw**>(activeOps->fOps.begin() ),
714 reinterpret_cast<SkPictureStateTree::Draw**>(activeOps->fOps.end()-1 ));
777 } 715 }
778 716
779 if (query == fCachedActiveOps->fCacheQueryRect) { 717 return activeOps;
780 return *fCachedActiveOps;
781 }
782
783 fCachedActiveOps->fOps.rewind();
784
785 fBoundingHierarchy->search(query, &(fCachedActiveOps->fOps));
786 if (0 != fCachedActiveOps->fOps.count()) {
787 SkTQSort<SkPictureStateTree::Draw>(
788 reinterpret_cast<SkPictureStateTree::Draw**>(fCachedActiveOps->fOps. begin()),
789 reinterpret_cast<SkPictureStateTree::Draw**>(fCachedActiveOps->fOps. end()-1));
790 }
791
792 fCachedActiveOps->fCacheQueryRect = query;
793 return *fCachedActiveOps;
794 } 718 }
795 719
796 class SkAutoResetOpID {
797 public:
798 SkAutoResetOpID(SkPictureData* data) : fData(data) { }
799 ~SkAutoResetOpID() {
800 if (NULL != fData) {
801 fData->resetOpID();
802 }
803 }
804
805 private:
806 SkPictureData* fData;
807 };
808
809 // TODO: Replace with hash or pass in "lastLookedUp" hint
810 SkPictureData::PlaybackReplacements::ReplacementInfo*
811 SkPictureData::PlaybackReplacements::lookupByStart(size_t start) {
812 SkDEBUGCODE(this->validate());
813 for (int i = 0; i < fReplacements.count(); ++i) {
814 if (start == fReplacements[i].fStart) {
815 return &fReplacements[i];
816 } else if (start < fReplacements[i].fStart) {
817 return NULL; // the ranges are monotonically increasing and non-ove rlapping
818 }
819 }
820
821 return NULL;
822 }
823
824 void SkPictureData::draw(SkCanvas& canvas, SkDrawPictureCallback* callback) {
825 SkAutoResetOpID aroi(this);
826 SkASSERT(0 == fCurOffset);
827
828 #ifdef ENABLE_TIME_DRAW
829 SkAutoTime at("SkPicture::draw", 50);
830 #endif
831
832 #ifdef SPEW_CLIP_SKIPPING
833 SkipClipRec skipRect, skipRRect, skipRegion, skipPath, skipCull;
834 int opCount = 0;
835 #endif
836
837 #ifdef SK_BUILD_FOR_ANDROID
838 SkAutoMutexAcquire autoMutex(fDrawMutex);
839 #endif
840
841 // kDrawComplete will be the signal that we have reached the end of
842 // the command stream
843 static const uint32_t kDrawComplete = SK_MaxU32;
844
845 SkReader32 reader(fOpData->bytes(), fOpData->size());
846 TextContainer text;
847 const SkTDArray<void*>* activeOps = NULL;
848
849 // When draw limits are enabled (i.e., 0 != fStart || 0 != fStop) the state
850 // tree isn't used to pick and choose the draw operations
851 if (0 == fStart && 0 == fStop) {
852 if (fUseBBH && NULL != fStateTree && NULL != fBoundingHierarchy) {
853 SkRect clipBounds;
854 if (canvas.getClipBounds(&clipBounds)) {
855 SkIRect query;
856 clipBounds.roundOut(&query);
857
858 const SkPicture::OperationList& activeOpsList = this->getActiveO ps(query);
859 if (activeOpsList.valid()) {
860 if (0 == activeOpsList.numOps()) {
861 return; // nothing to draw
862 }
863
864 // Since the opList is valid we know it is our derived class
865 activeOps = &((const CachedOperationList&)activeOpsList).fOp s;
866 }
867 }
868 }
869 }
870
871 SkPictureStateTree::Iterator it = (NULL == activeOps) ?
872 SkPictureStateTree::Iterator() :
873 fStateTree->getIterator(*activeOps, &canvas);
874
875 if (0 != fStart || 0 != fStop) {
876 reader.setOffset(fStart);
877 uint32_t size;
878 SkDEBUGCODE(DrawType op =) read_op_and_size(&reader, &size);
879 SkASSERT(SAVE_LAYER == op);
880 reader.setOffset(fStart+size);
881 }
882
883 if (it.isValid()) {
884 uint32_t skipTo = it.nextDraw();
885 if (kDrawComplete == skipTo) {
886 return;
887 }
888 reader.setOffset(skipTo);
889 }
890
891 // Record this, so we can concat w/ it if we encounter a setMatrix()
892 SkMatrix initialMatrix = canvas.getTotalMatrix();
893
894 SkAutoCanvasRestore acr(&canvas, false);
895
896 #ifdef SK_BUILD_FOR_ANDROID
897 fAbortCurrentPlayback = false;
898 #endif
899
900 #ifdef SK_DEVELOPER
901 int opIndex = -1;
902 #endif
903
904 while (!reader.eof()) {
905 if (callback && callback->abortDrawing()) {
906 return;
907 }
908 #ifdef SK_BUILD_FOR_ANDROID
909 if (fAbortCurrentPlayback) {
910 return;
911 }
912 #endif
913 if (0 != fStart || 0 != fStop) {
914 size_t offset = reader.offset() ;
915 if (offset >= fStop) {
916 uint32_t size;
917 SkDEBUGCODE(DrawType op =) read_op_and_size(&reader, &size);
918 SkASSERT(RESTORE == op);
919 return;
920 }
921 }
922
923 if (NULL != fReplacements) {
924 // Potentially replace a block of operations with a single drawBitma p call
925 SkPictureData::PlaybackReplacements::ReplacementInfo* temp =
926 fReplacements->lookupByStart(reader. offset());
927 if (NULL != temp) {
928 SkASSERT(NULL != temp->fBM);
929 SkASSERT(NULL != temp->fPaint);
930 canvas.save();
931 canvas.setMatrix(initialMatrix);
932 SkRect src = SkRect::Make(temp->fSrcRect);
933 SkRect dst = SkRect::MakeXYWH(temp->fPos.fX, temp->fPos.fY,
934 temp->fSrcRect.width(),
935 temp->fSrcRect.height());
936 canvas.drawBitmapRectToRect(*temp->fBM, &src, dst, temp->fPaint) ;
937 canvas.restore();
938
939 if (it.isValid()) {
940 // This save is needed since the BBH will automatically issu e
941 // a restore to balanced the saveLayer we're skipping
942 canvas.save();
943
944 // At this point we know that the PictureStateTree was aimin g
945 // for some draw op within temp's saveLayer (although potent ially
946 // in a separate saveLayer nested inside it).
947 // We need to skip all the operations inside temp's range
948 // along with all the associated state changes but update
949 // the state tree to the first operation outside temp's rang e.
950
951 uint32_t skipTo;
952 do {
953 skipTo = it.nextDraw();
954 if (kDrawComplete == skipTo) {
955 break;
956 }
957
958 if (skipTo <= temp->fStop) {
959 reader.setOffset(skipTo);
960 uint32_t size;
961 DrawType op = read_op_and_size(&reader, &size);
962 // Since we are relying on the normal SkPictureState Tree
963 // playback we need to convert any nested saveLayer calls
964 // it may issue into saves (so that all its internal
965 // restores will be balanced).
966 if (SAVE_LAYER == op) {
967 canvas.save();
968 }
969 }
970 } while (skipTo <= temp->fStop);
971
972 if (kDrawComplete == skipTo) {
973 break;
974 }
975
976 reader.setOffset(skipTo);
977 } else {
978 reader.setOffset(temp->fStop);
979 uint32_t size;
980 SkDEBUGCODE(DrawType op =) read_op_and_size(&reader, &size);
981 SkASSERT(RESTORE == op);
982 }
983 continue;
984 }
985 }
986
987 #ifdef SPEW_CLIP_SKIPPING
988 opCount++;
989 #endif
990
991 fCurOffset = reader.offset();
992 uint32_t size;
993 DrawType op = read_op_and_size(&reader, &size);
994 size_t skipTo = 0;
995 if (NOOP == op) {
996 // NOOPs are to be ignored - do not propagate them any further
997 skipTo = fCurOffset + size;
998 #ifdef SK_DEVELOPER
999 } else {
1000 opIndex++;
1001 if (this->preDraw(opIndex, op)) {
1002 skipTo = fCurOffset + size;
1003 }
1004 #endif
1005 }
1006
1007 if (0 != skipTo) {
1008 if (it.isValid()) {
1009 // If using a bounding box hierarchy, advance the state tree
1010 // iterator until at or after skipTo
1011 uint32_t adjustedSkipTo;
1012 do {
1013 adjustedSkipTo = it.nextDraw();
1014 } while (adjustedSkipTo < skipTo);
1015 skipTo = adjustedSkipTo;
1016 }
1017 if (kDrawComplete == skipTo) {
1018 break;
1019 }
1020 reader.setOffset(skipTo);
1021 continue;
1022 }
1023
1024 switch (op) {
1025 case CLIP_PATH: {
1026 const SkPath& path = getPath(reader);
1027 uint32_t packed = reader.readInt();
1028 SkRegion::Op regionOp = ClipParams_unpackRegionOp(packed);
1029 bool doAA = ClipParams_unpackDoAA(packed);
1030 size_t offsetToRestore = reader.readInt();
1031 SkASSERT(!offsetToRestore || \
1032 offsetToRestore >= reader.offset());
1033 canvas.clipPath(path, regionOp, doAA);
1034 if (canvas.isClipEmpty() && offsetToRestore) {
1035 #ifdef SPEW_CLIP_SKIPPING
1036 skipPath.recordSkip(offsetToRestore - reader.offset());
1037 #endif
1038 reader.setOffset(offsetToRestore);
1039 }
1040 } break;
1041 case CLIP_REGION: {
1042 SkRegion region;
1043 this->getRegion(reader, &region);
1044 uint32_t packed = reader.readInt();
1045 SkRegion::Op regionOp = ClipParams_unpackRegionOp(packed);
1046 size_t offsetToRestore = reader.readInt();
1047 SkASSERT(!offsetToRestore || \
1048 offsetToRestore >= reader.offset());
1049 canvas.clipRegion(region, regionOp);
1050 if (canvas.isClipEmpty() && offsetToRestore) {
1051 #ifdef SPEW_CLIP_SKIPPING
1052 skipRegion.recordSkip(offsetToRestore - reader.offset());
1053 #endif
1054 reader.setOffset(offsetToRestore);
1055 }
1056 } break;
1057 case CLIP_RECT: {
1058 const SkRect& rect = reader.skipT<SkRect>();
1059 uint32_t packed = reader.readInt();
1060 SkRegion::Op regionOp = ClipParams_unpackRegionOp(packed);
1061 bool doAA = ClipParams_unpackDoAA(packed);
1062 size_t offsetToRestore = reader.readInt();
1063 SkASSERT(!offsetToRestore || \
1064 offsetToRestore >= reader.offset());
1065 canvas.clipRect(rect, regionOp, doAA);
1066 if (canvas.isClipEmpty() && offsetToRestore) {
1067 #ifdef SPEW_CLIP_SKIPPING
1068 skipRect.recordSkip(offsetToRestore - reader.offset());
1069 #endif
1070 reader.setOffset(offsetToRestore);
1071 }
1072 } break;
1073 case CLIP_RRECT: {
1074 SkRRect rrect;
1075 reader.readRRect(&rrect);
1076 uint32_t packed = reader.readInt();
1077 SkRegion::Op regionOp = ClipParams_unpackRegionOp(packed);
1078 bool doAA = ClipParams_unpackDoAA(packed);
1079 size_t offsetToRestore = reader.readInt();
1080 SkASSERT(!offsetToRestore || offsetToRestore >= reader.offset()) ;
1081 canvas.clipRRect(rrect, regionOp, doAA);
1082 if (canvas.isClipEmpty() && offsetToRestore) {
1083 #ifdef SPEW_CLIP_SKIPPING
1084 skipRRect.recordSkip(offsetToRestore - reader.offset());
1085 #endif
1086 reader.setOffset(offsetToRestore);
1087 }
1088 } break;
1089 case PUSH_CULL: {
1090 const SkRect& cullRect = reader.skipT<SkRect>();
1091 size_t offsetToRestore = reader.readInt();
1092 if (offsetToRestore && canvas.quickReject(cullRect)) {
1093 #ifdef SPEW_CLIP_SKIPPING
1094 skipCull.recordSkip(offsetToRestore - reader.offset());
1095 #endif
1096 reader.setOffset(offsetToRestore);
1097 } else {
1098 canvas.pushCull(cullRect);
1099 }
1100 } break;
1101 case POP_CULL:
1102 canvas.popCull();
1103 break;
1104 case CONCAT: {
1105 SkMatrix matrix;
1106 this->getMatrix(reader, &matrix);
1107 canvas.concat(matrix);
1108 break;
1109 }
1110 case DRAW_BITMAP: {
1111 const SkPaint* paint = this->getPaint(reader);
1112 const SkBitmap& bitmap = this->getBitmap(reader);
1113 const SkPoint& loc = reader.skipT<SkPoint>();
1114 canvas.drawBitmap(bitmap, loc.fX, loc.fY, paint);
1115 } break;
1116 case DRAW_BITMAP_RECT_TO_RECT: {
1117 const SkPaint* paint = this->getPaint(reader);
1118 const SkBitmap& bitmap = this->getBitmap(reader);
1119 const SkRect* src = this->getRectPtr(reader); // may be null
1120 const SkRect& dst = reader.skipT<SkRect>(); // required
1121 SkCanvas::DrawBitmapRectFlags flags;
1122 flags = (SkCanvas::DrawBitmapRectFlags) reader.readInt();
1123 canvas.drawBitmapRectToRect(bitmap, src, dst, paint, flags);
1124 } break;
1125 case DRAW_BITMAP_MATRIX: {
1126 const SkPaint* paint = this->getPaint(reader);
1127 const SkBitmap& bitmap = this->getBitmap(reader);
1128 SkMatrix matrix;
1129 this->getMatrix(reader, &matrix);
1130 canvas.drawBitmapMatrix(bitmap, matrix, paint);
1131 } break;
1132 case DRAW_BITMAP_NINE: {
1133 const SkPaint* paint = this->getPaint(reader);
1134 const SkBitmap& bitmap = this->getBitmap(reader);
1135 const SkIRect& src = reader.skipT<SkIRect>();
1136 const SkRect& dst = reader.skipT<SkRect>();
1137 canvas.drawBitmapNine(bitmap, src, dst, paint);
1138 } break;
1139 case DRAW_CLEAR:
1140 canvas.clear(reader.readInt());
1141 break;
1142 case DRAW_DATA: {
1143 size_t length = reader.readInt();
1144 canvas.drawData(reader.skip(length), length);
1145 // skip handles padding the read out to a multiple of 4
1146 } break;
1147 case DRAW_DRRECT: {
1148 const SkPaint& paint = *this->getPaint(reader);
1149 SkRRect outer, inner;
1150 reader.readRRect(&outer);
1151 reader.readRRect(&inner);
1152 canvas.drawDRRect(outer, inner, paint);
1153 } break;
1154 case BEGIN_COMMENT_GROUP: {
1155 const char* desc = reader.readString();
1156 canvas.beginCommentGroup(desc);
1157 } break;
1158 case COMMENT: {
1159 const char* kywd = reader.readString();
1160 const char* value = reader.readString();
1161 canvas.addComment(kywd, value);
1162 } break;
1163 case END_COMMENT_GROUP: {
1164 canvas.endCommentGroup();
1165 } break;
1166 case DRAW_OVAL: {
1167 const SkPaint& paint = *this->getPaint(reader);
1168 canvas.drawOval(reader.skipT<SkRect>(), paint);
1169 } break;
1170 case DRAW_PAINT:
1171 canvas.drawPaint(*this->getPaint(reader));
1172 break;
1173 case DRAW_PATH: {
1174 const SkPaint& paint = *this->getPaint(reader);
1175 canvas.drawPath(getPath(reader), paint);
1176 } break;
1177 case DRAW_PICTURE:
1178 canvas.drawPicture(this->getPicture(reader));
1179 break;
1180 case DRAW_POINTS: {
1181 const SkPaint& paint = *this->getPaint(reader);
1182 SkCanvas::PointMode mode = (SkCanvas::PointMode)reader.readInt() ;
1183 size_t count = reader.readInt();
1184 const SkPoint* pts = (const SkPoint*)reader.skip(sizeof(SkPoint) * count);
1185 canvas.drawPoints(mode, count, pts, paint);
1186 } break;
1187 case DRAW_POS_TEXT: {
1188 const SkPaint& paint = *this->getPaint(reader);
1189 getText(reader, &text);
1190 size_t points = reader.readInt();
1191 const SkPoint* pos = (const SkPoint*)reader.skip(points * sizeof (SkPoint));
1192 canvas.drawPosText(text.text(), text.length(), pos, paint);
1193 } break;
1194 case DRAW_POS_TEXT_TOP_BOTTOM: {
1195 const SkPaint& paint = *this->getPaint(reader);
1196 getText(reader, &text);
1197 size_t points = reader.readInt();
1198 const SkPoint* pos = (const SkPoint*)reader.skip(points * sizeof (SkPoint));
1199 const SkScalar top = reader.readScalar();
1200 const SkScalar bottom = reader.readScalar();
1201 if (!canvas.quickRejectY(top, bottom)) {
1202 canvas.drawPosText(text.text(), text.length(), pos, paint);
1203 }
1204 } break;
1205 case DRAW_POS_TEXT_H: {
1206 const SkPaint& paint = *this->getPaint(reader);
1207 getText(reader, &text);
1208 size_t xCount = reader.readInt();
1209 const SkScalar constY = reader.readScalar();
1210 const SkScalar* xpos = (const SkScalar*)reader.skip(xCount * siz eof(SkScalar));
1211 canvas.drawPosTextH(text.text(), text.length(), xpos, constY,
1212 paint);
1213 } break;
1214 case DRAW_POS_TEXT_H_TOP_BOTTOM: {
1215 const SkPaint& paint = *this->getPaint(reader);
1216 getText(reader, &text);
1217 size_t xCount = reader.readInt();
1218 const SkScalar* xpos = (const SkScalar*)reader.skip((3 + xCount) * sizeof(SkScalar));
1219 const SkScalar top = *xpos++;
1220 const SkScalar bottom = *xpos++;
1221 const SkScalar constY = *xpos++;
1222 if (!canvas.quickRejectY(top, bottom)) {
1223 canvas.drawPosTextH(text.text(), text.length(), xpos,
1224 constY, paint);
1225 }
1226 } break;
1227 case DRAW_RECT: {
1228 const SkPaint& paint = *this->getPaint(reader);
1229 canvas.drawRect(reader.skipT<SkRect>(), paint);
1230 } break;
1231 case DRAW_RRECT: {
1232 const SkPaint& paint = *this->getPaint(reader);
1233 SkRRect rrect;
1234 reader.readRRect(&rrect);
1235 canvas.drawRRect(rrect, paint);
1236 } break;
1237 case DRAW_SPRITE: {
1238 const SkPaint* paint = this->getPaint(reader);
1239 const SkBitmap& bitmap = this->getBitmap(reader);
1240 int left = reader.readInt();
1241 int top = reader.readInt();
1242 canvas.drawSprite(bitmap, left, top, paint);
1243 } break;
1244 case DRAW_TEXT: {
1245 const SkPaint& paint = *this->getPaint(reader);
1246 this->getText(reader, &text);
1247 SkScalar x = reader.readScalar();
1248 SkScalar y = reader.readScalar();
1249 canvas.drawText(text.text(), text.length(), x, y, paint);
1250 } break;
1251 case DRAW_TEXT_TOP_BOTTOM: {
1252 const SkPaint& paint = *this->getPaint(reader);
1253 this->getText(reader, &text);
1254 const SkScalar* ptr = (const SkScalar*)reader.skip(4 * sizeof(Sk Scalar));
1255 // ptr[0] == x
1256 // ptr[1] == y
1257 // ptr[2] == top
1258 // ptr[3] == bottom
1259 if (!canvas.quickRejectY(ptr[2], ptr[3])) {
1260 canvas.drawText(text.text(), text.length(), ptr[0], ptr[1],
1261 paint);
1262 }
1263 } break;
1264 case DRAW_TEXT_ON_PATH: {
1265 const SkPaint& paint = *this->getPaint(reader);
1266 getText(reader, &text);
1267 const SkPath& path = this->getPath(reader);
1268 SkMatrix matrix;
1269 this->getMatrix(reader, &matrix);
1270 canvas.drawTextOnPath(text.text(), text.length(), path, &matrix, paint);
1271 } break;
1272 case DRAW_VERTICES: {
1273 SkAutoTUnref<SkXfermode> xfer;
1274 const SkPaint& paint = *this->getPaint(reader);
1275 DrawVertexFlags flags = (DrawVertexFlags)reader.readInt();
1276 SkCanvas::VertexMode vmode = (SkCanvas::VertexMode)reader.readIn t();
1277 int vCount = reader.readInt();
1278 const SkPoint* verts = (const SkPoint*)reader.skip(
1279 vCount * sizeof(SkPoint));
1280 const SkPoint* texs = NULL;
1281 const SkColor* colors = NULL;
1282 const uint16_t* indices = NULL;
1283 int iCount = 0;
1284 if (flags & DRAW_VERTICES_HAS_TEXS) {
1285 texs = (const SkPoint*)reader.skip(
1286 vCount * sizeof(SkPoint));
1287 }
1288 if (flags & DRAW_VERTICES_HAS_COLORS) {
1289 colors = (const SkColor*)reader.skip(
1290 vCount * sizeof(SkColor));
1291 }
1292 if (flags & DRAW_VERTICES_HAS_INDICES) {
1293 iCount = reader.readInt();
1294 indices = (const uint16_t*)reader.skip(
1295 iCount * sizeof(uint16_t));
1296 }
1297 if (flags & DRAW_VERTICES_HAS_XFER) {
1298 int mode = reader.readInt();
1299 if (mode < 0 || mode > SkXfermode::kLastMode) {
1300 mode = SkXfermode::kModulate_Mode;
1301 }
1302 xfer.reset(SkXfermode::Create((SkXfermode::Mode)mode));
1303 }
1304 canvas.drawVertices(vmode, vCount, verts, texs, colors, xfer,
1305 indices, iCount, paint);
1306 } break;
1307 case RESTORE:
1308 canvas.restore();
1309 break;
1310 case ROTATE:
1311 canvas.rotate(reader.readScalar());
1312 break;
1313 case SAVE:
1314 // SKPs with version < 29 also store a SaveFlags param.
1315 if (size > 4) {
1316 SkASSERT(8 == size);
1317 reader.readInt();
1318 }
1319 canvas.save();
1320 break;
1321 case SAVE_LAYER: {
1322 const SkRect* boundsPtr = this->getRectPtr(reader);
1323 const SkPaint* paint = this->getPaint(reader);
1324 canvas.saveLayer(boundsPtr, paint, (SkCanvas::SaveFlags) reader. readInt());
1325 } break;
1326 case SCALE: {
1327 SkScalar sx = reader.readScalar();
1328 SkScalar sy = reader.readScalar();
1329 canvas.scale(sx, sy);
1330 } break;
1331 case SET_MATRIX: {
1332 SkMatrix matrix;
1333 this->getMatrix(reader, &matrix);
1334 matrix.postConcat(initialMatrix);
1335 canvas.setMatrix(matrix);
1336 } break;
1337 case SKEW: {
1338 SkScalar sx = reader.readScalar();
1339 SkScalar sy = reader.readScalar();
1340 canvas.skew(sx, sy);
1341 } break;
1342 case TRANSLATE: {
1343 SkScalar dx = reader.readScalar();
1344 SkScalar dy = reader.readScalar();
1345 canvas.translate(dx, dy);
1346 } break;
1347 default:
1348 SkASSERT(0);
1349 }
1350
1351 #ifdef SK_DEVELOPER
1352 this->postDraw(opIndex);
1353 #endif
1354
1355 if (it.isValid()) {
1356 uint32_t skipTo = it.nextDraw();
1357 if (kDrawComplete == skipTo) {
1358 break;
1359 }
1360 reader.setOffset(skipTo);
1361 }
1362 }
1363
1364 #ifdef SPEW_CLIP_SKIPPING
1365 {
1366 size_t size = skipRect.fSize + skipRRect.fSize + skipPath.fSize + skipR egion.fSize +
1367 skipCull.fSize;
1368 SkDebugf("--- Clip skips %d%% rect:%d rrect:%d path:%d rgn:%d cull:%d\n" ,
1369 size * 100 / reader.offset(), skipRect.fCount, skipRRect.fCount,
1370 skipPath.fCount, skipRegion.fCount, skipCull.fCount);
1371 SkDebugf("--- Total ops: %d\n", opCount);
1372 }
1373 #endif
1374 // this->dumpSize();
1375 }
1376
1377
1378 #if SK_SUPPORT_GPU 720 #if SK_SUPPORT_GPU
1379 bool SkPictureData::suitableForGpuRasterization(GrContext* context, const char * *reason, 721 bool SkPictureData::suitableForGpuRasterization(GrContext* context, const char * *reason,
1380 int sampleCount) const { 722 int sampleCount) const {
1381 // TODO: the heuristic used here needs to be refined 723 // TODO: the heuristic used here needs to be refined
1382 static const int kNumPaintWithPathEffectUsesTol = 1; 724 static const int kNumPaintWithPathEffectUsesTol = 1;
1383 static const int kNumAAConcavePaths = 5; 725 static const int kNumAAConcavePaths = 5;
1384 726
1385 SkASSERT(fContentInfo.numAAHairlineConcavePaths() <= fContentInfo.numAAConca vePaths()); 727 SkASSERT(fContentInfo.numAAHairlineConcavePaths() <= fContentInfo.numAAConca vePaths());
1386 728
1387 int numNonDashedPathEffects = fContentInfo.numPaintWithPathEffectUses() - 729 int numNonDashedPathEffects = fContentInfo.numPaintWithPathEffectUses() -
(...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after
1743 1085
1744 #define DUMP_SCALAR(name) \ 1086 #define DUMP_SCALAR(name) \
1745 bufferPtr += dumpScalar(bufferPtr, buffer, #name) 1087 bufferPtr += dumpScalar(bufferPtr, buffer, #name)
1746 1088
1747 #define DUMP_TEXT() \ 1089 #define DUMP_TEXT() \
1748 dumpText(&bufferPtr, buffer) 1090 dumpText(&bufferPtr, buffer)
1749 1091
1750 void SkPictureData::dumpStream() { 1092 void SkPictureData::dumpStream() {
1751 SkDebugf("RecordStream stream = {\n"); 1093 SkDebugf("RecordStream stream = {\n");
1752 DrawType drawType; 1094 DrawType drawType;
1753 TextContainer text;
1754 fReadStream.rewind(); 1095 fReadStream.rewind();
1755 char buffer[DUMP_BUFFER_SIZE], * bufferPtr; 1096 char buffer[DUMP_BUFFER_SIZE], * bufferPtr;
1756 while (fReadStream.read(&drawType, sizeof(drawType))) { 1097 while (fReadStream.read(&drawType, sizeof(drawType))) {
1757 bufferPtr = buffer; 1098 bufferPtr = buffer;
1758 DUMP_DRAWTYPE(drawType); 1099 DUMP_DRAWTYPE(drawType);
1759 switch (drawType) { 1100 switch (drawType) {
1760 case CLIP_PATH: { 1101 case CLIP_PATH: {
1761 DUMP_PTR(SkPath, &getPath()); 1102 DUMP_PTR(SkPath, &getPath());
1762 DUMP_INT(SkRegion::Op); 1103 DUMP_INT(SkRegion::Op);
1763 DUMP_INT(offsetToRestore); 1104 DUMP_INT(offsetToRestore);
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
1926 for (index = 0; index < fPictureCount; index++) 1267 for (index = 0; index < fPictureCount; index++)
1927 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer ), 1268 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer ),
1928 "picture%p, ", fPictureRefs[index]); 1269 "picture%p, ", fPictureRefs[index]);
1929 if (fPictureCount > 0) 1270 if (fPictureCount > 0)
1930 SkDebugf("%s0};\n", pBuffer); 1271 SkDebugf("%s0};\n", pBuffer);
1931 1272
1932 const_cast<SkPictureData*>(this)->dumpStream(); 1273 const_cast<SkPictureData*>(this)->dumpStream();
1933 } 1274 }
1934 1275
1935 #endif 1276 #endif
OLDNEW
« no previous file with comments | « src/core/SkPictureData.h ('k') | src/core/SkPicturePlayback.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698