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