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 <algorithm> | 10 #include <algorithm> |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
81 // maybeProcessSpan - returns false if it can not process the span and needs t
o fallback to | 81 // maybeProcessSpan - returns false if it can not process the span and needs t
o fallback to |
82 // point lists for processing. | 82 // point lists for processing. |
83 template<typename Strategy, typename Next> | 83 template<typename Strategy, typename Next> |
84 class MatrixStage final : public SkLinearBitmapPipeline::PointProcessorInterface
{ | 84 class MatrixStage final : public SkLinearBitmapPipeline::PointProcessorInterface
{ |
85 public: | 85 public: |
86 template <typename... Args> | 86 template <typename... Args> |
87 MatrixStage(Next* next, Args&&... args) | 87 MatrixStage(Next* next, Args&&... args) |
88 : fNext{next} | 88 : fNext{next} |
89 , fStrategy{std::forward<Args>(args)...}{ } | 89 , fStrategy{std::forward<Args>(args)...}{ } |
90 | 90 |
91 MatrixStage(Next* next, const MatrixStage& stage) | 91 MatrixStage(Next* next, MatrixStage* stage) |
92 : fNext{next} | 92 : fNext{next} |
93 , fStrategy{stage.fStrategy} { } | 93 , fStrategy{stage->fStrategy} { } |
94 | 94 |
95 void SK_VECTORCALL pointListFew(int n, Sk4s xs, Sk4s ys) override { | 95 void SK_VECTORCALL pointListFew(int n, Sk4s xs, Sk4s ys) override { |
96 fStrategy.processPoints(&xs, &ys); | 96 fStrategy.processPoints(&xs, &ys); |
97 fNext->pointListFew(n, xs, ys); | 97 fNext->pointListFew(n, xs, ys); |
98 } | 98 } |
99 | 99 |
100 void SK_VECTORCALL pointList4(Sk4s xs, Sk4s ys) override { | 100 void SK_VECTORCALL pointList4(Sk4s xs, Sk4s ys) override { |
101 fStrategy.processPoints(&xs, &ys); | 101 fStrategy.processPoints(&xs, &ys); |
102 fNext->pointList4(xs, ys); | 102 fNext->pointList4(xs, ys); |
103 } | 103 } |
(...skipping 17 matching lines...) Expand all Loading... |
121 template <typename Next = SkLinearBitmapPipeline::PointProcessorInterface> | 121 template <typename Next = SkLinearBitmapPipeline::PointProcessorInterface> |
122 using ScaleMatrix = MatrixStage<ScaleMatrixStrategy, Next>; | 122 using ScaleMatrix = MatrixStage<ScaleMatrixStrategy, Next>; |
123 | 123 |
124 template <typename Next = SkLinearBitmapPipeline::PointProcessorInterface> | 124 template <typename Next = SkLinearBitmapPipeline::PointProcessorInterface> |
125 using AffineMatrix = MatrixStage<AffineMatrixStrategy, Next>; | 125 using AffineMatrix = MatrixStage<AffineMatrixStrategy, Next>; |
126 | 126 |
127 template <typename Next = SkLinearBitmapPipeline::PointProcessorInterface> | 127 template <typename Next = SkLinearBitmapPipeline::PointProcessorInterface> |
128 using PerspectiveMatrix = MatrixStage<PerspectiveMatrixStrategy, Next>; | 128 using PerspectiveMatrix = MatrixStage<PerspectiveMatrixStrategy, Next>; |
129 | 129 |
130 | 130 |
131 static SkLinearBitmapPipeline::PointProcessorInterface* choose_matrix( | |
132 SkLinearBitmapPipeline::PointProcessorInterface* next, | |
133 const SkMatrix& inverse, | |
134 SkLinearBitmapPipeline::MatrixStage* matrixProc) { | |
135 if (inverse.hasPerspective()) { | |
136 matrixProc->initStage<PerspectiveMatrix<>>( | |
137 next, | |
138 SkVector{inverse.getTranslateX(), inverse.getTranslateY()}, | |
139 SkVector{inverse.getScaleX(), inverse.getScaleY()}, | |
140 SkVector{inverse.getSkewX(), inverse.getSkewY()}, | |
141 SkVector{inverse.getPerspX(), inverse.getPerspY()}, | |
142 inverse.get(SkMatrix::kMPersp2)); | |
143 } else if (inverse.getSkewX() != 0.0f || inverse.getSkewY() != 0.0f) { | |
144 matrixProc->initStage<AffineMatrix<>>( | |
145 next, | |
146 SkVector{inverse.getTranslateX(), inverse.getTranslateY()}, | |
147 SkVector{inverse.getScaleX(), inverse.getScaleY()}, | |
148 SkVector{inverse.getSkewX(), inverse.getSkewY()}); | |
149 } else if (inverse.getScaleX() != 1.0f || inverse.getScaleY() != 1.0f) { | |
150 matrixProc->initStage<ScaleMatrix<>>( | |
151 next, | |
152 SkVector{inverse.getTranslateX(), inverse.getTranslateY()}, | |
153 SkVector{inverse.getScaleX(), inverse.getScaleY()}); | |
154 } else if (inverse.getTranslateX() != 0.0f || inverse.getTranslateY() != 0.0
f) { | |
155 matrixProc->initStage<TranslateMatrix<>>( | |
156 next, | |
157 SkVector{inverse.getTranslateX(), inverse.getTranslateY()}); | |
158 } else { | |
159 return next; | |
160 } | |
161 return matrixProc->get(); | |
162 } | |
163 | |
164 ////////////////////////////////////////////////////////////////////////////////
//////////////////// | 131 ////////////////////////////////////////////////////////////////////////////////
//////////////////// |
165 // Tile Stage | 132 // Tile Stage |
166 | 133 |
167 template<typename XStrategy, typename YStrategy, typename Next> | 134 template<typename XStrategy, typename YStrategy, typename Next> |
168 class CombinedTileStage final : public SkLinearBitmapPipeline::PointProcessorInt
erface { | 135 class CombinedTileStage final : public SkLinearBitmapPipeline::PointProcessorInt
erface { |
169 public: | 136 public: |
170 CombinedTileStage(Next* next, SkISize dimensions) | 137 CombinedTileStage(Next* next, SkISize dimensions) |
171 : fNext{next} | 138 : fNext{next} |
172 , fXStrategy{dimensions.width()} | 139 , fXStrategy{dimensions.width()} |
173 , fYStrategy{dimensions.height()}{ } | 140 , fYStrategy{dimensions.height()}{ } |
(...skipping 477 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
651 | 618 |
652 float postAlpha = SkColorGetA(paintColor) * (1.0f / 255.0f); | 619 float postAlpha = SkColorGetA(paintColor) * (1.0f / 255.0f); |
653 // As the stages are built, the chooser function may skip a stage. For examp
le, with the | 620 // As the stages are built, the chooser function may skip a stage. For examp
le, with the |
654 // identity matrix, the matrix stage is skipped, and the tilerStage is the f
irst stage. | 621 // identity matrix, the matrix stage is skipped, and the tilerStage is the f
irst stage. |
655 auto blenderStage = choose_blender_for_shading(alphaType, postAlpha, &fBlend
erStage); | 622 auto blenderStage = choose_blender_for_shading(alphaType, postAlpha, &fBlend
erStage); |
656 auto samplerStage = choose_pixel_sampler( | 623 auto samplerStage = choose_pixel_sampler( |
657 blenderStage, filterQuality, xTile, yTile, | 624 blenderStage, filterQuality, xTile, yTile, |
658 srcPixmap, paintColor, &fSampleStage, &fAccessor); | 625 srcPixmap, paintColor, &fSampleStage, &fAccessor); |
659 auto tilerStage = choose_tiler(samplerStage, dimensions, xTile, yTile, | 626 auto tilerStage = choose_tiler(samplerStage, dimensions, xTile, yTile, |
660 filterQuality, dx, &fTileStage); | 627 filterQuality, dx, &fTileStage); |
661 fFirstStage = choose_matrix(tilerStage, adjustedInverse, &fMatrixStage
); | 628 fFirstStage = ChooseMatrix(tilerStage, adjustedInverse); |
662 fLastStage = blenderStage; | 629 fLastStage = blenderStage; |
663 } | 630 } |
664 | 631 |
665 bool SkLinearBitmapPipeline::ClonePipelineForBlitting( | 632 bool SkLinearBitmapPipeline::ClonePipelineForBlitting( |
666 SkEmbeddableLinearPipeline* pipelineStorage, | 633 SkEmbeddableLinearPipeline* pipelineStorage, |
667 const SkLinearBitmapPipeline& pipeline, | 634 const SkLinearBitmapPipeline& pipeline, |
668 SkMatrix::TypeMask matrixMask, | 635 SkMatrix::TypeMask matrixMask, |
669 SkShader::TileMode xTileMode, | 636 SkShader::TileMode xTileMode, |
670 SkShader::TileMode yTileMode, | 637 SkShader::TileMode yTileMode, |
671 SkFilterQuality filterQuality, | 638 SkFilterQuality filterQuality, |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
714 fLastStage = fSampleStage.getInterface<DestinationInterface, RGBA8888Uni
tRepeatSrc>(); | 681 fLastStage = fSampleStage.getInterface<DestinationInterface, RGBA8888Uni
tRepeatSrc>(); |
715 } else { | 682 } else { |
716 fSampleStage.initSink<RGBA8888UnitRepeatSrcOver>( | 683 fSampleStage.initSink<RGBA8888UnitRepeatSrcOver>( |
717 srcPixmap.writable_addr32(0, 0), srcPixmap.rowBytes() / 4); | 684 srcPixmap.writable_addr32(0, 0), srcPixmap.rowBytes() / 4); |
718 fLastStage = fSampleStage.getInterface<DestinationInterface, RGBA8888Uni
tRepeatSrcOver>(); | 685 fLastStage = fSampleStage.getInterface<DestinationInterface, RGBA8888Uni
tRepeatSrcOver>(); |
719 } | 686 } |
720 | 687 |
721 auto sampleStage = fSampleStage.get(); | 688 auto sampleStage = fSampleStage.get(); |
722 auto tilerStage = pipeline.fTileStage.cloneStageTo(sampleStage, &fTileStage)
; | 689 auto tilerStage = pipeline.fTileStage.cloneStageTo(sampleStage, &fTileStage)
; |
723 tilerStage = (tilerStage != nullptr) ? tilerStage : sampleStage; | 690 tilerStage = (tilerStage != nullptr) ? tilerStage : sampleStage; |
724 auto matrixStage = pipeline.fMatrixStage.cloneStageTo(tilerStage, &fMatrixSt
age); | 691 auto matrixStage = pipeline.fMatrixStageCloner(tilerStage, &fMemory); |
725 matrixStage = (matrixStage != nullptr) ? matrixStage : tilerStage; | |
726 fFirstStage = matrixStage; | 692 fFirstStage = matrixStage; |
727 } | 693 } |
728 | 694 |
729 void SkLinearBitmapPipeline::shadeSpan4f(int x, int y, SkPM4f* dst, int count) { | 695 void SkLinearBitmapPipeline::shadeSpan4f(int x, int y, SkPM4f* dst, int count) { |
730 SkASSERT(count > 0); | 696 SkASSERT(count > 0); |
731 this->blitSpan(x, y, dst, count); | 697 this->blitSpan(x, y, dst, count); |
732 } | 698 } |
733 | 699 |
734 void SkLinearBitmapPipeline::blitSpan(int x, int y, void* dst, int count) { | 700 void SkLinearBitmapPipeline::blitSpan(int x, int y, void* dst, int count) { |
735 SkASSERT(count > 0); | 701 SkASSERT(count > 0); |
736 fLastStage->setDestination(dst, count); | 702 fLastStage->setDestination(dst, count); |
737 | 703 |
738 // The count and length arguments start out in a precise relation in order t
o keep the | 704 // The count and length arguments start out in a precise relation in order t
o keep the |
739 // math correct through the different stages. Count is the number of pixel t
o produce. | 705 // math correct through the different stages. Count is the number of pixel t
o produce. |
740 // Since the code samples at pixel centers, length is the distance from the
center of the | 706 // Since the code samples at pixel centers, length is the distance from the
center of the |
741 // first pixel to the center of the last pixel. This implies that length is
count-1. | 707 // first pixel to the center of the last pixel. This implies that length is
count-1. |
742 fFirstStage->pointSpan(Span{{x + 0.5f, y + 0.5f}, count - 1.0f, count}); | 708 fFirstStage->pointSpan(Span{{x + 0.5f, y + 0.5f}, count - 1.0f, count}); |
743 } | 709 } |
| 710 |
| 711 SkLinearBitmapPipeline::PointProcessorInterface* |
| 712 SkLinearBitmapPipeline::ChooseMatrix(PointProcessorInterface* next, const SkMatr
ix& inverse) { |
| 713 if (inverse.hasPerspective()) { |
| 714 auto matrixStage = fMemory.createT<PerspectiveMatrix<>>( |
| 715 next, |
| 716 SkVector{inverse.getTranslateX(), inverse.getTranslateY()}, |
| 717 SkVector{inverse.getScaleX(), inverse.getScaleY()}, |
| 718 SkVector{inverse.getSkewX(), inverse.getSkewY()}, |
| 719 SkVector{inverse.getPerspX(), inverse.getPerspY()}, |
| 720 inverse.get(SkMatrix::kMPersp2)); |
| 721 fMatrixStageCloner = |
| 722 [matrixStage](PointProcessorInterface* cloneNext, MemoryAllocator* m
emory) { |
| 723 return memory->createT<PerspectiveMatrix<>>(cloneNext, matrixSta
ge); |
| 724 }; |
| 725 return matrixStage; |
| 726 } else if (inverse.getSkewX() != 0.0f || inverse.getSkewY() != 0.0f) { |
| 727 auto matrixStage = fMemory.createT<AffineMatrix<>>( |
| 728 next, |
| 729 SkVector{inverse.getTranslateX(), inverse.getTranslateY()}, |
| 730 SkVector{inverse.getScaleX(), inverse.getScaleY()}, |
| 731 SkVector{inverse.getSkewX(), inverse.getSkewY()}); |
| 732 fMatrixStageCloner = |
| 733 [matrixStage](PointProcessorInterface* cloneNext, MemoryAllocator* m
emory) { |
| 734 return memory->createT<AffineMatrix<>>(cloneNext, matrixStage); |
| 735 }; |
| 736 return matrixStage; |
| 737 } else if (inverse.getScaleX() != 1.0f || inverse.getScaleY() != 1.0f) { |
| 738 auto matrixStage = fMemory.createT<ScaleMatrix<>>( |
| 739 next, |
| 740 SkVector{inverse.getTranslateX(), inverse.getTranslateY()}, |
| 741 SkVector{inverse.getScaleX(), inverse.getScaleY()}); |
| 742 fMatrixStageCloner = |
| 743 [matrixStage](PointProcessorInterface* cloneNext, MemoryAllocator* m
emory) { |
| 744 return memory->createT<ScaleMatrix<>>(cloneNext, matrixStage); |
| 745 }; |
| 746 return matrixStage; |
| 747 } else if (inverse.getTranslateX() != 0.0f || inverse.getTranslateY() != 0.0
f) { |
| 748 auto matrixStage = fMemory.createT<TranslateMatrix<>>( |
| 749 next, |
| 750 SkVector{inverse.getTranslateX(), inverse.getTranslateY()}); |
| 751 fMatrixStageCloner = |
| 752 [matrixStage](PointProcessorInterface* cloneNext, MemoryAllocator* m
emory) { |
| 753 return memory->createT<TranslateMatrix<>>(cloneNext, matrixStage
); |
| 754 }; |
| 755 return matrixStage; |
| 756 } else { |
| 757 fMatrixStageCloner = [](PointProcessorInterface* cloneNext, MemoryAlloca
tor* memory) { |
| 758 return cloneNext; |
| 759 }; |
| 760 return next; |
| 761 } |
| 762 } |
OLD | NEW |