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