1 /* 2 * Copyright 2011 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #ifndef SkPictureData_DEFINED 9 #define SkPictureData_DEFINED 10 11 #include "SkBitmap.h" 12 #include "SkPathHeap.h" 13 #include "SkPicture.h" 14 #include "SkPictureContentInfo.h" 15 #include "SkPictureFlat.h" 16 #include "SkPictureStateTree.h" 17 18 class SkData; 19 class SkPictureRecord; 20 class SkReader32; 21 class SkStream; 22 class SkWStream; 23 class SkBBoxHierarchy; 24 class SkMatrix; 25 class SkPaint; 26 class SkPath; 27 class SkPictureStateTree; 28 class SkReadBuffer; 29 class SkTextBlob; 30 31 struct SkPictInfo { 32 enum Flags { 33 kCrossProcess_Flag = 1 << 0, 34 kScalarIsFloat_Flag = 1 << 1, 35 kPtrIs64Bit_Flag = 1 << 2, 36 }; 37 38 char fMagic[8]; 39 uint32_t fVersion; 40 SkRect fCullRect; 41 uint32_t fFlags; 42 }; 43 44 #define SK_PICT_READER_TAG SkSetFourByteTag('r', 'e', 'a', 'd') 45 #define SK_PICT_FACTORY_TAG SkSetFourByteTag('f', 'a', 'c', 't') 46 #define SK_PICT_TYPEFACE_TAG SkSetFourByteTag('t', 'p', 'f', 'c') 47 #define SK_PICT_PICTURE_TAG SkSetFourByteTag('p', 'c', 't', 'r') 48 49 // This tag specifies the size of the ReadBuffer, needed for the following tags 50 #define SK_PICT_BUFFER_SIZE_TAG SkSetFourByteTag('a', 'r', 'a', 'y') 51 // these are all inside the ARRAYS tag 52 #define SK_PICT_BITMAP_BUFFER_TAG SkSetFourByteTag('b', 't', 'm', 'p') 53 #define SK_PICT_PAINT_BUFFER_TAG SkSetFourByteTag('p', 'n', 't', ' ') 54 #define SK_PICT_PATH_BUFFER_TAG SkSetFourByteTag('p', 't', 'h', ' ') 55 #define SK_PICT_TEXTBLOB_BUFFER_TAG SkSetFourByteTag('b', 'l', 'o', 'b') 56 57 // Always write this guy last (with no length field afterwards) 58 #define SK_PICT_EOF_TAG SkSetFourByteTag('e', 'o', 'f', ' ') 59 60 #ifdef SK_SUPPORT_LEGACY_PICTURE_CLONE 61 /** 62 * Container for data that is needed to deep copy a SkPicture. The container 63 * enables the data to be generated once and reused for subsequent copies. 64 */ 65 struct SkPictCopyInfo { 66 SkPictCopyInfo() : controller(1024) {} 67 68 SkChunkFlatController controller; 69 SkTDArray<SkFlatData*> paintData; 70 }; 71 #endif 72 73 class SkPictureData { 74 public: 75 #ifdef SK_SUPPORT_LEGACY_PICTURE_CLONE 76 SkPictureData(const SkPictureData& src, SkPictCopyInfo* deepCopyInfo = NULL); 77 #endif 78 SkPictureData(const SkPictureRecord& record, const SkPictInfo&, bool deepCopyOps); 79 static SkPictureData* CreateFromStream(SkStream*, 80 const SkPictInfo&, 81 SkPicture::InstallPixelRefProc); 82 static SkPictureData* CreateFromBuffer(SkReadBuffer&, const SkPictInfo&); 83 84 virtual ~SkPictureData(); 85 86 const SkPicture::OperationList* getActiveOps(const SkRect& queryRect) const; 87 88 void serialize(SkWStream*, SkPicture::EncodeBitmap) const; 89 void flatten(SkWriteBuffer&) const; 90 91 bool containsBitmaps() const; 92 93 bool hasText() const { return fContentInfo.hasText(); } 94 95 int opCount() const { return fContentInfo.numOperations(); } 96 97 const SkData* opData() const { return fOpData; } 98 99 protected: 100 explicit SkPictureData(const SkPictInfo& info); 101 102 bool parseStream(SkStream*, SkPicture::InstallPixelRefProc); 103 bool parseBuffer(SkReadBuffer& buffer); 104 105 public: 106 const SkBitmap& getBitmap(SkReader32* reader) const { 107 const int index = reader->readInt(); 108 if (SkBitmapHeap::INVALID_SLOT == index) { 109 #ifdef SK_DEBUG 110 SkDebugf("An invalid bitmap was recorded!\n"); 111 #endif 112 return fBadBitmap; 113 } 114 return (*fBitmaps)[index]; 115 } 116 117 const SkPath& getPath(SkReader32* reader) const { 118 int index = reader->readInt() - 1; 119 return (*fPathHeap.get())[index]; 120 } 121 122 const SkPicture* getPicture(SkReader32* reader) const { 123 int index = reader->readInt(); 124 SkASSERT(index > 0 && index <= fPictureCount); 125 return fPictureRefs[index - 1]; 126 } 127 128 const SkPaint* getPaint(SkReader32* reader) const { 129 int index = reader->readInt(); 130 if (index == 0) { 131 return NULL; 132 } 133 return &(*fPaints)[index - 1]; 134 } 135 136 const SkTextBlob* getTextBlob(SkReader32* reader) const { 137 int index = reader->readInt(); 138 SkASSERT(index > 0 && index <= fTextBlobCount); 139 return fTextBlobRefs[index - 1]; 140 } 141 142 void initIterator(SkPictureStateTree::Iterator* iter, 143 const SkTDArray<void*>& draws, 144 SkCanvas* canvas) const { 145 if (fStateTree) { 146 fStateTree->initIterator(iter, draws, canvas); 147 } 148 } 149 150 #if SK_SUPPORT_GPU 151 /** 152 * sampleCount is the number of samples-per-pixel or zero if non-MSAA. 153 * It is defaulted to be zero. 154 */ 155 bool suitableForGpuRasterization(GrContext* context, const char **reason, 156 int sampleCount = 0) const; 157 158 /** 159 * Calls getRecommendedSampleCount with GrPixelConfig and dpi to calculate sampleCount 160 * and then calls the above version of suitableForGpuRasterization 161 */ 162 bool suitableForGpuRasterization(GrContext* context, const char **reason, 163 GrPixelConfig config, SkScalar dpi) const; 164 165 bool suitableForLayerOptimization() const; 166 #endif 167 168 private: 169 friend class SkPicture; // needed in SkPicture::clone (rm when it is removed) 170 171 void init(); 172 173 // these help us with reading/writing 174 bool parseStreamTag(SkStream*, uint32_t tag, uint32_t size, SkPicture::InstallPixelRefProc); 175 bool parseBufferTag(SkReadBuffer&, uint32_t tag, uint32_t size); 176 void flattenToBuffer(SkWriteBuffer&) const; 177 178 // Only used by getBitmap() if the passed in index is SkBitmapHeap::INVALID_SLOT. This empty 179 // bitmap allows playback to draw nothing and move on. 180 SkBitmap fBadBitmap; 181 182 SkAutoTUnref<SkBitmapHeap> fBitmapHeap; 183 184 SkTRefArray<SkBitmap>* fBitmaps; 185 SkTRefArray<SkPaint>* fPaints; 186 187 SkData* fOpData; // opcodes and parameters 188 189 SkAutoTUnref<const SkPathHeap> fPathHeap; // reference counted 190 191 const SkPicture** fPictureRefs; 192 int fPictureCount; 193 const SkTextBlob** fTextBlobRefs; 194 int fTextBlobCount; 195 196 SkBBoxHierarchy* fBoundingHierarchy; 197 SkPictureStateTree* fStateTree; 198 199 SkPictureContentInfo fContentInfo; 200 201 SkTypefacePlayback fTFPlayback; 202 SkFactoryPlayback* fFactoryPlayback; 203 204 const SkPictInfo fInfo; 205 206 static void WriteFactories(SkWStream* stream, const SkFactorySet& rec); 207 static void WriteTypefaces(SkWStream* stream, const SkRefCntSet& rec); 208 209 void initForPlayback() const; 210 }; 211 212 #endif 213