blob: 12930e66759221b290b0fcdcedfc45341d140503 [file] [log] [blame]
reed@android.com8a1c16f2008-12-17 15:59:43 +00001/* libs/graphics/sgl/SkAntiRun.h
2**
3** Copyright 2006, The Android Open Source Project
4**
5** Licensed under the Apache License, Version 2.0 (the "License");
6** you may not use this file except in compliance with the License.
7** You may obtain a copy of the License at
8**
9** http://www.apache.org/licenses/LICENSE-2.0
10**
11** Unless required by applicable law or agreed to in writing, software
12** distributed under the License is distributed on an "AS IS" BASIS,
13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14** See the License for the specific language governing permissions and
15** limitations under the License.
16*/
17
18#ifndef SkAntiRun_DEFINED
19#define SkAntiRun_DEFINED
20
21#include "SkBlitter.h"
22
23inline int sk_make_nonzero_neg_one(int x)
24{
25 return (x | -x) >> 31;
26}
27
28#if 0
29template <int kShift> class SkAntiRun {
30 static uint8_t coverage_to_alpha(int aa)
31 {
32 aa <<= 8 - 2*kShift;
33 aa -= aa >> (8 - kShift - 1);
34 return SkToU8(aa);
35 }
36public:
37 void set(int start, int stop)
38 {
39 SkASSERT(start >= 0 && stop > start);
40
41#if 1
42 int fb = start & kMask;
43 int fe = stop & kMask;
44 int n = (stop >> kShift) - (start >> kShift) - 1;
45
46 if (n < 0)
47 {
48 fb = fe - fb;
49 n = 0;
50 fe = 0;
51 }
52 else
53 {
54 if (fb == 0)
55 n += 1;
56 else
57 fb = (1 << kShift) - fb;
58 }
59
60 fStartAlpha = coverage_to_alpha(fb);
61 fMiddleCount = n;
62 fStopAlpha = coverage_to_alpha(fe);
63#else
64 int x0 = start >> kShift;
65 int x1 = (stop - 1) >> kShift;
66 int middle = x1 - x0;
67 int aa;
68
69 if (middle == 0)
70 {
71 aa = stop - start;
72 aa <<= 8 - 2*kShift;
73 aa -= aa >> (8 - kShift - 1);
74 SkASSERT(aa > 0 && aa < kMax);
75 fStartAlpha = SkToU8(aa);
76 fMiddleCount = 0;
77 fStopAlpha = 0;
78 }
79 else
80 {
81 int aa = start & kMask;
82 aa <<= 8 - 2*kShift;
83 aa -= aa >> (8 - kShift - 1);
84 SkASSERT(aa >= 0 && aa < kMax);
85 if (aa)
86 fStartAlpha = SkToU8(kMax - aa);
87 else
88 {
89 fStartAlpha = 0;
90 middle += 1;
91 }
92 aa = stop & kMask;
93 aa <<= 8 - 2*kShift;
94 aa -= aa >> (8 - kShift - 1);
95 SkASSERT(aa >= 0 && aa < kMax);
96 middle += sk_make_nonzero_neg_one(aa);
97
98 fStopAlpha = SkToU8(aa);
99 fMiddleCount = middle;
100 }
101 SkASSERT(fStartAlpha < kMax);
102 SkASSERT(fStopAlpha < kMax);
103#endif
104 }
105
106 void blit(int x, int y, SkBlitter* blitter)
107 {
108 int16_t runs[2];
109 runs[0] = 1;
110 runs[1] = 0;
111
112 if (fStartAlpha)
113 {
114 blitter->blitAntiH(x, y, &fStartAlpha, runs);
115 x += 1;
116 }
117 if (fMiddleCount)
118 {
119 blitter->blitH(x, y, fMiddleCount);
120 x += fMiddleCount;
121 }
122 if (fStopAlpha)
123 blitter->blitAntiH(x, y, &fStopAlpha, runs);
124 }
125
126 uint8_t getStartAlpha() const { return fStartAlpha; }
127 int getMiddleCount() const { return fMiddleCount; }
128 uint8_t getStopAlpha() const { return fStopAlpha; }
129
130private:
131 uint8_t fStartAlpha, fStopAlpha;
132 int fMiddleCount;
133
134 enum {
135 kMask = (1 << kShift) - 1,
136 kMax = (1 << (8 - kShift)) - 1
137 };
138};
139#endif
140
141////////////////////////////////////////////////////////////////////////////////////
142
143class SkAlphaRuns {
144public:
145 int16_t* fRuns;
146 uint8_t* fAlpha;
147
148 bool empty() const
149 {
150 SkASSERT(fRuns[0] > 0);
151 return fAlpha[0] == 0 && fRuns[fRuns[0]] == 0;
152 }
153 void reset(int width);
154 void add(int x, U8CPU startAlpha, int middleCount, U8CPU stopAlpha, U8CPU maxValue);
155 SkDEBUGCODE(void assertValid(int y, int maxStep) const;)
156 SkDEBUGCODE(void dump() const;)
157
158 static void Break(int16_t runs[], uint8_t alpha[], int x, int count);
159 static void BreakAt(int16_t runs[], uint8_t alpha[], int x)
160 {
161 while (x > 0)
162 {
163 int n = runs[0];
164 SkASSERT(n > 0);
165
166 if (x < n)
167 {
168 alpha[x] = alpha[0];
169 runs[0] = SkToS16(x);
170 runs[x] = SkToS16(n - x);
171 break;
172 }
173 runs += n;
174 alpha += n;
175 x -= n;
176 }
177 }
178
179private:
180 SkDEBUGCODE(int fWidth;)
181 SkDEBUGCODE(void validate() const;)
182};
183
184#endif
185