OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2016 Google Inc. | 2 * Copyright 2016 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkBlitter.h" | 8 #include "SkBlitter.h" |
9 #include "SkColor.h" | 9 #include "SkColor.h" |
10 #include "SkColorFilter.h" | 10 #include "SkColorFilter.h" |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
51 typedef SkBlitter INHERITED; | 51 typedef SkBlitter INHERITED; |
52 }; | 52 }; |
53 | 53 |
54 SkBlitter* SkCreateRasterPipelineBlitter(const SkPixmap& dst, | 54 SkBlitter* SkCreateRasterPipelineBlitter(const SkPixmap& dst, |
55 const SkPaint& paint, | 55 const SkPaint& paint, |
56 SkTBlitterAllocator* alloc) { | 56 SkTBlitterAllocator* alloc) { |
57 return SkRasterPipelineBlitter::Create(dst, paint, alloc); | 57 return SkRasterPipelineBlitter::Create(dst, paint, alloc); |
58 } | 58 } |
59 | 59 |
60 // Clamp colors into [0,1] premul (e.g. just before storing back to memory). | 60 // Clamp colors into [0,1] premul (e.g. just before storing back to memory). |
61 static void SK_VECTORCALL clamp_01_premul(SkRasterPipeline::Stage* st, size_t x, | 61 SK_RASTER_STAGE(clamp_01_premul) { |
62 Sk4f r, Sk4f g, Sk4f b, Sk4f a, | |
63 Sk4f dr, Sk4f dg, Sk4f db, Sk4f da) { | |
64 a = Sk4f::Max(a, 0.0f); | 62 a = Sk4f::Max(a, 0.0f); |
65 r = Sk4f::Max(r, 0.0f); | 63 r = Sk4f::Max(r, 0.0f); |
66 g = Sk4f::Max(g, 0.0f); | 64 g = Sk4f::Max(g, 0.0f); |
67 b = Sk4f::Max(b, 0.0f); | 65 b = Sk4f::Max(b, 0.0f); |
68 | 66 |
69 a = Sk4f::Min(a, 1.0f); | 67 a = Sk4f::Min(a, 1.0f); |
70 r = Sk4f::Min(r, a); | 68 r = Sk4f::Min(r, a); |
71 g = Sk4f::Min(g, a); | 69 g = Sk4f::Min(g, a); |
72 b = Sk4f::Min(b, a); | 70 b = Sk4f::Min(b, a); |
73 | |
74 st->next(x, r,g,b,a, dr,dg,db,da); | |
75 } | 71 } |
76 | 72 |
77 // The default shader produces a constant color (from the SkPaint). | 73 // The default shader produces a constant color (from the SkPaint). |
78 static void SK_VECTORCALL constant_color(SkRasterPipeline::Stage* st, size_t x, | 74 SK_RASTER_STAGE(constant_color) { |
79 Sk4f r, Sk4f g, Sk4f b, Sk4f a, | 75 auto color = (const SkPM4f*)ctx; |
80 Sk4f dr, Sk4f dg, Sk4f db, Sk4f da) { | |
81 auto color = st->ctx<const SkPM4f*>(); | |
82 r = color->r(); | 76 r = color->r(); |
83 g = color->g(); | 77 g = color->g(); |
84 b = color->b(); | 78 b = color->b(); |
85 a = color->a(); | 79 a = color->a(); |
86 st->next(x, r,g,b,a, dr,dg,db,da); | |
87 } | 80 } |
88 | 81 |
89 // The default transfer mode is srcover, s' = s + d*(1-sa). | 82 // The default transfer mode is srcover, s' = s + d*(1-sa). |
90 static void SK_VECTORCALL srcover(SkRasterPipeline::Stage* st, size_t x, | 83 SK_RASTER_STAGE(srcover) { |
91 Sk4f r, Sk4f g, Sk4f b, Sk4f a, | 84 r += dr*(1.0f - a); |
92 Sk4f dr, Sk4f dg, Sk4f db, Sk4f da) { | 85 g += dg*(1.0f - a); |
93 auto A = 1.0f - a; | 86 b += db*(1.0f - a); |
94 r += dr*A; | 87 a += da*(1.0f - a); |
95 g += dg*A; | |
96 b += db*A; | |
97 a += da*A; | |
98 st->next(x, r,g,b,a, dr,dg,db,da); | |
99 } | 88 } |
100 | 89 |
101 static Sk4f lerp(const Sk4f& from, const Sk4f& to, const Sk4f& cov) { | 90 static Sk4f lerp(const Sk4f& from, const Sk4f& to, const Sk4f& cov) { |
102 return from + (to-from)*cov; | 91 return from + (to-from)*cov; |
103 } | 92 } |
104 | 93 |
105 // s' = d(1-c) + sc, for a constant c. | 94 // s' = d(1-c) + sc, for a constant c. |
106 static void SK_VECTORCALL lerp_constant_float(SkRasterPipeline::Stage* st, size_
t x, | 95 SK_RASTER_STAGE(lerp_constant_float) { |
107 Sk4f r, Sk4f g, Sk4f b, Sk4f a
, | 96 Sk4f c = *(const float*)ctx; |
108 Sk4f dr, Sk4f dg, Sk4f db, Sk4f da
) { | |
109 Sk4f c = *st->ctx<const float*>(); | |
110 | 97 |
111 r = lerp(dr, r, c); | 98 r = lerp(dr, r, c); |
112 g = lerp(dg, g, c); | 99 g = lerp(dg, g, c); |
113 b = lerp(db, b, c); | 100 b = lerp(db, b, c); |
114 a = lerp(da, a, c); | 101 a = lerp(da, a, c); |
115 st->next(x, r,g,b,a, dr,dg,db,da); | |
116 } | 102 } |
117 | 103 |
118 // s' = d(1-c) + sc, 4 pixels at a time for 8-bit coverage. | 104 // s' = d(1-c) + sc, 4 pixels at a time for 8-bit coverage. |
119 static void SK_VECTORCALL lerp_a8(SkRasterPipeline::Stage* st, size_t x, | 105 SK_RASTER_STAGE(lerp_a8) { |
120 Sk4f r, Sk4f g, Sk4f b, Sk4f a, | 106 auto ptr = (const uint8_t*)ctx + x; |
121 Sk4f dr, Sk4f dg, Sk4f db, Sk4f da) { | |
122 auto ptr = st->ctx<const uint8_t*>() + x; | |
123 Sk4f c = SkNx_cast<float>(Sk4b::Load(ptr)) * (1/255.0f); | 107 Sk4f c = SkNx_cast<float>(Sk4b::Load(ptr)) * (1/255.0f); |
124 | 108 |
125 r = lerp(dr, r, c); | 109 r = lerp(dr, r, c); |
126 g = lerp(dg, g, c); | 110 g = lerp(dg, g, c); |
127 b = lerp(db, b, c); | 111 b = lerp(db, b, c); |
128 a = lerp(da, a, c); | 112 a = lerp(da, a, c); |
129 st->next(x, r,g,b,a, dr,dg,db,da); | |
130 } | 113 } |
131 | 114 |
132 // Tail variant of lerp_a8() handling 1 pixel at a time. | 115 // Tail variant of lerp_a8() handling 1 pixel at a time. |
133 static void SK_VECTORCALL lerp_a8_1(SkRasterPipeline::Stage* st, size_t x, | 116 SK_RASTER_STAGE(lerp_a8_1) { |
134 Sk4f r, Sk4f g, Sk4f b, Sk4f a, | 117 auto ptr = (const uint8_t*)ctx + x; |
135 Sk4f dr, Sk4f dg, Sk4f db, Sk4f da) { | |
136 auto ptr = st->ctx<const uint8_t*>() + x; | |
137 Sk4f c = *ptr * (1/255.0f); | 118 Sk4f c = *ptr * (1/255.0f); |
138 | 119 |
139 r = lerp(dr, r, c); | 120 r = lerp(dr, r, c); |
140 g = lerp(dg, g, c); | 121 g = lerp(dg, g, c); |
141 b = lerp(db, b, c); | 122 b = lerp(db, b, c); |
142 a = lerp(da, a, c); | 123 a = lerp(da, a, c); |
143 st->next(x, r,g,b,a, dr,dg,db,da); | |
144 } | 124 } |
145 | 125 |
146 static void from_565(const Sk4h& _565, Sk4f* r, Sk4f* g, Sk4f* b) { | 126 static void from_565(const Sk4h& _565, Sk4f* r, Sk4f* g, Sk4f* b) { |
147 Sk4i _32_bit = SkNx_cast<int>(_565); | 127 Sk4i _32_bit = SkNx_cast<int>(_565); |
148 | 128 |
149 *r = SkNx_cast<float>(_32_bit & SK_R16_MASK_IN_PLACE) * (1.0f / SK_R16_MASK_
IN_PLACE); | 129 *r = SkNx_cast<float>(_32_bit & SK_R16_MASK_IN_PLACE) * (1.0f / SK_R16_MASK_
IN_PLACE); |
150 *g = SkNx_cast<float>(_32_bit & SK_G16_MASK_IN_PLACE) * (1.0f / SK_G16_MASK_
IN_PLACE); | 130 *g = SkNx_cast<float>(_32_bit & SK_G16_MASK_IN_PLACE) * (1.0f / SK_G16_MASK_
IN_PLACE); |
151 *b = SkNx_cast<float>(_32_bit & SK_B16_MASK_IN_PLACE) * (1.0f / SK_B16_MASK_
IN_PLACE); | 131 *b = SkNx_cast<float>(_32_bit & SK_B16_MASK_IN_PLACE) * (1.0f / SK_B16_MASK_
IN_PLACE); |
152 } | 132 } |
153 | 133 |
154 static Sk4h to_565(const Sk4f& r, const Sk4f& g, const Sk4f& b) { | 134 static Sk4h to_565(const Sk4f& r, const Sk4f& g, const Sk4f& b) { |
155 return SkNx_cast<uint16_t>( Sk4f_round(r * SK_R16_MASK) << SK_R16_SHIFT | 135 return SkNx_cast<uint16_t>( Sk4f_round(r * SK_R16_MASK) << SK_R16_SHIFT |
156 | Sk4f_round(g * SK_G16_MASK) << SK_G16_SHIFT | 136 | Sk4f_round(g * SK_G16_MASK) << SK_G16_SHIFT |
157 | Sk4f_round(b * SK_B16_MASK) << SK_B16_SHIFT); | 137 | Sk4f_round(b * SK_B16_MASK) << SK_B16_SHIFT); |
158 } | 138 } |
159 | 139 |
160 // s' = d(1-c) + sc, 4 pixels at a time for 565 coverage. | 140 // s' = d(1-c) + sc, 4 pixels at a time for 565 coverage. |
161 static void SK_VECTORCALL lerp_lcd16(SkRasterPipeline::Stage* st, size_t x, | 141 SK_RASTER_STAGE(lerp_lcd16) { |
162 Sk4f r, Sk4f g, Sk4f b, Sk4f a, | 142 auto ptr = (const uint16_t*)ctx + x; |
163 Sk4f dr, Sk4f dg, Sk4f db, Sk4f da) { | |
164 auto ptr = st->ctx<const uint16_t*>() + x; | |
165 Sk4f cr, cg, cb; | 143 Sk4f cr, cg, cb; |
166 from_565(Sk4h::Load(ptr), &cr, &cg, &cb); | 144 from_565(Sk4h::Load(ptr), &cr, &cg, &cb); |
167 | 145 |
168 r = lerp(dr, r, cr); | 146 r = lerp(dr, r, cr); |
169 g = lerp(dg, g, cg); | 147 g = lerp(dg, g, cg); |
170 b = lerp(db, b, cb); | 148 b = lerp(db, b, cb); |
171 a = 1.0f; | 149 a = 1.0f; |
172 st->next(x, r,g,b,a, dr,dg,db,da); | |
173 } | 150 } |
174 | 151 |
175 // Tail variant of lerp_lcd16() handling 1 pixel at a time. | 152 // Tail variant of lerp_lcd16() handling 1 pixel at a time. |
176 static void SK_VECTORCALL lerp_lcd16_1(SkRasterPipeline::Stage* st, size_t x, | 153 SK_RASTER_STAGE(lerp_lcd16_1) { |
177 Sk4f r, Sk4f g, Sk4f b, Sk4f a, | 154 auto ptr = (const uint16_t*)ctx + x; |
178 Sk4f dr, Sk4f dg, Sk4f db, Sk4f da) { | |
179 auto ptr = st->ctx<const uint16_t*>() + x; | |
180 Sk4f cr, cg, cb; | 155 Sk4f cr, cg, cb; |
181 from_565({*ptr,0,0,0}, &cr, &cg, &cb); | 156 from_565({*ptr,0,0,0}, &cr, &cg, &cb); |
182 | 157 |
183 r = lerp(dr, r, cr); | 158 r = lerp(dr, r, cr); |
184 g = lerp(dg, g, cg); | 159 g = lerp(dg, g, cg); |
185 b = lerp(db, b, cb); | 160 b = lerp(db, b, cb); |
186 a = 1.0f; | 161 a = 1.0f; |
187 st->next(x, r,g,b,a, dr,dg,db,da); | |
188 } | 162 } |
189 | 163 |
190 // Load 4 565 dst pixels. | 164 // Load 4 565 dst pixels. |
191 static void SK_VECTORCALL load_d_565(SkRasterPipeline::Stage* st, size_t x, | 165 SK_RASTER_STAGE(load_d_565) { |
192 Sk4f r, Sk4f g, Sk4f b, Sk4f a, | 166 auto ptr = (const uint16_t*)ctx + x; |
193 Sk4f dr, Sk4f dg, Sk4f db, Sk4f da) { | |
194 auto ptr = st->ctx<const uint16_t*>() + x; | |
195 | 167 |
196 from_565(Sk4h::Load(ptr), &dr,&dg,&db); | 168 from_565(Sk4h::Load(ptr), &dr,&dg,&db); |
197 da = 1.0f; | 169 da = 1.0f; |
198 st->next(x, r,g,b,a, dr,dg,db,da); | |
199 } | 170 } |
200 | 171 |
201 // Load 1 565 dst pixel. | 172 // Load 1 565 dst pixel. |
202 static void SK_VECTORCALL load_d_565_1(SkRasterPipeline::Stage* st, size_t x, | 173 SK_RASTER_STAGE(load_d_565_1) { |
203 Sk4f r, Sk4f g, Sk4f b, Sk4f a, | 174 auto ptr = (const uint16_t*)ctx + x; |
204 Sk4f dr, Sk4f dg, Sk4f db, Sk4f da) { | |
205 auto ptr = st->ctx<const uint16_t*>() + x; | |
206 | 175 |
207 from_565({*ptr,0,0,0}, &dr,&dg,&db); | 176 from_565({*ptr,0,0,0}, &dr,&dg,&db); |
208 da = 1.0f; | 177 da = 1.0f; |
209 st->next(x, r,g,b,a, dr,dg,db,da); | |
210 } | 178 } |
211 | 179 |
212 // Store 4 565 pixels. | 180 // Store 4 565 pixels. |
213 static void SK_VECTORCALL store_565(SkRasterPipeline::Stage* st, size_t x, | 181 SK_RASTER_STAGE(store_565) { |
214 Sk4f r, Sk4f g, Sk4f b, Sk4f a, | 182 auto ptr = (uint16_t*)ctx + x; |
215 Sk4f dr, Sk4f dg, Sk4f db, Sk4f da) { | |
216 auto ptr = st->ctx<uint16_t*>() + x; | |
217 to_565(r,g,b).store(ptr); | 183 to_565(r,g,b).store(ptr); |
218 } | 184 } |
219 | 185 |
220 // Store 1 565 pixel. | 186 // Store 1 565 pixel. |
221 static void SK_VECTORCALL store_565_1(SkRasterPipeline::Stage* st, size_t x, | 187 SK_RASTER_STAGE(store_565_1) { |
222 Sk4f r, Sk4f g, Sk4f b, Sk4f a, | 188 auto ptr = (uint16_t*)ctx + x; |
223 Sk4f dr, Sk4f dg, Sk4f db, Sk4f da) { | |
224 auto ptr = st->ctx<uint16_t*>() + x; | |
225 *ptr = to_565(r,g,b)[0]; | 189 *ptr = to_565(r,g,b)[0]; |
226 } | 190 } |
227 | 191 |
228 // Load 4 F16 pixels. | 192 // Load 4 F16 pixels. |
229 static void SK_VECTORCALL load_d_f16(SkRasterPipeline::Stage* st, size_t x, | 193 SK_RASTER_STAGE(load_d_f16) { |
230 Sk4f r, Sk4f g, Sk4f b, Sk4f a, | 194 auto ptr = (const uint64_t*)ctx + x; |
231 Sk4f dr, Sk4f dg, Sk4f db, Sk4f da) { | |
232 auto ptr = st->ctx<const uint64_t*>() + x; | |
233 | 195 |
234 Sk4h rh, gh, bh, ah; | 196 Sk4h rh, gh, bh, ah; |
235 Sk4h_load4(ptr, &rh, &gh, &bh, &ah); | 197 Sk4h_load4(ptr, &rh, &gh, &bh, &ah); |
236 | 198 |
237 dr = SkHalfToFloat_finite(rh); | 199 dr = SkHalfToFloat_finite(rh); |
238 dg = SkHalfToFloat_finite(gh); | 200 dg = SkHalfToFloat_finite(gh); |
239 db = SkHalfToFloat_finite(bh); | 201 db = SkHalfToFloat_finite(bh); |
240 da = SkHalfToFloat_finite(ah); | 202 da = SkHalfToFloat_finite(ah); |
241 | |
242 st->next(x, r,g,b,a, dr,dg,db,da); | |
243 } | 203 } |
244 | 204 |
245 // Load 1 F16 pixel. | 205 // Load 1 F16 pixel. |
246 static void SK_VECTORCALL load_d_f16_1(SkRasterPipeline::Stage* st, size_t x, | 206 SK_RASTER_STAGE(load_d_f16_1) { |
247 Sk4f r, Sk4f g, Sk4f b, Sk4f a, | 207 auto ptr = (const uint64_t*)ctx + x; |
248 Sk4f dr, Sk4f dg, Sk4f db, Sk4f da) { | |
249 auto ptr = st->ctx<const uint64_t*>() + x; | |
250 | 208 |
251 auto p0 = SkHalfToFloat_finite(ptr[0]); | 209 auto p0 = SkHalfToFloat_finite(ptr[0]); |
252 dr = { p0[0],0,0,0 }; | 210 dr = { p0[0],0,0,0 }; |
253 dg = { p0[1],0,0,0 }; | 211 dg = { p0[1],0,0,0 }; |
254 db = { p0[2],0,0,0 }; | 212 db = { p0[2],0,0,0 }; |
255 da = { p0[3],0,0,0 }; | 213 da = { p0[3],0,0,0 }; |
256 | |
257 st->next(x, r,g,b,a, dr,dg,db,da); | |
258 } | 214 } |
259 | 215 |
260 // Store 4 F16 pixels. | 216 // Store 4 F16 pixels. |
261 static void SK_VECTORCALL store_f16(SkRasterPipeline::Stage* st, size_t x, | 217 SK_RASTER_STAGE(store_f16) { |
262 Sk4f r, Sk4f g, Sk4f b, Sk4f a, | 218 auto ptr = (uint64_t*)ctx + x; |
263 Sk4f dr, Sk4f dg, Sk4f db, Sk4f da) { | |
264 auto ptr = st->ctx<uint64_t*>() + x; | |
265 | 219 |
266 Sk4h_store4(ptr, SkFloatToHalf_finite(r), SkFloatToHalf_finite(g), | 220 Sk4h_store4(ptr, SkFloatToHalf_finite(r), SkFloatToHalf_finite(g), |
267 SkFloatToHalf_finite(b), SkFloatToHalf_finite(a)); | 221 SkFloatToHalf_finite(b), SkFloatToHalf_finite(a)); |
268 } | 222 } |
269 | 223 |
270 // Store 1 F16 pixel. | 224 // Store 1 F16 pixel. |
271 static void SK_VECTORCALL store_f16_1(SkRasterPipeline::Stage* st, size_t x, | 225 SK_RASTER_STAGE(store_f16_1) { |
272 Sk4f r, Sk4f g, Sk4f b, Sk4f a, | 226 auto ptr = (uint64_t*)ctx + x; |
273 Sk4f dr, Sk4f dg, Sk4f db, Sk4f da) { | |
274 auto ptr = st->ctx<uint64_t*>() + x; | |
275 | 227 |
276 SkFloatToHalf_finite({r[0], g[0], b[0], a[0]}).store(ptr); | 228 SkFloatToHalf_finite({r[0], g[0], b[0], a[0]}).store(ptr); |
277 } | 229 } |
278 | 230 |
279 // Load 4 8-bit sRGB pixels from SkPMColor order to RGBA. | 231 // Load 4 8-bit sRGB pixels from SkPMColor order to RGBA. |
280 static void SK_VECTORCALL load_d_srgb(SkRasterPipeline::Stage* st, size_t x, | 232 SK_RASTER_STAGE(load_d_srgb) { |
281 Sk4f r, Sk4f g, Sk4f b, Sk4f a, | 233 auto ptr = (const uint32_t*)ctx + x; |
282 Sk4f dr, Sk4f dg, Sk4f db, Sk4f da) { | |
283 auto ptr = st->ctx<const uint32_t*>() + x; | |
284 | 234 |
285 dr = { sk_linear_from_srgb[(ptr[0] >> SK_R32_SHIFT) & 0xff], | 235 dr = { sk_linear_from_srgb[(ptr[0] >> SK_R32_SHIFT) & 0xff], |
286 sk_linear_from_srgb[(ptr[1] >> SK_R32_SHIFT) & 0xff], | 236 sk_linear_from_srgb[(ptr[1] >> SK_R32_SHIFT) & 0xff], |
287 sk_linear_from_srgb[(ptr[2] >> SK_R32_SHIFT) & 0xff], | 237 sk_linear_from_srgb[(ptr[2] >> SK_R32_SHIFT) & 0xff], |
288 sk_linear_from_srgb[(ptr[3] >> SK_R32_SHIFT) & 0xff] }; | 238 sk_linear_from_srgb[(ptr[3] >> SK_R32_SHIFT) & 0xff] }; |
289 | 239 |
290 dg = { sk_linear_from_srgb[(ptr[0] >> SK_G32_SHIFT) & 0xff], | 240 dg = { sk_linear_from_srgb[(ptr[0] >> SK_G32_SHIFT) & 0xff], |
291 sk_linear_from_srgb[(ptr[1] >> SK_G32_SHIFT) & 0xff], | 241 sk_linear_from_srgb[(ptr[1] >> SK_G32_SHIFT) & 0xff], |
292 sk_linear_from_srgb[(ptr[2] >> SK_G32_SHIFT) & 0xff], | 242 sk_linear_from_srgb[(ptr[2] >> SK_G32_SHIFT) & 0xff], |
293 sk_linear_from_srgb[(ptr[3] >> SK_G32_SHIFT) & 0xff] }; | 243 sk_linear_from_srgb[(ptr[3] >> SK_G32_SHIFT) & 0xff] }; |
294 | 244 |
295 db = { sk_linear_from_srgb[(ptr[0] >> SK_B32_SHIFT) & 0xff], | 245 db = { sk_linear_from_srgb[(ptr[0] >> SK_B32_SHIFT) & 0xff], |
296 sk_linear_from_srgb[(ptr[1] >> SK_B32_SHIFT) & 0xff], | 246 sk_linear_from_srgb[(ptr[1] >> SK_B32_SHIFT) & 0xff], |
297 sk_linear_from_srgb[(ptr[2] >> SK_B32_SHIFT) & 0xff], | 247 sk_linear_from_srgb[(ptr[2] >> SK_B32_SHIFT) & 0xff], |
298 sk_linear_from_srgb[(ptr[3] >> SK_B32_SHIFT) & 0xff] }; | 248 sk_linear_from_srgb[(ptr[3] >> SK_B32_SHIFT) & 0xff] }; |
299 | 249 |
300 da = SkNx_cast<float>(Sk4u::Load(ptr) >> SK_A32_SHIFT) * (1/255.0f); | 250 da = SkNx_cast<float>(Sk4u::Load(ptr) >> SK_A32_SHIFT) * (1/255.0f); |
301 | |
302 st->next(x, r,g,b,a, dr,dg,db,da); | |
303 } | 251 } |
304 | 252 |
305 // Tail variant of load_d_srgb() handling 1 pixel at a time. | 253 // Tail variant of load_d_srgb() handling 1 pixel at a time. |
306 static void SK_VECTORCALL load_d_srgb_1(SkRasterPipeline::Stage* st, size_t x, | 254 SK_RASTER_STAGE(load_d_srgb_1) { |
307 Sk4f r, Sk4f g, Sk4f b, Sk4f a, | 255 auto ptr = (const uint32_t*)ctx + x; |
308 Sk4f dr, Sk4f dg, Sk4f db, Sk4f da) { | |
309 auto ptr = st->ctx<const uint32_t*>() + x; | |
310 | 256 |
311 dr = { sk_linear_from_srgb[(*ptr >> SK_R32_SHIFT) & 0xff], 0,0,0 }; | 257 dr = { sk_linear_from_srgb[(*ptr >> SK_R32_SHIFT) & 0xff], 0,0,0 }; |
312 dg = { sk_linear_from_srgb[(*ptr >> SK_G32_SHIFT) & 0xff], 0,0,0 }; | 258 dg = { sk_linear_from_srgb[(*ptr >> SK_G32_SHIFT) & 0xff], 0,0,0 }; |
313 db = { sk_linear_from_srgb[(*ptr >> SK_B32_SHIFT) & 0xff], 0,0,0 }; | 259 db = { sk_linear_from_srgb[(*ptr >> SK_B32_SHIFT) & 0xff], 0,0,0 }; |
314 da = { (1/255.0f) * (*ptr >> SK_A32_SHIFT) , 0,0,0 }; | 260 da = { (1/255.0f) * (*ptr >> SK_A32_SHIFT) , 0,0,0 }; |
315 | |
316 st->next(x, r,g,b,a, dr,dg,db,da); | |
317 } | 261 } |
318 | 262 |
319 // Write out 4 pixels as 8-bit SkPMColor-order sRGB. | 263 // Write out 4 pixels as 8-bit SkPMColor-order sRGB. |
320 static void SK_VECTORCALL store_srgb(SkRasterPipeline::Stage* st, size_t x, | 264 SK_RASTER_STAGE(store_srgb) { |
321 Sk4f r, Sk4f g, Sk4f b, Sk4f a, | 265 auto ptr = (uint32_t*)ctx + x; |
322 Sk4f dr, Sk4f dg, Sk4f db, Sk4f da) { | |
323 auto dst = st->ctx<uint32_t*>() + x; | |
324 ( sk_linear_to_srgb_noclamp(r) << SK_R32_SHIFT | 266 ( sk_linear_to_srgb_noclamp(r) << SK_R32_SHIFT |
325 | sk_linear_to_srgb_noclamp(g) << SK_G32_SHIFT | 267 | sk_linear_to_srgb_noclamp(g) << SK_G32_SHIFT |
326 | sk_linear_to_srgb_noclamp(b) << SK_B32_SHIFT | 268 | sk_linear_to_srgb_noclamp(b) << SK_B32_SHIFT |
327 | Sk4f_round(255.0f * a) << SK_A32_SHIFT).store(dst); | 269 | Sk4f_round(255.0f * a) << SK_A32_SHIFT).store(ptr); |
328 } | 270 } |
329 | 271 |
330 // Tail variant of store_srgb() handling 1 pixel at a time. | 272 // Tail variant of store_srgb() handling 1 pixel at a time. |
331 static void SK_VECTORCALL store_srgb_1(SkRasterPipeline::Stage* st, size_t x, | 273 SK_RASTER_STAGE(store_srgb_1) { |
332 Sk4f r, Sk4f g, Sk4f b, Sk4f a, | 274 auto ptr = (uint32_t*)ctx + x; |
333 Sk4f dr, Sk4f dg, Sk4f db, Sk4f da) { | |
334 auto dst = st->ctx<uint32_t*>() + x; | |
335 Sk4i rgb = sk_linear_to_srgb_noclamp(swizzle_rb_if_bgra({ r[0], g[0], b[0],
0.0f })); | 275 Sk4i rgb = sk_linear_to_srgb_noclamp(swizzle_rb_if_bgra({ r[0], g[0], b[0],
0.0f })); |
336 | 276 |
337 uint32_t rgba; | 277 uint32_t rgba; |
338 SkNx_cast<uint8_t>(rgb).store(&rgba); | 278 SkNx_cast<uint8_t>(rgb).store(&rgba); |
339 rgba |= (uint32_t)(255.0f * a[0] + 0.5f) << 24; | 279 rgba |= (uint32_t)(255.0f * a[0] + 0.5f) << 24; |
340 *dst = rgba; | 280 *ptr = rgba; |
341 } | 281 } |
342 | 282 |
343 static bool supported(const SkImageInfo& info) { | 283 static bool supported(const SkImageInfo& info) { |
344 switch (info.colorType()) { | 284 switch (info.colorType()) { |
345 case kN32_SkColorType: return info.gammaCloseToSRGB(); | 285 case kN32_SkColorType: return info.gammaCloseToSRGB(); |
346 case kRGBA_F16_SkColorType: return true; | 286 case kRGBA_F16_SkColorType: return true; |
347 case kRGB_565_SkColorType: return true; | 287 case kRGB_565_SkColorType: return true; |
348 default: return false; | 288 default: return false; |
349 } | 289 } |
350 } | 290 } |
(...skipping 28 matching lines...) Expand all Loading... |
379 } else { | 319 } else { |
380 swizzle_rb(SkNx_cast<float>(Sk4b::Load(&paintColor)) * (1/255.0f)).store
(&color); | 320 swizzle_rb(SkNx_cast<float>(Sk4b::Load(&paintColor)) * (1/255.0f)).store
(&color); |
381 } | 321 } |
382 | 322 |
383 auto blitter = alloc->createT<SkRasterPipelineBlitter>( | 323 auto blitter = alloc->createT<SkRasterPipelineBlitter>( |
384 dst, | 324 dst, |
385 shader, colorFilter, xfermode, | 325 shader, colorFilter, xfermode, |
386 color.premul()); | 326 color.premul()); |
387 | 327 |
388 if (!paint.getShader()) { | 328 if (!paint.getShader()) { |
389 blitter->fShader.append(constant_color, &blitter->fPaintColor); | 329 blitter->fShader.append<constant_color>(&blitter->fPaintColor); |
390 } | 330 } |
391 if (!paint.getXfermode()) { | 331 if (!paint.getXfermode()) { |
392 blitter->fXfermode.append(srcover); | 332 blitter->fXfermode.append<srcover>(); |
393 } | 333 } |
394 | 334 |
395 return blitter; | 335 return blitter; |
396 } | 336 } |
397 | 337 |
398 void SkRasterPipelineBlitter::append_load_d(SkRasterPipeline* p, const void* dst
) const { | 338 void SkRasterPipelineBlitter::append_load_d(SkRasterPipeline* p, const void* dst
) const { |
399 SkASSERT(supported(fDst.info())); | 339 SkASSERT(supported(fDst.info())); |
400 | 340 |
401 switch (fDst.info().colorType()) { | 341 switch (fDst.info().colorType()) { |
402 case kN32_SkColorType: | 342 case kN32_SkColorType: |
403 if (fDst.info().gammaCloseToSRGB()) { | 343 if (fDst.info().gammaCloseToSRGB()) { |
404 p->append(load_d_srgb, load_d_srgb_1, dst); | 344 p->append<load_d_srgb, load_d_srgb_1>(dst); |
405 } | 345 } |
406 break; | 346 break; |
407 case kRGBA_F16_SkColorType: | 347 case kRGBA_F16_SkColorType: |
408 p->append(load_d_f16, load_d_f16_1, dst); | 348 p->append<load_d_f16, load_d_f16_1>(dst); |
409 break; | 349 break; |
410 case kRGB_565_SkColorType: | 350 case kRGB_565_SkColorType: |
411 p->append(load_d_565, load_d_565_1, dst); | 351 p->append<load_d_565, load_d_565_1>(dst); |
412 break; | 352 break; |
413 default: break; | 353 default: break; |
414 } | 354 } |
415 } | 355 } |
416 | 356 |
417 void SkRasterPipelineBlitter::append_store(SkRasterPipeline* p, void* dst) const
{ | 357 void SkRasterPipelineBlitter::append_store(SkRasterPipeline* p, void* dst) const
{ |
418 SkASSERT(supported(fDst.info())); | 358 SkASSERT(supported(fDst.info())); |
419 | 359 |
420 p->append(clamp_01_premul); | 360 p->append<clamp_01_premul>(); |
421 switch (fDst.info().colorType()) { | 361 switch (fDst.info().colorType()) { |
422 case kN32_SkColorType: | 362 case kN32_SkColorType: |
423 if (fDst.info().gammaCloseToSRGB()) { | 363 if (fDst.info().gammaCloseToSRGB()) { |
424 p->append(store_srgb, store_srgb_1, dst); | 364 p->append<store_srgb, store_srgb_1>(dst); |
425 } | 365 } |
426 break; | 366 break; |
427 case kRGBA_F16_SkColorType: | 367 case kRGBA_F16_SkColorType: |
428 p->append(store_f16, store_f16_1, dst); | 368 p->append<store_f16, store_f16_1>(dst); |
429 break; | 369 break; |
430 case kRGB_565_SkColorType: | 370 case kRGB_565_SkColorType: |
431 p->append(store_565, store_565_1, dst); | 371 p->append<store_565, store_565_1>(dst); |
432 break; | 372 break; |
433 default: break; | 373 default: break; |
434 } | 374 } |
435 } | 375 } |
436 | 376 |
437 void SkRasterPipelineBlitter::blitH(int x, int y, int w) { | 377 void SkRasterPipelineBlitter::blitH(int x, int y, int w) { |
438 auto dst = fDst.writable_addr(0,y); | 378 auto dst = fDst.writable_addr(0,y); |
439 | 379 |
440 SkRasterPipeline p; | 380 SkRasterPipeline p; |
441 p.extend(fShader); | 381 p.extend(fShader); |
442 p.extend(fColorFilter); | 382 p.extend(fColorFilter); |
443 this->append_load_d(&p, dst); | 383 this->append_load_d(&p, dst); |
444 p.extend(fXfermode); | 384 p.extend(fXfermode); |
445 this->append_store(&p, dst); | 385 this->append_store(&p, dst); |
446 | 386 |
447 p.run(x, w); | 387 p.run(x, w); |
448 } | 388 } |
449 | 389 |
450 void SkRasterPipelineBlitter::blitAntiH(int x, int y, const SkAlpha aa[], const
int16_t runs[]) { | 390 void SkRasterPipelineBlitter::blitAntiH(int x, int y, const SkAlpha aa[], const
int16_t runs[]) { |
451 auto dst = fDst.writable_addr(0,y); | 391 auto dst = fDst.writable_addr(0,y); |
452 float coverage; | 392 float coverage; |
453 | 393 |
454 SkRasterPipeline p; | 394 SkRasterPipeline p; |
455 p.extend(fShader); | 395 p.extend(fShader); |
456 p.extend(fColorFilter); | 396 p.extend(fColorFilter); |
457 this->append_load_d(&p, dst); | 397 this->append_load_d(&p, dst); |
458 p.extend(fXfermode); | 398 p.extend(fXfermode); |
459 p.append(lerp_constant_float, &coverage); | 399 p.append<lerp_constant_float>(&coverage); |
460 this->append_store(&p, dst); | 400 this->append_store(&p, dst); |
461 | 401 |
462 for (int16_t run = *runs; run > 0; run = *runs) { | 402 for (int16_t run = *runs; run > 0; run = *runs) { |
463 coverage = *aa * (1/255.0f); | 403 coverage = *aa * (1/255.0f); |
464 p.run(x, run); | 404 p.run(x, run); |
465 | 405 |
466 x += run; | 406 x += run; |
467 runs += run; | 407 runs += run; |
468 aa += run; | 408 aa += run; |
469 } | 409 } |
470 } | 410 } |
471 | 411 |
472 void SkRasterPipelineBlitter::blitMask(const SkMask& mask, const SkIRect& clip)
{ | 412 void SkRasterPipelineBlitter::blitMask(const SkMask& mask, const SkIRect& clip)
{ |
473 if (mask.fFormat == SkMask::kBW_Format) { | 413 if (mask.fFormat == SkMask::kBW_Format) { |
474 // TODO: native BW masks? | 414 // TODO: native BW masks? |
475 return INHERITED::blitMask(mask, clip); | 415 return INHERITED::blitMask(mask, clip); |
476 } | 416 } |
477 | 417 |
478 int x = clip.left(); | 418 int x = clip.left(); |
479 for (int y = clip.top(); y < clip.bottom(); y++) { | 419 for (int y = clip.top(); y < clip.bottom(); y++) { |
480 auto dst = fDst.writable_addr(0,y); | 420 auto dst = fDst.writable_addr(0,y); |
481 | 421 |
482 SkRasterPipeline p; | 422 SkRasterPipeline p; |
483 p.extend(fShader); | 423 p.extend(fShader); |
484 p.extend(fColorFilter); | 424 p.extend(fColorFilter); |
485 this->append_load_d(&p, dst); | 425 this->append_load_d(&p, dst); |
486 p.extend(fXfermode); | 426 p.extend(fXfermode); |
487 switch (mask.fFormat) { | 427 switch (mask.fFormat) { |
488 case SkMask::kA8_Format: | 428 case SkMask::kA8_Format: |
489 p.append(lerp_a8, lerp_a8_1, mask.getAddr8(x,y)-x); | 429 p.append<lerp_a8, lerp_a8_1>(mask.getAddr8(x,y)-x); |
490 break; | 430 break; |
491 case SkMask::kLCD16_Format: | 431 case SkMask::kLCD16_Format: |
492 p.append(lerp_lcd16, lerp_lcd16_1, mask.getAddrLCD16(x,y)-x); | 432 p.append<lerp_lcd16, lerp_lcd16_1>(mask.getAddrLCD16(x,y)-x); |
493 break; | 433 break; |
494 default: break; | 434 default: break; |
495 } | 435 } |
496 this->append_store(&p, dst); | 436 this->append_store(&p, dst); |
497 | 437 |
498 p.run(x, clip.width()); | 438 p.run(x, clip.width()); |
499 } | 439 } |
500 } | 440 } |
OLD | NEW |