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 29class SkPictureRecord; 30class SkStream; 31class SkWStream; 32class SkBBoxHierarchy; 33class SkPictureStateTree; 34 35struct 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 */ 52struct SkPictCopyInfo { 53 SkPictCopyInfo() : initialized(false), controller(1024) {} 54 55 bool initialized; 56 SkChunkFlatController controller; 57 SkTDArray<SkFlatData*> paintData; 58}; 59 60class SkPicturePlayback { 61public: 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 81 void abort() { fAbortCurrentPlayback = true; } 82#endif 83 84protected: 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 92private: 93 class TextContainer { 94 public: 95 size_t length() { return fByteLength; } 96 const void* text() { return (const void*) fText; } 97 size_t fByteLength; 98 const char* fText; 99 }; 100 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 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 120 const SkPath& getPath(SkReader32& reader) { 121 return (*fPathHeap)[reader.readInt() - 1]; 122 } 123 124 SkPicture& getPicture(SkReader32& reader) { 125 int index = reader.readInt(); 126 SkASSERT(index > 0 && index <= fPictureCount); 127 return *fPictureRefs[index - 1]; 128 } 129 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 138 const SkRect* getRectPtr(SkReader32& reader) { 139 if (reader.readBool()) { 140 return &reader.skipT<SkRect>(); 141 } else { 142 return NULL; 143 } 144 } 145 146 const SkIRect* getIRectPtr(SkReader32& reader) { 147 if (reader.readBool()) { 148 return &reader.skipT<SkIRect>(); 149 } else { 150 return NULL; 151 } 152 } 153 154 const SkRegion& getRegion(SkReader32& reader) { 155 int index = reader.readInt(); 156 return (*fRegions)[index - 1]; 157 } 158 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 167public: 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 176private: 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 194public: 195 void dump() const; 196#endif 197 198private: // 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 204private: 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