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

Side by Side Diff: src/core/SkLinearBitmapPipeline_sample.h

Issue 1775963002: Bilerp + mirror + perspective (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Address comments. Created 4 years, 9 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/SkLinearBitmapPipeline_matrix.h ('k') | src/core/SkLinearBitmapPipeline_tile.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * Copyright 2016 Google Inc.
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 SkLinearBitmapPipeline_sampler_DEFINED
9 #define SkLinearBitmapPipeline_sampler_DEFINED
10
11 #include "SkLinearBitmapPipeline_core.h"
12 #include <tuple>
13
14 namespace {
15 // Explaination of the math:
16 // 1 - x x
17 // +--------+--------+
18 // | | |
19 // 1 - y | px00 | px10 |
20 // | | |
21 // +--------+--------+
22 // | | |
23 // y | px01 | px11 |
24 // | | |
25 // +--------+--------+
26 //
27 //
28 // Given a pixelxy each is multiplied by a different factor derived from the fra ctional part of x
29 // and y:
30 // * px00 -> (1 - x)(1 - y) = 1 - x - y + xy
31 // * px10 -> x(1 - y) = x - xy
32 // * px01 -> (1 - x)y = y - xy
33 // * px11 -> xy
34 // So x * y is calculated first and then used to calculate all the other factors .
35 static Sk4s VECTORCALL bilerp4(Sk4s xs, Sk4s ys, Sk4f px00, Sk4f px10,
36 Sk4f px01, Sk4f px11) {
37 // Calculate fractional xs and ys.
38 Sk4s fxs = xs - xs.floor();
39 Sk4s fys = ys - ys.floor();
40 Sk4s fxys{fxs * fys};
41 Sk4f sum = px11 * fxys;
42 sum = sum + px01 * (fys - fxys);
43 sum = sum + px10 * (fxs - fxys);
44 sum = sum + px00 * (Sk4f{1.0f} - fxs - fys + fxys);
45 return sum;
46 }
47
48 // The GeneralSampler class
49 template<typename SourceStrategy, typename Next>
50 class GeneralSampler {
51 public:
52 template<typename... Args>
53 GeneralSampler(SkLinearBitmapPipeline::PixelPlacerInterface* next, Args&& .. . args)
54 : fNext{next}, fStrategy{std::forward<Args>(args)...} { }
55
56 void VECTORCALL nearestListFew(int n, Sk4s xs, Sk4s ys) {
57 SkASSERT(0 < n && n < 4);
58 Sk4f px0, px1, px2;
59 fStrategy.getFewPixels(n, xs, ys, &px0, &px1, &px2);
60 if (n >= 1) fNext->placePixel(px0);
61 if (n >= 2) fNext->placePixel(px1);
62 if (n >= 3) fNext->placePixel(px2);
63 }
64
65 void VECTORCALL nearestList4(Sk4s xs, Sk4s ys) {
66 Sk4f px0, px1, px2, px3;
67 fStrategy.get4Pixels(xs, ys, &px0, &px1, &px2, &px3);
68 fNext->place4Pixels(px0, px1, px2, px3);
69 }
70
71 void nearestSpan(Span span) {
72 SkASSERT(!span.isEmpty());
73 SkPoint start;
74 SkScalar length;
75 int count;
76 std::tie(start, length, count) = span;
77 SkScalar absLength = SkScalarAbs(length);
78 if (absLength < (count - 1)) {
79 this->nearestSpanSlowRate(span);
80 } else if (absLength == (count - 1)) {
81 this->nearestSpanUnitRate(span);
82 } else {
83 this->nearestSpanFastRate(span);
84 }
85 }
86
87 Sk4f bilerNonEdgePixel(SkScalar x, SkScalar y) {
88 Sk4f px00, px10, px01, px11;
89 Sk4f xs = Sk4f{x};
90 Sk4f ys = Sk4f{y};
91 Sk4f sampleXs = xs + Sk4f{-0.5f, 0.5f, -0.5f, 0.5f};
92 Sk4f sampleYs = ys + Sk4f{-0.5f, -0.5f, 0.5f, 0.5f};
93 fStrategy.get4Pixels(sampleXs, sampleYs, &px00, &px10, &px01, &px11);
94 return bilerp4(xs, ys, px00, px10, px01, px11);
95 }
96
97 void VECTORCALL bilerpListFew(int n, Sk4s xs, Sk4s ys) {
98 SkASSERT(0 < n && n < 4);
99 auto bilerpPixel = [&](int index) {
100 return this->bilerNonEdgePixel(xs[index], ys[index]);
101 };
102
103 if (n >= 1) fNext->placePixel(bilerpPixel(0));
104 if (n >= 2) fNext->placePixel(bilerpPixel(1));
105 if (n >= 3) fNext->placePixel(bilerpPixel(2));
106 }
107
108 void VECTORCALL bilerpList4(Sk4s xs, Sk4s ys) {
109 auto bilerpPixel = [&](int index) {
110 return this->bilerNonEdgePixel(xs[index], ys[index]);
111 };
112 fNext->place4Pixels(bilerpPixel(0), bilerpPixel(1), bilerpPixel(2), bile rpPixel(3));
113 }
114
115 void VECTORCALL bilerpEdge(Sk4s sampleXs, Sk4s sampleYs) {
116 Sk4f px00, px10, px01, px11;
117 Sk4f xs = Sk4f{sampleXs[0]};
118 Sk4f ys = Sk4f{sampleYs[0]};
119 fStrategy.get4Pixels(sampleXs, sampleYs, &px00, &px10, &px01, &px11);
120 Sk4f pixel = bilerp4(xs, ys, px00, px10, px01, px11);
121 fNext->placePixel(pixel);
122 }
123
124 void bilerpSpan(Span span) {
125 this->bilerpSpanWithY(span, span.startY());
126 }
127
128 void bilerpSpanWithY(Span span, SkScalar y) {
129 SkASSERT(!span.isEmpty());
130 SkPoint start;
131 SkScalar length;
132 int count;
133 std::tie(start, length, count) = span;
134 SkScalar absLength = SkScalarAbs(length);
135 if (absLength == 0.0f) {
136 this->bilerpSpanZeroRate(span, y);
137 } else if (absLength < (count - 1)) {
138 this->bilerpSpanSlowRate(span, y);
139 } else if (absLength == (count - 1)) {
140 if (std::fmod(span.startX() - 0.5f, 1.0f) == 0.0f) {
141 if (std::fmod(span.startY() - 0.5f, 1.0f) == 0.0f) {
142 this->nearestSpanUnitRate(span);
143 } else {
144 this->bilerpSpanUnitRateAlignedX(span, y);
145 }
146 } else {
147 this->bilerpSpanUnitRate(span, y);
148 }
149 } else {
150 this->bilerpSpanFastRate(span, y);
151 }
152 }
153
154 private:
155 // When moving through source space more slowly than dst space (zoomed in),
156 // we'll be sampling from the same source pixel more than once.
157 void nearestSpanSlowRate(Span span) {
158 SkPoint start;
159 SkScalar length;
160 int count;
161 std::tie(start, length, count) = span;
162 SkScalar x = X(start);
163 SkFixed fx = SkScalarToFixed(x);
164 SkScalar dx = length / (count - 1);
165 SkFixed fdx = SkScalarToFixed(dx);
166
167 const void* row = fStrategy.row((int)std::floor(Y(start)));
168 Next* next = fNext;
169
170 int ix = SkFixedFloorToInt(fx);
171 int prevIX = ix;
172 Sk4f fpixel = fStrategy.getPixel(row, ix);
173
174 // When dx is less than one, each pixel is used more than once. Using th e fixed point fx
175 // allows the code to quickly check that the same pixel is being used. T he code uses this
176 // same pixel check to do the sRGB and normalization only once.
177 auto getNextPixel = [&]() {
178 if (ix != prevIX) {
179 fpixel = fStrategy.getPixel(row, ix);
180 prevIX = ix;
181 }
182 fx += fdx;
183 ix = SkFixedFloorToInt(fx);
184 return fpixel;
185 };
186
187 while (count >= 4) {
188 Sk4f px0 = getNextPixel();
189 Sk4f px1 = getNextPixel();
190 Sk4f px2 = getNextPixel();
191 Sk4f px3 = getNextPixel();
192 next->place4Pixels(px0, px1, px2, px3);
193 count -= 4;
194 }
195 while (count > 0) {
196 next->placePixel(getNextPixel());
197 count -= 1;
198 }
199 }
200
201 // We're moving through source space at a rate of 1 source pixel per 1 dst p ixel.
202 // We'll never re-use pixels, but we can at least load contiguous pixels.
203 void nearestSpanUnitRate(Span span) {
204 SkPoint start;
205 SkScalar length;
206 int count;
207 std::tie(start, length, count) = span;
208 int ix = SkScalarFloorToInt(X(start));
209 const void* row = fStrategy.row((int)std::floor(Y(start)));
210 Next* next = fNext;
211 if (length > 0) {
212 while (count >= 4) {
213 Sk4f px0, px1, px2, px3;
214 fStrategy.get4Pixels(row, ix, &px0, &px1, &px2, &px3);
215 next->place4Pixels(px0, px1, px2, px3);
216 ix += 4;
217 count -= 4;
218 }
219
220 while (count > 0) {
221 next->placePixel(fStrategy.getPixel(row, ix));
222 ix += 1;
223 count -= 1;
224 }
225 } else {
226 while (count >= 4) {
227 Sk4f px0, px1, px2, px3;
228 fStrategy.get4Pixels(row, ix - 3, &px3, &px2, &px1, &px0);
229 next->place4Pixels(px0, px1, px2, px3);
230 ix -= 4;
231 count -= 4;
232 }
233
234 while (count > 0) {
235 next->placePixel(fStrategy.getPixel(row, ix));
236 ix -= 1;
237 count -= 1;
238 }
239 }
240 }
241
242 // We're moving through source space faster than dst (zoomed out),
243 // so we'll never reuse a source pixel or be able to do contiguous loads.
244 void nearestSpanFastRate(Span span) {
245 struct NearestWrapper {
246 void VECTORCALL pointListFew(int n, Sk4s xs, Sk4s ys) {
247 fSampler.nearestListFew(n, xs, ys);
248 }
249
250 void VECTORCALL pointList4(Sk4s xs, Sk4s ys) {
251 fSampler.nearestList4(xs, ys);
252 }
253
254 GeneralSampler& fSampler;
255 };
256 NearestWrapper wrapper{*this};
257 span_fallback(span, &wrapper);
258 }
259
260 void bilerpSpanZeroRate(Span span, SkScalar y1) {
261 SkScalar y0 = span.startY() - 0.5f;
262 y1 += 0.5f;
263 int iy0 = SkScalarFloorToInt(y0);
264 SkScalar filterY1 = y0 - iy0;
265 SkScalar filterY0 = 1.0f - filterY1;
266 int iy1 = SkScalarFloorToInt(y1);
267 int ix = SkScalarFloorToInt(span.startX());
268 Sk4f pixelY0 = fStrategy.getPixel(fStrategy.row(iy0), ix);
269 Sk4f pixelY1 = fStrategy.getPixel(fStrategy.row(iy1), ix);
270 Sk4f filterPixel = pixelY0 * filterY0 + pixelY1 * filterY1;
271 int count = span.count();
272 while (count >= 4) {
273 fNext->place4Pixels(filterPixel, filterPixel, filterPixel, filterPix el);
274 count -= 4;
275 }
276 while (count > 0) {
277 fNext->placePixel(filterPixel);
278 count -= 1;
279 }
280 }
281
282 // When moving through source space more slowly than dst space (zoomed in),
283 // we'll be sampling from the same source pixel more than once.
284 void bilerpSpanSlowRate(Span span, SkScalar ry1) {
285 SkPoint start;
286 SkScalar length;
287 int count;
288 std::tie(start, length, count) = span;
289 SkFixed fx = SkScalarToFixed(X(start)
290 -0.5f);
291
292 SkFixed fdx = SkScalarToFixed(length / (count - 1));
293 //start = start + SkPoint{-0.5f, -0.5f};
294
295 Sk4f xAdjust;
296 if (fdx >= 0) {
297 xAdjust = Sk4f{-1.0f};
298 } else {
299 xAdjust = Sk4f{1.0f};
300 }
301 int ix = SkFixedFloorToInt(fx);
302 int ioldx = ix;
303 Sk4f x{SkFixedToScalar(fx) - ix};
304 Sk4f dx{SkFixedToScalar(fdx)};
305 SkScalar ry0 = Y(start) - 0.5f;
306 ry1 += 0.5f;
307 SkScalar yFloor = std::floor(ry0);
308 Sk4f y1 = Sk4f{ry0 - yFloor};
309 Sk4f y0 = Sk4f{1.0f} - y1;
310 const uint32_t* const row0 = fStrategy.row(SkScalarFloorToInt(ry0));
311 const uint32_t* const row1 = fStrategy.row(SkScalarFloorToInt(ry1));
312 Sk4f fpixel00 = y0 * fStrategy.getPixel(row0, ix);
313 Sk4f fpixel01 = y1 * fStrategy.getPixel(row1, ix);
314 Sk4f fpixel10 = y0 * fStrategy.getPixel(row0, ix + 1);
315 Sk4f fpixel11 = y1 * fStrategy.getPixel(row1, ix + 1);
316 auto getNextPixel = [&]() {
317 if (ix != ioldx) {
318 fpixel00 = fpixel10;
319 fpixel01 = fpixel11;
320 fpixel10 = y0 * fStrategy.getPixel(row0, ix + 1);
321 fpixel11 = y1 * fStrategy.getPixel(row1, ix + 1);
322 ioldx = ix;
323 x = x + xAdjust;
324 }
325
326 Sk4f x0, x1;
327 x0 = Sk4f{1.0f} - x;
328 x1 = x;
329 Sk4f fpixel = x0 * (fpixel00 + fpixel01) + x1 * (fpixel10 + fpixel11 );
330 fx += fdx;
331 ix = SkFixedFloorToInt(fx);
332 x = x + dx;
333 return fpixel;
334 };
335
336 while (count >= 4) {
337 Sk4f fpixel0 = getNextPixel();
338 Sk4f fpixel1 = getNextPixel();
339 Sk4f fpixel2 = getNextPixel();
340 Sk4f fpixel3 = getNextPixel();
341
342 fNext->place4Pixels(fpixel0, fpixel1, fpixel2, fpixel3);
343 count -= 4;
344 }
345
346 while (count > 0) {
347 fNext->placePixel(getNextPixel());
348
349 count -= 1;
350 }
351 }
352
353 // We're moving through source space at a rate of 1 source pixel per 1 dst p ixel.
354 // We'll never re-use pixels, but we can at least load contiguous pixels.
355 void bilerpSpanUnitRate(Span span, SkScalar y1) {
356 y1 += 0.5f;
357 SkScalar y0 = span.startY() - 0.5f;
358 int iy0 = SkScalarFloorToInt(y0);
359 SkScalar filterY1 = y0 - iy0;
360 SkScalar filterY0 = 1.0f - filterY1;
361 int iy1 = SkScalarFloorToInt(y1);
362 const void* rowY0 = fStrategy.row(iy0);
363 const void* rowY1 = fStrategy.row(iy1);
364 SkScalar x0 = span.startX() - 0.5f;
365 int ix0 = SkScalarFloorToInt(x0);
366 SkScalar filterX1 = x0 - ix0;
367 SkScalar filterX0 = 1.0f - filterX1;
368
369 auto getPixelY0 = [&]() {
370 Sk4f px = fStrategy.getPixel(rowY0, ix0);
371 return px * filterY0;
372 };
373
374 auto getPixelY1 = [&]() {
375 Sk4f px = fStrategy.getPixel(rowY1, ix0);
376 return px * filterY1;
377 };
378
379 auto get4PixelsY0 = [&](int ix, Sk4f* px0, Sk4f* px1, Sk4f* px2, Sk4f* p x3) {
380 fStrategy.get4Pixels(rowY0, ix, px0, px1, px2, px3);
381 *px0 = *px0 * filterY0;
382 *px1 = *px1 * filterY0;
383 *px2 = *px2 * filterY0;
384 *px3 = *px3 * filterY0;
385 };
386
387 auto get4PixelsY1 = [&](int ix, Sk4f* px0, Sk4f* px1, Sk4f* px2, Sk4f* p x3) {
388 fStrategy.get4Pixels(rowY1, ix, px0, px1, px2, px3);
389 *px0 = *px0 * filterY1;
390 *px1 = *px1 * filterY1;
391 *px2 = *px2 * filterY1;
392 *px3 = *px3 * filterY1;
393 };
394
395 auto lerp = [&](Sk4f& pixelX0, Sk4f& pixelX1) {
396 return pixelX0 * filterX0 + pixelX1 * filterX1;
397 };
398
399 // Mid making 4 unit rate.
400 Sk4f pxB = getPixelY0() + getPixelY1();
401 if (span.length() > 0) {
402 int count = span.count();
403 while (count >= 4) {
404 Sk4f px00, px10, px20, px30;
405 get4PixelsY0(ix0, &px00, &px10, &px20, &px30);
406 Sk4f px01, px11, px21, px31;
407 get4PixelsY1(ix0, &px01, &px11, &px21, &px31);
408 Sk4f pxS0 = px00 + px01;
409 Sk4f px0 = lerp(pxB, pxS0);
410 Sk4f pxS1 = px10 + px11;
411 Sk4f px1 = lerp(pxS0, pxS1);
412 Sk4f pxS2 = px20 + px21;
413 Sk4f px2 = lerp(pxS1, pxS2);
414 Sk4f pxS3 = px30 + px31;
415 Sk4f px3 = lerp(pxS2, pxS3);
416 pxB = pxS3;
417 fNext->place4Pixels(
418 px0,
419 px1,
420 px2,
421 px3);
422 ix0 += 4;
423 count -= 4;
424 }
425 while (count > 0) {
426 Sk4f pixelY0 = fStrategy.getPixel(rowY0, ix0);
427 Sk4f pixelY1 = fStrategy.getPixel(rowY1, ix0);
428
429 fNext->placePixel(lerp(pixelY0, pixelY1));
430 ix0 += 1;
431 count -= 1;
432 }
433 } else {
434 int count = span.count();
435 while (count >= 4) {
436 Sk4f px00, px10, px20, px30;
437 get4PixelsY0(ix0 - 3, &px00, &px10, &px20, &px30);
438 Sk4f px01, px11, px21, px31;
439 get4PixelsY1(ix0 - 3, &px01, &px11, &px21, &px31);
440 Sk4f pxS3 = px30 + px31;
441 Sk4f px0 = lerp(pxS3, pxB);
442 Sk4f pxS2 = px20 + px21;
443 Sk4f px1 = lerp(pxS2, pxS3);
444 Sk4f pxS1 = px10 + px11;
445 Sk4f px2 = lerp(pxS1, pxS2);
446 Sk4f pxS0 = px00 + px01;
447 Sk4f px3 = lerp(pxS0, pxS1);
448 pxB = pxS0;
449 fNext->place4Pixels(
450 px0,
451 px1,
452 px2,
453 px3);
454 ix0 -= 4;
455 count -= 4;
456 }
457 while (count > 0) {
458 Sk4f pixelY0 = fStrategy.getPixel(rowY0, ix0);
459 Sk4f pixelY1 = fStrategy.getPixel(rowY1, ix0);
460
461 fNext->placePixel(lerp(pixelY0, pixelY1));
462 ix0 -= 1;
463 count -= 1;
464 }
465 }
466 }
467
468 void bilerpSpanUnitRateAlignedX(Span span, SkScalar y1) {
469 SkScalar y0 = span.startY() - 0.5f;
470 y1 += 0.5f;
471 int iy0 = SkScalarFloorToInt(y0);
472 SkScalar filterY1 = y0 - iy0;
473 SkScalar filterY0 = 1.0f - filterY1;
474 int iy1 = SkScalarFloorToInt(y1);
475 int ix = SkScalarFloorToInt(span.startX());
476 const void* rowY0 = fStrategy.row(iy0);
477 const void* rowY1 = fStrategy.row(iy1);
478 auto lerp = [&](Sk4f* pixelY0, Sk4f* pixelY1) {
479 return *pixelY0 * filterY0 + *pixelY1 * filterY1;
480 };
481
482 if (span.length() > 0) {
483 int count = span.count();
484 while (count >= 4) {
485 Sk4f px00, px10, px20, px30;
486 fStrategy.get4Pixels(rowY0, ix, &px00, &px10, &px20, &px30);
487 Sk4f px01, px11, px21, px31;
488 fStrategy.get4Pixels(rowY1, ix, &px01, &px11, &px21, &px31);
489 fNext->place4Pixels(
490 lerp(&px00, &px01), lerp(&px10, &px11), lerp(&px20, &px21), lerp(&px30, &px31));
491 ix += 4;
492 count -= 4;
493 }
494 while (count > 0) {
495 Sk4f pixelY0 = fStrategy.getPixel(rowY0, ix);
496 Sk4f pixelY1 = fStrategy.getPixel(rowY1, ix);
497
498 fNext->placePixel(lerp(&pixelY0, &pixelY1));
499 ix += 1;
500 count -= 1;
501 }
502 } else {
503 int count = span.count();
504 while (count >= 4) {
505 Sk4f px00, px10, px20, px30;
506 fStrategy.get4Pixels(rowY0, ix - 3, &px30, &px20, &px10, &px00);
507 Sk4f px01, px11, px21, px31;
508 fStrategy.get4Pixels(rowY1, ix - 3, &px31, &px21, &px11, &px01);
509 fNext->place4Pixels(
510 lerp(&px00, &px01), lerp(&px10, &px11), lerp(&px20, &px21), lerp(&px30, &px31));
511 ix -= 4;
512 count -= 4;
513 }
514 while (count > 0) {
515 Sk4f pixelY0 = fStrategy.getPixel(rowY0, ix);
516 Sk4f pixelY1 = fStrategy.getPixel(rowY1, ix);
517
518 fNext->placePixel(lerp(&pixelY0, &pixelY1));
519 ix -= 1;
520 count -= 1;
521 }
522 }
523 }
524
525 // We're moving through source space faster than dst (zoomed out),
526 // so we'll never reuse a source pixel or be able to do contiguous loads.
527 void bilerpSpanFastRate(Span span, SkScalar y1) {
528 SkPoint start;
529 SkScalar length;
530 int count;
531 std::tie(start, length, count) = span;
532 SkScalar x = X(start);
533 SkScalar y = Y(start);
534 if (false && y == y1) {
535 struct BilerpWrapper {
536 void VECTORCALL pointListFew(int n, Sk4s xs, Sk4s ys) {
537 fSampler.bilerpListFew(n, xs, ys);
538 }
539
540 void VECTORCALL pointList4(Sk4s xs, Sk4s ys) {
541 fSampler.bilerpList4(xs, ys);
542 }
543
544 GeneralSampler& fSampler;
545 };
546 BilerpWrapper wrapper{*this};
547 span_fallback(span, &wrapper);
548 } else {
549 SkScalar dx = length / (count - 1);
550 Sk4f ys = {y - 0.5f, y - 0.5f, y1 + 0.5f, y1 + 0.5f};
551 while (count > 0) {
552 Sk4f xs = Sk4f{-0.5f, 0.5f, -0.5f, 0.5f} + Sk4f{x};
553 this->bilerpEdge(xs, ys);
554 x += dx;
555 count -= 1;
556 }
557 }
558 }
559
560 Next* const fNext;
561 SourceStrategy fStrategy;
562 };
563
564 class sRGBFast {
565 public:
566 static Sk4s VECTORCALL sRGBToLinear(Sk4s pixel) {
567 Sk4s l = pixel * pixel;
568 return Sk4s{l[0], l[1], l[2], pixel[3]};
569 }
570 };
571
572 enum class ColorOrder {
573 kRGBA = false,
574 kBGRA = true,
575 };
576 template <SkColorProfileType colorProfile, ColorOrder colorOrder>
577 class Pixel8888 {
578 public:
579 Pixel8888(int width, const uint32_t* src) : fSrc{src}, fWidth{width}{ }
580 Pixel8888(const SkPixmap& srcPixmap)
581 : fSrc{srcPixmap.addr32()}
582 , fWidth{static_cast<int>(srcPixmap.rowBytes() / 4)} { }
583
584 void VECTORCALL getFewPixels(int n, Sk4s xs, Sk4s ys, Sk4f* px0, Sk4f* px1, Sk4f* px2) {
585 Sk4i XIs = SkNx_cast<int, SkScalar>(xs);
586 Sk4i YIs = SkNx_cast<int, SkScalar>(ys);
587 Sk4i bufferLoc = YIs * fWidth + XIs;
588 switch (n) {
589 case 3:
590 *px2 = this->getPixel(fSrc, bufferLoc[2]);
591 case 2:
592 *px1 = this->getPixel(fSrc, bufferLoc[1]);
593 case 1:
594 *px0 = this->getPixel(fSrc, bufferLoc[0]);
595 default:
596 break;
597 }
598 }
599
600 void VECTORCALL get4Pixels(Sk4s xs, Sk4s ys, Sk4f* px0, Sk4f* px1, Sk4f* px2 , Sk4f* px3) {
601 Sk4i XIs = SkNx_cast<int, SkScalar>(xs);
602 Sk4i YIs = SkNx_cast<int, SkScalar>(ys);
603 Sk4i bufferLoc = YIs * fWidth + XIs;
604 *px0 = this->getPixel(fSrc, bufferLoc[0]);
605 *px1 = this->getPixel(fSrc, bufferLoc[1]);
606 *px2 = this->getPixel(fSrc, bufferLoc[2]);
607 *px3 = this->getPixel(fSrc, bufferLoc[3]);
608 }
609
610 void get4Pixels(const void* vsrc, int index, Sk4f* px0, Sk4f* px1, Sk4f* px2 , Sk4f* px3) {
611 const uint32_t* src = static_cast<const uint32_t*>(vsrc);
612 *px0 = this->getPixel(src, index + 0);
613 *px1 = this->getPixel(src, index + 1);
614 *px2 = this->getPixel(src, index + 2);
615 *px3 = this->getPixel(src, index + 3);
616 }
617
618 Sk4f getPixel(const void* vsrc, int index) {
619 const uint32_t* src = static_cast<const uint32_t*>(vsrc);
620 Sk4b bytePixel = Sk4b::Load((uint8_t *)(&src[index]));
621 Sk4f pixel = SkNx_cast<float, uint8_t>(bytePixel);
622 if (colorOrder == ColorOrder::kBGRA) {
623 pixel = SkNx_shuffle<2, 1, 0, 3>(pixel);
624 }
625 pixel = pixel * Sk4f{1.0f/255.0f};
626 if (colorProfile == kSRGB_SkColorProfileType) {
627 pixel = sRGBFast::sRGBToLinear(pixel);
628 }
629 return pixel;
630 }
631
632 const uint32_t* row(int y) { return fSrc + y * fWidth[0]; }
633
634 private:
635 const uint32_t* const fSrc;
636 const Sk4i fWidth;
637 };
638 using Pixel8888SRGB = Pixel8888<kSRGB_SkColorProfileType, ColorOrder::kRGBA>;
639 using Pixel8888LRGB = Pixel8888<kLinear_SkColorProfileType, ColorOrder::kRGBA>;
640 using Pixel8888SBGR = Pixel8888<kSRGB_SkColorProfileType, ColorOrder::kBGRA>;
641 using Pixel8888LBGR = Pixel8888<kLinear_SkColorProfileType, ColorOrder::kBGRA>;
642 } // namespace
643
644 #endif // SkLinearBitmapPipeline_sampler_DEFINED
OLDNEW
« no previous file with comments | « src/core/SkLinearBitmapPipeline_matrix.h ('k') | src/core/SkLinearBitmapPipeline_tile.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698