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