SkPictureRecord.h revision af641a1c10f176cb9617026d3cc93c117a85d13d
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 SkPictureRecord_DEFINED 9#define SkPictureRecord_DEFINED 10 11#include "SkCanvas.h" 12#include "SkFlattenable.h" 13#include "SkPicture.h" 14#include "SkPictureData.h" 15#include "SkTemplates.h" 16#include "SkWriter32.h" 17 18// These macros help with packing and unpacking a single byte value and 19// a 3 byte value into/out of a uint32_t 20#define MASK_24 0x00FFFFFF 21#define UNPACK_8_24(combined, small, large) \ 22 small = (combined >> 24) & 0xFF; \ 23 large = combined & MASK_24; 24#define PACK_8_24(small, large) ((small << 24) | large) 25 26 27class SkPictureRecord : public SkCanvas { 28public: 29 SkPictureRecord(const SkISize& dimensions, uint32_t recordFlags); 30 virtual ~SkPictureRecord(); 31 32 virtual void clear(SkColor) SK_OVERRIDE; 33 virtual void drawPaint(const SkPaint& paint) SK_OVERRIDE; 34 virtual void drawPoints(PointMode, size_t count, const SkPoint pts[], 35 const SkPaint&) SK_OVERRIDE; 36 virtual void drawOval(const SkRect&, const SkPaint&) SK_OVERRIDE; 37 virtual void drawRect(const SkRect&, const SkPaint&) SK_OVERRIDE; 38 virtual void drawRRect(const SkRRect&, const SkPaint&) SK_OVERRIDE; 39 virtual void drawPath(const SkPath& path, const SkPaint&) SK_OVERRIDE; 40 virtual void drawBitmap(const SkBitmap&, SkScalar left, SkScalar top, 41 const SkPaint*) SK_OVERRIDE; 42 virtual void drawBitmapRectToRect(const SkBitmap&, const SkRect* src, 43 const SkRect& dst, const SkPaint* paint, 44 DrawBitmapRectFlags flags) SK_OVERRIDE; 45 virtual void drawBitmapMatrix(const SkBitmap&, const SkMatrix&, 46 const SkPaint*) SK_OVERRIDE; 47 virtual void drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, 48 const SkRect& dst, const SkPaint*) SK_OVERRIDE; 49 virtual void drawSprite(const SkBitmap&, int left, int top, 50 const SkPaint*) SK_OVERRIDE; 51 virtual void drawVertices(VertexMode, int vertexCount, 52 const SkPoint vertices[], const SkPoint texs[], 53 const SkColor colors[], SkXfermode*, 54 const uint16_t indices[], int indexCount, 55 const SkPaint&) SK_OVERRIDE; 56 virtual void drawData(const void*, size_t) SK_OVERRIDE; 57 virtual void beginCommentGroup(const char* description) SK_OVERRIDE; 58 virtual void addComment(const char* kywd, const char* value) SK_OVERRIDE; 59 virtual void endCommentGroup() SK_OVERRIDE; 60 virtual bool isDrawingToLayer() const SK_OVERRIDE; 61 62 const SkTDArray<const SkPicture* >& getPictureRefs() const { 63 return fPictureRefs; 64 } 65 66 const SkTDArray<const SkTextBlob* >& getTextBlobRefs() const { 67 return fTextBlobRefs; 68 } 69 70 SkData* opData(bool deepCopy) const { 71 this->validate(fWriter.bytesWritten(), 0); 72 73 if (fWriter.bytesWritten() == 0) { 74 return SkData::NewEmpty(); 75 } 76 77 if (deepCopy) { 78 return SkData::NewWithCopy(fWriter.contiguousArray(), fWriter.bytesWritten()); 79 } 80 81 return fWriter.snapshotAsData(); 82 } 83 84 const SkPictureContentInfo& contentInfo() const { 85 return fContentInfo; 86 } 87 88 void setFlags(uint32_t recordFlags) { 89 fRecordFlags = recordFlags; 90 } 91 92 const SkWriter32& writeStream() const { 93 return fWriter; 94 } 95 96 void beginRecording(); 97 void endRecording(); 98 99protected: 100 void addNoOp(); 101 102private: 103 void handleOptimization(int opt); 104 size_t recordRestoreOffsetPlaceholder(SkRegion::Op); 105 void fillRestoreOffsetPlaceholdersForCurrentStackLevel(uint32_t restoreOffset); 106 107 SkTDArray<int32_t> fRestoreOffsetStack; 108 int fFirstSavedLayerIndex; 109 enum { 110 kNoSavedLayerIndex = -1 111 }; 112 113 SkTDArray<uint32_t> fCullOffsetStack; 114 115 /* 116 * Write the 'drawType' operation and chunk size to the skp. 'size' 117 * can potentially be increased if the chunk size needs its own storage 118 * location (i.e., it overflows 24 bits). 119 * Returns the start offset of the chunk. This is the location at which 120 * the opcode & size are stored. 121 * TODO: since we are handing the size into here we could call reserve 122 * and then return a pointer to the memory storage. This could decrease 123 * allocation overhead but could lead to more wasted space (the tail 124 * end of blocks could go unused). Possibly add a second addDraw that 125 * operates in this manner. 126 */ 127 size_t addDraw(DrawType drawType, size_t* size) { 128 size_t offset = fWriter.bytesWritten(); 129 130 this->predrawNotify(); 131 fContentInfo.addOperation(); 132 133 SkASSERT(0 != *size); 134 SkASSERT(((uint8_t) drawType) == drawType); 135 136 if (0 != (*size & ~MASK_24) || *size == MASK_24) { 137 fWriter.writeInt(PACK_8_24(drawType, MASK_24)); 138 *size += 1; 139 fWriter.writeInt(SkToU32(*size)); 140 } else { 141 fWriter.writeInt(PACK_8_24(drawType, SkToU32(*size))); 142 } 143 144 return offset; 145 } 146 147 void addInt(int value) { 148 fWriter.writeInt(value); 149 } 150 void addScalar(SkScalar scalar) { 151 fWriter.writeScalar(scalar); 152 } 153 154 void addBitmap(const SkBitmap& bitmap); 155 void addMatrix(const SkMatrix& matrix); 156 void addPaint(const SkPaint& paint) { this->addPaintPtr(&paint); } 157 void addPaintPtr(const SkPaint* paint); 158 void addPatch(const SkPoint cubics[12]); 159 void addPath(const SkPath& path); 160 void addPicture(const SkPicture* picture); 161 void addPoint(const SkPoint& point); 162 void addPoints(const SkPoint pts[], int count); 163 void addRect(const SkRect& rect); 164 void addRectPtr(const SkRect* rect); 165 void addIRect(const SkIRect& rect); 166 void addIRectPtr(const SkIRect* rect); 167 void addRRect(const SkRRect&); 168 void addRegion(const SkRegion& region); 169 void addText(const void* text, size_t byteLength); 170 void addTextBlob(const SkTextBlob* blob); 171 172 int find(const SkBitmap& bitmap); 173 174protected: 175 void validate(size_t initialOffset, size_t size) const { 176 SkASSERT(fWriter.bytesWritten() == initialOffset + size); 177 } 178 179 virtual SkSurface* onNewSurface(const SkImageInfo&, const SkSurfaceProps&) SK_OVERRIDE; 180 const void* onPeekPixels(SkImageInfo*, size_t*) SK_OVERRIDE { 181 return NULL; 182 } 183 184 virtual void willSave() SK_OVERRIDE; 185 virtual SaveLayerStrategy willSaveLayer(const SkRect*, const SkPaint*, SaveFlags) SK_OVERRIDE; 186 virtual void willRestore() SK_OVERRIDE; 187 188 virtual void didConcat(const SkMatrix&) SK_OVERRIDE; 189 virtual void didSetMatrix(const SkMatrix&) SK_OVERRIDE; 190 191 virtual void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&) SK_OVERRIDE; 192 virtual void onPushCull(const SkRect&) SK_OVERRIDE; 193 virtual void onPopCull() SK_OVERRIDE; 194 195 virtual void onDrawText(const void* text, size_t byteLength, SkScalar x, SkScalar y, 196 const SkPaint&) SK_OVERRIDE; 197 virtual void onDrawPosText(const void* text, size_t byteLength, const SkPoint pos[], 198 const SkPaint&) SK_OVERRIDE; 199 virtual void onDrawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], 200 SkScalar constY, const SkPaint&) SK_OVERRIDE; 201 virtual void onDrawTextOnPath(const void* text, size_t byteLength, const SkPath& path, 202 const SkMatrix* matrix, const SkPaint&) SK_OVERRIDE; 203 virtual void onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, 204 const SkPaint& paint) SK_OVERRIDE; 205 206 virtual void onDrawPatch(const SkPoint cubics[12], const SkColor colors[4], 207 const SkPoint texCoords[4], SkXfermode* xmode, 208 const SkPaint& paint) SK_OVERRIDE; 209 210 virtual void onClipRect(const SkRect&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE; 211 virtual void onClipRRect(const SkRRect&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE; 212 virtual void onClipPath(const SkPath&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE; 213 virtual void onClipRegion(const SkRegion&, SkRegion::Op) SK_OVERRIDE; 214 215 virtual void onDrawPicture(const SkPicture*, const SkMatrix*, const SkPaint*) SK_OVERRIDE; 216 217 int addPathToHeap(const SkPath& path); // does not write to ops stream 218 219 // These entry points allow the writing of matrices, clips, saves & 220 // restores to be deferred (e.g., if the MC state is being collapsed and 221 // only written out as needed). 222 void recordConcat(const SkMatrix& matrix); 223 void recordTranslate(const SkMatrix& matrix); 224 void recordScale(const SkMatrix& matrix); 225 size_t recordClipRect(const SkRect& rect, SkRegion::Op op, bool doAA); 226 size_t recordClipRRect(const SkRRect& rrect, SkRegion::Op op, bool doAA); 227 size_t recordClipPath(int pathID, SkRegion::Op op, bool doAA); 228 size_t recordClipRegion(const SkRegion& region, SkRegion::Op op); 229 void recordSave(); 230 void recordSaveLayer(const SkRect* bounds, const SkPaint* paint, SaveFlags flags); 231 void recordRestore(bool fillInSkips = true); 232 233private: 234 SkPictureContentInfo fContentInfo; 235 236 SkTArray<SkBitmap> fBitmaps; 237 SkTArray<SkPaint> fPaints; 238 SkTArray<SkPath> fPaths; 239 240 SkWriter32 fWriter; 241 242 // we ref each item in these arrays 243 SkTDArray<const SkPicture*> fPictureRefs; 244 SkTDArray<const SkTextBlob*> fTextBlobRefs; 245 246 uint32_t fRecordFlags; 247 int fInitialSaveCount; 248 249 friend class SkPictureData; // for SkPictureData's SkPictureRecord-based constructor 250 251 typedef SkCanvas INHERITED; 252}; 253 254#endif 255