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