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 "include/core/SkCanvas.h" 12 #include "include/core/SkCanvasVirtualEnforcer.h" 13 #include "include/core/SkColor.h" 14 #include "include/core/SkData.h" 15 #include "include/core/SkDrawable.h" 16 #include "include/core/SkImage.h" 17 #include "include/core/SkM44.h" 18 #include "include/core/SkPaint.h" 19 #include "include/core/SkPath.h" 20 #include "include/core/SkPicture.h" 21 #include "include/core/SkRefCnt.h" 22 #include "include/core/SkSamplingOptions.h" 23 #include "include/core/SkScalar.h" 24 #include "include/core/SkTextBlob.h" 25 #include "include/core/SkVertices.h" 26 #include "include/private/base/SkAssert.h" 27 #include "include/private/base/SkDebug.h" 28 #include "include/private/base/SkTArray.h" 29 #include "include/private/base/SkTDArray.h" 30 #include "include/private/base/SkTo.h" 31 #include "include/private/chromium/Slug.h" 32 #include "src/core/SkPictureFlat.h" 33 #include "src/core/SkTHash.h" 34 #include "src/core/SkWriter32.h" 35 36 #include <cstddef> 37 #include <cstdint> 38 39 class SkBitmap; 40 class SkMatrix; 41 class SkPixmap; 42 class SkRRect; 43 class SkRegion; 44 class SkShader; 45 class SkSurface; 46 class SkSurfaceProps; 47 enum class SkBlendMode; 48 enum class SkClipOp; 49 struct SkDrawShadowRec; 50 struct SkIRect; 51 struct SkISize; 52 struct SkImageInfo; 53 struct SkPoint; 54 struct SkRSXform; 55 struct SkRect; 56 57 58 // These macros help with packing and unpacking a single byte value and 59 // a 3 byte value into/out of a uint32_t 60 #define MASK_24 0x00FFFFFF 61 #define UNPACK_8_24(combined, small, large) \ 62 small = (combined >> 24) & 0xFF; \ 63 large = combined & MASK_24 64 #define PACK_8_24(small, large) ((small << 24) | large) 65 66 67 class SkPictureRecord : public SkCanvasVirtualEnforcer<SkCanvas> { 68 public: 69 SkPictureRecord(const SkISize& dimensions, uint32_t recordFlags); 70 71 SkPictureRecord(const SkIRect& dimensions, uint32_t recordFlags); 72 getPictures()73 const skia_private::TArray<sk_sp<const SkPicture>>& getPictures() const { 74 return fPictures; 75 } 76 getDrawables()77 const skia_private::TArray<sk_sp<SkDrawable>>& getDrawables() const { 78 return fDrawables; 79 } 80 getTextBlobs()81 const skia_private::TArray<sk_sp<const SkTextBlob>>& getTextBlobs() const { 82 return fTextBlobs; 83 } 84 getSlugs()85 const skia_private::TArray<sk_sp<const sktext::gpu::Slug>>& getSlugs() const { 86 return fSlugs; 87 } 88 getVertices()89 const skia_private::TArray<sk_sp<const SkVertices>>& getVertices() const { 90 return fVertices; 91 } 92 getImages()93 const skia_private::TArray<sk_sp<const SkImage>>& getImages() const { 94 return fImages; 95 } 96 opData()97 sk_sp<SkData> opData() const { 98 this->validate(fWriter.bytesWritten(), 0); 99 100 if (fWriter.bytesWritten() == 0) { 101 return SkData::MakeEmpty(); 102 } 103 return fWriter.snapshotAsData(); 104 } 105 setFlags(uint32_t recordFlags)106 void setFlags(uint32_t recordFlags) { 107 fRecordFlags = recordFlags; 108 } 109 writeStream()110 const SkWriter32& writeStream() const { 111 return fWriter; 112 } 113 114 void beginRecording(); 115 void endRecording(); 116 117 protected: 118 void addNoOp(); 119 120 private: 121 void handleOptimization(int opt); 122 size_t recordRestoreOffsetPlaceholder(); 123 void fillRestoreOffsetPlaceholdersForCurrentStackLevel(uint32_t restoreOffset); 124 125 SkTDArray<int32_t> fRestoreOffsetStack; 126 127 SkTDArray<uint32_t> fCullOffsetStack; 128 129 /* 130 * Write the 'drawType' operation and chunk size to the skp. 'size' 131 * can potentially be increased if the chunk size needs its own storage 132 * location (i.e., it overflows 24 bits). 133 * Returns the start offset of the chunk. This is the location at which 134 * the opcode & size are stored. 135 * TODO: since we are handing the size into here we could call reserve 136 * and then return a pointer to the memory storage. This could decrease 137 * allocation overhead but could lead to more wasted space (the tail 138 * end of blocks could go unused). Possibly add a second addDraw that 139 * operates in this manner. 140 */ addDraw(DrawType drawType,size_t * size)141 size_t addDraw(DrawType drawType, size_t* size) { 142 size_t offset = fWriter.bytesWritten(); 143 144 SkASSERT_RELEASE(this->predrawNotify()); 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(SkToU32(*size)); 153 } else { 154 fWriter.writeInt(PACK_8_24(drawType, SkToU32(*size))); 155 } 156 157 return offset; 158 } 159 addInt(int value)160 void addInt(int value) { 161 fWriter.writeInt(value); 162 } addScalar(SkScalar scalar)163 void addScalar(SkScalar scalar) { 164 fWriter.writeScalar(scalar); 165 } 166 167 void addImage(const SkImage*); 168 void addMatrix(const SkMatrix& matrix); addPaint(const SkPaint & paint)169 void addPaint(const SkPaint& paint) { this->addPaintPtr(&paint); } 170 void addPaintPtr(const SkPaint* paint); 171 void addPatch(const SkPoint cubics[12]); 172 void addPath(const SkPath& path); 173 void addPicture(const SkPicture* picture); 174 void addDrawable(SkDrawable* picture); 175 void addPoint(const SkPoint& point); 176 void addPoints(const SkPoint pts[], int count); 177 void addRect(const SkRect& rect); 178 void addRectPtr(const SkRect* rect); 179 void addIRect(const SkIRect& rect); 180 void addIRectPtr(const SkIRect* rect); 181 void addRRect(const SkRRect&); 182 void addRegion(const SkRegion& region); 183 void addSampling(const SkSamplingOptions&); 184 void addText(const void* text, size_t byteLength); 185 void addTextBlob(const SkTextBlob* blob); 186 void addSlug(const sktext::gpu::Slug* slug); 187 void addVertices(const SkVertices*); 188 189 int find(const SkBitmap& bitmap); 190 191 protected: validate(size_t initialOffset,size_t size)192 void validate(size_t initialOffset, size_t size) const { 193 SkASSERT(fWriter.bytesWritten() == initialOffset + size); 194 } 195 196 sk_sp<SkSurface> onNewSurface(const SkImageInfo&, const SkSurfaceProps&) override; onPeekPixels(SkPixmap *)197 bool onPeekPixels(SkPixmap*) override { return false; } 198 199 void willSave() override; 200 SaveLayerStrategy getSaveLayerStrategy(const SaveLayerRec&) override; 201 bool onDoSaveBehind(const SkRect*) override; 202 void willRestore() override; 203 204 void didConcat44(const SkM44&) override; 205 void didSetM44(const SkM44&) override; 206 void didScale(SkScalar, SkScalar) override; 207 void didTranslate(SkScalar, SkScalar) override; 208 209 void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&) override; 210 211 void onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, 212 const SkPaint& paint) override; 213 void onDrawSlug(const sktext::gpu::Slug* slug, const SkPaint& paint) override; 214 void onDrawPatch(const SkPoint cubics[12], const SkColor colors[4], 215 const SkPoint texCoords[4], SkBlendMode, const SkPaint& paint) override; 216 217 void onDrawPaint(const SkPaint&) override; 218 void onDrawBehind(const SkPaint&) override; 219 void onDrawPoints(PointMode, size_t count, const SkPoint pts[], const SkPaint&) override; 220 void onDrawRect(const SkRect&, const SkPaint&) override; 221 void onDrawRegion(const SkRegion&, const SkPaint&) override; 222 void onDrawOval(const SkRect&, const SkPaint&) override; 223 void onDrawArc(const SkRect&, SkScalar, SkScalar, bool, const SkPaint&) override; 224 void onDrawRRect(const SkRRect&, const SkPaint&) override; 225 void onDrawPath(const SkPath&, const SkPaint&) override; 226 227 void onDrawImage2(const SkImage*, SkScalar, SkScalar, const SkSamplingOptions&, 228 const SkPaint*) override; 229 void onDrawImageRect2(const SkImage*, const SkRect&, const SkRect&, const SkSamplingOptions&, 230 const SkPaint*, SrcRectConstraint) override; 231 void onDrawImageLattice2(const SkImage*, const Lattice&, const SkRect&, SkFilterMode, 232 const SkPaint*) override; 233 void onDrawAtlas2(const SkImage*, const SkRSXform[], const SkRect[], const SkColor[], int, 234 SkBlendMode, const SkSamplingOptions&, const SkRect*, const SkPaint*) override; 235 236 void onDrawShadowRec(const SkPath&, const SkDrawShadowRec&) override; 237 void onDrawVerticesObject(const SkVertices*, SkBlendMode, const SkPaint&) override; 238 239 void onClipRect(const SkRect&, SkClipOp, ClipEdgeStyle) override; 240 void onClipRRect(const SkRRect&, SkClipOp, ClipEdgeStyle) override; 241 void onClipPath(const SkPath&, SkClipOp, ClipEdgeStyle) override; 242 void onClipShader(sk_sp<SkShader>, SkClipOp) override; 243 void onClipRegion(const SkRegion&, SkClipOp) override; 244 void onResetClip() override; 245 246 void onDrawPicture(const SkPicture*, const SkMatrix*, const SkPaint*) override; 247 248 void onDrawDrawable(SkDrawable*, const SkMatrix*) override; 249 void onDrawAnnotation(const SkRect&, const char[], SkData*) override; 250 251 void onDrawEdgeAAQuad(const SkRect&, const SkPoint[4], QuadAAFlags, const SkColor4f&, 252 SkBlendMode) override; 253 void onDrawEdgeAAImageSet2(const ImageSetEntry[], int count, const SkPoint[], const SkMatrix[], 254 const SkSamplingOptions&,const SkPaint*, SrcRectConstraint) override; 255 256 int addPathToHeap(const SkPath& path); // does not write to ops stream 257 258 // These entry points allow the writing of matrices, clips, saves & 259 // restores to be deferred (e.g., if the MC state is being collapsed and 260 // only written out as needed). 261 void recordConcat(const SkMatrix& matrix); 262 void recordTranslate(const SkMatrix& matrix); 263 void recordScale(const SkMatrix& matrix); 264 size_t recordClipRect(const SkRect& rect, SkClipOp op, bool doAA); 265 size_t recordClipRRect(const SkRRect& rrect, SkClipOp op, bool doAA); 266 size_t recordClipPath(int pathID, SkClipOp op, bool doAA); 267 size_t recordClipRegion(const SkRegion& region, SkClipOp op); 268 void recordSave(); 269 void recordSaveLayer(const SaveLayerRec&); 270 void recordRestore(bool fillInSkips = true); 271 272 private: 273 skia_private::TArray<SkPaint> fPaints; 274 275 struct PathHash { operatorPathHash276 uint32_t operator()(const SkPath& p) { return p.getGenerationID(); } 277 }; 278 skia_private::THashMap<SkPath, int, PathHash> fPaths; 279 280 SkWriter32 fWriter; 281 282 skia_private::TArray<sk_sp<const SkImage>> fImages; 283 skia_private::TArray<sk_sp<const SkPicture>> fPictures; 284 skia_private::TArray<sk_sp<SkDrawable>> fDrawables; 285 skia_private::TArray<sk_sp<const SkTextBlob>> fTextBlobs; 286 skia_private::TArray<sk_sp<const SkVertices>> fVertices; 287 skia_private::TArray<sk_sp<const sktext::gpu::Slug>> fSlugs; 288 289 uint32_t fRecordFlags; 290 int fInitialSaveCount; 291 292 friend class SkPictureData; // for SkPictureData's SkPictureRecord-based constructor 293 }; 294 295 #endif 296