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 "SkData.h" 12 #include "SkCanvas.h" 13 #include "SkDrawable.h" 14 #include "SkDrawShadowRec.h" 15 #include "SkImage.h" 16 #include "SkImageFilter.h" 17 #include "SkMatrix.h" 18 #include "SkPath.h" 19 #include "SkPicture.h" 20 #include "SkRect.h" 21 #include "SkRegion.h" 22 #include "SkRRect.h" 23 #include "SkRSXform.h" 24 #include "SkString.h" 25 #include "SkTextBlob.h" 26 #include "SkVertices.h" 27 28 // Windows.h, will pull in all of the GDI defines. GDI #defines 29 // DrawText to DrawTextA or DrawTextW, but SkRecord has a struct 30 // called DrawText. Since this file does not use GDI, undefing 31 // DrawText makes things less confusing. 32 #ifdef DrawText 33 #undef DrawText 34 #endif 35 36 namespace SkRecords { 37 38 // A list of all the types of canvas calls we can record. 39 // Each of these is reified into a struct below. 40 // 41 // (We're using the macro-of-macro trick here to do several different things with the same list.) 42 // 43 // We leave this SK_RECORD_TYPES macro defined for use by code that wants to operate on SkRecords 44 // types polymorphically. (See SkRecord::Record::{visit,mutate} for an example.) 45 // 46 // Order doesn't technically matter here, but the compiler can generally generate better code if 47 // you keep them semantically grouped, especially the Draws. It's also nice to leave NoOp at 0. 48 #define SK_RECORD_TYPES(M) \ 49 M(NoOp) \ 50 M(Restore) \ 51 M(Save) \ 52 M(SaveLayer) \ 53 M(SetMatrix) \ 54 M(Translate) \ 55 M(Concat) \ 56 M(ClipPath) \ 57 M(ClipRRect) \ 58 M(ClipRect) \ 59 M(ClipRegion) \ 60 M(DrawArc) \ 61 M(DrawDrawable) \ 62 M(DrawImage) \ 63 M(DrawImageLattice) \ 64 M(DrawImageRect) \ 65 M(DrawImageNine) \ 66 M(DrawDRRect) \ 67 M(DrawOval) \ 68 M(DrawPaint) \ 69 M(DrawPath) \ 70 M(DrawPatch) \ 71 M(DrawPicture) \ 72 M(DrawPoints) \ 73 M(DrawPosText) \ 74 M(DrawPosTextH) \ 75 M(DrawText) \ 76 M(DrawTextOnPath) \ 77 M(DrawTextRSXform) \ 78 M(DrawRRect) \ 79 M(DrawRect) \ 80 M(DrawRegion) \ 81 M(DrawTextBlob) \ 82 M(DrawAtlas) \ 83 M(DrawVertices) \ 84 M(DrawShadowRec) \ 85 M(DrawAnnotation) 86 87 // Defines SkRecords::Type, an enum of all record types. 88 #define ENUM(T) T##_Type, 89 enum Type { SK_RECORD_TYPES(ENUM) }; 90 #undef ENUM 91 92 #define ACT_AS_PTR(ptr) \ 93 operator T*() const { return ptr; } \ 94 T* operator->() const { return ptr; } 95 96 // An Optional doesn't own the pointer's memory, but may need to destroy non-POD data. 97 template <typename T> 98 class Optional : SkNoncopyable { 99 public: Optional()100 Optional() : fPtr(nullptr) {} Optional(T * ptr)101 Optional(T* ptr) : fPtr(ptr) {} Optional(Optional && o)102 Optional(Optional&& o) : fPtr(o.fPtr) { 103 o.fPtr = nullptr; 104 } ~Optional()105 ~Optional() { if (fPtr) fPtr->~T(); } 106 107 ACT_AS_PTR(fPtr) 108 private: 109 T* fPtr; 110 }; 111 112 // Like Optional, but ptr must not be NULL. 113 template <typename T> 114 class Adopted : SkNoncopyable { 115 public: 116 Adopted(T* ptr) : fPtr(ptr) { SkASSERT(fPtr); } 117 Adopted(Adopted* source) { 118 // Transfer ownership from source to this. 119 fPtr = source->fPtr; 120 source->fPtr = NULL; 121 } 122 ~Adopted() { if (fPtr) fPtr->~T(); } 123 124 ACT_AS_PTR(fPtr) 125 private: 126 T* fPtr; 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: 133 PODArray() {} 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 enum Tags { 160 kDraw_Tag = 1, // May draw something (usually named DrawFoo). 161 kHasImage_Tag = 2, // Contains an SkImage or SkBitmap. 162 kHasText_Tag = 4, // Contains text. 163 kHasPaint_Tag = 8, // May have an SkPaint field, at least optionally. 164 165 kDrawWithPaint_Tag = kDraw_Tag | kHasPaint_Tag, 166 }; 167 168 // A macro to make it a little easier to define a struct that can be stored in SkRecord. 169 #define RECORD(T, tags, ...) \ 170 struct T { \ 171 static const Type kType = T##_Type; \ 172 static const int kTags = tags; \ 173 __VA_ARGS__; \ 174 }; 175 176 RECORD(NoOp, 0); 177 RECORD(Restore, 0, 178 SkIRect devBounds; 179 TypedMatrix matrix); 180 RECORD(Save, 0); 181 182 RECORD(SaveLayer, kHasPaint_Tag, 183 Optional<SkRect> bounds; 184 Optional<SkPaint> paint; 185 sk_sp<const SkImageFilter> backdrop; 186 sk_sp<const SkImage> clipMask; 187 Optional<SkMatrix> clipMatrix; 188 SkCanvas::SaveLayerFlags saveLayerFlags); 189 190 RECORD(SetMatrix, 0, 191 TypedMatrix matrix); 192 RECORD(Concat, 0, 193 TypedMatrix matrix); 194 195 RECORD(Translate, 0, 196 SkScalar dx; 197 SkScalar dy); 198 199 struct ClipOpAndAA { 200 ClipOpAndAA() {} 201 ClipOpAndAA(SkClipOp op, bool aa) : fOp(static_cast<unsigned>(op)), fAA(aa) {} 202 203 SkClipOp op() const { return static_cast<SkClipOp>(fOp); } 204 bool aa() const { return fAA != 0; } 205 206 private: 207 unsigned fOp : 31; // This really only needs to be 3, but there's no win today to do so. 208 unsigned fAA : 1; // MSVC won't pack an enum with an bool, so we call this an unsigned. 209 }; 210 static_assert(sizeof(ClipOpAndAA) == 4, "ClipOpAndAASize"); 211 212 RECORD(ClipPath, 0, 213 SkIRect devBounds; 214 PreCachedPath path; 215 ClipOpAndAA opAA); 216 RECORD(ClipRRect, 0, 217 SkIRect devBounds; 218 SkRRect rrect; 219 ClipOpAndAA opAA); 220 RECORD(ClipRect, 0, 221 SkIRect devBounds; 222 SkRect rect; 223 ClipOpAndAA opAA); 224 RECORD(ClipRegion, 0, 225 SkIRect devBounds; 226 SkRegion region; 227 SkClipOp op); 228 229 // While not strictly required, if you have an SkPaint, it's fastest to put it first. 230 RECORD(DrawArc, kDraw_Tag|kHasPaint_Tag, 231 SkPaint paint; 232 SkRect oval; 233 SkScalar startAngle; 234 SkScalar sweepAngle; 235 unsigned useCenter); 236 RECORD(DrawDRRect, kDraw_Tag|kHasPaint_Tag, 237 SkPaint paint; 238 SkRRect outer; 239 SkRRect inner); 240 RECORD(DrawDrawable, kDraw_Tag, 241 Optional<SkMatrix> matrix; 242 SkRect worstCaseBounds; 243 int32_t index); 244 RECORD(DrawImage, kDraw_Tag|kHasImage_Tag|kHasPaint_Tag, 245 Optional<SkPaint> paint; 246 sk_sp<const SkImage> image; 247 SkScalar left; 248 SkScalar top); 249 RECORD(DrawImageLattice, kDraw_Tag|kHasImage_Tag|kHasPaint_Tag, 250 Optional<SkPaint> paint; 251 sk_sp<const SkImage> image; 252 int xCount; 253 PODArray<int> xDivs; 254 int yCount; 255 PODArray<int> yDivs; 256 int flagCount; 257 PODArray<SkCanvas::Lattice::Flags> flags; 258 SkIRect src; 259 SkRect dst); 260 RECORD(DrawImageRect, kDraw_Tag|kHasImage_Tag|kHasPaint_Tag, 261 Optional<SkPaint> paint; 262 sk_sp<const SkImage> image; 263 Optional<SkRect> src; 264 SkRect dst; 265 SkCanvas::SrcRectConstraint constraint); 266 RECORD(DrawImageNine, kDraw_Tag|kHasImage_Tag|kHasPaint_Tag, 267 Optional<SkPaint> paint; 268 sk_sp<const SkImage> image; 269 SkIRect center; 270 SkRect dst); 271 RECORD(DrawOval, kDraw_Tag|kHasPaint_Tag, 272 SkPaint paint; 273 SkRect oval); 274 RECORD(DrawPaint, kDraw_Tag|kHasPaint_Tag, 275 SkPaint paint); 276 RECORD(DrawPath, kDraw_Tag|kHasPaint_Tag, 277 SkPaint paint; 278 PreCachedPath path); 279 RECORD(DrawPicture, kDraw_Tag|kHasPaint_Tag, 280 Optional<SkPaint> paint; 281 sk_sp<const SkPicture> picture; 282 TypedMatrix matrix); 283 RECORD(DrawPoints, kDraw_Tag|kHasPaint_Tag, 284 SkPaint paint; 285 SkCanvas::PointMode mode; 286 unsigned count; 287 SkPoint* pts); 288 RECORD(DrawPosText, kDraw_Tag|kHasText_Tag|kHasPaint_Tag, 289 SkPaint paint; 290 PODArray<char> text; 291 size_t byteLength; 292 PODArray<SkPoint> pos); 293 RECORD(DrawPosTextH, kDraw_Tag|kHasText_Tag|kHasPaint_Tag, 294 SkPaint paint; 295 PODArray<char> text; 296 unsigned byteLength; 297 SkScalar y; 298 PODArray<SkScalar> xpos); 299 RECORD(DrawRRect, kDraw_Tag|kHasPaint_Tag, 300 SkPaint paint; 301 SkRRect rrect); 302 RECORD(DrawRect, kDraw_Tag|kHasPaint_Tag, 303 SkPaint paint; 304 SkRect rect); 305 RECORD(DrawRegion, kDraw_Tag|kHasPaint_Tag, 306 SkPaint paint; 307 SkRegion region); 308 RECORD(DrawText, kDraw_Tag|kHasText_Tag|kHasPaint_Tag, 309 SkPaint paint; 310 PODArray<char> text; 311 size_t byteLength; 312 SkScalar x; 313 SkScalar y); 314 RECORD(DrawTextBlob, kDraw_Tag|kHasText_Tag|kHasPaint_Tag, 315 SkPaint paint; 316 sk_sp<const SkTextBlob> blob; 317 SkScalar x; 318 SkScalar y); 319 RECORD(DrawTextOnPath, kDraw_Tag|kHasText_Tag|kHasPaint_Tag, 320 SkPaint paint; 321 PODArray<char> text; 322 size_t byteLength; 323 PreCachedPath path; 324 TypedMatrix matrix); 325 RECORD(DrawTextRSXform, kDraw_Tag|kHasText_Tag|kHasPaint_Tag, 326 SkPaint paint; 327 PODArray<char> text; 328 size_t byteLength; 329 PODArray<SkRSXform> xforms; 330 Optional<SkRect> cull); 331 RECORD(DrawPatch, kDraw_Tag|kHasPaint_Tag, 332 SkPaint paint; 333 PODArray<SkPoint> cubics; 334 PODArray<SkColor> colors; 335 PODArray<SkPoint> texCoords; 336 SkBlendMode bmode); 337 RECORD(DrawAtlas, kDraw_Tag|kHasImage_Tag|kHasPaint_Tag, 338 Optional<SkPaint> paint; 339 sk_sp<const SkImage> atlas; 340 PODArray<SkRSXform> xforms; 341 PODArray<SkRect> texs; 342 PODArray<SkColor> colors; 343 int count; 344 SkBlendMode mode; 345 Optional<SkRect> cull); 346 RECORD(DrawVertices, kDraw_Tag|kHasPaint_Tag, 347 SkPaint paint; 348 sk_sp<SkVertices> vertices; 349 SkBlendMode bmode); 350 RECORD(DrawShadowRec, kDraw_Tag, 351 PreCachedPath path; 352 SkDrawShadowRec rec); 353 RECORD(DrawAnnotation, 0, // TODO: kDraw_Tag, skia:5548 354 SkRect rect; 355 SkString key; 356 sk_sp<SkData> value); 357 #undef RECORD 358 359 } // namespace SkRecords 360 361 #endif//SkRecords_DEFINED 362