Flutter Engine
The Flutter Engine
Public Member Functions | Static Public Member Functions | Public Attributes | List of all members
SkAlphaRuns Class Reference

#include <SkAlphaRuns.h>

Public Member Functions

bool empty () const
 
void reset (int width)
 Reinitialize for a new scanline. More...
 
SK_ALWAYS_INLINE int add (int x, U8CPU startAlpha, int middleCount, U8CPU stopAlpha, U8CPU maxValue, int offsetX)
 
 SkDEBUGCODE (void assertValid(int y, int maxStep) const ;) SkDEBUGCODE(void dump() const
 

Static Public Member Functions

static SkAlpha CatchOverflow (int alpha)
 
static void Break (int16_t runs[], uint8_t alpha[], int x, int count)
 
static void BreakAt (int16_t runs[], uint8_t alpha[], int x)
 

Public Attributes

int16_t * fRuns
 
uint8_t * fAlpha
 

Detailed Description

Sparse array of run-length-encoded alpha (supersampling coverage) values. Sparseness allows us to independently compose several paths into the same SkAlphaRuns buffer.

Definition at line 24 of file SkAlphaRuns.h.

Member Function Documentation

◆ add()

SK_ALWAYS_INLINE int SkAlphaRuns::add ( int  x,
U8CPU  startAlpha,
int  middleCount,
U8CPU  stopAlpha,
U8CPU  maxValue,
int  offsetX 
)
inline

Insert into the buffer a run starting at (x-offsetX): if startAlpha > 0 one pixel with value += startAlpha, max 255 if middleCount > 0 middleCount pixels with value += maxValue if stopAlpha > 0 one pixel with value += stopAlpha Returns the offsetX value that should be passed on the next call, assuming we're on the same scanline. If the caller is switching scanlines, then offsetX should be 0 when this is called.

Definition at line 58 of file SkAlphaRuns.h.

59 {
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 }
#define SkASSERT(cond)
Definition: SkAssert.h:116
constexpr int32_t SkToS32(S x)
Definition: SkTo.h:25
constexpr uint8_t SkToU8(S x)
Definition: SkTo.h:22
static void Break(int16_t runs[], uint8_t alpha[], int x, int count)
Definition: SkAlphaRuns.h:126
uint8_t * fAlpha
Definition: SkAlphaRuns.h:27
SkDEBUGCODE(void assertValid(int y, int maxStep) const ;) SkDEBUGCODE(void dump() const
int16_t * fRuns
Definition: SkAlphaRuns.h:26
static SkAlpha CatchOverflow(int alpha)
Definition: SkAlphaRuns.h:30
double x
SkScalar offsetX

◆ Break()

static void SkAlphaRuns::Break ( int16_t  runs[],
uint8_t  alpha[],
int  x,
int  count 
)
inlinestatic

Break the runs in the buffer at offsets x and x+count, properly updating the runs to the right and left. i.e. from the state AAAABBBB, run-length encoded as A4B4, Break(..., 2, 5) would produce AAAABBBB rle as A2A2B3B1. Allows add() to sum another run to some of the new sub-runs. i.e. adding ..CCCCC. would produce AADDEEEB, rle as A2D2E3B1.

Definition at line 126 of file SkAlphaRuns.h.

126 {
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 }
int count
Definition: FontMgrTest.cpp:50
constexpr int16_t SkToS16(S x)
Definition: SkTo.h:23

◆ BreakAt()

static void SkAlphaRuns::BreakAt ( int16_t  runs[],
uint8_t  alpha[],
int  x 
)
inlinestatic

Cut (at offset x in the buffer) a run into two shorter runs with matching alpha values. Used by the RectClipBlitter to trim a RLE encoding to match the clipping rectangle.

Definition at line 179 of file SkAlphaRuns.h.

179 {
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 }

◆ CatchOverflow()

static SkAlpha SkAlphaRuns::CatchOverflow ( int  alpha)
inlinestatic

Definition at line 30 of file SkAlphaRuns.h.

30 {
31 SkASSERT(alpha >= 0 && alpha <= 256);
32 return alpha - (alpha >> 8);
33 }

◆ empty()

bool SkAlphaRuns::empty ( ) const
inline

Returns true if the scanline contains only a single run, of alpha value 0.

Definition at line 37 of file SkAlphaRuns.h.

37 {
38 SkASSERT(fRuns[0] > 0);
39 return fAlpha[0] == 0 && fRuns[fRuns[0]] == 0;
40 }

◆ reset()

void SkAlphaRuns::reset ( int  width)

Reinitialize for a new scanline.

Definition at line 11 of file SkAlphaRuns.cpp.

11 {
12 SkASSERT(width > 0);
13
14#ifdef SK_DEBUG
15 SkOpts::memset16((uint16_t*)fRuns, (uint16_t)(-42), width);
16#endif
17 fRuns[0] = SkToS16(width);
18 fRuns[width] = 0;
19 fAlpha[0] = 0;
20
21 SkDEBUGCODE(fWidth = width;)
22 SkDEBUGCODE(this->validate();)
23}
void(* memset16)(uint16_t[], uint16_t, int)
int32_t width

◆ SkDEBUGCODE()

SkAlphaRuns::SkDEBUGCODE ( void assertValid(int y, int maxStep) const ;  ) const

Member Data Documentation

◆ fAlpha

uint8_t* SkAlphaRuns::fAlpha

Definition at line 27 of file SkAlphaRuns.h.

◆ fRuns

int16_t* SkAlphaRuns::fRuns

Definition at line 26 of file SkAlphaRuns.h.


The documentation for this class was generated from the following files: