1 2 /* 3 * Copyright 2011 Google Inc. 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 */ 8 #ifndef SkPicturePlayback_DEFINED 9 #define SkPicturePlayback_DEFINED 10 11 #include "SkPicture.h" 12 #include "SkReader32.h" 13 14 #include "SkBitmap.h" 15 #include "SkData.h" 16 #include "SkMatrix.h" 17 #include "SkOrderedReadBuffer.h" 18 #include "SkPaint.h" 19 #include "SkPath.h" 20 #include "SkPathHeap.h" 21 #include "SkRegion.h" 22 #include "SkRRect.h" 23 #include "SkPictureFlat.h" 24 25 #ifdef SK_BUILD_FOR_ANDROID 26 #include "SkThread.h" 27 #endif 28 29 class SkPictureRecord; 30 class SkStream; 31 class SkWStream; 32 class SkBBoxHierarchy; 33 class SkPictureStateTree; 34 35 struct SkPictInfo { 36 enum Flags { 37 kCrossProcess_Flag = 1 << 0, 38 kScalarIsFloat_Flag = 1 << 1, 39 kPtrIs64Bit_Flag = 1 << 2, 40 }; 41 42 uint32_t fVersion; 43 uint32_t fWidth; 44 uint32_t fHeight; 45 uint32_t fFlags; 46 }; 47 48 /** 49 * Container for data that is needed to deep copy a SkPicture. The container 50 * enables the data to be generated once and reused for subsequent copies. 51 */ 52 struct SkPictCopyInfo { SkPictCopyInfoSkPictCopyInfo53 SkPictCopyInfo() : initialized(false), controller(1024) {} 54 55 bool initialized; 56 SkChunkFlatController controller; 57 SkTDArray<SkFlatData*> paintData; 58 }; 59 60 class SkPicturePlayback { 61 public: 62 SkPicturePlayback(); 63 SkPicturePlayback(const SkPicturePlayback& src, SkPictCopyInfo* deepCopyInfo = NULL); 64 explicit SkPicturePlayback(const SkPictureRecord& record, bool deepCopy = false); 65 static SkPicturePlayback* CreateFromStream(SkStream*, const SkPictInfo&, 66 SkPicture::InstallPixelRefProc); 67 68 virtual ~SkPicturePlayback(); 69 70 void draw(SkCanvas& canvas, SkDrawPictureCallback*); 71 72 void serialize(SkWStream*, SkPicture::EncodeBitmap) const; 73 74 void dumpSize() const; 75 76 bool containsBitmaps() const; 77 78 #ifdef SK_BUILD_FOR_ANDROID 79 // Can be called in the middle of playback (the draw() call). WIll abort the 80 // drawing and return from draw() after the "current" op code is done abort()81 void abort() { fAbortCurrentPlayback = true; } 82 #endif 83 84 protected: 85 bool parseStream(SkStream*, const SkPictInfo&, 86 SkPicture::InstallPixelRefProc); 87 #ifdef SK_DEVELOPER 88 virtual bool preDraw(int opIndex, int type); 89 virtual void postDraw(int opIndex); 90 #endif 91 92 private: 93 class TextContainer { 94 public: length()95 size_t length() { return fByteLength; } text()96 const void* text() { return (const void*) fText; } 97 size_t fByteLength; 98 const char* fText; 99 }; 100 getBitmap(SkReader32 & reader)101 const SkBitmap& getBitmap(SkReader32& reader) { 102 const int index = reader.readInt(); 103 if (SkBitmapHeap::INVALID_SLOT == index) { 104 #ifdef SK_DEBUG 105 SkDebugf("An invalid bitmap was recorded!\n"); 106 #endif 107 return fBadBitmap; 108 } 109 return (*fBitmaps)[index]; 110 } 111 getMatrix(SkReader32 & reader)112 const SkMatrix* getMatrix(SkReader32& reader) { 113 int index = reader.readInt(); 114 if (index == 0) { 115 return NULL; 116 } 117 return &(*fMatrices)[index - 1]; 118 } 119 getPath(SkReader32 & reader)120 const SkPath& getPath(SkReader32& reader) { 121 return (*fPathHeap)[reader.readInt() - 1]; 122 } 123 getPicture(SkReader32 & reader)124 SkPicture& getPicture(SkReader32& reader) { 125 int index = reader.readInt(); 126 SkASSERT(index > 0 && index <= fPictureCount); 127 return *fPictureRefs[index - 1]; 128 } 129 getPaint(SkReader32 & reader)130 const SkPaint* getPaint(SkReader32& reader) { 131 int index = reader.readInt(); 132 if (index == 0) { 133 return NULL; 134 } 135 return &(*fPaints)[index - 1]; 136 } 137 getRectPtr(SkReader32 & reader)138 const SkRect* getRectPtr(SkReader32& reader) { 139 if (reader.readBool()) { 140 return &reader.skipT<SkRect>(); 141 } else { 142 return NULL; 143 } 144 } 145 getIRectPtr(SkReader32 & reader)146 const SkIRect* getIRectPtr(SkReader32& reader) { 147 if (reader.readBool()) { 148 return &reader.skipT<SkIRect>(); 149 } else { 150 return NULL; 151 } 152 } 153 getRegion(SkReader32 & reader)154 const SkRegion& getRegion(SkReader32& reader) { 155 int index = reader.readInt(); 156 return (*fRegions)[index - 1]; 157 } 158 getText(SkReader32 & reader,TextContainer * text)159 void getText(SkReader32& reader, TextContainer* text) { 160 size_t length = text->fByteLength = reader.readInt(); 161 text->fText = (const char*)reader.skip(length); 162 } 163 164 void init(); 165 166 #ifdef SK_DEBUG_SIZE 167 public: 168 int size(size_t* sizePtr); 169 int bitmaps(size_t* size); 170 int paints(size_t* size); 171 int paths(size_t* size); 172 int regions(size_t* size); 173 #endif 174 175 #ifdef SK_DEBUG_DUMP 176 private: 177 void dumpBitmap(const SkBitmap& bitmap) const; 178 void dumpMatrix(const SkMatrix& matrix) const; 179 void dumpPaint(const SkPaint& paint) const; 180 void dumpPath(const SkPath& path) const; 181 void dumpPicture(const SkPicture& picture) const; 182 void dumpRegion(const SkRegion& region) const; 183 int dumpDrawType(char* bufferPtr, char* buffer, DrawType drawType); 184 int dumpInt(char* bufferPtr, char* buffer, char* name); 185 int dumpRect(char* bufferPtr, char* buffer, char* name); 186 int dumpPoint(char* bufferPtr, char* buffer, char* name); 187 void dumpPointArray(char** bufferPtrPtr, char* buffer, int count); 188 int dumpPtr(char* bufferPtr, char* buffer, char* name, void* ptr); 189 int dumpRectPtr(char* bufferPtr, char* buffer, char* name); 190 int dumpScalar(char* bufferPtr, char* buffer, char* name); 191 void dumpText(char** bufferPtrPtr, char* buffer); 192 void dumpStream(); 193 194 public: 195 void dump() const; 196 #endif 197 198 private: // these help us with reading/writing 199 bool parseStreamTag(SkStream*, const SkPictInfo&, uint32_t tag, size_t size, 200 SkPicture::InstallPixelRefProc); 201 bool parseBufferTag(SkOrderedReadBuffer&, uint32_t tag, size_t size); 202 void flattenToBuffer(SkOrderedWriteBuffer&) const; 203 204 private: 205 // Only used by getBitmap() if the passed in index is SkBitmapHeap::INVALID_SLOT. This empty 206 // bitmap allows playback to draw nothing and move on. 207 SkBitmap fBadBitmap; 208 209 SkAutoTUnref<SkBitmapHeap> fBitmapHeap; 210 SkAutoTUnref<SkPathHeap> fPathHeap; 211 212 SkTRefArray<SkBitmap>* fBitmaps; 213 SkTRefArray<SkMatrix>* fMatrices; 214 SkTRefArray<SkPaint>* fPaints; 215 SkTRefArray<SkRegion>* fRegions; 216 217 SkData* fOpData; // opcodes and parameters 218 219 SkPicture** fPictureRefs; 220 int fPictureCount; 221 222 SkBBoxHierarchy* fBoundingHierarchy; 223 SkPictureStateTree* fStateTree; 224 225 SkTypefacePlayback fTFPlayback; 226 SkFactoryPlayback* fFactoryPlayback; 227 #ifdef SK_BUILD_FOR_ANDROID 228 SkMutex fDrawMutex; 229 bool fAbortCurrentPlayback; 230 #endif 231 }; 232 233 #endif 234