Flutter Engine
The Flutter Engine
SkBlitter.h
Go to the documentation of this file.
1/*
2 * Copyright 2006 The Android Open Source Project
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 SkBlitter_DEFINED
9#define SkBlitter_DEFINED
10
12#include "include/core/SkRect.h"
20
21#include <cstddef>
22#include <cstdint>
23
24class SkArenaAlloc;
25class SkMatrix;
26class SkPaint;
27class SkPixmap;
28class SkShader;
29class SkSurfaceProps;
30struct SkMask;
31
32/** SkBlitter and its subclasses are responsible for actually writing pixels
33 into memory. Besides efficiency, they handle clipping and antialiasing.
34 A SkBlitter subclass contains all the context needed to generate pixels
35 for the destination and how src/generated pixels map to the destination.
36 The coordinates passed to the blitX calls are in destination pixel space.
37*/
38class SkBlitter {
39public:
40 virtual ~SkBlitter();
41
42 /// Blit a horizontal run of one or more pixels.
43 virtual void blitH(int x, int y, int width) = 0;
44
45 /// Blit a horizontal run of antialiased pixels; runs[] is a *sparse*
46 /// zero-terminated run-length encoding of spans of constant alpha values.
47 /// The runs[] and antialias[] work together to represent long runs of pixels with the same
48 /// alphas. The runs[] contains the number of pixels with the same alpha, and antialias[]
49 /// contain the coverage value for that number of pixels. The runs[] (and antialias[]) are
50 /// encoded in a clever way. The runs array is zero terminated, and has enough entries for
51 /// each pixel plus one, in most cases some of the entries will not contain valid data. An entry
52 /// in the runs array contains the number of pixels (np) that have the same alpha value. The
53 /// next np value is found np entries away. For example, if runs[0] = 7, then the next valid
54 /// entry will by at runs[7]. The runs array and antialias[] are coupled by index. So, if the
55 /// np entry is at runs[45] = 12 then the alpha value can be found at antialias[45] = 0x88.
56 /// This would mean to use an alpha value of 0x88 for the next 12 pixels starting at pixel 45.
57 virtual void blitAntiH(int x, int y, const SkAlpha antialias[], const int16_t runs[]) = 0;
58
59 /// Blit a vertical run of pixels with a constant alpha value.
60 virtual void blitV(int x, int y, int height, SkAlpha alpha);
61
62 /// Blit a solid rectangle one or more pixels wide.
63 virtual void blitRect(int x, int y, int width, int height);
64
65 /** Blit a rectangle with one alpha-blended column on the left,
66 width (zero or more) opaque pixels, and one alpha-blended column
67 on the right.
68 The result will always be at least two pixels wide.
69 */
70 virtual void blitAntiRect(int x, int y, int width, int height,
71 SkAlpha leftAlpha, SkAlpha rightAlpha);
72
73 // Blit a rect in AA with size at least 3 x 3 (small rect has too many edge cases...)
74 void blitFatAntiRect(const SkRect& rect);
75
76 /// Blit a pattern of pixels defined by a rectangle-clipped mask;
77 /// typically used for text.
78 virtual void blitMask(const SkMask&, const SkIRect& clip);
79
80 // (x, y), (x + 1, y)
81 virtual void blitAntiH2(int x, int y, U8CPU a0, U8CPU a1) {
82 int16_t runs[3];
83 uint8_t aa[2];
84
85 runs[0] = 1;
86 runs[1] = 1;
87 runs[2] = 0;
88 aa[0] = SkToU8(a0);
89 aa[1] = SkToU8(a1);
90 this->blitAntiH(x, y, aa, runs);
91 }
92
93 // (x, y), (x, y + 1)
94 virtual void blitAntiV2(int x, int y, U8CPU a0, U8CPU a1) {
95 int16_t runs[2];
96 uint8_t aa[1];
97
98 runs[0] = 1;
99 runs[1] = 0;
100 aa[0] = SkToU8(a0);
101 this->blitAntiH(x, y, aa, runs);
102 // reset in case the clipping blitter modified runs
103 runs[0] = 1;
104 runs[1] = 0;
105 aa[0] = SkToU8(a1);
106 this->blitAntiH(x, y + 1, aa, runs);
107 }
108
109 /**
110 * Special method just to identify the null blitter, which is returned
111 * from Choose() if the request cannot be fulfilled. Default impl
112 * returns false.
113 */
114 virtual bool isNullBlitter() const;
115
116 /**
117 * Special methods for blitters that can blit more than one row at a time.
118 * This function returns the number of rows that this blitter could optimally
119 * process at a time. It is still required to support blitting one scanline
120 * at a time.
121 */
122 virtual int requestRowsPreserved() const { return 1; }
123
124 /**
125 * This function allocates memory for the blitter that the blitter then owns.
126 * The memory can be used by the calling function at will, but it will be
127 * released when the blitter's destructor is called. This function returns
128 * nullptr if no persistent memory is needed by the blitter.
129 */
130 virtual void* allocBlitMemory(size_t sz) {
132 }
133
134 ///@name non-virtual helpers
135#if defined(SK_SUPPORT_LEGACY_ALPHA_BITMAP_AS_COVERAGE)
136 void blitMaskRegion(const SkMask& mask, const SkRegion& clip);
137#endif
138 void blitRectRegion(const SkIRect& rect, const SkRegion& clip);
139 void blitRegion(const SkRegion& clip);
140 ///@}
141
142 /** @name Factories
143 Return the correct blitter to use given the specified context.
144 */
145 static SkBlitter* Choose(const SkPixmap& dst,
146 const SkMatrix& ctm,
147 const SkPaint& paint,
149 bool drawCoverage,
150 sk_sp<SkShader> clipShader,
151 const SkSurfaceProps& props);
152
153 static SkBlitter* ChooseSprite(const SkPixmap& dst,
154 const SkPaint&,
155 const SkPixmap& src,
156 int left, int top,
157 SkArenaAlloc*, sk_sp<SkShader> clipShader);
158 ///@}
159
160 static bool UseLegacyBlitter(const SkPixmap&, const SkPaint&, const SkMatrix&);
161
162protected:
164};
165
166/** This blitter silently never draws anything.
167*/
168class SkNullBlitter : public SkBlitter {
169public:
170 void blitH(int x, int y, int width) override;
171 void blitAntiH(int x, int y, const SkAlpha[], const int16_t runs[]) override;
172 void blitV(int x, int y, int height, SkAlpha alpha) override;
173 void blitRect(int x, int y, int width, int height) override;
174 void blitMask(const SkMask&, const SkIRect& clip) override;
175 bool isNullBlitter() const override;
176};
177
178/** Wraps another (real) blitter, and ensures that the real blitter is only
179 called with coordinates that have been clipped by the specified clipRect.
180 This means the caller need not perform the clipping ahead of time.
181*/
183public:
184 void init(SkBlitter* blitter, const SkIRect& clipRect) {
185 SkASSERT(!clipRect.isEmpty());
186 fBlitter = blitter;
187 fClipRect = clipRect;
188 }
189
190 void blitH(int x, int y, int width) override;
191 void blitAntiH(int x, int y, const SkAlpha[], const int16_t runs[]) override;
192 void blitV(int x, int y, int height, SkAlpha alpha) override;
193 void blitRect(int x, int y, int width, int height) override;
194 void blitAntiRect(int x, int y, int width, int height,
195 SkAlpha leftAlpha, SkAlpha rightAlpha) override;
196 void blitMask(const SkMask&, const SkIRect& clip) override;
197
198 int requestRowsPreserved() const override {
199 return fBlitter->requestRowsPreserved();
200 }
201
202 void* allocBlitMemory(size_t sz) override {
203 return fBlitter->allocBlitMemory(sz);
204 }
205
206private:
207 SkBlitter* fBlitter;
208 SkIRect fClipRect;
209};
210
211/** Wraps another (real) blitter, and ensures that the real blitter is only
212 called with coordinates that have been clipped by the specified clipRgn.
213 This means the caller need not perform the clipping ahead of time.
214*/
216public:
217 void init(SkBlitter* blitter, const SkRegion* clipRgn) {
218 SkASSERT(clipRgn && !clipRgn->isEmpty());
219 fBlitter = blitter;
220 fRgn = clipRgn;
221 }
222
223 void blitH(int x, int y, int width) override;
224 void blitAntiH(int x, int y, const SkAlpha[], const int16_t runs[]) override;
225 void blitV(int x, int y, int height, SkAlpha alpha) override;
226 void blitRect(int x, int y, int width, int height) override;
227 void blitAntiRect(int x, int y, int width, int height,
228 SkAlpha leftAlpha, SkAlpha rightAlpha) override;
229 void blitMask(const SkMask&, const SkIRect& clip) override;
230
231 int requestRowsPreserved() const override {
232 return fBlitter->requestRowsPreserved();
233 }
234
235 void* allocBlitMemory(size_t sz) override {
236 return fBlitter->allocBlitMemory(sz);
237 }
238
239private:
240 SkBlitter* fBlitter;
241 const SkRegion* fRgn;
242};
243
244#ifdef SK_DEBUG
245class SkRectClipCheckBlitter : public SkBlitter {
246public:
247 void init(SkBlitter* blitter, const SkIRect& clipRect) {
248 SkASSERT(blitter);
249 SkASSERT(!clipRect.isEmpty());
250 fBlitter = blitter;
251 fClipRect = clipRect;
252 }
253
254 void blitH(int x, int y, int width) override;
255 void blitAntiH(int x, int y, const SkAlpha[], const int16_t runs[]) override;
256 void blitV(int x, int y, int height, SkAlpha alpha) override;
257 void blitRect(int x, int y, int width, int height) override;
258 void blitAntiRect(int x, int y, int width, int height,
259 SkAlpha leftAlpha, SkAlpha rightAlpha) override;
260 void blitMask(const SkMask&, const SkIRect& clip) override;
261 void blitAntiH2(int x, int y, U8CPU a0, U8CPU a1) override;
262 void blitAntiV2(int x, int y, U8CPU a0, U8CPU a1) override;
263
264 int requestRowsPreserved() const override {
265 return fBlitter->requestRowsPreserved();
266 }
267
268 void* allocBlitMemory(size_t sz) override {
269 return fBlitter->allocBlitMemory(sz);
270 }
271
272private:
273 SkBlitter* fBlitter;
274 SkIRect fClipRect;
275};
276#endif
277
278/** Factory to set up the appropriate most-efficient wrapper blitter
279 to apply a clip. Returns a pointer to a member, so lifetime must
280 be managed carefully.
281*/
283public:
284 SkBlitter* apply(SkBlitter* blitter, const SkRegion* clip,
285 const SkIRect* bounds = nullptr);
286
287private:
288 SkNullBlitter fNullBlitter;
289 SkRectClipBlitter fRectBlitter;
290 SkRgnClipBlitter fRgnBlitter;
291};
292
293// A good size for creating shader contexts on the stack.
295
296#endif
#define SkASSERT(cond)
Definition: SkAssert.h:116
@ kSkBlitterContextSize
Definition: SkBlitter.h:294
unsigned U8CPU
Definition: SkCPUTypes.h:18
uint8_t SkAlpha
Definition: SkColor.h:26
static SkPath clip(const SkPath &path, const SkHalfPlane &plane)
Definition: SkPath.cpp:3892
static bool left(const SkPoint &p0, const SkPoint &p1)
constexpr uint8_t SkToU8(S x)
Definition: SkTo.h:22
void * reset(size_t size=0, OnShrink shrink=kAlloc_OnShrink)
Definition: SkAutoMalloc.h:53
SkBlitter * apply(SkBlitter *blitter, const SkRegion *clip, const SkIRect *bounds=nullptr)
Definition: SkBlitter.cpp:626
static SkBlitter * ChooseSprite(const SkPixmap &dst, const SkPaint &, const SkPixmap &src, int left, int top, SkArenaAlloc *, sk_sp< SkShader > clipShader)
void blitFatAntiRect(const SkRect &rect)
Definition: SkBlitter.cpp:67
virtual void blitAntiH2(int x, int y, U8CPU a0, U8CPU a1)
Definition: SkBlitter.h:81
static SkBlitter * Choose(const SkPixmap &dst, const SkMatrix &ctm, const SkPaint &paint, SkArenaAlloc *, bool drawCoverage, sk_sp< SkShader > clipShader, const SkSurfaceProps &props)
Definition: SkBlitter.cpp:685
virtual bool isNullBlitter() const
Definition: SkBlitter.cpp:48
static bool UseLegacyBlitter(const SkPixmap &, const SkPaint &, const SkMatrix &)
Definition: SkBlitter.cpp:648
virtual int requestRowsPreserved() const
Definition: SkBlitter.h:122
void blitRectRegion(const SkIRect &rect, const SkRegion &clip)
Definition: SkBlitter.cpp:300
virtual void blitAntiV2(int x, int y, U8CPU a0, U8CPU a1)
Definition: SkBlitter.h:94
virtual void blitMask(const SkMask &, const SkIRect &clip)
Definition: SkBlitter.cpp:201
virtual void blitAntiRect(int x, int y, int width, int height, SkAlpha leftAlpha, SkAlpha rightAlpha)
Definition: SkBlitter.cpp:143
virtual void * allocBlitMemory(size_t sz)
Definition: SkBlitter.h:130
void blitRegion(const SkRegion &clip)
Definition: SkBlitter.cpp:310
virtual void blitAntiH(int x, int y, const SkAlpha antialias[], const int16_t runs[])=0
SkAutoMalloc fBlitMemory
Definition: SkBlitter.h:163
virtual ~SkBlitter()
Definition: SkBlitter.cpp:46
virtual void blitH(int x, int y, int width)=0
Blit a horizontal run of one or more pixels.
virtual void blitV(int x, int y, int height, SkAlpha alpha)
Blit a vertical run of pixels with a constant alpha value.
Definition: SkBlitter.cpp:119
virtual void blitRect(int x, int y, int width, int height)
Blit a solid rectangle one or more pixels wide.
Definition: SkBlitter.cpp:133
void blitMask(const SkMask &, const SkIRect &clip) override
Definition: SkBlitter.cpp:327
void blitV(int x, int y, int height, SkAlpha alpha) override
Blit a vertical run of pixels with a constant alpha value.
Definition: SkBlitter.cpp:323
void blitRect(int x, int y, int width, int height) override
Blit a solid rectangle one or more pixels wide.
Definition: SkBlitter.cpp:325
bool isNullBlitter() const override
Definition: SkBlitter.cpp:329
void blitH(int x, int y, int width) override
Blit a horizontal run of one or more pixels.
Definition: SkBlitter.cpp:318
void blitAntiH(int x, int y, const SkAlpha[], const int16_t runs[]) override
Definition: SkBlitter.cpp:320
void blitAntiH(int x, int y, const SkAlpha[], const int16_t runs[]) override
Definition: SkBlitter.cpp:379
int requestRowsPreserved() const override
Definition: SkBlitter.h:198
void blitH(int x, int y, int width) override
Blit a horizontal run of one or more pixels.
Definition: SkBlitter.cpp:357
void blitV(int x, int y, int height, SkAlpha alpha) override
Blit a vertical run of pixels with a constant alpha value.
Definition: SkBlitter.cpp:417
void blitAntiRect(int x, int y, int width, int height, SkAlpha leftAlpha, SkAlpha rightAlpha) override
Definition: SkBlitter.cpp:448
void blitMask(const SkMask &, const SkIRect &clip) override
Definition: SkBlitter.cpp:479
void init(SkBlitter *blitter, const SkIRect &clipRect)
Definition: SkBlitter.h:184
void blitRect(int x, int y, int width, int height) override
Blit a solid rectangle one or more pixels wide.
Definition: SkBlitter.cpp:439
void * allocBlitMemory(size_t sz) override
Definition: SkBlitter.h:202
bool isEmpty() const
Definition: SkRegion.h:146
void blitMask(const SkMask &, const SkIRect &clip) override
Definition: SkBlitter.cpp:611
void blitAntiH(int x, int y, const SkAlpha[], const int16_t runs[]) override
Definition: SkBlitter.cpp:501
void init(SkBlitter *blitter, const SkRegion *clipRgn)
Definition: SkBlitter.h:217
int requestRowsPreserved() const override
Definition: SkBlitter.h:231
void blitRect(int x, int y, int width, int height) override
Blit a solid rectangle one or more pixels wide.
Definition: SkBlitter.cpp:558
void blitV(int x, int y, int height, SkAlpha alpha) override
Blit a vertical run of pixels with a constant alpha value.
Definition: SkBlitter.cpp:543
void * allocBlitMemory(size_t sz) override
Definition: SkBlitter.h:235
void blitAntiRect(int x, int y, int width, int height, SkAlpha leftAlpha, SkAlpha rightAlpha) override
Definition: SkBlitter.cpp:573
void blitH(int x, int y, int width) override
Blit a horizontal run of one or more pixels.
Definition: SkBlitter.cpp:491
const Paint & paint
Definition: color_source.cc:38
double y
double x
static bool init()
Optional< SkRect > bounds
Definition: SkRecords.h:189
clipRect(r.rect, r.opAA.op(), r.opAA.aa())) template<> void Draw
sk_sp< SkBlender > blender SkRect rect
Definition: SkRecords.h:350
dst
Definition: cp.py:12
int32_t height
int32_t width
Definition: SkRect.h:32
Definition: SkMask.h:25