SkPicturePlayback.h revision b0430d024572b1a5e5d7b80e406c668e975e3030
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 "SkReadBuffer.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 char fMagic[8]; 43 uint32_t fVersion; 44 uint32_t fWidth; 45 uint32_t fHeight; 46 uint32_t fFlags; 47}; 48 49#define SK_PICT_READER_TAG SkSetFourByteTag('r', 'e', 'a', 'd') 50#define SK_PICT_FACTORY_TAG SkSetFourByteTag('f', 'a', 'c', 't') 51#define SK_PICT_TYPEFACE_TAG SkSetFourByteTag('t', 'p', 'f', 'c') 52#define SK_PICT_PICTURE_TAG SkSetFourByteTag('p', 'c', 't', 'r') 53 54// This tag specifies the size of the ReadBuffer, needed for the following tags 55#define SK_PICT_BUFFER_SIZE_TAG SkSetFourByteTag('a', 'r', 'a', 'y') 56// these are all inside the ARRAYS tag 57#define SK_PICT_BITMAP_BUFFER_TAG SkSetFourByteTag('b', 't', 'm', 'p') 58#define SK_PICT_PAINT_BUFFER_TAG SkSetFourByteTag('p', 'n', 't', ' ') 59#define SK_PICT_PATH_BUFFER_TAG SkSetFourByteTag('p', 't', 'h', ' ') 60 61// Always write this guy last (with no length field afterwards) 62#define SK_PICT_EOF_TAG SkSetFourByteTag('e', 'o', 'f', ' ') 63 64/** 65 * Container for data that is needed to deep copy a SkPicture. The container 66 * enables the data to be generated once and reused for subsequent copies. 67 */ 68struct SkPictCopyInfo { 69 SkPictCopyInfo() : initialized(false), controller(1024) {} 70 71 bool initialized; 72 SkChunkFlatController controller; 73 SkTDArray<SkFlatData*> paintData; 74}; 75 76class SkPicturePlayback { 77public: 78 SkPicturePlayback(const SkPicture* picture, const SkPicturePlayback& src, 79 SkPictCopyInfo* deepCopyInfo = NULL); 80 SkPicturePlayback(const SkPicture* picture, const SkPictureRecord& record, const SkPictInfo&, 81 bool deepCopy = false); 82 static SkPicturePlayback* CreateFromStream(SkPicture* picture, 83 SkStream*, 84 const SkPictInfo&, 85 SkPicture::InstallPixelRefProc); 86 static SkPicturePlayback* CreateFromBuffer(SkPicture* picture, 87 SkReadBuffer&, 88 const SkPictInfo&); 89 90 virtual ~SkPicturePlayback(); 91 92 const SkPicture::OperationList& getActiveOps(const SkIRect& queryRect); 93 94 void draw(SkCanvas& canvas, SkDrawPictureCallback*); 95 96 void serialize(SkWStream*, SkPicture::EncodeBitmap) const; 97 void flatten(SkWriteBuffer&) const; 98 99 void dumpSize() const; 100 101 bool containsBitmaps() const; 102 103#ifdef SK_BUILD_FOR_ANDROID 104 // Can be called in the middle of playback (the draw() call). WIll abort the 105 // drawing and return from draw() after the "current" op code is done 106 void abort() { fAbortCurrentPlayback = true; } 107#endif 108 109 size_t curOpID() const { return fCurOffset; } 110 void resetOpID() { fCurOffset = 0; } 111 112protected: 113 explicit SkPicturePlayback(const SkPicture* picture, const SkPictInfo& info); 114 115 bool parseStream(SkPicture* picture, SkStream*, SkPicture::InstallPixelRefProc); 116 bool parseBuffer(SkPicture* picture, SkReadBuffer& buffer); 117#ifdef SK_DEVELOPER 118 virtual bool preDraw(int opIndex, int type); 119 virtual void postDraw(int opIndex); 120#endif 121 122private: 123 class TextContainer { 124 public: 125 size_t length() { return fByteLength; } 126 const void* text() { return (const void*) fText; } 127 size_t fByteLength; 128 const char* fText; 129 }; 130 131 const SkBitmap& getBitmap(SkReader32& reader) { 132 const int index = reader.readInt(); 133 if (SkBitmapHeap::INVALID_SLOT == index) { 134#ifdef SK_DEBUG 135 SkDebugf("An invalid bitmap was recorded!\n"); 136#endif 137 return fBadBitmap; 138 } 139 return (*fBitmaps)[index]; 140 } 141 142 void getMatrix(SkReader32& reader, SkMatrix* matrix) { 143 reader.readMatrix(matrix); 144 } 145 146 const SkPath& getPath(SkReader32& reader) { 147 return fPicture->getPath(reader.readInt() - 1); 148 } 149 150 SkPicture& getPicture(SkReader32& reader) { 151 int index = reader.readInt(); 152 SkASSERT(index > 0 && index <= fPictureCount); 153 return *fPictureRefs[index - 1]; 154 } 155 156 const SkPaint* getPaint(SkReader32& reader) { 157 int index = reader.readInt(); 158 if (index == 0) { 159 return NULL; 160 } 161 return &(*fPaints)[index - 1]; 162 } 163 164 const SkRect* getRectPtr(SkReader32& reader) { 165 if (reader.readBool()) { 166 return &reader.skipT<SkRect>(); 167 } else { 168 return NULL; 169 } 170 } 171 172 const SkIRect* getIRectPtr(SkReader32& reader) { 173 if (reader.readBool()) { 174 return &reader.skipT<SkIRect>(); 175 } else { 176 return NULL; 177 } 178 } 179 180 void getRegion(SkReader32& reader, SkRegion* region) { 181 reader.readRegion(region); 182 } 183 184 void getText(SkReader32& reader, TextContainer* text) { 185 size_t length = text->fByteLength = reader.readInt(); 186 text->fText = (const char*)reader.skip(length); 187 } 188 189 void init(); 190 191#ifdef SK_DEBUG_SIZE 192public: 193 int size(size_t* sizePtr); 194 int bitmaps(size_t* size); 195 int paints(size_t* size); 196 int paths(size_t* size); 197#endif 198 199#ifdef SK_DEBUG_DUMP 200private: 201 void dumpBitmap(const SkBitmap& bitmap) const; 202 void dumpMatrix(const SkMatrix& matrix) const; 203 void dumpPaint(const SkPaint& paint) const; 204 void dumpPath(const SkPath& path) const; 205 void dumpPicture(const SkPicture& picture) const; 206 void dumpRegion(const SkRegion& region) const; 207 int dumpDrawType(char* bufferPtr, char* buffer, DrawType drawType); 208 int dumpInt(char* bufferPtr, char* buffer, char* name); 209 int dumpRect(char* bufferPtr, char* buffer, char* name); 210 int dumpPoint(char* bufferPtr, char* buffer, char* name); 211 void dumpPointArray(char** bufferPtrPtr, char* buffer, int count); 212 int dumpPtr(char* bufferPtr, char* buffer, char* name, void* ptr); 213 int dumpRectPtr(char* bufferPtr, char* buffer, char* name); 214 int dumpScalar(char* bufferPtr, char* buffer, char* name); 215 void dumpText(char** bufferPtrPtr, char* buffer); 216 void dumpStream(); 217 218public: 219 void dump() const; 220#endif 221 222private: // these help us with reading/writing 223 bool parseStreamTag(SkPicture* picture, SkStream*, uint32_t tag, uint32_t size, 224 SkPicture::InstallPixelRefProc); 225 bool parseBufferTag(SkPicture* picture, SkReadBuffer&, uint32_t tag, uint32_t size); 226 void flattenToBuffer(SkWriteBuffer&) const; 227 228private: 229 // The picture that owns this SkPicturePlayback object 230 const SkPicture* fPicture; 231 232 // Only used by getBitmap() if the passed in index is SkBitmapHeap::INVALID_SLOT. This empty 233 // bitmap allows playback to draw nothing and move on. 234 SkBitmap fBadBitmap; 235 236 SkAutoTUnref<SkBitmapHeap> fBitmapHeap; 237 238 SkTRefArray<SkBitmap>* fBitmaps; 239 SkTRefArray<SkPaint>* fPaints; 240 241 SkData* fOpData; // opcodes and parameters 242 243 SkPicture** fPictureRefs; 244 int fPictureCount; 245 246 SkBBoxHierarchy* fBoundingHierarchy; 247 SkPictureStateTree* fStateTree; 248 249 class CachedOperationList : public SkPicture::OperationList { 250 public: 251 CachedOperationList() { 252 fCacheQueryRect.setEmpty(); 253 } 254 255 virtual bool valid() const { return true; } 256 virtual int numOps() const SK_OVERRIDE { return fOps.count(); } 257 virtual uint32_t offset(int index) const SK_OVERRIDE; 258 virtual const SkMatrix& matrix(int index) const SK_OVERRIDE; 259 260 // The query rect for which the cached active ops are valid 261 SkIRect fCacheQueryRect; 262 263 // The operations which are active within 'fCachedQueryRect' 264 SkTDArray<void*> fOps; 265 266 private: 267 typedef SkPicture::OperationList INHERITED; 268 }; 269 270 CachedOperationList* fCachedActiveOps; 271 272 SkTypefacePlayback fTFPlayback; 273 SkFactoryPlayback* fFactoryPlayback; 274 275 // The offset of the current operation when within the draw method 276 size_t fCurOffset; 277 278 const SkPictInfo fInfo; 279 280 static void WriteFactories(SkWStream* stream, const SkFactorySet& rec); 281 static void WriteTypefaces(SkWStream* stream, const SkRefCntSet& rec); 282 283#ifdef SK_BUILD_FOR_ANDROID 284 SkMutex fDrawMutex; 285 bool fAbortCurrentPlayback; 286#endif 287}; 288 289#endif 290