Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(670)

Side by Side Diff: src/core/SkRasterPipelineBlitter.cpp

Issue 2195853002: SkRasterPipeline: new APIs for fusion (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: bench both ways Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/core/SkRasterPipeline.h ('k') | tests/SkRasterPipelineTest.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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 }
OLDNEW
« no previous file with comments | « src/core/SkRasterPipeline.h ('k') | tests/SkRasterPipelineTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698