OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2016 Google Inc. | 2 * Copyright 2016 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkLinearBitmapPipeline.h" | 8 #include "SkLinearBitmapPipeline.h" |
9 | 9 |
10 #include "SkPM4f.h" | 10 #include "SkPM4f.h" |
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
231 this->bilerpPoint(xs[1], ys[1]); | 231 this->bilerpPoint(xs[1], ys[1]); |
232 this->bilerpPoint(xs[2], ys[2]); | 232 this->bilerpPoint(xs[2], ys[2]); |
233 this->bilerpPoint(xs[3], ys[3]); | 233 this->bilerpPoint(xs[3], ys[3]); |
234 } | 234 } |
235 | 235 |
236 struct Wrapper { | 236 struct Wrapper { |
237 void pointSpan(Span span) { | 237 void pointSpan(Span span) { |
238 processor->breakIntoEdges(span); | 238 processor->breakIntoEdges(span); |
239 } | 239 } |
240 | 240 |
241 void repeatSpan(Span span, int32_t repeatCount) { | |
242 while (repeatCount --> 0) { | |
243 processor->pointSpan(span); | |
244 } | |
245 } | |
246 | |
247 BilerpTileStage* processor; | 241 BilerpTileStage* processor; |
248 }; | 242 }; |
249 | 243 |
250 // The span you pass must not be empty. | 244 // The span you pass must not be empty. |
251 void pointSpan(Span span) override { | 245 void pointSpan(Span span) override { |
252 SkASSERT(!span.isEmpty()); | 246 SkASSERT(!span.isEmpty()); |
253 | 247 |
254 Wrapper wrapper = {this}; | 248 Wrapper wrapper = {this}; |
255 if (!fXStrategy.maybeProcessSpan(span, &wrapper)) { | 249 if (!fXStrategy.maybeProcessSpan(span, &wrapper)) { |
256 span_fallback(span, this); | 250 span_fallback(span, this); |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
363 break; | 357 break; |
364 } | 358 } |
365 }; | 359 }; |
366 | 360 |
367 static SkLinearBitmapPipeline::PointProcessorInterface* choose_tiler( | 361 static SkLinearBitmapPipeline::PointProcessorInterface* choose_tiler( |
368 SkLinearBitmapPipeline::SampleProcessorInterface* next, | 362 SkLinearBitmapPipeline::SampleProcessorInterface* next, |
369 SkISize dimensions, | 363 SkISize dimensions, |
370 SkShader::TileMode xMode, | 364 SkShader::TileMode xMode, |
371 SkShader::TileMode yMode, | 365 SkShader::TileMode yMode, |
372 SkFilterQuality filterQuality, | 366 SkFilterQuality filterQuality, |
373 SkScalar dx, | 367 SkLinearBitmapPipeline::TileStage* tileStage) { |
374 SkLinearBitmapPipeline::TileStage* tileStage) | |
375 { | |
376 switch (xMode) { | 368 switch (xMode) { |
377 case SkShader::kClamp_TileMode: | 369 case SkShader::kClamp_TileMode: |
378 choose_tiler_ymode<XClampStrategy>(yMode, filterQuality, dimensions,
next, tileStage); | 370 choose_tiler_ymode<XClampStrategy>(yMode, filterQuality, dimensions,
next, tileStage); |
379 break; | 371 break; |
380 case SkShader::kRepeat_TileMode: | 372 case SkShader::kRepeat_TileMode: |
381 if (dx == 1.0f && filterQuality == kNone_SkFilterQuality) { | 373 choose_tiler_ymode<XRepeatStrategy>(yMode, filterQuality, dimensions
, next, tileStage); |
382 choose_tiler_ymode<XRepeatUnitScaleStrategy>( | |
383 yMode, kNone_SkFilterQuality, dimensions, next, tileStage); | |
384 } else { | |
385 choose_tiler_ymode<XRepeatStrategy>( | |
386 yMode, filterQuality, dimensions, next, tileStage); | |
387 } | |
388 break; | 374 break; |
389 case SkShader::kMirror_TileMode: | 375 case SkShader::kMirror_TileMode: |
390 choose_tiler_ymode<XMirrorStrategy>(yMode, filterQuality, dimensions
, next, tileStage); | 376 choose_tiler_ymode<XMirrorStrategy>(yMode, filterQuality, dimensions
, next, tileStage); |
391 break; | 377 break; |
392 } | 378 } |
393 | 379 |
394 return tileStage->get(); | 380 return tileStage->get(); |
395 } | 381 } |
396 | 382 |
397 | 383 |
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
595 if (inverse.getScaleX() >= 0.0f) { | 581 if (inverse.getScaleX() >= 0.0f) { |
596 adjustedInverse.setTranslateX( | 582 adjustedInverse.setTranslateX( |
597 nextafterf(inverse.getTranslateX(), std::floor(inverse.getTransl
ateX()))); | 583 nextafterf(inverse.getTranslateX(), std::floor(inverse.getTransl
ateX()))); |
598 } | 584 } |
599 if (inverse.getScaleY() >= 0.0f) { | 585 if (inverse.getScaleY() >= 0.0f) { |
600 adjustedInverse.setTranslateY( | 586 adjustedInverse.setTranslateY( |
601 nextafterf(inverse.getTranslateY(), std::floor(inverse.getTransl
ateY()))); | 587 nextafterf(inverse.getTranslateY(), std::floor(inverse.getTransl
ateY()))); |
602 } | 588 } |
603 } | 589 } |
604 | 590 |
605 SkScalar dx = adjustedInverse.getScaleX(); | |
606 | |
607 // If it is an index 8 color type, the sampler converts to unpremul for bett
er fidelity. | 591 // If it is an index 8 color type, the sampler converts to unpremul for bett
er fidelity. |
608 SkAlphaType alphaType = srcImageInfo.alphaType(); | 592 SkAlphaType alphaType = srcImageInfo.alphaType(); |
609 if (srcPixmap.colorType() == kIndex_8_SkColorType) { | 593 if (srcPixmap.colorType() == kIndex_8_SkColorType) { |
610 alphaType = kUnpremul_SkAlphaType; | 594 alphaType = kUnpremul_SkAlphaType; |
611 } | 595 } |
612 | 596 |
613 // As the stages are built, the chooser function may skip a stage. For examp
le, with the | 597 // As the stages are built, the chooser function may skip a stage. For examp
le, with the |
614 // identity matrix, the matrix stage is skipped, and the tilerStage is the f
irst stage. | 598 // identity matrix, the matrix stage is skipped, and the tilerStage is the f
irst stage. |
615 auto placementStage = choose_pixel_placer(alphaType, postAlpha, &fPixelStage
); | 599 auto placementStage = choose_pixel_placer(alphaType, postAlpha, &fPixelStage
); |
616 auto samplerStage = choose_pixel_sampler(placementStage, | 600 auto samplerStage = choose_pixel_sampler(placementStage, |
617 filterQuality, srcPixmap, &fSampl
eStage); | 601 filterQuality, srcPixmap, &fSampl
eStage); |
618 auto tilerStage = choose_tiler(samplerStage, | 602 auto tilerStage = choose_tiler(samplerStage, |
619 dimensions, xTile, yTile, filterQuality,
dx, &fTiler); | 603 dimensions, xTile, yTile, filterQuality,
&fTiler); |
620 fFirstStage = choose_matrix(tilerStage, adjustedInverse, &fMatrixSta
ge); | 604 fFirstStage = choose_matrix(tilerStage, adjustedInverse, &fMatrixSta
ge); |
621 } | 605 } |
622 | 606 |
623 void SkLinearBitmapPipeline::shadeSpan4f(int x, int y, SkPM4f* dst, int count) { | 607 void SkLinearBitmapPipeline::shadeSpan4f(int x, int y, SkPM4f* dst, int count) { |
624 SkASSERT(count > 0); | 608 SkASSERT(count > 0); |
625 fPixelStage->setDestination(dst); | 609 fPixelStage->setDestination(dst); |
626 // The count and length arguments start out in a precise relation in order t
o keep the | 610 // The count and length arguments start out in a precise relation in order t
o keep the |
627 // math correct through the different stages. Count is the number of pixel t
o produce. | 611 // math correct through the different stages. Count is the number of pixel t
o produce. |
628 // Since the code samples at pixel centers, length is the distance from the
center of the | 612 // Since the code samples at pixel centers, length is the distance from the
center of the |
629 // first pixel to the center of the last pixel. This implies that length is
count-1. | 613 // first pixel to the center of the last pixel. This implies that length is
count-1. |
630 fFirstStage->pointSpan(Span{{x + 0.5f, y + 0.5f}, count - 1.0f, count}); | 614 fFirstStage->pointSpan(Span{{x + 0.5f, y + 0.5f}, count - 1.0f, count}); |
631 } | 615 } |
OLD | NEW |