| 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 #include <new> | 7 #include <new> |
| 8 #include "SkBBoxHierarchy.h" | 8 #include "SkBBoxHierarchy.h" |
| 9 #include "SkPicturePlayback.h" | 9 #include "SkPicturePlayback.h" |
| 10 #include "SkPictureRecord.h" | 10 #include "SkPictureRecord.h" |
| (...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 198 fBitmaps = NULL; | 198 fBitmaps = NULL; |
| 199 fPaints = NULL; | 199 fPaints = NULL; |
| 200 fPictureRefs = NULL; | 200 fPictureRefs = NULL; |
| 201 fPictureCount = 0; | 201 fPictureCount = 0; |
| 202 fOpData = NULL; | 202 fOpData = NULL; |
| 203 fFactoryPlayback = NULL; | 203 fFactoryPlayback = NULL; |
| 204 fBoundingHierarchy = NULL; | 204 fBoundingHierarchy = NULL; |
| 205 fStateTree = NULL; | 205 fStateTree = NULL; |
| 206 fCachedActiveOps = NULL; | 206 fCachedActiveOps = NULL; |
| 207 fCurOffset = 0; | 207 fCurOffset = 0; |
| 208 fUseBBH = true; |
| 209 fStart = 0; |
| 210 fStop = 0; |
| 211 fReplacements = NULL; |
| 208 } | 212 } |
| 209 | 213 |
| 210 SkPicturePlayback::~SkPicturePlayback() { | 214 SkPicturePlayback::~SkPicturePlayback() { |
| 211 SkSafeUnref(fOpData); | 215 SkSafeUnref(fOpData); |
| 212 | 216 |
| 213 SkSafeUnref(fBitmaps); | 217 SkSafeUnref(fBitmaps); |
| 214 SkSafeUnref(fPaints); | 218 SkSafeUnref(fPaints); |
| 215 SkSafeUnref(fBoundingHierarchy); | 219 SkSafeUnref(fBoundingHierarchy); |
| 216 SkSafeUnref(fStateTree); | 220 SkSafeUnref(fStateTree); |
| 217 | 221 |
| (...skipping 519 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 737 ~SkAutoResetOpID() { | 741 ~SkAutoResetOpID() { |
| 738 if (NULL != fPlayback) { | 742 if (NULL != fPlayback) { |
| 739 fPlayback->resetOpID(); | 743 fPlayback->resetOpID(); |
| 740 } | 744 } |
| 741 } | 745 } |
| 742 | 746 |
| 743 private: | 747 private: |
| 744 SkPicturePlayback* fPlayback; | 748 SkPicturePlayback* fPlayback; |
| 745 }; | 749 }; |
| 746 | 750 |
| 751 // TODO: Replace with hash or pass in "lastLookedUp" hint |
| 752 SkPicturePlayback::PlaybackReplacements::ReplacementInfo* |
| 753 SkPicturePlayback::PlaybackReplacements::lookupByStart(size_t start) { |
| 754 SkDEBUGCODE(this->validate()); |
| 755 for (int i = 0; i < fReplacements.count(); ++i) { |
| 756 if (start == fReplacements[i].fStart) { |
| 757 return &fReplacements[i]; |
| 758 } else if (start < fReplacements[i].fStart) { |
| 759 return NULL; // the ranges are monotonically increasing and non-ove
rlapping |
| 760 } |
| 761 } |
| 762 |
| 763 return NULL; |
| 764 } |
| 765 |
| 747 void SkPicturePlayback::draw(SkCanvas& canvas, SkDrawPictureCallback* callback)
{ | 766 void SkPicturePlayback::draw(SkCanvas& canvas, SkDrawPictureCallback* callback)
{ |
| 748 SkAutoResetOpID aroi(this); | 767 SkAutoResetOpID aroi(this); |
| 749 SkASSERT(0 == fCurOffset); | 768 SkASSERT(0 == fCurOffset); |
| 750 | 769 |
| 751 #ifdef ENABLE_TIME_DRAW | 770 #ifdef ENABLE_TIME_DRAW |
| 752 SkAutoTime at("SkPicture::draw", 50); | 771 SkAutoTime at("SkPicture::draw", 50); |
| 753 #endif | 772 #endif |
| 754 | 773 |
| 755 #ifdef SPEW_CLIP_SKIPPING | 774 #ifdef SPEW_CLIP_SKIPPING |
| 756 SkipClipRec skipRect, skipRRect, skipRegion, skipPath, skipCull; | 775 SkipClipRec skipRect, skipRRect, skipRegion, skipPath, skipCull; |
| 757 int opCount = 0; | 776 int opCount = 0; |
| 758 #endif | 777 #endif |
| 759 | 778 |
| 760 #ifdef SK_BUILD_FOR_ANDROID | 779 #ifdef SK_BUILD_FOR_ANDROID |
| 761 SkAutoMutexAcquire autoMutex(fDrawMutex); | 780 SkAutoMutexAcquire autoMutex(fDrawMutex); |
| 762 #endif | 781 #endif |
| 763 | 782 |
| 764 // kDrawComplete will be the signal that we have reached the end of | 783 // kDrawComplete will be the signal that we have reached the end of |
| 765 // the command stream | 784 // the command stream |
| 766 static const uint32_t kDrawComplete = SK_MaxU32; | 785 static const uint32_t kDrawComplete = SK_MaxU32; |
| 767 | 786 |
| 768 SkReader32 reader(fOpData->bytes(), fOpData->size()); | 787 SkReader32 reader(fOpData->bytes(), fOpData->size()); |
| 769 TextContainer text; | 788 TextContainer text; |
| 770 const SkTDArray<void*>* activeOps = NULL; | 789 const SkTDArray<void*>* activeOps = NULL; |
| 771 | 790 |
| 772 if (NULL != fStateTree && NULL != fBoundingHierarchy) { | 791 // When draw limits are enabled (i.e., 0 != fStart || 0 != fStop) the state |
| 773 SkRect clipBounds; | 792 // tree isn't used to pick and choose the draw operations |
| 774 if (canvas.getClipBounds(&clipBounds)) { | 793 if (0 == fStart && 0 == fStop) { |
| 775 SkIRect query; | 794 if (fUseBBH && NULL != fStateTree && NULL != fBoundingHierarchy) { |
| 776 clipBounds.roundOut(&query); | 795 SkRect clipBounds; |
| 796 if (canvas.getClipBounds(&clipBounds)) { |
| 797 SkIRect query; |
| 798 clipBounds.roundOut(&query); |
| 777 | 799 |
| 778 const SkPicture::OperationList& activeOpsList = this->getActiveOps(q
uery); | 800 const SkPicture::OperationList& activeOpsList = this->getActiveO
ps(query); |
| 779 if (activeOpsList.valid()) { | 801 if (activeOpsList.valid()) { |
| 780 if (0 == activeOpsList.numOps()) { | 802 if (0 == activeOpsList.numOps()) { |
| 781 return; // nothing to draw | 803 return; // nothing to draw |
| 804 } |
| 805 |
| 806 // Since the opList is valid we know it is our derived class |
| 807 activeOps = &((const CachedOperationList&)activeOpsList).fOp
s; |
| 782 } | 808 } |
| 783 | |
| 784 // Since the opList is valid we know it is our derived class | |
| 785 activeOps = &((const CachedOperationList&)activeOpsList).fOps; | |
| 786 } | 809 } |
| 787 } | 810 } |
| 788 } | 811 } |
| 789 | 812 |
| 790 SkPictureStateTree::Iterator it = (NULL == activeOps) ? | 813 SkPictureStateTree::Iterator it = (NULL == activeOps) ? |
| 791 SkPictureStateTree::Iterator() : | 814 SkPictureStateTree::Iterator() : |
| 792 fStateTree->getIterator(*activeOps, &canvas); | 815 fStateTree->getIterator(*activeOps, &canvas); |
| 793 | 816 |
| 817 if (0 != fStart || 0 != fStop) { |
| 818 reader.setOffset(fStart); |
| 819 uint32_t size; |
| 820 SkDEBUGCODE(DrawType op =) read_op_and_size(&reader, &size); |
| 821 SkASSERT(SAVE_LAYER == op); |
| 822 reader.setOffset(fStart+size); |
| 823 } |
| 824 |
| 794 if (it.isValid()) { | 825 if (it.isValid()) { |
| 795 uint32_t skipTo = it.nextDraw(); | 826 uint32_t skipTo = it.nextDraw(); |
| 796 if (kDrawComplete == skipTo) { | 827 if (kDrawComplete == skipTo) { |
| 797 return; | 828 return; |
| 798 } | 829 } |
| 799 reader.setOffset(skipTo); | 830 reader.setOffset(skipTo); |
| 800 } | 831 } |
| 801 | 832 |
| 802 // Record this, so we can concat w/ it if we encounter a setMatrix() | 833 // Record this, so we can concat w/ it if we encounter a setMatrix() |
| 803 SkMatrix initialMatrix = canvas.getTotalMatrix(); | 834 SkMatrix initialMatrix = canvas.getTotalMatrix(); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 814 while (!reader.eof()) { | 845 while (!reader.eof()) { |
| 815 if (callback && callback->abortDrawing()) { | 846 if (callback && callback->abortDrawing()) { |
| 816 canvas.restoreToCount(originalSaveCount); | 847 canvas.restoreToCount(originalSaveCount); |
| 817 return; | 848 return; |
| 818 } | 849 } |
| 819 #ifdef SK_BUILD_FOR_ANDROID | 850 #ifdef SK_BUILD_FOR_ANDROID |
| 820 if (fAbortCurrentPlayback) { | 851 if (fAbortCurrentPlayback) { |
| 821 return; | 852 return; |
| 822 } | 853 } |
| 823 #endif | 854 #endif |
| 855 if (0 != fStart || 0 != fStop) { |
| 856 size_t offset = reader.offset() ; |
| 857 if (offset >= fStop) { |
| 858 uint32_t size; |
| 859 SkDEBUGCODE(DrawType op =) read_op_and_size(&reader, &size); |
| 860 SkASSERT(RESTORE == op); |
| 861 return; |
| 862 } |
| 863 } |
| 864 |
| 865 if (NULL != fReplacements) { |
| 866 // Potentially replace a block of operations with a single drawBitma
p call |
| 867 SkPicturePlayback::PlaybackReplacements::ReplacementInfo* temp = |
| 868 fReplacements->lookupByStart(reader.
offset()); |
| 869 if (NULL != temp) { |
| 870 SkASSERT(NULL != temp->fBM); |
| 871 SkASSERT(NULL != temp->fPaint); |
| 872 canvas.drawBitmap(*temp->fBM, temp->fPos.fX, temp->fPos.fY, temp
->fPaint); |
| 873 |
| 874 if (it.isValid()) { |
| 875 // This save is needed since the BBH will automatically issu
e |
| 876 // a restore to balanced the saveLayer we're skipping |
| 877 canvas.save(); |
| 878 // Note: This skipping only works if the client only issues |
| 879 // well behaved saveLayer calls (i.e., doesn't use |
| 880 // kMatrix_SaveFlag or kClip_SaveFlag in isolation) |
| 881 |
| 882 // At this point we know that the PictureStateTree was aimin
g |
| 883 // for some draw op within temp's saveLayer (although potent
ially |
| 884 // in a separate saveLayer nested inside it). |
| 885 // We need to skip all the operations inside temp's range |
| 886 // along with all the associated state changes but update |
| 887 // the state tree to the first operation outside temp's rang
e. |
| 888 SkASSERT(it.peekDraw() >= temp->fStart && it.peekDraw() <= t
emp->fStop); |
| 889 |
| 890 while (kDrawComplete != it.peekDraw() && it.peekDraw() <= te
mp->fStop) { |
| 891 it.skipDraw(); |
| 892 } |
| 893 |
| 894 if (kDrawComplete == it.peekDraw()) { |
| 895 break; |
| 896 } |
| 897 |
| 898 uint32_t skipTo = it.nextDraw(); |
| 899 reader.setOffset(skipTo); |
| 900 } else { |
| 901 reader.setOffset(temp->fStop); |
| 902 uint32_t size; |
| 903 SkDEBUGCODE(DrawType op =) read_op_and_size(&reader, &size); |
| 904 SkASSERT(RESTORE == op); |
| 905 } |
| 906 continue; |
| 907 } |
| 908 } |
| 824 | 909 |
| 825 #ifdef SPEW_CLIP_SKIPPING | 910 #ifdef SPEW_CLIP_SKIPPING |
| 826 opCount++; | 911 opCount++; |
| 827 #endif | 912 #endif |
| 828 | 913 |
| 829 fCurOffset = reader.offset(); | 914 fCurOffset = reader.offset(); |
| 830 uint32_t size; | 915 uint32_t size; |
| 831 DrawType op = read_op_and_size(&reader, &size); | 916 DrawType op = read_op_and_size(&reader, &size); |
| 832 size_t skipTo = 0; | 917 size_t skipTo = 0; |
| 833 if (NOOP == op) { | 918 if (NOOP == op) { |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 908 reader.setOffset(offsetToRestore); | 993 reader.setOffset(offsetToRestore); |
| 909 } | 994 } |
| 910 } break; | 995 } break; |
| 911 case CLIP_RRECT: { | 996 case CLIP_RRECT: { |
| 912 SkRRect rrect; | 997 SkRRect rrect; |
| 913 reader.readRRect(&rrect); | 998 reader.readRRect(&rrect); |
| 914 uint32_t packed = reader.readInt(); | 999 uint32_t packed = reader.readInt(); |
| 915 SkRegion::Op regionOp = ClipParams_unpackRegionOp(packed); | 1000 SkRegion::Op regionOp = ClipParams_unpackRegionOp(packed); |
| 916 bool doAA = ClipParams_unpackDoAA(packed); | 1001 bool doAA = ClipParams_unpackDoAA(packed); |
| 917 size_t offsetToRestore = reader.readInt(); | 1002 size_t offsetToRestore = reader.readInt(); |
| 918 SkASSERT(!offsetToRestore || \ | 1003 SkASSERT(!offsetToRestore || offsetToRestore >= reader.offset())
; |
| 919 offsetToRestore >= reader.offset()); | |
| 920 canvas.clipRRect(rrect, regionOp, doAA); | 1004 canvas.clipRRect(rrect, regionOp, doAA); |
| 921 if (canvas.isClipEmpty() && offsetToRestore) { | 1005 if (canvas.isClipEmpty() && offsetToRestore) { |
| 922 #ifdef SPEW_CLIP_SKIPPING | 1006 #ifdef SPEW_CLIP_SKIPPING |
| 923 skipRRect.recordSkip(offsetToRestore - reader.offset()); | 1007 skipRRect.recordSkip(offsetToRestore - reader.offset()); |
| 924 #endif | 1008 #endif |
| 925 reader.setOffset(offsetToRestore); | 1009 reader.setOffset(offsetToRestore); |
| 926 } | 1010 } |
| 927 } break; | 1011 } break; |
| 928 case PUSH_CULL: { | 1012 case PUSH_CULL: { |
| 929 const SkRect& cullRect = reader.skipT<SkRect>(); | 1013 const SkRect& cullRect = reader.skipT<SkRect>(); |
| (...skipping 782 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1712 for (index = 0; index < fPictureCount; index++) | 1796 for (index = 0; index < fPictureCount; index++) |
| 1713 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer
), | 1797 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer
), |
| 1714 "picture%p, ", fPictureRefs[index]); | 1798 "picture%p, ", fPictureRefs[index]); |
| 1715 if (fPictureCount > 0) | 1799 if (fPictureCount > 0) |
| 1716 SkDebugf("%s0};\n", pBuffer); | 1800 SkDebugf("%s0};\n", pBuffer); |
| 1717 | 1801 |
| 1718 const_cast<SkPicturePlayback*>(this)->dumpStream(); | 1802 const_cast<SkPicturePlayback*>(this)->dumpStream(); |
| 1719 } | 1803 } |
| 1720 | 1804 |
| 1721 #endif | 1805 #endif |
| OLD | NEW |