SkPictureRecord.h revision bda591c739001b41d77048d680f81e05723cbc05
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#ifdef SK_COLLAPSE_MATRIX_CLIP_STATE 14#include "SkMatrixClipStateMgr.h" 15#endif 16#include "SkPathHeap.h" 17#include "SkPicture.h" 18#include "SkPictureFlat.h" 19#include "SkTemplates.h" 20#include "SkWriter32.h" 21 22class SkPictureStateTree; 23class SkBBoxHierarchy; 24 25// These macros help with packing and unpacking a single byte value and 26// a 3 byte value into/out of a uint32_t 27#define MASK_24 0x00FFFFFF 28#define UNPACK_8_24(combined, small, large) \ 29 small = (combined >> 24) & 0xFF; \ 30 large = combined & MASK_24; 31#define PACK_8_24(small, large) ((small << 24) | large) 32 33 34class SkPictureRecord : public SkCanvas { 35public: 36 SkPictureRecord(uint32_t recordFlags, SkBaseDevice*); 37 virtual ~SkPictureRecord(); 38 39 virtual SkBaseDevice* setDevice(SkBaseDevice* device) SK_OVERRIDE; 40 41 virtual int save(SaveFlags) SK_OVERRIDE; 42 virtual int saveLayer(const SkRect* bounds, const SkPaint*, SaveFlags) SK_OVERRIDE; 43 virtual void restore() SK_OVERRIDE; 44 virtual bool translate(SkScalar dx, SkScalar dy) SK_OVERRIDE; 45 virtual bool scale(SkScalar sx, SkScalar sy) SK_OVERRIDE; 46 virtual bool rotate(SkScalar degrees) SK_OVERRIDE; 47 virtual bool skew(SkScalar sx, SkScalar sy) SK_OVERRIDE; 48 virtual bool concat(const SkMatrix& matrix) SK_OVERRIDE; 49 virtual void setMatrix(const SkMatrix& matrix) SK_OVERRIDE; 50 virtual bool clipRect(const SkRect&, SkRegion::Op, bool) SK_OVERRIDE; 51 virtual bool clipRRect(const SkRRect&, SkRegion::Op, bool) SK_OVERRIDE; 52 virtual bool clipPath(const SkPath&, SkRegion::Op, bool) SK_OVERRIDE; 53 virtual bool clipRegion(const SkRegion& region, SkRegion::Op op) SK_OVERRIDE; 54 virtual void clear(SkColor) SK_OVERRIDE; 55 virtual void drawPaint(const SkPaint& paint) SK_OVERRIDE; 56 virtual void drawPoints(PointMode, size_t count, const SkPoint pts[], 57 const SkPaint&) SK_OVERRIDE; 58 virtual void drawOval(const SkRect&, const SkPaint&) SK_OVERRIDE; 59 virtual void drawRect(const SkRect&, const SkPaint&) SK_OVERRIDE; 60 virtual void drawRRect(const SkRRect&, const SkPaint&) SK_OVERRIDE; 61 virtual void drawPath(const SkPath& path, const SkPaint&) SK_OVERRIDE; 62 virtual void drawBitmap(const SkBitmap&, SkScalar left, SkScalar top, 63 const SkPaint*) SK_OVERRIDE; 64 virtual void drawBitmapRectToRect(const SkBitmap&, const SkRect* src, 65 const SkRect& dst, const SkPaint* paint, 66 DrawBitmapRectFlags flags) SK_OVERRIDE; 67 virtual void drawBitmapMatrix(const SkBitmap&, const SkMatrix&, 68 const SkPaint*) SK_OVERRIDE; 69 virtual void drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, 70 const SkRect& dst, const SkPaint*) SK_OVERRIDE; 71 virtual void drawSprite(const SkBitmap&, int left, int top, 72 const SkPaint*) SK_OVERRIDE; 73 virtual void drawText(const void* text, size_t byteLength, SkScalar x, 74 SkScalar y, const SkPaint&) SK_OVERRIDE; 75 virtual void drawPosText(const void* text, size_t byteLength, 76 const SkPoint pos[], const SkPaint&) SK_OVERRIDE; 77 virtual void drawPosTextH(const void* text, size_t byteLength, 78 const SkScalar xpos[], SkScalar constY, const SkPaint&) SK_OVERRIDE; 79 virtual void drawTextOnPath(const void* text, size_t byteLength, 80 const SkPath& path, const SkMatrix* matrix, 81 const SkPaint&) SK_OVERRIDE; 82 virtual void drawPicture(SkPicture& picture) SK_OVERRIDE; 83 virtual void drawVertices(VertexMode, int vertexCount, 84 const SkPoint vertices[], const SkPoint texs[], 85 const SkColor colors[], SkXfermode*, 86 const uint16_t indices[], int indexCount, 87 const SkPaint&) SK_OVERRIDE; 88 virtual void drawData(const void*, size_t) SK_OVERRIDE; 89 virtual void beginCommentGroup(const char* description) SK_OVERRIDE; 90 virtual void addComment(const char* kywd, const char* value) SK_OVERRIDE; 91 virtual void endCommentGroup() SK_OVERRIDE; 92 virtual bool isDrawingToLayer() const SK_OVERRIDE; 93 94 void addFontMetricsTopBottom(const SkPaint& paint, const SkFlatData&, 95 SkScalar minY, SkScalar maxY); 96 97 const SkTDArray<SkPicture* >& getPictureRefs() const { 98 return fPictureRefs; 99 } 100 101 void setFlags(uint32_t recordFlags) { 102 fRecordFlags = recordFlags; 103 } 104 105 const SkWriter32& writeStream() const { 106 return fWriter; 107 } 108 109 void beginRecording(); 110 void endRecording(); 111 112private: 113 void handleOptimization(int opt); 114 int recordRestoreOffsetPlaceholder(SkRegion::Op); 115 void fillRestoreOffsetPlaceholdersForCurrentStackLevel(uint32_t restoreOffset); 116 117#ifndef SK_COLLAPSE_MATRIX_CLIP_STATE 118 SkTDArray<int32_t> fRestoreOffsetStack; 119 int fFirstSavedLayerIndex; 120 enum { 121 kNoSavedLayerIndex = -1 122 }; 123#endif 124 125 /* 126 * Write the 'drawType' operation and chunk size to the skp. 'size' 127 * can potentially be increased if the chunk size needs its own storage 128 * location (i.e., it overflows 24 bits). 129 * Returns the start offset of the chunk. This is the location at which 130 * the opcode & size are stored. 131 * TODO: since we are handing the size into here we could call reserve 132 * and then return a pointer to the memory storage. This could decrease 133 * allocation overhead but could lead to more wasted space (the tail 134 * end of blocks could go unused). Possibly add a second addDraw that 135 * operates in this manner. 136 */ 137 size_t addDraw(DrawType drawType, uint32_t* size) { 138 size_t offset = fWriter.bytesWritten(); 139 140 this->predrawNotify(); 141 142 #ifdef SK_DEBUG_TRACE 143 SkDebugf("add %s\n", DrawTypeToString(drawType)); 144 #endif 145 146 SkASSERT(0 != *size); 147 SkASSERT(((uint8_t) drawType) == drawType); 148 149 if (0 != (*size & ~MASK_24) || *size == MASK_24) { 150 fWriter.writeInt(PACK_8_24(drawType, MASK_24)); 151 *size += 1; 152 fWriter.writeInt(*size); 153 } else { 154 fWriter.writeInt(PACK_8_24(drawType, *size)); 155 } 156 157 return offset; 158 } 159 160 void addInt(int value) { 161 fWriter.writeInt(value); 162 } 163 void addScalar(SkScalar scalar) { 164 fWriter.writeScalar(scalar); 165 } 166 167 void addBitmap(const SkBitmap& bitmap); 168 void addMatrix(const SkMatrix& matrix); 169 const SkFlatData* addPaint(const SkPaint& paint) { return this->addPaintPtr(&paint); } 170 const SkFlatData* addPaintPtr(const SkPaint* paint); 171 void addFlatPaint(const SkFlatData* flatPaint); 172 void addPath(const SkPath& path); 173 void addPicture(SkPicture& picture); 174 void addPoint(const SkPoint& point); 175 void addPoints(const SkPoint pts[], int count); 176 void addRect(const SkRect& rect); 177 void addRectPtr(const SkRect* rect); 178 void addIRect(const SkIRect& rect); 179 void addIRectPtr(const SkIRect* rect); 180 void addRRect(const SkRRect&); 181 void addRegion(const SkRegion& region); 182 void addText(const void* text, size_t byteLength); 183 184 int find(const SkBitmap& bitmap); 185 186#ifdef SK_DEBUG_DUMP 187public: 188 void dumpMatrices(); 189 void dumpPaints(); 190#endif 191 192#ifdef SK_DEBUG_SIZE 193public: 194 size_t size() const; 195 int bitmaps(size_t* size) const; 196 int matrices(size_t* size) const; 197 int paints(size_t* size) const; 198 int paths(size_t* size) const; 199 int regions(size_t* size) const; 200 size_t streamlen() const; 201 202 size_t fPointBytes, fRectBytes, fTextBytes; 203 int fPointWrites, fRectWrites, fTextWrites; 204#endif 205 206#ifdef SK_DEBUG_VALIDATE 207public: 208 void validate(size_t initialOffset, uint32_t size) const; 209private: 210 void validateBitmaps() const; 211 void validateMatrices() const; 212 void validatePaints() const; 213 void validatePaths() const; 214 void validateRegions() const; 215#else 216public: 217 void validate(size_t initialOffset, uint32_t size) const { 218 SkASSERT(fWriter.bytesWritten() == initialOffset + size); 219 } 220#endif 221 222protected: 223 virtual SkSurface* onNewSurface(const SkImageInfo&) SK_OVERRIDE; 224 225 // Return fontmetrics.fTop,fBottom in topbot[0,1], after they have been 226 // tweaked by paint.computeFastBounds(). 227 static void ComputeFontMetricsTopBottom(const SkPaint& paint, SkScalar topbot[2]); 228 229 // Make sure that flat has fTopBot written. 230 static void WriteTopBot(const SkPaint& paint, const SkFlatData& flat) { 231 if (!flat.isTopBotWritten()) { 232 ComputeFontMetricsTopBottom(paint, flat.writableTopBot()); 233 SkASSERT(flat.isTopBotWritten()); 234 } 235 } 236 // Will return a cached version when possible. 237 const SkFlatData* getFlatPaintData(const SkPaint& paint); 238 /** 239 * SkBBoxRecord::drawPosTextH gets a flat paint and uses it, 240 * then it calls this, using the extra parameter, to avoid duplication. 241 */ 242 void drawPosTextHImpl(const void* text, size_t byteLength, 243 const SkScalar xpos[], SkScalar constY, 244 const SkPaint& paint, const SkFlatData* flatPaintData); 245 246 int addPathToHeap(const SkPath& path); // does not write to ops stream 247 248 // These entry points allow the writing of matrices, clips, saves & 249 // restores to be deferred (e.g., if the MC state is being collapsed and 250 // only written out as needed). 251 void recordConcat(const SkMatrix& matrix); 252 int recordClipRect(const SkRect& rect, SkRegion::Op op, bool doAA); 253 int recordClipRRect(const SkRRect& rrect, SkRegion::Op op, bool doAA); 254 int recordClipPath(int pathID, SkRegion::Op op, bool doAA); 255 int recordClipRegion(const SkRegion& region, SkRegion::Op op); 256 void recordSave(SaveFlags flags); 257 void recordSaveLayer(const SkRect* bounds, const SkPaint* paint, SaveFlags flags); 258 void recordRestore(bool fillInSkips = true); 259 260 // These are set to NULL in our constructor, but may be changed by 261 // subclasses, in which case they will be SkSafeUnref'd in our destructor. 262 SkBBoxHierarchy* fBoundingHierarchy; 263 SkPictureStateTree* fStateTree; 264 265 // Allocated in the constructor and managed by this class. 266 SkBitmapHeap* fBitmapHeap; 267 268private: 269 friend class MatrixClipState; // for access to *Impl methods 270 friend class SkMatrixClipStateMgr; // for access to *Impl methods 271 272 SkChunkFlatController fFlattenableHeap; 273 274 SkPaintDictionary fPaints; 275 276 SkPathHeap* fPathHeap; // reference counted 277 SkWriter32 fWriter; 278 279 // we ref each item in these arrays 280 SkTDArray<SkPicture*> fPictureRefs; 281 282 uint32_t fRecordFlags; 283 int fInitialSaveCount; 284 285 friend class SkPicturePlayback; 286 friend class SkPictureTester; // for unit testing 287 288#ifdef SK_COLLAPSE_MATRIX_CLIP_STATE 289 SkMatrixClipStateMgr fMCMgr; 290#endif 291 292 typedef SkCanvas INHERITED; 293}; 294 295#endif 296