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