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