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 "SkCanvas.h"
     12 #include "SkDrawable.h"
     13 #include "SkImageFilter.h"
     14 #include "SkMatrix.h"
     15 #include "SkPath.h"
     16 #include "SkPicture.h"
     17 #include "SkRect.h"
     18 #include "SkRRect.h"
     19 #include "SkRSXform.h"
     20 #include "SkTextBlob.h"
     21 
     22 namespace SkRecords {
     23 
     24 // A list of all the types of canvas calls we can record.
     25 // Each of these is reified into a struct below.
     26 //
     27 // (We're using the macro-of-macro trick here to do several different things with the same list.)
     28 //
     29 // We leave this SK_RECORD_TYPES macro defined for use by code that wants to operate on SkRecords
     30 // types polymorphically.  (See SkRecord::Record::{visit,mutate} for an example.)
     31 //
     32 // Order doesn't technically matter here, but the compiler can generally generate better code if
     33 // you keep them semantically grouped, especially the Draws.  It's also nice to leave NoOp at 0.
     34 #define SK_RECORD_TYPES(M)                                          \
     35     M(NoOp)                                                         \
     36     M(Restore)                                                      \
     37     M(Save)                                                         \
     38     M(SaveLayer)                                                    \
     39     M(SetMatrix)                                                    \
     40     M(Concat)                                                       \
     41     M(ClipPath)                                                     \
     42     M(ClipRRect)                                                    \
     43     M(ClipRect)                                                     \
     44     M(ClipRegion)                                                   \
     45     M(DrawBitmap)                                                   \
     46     M(DrawBitmapNine)                                               \
     47     M(DrawBitmapRect)                                               \
     48     M(DrawBitmapRectFast)                                           \
     49     M(DrawBitmapRectFixedSize)                                      \
     50     M(DrawDrawable)                                                 \
     51     M(DrawImage)                                                    \
     52     M(DrawImageRect)                                                \
     53     M(DrawImageNine)                                                \
     54     M(DrawDRRect)                                                   \
     55     M(DrawOval)                                                     \
     56     M(DrawPaint)                                                    \
     57     M(DrawPath)                                                     \
     58     M(DrawPatch)                                                    \
     59     M(DrawPicture)                                                  \
     60     M(DrawPoints)                                                   \
     61     M(DrawPosText)                                                  \
     62     M(DrawPosTextH)                                                 \
     63     M(DrawText)                                                     \
     64     M(DrawTextOnPath)                                               \
     65     M(DrawRRect)                                                    \
     66     M(DrawRect)                                                     \
     67     M(DrawTextBlob)                                                 \
     68     M(DrawAtlas)                                                    \
     69     M(DrawVertices)
     70 
     71 // Defines SkRecords::Type, an enum of all record types.
     72 #define ENUM(T) T##_Type,
     73 enum Type { SK_RECORD_TYPES(ENUM) };
     74 #undef ENUM
     75 
     76 #define ACT_AS_PTR(ptr)                 \
     77     operator T*() const { return ptr; } \
     78     T* operator->() const { return ptr; }
     79 
     80 template <typename T>
     81 class RefBox : SkNoncopyable {
     82 public:
     83     RefBox() {}
     84     RefBox(T* obj) : fObj(SkSafeRef(obj)) {}
     85     RefBox(RefBox&& o) : fObj(o.fObj) {
     86         o.fObj = nullptr;
     87     }
     88     ~RefBox() { SkSafeUnref(fObj); }
     89 
     90     ACT_AS_PTR(fObj);
     91 
     92 private:
     93     T* fObj;
     94 };
     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:
    100     Optional() : fPtr(nullptr) {}
    101     Optional(T* ptr) : fPtr(ptr) {}
    102     Optional(Optional&& o) : fPtr(o.fPtr) {
    103         o.fPtr = nullptr;
    104     }
    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 // Like SkBitmap, but deep copies pixels if they're not immutable.
    145 // Using this, we guarantee the immutability of all bitmaps we record.
    146 class ImmutableBitmap : SkNoncopyable {
    147 public:
    148     ImmutableBitmap() {}
    149     ImmutableBitmap(const SkBitmap& bitmap);
    150     ImmutableBitmap(ImmutableBitmap&& o) {
    151         fBitmap.swap(o.fBitmap);
    152     }
    153 
    154     int width()  const { return fBitmap.width();  }
    155     int height() const { return fBitmap.height(); }
    156 
    157     // While the pixels are immutable, SkBitmap itself is not thread-safe, so return a copy.
    158     SkBitmap shallowCopy() const { return fBitmap; }
    159 private:
    160     SkBitmap fBitmap;
    161 };
    162 
    163 // SkPath::getBounds() isn't thread safe unless we precache the bounds in a singlethreaded context.
    164 // SkPath::cheapComputeDirection() is similar.
    165 // Recording is a convenient time to cache these, or we can delay it to between record and playback.
    166 struct PreCachedPath : public SkPath {
    167     PreCachedPath() {}
    168     PreCachedPath(const SkPath& path);
    169 };
    170 
    171 // Like SkPath::getBounds(), SkMatrix::getType() isn't thread safe unless we precache it.
    172 // This may not cover all SkMatrices used by the picture (e.g. some could be hiding in a shader).
    173 struct TypedMatrix : public SkMatrix {
    174     TypedMatrix() {}
    175     TypedMatrix(const SkMatrix& matrix);
    176 };
    177 
    178 enum Tags {
    179     kDraw_Tag      = 1,   // May draw something (usually named DrawFoo).
    180     kHasImage_Tag  = 2,   // Contains an SkImage or SkBitmap.
    181     kHasText_Tag   = 4,   // Contains text.
    182 };
    183 
    184 // A macro to make it a little easier to define a struct that can be stored in SkRecord.
    185 #define RECORD(T, tags, ...)            \
    186 struct T {                              \
    187     static const Type kType = T##_Type; \
    188     static const int kTags = tags;      \
    189     __VA_ARGS__;                        \
    190 };
    191 
    192 RECORD(NoOp, 0);
    193 RECORD(Restore, 0,
    194         SkIRect devBounds;
    195         TypedMatrix matrix);
    196 RECORD(Save, 0);
    197 
    198 RECORD(SaveLayer, 0,
    199        Optional<SkRect> bounds;
    200        Optional<SkPaint> paint;
    201        RefBox<const SkImageFilter> backdrop;
    202        SkCanvas::SaveLayerFlags saveLayerFlags);
    203 
    204 RECORD(SetMatrix, 0,
    205         TypedMatrix matrix);
    206 RECORD(Concat, 0,
    207         TypedMatrix matrix);
    208 
    209 struct RegionOpAndAA {
    210     RegionOpAndAA() {}
    211     RegionOpAndAA(SkRegion::Op op, bool aa) : op(op), aa(aa) {}
    212     SkRegion::Op op : 31;  // This really only needs to be 3, but there's no win today to do so.
    213     unsigned     aa :  1;  // MSVC won't pack an enum with an bool, so we call this an unsigned.
    214 };
    215 static_assert(sizeof(RegionOpAndAA) == 4, "RegionOpAndAASize");
    216 
    217 RECORD(ClipPath, 0,
    218         SkIRect devBounds;
    219         PreCachedPath path;
    220         RegionOpAndAA opAA);
    221 RECORD(ClipRRect, 0,
    222         SkIRect devBounds;
    223         SkRRect rrect;
    224         RegionOpAndAA opAA);
    225 RECORD(ClipRect, 0,
    226         SkIRect devBounds;
    227         SkRect rect;
    228         RegionOpAndAA opAA);
    229 RECORD(ClipRegion, 0,
    230         SkIRect devBounds;
    231         SkRegion region;
    232         SkRegion::Op op);
    233 
    234 // While not strictly required, if you have an SkPaint, it's fastest to put it first.
    235 RECORD(DrawBitmap, kDraw_Tag|kHasImage_Tag,
    236         Optional<SkPaint> paint;
    237         ImmutableBitmap bitmap;
    238         SkScalar left;
    239         SkScalar top);
    240 RECORD(DrawBitmapNine, kDraw_Tag|kHasImage_Tag,
    241         Optional<SkPaint> paint;
    242         ImmutableBitmap bitmap;
    243         SkIRect center;
    244         SkRect dst);
    245 RECORD(DrawBitmapRect, kDraw_Tag|kHasImage_Tag,
    246         Optional<SkPaint> paint;
    247         ImmutableBitmap bitmap;
    248         Optional<SkRect> src;
    249         SkRect dst);
    250 RECORD(DrawBitmapRectFast, kDraw_Tag|kHasImage_Tag,
    251         Optional<SkPaint> paint;
    252         ImmutableBitmap bitmap;
    253         Optional<SkRect> src;
    254         SkRect dst);
    255 RECORD(DrawBitmapRectFixedSize, kDraw_Tag|kHasImage_Tag,
    256         SkPaint paint;
    257         ImmutableBitmap bitmap;
    258         SkRect src;
    259         SkRect dst;
    260         SkCanvas::SrcRectConstraint constraint);
    261 RECORD(DrawDRRect, kDraw_Tag,
    262         SkPaint paint;
    263         SkRRect outer;
    264         SkRRect inner);
    265 RECORD(DrawDrawable, kDraw_Tag,
    266         Optional<SkMatrix> matrix;
    267         SkRect worstCaseBounds;
    268         int32_t index);
    269 RECORD(DrawImage, kDraw_Tag|kHasImage_Tag,
    270         Optional<SkPaint> paint;
    271         RefBox<const SkImage> image;
    272         SkScalar left;
    273         SkScalar top);
    274 RECORD(DrawImageRect, kDraw_Tag|kHasImage_Tag,
    275         Optional<SkPaint> paint;
    276         RefBox<const SkImage> image;
    277         Optional<SkRect> src;
    278         SkRect dst;
    279         SkCanvas::SrcRectConstraint constraint);
    280 RECORD(DrawImageNine, kDraw_Tag|kHasImage_Tag,
    281         Optional<SkPaint> paint;
    282         RefBox<const SkImage> image;
    283         SkIRect center;
    284         SkRect dst);
    285 RECORD(DrawOval, kDraw_Tag,
    286         SkPaint paint;
    287         SkRect oval);
    288 RECORD(DrawPaint, kDraw_Tag,
    289         SkPaint paint);
    290 RECORD(DrawPath, kDraw_Tag,
    291         SkPaint paint;
    292         PreCachedPath path);
    293 RECORD(DrawPicture, kDraw_Tag,
    294         Optional<SkPaint> paint;
    295         RefBox<const SkPicture> picture;
    296         TypedMatrix matrix);
    297 RECORD(DrawPoints, kDraw_Tag,
    298         SkPaint paint;
    299         SkCanvas::PointMode mode;
    300         unsigned count;
    301         SkPoint* pts);
    302 RECORD(DrawPosText, kDraw_Tag|kHasText_Tag,
    303         SkPaint paint;
    304         PODArray<char> text;
    305         size_t byteLength;
    306         PODArray<SkPoint> pos);
    307 RECORD(DrawPosTextH, kDraw_Tag|kHasText_Tag,
    308         SkPaint paint;
    309         PODArray<char> text;
    310         unsigned byteLength;
    311         SkScalar y;
    312         PODArray<SkScalar> xpos);
    313 RECORD(DrawRRect, kDraw_Tag,
    314         SkPaint paint;
    315         SkRRect rrect);
    316 RECORD(DrawRect, kDraw_Tag,
    317         SkPaint paint;
    318         SkRect rect);
    319 RECORD(DrawText, kDraw_Tag|kHasText_Tag,
    320         SkPaint paint;
    321         PODArray<char> text;
    322         size_t byteLength;
    323         SkScalar x;
    324         SkScalar y);
    325 RECORD(DrawTextBlob, kDraw_Tag|kHasText_Tag,
    326         SkPaint paint;
    327         RefBox<const SkTextBlob> blob;
    328         SkScalar x;
    329         SkScalar y);
    330 RECORD(DrawTextOnPath, kDraw_Tag|kHasText_Tag,
    331         SkPaint paint;
    332         PODArray<char> text;
    333         size_t byteLength;
    334         PreCachedPath path;
    335         TypedMatrix matrix);
    336 RECORD(DrawPatch, kDraw_Tag,
    337         SkPaint paint;
    338         PODArray<SkPoint> cubics;
    339         PODArray<SkColor> colors;
    340         PODArray<SkPoint> texCoords;
    341         RefBox<SkXfermode> xmode);
    342 RECORD(DrawAtlas, kDraw_Tag|kHasImage_Tag,
    343         Optional<SkPaint> paint;
    344         RefBox<const SkImage> atlas;
    345         PODArray<SkRSXform> xforms;
    346         PODArray<SkRect> texs;
    347         PODArray<SkColor> colors;
    348         int count;
    349         SkXfermode::Mode mode;
    350         Optional<SkRect> cull);
    351 RECORD(DrawVertices, kDraw_Tag,
    352         SkPaint paint;
    353         SkCanvas::VertexMode vmode;
    354         int vertexCount;
    355         PODArray<SkPoint> vertices;
    356         PODArray<SkPoint> texs;
    357         PODArray<SkColor> colors;
    358         RefBox<SkXfermode> xmode;
    359         PODArray<uint16_t> indices;
    360         int indexCount);
    361 
    362 #undef RECORD
    363 
    364 }  // namespace SkRecords
    365 
    366 #endif//SkRecords_DEFINED
    367