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