1 /* 2 * Copyright 2014 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 SkRecords_DEFINED 9 #define SkRecords_DEFINED 10 11 #include "include/core/SkCanvas.h" 12 #include "include/core/SkData.h" 13 #include "include/core/SkDrawable.h" 14 #include "include/core/SkImage.h" 15 #include "include/core/SkImageFilter.h" 16 #include "include/core/SkM44.h" 17 #include "include/core/SkMatrix.h" 18 #include "include/core/SkPath.h" 19 #include "include/core/SkPicture.h" 20 #include "include/core/SkRRect.h" 21 #include "include/core/SkRSXform.h" 22 #include "include/core/SkRect.h" 23 #include "include/core/SkRegion.h" 24 #include "include/core/SkString.h" 25 #include "include/core/SkTextBlob.h" 26 #include "include/core/SkVertices.h" 27 #include "src/core/SkDrawShadowInfo.h" 28 29 namespace SkRecords { 30 31 // A list of all the types of canvas calls we can record. 32 // Each of these is reified into a struct below. 33 // 34 // (We're using the macro-of-macro trick here to do several different things with the same list.) 35 // 36 // We leave this SK_RECORD_TYPES macro defined for use by code that wants to operate on SkRecords 37 // types polymorphically. (See SkRecord::Record::{visit,mutate} for an example.) 38 // 39 // Order doesn't technically matter here, but the compiler can generally generate better code if 40 // you keep them semantically grouped, especially the Draws. It's also nice to leave NoOp at 0. 41 #define SK_RECORD_TYPES(M) \ 42 M(NoOp) \ 43 M(Flush) \ 44 M(Restore) \ 45 M(Save) \ 46 M(SaveLayer) \ 47 M(SaveBehind) \ 48 M(MarkCTM) \ 49 M(SetMatrix) \ 50 M(SetM44) \ 51 M(Translate) \ 52 M(Scale) \ 53 M(Concat) \ 54 M(Concat44) \ 55 M(ClipPath) \ 56 M(ClipRRect) \ 57 M(ClipRect) \ 58 M(ClipRegion) \ 59 M(ClipShader) \ 60 M(ResetClip) \ 61 M(DrawArc) \ 62 M(DrawDrawable) \ 63 M(DrawImage) \ 64 M(DrawImageLattice) \ 65 M(DrawImageRect) \ 66 M(DrawDRRect) \ 67 M(DrawOval) \ 68 M(DrawBehind) \ 69 M(DrawPaint) \ 70 M(DrawPath) \ 71 M(DrawPatch) \ 72 M(DrawPicture) \ 73 M(DrawPoints) \ 74 M(DrawRRect) \ 75 M(DrawRect) \ 76 M(DrawRegion) \ 77 M(DrawTextBlob) \ 78 M(DrawAtlas) \ 79 M(DrawVertices) \ 80 M(DrawShadowRec) \ 81 M(DrawAnnotation) \ 82 M(DrawEdgeAAQuad) \ 83 M(DrawEdgeAAImageSet) 84 85 86 // Defines SkRecords::Type, an enum of all record types. 87 #define ENUM(T) T##_Type, 88 enum Type { SK_RECORD_TYPES(ENUM) }; 89 #undef ENUM 90 91 #define ACT_AS_PTR(ptr) \ 92 operator T*() const { return ptr; } \ 93 T* operator->() const { return ptr; } 94 95 // An Optional doesn't own the pointer's memory, but may need to destroy non-POD data. 96 template <typename T> 97 class Optional { 98 public: Optional()99 Optional() : fPtr(nullptr) {} Optional(T * ptr)100 Optional(T* ptr) : fPtr(ptr) {} Optional(Optional && o)101 Optional(Optional&& o) : fPtr(o.fPtr) { 102 o.fPtr = nullptr; 103 } ~Optional()104 ~Optional() { if (fPtr) fPtr->~T(); } 105 106 ACT_AS_PTR(fPtr) 107 private: 108 T* fPtr; 109 Optional(const Optional&) = delete; 110 Optional& operator=(const Optional&) = delete; 111 }; 112 113 // PODArray doesn't own the pointer's memory, and we assume the data is POD. 114 template <typename T> 115 class PODArray { 116 public: PODArray()117 PODArray() {} PODArray(T * ptr)118 PODArray(T* ptr) : fPtr(ptr) {} 119 // Default copy and assign. 120 121 ACT_AS_PTR(fPtr) 122 private: 123 T* fPtr; 124 }; 125 126 #undef ACT_AS_PTR 127 128 // SkPath::getBounds() isn't thread safe unless we precache the bounds in a singlethreaded context. 129 // SkPath::cheapComputeDirection() is similar. 130 // Recording is a convenient time to cache these, or we can delay it to between record and playback. 131 struct PreCachedPath : public SkPath { 132 PreCachedPath() {} 133 PreCachedPath(const SkPath& path); 134 }; 135 136 // Like SkPath::getBounds(), SkMatrix::getType() isn't thread safe unless we precache it. 137 // This may not cover all SkMatrices used by the picture (e.g. some could be hiding in a shader). 138 struct TypedMatrix : public SkMatrix { 139 TypedMatrix() {} 140 TypedMatrix(const SkMatrix& matrix); 141 }; 142 143 enum Tags { 144 kDraw_Tag = 1, // May draw something (usually named DrawFoo). 145 kHasImage_Tag = 2, // Contains an SkImage or SkBitmap. 146 kHasText_Tag = 4, // Contains text. 147 kHasPaint_Tag = 8, // May have an SkPaint field, at least optionally. 148 149 kDrawWithPaint_Tag = kDraw_Tag | kHasPaint_Tag, 150 }; 151 152 // A macro to make it a little easier to define a struct that can be stored in SkRecord. 153 #define RECORD(T, tags, ...) \ 154 struct T { \ 155 static const Type kType = T##_Type; \ 156 static const int kTags = tags; \ 157 __VA_ARGS__; \ 158 }; 159 160 RECORD(NoOp, 0); 161 RECORD(Flush, 0); 162 RECORD(Restore, 0, 163 TypedMatrix matrix); 164 RECORD(Save, 0); 165 166 RECORD(SaveLayer, kHasPaint_Tag, 167 Optional<SkRect> bounds; 168 Optional<SkPaint> paint; 169 sk_sp<const SkImageFilter> backdrop; 170 SkCanvas::SaveLayerFlags saveLayerFlags; 171 SkScalar backdropScale); 172 173 RECORD(SaveBehind, 0, 174 Optional<SkRect> subset); 175 176 RECORD(MarkCTM, 0, 177 SkString name); 178 RECORD(SetMatrix, 0, 179 TypedMatrix matrix); 180 RECORD(SetM44, 0, 181 SkM44 matrix); 182 RECORD(Concat, 0, 183 TypedMatrix matrix); 184 RECORD(Concat44, 0, 185 SkM44 matrix); 186 187 RECORD(Translate, 0, 188 SkScalar dx; 189 SkScalar dy); 190 191 RECORD(Scale, 0, 192 SkScalar sx; 193 SkScalar sy); 194 195 struct ClipOpAndAA { 196 ClipOpAndAA() {} 197 ClipOpAndAA(SkClipOp op, bool aa) : fOp(static_cast<unsigned>(op)), fAA(aa) {} 198 199 SkClipOp op() const { return static_cast<SkClipOp>(fOp); } 200 bool aa() const { return fAA != 0; } 201 202 private: 203 unsigned fOp : 31; // This really only needs to be 3, but there's no win today to do so. 204 unsigned fAA : 1; // MSVC won't pack an enum with an bool, so we call this an unsigned. 205 }; 206 static_assert(sizeof(ClipOpAndAA) == 4, "ClipOpAndAASize"); 207 208 RECORD(ClipPath, 0, 209 PreCachedPath path; 210 ClipOpAndAA opAA); 211 RECORD(ClipRRect, 0, 212 SkRRect rrect; 213 ClipOpAndAA opAA); 214 RECORD(ClipRect, 0, 215 SkRect rect; 216 ClipOpAndAA opAA); 217 RECORD(ClipRegion, 0, 218 SkRegion region; 219 SkClipOp op); 220 RECORD(ClipShader, 0, 221 sk_sp<SkShader> shader; 222 SkClipOp op); 223 RECORD(ResetClip, 0); 224 225 // While not strictly required, if you have an SkPaint, it's fastest to put it first. 226 RECORD(DrawArc, kDraw_Tag|kHasPaint_Tag, 227 SkPaint paint; 228 SkRect oval; 229 SkScalar startAngle; 230 SkScalar sweepAngle; 231 unsigned useCenter); 232 RECORD(DrawDRRect, kDraw_Tag|kHasPaint_Tag, 233 SkPaint paint; 234 SkRRect outer; 235 SkRRect inner); 236 RECORD(DrawDrawable, kDraw_Tag, 237 Optional<SkMatrix> matrix; 238 SkRect worstCaseBounds; 239 int32_t index); 240 RECORD(DrawImage, kDraw_Tag|kHasImage_Tag|kHasPaint_Tag, 241 Optional<SkPaint> paint; 242 sk_sp<const SkImage> image; 243 SkScalar left; 244 SkScalar top; 245 SkSamplingOptions sampling); 246 RECORD(DrawImageLattice, kDraw_Tag|kHasImage_Tag|kHasPaint_Tag, 247 Optional<SkPaint> paint; 248 sk_sp<const SkImage> image; 249 int xCount; 250 PODArray<int> xDivs; 251 int yCount; 252 PODArray<int> yDivs; 253 int flagCount; 254 PODArray<SkCanvas::Lattice::RectType> flags; 255 PODArray<SkColor> colors; 256 SkIRect src; 257 SkRect dst; 258 SkFilterMode filter); 259 RECORD(DrawImageRect, kDraw_Tag|kHasImage_Tag|kHasPaint_Tag, 260 Optional<SkPaint> paint; 261 sk_sp<const SkImage> image; 262 SkRect src; 263 SkRect dst; 264 SkSamplingOptions sampling; 265 SkCanvas::SrcRectConstraint constraint); 266 RECORD(DrawOval, kDraw_Tag|kHasPaint_Tag, 267 SkPaint paint; 268 SkRect oval); 269 RECORD(DrawPaint, kDraw_Tag|kHasPaint_Tag, 270 SkPaint paint); 271 RECORD(DrawBehind, kDraw_Tag|kHasPaint_Tag, 272 SkPaint paint); 273 RECORD(DrawPath, kDraw_Tag|kHasPaint_Tag, 274 SkPaint paint; 275 PreCachedPath path); 276 RECORD(DrawPicture, kDraw_Tag|kHasPaint_Tag, 277 Optional<SkPaint> paint; 278 sk_sp<const SkPicture> picture; 279 TypedMatrix matrix); 280 RECORD(DrawPoints, kDraw_Tag|kHasPaint_Tag, 281 SkPaint paint; 282 SkCanvas::PointMode mode; 283 unsigned count; 284 PODArray<SkPoint> pts); 285 RECORD(DrawRRect, kDraw_Tag|kHasPaint_Tag, 286 SkPaint paint; 287 SkRRect rrect); 288 RECORD(DrawRect, kDraw_Tag|kHasPaint_Tag, 289 SkPaint paint; 290 SkRect rect); 291 RECORD(DrawRegion, kDraw_Tag|kHasPaint_Tag, 292 SkPaint paint; 293 SkRegion region); 294 RECORD(DrawTextBlob, kDraw_Tag|kHasText_Tag|kHasPaint_Tag, 295 SkPaint paint; 296 sk_sp<const SkTextBlob> blob; 297 SkScalar x; 298 SkScalar y); 299 RECORD(DrawPatch, kDraw_Tag|kHasPaint_Tag, 300 SkPaint paint; 301 PODArray<SkPoint> cubics; 302 PODArray<SkColor> colors; 303 PODArray<SkPoint> texCoords; 304 SkBlendMode bmode); 305 RECORD(DrawAtlas, kDraw_Tag|kHasImage_Tag|kHasPaint_Tag, 306 Optional<SkPaint> paint; 307 sk_sp<const SkImage> atlas; 308 PODArray<SkRSXform> xforms; 309 PODArray<SkRect> texs; 310 PODArray<SkColor> colors; 311 int count; 312 SkBlendMode mode; 313 SkSamplingOptions sampling; 314 Optional<SkRect> cull); 315 RECORD(DrawVertices, kDraw_Tag|kHasPaint_Tag, 316 SkPaint paint; 317 sk_sp<SkVertices> vertices; 318 SkBlendMode bmode); 319 RECORD(DrawShadowRec, kDraw_Tag, 320 PreCachedPath path; 321 SkDrawShadowRec rec); 322 RECORD(DrawAnnotation, 0, // TODO: kDraw_Tag, skia:5548 323 SkRect rect; 324 SkString key; 325 sk_sp<SkData> value); 326 RECORD(DrawEdgeAAQuad, kDraw_Tag, 327 SkRect rect; 328 PODArray<SkPoint> clip; 329 SkCanvas::QuadAAFlags aa; 330 SkColor4f color; 331 SkBlendMode mode); 332 RECORD(DrawEdgeAAImageSet, kDraw_Tag|kHasImage_Tag|kHasPaint_Tag, 333 Optional<SkPaint> paint; 334 SkAutoTArray<SkCanvas::ImageSetEntry> set; 335 int count; 336 PODArray<SkPoint> dstClips; 337 PODArray<SkMatrix> preViewMatrices; 338 SkSamplingOptions sampling; 339 SkCanvas::SrcRectConstraint constraint); 340 #undef RECORD 341 342 } // namespace SkRecords 343 344 #endif//SkRecords_DEFINED 345