1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/trunk/src/core/SkPictureRecord.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,315 @@ 1.4 +/* 1.5 + * Copyright 2011 Google Inc. 1.6 + * 1.7 + * Use of this source code is governed by a BSD-style license that can be 1.8 + * found in the LICENSE file. 1.9 + */ 1.10 + 1.11 +#ifndef SkPictureRecord_DEFINED 1.12 +#define SkPictureRecord_DEFINED 1.13 + 1.14 +#include "SkCanvas.h" 1.15 +#include "SkFlattenable.h" 1.16 +#ifdef SK_COLLAPSE_MATRIX_CLIP_STATE 1.17 +#include "SkMatrixClipStateMgr.h" 1.18 +#endif 1.19 +#include "SkPathHeap.h" 1.20 +#include "SkPicture.h" 1.21 +#include "SkPictureFlat.h" 1.22 +#include "SkTemplates.h" 1.23 +#include "SkWriter32.h" 1.24 + 1.25 +class SkBBoxHierarchy; 1.26 +class SkOffsetTable; 1.27 +class SkPictureStateTree; 1.28 + 1.29 +// These macros help with packing and unpacking a single byte value and 1.30 +// a 3 byte value into/out of a uint32_t 1.31 +#define MASK_24 0x00FFFFFF 1.32 +#define UNPACK_8_24(combined, small, large) \ 1.33 + small = (combined >> 24) & 0xFF; \ 1.34 + large = combined & MASK_24; 1.35 +#define PACK_8_24(small, large) ((small << 24) | large) 1.36 + 1.37 + 1.38 +class SkPictureRecord : public SkCanvas { 1.39 +public: 1.40 + SkPictureRecord(const SkISize& dimensions, uint32_t recordFlags); 1.41 + virtual ~SkPictureRecord(); 1.42 + 1.43 + virtual void clear(SkColor) SK_OVERRIDE; 1.44 + virtual void drawPaint(const SkPaint& paint) SK_OVERRIDE; 1.45 + virtual void drawPoints(PointMode, size_t count, const SkPoint pts[], 1.46 + const SkPaint&) SK_OVERRIDE; 1.47 + virtual void drawOval(const SkRect&, const SkPaint&) SK_OVERRIDE; 1.48 + virtual void drawRect(const SkRect&, const SkPaint&) SK_OVERRIDE; 1.49 + virtual void drawRRect(const SkRRect&, const SkPaint&) SK_OVERRIDE; 1.50 + virtual void drawPath(const SkPath& path, const SkPaint&) SK_OVERRIDE; 1.51 + virtual void drawBitmap(const SkBitmap&, SkScalar left, SkScalar top, 1.52 + const SkPaint*) SK_OVERRIDE; 1.53 + virtual void drawBitmapRectToRect(const SkBitmap&, const SkRect* src, 1.54 + const SkRect& dst, const SkPaint* paint, 1.55 + DrawBitmapRectFlags flags) SK_OVERRIDE; 1.56 + virtual void drawBitmapMatrix(const SkBitmap&, const SkMatrix&, 1.57 + const SkPaint*) SK_OVERRIDE; 1.58 + virtual void drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, 1.59 + const SkRect& dst, const SkPaint*) SK_OVERRIDE; 1.60 + virtual void drawSprite(const SkBitmap&, int left, int top, 1.61 + const SkPaint*) SK_OVERRIDE; 1.62 + virtual void drawText(const void* text, size_t byteLength, SkScalar x, 1.63 + SkScalar y, const SkPaint&) SK_OVERRIDE; 1.64 + virtual void drawPosText(const void* text, size_t byteLength, 1.65 + const SkPoint pos[], const SkPaint&) SK_OVERRIDE; 1.66 + virtual void drawPosTextH(const void* text, size_t byteLength, 1.67 + const SkScalar xpos[], SkScalar constY, const SkPaint&) SK_OVERRIDE; 1.68 + virtual void drawTextOnPath(const void* text, size_t byteLength, 1.69 + const SkPath& path, const SkMatrix* matrix, 1.70 + const SkPaint&) SK_OVERRIDE; 1.71 + virtual void drawPicture(SkPicture& picture) SK_OVERRIDE; 1.72 + virtual void drawVertices(VertexMode, int vertexCount, 1.73 + const SkPoint vertices[], const SkPoint texs[], 1.74 + const SkColor colors[], SkXfermode*, 1.75 + const uint16_t indices[], int indexCount, 1.76 + const SkPaint&) SK_OVERRIDE; 1.77 + virtual void drawData(const void*, size_t) SK_OVERRIDE; 1.78 + virtual void beginCommentGroup(const char* description) SK_OVERRIDE; 1.79 + virtual void addComment(const char* kywd, const char* value) SK_OVERRIDE; 1.80 + virtual void endCommentGroup() SK_OVERRIDE; 1.81 + virtual bool isDrawingToLayer() const SK_OVERRIDE; 1.82 + 1.83 + void addFontMetricsTopBottom(const SkPaint& paint, const SkFlatData&, 1.84 + SkScalar minY, SkScalar maxY); 1.85 + 1.86 + const SkTDArray<SkPicture* >& getPictureRefs() const { 1.87 + return fPictureRefs; 1.88 + } 1.89 + 1.90 + void setFlags(uint32_t recordFlags) { 1.91 + fRecordFlags = recordFlags; 1.92 + } 1.93 + 1.94 + const SkWriter32& writeStream() const { 1.95 + return fWriter; 1.96 + } 1.97 + 1.98 + void beginRecording(); 1.99 + void endRecording(); 1.100 + 1.101 + void internalOnly_EnableOpts(bool optsEnabled) { 1.102 + fOptsEnabled = optsEnabled; 1.103 + } 1.104 + 1.105 +private: 1.106 + void handleOptimization(int opt); 1.107 + int recordRestoreOffsetPlaceholder(SkRegion::Op); 1.108 + void fillRestoreOffsetPlaceholdersForCurrentStackLevel(uint32_t restoreOffset); 1.109 + 1.110 +#ifndef SK_COLLAPSE_MATRIX_CLIP_STATE 1.111 + SkTDArray<int32_t> fRestoreOffsetStack; 1.112 + int fFirstSavedLayerIndex; 1.113 + enum { 1.114 + kNoSavedLayerIndex = -1 1.115 + }; 1.116 +#endif 1.117 + 1.118 + SkTDArray<uint32_t> fCullOffsetStack; 1.119 + 1.120 + /* 1.121 + * Write the 'drawType' operation and chunk size to the skp. 'size' 1.122 + * can potentially be increased if the chunk size needs its own storage 1.123 + * location (i.e., it overflows 24 bits). 1.124 + * Returns the start offset of the chunk. This is the location at which 1.125 + * the opcode & size are stored. 1.126 + * TODO: since we are handing the size into here we could call reserve 1.127 + * and then return a pointer to the memory storage. This could decrease 1.128 + * allocation overhead but could lead to more wasted space (the tail 1.129 + * end of blocks could go unused). Possibly add a second addDraw that 1.130 + * operates in this manner. 1.131 + */ 1.132 + size_t addDraw(DrawType drawType, uint32_t* size) { 1.133 + size_t offset = fWriter.bytesWritten(); 1.134 + 1.135 + this->predrawNotify(); 1.136 + 1.137 + #ifdef SK_DEBUG_TRACE 1.138 + SkDebugf("add %s\n", DrawTypeToString(drawType)); 1.139 + #endif 1.140 + 1.141 + SkASSERT(0 != *size); 1.142 + SkASSERT(((uint8_t) drawType) == drawType); 1.143 + 1.144 + if (0 != (*size & ~MASK_24) || *size == MASK_24) { 1.145 + fWriter.writeInt(PACK_8_24(drawType, MASK_24)); 1.146 + *size += 1; 1.147 + fWriter.writeInt(*size); 1.148 + } else { 1.149 + fWriter.writeInt(PACK_8_24(drawType, *size)); 1.150 + } 1.151 + 1.152 + return offset; 1.153 + } 1.154 + 1.155 + void addInt(int value) { 1.156 + fWriter.writeInt(value); 1.157 + } 1.158 + void addScalar(SkScalar scalar) { 1.159 + fWriter.writeScalar(scalar); 1.160 + } 1.161 + 1.162 + // The command at 'offset' in the skp uses the specified bitmap 1.163 + void trackBitmapUse(int bitmapID, size_t offset); 1.164 + int addBitmap(const SkBitmap& bitmap); 1.165 + void addMatrix(const SkMatrix& matrix); 1.166 + const SkFlatData* addPaint(const SkPaint& paint) { return this->addPaintPtr(&paint); } 1.167 + const SkFlatData* addPaintPtr(const SkPaint* paint); 1.168 + void addFlatPaint(const SkFlatData* flatPaint); 1.169 + void addPath(const SkPath& path); 1.170 + void addPicture(SkPicture& picture); 1.171 + void addPoint(const SkPoint& point); 1.172 + void addPoints(const SkPoint pts[], int count); 1.173 + void addRect(const SkRect& rect); 1.174 + void addRectPtr(const SkRect* rect); 1.175 + void addIRect(const SkIRect& rect); 1.176 + void addIRectPtr(const SkIRect* rect); 1.177 + void addRRect(const SkRRect&); 1.178 + void addRegion(const SkRegion& region); 1.179 + void addText(const void* text, size_t byteLength); 1.180 + 1.181 + int find(const SkBitmap& bitmap); 1.182 + 1.183 +#ifdef SK_DEBUG_DUMP 1.184 +public: 1.185 + void dumpMatrices(); 1.186 + void dumpPaints(); 1.187 +#endif 1.188 + 1.189 +#ifdef SK_DEBUG_SIZE 1.190 +public: 1.191 + size_t size() const; 1.192 + int bitmaps(size_t* size) const; 1.193 + int matrices(size_t* size) const; 1.194 + int paints(size_t* size) const; 1.195 + int paths(size_t* size) const; 1.196 + int regions(size_t* size) const; 1.197 + size_t streamlen() const; 1.198 + 1.199 + size_t fPointBytes, fRectBytes, fTextBytes; 1.200 + int fPointWrites, fRectWrites, fTextWrites; 1.201 +#endif 1.202 + 1.203 +#ifdef SK_DEBUG_VALIDATE 1.204 +public: 1.205 + void validate(size_t initialOffset, uint32_t size) const; 1.206 +private: 1.207 + void validateBitmaps() const; 1.208 + void validateMatrices() const; 1.209 + void validatePaints() const; 1.210 + void validatePaths() const; 1.211 + void validateRegions() const; 1.212 +#else 1.213 +public: 1.214 + void validate(size_t initialOffset, uint32_t size) const { 1.215 + SkASSERT(fWriter.bytesWritten() == initialOffset + size); 1.216 + } 1.217 +#endif 1.218 + 1.219 +protected: 1.220 + virtual SkSurface* onNewSurface(const SkImageInfo&) SK_OVERRIDE; 1.221 + const void* onPeekPixels(SkImageInfo*, size_t*) SK_OVERRIDE { 1.222 + return NULL; 1.223 + } 1.224 + 1.225 + virtual void willSave(SaveFlags) SK_OVERRIDE; 1.226 + virtual SaveLayerStrategy willSaveLayer(const SkRect*, const SkPaint*, SaveFlags) SK_OVERRIDE; 1.227 + virtual void willRestore() SK_OVERRIDE; 1.228 + 1.229 + virtual void didTranslate(SkScalar, SkScalar) SK_OVERRIDE; 1.230 + virtual void didScale(SkScalar, SkScalar) SK_OVERRIDE; 1.231 + virtual void didRotate(SkScalar) SK_OVERRIDE; 1.232 + virtual void didSkew(SkScalar, SkScalar) SK_OVERRIDE; 1.233 + virtual void didConcat(const SkMatrix&) SK_OVERRIDE; 1.234 + virtual void didSetMatrix(const SkMatrix&) SK_OVERRIDE; 1.235 + 1.236 + virtual void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&) SK_OVERRIDE; 1.237 + virtual void onPushCull(const SkRect&) SK_OVERRIDE; 1.238 + virtual void onPopCull() SK_OVERRIDE; 1.239 + 1.240 + virtual void onClipRect(const SkRect&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE; 1.241 + virtual void onClipRRect(const SkRRect&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE; 1.242 + virtual void onClipPath(const SkPath&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE; 1.243 + virtual void onClipRegion(const SkRegion&, SkRegion::Op) SK_OVERRIDE; 1.244 + 1.245 + // Return fontmetrics.fTop,fBottom in topbot[0,1], after they have been 1.246 + // tweaked by paint.computeFastBounds(). 1.247 + static void ComputeFontMetricsTopBottom(const SkPaint& paint, SkScalar topbot[2]); 1.248 + 1.249 + // Make sure that flat has fTopBot written. 1.250 + static void WriteTopBot(const SkPaint& paint, const SkFlatData& flat) { 1.251 + if (!flat.isTopBotWritten()) { 1.252 + ComputeFontMetricsTopBottom(paint, flat.writableTopBot()); 1.253 + SkASSERT(flat.isTopBotWritten()); 1.254 + } 1.255 + } 1.256 + // Will return a cached version when possible. 1.257 + const SkFlatData* getFlatPaintData(const SkPaint& paint); 1.258 + /** 1.259 + * SkBBoxRecord::drawPosTextH gets a flat paint and uses it, 1.260 + * then it calls this, using the extra parameter, to avoid duplication. 1.261 + */ 1.262 + void drawPosTextHImpl(const void* text, size_t byteLength, 1.263 + const SkScalar xpos[], SkScalar constY, 1.264 + const SkPaint& paint, const SkFlatData* flatPaintData); 1.265 + 1.266 + int addPathToHeap(const SkPath& path); // does not write to ops stream 1.267 + 1.268 + // These entry points allow the writing of matrices, clips, saves & 1.269 + // restores to be deferred (e.g., if the MC state is being collapsed and 1.270 + // only written out as needed). 1.271 + void recordConcat(const SkMatrix& matrix); 1.272 + int recordClipRect(const SkRect& rect, SkRegion::Op op, bool doAA); 1.273 + int recordClipRRect(const SkRRect& rrect, SkRegion::Op op, bool doAA); 1.274 + int recordClipPath(int pathID, SkRegion::Op op, bool doAA); 1.275 + int recordClipRegion(const SkRegion& region, SkRegion::Op op); 1.276 + void recordSave(SaveFlags flags); 1.277 + void recordSaveLayer(const SkRect* bounds, const SkPaint* paint, SaveFlags flags); 1.278 + void recordRestore(bool fillInSkips = true); 1.279 + 1.280 + // These are set to NULL in our constructor, but may be changed by 1.281 + // subclasses, in which case they will be SkSafeUnref'd in our destructor. 1.282 + SkBBoxHierarchy* fBoundingHierarchy; 1.283 + SkPictureStateTree* fStateTree; 1.284 + 1.285 + // Allocated in the constructor and managed by this class. 1.286 + SkBitmapHeap* fBitmapHeap; 1.287 + 1.288 +private: 1.289 + friend class MatrixClipState; // for access to *Impl methods 1.290 + friend class SkMatrixClipStateMgr; // for access to *Impl methods 1.291 + 1.292 + SkChunkFlatController fFlattenableHeap; 1.293 + 1.294 + SkPaintDictionary fPaints; 1.295 + 1.296 + SkPathHeap* fPathHeap; // reference counted 1.297 + SkWriter32 fWriter; 1.298 + 1.299 + // we ref each item in these arrays 1.300 + SkTDArray<SkPicture*> fPictureRefs; 1.301 + 1.302 + uint32_t fRecordFlags; 1.303 + bool fOptsEnabled; 1.304 + int fInitialSaveCount; 1.305 + 1.306 + SkAutoTUnref<SkOffsetTable> fBitmapUseOffsets; 1.307 + 1.308 + friend class SkPicturePlayback; 1.309 + friend class SkPictureTester; // for unit testing 1.310 + 1.311 +#ifdef SK_COLLAPSE_MATRIX_CLIP_STATE 1.312 + SkMatrixClipStateMgr fMCMgr; 1.313 +#endif 1.314 + 1.315 + typedef SkCanvas INHERITED; 1.316 +}; 1.317 + 1.318 +#endif