aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/pipe/SkGPipePriv.h
blob: 31803ea9b55a88b78cb4990f0a2fc4d52ff474bd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278

/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */



#ifndef SkGPipePriv_DEFINED
#define SkGPipePriv_DEFINED

#include "SkTypes.h"

#define UNIMPLEMENTED

// these must be contiguous, 0...N-1
enum PaintFlats {
    kColorFilter_PaintFlat,
    kDrawLooper_PaintFlat,
    kMaskFilter_PaintFlat,
    kPathEffect_PaintFlat,
    kRasterizer_PaintFlat,
    kShader_PaintFlat,
    kImageFilter_PaintFlat,
    kXfermode_PaintFlat,

    kLast_PaintFlat = kXfermode_PaintFlat
};
#define kCount_PaintFlats   (kLast_PaintFlat + 1)

enum DrawOps {
    kSkip_DrawOp,   // skip an addition N bytes (N == data)

    // these match Canvas apis
    kClipPath_DrawOp,
    kClipRegion_DrawOp,
    kClipRect_DrawOp,
    kConcat_DrawOp,
    kDrawBitmap_DrawOp,
    kDrawBitmapMatrix_DrawOp,
    kDrawBitmapNine_DrawOp,
    kDrawBitmapRectToRect_DrawOp,
    kDrawClear_DrawOp,
    kDrawData_DrawOp,
    kDrawPaint_DrawOp,
    kDrawPath_DrawOp,
    kDrawPicture_DrawOp,
    kDrawPoints_DrawOp,
    kDrawPosText_DrawOp,
    kDrawPosTextH_DrawOp,
    kDrawRect_DrawOp,
    kDrawSprite_DrawOp,
    kDrawText_DrawOp,
    kDrawTextOnPath_DrawOp,
    kDrawVertices_DrawOp,
    kRestore_DrawOp,
    kRotate_DrawOp,
    kSave_DrawOp,
    kSaveLayer_DrawOp,
    kScale_DrawOp,
    kSetMatrix_DrawOp,
    kSkew_DrawOp,
    kTranslate_DrawOp,

    kPaintOp_DrawOp,
    kSetTypeface_DrawOp,

    kDef_Typeface_DrawOp,
    kDef_Flattenable_DrawOp,
    kDef_Bitmap_DrawOp,
    kDef_Factory_DrawOp,

    // these are signals to playback, not drawing verbs
    kReportFlags_DrawOp,
    kShareBitmapHeap_DrawOp,
    kDone_DrawOp,
};

/**
 *  DrawOp packs into a 32bit int as follows
 *
 *  DrawOp:8 - Flags:4 - Data:20
 *
 *  Flags and Data are called out separately, so we can reuse Data between
 *  different Ops that might have different Flags. e.g. Data might be a Paint
 *  index for both drawRect (no flags) and saveLayer (does have flags).
 *
 *  All Ops that take a SkPaint use their Data field to store the index to
 *  the paint (previously defined with kPaintOp_DrawOp).
 */

#define DRAWOPS_OP_BITS     8
#define DRAWOPS_FLAG_BITS   4
#define DRAWOPS_DATA_BITS   20

#define DRAWOPS_OP_MASK     ((1 << DRAWOPS_OP_BITS) - 1)
#define DRAWOPS_FLAG_MASK   ((1 << DRAWOPS_FLAG_BITS) - 1)
#define DRAWOPS_DATA_MASK   ((1 << DRAWOPS_DATA_BITS) - 1)

static inline unsigned DrawOp_unpackOp(uint32_t op32) {
    return (op32 >> (DRAWOPS_FLAG_BITS + DRAWOPS_DATA_BITS));
}

static inline unsigned DrawOp_unpackFlags(uint32_t op32) {
    return (op32 >> DRAWOPS_DATA_BITS) & DRAWOPS_FLAG_MASK;
}

static inline unsigned DrawOp_unpackData(uint32_t op32) {
    return op32 & DRAWOPS_DATA_MASK;
}

static inline uint32_t DrawOp_packOpFlagData(DrawOps op, unsigned flags, unsigned data) {
    SkASSERT(0 == (op & ~DRAWOPS_OP_MASK));
    SkASSERT(0 == (flags & ~DRAWOPS_FLAG_MASK));
    SkASSERT(0 == (data & ~DRAWOPS_DATA_MASK));

    return (op << (DRAWOPS_FLAG_BITS + DRAWOPS_DATA_BITS)) |
           (flags << DRAWOPS_DATA_BITS) |
            data;
}

/** DrawOp specific flag bits
 */

enum {
    kSaveLayer_HasBounds_DrawOpFlag = 1 << 0,
    kSaveLayer_HasPaint_DrawOpFlag = 1 << 1,
};
enum {
    kClear_HasColor_DrawOpFlag  = 1 << 0
};
enum {
    kDrawTextOnPath_HasMatrix_DrawOpFlag = 1 << 0
};
enum {
    kDrawVertices_HasTexs_DrawOpFlag     = 1 << 0,
    kDrawVertices_HasColors_DrawOpFlag   = 1 << 1,
    kDrawVertices_HasIndices_DrawOpFlag  = 1 << 2,
};
enum {
    kDrawBitmap_HasPaint_DrawOpFlag   = 1 << 0,
    // Specific to drawBitmapRect, but needs to be different from HasPaint,
    // which is used for all drawBitmap calls, so include it here.
    kDrawBitmap_HasSrcRect_DrawOpFlag = 1 << 1,
};
enum {
    kClip_HasAntiAlias_DrawOpFlag = 1 << 0,
};
///////////////////////////////////////////////////////////////////////////////

class BitmapInfo : SkNoncopyable {
public:
    BitmapInfo(SkBitmap* bitmap, uint32_t genID, int toBeDrawnCount)
        : fBitmap(bitmap)
        , fGenID(genID)
        , fBytesAllocated(0)
        , fMoreRecentlyUsed(NULL)
        , fLessRecentlyUsed(NULL)
        , fToBeDrawnCount(toBeDrawnCount)
    {}

    ~BitmapInfo() {
        SkASSERT(0 == fToBeDrawnCount);
        SkDELETE(fBitmap);
    }

    void addDraws(int drawsToAdd) {
        if (0 == fToBeDrawnCount) {
            // The readers will only ever decrement the count, so once the
            // count is zero, the writer will be the only one modifying it,
            // so it does not need to be an atomic operation.
            fToBeDrawnCount = drawsToAdd;
        } else {
            sk_atomic_add(&fToBeDrawnCount, drawsToAdd);
        }
    }

    void decDraws() {
        sk_atomic_dec(&fToBeDrawnCount);
    }

    int drawCount() const {
        return fToBeDrawnCount;
    }

    SkBitmap* fBitmap;
    // Store the generation ID of the original bitmap, since copying does
    // not copy this field, so fBitmap's generation ID will not be useful
    // for comparing.
    // FIXME: Is it reasonable to make copying a bitmap/pixelref copy the
    // generation ID?
    uint32_t fGenID;
    // Keep track of the bytes allocated for this bitmap. When replacing the
    // bitmap or removing this BitmapInfo we know how much memory has been
    // reclaimed.
    size_t fBytesAllocated;
    // TODO: Generalize the LRU caching mechanism
    BitmapInfo* fMoreRecentlyUsed;
    BitmapInfo* fLessRecentlyUsed;
private:
    int      fToBeDrawnCount;
};

static inline bool shouldFlattenBitmaps(uint32_t flags) {
    return SkToBool(flags & SkGPipeWriter::kCrossProcess_Flag
            && !(flags & SkGPipeWriter::kSharedAddressSpace_Flag));
}

///////////////////////////////////////////////////////////////////////////////

enum PaintOps {
    kReset_PaintOp,     // no arg

    kFlags_PaintOp,     // arg inline
    kColor_PaintOp,     // arg 32
    kStyle_PaintOp,     // arg inline
    kJoin_PaintOp,      // arg inline
    kCap_PaintOp,       // arg inline
    kWidth_PaintOp,     // arg scalar
    kMiter_PaintOp,// arg scalar

    kEncoding_PaintOp,  // arg inline - text
    kHinting_PaintOp,   // arg inline - text
    kAlign_PaintOp,     // arg inline - text
    kTextSize_PaintOp,  // arg scalar - text
    kTextScaleX_PaintOp,// arg scalar - text
    kTextSkewX_PaintOp, // arg scalar - text
    kTypeface_PaintOp,  // arg inline (index) - text

    kFlatIndex_PaintOp, // flags=paintflat, data=index
};

#define PAINTOPS_OP_BITS     8
#define PAINTOPS_FLAG_BITS   4
#define PAINTOPS_DATA_BITS   20

#define PAINTOPS_OP_MASK     ((1 << PAINTOPS_OP_BITS) - 1)
#define PAINTOPS_FLAG_MASK   ((1 << PAINTOPS_FLAG_BITS) - 1)
#define PAINTOPS_DATA_MASK   ((1 << PAINTOPS_DATA_BITS) - 1)

static inline unsigned PaintOp_unpackOp(uint32_t op32) {
    return (op32 >> (PAINTOPS_FLAG_BITS + PAINTOPS_DATA_BITS));
}

static inline unsigned PaintOp_unpackFlags(uint32_t op32) {
    return (op32 >> PAINTOPS_DATA_BITS) & PAINTOPS_FLAG_MASK;
}

static inline unsigned PaintOp_unpackData(uint32_t op32) {
    return op32 & PAINTOPS_DATA_MASK;
}

static inline uint32_t PaintOp_packOp(PaintOps op) {
    SkASSERT(0 == (op & ~PAINTOPS_OP_MASK));

    return op << (PAINTOPS_FLAG_BITS + PAINTOPS_DATA_BITS);
}

static inline uint32_t PaintOp_packOpData(PaintOps op, unsigned data) {
    SkASSERT(0 == (op & ~PAINTOPS_OP_MASK));
    SkASSERT(0 == (data & ~PAINTOPS_DATA_MASK));

    return (op << (PAINTOPS_FLAG_BITS + PAINTOPS_DATA_BITS)) | data;
}

static inline uint32_t PaintOp_packOpFlagData(PaintOps op, unsigned flags, unsigned data) {
    SkASSERT(0 == (op & ~PAINTOPS_OP_MASK));
    SkASSERT(0 == (flags & ~PAINTOPS_FLAG_MASK));
    SkASSERT(0 == (data & ~PAINTOPS_DATA_MASK));

    return (op << (PAINTOPS_FLAG_BITS + PAINTOPS_DATA_BITS)) |
    (flags << PAINTOPS_DATA_BITS) |
    data;
}

#endif