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

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

Issue 261663003: First pass at pre-rendering saveLayers for GPU (Closed) Base URL: http://skia.googlecode.com/svn/trunk/
Patch Set: Fixed comments Created 6 years, 7 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 | Annotate | Revision Log
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 "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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698