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

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

Issue 2174793002: Revert of Redo Tiling (Closed) Base URL: https://skia.googlesource.com/skia.git@reduce-LBP-sample
Patch Set: 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/SkLinearBitmapPipeline.h ('k') | src/core/SkLinearBitmapPipeline_core.h » ('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 "SkLinearBitmapPipeline.h" 8 #include "SkLinearBitmapPipeline.h"
9 9
10 #include <algorithm> 10 #include <algorithm>
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
158 } else { 158 } else {
159 return next; 159 return next;
160 } 160 }
161 return matrixProc->get(); 161 return matrixProc->get();
162 } 162 }
163 163
164 //////////////////////////////////////////////////////////////////////////////// //////////////////// 164 //////////////////////////////////////////////////////////////////////////////// ////////////////////
165 // Tile Stage 165 // Tile Stage
166 166
167 template<typename XStrategy, typename YStrategy, typename Next> 167 template<typename XStrategy, typename YStrategy, typename Next>
168 class CombinedTileStage final : public SkLinearBitmapPipeline::PointProcessorInt erface { 168 class NearestTileStage final : public SkLinearBitmapPipeline::PointProcessorInte rface {
169 public: 169 public:
170 CombinedTileStage(Next* next, SkISize dimensions) 170 template <typename... Args>
171 NearestTileStage(Next* next, SkISize dimensions)
171 : fNext{next} 172 : fNext{next}
172 , fXStrategy{dimensions.width()} 173 , fXStrategy{dimensions.width()}
173 , fYStrategy{dimensions.height()}{ } 174 , fYStrategy{dimensions.height()}{ }
174 175
175 CombinedTileStage(Next* next, const CombinedTileStage& stage) 176 NearestTileStage(Next* next, const NearestTileStage& stage)
176 : fNext{next} 177 : fNext{next}
177 , fXStrategy{stage.fXStrategy} 178 , fXStrategy{stage.fXStrategy}
178 , fYStrategy{stage.fYStrategy} { } 179 , fYStrategy{stage.fYStrategy} { }
179 180
180 void SK_VECTORCALL pointListFew(int n, Sk4s xs, Sk4s ys) override { 181 void SK_VECTORCALL pointListFew(int n, Sk4s xs, Sk4s ys) override {
181 fXStrategy.tileXPoints(&xs); 182 fXStrategy.tileXPoints(&xs);
182 fYStrategy.tileYPoints(&ys); 183 fYStrategy.tileYPoints(&ys);
183 fNext->pointListFew(n, xs, ys); 184 fNext->pointListFew(n, xs, ys);
184 } 185 }
185 186
186 void SK_VECTORCALL pointList4(Sk4s xs, Sk4s ys) override { 187 void SK_VECTORCALL pointList4(Sk4s xs, Sk4s ys) override {
187 fXStrategy.tileXPoints(&xs); 188 fXStrategy.tileXPoints(&xs);
188 fYStrategy.tileYPoints(&ys); 189 fYStrategy.tileYPoints(&ys);
189 fNext->pointList4(xs, ys); 190 fNext->pointList4(xs, ys);
190 } 191 }
191 192
192 // The span you pass must not be empty. 193 // The span you pass must not be empty.
193 void pointSpan(Span span) override { 194 void pointSpan(Span span) override {
194 SkASSERT(!span.isEmpty()); 195 SkASSERT(!span.isEmpty());
195 SkPoint start; SkScalar length; int count; 196 SkPoint start; SkScalar length; int count;
196 std::tie(start, length, count) = span; 197 std::tie(start, length, count) = span;
197
198 if (span.count() == 1) {
199 this->pointListFew(1, span.startX(), span.startY());
200 return;
201 }
202
203 SkScalar x = X(start); 198 SkScalar x = X(start);
204 SkScalar y = fYStrategy.tileY(Y(start)); 199 SkScalar y = fYStrategy.tileY(Y(start));
205 Span yAdjustedSpan{{x, y}, length, count}; 200 Span yAdjustedSpan{{x, y}, length, count};
206
207 if (!fXStrategy.maybeProcessSpan(yAdjustedSpan, fNext)) { 201 if (!fXStrategy.maybeProcessSpan(yAdjustedSpan, fNext)) {
208 span_fallback(span, this); 202 span_fallback(span, this);
209 } 203 }
210 } 204 }
211 205
212 private: 206 private:
213 Next* const fNext; 207 Next* const fNext;
214 XStrategy fXStrategy; 208 XStrategy fXStrategy;
215 YStrategy fYStrategy; 209 YStrategy fYStrategy;
216 }; 210 };
217 211
218 template <typename XStrategy, typename Next> 212 template<typename XStrategy, typename YStrategy, typename Next>
213 class BilerpTileStage final : public SkLinearBitmapPipeline::PointProcessorInter face {
214 public:
215 template <typename... Args>
216 BilerpTileStage(Next* next, SkISize dimensions)
217 : fNext{next}
218 , fXMax(dimensions.width())
219 , fYMax(dimensions.height())
220 , fXStrategy{dimensions.width()}
221 , fYStrategy{dimensions.height()} { }
222
223 BilerpTileStage(Next* next, const BilerpTileStage& stage)
224 : fNext{next}
225 , fXMax{stage.fXMax}
226 , fYMax{stage.fYMax}
227 , fXStrategy{stage.fXStrategy}
228 , fYStrategy{stage.fYStrategy} { }
229
230 void SK_VECTORCALL pointListFew(int n, Sk4s xs, Sk4s ys) override {
231 fXStrategy.tileXPoints(&xs);
232 fYStrategy.tileYPoints(&ys);
233 // TODO: check to see if xs and ys are in range then just call pointList Few on next.
234 if (n >= 1) this->bilerpPoint(xs[0], ys[0]);
235 if (n >= 2) this->bilerpPoint(xs[1], ys[1]);
236 if (n >= 3) this->bilerpPoint(xs[2], ys[2]);
237 }
238
239 void SK_VECTORCALL pointList4(Sk4s xs, Sk4s ys) override {
240 fXStrategy.tileXPoints(&xs);
241 fYStrategy.tileYPoints(&ys);
242 // TODO: check to see if xs and ys are in range then just call pointList 4 on next.
243 this->bilerpPoint(xs[0], ys[0]);
244 this->bilerpPoint(xs[1], ys[1]);
245 this->bilerpPoint(xs[2], ys[2]);
246 this->bilerpPoint(xs[3], ys[3]);
247 }
248
249 struct Wrapper {
250 void pointSpan(Span span) {
251 processor->breakIntoEdges(span);
252 }
253
254 void repeatSpan(Span span, int32_t repeatCount) {
255 while (repeatCount --> 0) {
256 processor->pointSpan(span);
257 }
258 }
259
260 BilerpTileStage* processor;
261 };
262
263 // The span you pass must not be empty.
264 void pointSpan(Span span) override {
265 SkASSERT(!span.isEmpty());
266
267 Wrapper wrapper = {this};
268 if (!fXStrategy.maybeProcessSpan(span, &wrapper)) {
269 span_fallback(span, this);
270 }
271 }
272
273 private:
274 void bilerpPoint(SkScalar x, SkScalar y) {
275 Sk4f txs = Sk4f{x} + Sk4f{-0.5f, 0.5f, -0.5f, 0.5f};
276 Sk4f tys = Sk4f{y} + Sk4f{-0.5f, -0.5f, 0.5f, 0.5f};
277 fXStrategy.tileXPoints(&txs);
278 fYStrategy.tileYPoints(&tys);
279 fNext->bilerpEdge(txs, tys);
280 }
281
282 void handleEdges(Span span, SkScalar dx) {
283 SkPoint start; SkScalar length; int count;
284 std::tie(start, length, count) = span;
285 SkScalar x = X(start);
286 SkScalar y = Y(start);
287 SkScalar tiledY = fYStrategy.tileY(y);
288 while (count > 0) {
289 this->bilerpPoint(x, tiledY);
290 x += dx;
291 count -= 1;
292 }
293 }
294
295 void yProcessSpan(Span span) {
296 SkScalar tiledY = fYStrategy.tileY(span.startY());
297 if (0.5f <= tiledY && tiledY < fYMax - 0.5f ) {
298 Span tiledSpan{{span.startX(), tiledY}, span.length(), span.count()} ;
299 fNext->pointSpan(tiledSpan);
300 } else {
301 // Convert to the Y0 bilerp sample set by shifting by -0.5f. Then ti le that new y
302 // value and shift it back resulting in the working Y0. Do the same thing with Y1 but
303 // in the opposite direction.
304 SkScalar y0 = fYStrategy.tileY(span.startY() - 0.5f) + 0.5f;
305 SkScalar y1 = fYStrategy.tileY(span.startY() + 0.5f) - 0.5f;
306 Span newSpan{{span.startX(), y0}, span.length(), span.count()};
307 fNext->bilerpSpan(newSpan, y1);
308 }
309 }
310 void breakIntoEdges(Span span) {
311 if (span.count() == 1) {
312 this->bilerpPoint(span.startX(), span.startY());
313 } else if (span.length() == 0) {
314 yProcessSpan(span);
315 } else {
316 SkScalar dx = span.length() / (span.count() - 1);
317 if (span.length() > 0) {
318 Span leftBorder = span.breakAt(0.5f, dx);
319 if (!leftBorder.isEmpty()) {
320 this->handleEdges(leftBorder, dx);
321 }
322 Span center = span.breakAt(fXMax - 0.5f, dx);
323 if (!center.isEmpty()) {
324 this->yProcessSpan(center);
325 }
326
327 if (!span.isEmpty()) {
328 this->handleEdges(span, dx);
329 }
330 } else {
331 Span center = span.breakAt(fXMax + 0.5f, dx);
332 if (!span.isEmpty()) {
333 this->handleEdges(span, dx);
334 }
335 Span leftEdge = center.breakAt(0.5f, dx);
336 if (!center.isEmpty()) {
337 this->yProcessSpan(center);
338 }
339 if (!leftEdge.isEmpty()) {
340 this->handleEdges(leftEdge, dx);
341 }
342
343 }
344 }
345 }
346
347 Next* const fNext;
348 SkScalar fXMax;
349 SkScalar fYMax;
350 XStrategy fXStrategy;
351 YStrategy fYStrategy;
352 };
353
354 template <typename XStrategy, typename YStrategy, typename Next>
355 void make_tile_stage(
356 SkFilterQuality filterQuality, SkISize dimensions,
357 Next* next, SkLinearBitmapPipeline::TileStage* tileStage) {
358 if (filterQuality == kNone_SkFilterQuality) {
359 tileStage->initStage<NearestTileStage<XStrategy, YStrategy, Next>>(next, dimensions);
360 } else {
361 tileStage->initStage<BilerpTileStage<XStrategy, YStrategy, Next>>(next, dimensions);
362 }
363 }
364 template <typename XStrategy>
219 void choose_tiler_ymode( 365 void choose_tiler_ymode(
220 SkShader::TileMode yMode, SkFilterQuality filterQuality, SkISize dimensions, 366 SkShader::TileMode yMode, SkFilterQuality filterQuality, SkISize dimensions,
221 Next* next, 367 SkLinearBitmapPipeline::SampleProcessorInterface* next,
222 SkLinearBitmapPipeline::TileStage* tileStage) { 368 SkLinearBitmapPipeline::TileStage* tileStage) {
223 switch (yMode) { 369 switch (yMode) {
224 case SkShader::kClamp_TileMode: { 370 case SkShader::kClamp_TileMode:
225 using Tiler = CombinedTileStage<XStrategy, YClampStrategy, Next>; 371 make_tile_stage<XStrategy, YClampStrategy>(filterQuality, dimensions , next, tileStage);
226 tileStage->initStage<Tiler>(next, dimensions);
227 break; 372 break;
228 } 373 case SkShader::kRepeat_TileMode:
229 case SkShader::kRepeat_TileMode: { 374 make_tile_stage<XStrategy, YRepeatStrategy>(filterQuality, dimension s, next, tileStage);
230 using Tiler = CombinedTileStage<XStrategy, YRepeatStrategy, Next>;
231 tileStage->initStage<Tiler>(next, dimensions);
232 break; 375 break;
233 } 376 case SkShader::kMirror_TileMode:
234 case SkShader::kMirror_TileMode: { 377 make_tile_stage<XStrategy, YMirrorStrategy>(filterQuality, dimension s, next, tileStage);
235 using Tiler = CombinedTileStage<XStrategy, YMirrorStrategy, Next>;
236 tileStage->initStage<Tiler>(next, dimensions);
237 break; 378 break;
238 }
239 } 379 }
240 }; 380 };
241 381
242 static SkLinearBitmapPipeline::PointProcessorInterface* choose_tiler( 382 static SkLinearBitmapPipeline::PointProcessorInterface* choose_tiler(
243 SkLinearBitmapPipeline::SampleProcessorInterface* next, 383 SkLinearBitmapPipeline::SampleProcessorInterface* next,
244 SkISize dimensions, 384 SkISize dimensions,
245 SkShader::TileMode xMode, 385 SkShader::TileMode xMode,
246 SkShader::TileMode yMode, 386 SkShader::TileMode yMode,
247 SkFilterQuality filterQuality, 387 SkFilterQuality filterQuality,
248 SkScalar dx, 388 SkScalar dx,
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
320 int32_t y = SkScalarTruncToInt(span.startY()); 460 int32_t y = SkScalarTruncToInt(span.startY());
321 const uint32_t* src = this->pixelAddress(x, y); 461 const uint32_t* src = this->pixelAddress(x, y);
322 uint32_t* dest = fDest; 462 uint32_t* dest = fDest;
323 while (repeatCount --> 0) { 463 while (repeatCount --> 0) {
324 memmove(dest, src, span.count() * sizeof(uint32_t)); 464 memmove(dest, src, span.count() * sizeof(uint32_t));
325 dest += span.count(); 465 dest += span.count();
326 } 466 }
327 fDest = dest; 467 fDest = dest;
328 } 468 }
329 469
470 void SK_VECTORCALL bilerpEdge(Sk4s xs, Sk4s ys) override { SkFAIL("Not Imple mented"); }
471
472 void bilerpSpan(Span span, SkScalar y) override { SkFAIL("Not Implemented"); }
473
330 void setDestination(void* dst, int count) override { 474 void setDestination(void* dst, int count) override {
331 fDest = static_cast<uint32_t*>(dst); 475 fDest = static_cast<uint32_t*>(dst);
332 fEnd = fDest + count; 476 fEnd = fDest + count;
333 } 477 }
334 478
335 private: 479 private:
336 const uint32_t* pixelAddress(int32_t x, int32_t y) { 480 const uint32_t* pixelAddress(int32_t x, int32_t y) {
337 return &fSrc[fWidth * y + x]; 481 return &fSrc[fWidth * y + x];
338 } 482 }
339 const uint32_t* const fSrc; 483 const uint32_t* const fSrc;
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
387 int32_t y = (int32_t)span.startY(); 531 int32_t y = (int32_t)span.startY();
388 const uint32_t* beginSpan = this->pixelAddress(x, y); 532 const uint32_t* beginSpan = this->pixelAddress(x, y);
389 533
390 SkOpts::srcover_srgb_srgb(fDest, beginSpan, span.count() * repeatCount, span.count()); 534 SkOpts::srcover_srgb_srgb(fDest, beginSpan, span.count() * repeatCount, span.count());
391 535
392 fDest += span.count() * repeatCount; 536 fDest += span.count() * repeatCount;
393 537
394 SkASSERT(fDest <= fEnd); 538 SkASSERT(fDest <= fEnd);
395 } 539 }
396 540
541 void SK_VECTORCALL bilerpEdge(Sk4s xs, Sk4s ys) override { SkFAIL("Not Imple mented"); }
542
543 void bilerpSpan(Span span, SkScalar y) override { SkFAIL("Not Implemented"); }
544
397 void setDestination(void* dst, int count) override { 545 void setDestination(void* dst, int count) override {
398 SkASSERT(count > 0); 546 SkASSERT(count > 0);
399 fDest = static_cast<uint32_t*>(dst); 547 fDest = static_cast<uint32_t*>(dst);
400 fEnd = fDest + count; 548 fEnd = fDest + count;
401 } 549 }
402 550
403 private: 551 private:
404 const uint32_t* pixelAddress(int32_t x, int32_t y) { 552 const uint32_t* pixelAddress(int32_t x, int32_t y) {
405 return &fSrc[fWidth * y + x]; 553 return &fSrc[fWidth * y + x];
406 } 554 }
(...skipping 20 matching lines...) Expand all
427 using PA = PixelAccessor<colorType, kSRGB_SkGammaType>; 575 using PA = PixelAccessor<colorType, kSRGB_SkGammaType>;
428 accessor->init<PA>(srcPixmap); 576 accessor->init<PA>(srcPixmap);
429 return accessor->get(); 577 return accessor->get();
430 } else { 578 } else {
431 using PA = PixelAccessor<colorType, kLinear_SkGammaType>; 579 using PA = PixelAccessor<colorType, kLinear_SkGammaType>;
432 accessor->init<PA>(srcPixmap); 580 accessor->init<PA>(srcPixmap);
433 return accessor->get(); 581 return accessor->get();
434 } 582 }
435 } 583 }
436 584
437 static SkLinearBitmapPipeline::PixelAccessorInterface* choose_pixel_accessor( 585 template<template <typename, typename> class Sampler>
586 static SkLinearBitmapPipeline::SampleProcessorInterface* choose_pixel_sampler_ba se(
587 Blender* next,
438 const SkPixmap& srcPixmap, 588 const SkPixmap& srcPixmap,
439 const SkColor A8TintColor, 589 const SkColor A8TintColor,
590 SkLinearBitmapPipeline::SampleStage* sampleStage,
440 SkLinearBitmapPipeline::Accessor* accessor) 591 SkLinearBitmapPipeline::Accessor* accessor)
441 { 592 {
442 const SkImageInfo& imageInfo = srcPixmap.info(); 593 const SkImageInfo& imageInfo = srcPixmap.info();
443 594
444 SkLinearBitmapPipeline::PixelAccessorInterface* pixelAccessor = nullptr; 595 SkLinearBitmapPipeline::PixelAccessorInterface* pixelAccessor = nullptr;
445 switch (imageInfo.colorType()) { 596 switch (imageInfo.colorType()) {
446 case kAlpha_8_SkColorType: { 597 case kAlpha_8_SkColorType: {
447 using PA = PixelAccessor<kAlpha_8_SkColorType, kLinear_SkGammaTy pe>; 598 using PA = PixelAccessor<kAlpha_8_SkColorType, kLinear_SkGammaTy pe>;
448 accessor->init<PA>(srcPixmap, A8TintColor); 599 accessor->init<PA>(srcPixmap, A8TintColor);
449 pixelAccessor = accessor->get(); 600 pixelAccessor = accessor->get();
(...skipping 21 matching lines...) Expand all
471 using PA = PixelAccessor<kRGBA_F16_SkColorType, kLinear_SkGammaT ype>; 622 using PA = PixelAccessor<kRGBA_F16_SkColorType, kLinear_SkGammaT ype>;
472 accessor->init<PA>(srcPixmap); 623 accessor->init<PA>(srcPixmap);
473 pixelAccessor = accessor->get(); 624 pixelAccessor = accessor->get();
474 } 625 }
475 break; 626 break;
476 default: 627 default:
477 SkFAIL("Not implemented. Unsupported src"); 628 SkFAIL("Not implemented. Unsupported src");
478 break; 629 break;
479 } 630 }
480 631
481 return pixelAccessor; 632 using S = Sampler<PixelAccessorShim, Blender>;
633 sampleStage->initStage<S>(next, pixelAccessor);
634 return sampleStage->get();
482 } 635 }
483 636
484 SkLinearBitmapPipeline::SampleProcessorInterface* choose_pixel_sampler( 637 SkLinearBitmapPipeline::SampleProcessorInterface* choose_pixel_sampler(
485 Blender* next, 638 Blender* next,
486 SkFilterQuality filterQuality, 639 SkFilterQuality filterQuality,
487 SkShader::TileMode xTile, SkShader::TileMode yTile,
488 const SkPixmap& srcPixmap, 640 const SkPixmap& srcPixmap,
489 const SkColor A8TintColor, 641 const SkColor A8TintColor,
490 SkLinearBitmapPipeline::SampleStage* sampleStage, 642 SkLinearBitmapPipeline::SampleStage* sampleStage,
491 SkLinearBitmapPipeline::Accessor* accessor) { 643 SkLinearBitmapPipeline::Accessor* accessor) {
492 const SkImageInfo& imageInfo = srcPixmap.info(); 644 const SkImageInfo& imageInfo = srcPixmap.info();
493 SkISize dimensions = imageInfo.dimensions();
494 645
495 // Special case samplers with fully expanded templates 646 // Special case samplers with fully expanded templates
496 if (imageInfo.gammaCloseToSRGB()) { 647 if (imageInfo.gammaCloseToSRGB()) {
497 if (filterQuality == kNone_SkFilterQuality) { 648 if (filterQuality == kNone_SkFilterQuality) {
498 switch (imageInfo.colorType()) { 649 switch (imageInfo.colorType()) {
499 case kN32_SkColorType: { 650 case kN32_SkColorType: {
500 using S = 651 using S =
501 NearestNeighborSampler< 652 NearestNeighborSampler<
502 PixelAccessor<kN32_SkColorType, kSRGB_SkGammaType>, Blen der>; 653 PixelAccessor<kN32_SkColorType, kSRGB_SkGammaType>, Blen der>;
503 sampleStage->initStage<S>(next, srcPixmap); 654 sampleStage->initStage<S>(next, srcPixmap);
504 return sampleStage->get(); 655 return sampleStage->get();
505 } 656 }
506 case kIndex_8_SkColorType: { 657 case kIndex_8_SkColorType: {
507 using S = 658 using S =
508 NearestNeighborSampler< 659 NearestNeighborSampler<
509 PixelAccessor<kIndex_8_SkColorType, kSRGB_SkGammaType>, Blender>; 660 PixelAccessor<kIndex_8_SkColorType, kSRGB_SkGammaType>, Blender>;
510 sampleStage->initStage<S>(next, srcPixmap); 661 sampleStage->initStage<S>(next, srcPixmap);
511 return sampleStage->get(); 662 return sampleStage->get();
512 } 663 }
513 default: 664 default:
514 break; 665 break;
515 } 666 }
516 } else { 667 } else {
517 switch (imageInfo.colorType()) { 668 switch (imageInfo.colorType()) {
518 case kN32_SkColorType: { 669 case kN32_SkColorType: {
519 using S = 670 using S =
520 BilerpSampler< 671 BilerpSampler<
521 PixelAccessor<kN32_SkColorType, kSRGB_SkGammaType>, Blen der>; 672 PixelAccessor<kN32_SkColorType, kSRGB_SkGammaType>, Blen der>;
522 sampleStage->initStage<S>(next, dimensions, xTile, yTile, sr cPixmap); 673 sampleStage->initStage<S>(next, srcPixmap);
523 return sampleStage->get(); 674 return sampleStage->get();
524 } 675 }
525 case kIndex_8_SkColorType: { 676 case kIndex_8_SkColorType: {
526 using S = 677 using S =
527 BilerpSampler< 678 BilerpSampler<
528 PixelAccessor<kIndex_8_SkColorType, kSRGB_SkGammaType>, Blender>; 679 PixelAccessor<kIndex_8_SkColorType, kSRGB_SkGammaType>, Blender>;
529 sampleStage->initStage<S>(next, dimensions, xTile, yTile, sr cPixmap); 680 sampleStage->initStage<S>(next, srcPixmap);
530 return sampleStage->get(); 681 return sampleStage->get();
531 } 682 }
532 default: 683 default:
533 break; 684 break;
534 } 685 }
535 } 686 }
536 } 687 }
537 688
538 auto pixelAccessor = choose_pixel_accessor(srcPixmap, A8TintColor, accessor) ;
539 // General cases. 689 // General cases.
540 if (filterQuality == kNone_SkFilterQuality) { 690 if (filterQuality == kNone_SkFilterQuality) {
541 using S = NearestNeighborSampler<PixelAccessorShim, Blender>; 691 return choose_pixel_sampler_base<NearestNeighborSampler>(
542 sampleStage->initStage<S>(next, pixelAccessor); 692 next, srcPixmap, A8TintColor, sampleStage, accessor);
543 } else { 693 } else {
544 using S = BilerpSampler<PixelAccessorShim, Blender>; 694 return choose_pixel_sampler_base<BilerpSampler>(
545 sampleStage->initStage<S>(next, dimensions, xTile, yTile, pixelAccessor) ; 695 next, srcPixmap, A8TintColor, sampleStage, accessor);
546 } 696 }
547 return sampleStage->get();
548 } 697 }
549 698
550 //////////////////////////////////////////////////////////////////////////////// //////////////////// 699 //////////////////////////////////////////////////////////////////////////////// ////////////////////
551 // Pixel Blender Stage 700 // Pixel Blender Stage
552 template <SkAlphaType alphaType> 701 template <SkAlphaType alphaType>
553 class SrcFPPixel final : public SkLinearBitmapPipeline::BlendProcessorInterface { 702 class SrcFPPixel final : public SkLinearBitmapPipeline::BlendProcessorInterface {
554 public: 703 public:
555 SrcFPPixel(float postAlpha) : fPostAlpha{postAlpha} { } 704 SrcFPPixel(float postAlpha) : fPostAlpha{postAlpha} { }
556 SrcFPPixel(const SrcFPPixel& Blender) : fPostAlpha(Blender.fPostAlpha) {} 705 SrcFPPixel(const SrcFPPixel& Blender) : fPostAlpha(Blender.fPostAlpha) {}
557 void SK_VECTORCALL blendPixel(Sk4f pixel) override { 706 void SK_VECTORCALL blendPixel(Sk4f pixel) override {
558 SkASSERT(fDst + 1 <= fEnd ); 707 SkASSERT(fDst + 1 <= fEnd );
559 this->srcPixel(fDst, pixel, 0); 708 SrcPixel(fDst, pixel, 0);
560 fDst += 1; 709 fDst += 1;
561 } 710 }
562 711
563 void SK_VECTORCALL blend4Pixels(Sk4f p0, Sk4f p1, Sk4f p2, Sk4f p3) override { 712 void SK_VECTORCALL blend4Pixels(Sk4f p0, Sk4f p1, Sk4f p2, Sk4f p3) override {
564 SkASSERT(fDst + 4 <= fEnd); 713 SkASSERT(fDst + 4 <= fEnd);
565 SkPM4f* dst = fDst; 714 SkPM4f* dst = fDst;
566 this->srcPixel(dst, p0, 0); 715 SrcPixel(dst, p0, 0);
567 this->srcPixel(dst, p1, 1); 716 SrcPixel(dst, p1, 1);
568 this->srcPixel(dst, p2, 2); 717 SrcPixel(dst, p2, 2);
569 this->srcPixel(dst, p3, 3); 718 SrcPixel(dst, p3, 3);
570 fDst += 4; 719 fDst += 4;
571 } 720 }
572 721
573 void setDestination(void* dst, int count) override { 722 void setDestination(void* dst, int count) override {
574 fDst = static_cast<SkPM4f*>(dst); 723 fDst = static_cast<SkPM4f*>(dst);
575 fEnd = fDst + count; 724 fEnd = fDst + count;
576 } 725 }
577 726
578 private: 727 private:
579 void SK_VECTORCALL srcPixel(SkPM4f* dst, Sk4f pixel, int index) { 728 void SK_VECTORCALL SrcPixel(SkPM4f* dst, Sk4f pixel, int index) {
580 check_pixel(pixel);
581
582 Sk4f newPixel = pixel; 729 Sk4f newPixel = pixel;
583 if (alphaType == kUnpremul_SkAlphaType) { 730 if (alphaType == kUnpremul_SkAlphaType) {
584 newPixel = Premultiply(pixel); 731 newPixel = Premultiply(pixel);
585 } 732 }
586 newPixel = newPixel * fPostAlpha; 733 newPixel = newPixel * fPostAlpha;
587 newPixel.store(dst + index); 734 newPixel.store(dst + index);
588 } 735 }
589 static Sk4f SK_VECTORCALL Premultiply(Sk4f pixel) { 736 static Sk4f SK_VECTORCALL Premultiply(Sk4f pixel) {
590 float alpha = pixel[3]; 737 float alpha = pixel[3];
591 return pixel * Sk4f{alpha, alpha, alpha, 1.0f}; 738 return pixel * Sk4f{alpha, alpha, alpha, 1.0f};
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
643 SkAlphaType alphaType = srcImageInfo.alphaType(); 790 SkAlphaType alphaType = srcImageInfo.alphaType();
644 if (srcPixmap.colorType() == kIndex_8_SkColorType) { 791 if (srcPixmap.colorType() == kIndex_8_SkColorType) {
645 alphaType = kUnpremul_SkAlphaType; 792 alphaType = kUnpremul_SkAlphaType;
646 } 793 }
647 794
648 float postAlpha = SkColorGetA(paintColor) * (1.0f / 255.0f); 795 float postAlpha = SkColorGetA(paintColor) * (1.0f / 255.0f);
649 // As the stages are built, the chooser function may skip a stage. For examp le, with the 796 // As the stages are built, the chooser function may skip a stage. For examp le, with the
650 // identity matrix, the matrix stage is skipped, and the tilerStage is the f irst stage. 797 // identity matrix, the matrix stage is skipped, and the tilerStage is the f irst stage.
651 auto blenderStage = choose_blender_for_shading(alphaType, postAlpha, &fBlend erStage); 798 auto blenderStage = choose_blender_for_shading(alphaType, postAlpha, &fBlend erStage);
652 auto samplerStage = choose_pixel_sampler( 799 auto samplerStage = choose_pixel_sampler(
653 blenderStage, filterQuality, xTile, yTile, 800 blenderStage, filterQuality, srcPixmap, paintColor, &fSampleStage, &fAcc essor);
654 srcPixmap, paintColor, &fSampleStage, &fAccessor);
655 auto tilerStage = choose_tiler(samplerStage, dimensions, xTile, yTile, 801 auto tilerStage = choose_tiler(samplerStage, dimensions, xTile, yTile,
656 filterQuality, dx, &fTileStage); 802 filterQuality, dx, &fTileStage);
657 fFirstStage = choose_matrix(tilerStage, adjustedInverse, &fMatrixStage ); 803 fFirstStage = choose_matrix(tilerStage, adjustedInverse, &fMatrixStage );
658 fLastStage = blenderStage; 804 fLastStage = blenderStage;
659 } 805 }
660 806
661 bool SkLinearBitmapPipeline::ClonePipelineForBlitting( 807 bool SkLinearBitmapPipeline::ClonePipelineForBlitting(
662 SkEmbeddableLinearPipeline* pipelineStorage, 808 SkEmbeddableLinearPipeline* pipelineStorage,
663 const SkLinearBitmapPipeline& pipeline, 809 const SkLinearBitmapPipeline& pipeline,
664 SkMatrix::TypeMask matrixMask, 810 SkMatrix::TypeMask matrixMask,
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
730 void SkLinearBitmapPipeline::blitSpan(int x, int y, void* dst, int count) { 876 void SkLinearBitmapPipeline::blitSpan(int x, int y, void* dst, int count) {
731 SkASSERT(count > 0); 877 SkASSERT(count > 0);
732 fLastStage->setDestination(dst, count); 878 fLastStage->setDestination(dst, count);
733 879
734 // The count and length arguments start out in a precise relation in order t o keep the 880 // The count and length arguments start out in a precise relation in order t o keep the
735 // math correct through the different stages. Count is the number of pixel t o produce. 881 // math correct through the different stages. Count is the number of pixel t o produce.
736 // Since the code samples at pixel centers, length is the distance from the center of the 882 // Since the code samples at pixel centers, length is the distance from the center of the
737 // first pixel to the center of the last pixel. This implies that length is count-1. 883 // first pixel to the center of the last pixel. This implies that length is count-1.
738 fFirstStage->pointSpan(Span{{x + 0.5f, y + 0.5f}, count - 1.0f, count}); 884 fFirstStage->pointSpan(Span{{x + 0.5f, y + 0.5f}, count - 1.0f, count});
739 } 885 }
OLDNEW
« no previous file with comments | « src/core/SkLinearBitmapPipeline.h ('k') | src/core/SkLinearBitmapPipeline_core.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698