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