| 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 #ifndef SkLinearBitmapPipeline_sampler_DEFINED | 8 #ifndef SkLinearBitmapPipeline_sampler_DEFINED |
| 9 #define SkLinearBitmapPipeline_sampler_DEFINED | 9 #define SkLinearBitmapPipeline_sampler_DEFINED |
| 10 | 10 |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 45 sum = sum + px10 * (fxs - fxys); | 45 sum = sum + px10 * (fxs - fxys); |
| 46 sum = sum + px00 * (Sk4f{1.0f} - fxs - fys + fxys); | 46 sum = sum + px00 * (Sk4f{1.0f} - fxs - fys + fxys); |
| 47 return sum; | 47 return sum; |
| 48 } | 48 } |
| 49 | 49 |
| 50 // The GeneralSampler class | 50 // The GeneralSampler class |
| 51 template<typename SourceStrategy, typename Next> | 51 template<typename SourceStrategy, typename Next> |
| 52 class GeneralSampler { | 52 class GeneralSampler { |
| 53 public: | 53 public: |
| 54 template<typename... Args> | 54 template<typename... Args> |
| 55 GeneralSampler(SkLinearBitmapPipeline::PixelPlacerInterface* next, Args&& ..
. args) | 55 GeneralSampler(SkLinearBitmapPipeline::MixProcessorInterface* next, Args&& .
.. args) |
| 56 : fNext{next}, fStrategy{std::forward<Args>(args)...} { } | 56 : fNext{next}, fStrategy{std::forward<Args>(args)...} { } |
| 57 | 57 |
| 58 GeneralSampler(SkLinearBitmapPipeline::MixProcessorInterface* next, |
| 59 const GeneralSampler& sampler) |
| 60 : fNext{next}, fStrategy{sampler.fStrategy} { } |
| 61 |
| 58 void VECTORCALL nearestListFew(int n, Sk4s xs, Sk4s ys) { | 62 void VECTORCALL nearestListFew(int n, Sk4s xs, Sk4s ys) { |
| 59 SkASSERT(0 < n && n < 4); | 63 SkASSERT(0 < n && n < 4); |
| 60 Sk4f px0, px1, px2; | 64 Sk4f px0, px1, px2; |
| 61 fStrategy.getFewPixels(n, xs, ys, &px0, &px1, &px2); | 65 fStrategy.getFewPixels(n, xs, ys, &px0, &px1, &px2); |
| 62 if (n >= 1) fNext->placePixel(px0); | 66 if (n >= 1) fNext->mixPixel(px0); |
| 63 if (n >= 2) fNext->placePixel(px1); | 67 if (n >= 2) fNext->mixPixel(px1); |
| 64 if (n >= 3) fNext->placePixel(px2); | 68 if (n >= 3) fNext->mixPixel(px2); |
| 65 } | 69 } |
| 66 | 70 |
| 67 void VECTORCALL nearestList4(Sk4s xs, Sk4s ys) { | 71 void VECTORCALL nearestList4(Sk4s xs, Sk4s ys) { |
| 68 Sk4f px0, px1, px2, px3; | 72 Sk4f px0, px1, px2, px3; |
| 69 fStrategy.get4Pixels(xs, ys, &px0, &px1, &px2, &px3); | 73 fStrategy.get4Pixels(xs, ys, &px0, &px1, &px2, &px3); |
| 70 fNext->place4Pixels(px0, px1, px2, px3); | 74 fNext->mix4Pixels(px0, px1, px2, px3); |
| 71 } | 75 } |
| 72 | 76 |
| 73 void nearestSpan(Span span) { | 77 void nearestSpan(Span span) { |
| 74 SkASSERT(!span.isEmpty()); | 78 SkASSERT(!span.isEmpty()); |
| 75 SkPoint start; | 79 SkPoint start; |
| 76 SkScalar length; | 80 SkScalar length; |
| 77 int count; | 81 int count; |
| 78 std::tie(start, length, count) = span; | 82 std::tie(start, length, count) = span; |
| 79 SkScalar absLength = SkScalarAbs(length); | 83 SkScalar absLength = SkScalarAbs(length); |
| 80 if (absLength < (count - 1)) { | 84 if (absLength < (count - 1)) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 95 fStrategy.get4Pixels(sampleXs, sampleYs, &px00, &px10, &px01, &px11); | 99 fStrategy.get4Pixels(sampleXs, sampleYs, &px00, &px10, &px01, &px11); |
| 96 return bilerp4(xs, ys, px00, px10, px01, px11); | 100 return bilerp4(xs, ys, px00, px10, px01, px11); |
| 97 } | 101 } |
| 98 | 102 |
| 99 void VECTORCALL bilerpListFew(int n, Sk4s xs, Sk4s ys) { | 103 void VECTORCALL bilerpListFew(int n, Sk4s xs, Sk4s ys) { |
| 100 SkASSERT(0 < n && n < 4); | 104 SkASSERT(0 < n && n < 4); |
| 101 auto bilerpPixel = [&](int index) { | 105 auto bilerpPixel = [&](int index) { |
| 102 return this->bilerNonEdgePixel(xs[index], ys[index]); | 106 return this->bilerNonEdgePixel(xs[index], ys[index]); |
| 103 }; | 107 }; |
| 104 | 108 |
| 105 if (n >= 1) fNext->placePixel(bilerpPixel(0)); | 109 if (n >= 1) fNext->mixPixel(bilerpPixel(0)); |
| 106 if (n >= 2) fNext->placePixel(bilerpPixel(1)); | 110 if (n >= 2) fNext->mixPixel(bilerpPixel(1)); |
| 107 if (n >= 3) fNext->placePixel(bilerpPixel(2)); | 111 if (n >= 3) fNext->mixPixel(bilerpPixel(2)); |
| 108 } | 112 } |
| 109 | 113 |
| 110 void VECTORCALL bilerpList4(Sk4s xs, Sk4s ys) { | 114 void VECTORCALL bilerpList4(Sk4s xs, Sk4s ys) { |
| 111 auto bilerpPixel = [&](int index) { | 115 auto bilerpPixel = [&](int index) { |
| 112 return this->bilerNonEdgePixel(xs[index], ys[index]); | 116 return this->bilerNonEdgePixel(xs[index], ys[index]); |
| 113 }; | 117 }; |
| 114 fNext->place4Pixels(bilerpPixel(0), bilerpPixel(1), bilerpPixel(2), bile
rpPixel(3)); | 118 fNext->mix4Pixels(bilerpPixel(0), bilerpPixel(1), bilerpPixel(2), bilerp
Pixel(3)); |
| 115 } | 119 } |
| 116 | 120 |
| 117 void VECTORCALL bilerpEdge(Sk4s sampleXs, Sk4s sampleYs) { | 121 void VECTORCALL bilerpEdge(Sk4s sampleXs, Sk4s sampleYs) { |
| 118 Sk4f px00, px10, px01, px11; | 122 Sk4f px00, px10, px01, px11; |
| 119 Sk4f xs = Sk4f{sampleXs[0]}; | 123 Sk4f xs = Sk4f{sampleXs[0]}; |
| 120 Sk4f ys = Sk4f{sampleYs[0]}; | 124 Sk4f ys = Sk4f{sampleYs[0]}; |
| 121 fStrategy.get4Pixels(sampleXs, sampleYs, &px00, &px10, &px01, &px11); | 125 fStrategy.get4Pixels(sampleXs, sampleYs, &px00, &px10, &px01, &px11); |
| 122 Sk4f pixel = bilerp4(xs, ys, px00, px10, px01, px11); | 126 Sk4f pixel = bilerp4(xs, ys, px00, px10, px01, px11); |
| 123 fNext->placePixel(pixel); | 127 fNext->mixPixel(pixel); |
| 124 } | 128 } |
| 125 | 129 |
| 126 void bilerpSpan(Span span) { | 130 void bilerpSpan(Span span) { |
| 127 this->bilerpSpanWithY(span, span.startY()); | 131 this->bilerpSpanWithY(span, span.startY()); |
| 128 } | 132 } |
| 129 | 133 |
| 130 void bilerpSpanWithY(Span span, SkScalar y) { | 134 void bilerpSpanWithY(Span span, SkScalar y) { |
| 131 SkASSERT(!span.isEmpty()); | 135 SkASSERT(!span.isEmpty()); |
| 132 SkPoint start; | 136 SkPoint start; |
| 133 SkScalar length; | 137 SkScalar length; |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 184 fx += fdx; | 188 fx += fdx; |
| 185 ix = SkFixedFloorToInt(fx); | 189 ix = SkFixedFloorToInt(fx); |
| 186 return fpixel; | 190 return fpixel; |
| 187 }; | 191 }; |
| 188 | 192 |
| 189 while (count >= 4) { | 193 while (count >= 4) { |
| 190 Sk4f px0 = getNextPixel(); | 194 Sk4f px0 = getNextPixel(); |
| 191 Sk4f px1 = getNextPixel(); | 195 Sk4f px1 = getNextPixel(); |
| 192 Sk4f px2 = getNextPixel(); | 196 Sk4f px2 = getNextPixel(); |
| 193 Sk4f px3 = getNextPixel(); | 197 Sk4f px3 = getNextPixel(); |
| 194 next->place4Pixels(px0, px1, px2, px3); | 198 next->mix4Pixels(px0, px1, px2, px3); |
| 195 count -= 4; | 199 count -= 4; |
| 196 } | 200 } |
| 197 while (count > 0) { | 201 while (count > 0) { |
| 198 next->placePixel(getNextPixel()); | 202 next->mixPixel(getNextPixel()); |
| 199 count -= 1; | 203 count -= 1; |
| 200 } | 204 } |
| 201 } | 205 } |
| 202 | 206 |
| 203 // We're moving through source space at a rate of 1 source pixel per 1 dst p
ixel. | 207 // We're moving through source space at a rate of 1 source pixel per 1 dst p
ixel. |
| 204 // We'll never re-use pixels, but we can at least load contiguous pixels. | 208 // We'll never re-use pixels, but we can at least load contiguous pixels. |
| 205 void nearestSpanUnitRate(Span span) { | 209 void nearestSpanUnitRate(Span span) { |
| 206 SkPoint start; | 210 SkPoint start; |
| 207 SkScalar length; | 211 SkScalar length; |
| 208 int count; | 212 int count; |
| 209 std::tie(start, length, count) = span; | 213 std::tie(start, length, count) = span; |
| 210 int ix = SkScalarFloorToInt(X(start)); | 214 int ix = SkScalarFloorToInt(X(start)); |
| 211 const void* row = fStrategy.row((int)std::floor(Y(start))); | 215 const void* row = fStrategy.row((int)std::floor(Y(start))); |
| 212 Next* next = fNext; | 216 Next* next = fNext; |
| 213 if (length > 0) { | 217 if (length > 0) { |
| 214 while (count >= 4) { | 218 while (count >= 4) { |
| 215 Sk4f px0, px1, px2, px3; | 219 Sk4f px0, px1, px2, px3; |
| 216 fStrategy.get4Pixels(row, ix, &px0, &px1, &px2, &px3); | 220 fStrategy.get4Pixels(row, ix, &px0, &px1, &px2, &px3); |
| 217 next->place4Pixels(px0, px1, px2, px3); | 221 next->mix4Pixels(px0, px1, px2, px3); |
| 218 ix += 4; | 222 ix += 4; |
| 219 count -= 4; | 223 count -= 4; |
| 220 } | 224 } |
| 221 | 225 |
| 222 while (count > 0) { | 226 while (count > 0) { |
| 223 next->placePixel(fStrategy.getPixelAt(row, ix)); | 227 next->mixPixel(fStrategy.getPixelAt(row, ix)); |
| 224 ix += 1; | 228 ix += 1; |
| 225 count -= 1; | 229 count -= 1; |
| 226 } | 230 } |
| 227 } else { | 231 } else { |
| 228 while (count >= 4) { | 232 while (count >= 4) { |
| 229 Sk4f px0, px1, px2, px3; | 233 Sk4f px0, px1, px2, px3; |
| 230 fStrategy.get4Pixels(row, ix - 3, &px3, &px2, &px1, &px0); | 234 fStrategy.get4Pixels(row, ix - 3, &px3, &px2, &px1, &px0); |
| 231 next->place4Pixels(px0, px1, px2, px3); | 235 next->mix4Pixels(px0, px1, px2, px3); |
| 232 ix -= 4; | 236 ix -= 4; |
| 233 count -= 4; | 237 count -= 4; |
| 234 } | 238 } |
| 235 | 239 |
| 236 while (count > 0) { | 240 while (count > 0) { |
| 237 next->placePixel(fStrategy.getPixelAt(row, ix)); | 241 next->mixPixel(fStrategy.getPixelAt(row, ix)); |
| 238 ix -= 1; | 242 ix -= 1; |
| 239 count -= 1; | 243 count -= 1; |
| 240 } | 244 } |
| 241 } | 245 } |
| 242 } | 246 } |
| 243 | 247 |
| 244 // We're moving through source space faster than dst (zoomed out), | 248 // We're moving through source space faster than dst (zoomed out), |
| 245 // so we'll never reuse a source pixel or be able to do contiguous loads. | 249 // so we'll never reuse a source pixel or be able to do contiguous loads. |
| 246 void nearestSpanFastRate(Span span) { | 250 void nearestSpanFastRate(Span span) { |
| 247 struct NearestWrapper { | 251 struct NearestWrapper { |
| (...skipping 17 matching lines...) Expand all Loading... |
| 265 int iy0 = SkScalarFloorToInt(y0); | 269 int iy0 = SkScalarFloorToInt(y0); |
| 266 SkScalar filterY1 = y0 - iy0; | 270 SkScalar filterY1 = y0 - iy0; |
| 267 SkScalar filterY0 = 1.0f - filterY1; | 271 SkScalar filterY0 = 1.0f - filterY1; |
| 268 int iy1 = SkScalarFloorToInt(y1); | 272 int iy1 = SkScalarFloorToInt(y1); |
| 269 int ix = SkScalarFloorToInt(span.startX()); | 273 int ix = SkScalarFloorToInt(span.startX()); |
| 270 Sk4f pixelY0 = fStrategy.getPixelAt(fStrategy.row(iy0), ix); | 274 Sk4f pixelY0 = fStrategy.getPixelAt(fStrategy.row(iy0), ix); |
| 271 Sk4f pixelY1 = fStrategy.getPixelAt(fStrategy.row(iy1), ix); | 275 Sk4f pixelY1 = fStrategy.getPixelAt(fStrategy.row(iy1), ix); |
| 272 Sk4f filterPixel = pixelY0 * filterY0 + pixelY1 * filterY1; | 276 Sk4f filterPixel = pixelY0 * filterY0 + pixelY1 * filterY1; |
| 273 int count = span.count(); | 277 int count = span.count(); |
| 274 while (count >= 4) { | 278 while (count >= 4) { |
| 275 fNext->place4Pixels(filterPixel, filterPixel, filterPixel, filterPix
el); | 279 fNext->mix4Pixels(filterPixel, filterPixel, filterPixel, filterPixel
); |
| 276 count -= 4; | 280 count -= 4; |
| 277 } | 281 } |
| 278 while (count > 0) { | 282 while (count > 0) { |
| 279 fNext->placePixel(filterPixel); | 283 fNext->mixPixel(filterPixel); |
| 280 count -= 1; | 284 count -= 1; |
| 281 } | 285 } |
| 282 } | 286 } |
| 283 | 287 |
| 284 // When moving through source space more slowly than dst space (zoomed in), | 288 // When moving through source space more slowly than dst space (zoomed in), |
| 285 // we'll be sampling from the same source pixel more than once. | 289 // we'll be sampling from the same source pixel more than once. |
| 286 void bilerpSpanSlowRate(Span span, SkScalar ry1) { | 290 void bilerpSpanSlowRate(Span span, SkScalar ry1) { |
| 287 SkPoint start; | 291 SkPoint start; |
| 288 SkScalar length; | 292 SkScalar length; |
| 289 int count; | 293 int count; |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 334 x = x + dx; | 338 x = x + dx; |
| 335 return fpixel; | 339 return fpixel; |
| 336 }; | 340 }; |
| 337 | 341 |
| 338 while (count >= 4) { | 342 while (count >= 4) { |
| 339 Sk4f fpixel0 = getNextPixel(); | 343 Sk4f fpixel0 = getNextPixel(); |
| 340 Sk4f fpixel1 = getNextPixel(); | 344 Sk4f fpixel1 = getNextPixel(); |
| 341 Sk4f fpixel2 = getNextPixel(); | 345 Sk4f fpixel2 = getNextPixel(); |
| 342 Sk4f fpixel3 = getNextPixel(); | 346 Sk4f fpixel3 = getNextPixel(); |
| 343 | 347 |
| 344 fNext->place4Pixels(fpixel0, fpixel1, fpixel2, fpixel3); | 348 fNext->mix4Pixels(fpixel0, fpixel1, fpixel2, fpixel3); |
| 345 count -= 4; | 349 count -= 4; |
| 346 } | 350 } |
| 347 | 351 |
| 348 while (count > 0) { | 352 while (count > 0) { |
| 349 fNext->placePixel(getNextPixel()); | 353 fNext->mixPixel(getNextPixel()); |
| 350 | 354 |
| 351 count -= 1; | 355 count -= 1; |
| 352 } | 356 } |
| 353 } | 357 } |
| 354 | 358 |
| 355 // We're moving through source space at a rate of 1 source pixel per 1 dst p
ixel. | 359 // We're moving through source space at a rate of 1 source pixel per 1 dst p
ixel. |
| 356 // We'll never re-use pixels, but we can at least load contiguous pixels. | 360 // We'll never re-use pixels, but we can at least load contiguous pixels. |
| 357 void bilerpSpanUnitRate(Span span, SkScalar y1) { | 361 void bilerpSpanUnitRate(Span span, SkScalar y1) { |
| 358 y1 += 0.5f; | 362 y1 += 0.5f; |
| 359 SkScalar y0 = span.startY() - 0.5f; | 363 SkScalar y0 = span.startY() - 0.5f; |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 409 get4PixelsY1(ix0, &px01, &px11, &px21, &px31); | 413 get4PixelsY1(ix0, &px01, &px11, &px21, &px31); |
| 410 Sk4f pxS0 = px00 + px01; | 414 Sk4f pxS0 = px00 + px01; |
| 411 Sk4f px0 = lerp(pxB, pxS0); | 415 Sk4f px0 = lerp(pxB, pxS0); |
| 412 Sk4f pxS1 = px10 + px11; | 416 Sk4f pxS1 = px10 + px11; |
| 413 Sk4f px1 = lerp(pxS0, pxS1); | 417 Sk4f px1 = lerp(pxS0, pxS1); |
| 414 Sk4f pxS2 = px20 + px21; | 418 Sk4f pxS2 = px20 + px21; |
| 415 Sk4f px2 = lerp(pxS1, pxS2); | 419 Sk4f px2 = lerp(pxS1, pxS2); |
| 416 Sk4f pxS3 = px30 + px31; | 420 Sk4f pxS3 = px30 + px31; |
| 417 Sk4f px3 = lerp(pxS2, pxS3); | 421 Sk4f px3 = lerp(pxS2, pxS3); |
| 418 pxB = pxS3; | 422 pxB = pxS3; |
| 419 fNext->place4Pixels( | 423 fNext->mix4Pixels(px0, px1, px2, px3); |
| 420 px0, | |
| 421 px1, | |
| 422 px2, | |
| 423 px3); | |
| 424 ix0 += 4; | 424 ix0 += 4; |
| 425 count -= 4; | 425 count -= 4; |
| 426 } | 426 } |
| 427 while (count > 0) { | 427 while (count > 0) { |
| 428 Sk4f pixelY0 = fStrategy.getPixelAt(rowY0, ix0); | 428 Sk4f pixelY0 = fStrategy.getPixelAt(rowY0, ix0); |
| 429 Sk4f pixelY1 = fStrategy.getPixelAt(rowY1, ix0); | 429 Sk4f pixelY1 = fStrategy.getPixelAt(rowY1, ix0); |
| 430 | 430 |
| 431 fNext->placePixel(lerp(pixelY0, pixelY1)); | 431 fNext->mixPixel(lerp(pixelY0, pixelY1)); |
| 432 ix0 += 1; | 432 ix0 += 1; |
| 433 count -= 1; | 433 count -= 1; |
| 434 } | 434 } |
| 435 } else { | 435 } else { |
| 436 int count = span.count(); | 436 int count = span.count(); |
| 437 while (count >= 4) { | 437 while (count >= 4) { |
| 438 Sk4f px00, px10, px20, px30; | 438 Sk4f px00, px10, px20, px30; |
| 439 get4PixelsY0(ix0 - 3, &px00, &px10, &px20, &px30); | 439 get4PixelsY0(ix0 - 3, &px00, &px10, &px20, &px30); |
| 440 Sk4f px01, px11, px21, px31; | 440 Sk4f px01, px11, px21, px31; |
| 441 get4PixelsY1(ix0 - 3, &px01, &px11, &px21, &px31); | 441 get4PixelsY1(ix0 - 3, &px01, &px11, &px21, &px31); |
| 442 Sk4f pxS3 = px30 + px31; | 442 Sk4f pxS3 = px30 + px31; |
| 443 Sk4f px0 = lerp(pxS3, pxB); | 443 Sk4f px0 = lerp(pxS3, pxB); |
| 444 Sk4f pxS2 = px20 + px21; | 444 Sk4f pxS2 = px20 + px21; |
| 445 Sk4f px1 = lerp(pxS2, pxS3); | 445 Sk4f px1 = lerp(pxS2, pxS3); |
| 446 Sk4f pxS1 = px10 + px11; | 446 Sk4f pxS1 = px10 + px11; |
| 447 Sk4f px2 = lerp(pxS1, pxS2); | 447 Sk4f px2 = lerp(pxS1, pxS2); |
| 448 Sk4f pxS0 = px00 + px01; | 448 Sk4f pxS0 = px00 + px01; |
| 449 Sk4f px3 = lerp(pxS0, pxS1); | 449 Sk4f px3 = lerp(pxS0, pxS1); |
| 450 pxB = pxS0; | 450 pxB = pxS0; |
| 451 fNext->place4Pixels( | 451 fNext->mix4Pixels(px0, px1, px2, px3); |
| 452 px0, | |
| 453 px1, | |
| 454 px2, | |
| 455 px3); | |
| 456 ix0 -= 4; | 452 ix0 -= 4; |
| 457 count -= 4; | 453 count -= 4; |
| 458 } | 454 } |
| 459 while (count > 0) { | 455 while (count > 0) { |
| 460 Sk4f pixelY0 = fStrategy.getPixelAt(rowY0, ix0); | 456 Sk4f pixelY0 = fStrategy.getPixelAt(rowY0, ix0); |
| 461 Sk4f pixelY1 = fStrategy.getPixelAt(rowY1, ix0); | 457 Sk4f pixelY1 = fStrategy.getPixelAt(rowY1, ix0); |
| 462 | 458 |
| 463 fNext->placePixel(lerp(pixelY0, pixelY1)); | 459 fNext->mixPixel(lerp(pixelY0, pixelY1)); |
| 464 ix0 -= 1; | 460 ix0 -= 1; |
| 465 count -= 1; | 461 count -= 1; |
| 466 } | 462 } |
| 467 } | 463 } |
| 468 } | 464 } |
| 469 | 465 |
| 470 void bilerpSpanUnitRateAlignedX(Span span, SkScalar y1) { | 466 void bilerpSpanUnitRateAlignedX(Span span, SkScalar y1) { |
| 471 SkScalar y0 = span.startY() - 0.5f; | 467 SkScalar y0 = span.startY() - 0.5f; |
| 472 y1 += 0.5f; | 468 y1 += 0.5f; |
| 473 int iy0 = SkScalarFloorToInt(y0); | 469 int iy0 = SkScalarFloorToInt(y0); |
| 474 SkScalar filterY1 = y0 - iy0; | 470 SkScalar filterY1 = y0 - iy0; |
| 475 SkScalar filterY0 = 1.0f - filterY1; | 471 SkScalar filterY0 = 1.0f - filterY1; |
| 476 int iy1 = SkScalarFloorToInt(y1); | 472 int iy1 = SkScalarFloorToInt(y1); |
| 477 int ix = SkScalarFloorToInt(span.startX()); | 473 int ix = SkScalarFloorToInt(span.startX()); |
| 478 const void* rowY0 = fStrategy.row(iy0); | 474 const void* rowY0 = fStrategy.row(iy0); |
| 479 const void* rowY1 = fStrategy.row(iy1); | 475 const void* rowY1 = fStrategy.row(iy1); |
| 480 auto lerp = [&](Sk4f* pixelY0, Sk4f* pixelY1) { | 476 auto lerp = [&](Sk4f* pixelY0, Sk4f* pixelY1) { |
| 481 return *pixelY0 * filterY0 + *pixelY1 * filterY1; | 477 return *pixelY0 * filterY0 + *pixelY1 * filterY1; |
| 482 }; | 478 }; |
| 483 | 479 |
| 484 if (span.length() > 0) { | 480 if (span.length() > 0) { |
| 485 int count = span.count(); | 481 int count = span.count(); |
| 486 while (count >= 4) { | 482 while (count >= 4) { |
| 487 Sk4f px00, px10, px20, px30; | 483 Sk4f px00, px10, px20, px30; |
| 488 fStrategy.get4Pixels(rowY0, ix, &px00, &px10, &px20, &px30); | 484 fStrategy.get4Pixels(rowY0, ix, &px00, &px10, &px20, &px30); |
| 489 Sk4f px01, px11, px21, px31; | 485 Sk4f px01, px11, px21, px31; |
| 490 fStrategy.get4Pixels(rowY1, ix, &px01, &px11, &px21, &px31); | 486 fStrategy.get4Pixels(rowY1, ix, &px01, &px11, &px21, &px31); |
| 491 fNext->place4Pixels( | 487 fNext->mix4Pixels( |
| 492 lerp(&px00, &px01), lerp(&px10, &px11), lerp(&px20, &px21),
lerp(&px30, &px31)); | 488 lerp(&px00, &px01), lerp(&px10, &px11), lerp(&px20, &px21),
lerp(&px30, &px31)); |
| 493 ix += 4; | 489 ix += 4; |
| 494 count -= 4; | 490 count -= 4; |
| 495 } | 491 } |
| 496 while (count > 0) { | 492 while (count > 0) { |
| 497 Sk4f pixelY0 = fStrategy.getPixelAt(rowY0, ix); | 493 Sk4f pixelY0 = fStrategy.getPixelAt(rowY0, ix); |
| 498 Sk4f pixelY1 = fStrategy.getPixelAt(rowY1, ix); | 494 Sk4f pixelY1 = fStrategy.getPixelAt(rowY1, ix); |
| 499 | 495 |
| 500 fNext->placePixel(lerp(&pixelY0, &pixelY1)); | 496 fNext->mixPixel(lerp(&pixelY0, &pixelY1)); |
| 501 ix += 1; | 497 ix += 1; |
| 502 count -= 1; | 498 count -= 1; |
| 503 } | 499 } |
| 504 } else { | 500 } else { |
| 505 int count = span.count(); | 501 int count = span.count(); |
| 506 while (count >= 4) { | 502 while (count >= 4) { |
| 507 Sk4f px00, px10, px20, px30; | 503 Sk4f px00, px10, px20, px30; |
| 508 fStrategy.get4Pixels(rowY0, ix - 3, &px30, &px20, &px10, &px00); | 504 fStrategy.get4Pixels(rowY0, ix - 3, &px30, &px20, &px10, &px00); |
| 509 Sk4f px01, px11, px21, px31; | 505 Sk4f px01, px11, px21, px31; |
| 510 fStrategy.get4Pixels(rowY1, ix - 3, &px31, &px21, &px11, &px01); | 506 fStrategy.get4Pixels(rowY1, ix - 3, &px31, &px21, &px11, &px01); |
| 511 fNext->place4Pixels( | 507 fNext->mix4Pixels( |
| 512 lerp(&px00, &px01), lerp(&px10, &px11), lerp(&px20, &px21),
lerp(&px30, &px31)); | 508 lerp(&px00, &px01), lerp(&px10, &px11), lerp(&px20, &px21),
lerp(&px30, &px31)); |
| 513 ix -= 4; | 509 ix -= 4; |
| 514 count -= 4; | 510 count -= 4; |
| 515 } | 511 } |
| 516 while (count > 0) { | 512 while (count > 0) { |
| 517 Sk4f pixelY0 = fStrategy.getPixelAt(rowY0, ix); | 513 Sk4f pixelY0 = fStrategy.getPixelAt(rowY0, ix); |
| 518 Sk4f pixelY1 = fStrategy.getPixelAt(rowY1, ix); | 514 Sk4f pixelY1 = fStrategy.getPixelAt(rowY1, ix); |
| 519 | 515 |
| 520 fNext->placePixel(lerp(&pixelY0, &pixelY1)); | 516 fNext->mixPixel(lerp(&pixelY0, &pixelY1)); |
| 521 ix -= 1; | 517 ix -= 1; |
| 522 count -= 1; | 518 count -= 1; |
| 523 } | 519 } |
| 524 } | 520 } |
| 525 } | 521 } |
| 526 | 522 |
| 527 // We're moving through source space faster than dst (zoomed out), | 523 // We're moving through source space faster than dst (zoomed out), |
| 528 // so we'll never reuse a source pixel or be able to do contiguous loads. | 524 // so we'll never reuse a source pixel or be able to do contiguous loads. |
| 529 void bilerpSpanFastRate(Span span, SkScalar y1) { | 525 void bilerpSpanFastRate(Span span, SkScalar y1) { |
| 530 SkPoint start; | 526 SkPoint start; |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 650 SkASSERT(srcPixmap.colorType() == kIndex_8_SkColorType); | 646 SkASSERT(srcPixmap.colorType() == kIndex_8_SkColorType); |
| 651 SkColorTable* skColorTable = srcPixmap.ctable(); | 647 SkColorTable* skColorTable = srcPixmap.ctable(); |
| 652 SkASSERT(skColorTable != nullptr); | 648 SkASSERT(skColorTable != nullptr); |
| 653 | 649 |
| 654 fColorTable = (Sk4f*)SkAlign16((intptr_t)fColorTableStorage.get()); | 650 fColorTable = (Sk4f*)SkAlign16((intptr_t)fColorTableStorage.get()); |
| 655 for (int i = 0; i < skColorTable->count(); i++) { | 651 for (int i = 0; i < skColorTable->count(); i++) { |
| 656 fColorTable[i] = this->convertPixel((*skColorTable)[i]); | 652 fColorTable[i] = this->convertPixel((*skColorTable)[i]); |
| 657 } | 653 } |
| 658 } | 654 } |
| 659 | 655 |
| 656 PixelIndex8(const PixelIndex8& strategy) |
| 657 : fSrc{strategy.fSrc}, fWidth{strategy.fWidth} { |
| 658 fColorTable = (Sk4f*)SkAlign16((intptr_t)fColorTableStorage.get()); |
| 659 // TODO: figure out the count. |
| 660 for (int i = 0; i < 256; i++) { |
| 661 fColorTable[i] = strategy.fColorTable[i]; |
| 662 } |
| 663 } |
| 664 |
| 660 void VECTORCALL getFewPixels(int n, Sk4s xs, Sk4s ys, Sk4f* px0, Sk4f* px1,
Sk4f* px2) { | 665 void VECTORCALL getFewPixels(int n, Sk4s xs, Sk4s ys, Sk4f* px0, Sk4f* px1,
Sk4f* px2) { |
| 661 Sk4i XIs = SkNx_cast<int, SkScalar>(xs); | 666 Sk4i XIs = SkNx_cast<int, SkScalar>(xs); |
| 662 Sk4i YIs = SkNx_cast<int, SkScalar>(ys); | 667 Sk4i YIs = SkNx_cast<int, SkScalar>(ys); |
| 663 Sk4i bufferLoc = YIs * fWidth + XIs; | 668 Sk4i bufferLoc = YIs * fWidth + XIs; |
| 664 switch (n) { | 669 switch (n) { |
| 665 case 3: | 670 case 3: |
| 666 *px2 = this->getPixelAt(fSrc, bufferLoc[2]); | 671 *px2 = this->getPixelAt(fSrc, bufferLoc[2]); |
| 667 case 2: | 672 case 2: |
| 668 *px1 = this->getPixelAt(fSrc, bufferLoc[1]); | 673 *px1 = this->getPixelAt(fSrc, bufferLoc[1]); |
| 669 case 1: | 674 case 1: |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 725 SkAutoMalloc fColorTableStorage{kColorTableSize}; | 730 SkAutoMalloc fColorTableStorage{kColorTableSize}; |
| 726 Sk4f* fColorTable; | 731 Sk4f* fColorTable; |
| 727 }; | 732 }; |
| 728 | 733 |
| 729 using PixelIndex8SRGB = PixelIndex8<kSRGB_SkColorProfileType>; | 734 using PixelIndex8SRGB = PixelIndex8<kSRGB_SkColorProfileType>; |
| 730 using PixelIndex8LRGB = PixelIndex8<kLinear_SkColorProfileType>; | 735 using PixelIndex8LRGB = PixelIndex8<kLinear_SkColorProfileType>; |
| 731 | 736 |
| 732 } // namespace | 737 } // namespace |
| 733 | 738 |
| 734 #endif // SkLinearBitmapPipeline_sampler_DEFINED | 739 #endif // SkLinearBitmapPipeline_sampler_DEFINED |
| OLD | NEW |