Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
SkAlphaRuns.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 SkAlphaRuns_DEFINED
9#define SkAlphaRuns_DEFINED
10
16
17#include <cstdint>
18
19/** Sparse array of run-length-encoded alpha (supersampling coverage) values.
20 Sparseness allows us to independently compose several paths into the
21 same SkAlphaRuns buffer.
22*/
23
25public:
26 int16_t* fRuns;
27 uint8_t* fAlpha;
28
29 // Return 0-255 given 0-256
30 static inline SkAlpha CatchOverflow(int alpha) {
31 SkASSERT(alpha >= 0 && alpha <= 256);
32 return alpha - (alpha >> 8);
33 }
34
35 /// Returns true if the scanline contains only a single run,
36 /// of alpha value 0.
37 bool empty() const {
38 SkASSERT(fRuns[0] > 0);
39 return fAlpha[0] == 0 && fRuns[fRuns[0]] == 0;
40 }
41
42 /// Reinitialize for a new scanline.
43 void reset(int width);
44
45 /**
46 * Insert into the buffer a run starting at (x-offsetX):
47 * if startAlpha > 0
48 * one pixel with value += startAlpha,
49 * max 255
50 * if middleCount > 0
51 * middleCount pixels with value += maxValue
52 * if stopAlpha > 0
53 * one pixel with value += stopAlpha
54 * Returns the offsetX value that should be passed on the next call,
55 * assuming we're on the same scanline. If the caller is switching
56 * scanlines, then offsetX should be 0 when this is called.
57 */
58 SK_ALWAYS_INLINE int add(int x, U8CPU startAlpha, int middleCount, U8CPU stopAlpha,
59 U8CPU maxValue, int offsetX) {
60 SkASSERT(middleCount >= 0);
61 SkASSERT(x >= 0 && x + (startAlpha != 0) + middleCount + (stopAlpha != 0) <= fWidth);
62
63 SkASSERT(fRuns[offsetX] >= 0);
64
65 int16_t* runs = fRuns + offsetX;
66 uint8_t* alpha = fAlpha + offsetX;
67 uint8_t* lastAlpha = alpha;
68 x -= offsetX;
69
70 if (startAlpha) {
71 SkAlphaRuns::Break(runs, alpha, x, 1);
72 /* I should be able to just add alpha[x] + startAlpha.
73 However, if the trailing edge of the previous span and the leading
74 edge of the current span round to the same super-sampled x value,
75 I might overflow to 256 with this add, hence the funny subtract (crud).
76 */
77 unsigned tmp = alpha[x] + startAlpha;
78 SkASSERT(tmp <= 256);
79 alpha[x] = SkToU8(tmp - (tmp >> 8)); // was (tmp >> 7), but that seems wrong if we're trying to catch 256
80
81 runs += x + 1;
82 alpha += x + 1;
83 x = 0;
84 SkDEBUGCODE(this->validate();)
85 }
86
87 if (middleCount) {
88 SkAlphaRuns::Break(runs, alpha, x, middleCount);
89 alpha += x;
90 runs += x;
91 x = 0;
92 do {
93 alpha[0] = SkToU8(CatchOverflow(alpha[0] + maxValue));
94 int n = runs[0];
95 SkASSERT(n <= middleCount);
96 alpha += n;
97 runs += n;
98 middleCount -= n;
99 } while (middleCount > 0);
100 SkDEBUGCODE(this->validate();)
101 lastAlpha = alpha;
102 }
103
104 if (stopAlpha) {
105 SkAlphaRuns::Break(runs, alpha, x, 1);
106 alpha += x;
107 alpha[0] = SkToU8(alpha[0] + stopAlpha);
108 SkDEBUGCODE(this->validate();)
109 lastAlpha = alpha;
110 }
111
112 return SkToS32(lastAlpha - fAlpha); // new offsetX
113 }
114
115 SkDEBUGCODE(void assertValid(int y, int maxStep) const;)
116 SkDEBUGCODE(void dump() const;)
117
118 /**
119 * Break the runs in the buffer at offsets x and x+count, properly
120 * updating the runs to the right and left.
121 * i.e. from the state AAAABBBB, run-length encoded as A4B4,
122 * Break(..., 2, 5) would produce AAAABBBB rle as A2A2B3B1.
123 * Allows add() to sum another run to some of the new sub-runs.
124 * i.e. adding ..CCCCC. would produce AADDEEEB, rle as A2D2E3B1.
125 */
126 static void Break(int16_t runs[], uint8_t alpha[], int x, int count) {
127 SkASSERT(count > 0 && x >= 0);
128
129 // SkAlphaRuns::BreakAt(runs, alpha, x);
130 // SkAlphaRuns::BreakAt(&runs[x], &alpha[x], count);
131
132 int16_t* next_runs = runs + x;
133 uint8_t* next_alpha = alpha + x;
134
135 while (x > 0) {
136 int n = runs[0];
137 SkASSERT(n > 0);
138
139 if (x < n) {
140 alpha[x] = alpha[0];
141 runs[0] = SkToS16(x);
142 runs[x] = SkToS16(n - x);
143 break;
144 }
145 runs += n;
146 alpha += n;
147 x -= n;
148 }
149
150 runs = next_runs;
151 alpha = next_alpha;
152 x = count;
153
154 for (;;) {
155 int n = runs[0];
156 SkASSERT(n > 0);
157
158 if (x < n) {
159 alpha[x] = alpha[0];
160 runs[0] = SkToS16(x);
161 runs[x] = SkToS16(n - x);
162 break;
163 }
164 x -= n;
165 if (x <= 0) {
166 break;
167 }
168 runs += n;
169 alpha += n;
170 }
171 }
172
173 /**
174 * Cut (at offset x in the buffer) a run into two shorter runs with
175 * matching alpha values.
176 * Used by the RectClipBlitter to trim a RLE encoding to match the
177 * clipping rectangle.
178 */
179 static void BreakAt(int16_t runs[], uint8_t alpha[], int x) {
180 while (x > 0) {
181 int n = runs[0];
182 SkASSERT(n > 0);
183
184 if (x < n) {
185 alpha[x] = alpha[0];
186 runs[0] = SkToS16(x);
187 runs[x] = SkToS16(n - x);
188 break;
189 }
190 runs += n;
191 alpha += n;
192 x -= n;
193 }
194 }
195
196private:
197 SkDEBUGCODE(int fWidth;)
198 SkDEBUGCODE(void validate() const;)
199};
200
201#endif
m reset()
int count
#define SkASSERT(cond)
Definition SkAssert.h:116
#define SK_ALWAYS_INLINE
unsigned U8CPU
Definition SkCPUTypes.h:18
uint8_t SkAlpha
Definition SkColor.h:26
#define SkDEBUGCODE(...)
Definition SkDebug.h:23
constexpr int32_t SkToS32(S x)
Definition SkTo.h:25
constexpr uint8_t SkToU8(S x)
Definition SkTo.h:22
constexpr int16_t SkToS16(S x)
Definition SkTo.h:23
static void dump(const float m[20], SkYUVColorSpace cs, bool rgb2yuv)
bool empty() const
Definition SkAlphaRuns.h:37
static void Break(int16_t runs[], uint8_t alpha[], int x, int count)
uint8_t * fAlpha
Definition SkAlphaRuns.h:27
SkDEBUGCODE(void assertValid(int y, int maxStep) const ;) SkDEBUGCODE(void dump() const
SK_ALWAYS_INLINE int add(int x, U8CPU startAlpha, int middleCount, U8CPU stopAlpha, U8CPU maxValue, int offsetX)
Definition SkAlphaRuns.h:58
static void BreakAt(int16_t runs[], uint8_t alpha[], int x)
int16_t * fRuns
Definition SkAlphaRuns.h:26
static SkAlpha CatchOverflow(int alpha)
Definition SkAlphaRuns.h:30
double y
double x
SkScalar offsetX
int32_t width