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 #include "SkPM4f.h" | 9 #include "SkPM4f.h" |
10 | 10 |
11 #include <algorithm> | 11 #include <algorithm> |
12 #include <cmath> | 12 #include <cmath> |
13 #include <limits> | 13 #include <limits> |
14 #include "SkColor.h" | 14 #include "SkColor.h" |
15 #include "SkSize.h" | 15 #include "SkSize.h" |
16 | 16 |
17 // Tweak ABI of functions that pass Sk4f by value to pass them via registers. | |
18 #if defined(_MSC_VER) && SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE2 | |
19 #define VECTORCALL __vectorcall | |
20 #elif defined(SK_CPU_ARM32) && defined(SK_ARM_HAS_NEON) | |
21 #define VECTORCALL __attribute__((pcs("aapcs-vfp"))) | |
22 #else | |
23 #define VECTORCALL | |
24 #endif | |
25 | |
26 class SkLinearBitmapPipeline::PointProcessorInterface { | |
27 public: | |
28 virtual ~PointProcessorInterface() { } | |
29 virtual void VECTORCALL pointListFew(int n, Sk4f xs, Sk4f ys) = 0; | |
30 virtual void VECTORCALL pointList4(Sk4f xs, Sk4f ys) = 0; | |
31 | |
32 // The pointSpan method efficiently process horizontal spans of pixels. | |
33 // * start - the point where to start the span. | |
34 // * length - the number of pixels to traverse in source space. | |
35 // * count - the number of pixels to produce in destination space. | |
36 // Both start and length are mapped through the inversion matrix to produce values in source | |
37 // space. After the matrix operation, the tilers may break the spans up into smaller spans. | |
38 // The tilers can produce spans that seem nonsensical. | |
39 // * The clamp tiler can create spans with length of 0. This indicates to co py an edge pixel out | |
40 // to the edge of the destination scan. | |
41 // * The mirror tiler can produce spans with negative length. This indicates that the source | |
42 // should be traversed in the opposite direction to the destination pixels . | |
43 virtual void pointSpan(SkPoint start, SkScalar length, int count) = 0; | |
44 }; | |
45 | |
46 class SkLinearBitmapPipeline::BilerpProcessorInterface | |
47 : public SkLinearBitmapPipeline::PointProcessorInterface { | |
48 public: | |
49 // The x's and y's are setup in the following order: | |
50 // +--------+--------+ | |
51 // | | | | |
52 // | px00 | px10 | | |
53 // | 0 | 1 | | |
54 // +--------+--------+ | |
55 // | | | | |
56 // | px01 | px11 | | |
57 // | 2 | 3 | | |
58 // +--------+--------+ | |
59 // These pixels coordinates are arranged in the following order in xs and ys : | |
60 // px00 px10 px01 px11 | |
61 virtual void VECTORCALL bilerpList(Sk4f xs, Sk4f ys) = 0; | |
62 }; | |
63 | |
64 class SkLinearBitmapPipeline::PixelPlacerInterface { | |
65 public: | |
66 virtual ~PixelPlacerInterface() { } | |
67 virtual void setDestination(SkPM4f* dst) = 0; | |
68 virtual void VECTORCALL placePixel(Sk4f pixel0) = 0; | |
69 virtual void VECTORCALL place4Pixels(Sk4f p0, Sk4f p1, Sk4f p2, Sk4f p3) = 0 ; | |
70 }; | |
71 | |
72 namespace { | |
73 | |
17 struct X { | 74 struct X { |
18 explicit X(SkScalar val) : fVal{val} { } | 75 explicit X(SkScalar val) : fVal{val} { } |
19 explicit X(SkPoint pt) : fVal{pt.fX} { } | 76 explicit X(SkPoint pt) : fVal{pt.fX} { } |
20 explicit X(SkSize s) : fVal{s.fWidth} { } | 77 explicit X(SkSize s) : fVal{s.fWidth} { } |
21 explicit X(SkISize s) : fVal(s.fWidth) { } | 78 explicit X(SkISize s) : fVal(s.fWidth) { } |
22 operator float () const {return fVal;} | 79 operator float () const {return fVal;} |
23 private: | 80 private: |
24 float fVal; | 81 float fVal; |
25 }; | 82 }; |
26 | 83 |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
61 // to work over. | 118 // to work over. |
62 // start - is the starting pixel. This is in destination space before the matr ix stage, and in | 119 // start - is the starting pixel. This is in destination space before the matr ix stage, and in |
63 // source space after the matrix stage. | 120 // source space after the matrix stage. |
64 // length - is this distance between the first pixel center and the last pixel center. Like start, | 121 // length - is this distance between the first pixel center and the last pixel center. Like start, |
65 // this is in destination space before the matrix stage, and in source space after. | 122 // this is in destination space before the matrix stage, and in source space after. |
66 // count - the number of pixels in source space to produce. | 123 // count - the number of pixels in source space to produce. |
67 // next - a pointer to the next stage. | 124 // next - a pointer to the next stage. |
68 // maybeProcessSpan - returns false if it can not process the span and needs t o fallback to | 125 // maybeProcessSpan - returns false if it can not process the span and needs t o fallback to |
69 // point lists for processing. | 126 // point lists for processing. |
70 template<typename Strategy, typename Next> | 127 template<typename Strategy, typename Next> |
71 class PointProcessor final : public PointProcessorInterface { | 128 class PointProcessor final : public SkLinearBitmapPipeline::PointProcessorInterf ace { |
72 public: | 129 public: |
73 template <typename... Args> | 130 template <typename... Args> |
74 PointProcessor(Next* next, Args&&... args) | 131 PointProcessor(Next* next, Args&&... args) |
75 : fNext{next} | 132 : fNext{next} |
76 , fStrategy{std::forward<Args>(args)...}{ } | 133 , fStrategy{std::forward<Args>(args)...}{ } |
77 | 134 |
78 void pointListFew(int n, Sk4fArg xs, Sk4fArg ys) override { | 135 void VECTORCALL pointListFew(int n, Sk4f xs, Sk4f ys) override { |
79 Sk4f newXs = xs; | 136 Sk4f newXs = xs; |
80 Sk4f newYs = ys; | 137 Sk4f newYs = ys; |
f(malita)
2016/02/22 22:48:08
Are the locals still needed?
mtklein
2016/02/22 23:00:55
Nope.
| |
81 fStrategy.processPoints(&newXs, &newYs); | 138 fStrategy.processPoints(&newXs, &newYs); |
82 fNext->pointListFew(n, newXs, newYs); | 139 fNext->pointListFew(n, newXs, newYs); |
83 } | 140 } |
84 | 141 |
85 void pointList4(Sk4fArg xs, Sk4fArg ys) override { | 142 void VECTORCALL pointList4(Sk4f xs, Sk4f ys) override { |
86 Sk4f newXs = xs; | 143 Sk4f newXs = xs; |
87 Sk4f newYs = ys; | 144 Sk4f newYs = ys; |
88 fStrategy.processPoints(&newXs, &newYs); | 145 fStrategy.processPoints(&newXs, &newYs); |
89 fNext->pointList4(newXs, newYs); | 146 fNext->pointList4(newXs, newYs); |
90 } | 147 } |
91 | 148 |
92 void pointSpan(SkPoint start, SkScalar length, int count) override { | 149 void pointSpan(SkPoint start, SkScalar length, int count) override { |
93 if (!fStrategy.maybeProcessSpan(start, length, count, fNext)) { | 150 if (!fStrategy.maybeProcessSpan(start, length, count, fNext)) { |
94 span_fallback(start, length, count, this); | 151 span_fallback(start, length, count, this); |
95 } | 152 } |
96 } | 153 } |
97 | 154 |
98 private: | 155 private: |
99 Next* const fNext; | 156 Next* const fNext; |
100 Strategy fStrategy; | 157 Strategy fStrategy; |
101 }; | 158 }; |
102 | 159 |
103 // See PointProcessor for responsibilities of Strategy. | 160 // See PointProcessor for responsibilities of Strategy. |
104 template<typename Strategy, typename Next> | 161 template<typename Strategy, typename Next> |
105 class BilerpProcessor final : public BilerpProcessorInterface { | 162 class BilerpProcessor final : public SkLinearBitmapPipeline::BilerpProcessorInte rface { |
106 public: | 163 public: |
107 template <typename... Args> | 164 template <typename... Args> |
108 BilerpProcessor(Next* next, Args&&... args) | 165 BilerpProcessor(Next* next, Args&&... args) |
109 : fNext{next} | 166 : fNext{next} |
110 , fStrategy{std::forward<Args>(args)...}{ } | 167 , fStrategy{std::forward<Args>(args)...}{ } |
111 | 168 |
112 void pointListFew(int n, Sk4fArg xs, Sk4fArg ys) override { | 169 void VECTORCALL pointListFew(int n, Sk4f xs, Sk4f ys) override { |
113 Sk4f newXs = xs; | 170 Sk4f newXs = xs; |
114 Sk4f newYs = ys; | 171 Sk4f newYs = ys; |
115 fStrategy.processPoints(&newXs, &newYs); | 172 fStrategy.processPoints(&newXs, &newYs); |
116 fNext->pointListFew(n, newXs, newYs); | 173 fNext->pointListFew(n, newXs, newYs); |
117 } | 174 } |
118 | 175 |
119 void pointList4(Sk4fArg xs, Sk4fArg ys) override { | 176 void VECTORCALL pointList4(Sk4f xs, Sk4f ys) override { |
120 Sk4f newXs = xs; | 177 Sk4f newXs = xs; |
121 Sk4f newYs = ys; | 178 Sk4f newYs = ys; |
122 fStrategy.processPoints(&newXs, &newYs); | 179 fStrategy.processPoints(&newXs, &newYs); |
123 fNext->pointList4(newXs, newYs); | 180 fNext->pointList4(newXs, newYs); |
124 } | 181 } |
125 | 182 |
126 void bilerpList(Sk4fArg xs, Sk4fArg ys) override { | 183 void VECTORCALL bilerpList(Sk4f xs, Sk4f ys) override { |
127 Sk4f newXs = xs; | 184 Sk4f newXs = xs; |
128 Sk4f newYs = ys; | 185 Sk4f newYs = ys; |
129 fStrategy.processPoints(&newXs, &newYs); | 186 fStrategy.processPoints(&newXs, &newYs); |
130 fNext->bilerpList(newXs, newYs); | 187 fNext->bilerpList(newXs, newYs); |
131 } | 188 } |
132 | 189 |
133 void pointSpan(SkPoint start, SkScalar length, int count) override { | 190 void pointSpan(SkPoint start, SkScalar length, int count) override { |
134 if (!fStrategy.maybeProcessSpan(start, length, count, fNext)) { | 191 if (!fStrategy.maybeProcessSpan(start, length, count, fNext)) { |
135 span_fallback(start, length, count, this); | 192 span_fallback(start, length, count, this); |
136 } | 193 } |
137 } | 194 } |
138 | 195 |
139 private: | 196 private: |
140 Next* const fNext; | 197 Next* const fNext; |
141 Strategy fStrategy; | 198 Strategy fStrategy; |
142 }; | 199 }; |
143 | 200 |
144 class SkippedStage final : public BilerpProcessorInterface { | 201 class SkippedStage final : public SkLinearBitmapPipeline::BilerpProcessorInterfa ce { |
145 void pointListFew(int n, Sk4fArg xs, Sk4fArg ys) override { | 202 void VECTORCALL pointListFew(int n, Sk4f xs, Sk4f ys) override { |
146 SkFAIL("Skipped stage."); | 203 SkFAIL("Skipped stage."); |
147 } | 204 } |
148 void pointList4(Sk4fArg Xs, Sk4fArg Ys) override { | 205 void VECTORCALL pointList4(Sk4f Xs, Sk4f Ys) override { |
149 SkFAIL("Skipped stage."); | 206 SkFAIL("Skipped stage."); |
150 } | 207 } |
151 void bilerpList(Sk4fArg xs, Sk4fArg ys) override { | 208 void VECTORCALL bilerpList(Sk4f xs, Sk4f ys) override { |
152 SkFAIL("Skipped stage."); | 209 SkFAIL("Skipped stage."); |
153 } | 210 } |
154 void pointSpan(SkPoint start, SkScalar length, int count) override { | 211 void pointSpan(SkPoint start, SkScalar length, int count) override { |
155 SkFAIL("Skipped stage."); | 212 SkFAIL("Skipped stage."); |
156 } | 213 } |
157 }; | 214 }; |
158 | 215 |
159 class TranslateMatrixStrategy { | 216 class TranslateMatrixStrategy { |
160 public: | 217 public: |
161 TranslateMatrixStrategy(SkVector offset) | 218 TranslateMatrixStrategy(SkVector offset) |
162 : fXOffset{X(offset)} | 219 : fXOffset{X(offset)} |
163 , fYOffset{Y(offset)} { } | 220 , fYOffset{Y(offset)} { } |
164 | 221 |
165 void processPoints(Sk4f* xs, Sk4f* ys) { | 222 void processPoints(Sk4f* xs, Sk4f* ys) { |
166 *xs = *xs + fXOffset; | 223 *xs = *xs + fXOffset; |
167 *ys = *ys + fYOffset; | 224 *ys = *ys + fYOffset; |
168 } | 225 } |
169 | 226 |
170 template <typename Next> | 227 template <typename Next> |
171 bool maybeProcessSpan(SkPoint start, SkScalar length, int count, Next* next) { | 228 bool maybeProcessSpan(SkPoint start, SkScalar length, int count, Next* next) { |
172 next->pointSpan(start + SkPoint{fXOffset[0], fYOffset[0]}, length, count ); | 229 next->pointSpan(start + SkPoint{fXOffset[0], fYOffset[0]}, length, count ); |
173 return true; | 230 return true; |
174 } | 231 } |
175 | 232 |
176 private: | 233 private: |
177 const Sk4f fXOffset, fYOffset; | 234 const Sk4f fXOffset, fYOffset; |
178 }; | 235 }; |
179 template <typename Next = PointProcessorInterface> | 236 template <typename Next = SkLinearBitmapPipeline::PointProcessorInterface> |
180 using TranslateMatrix = PointProcessor<TranslateMatrixStrategy, Next>; | 237 using TranslateMatrix = PointProcessor<TranslateMatrixStrategy, Next>; |
181 | 238 |
182 class ScaleMatrixStrategy { | 239 class ScaleMatrixStrategy { |
183 public: | 240 public: |
184 ScaleMatrixStrategy(SkVector offset, SkVector scale) | 241 ScaleMatrixStrategy(SkVector offset, SkVector scale) |
185 : fXOffset{X(offset)}, fYOffset{Y(offset)} | 242 : fXOffset{X(offset)}, fYOffset{Y(offset)} |
186 , fXScale{X(scale)}, fYScale{Y(scale)} { } | 243 , fXScale{X(scale)}, fYScale{Y(scale)} { } |
187 void processPoints(Sk4f* xs, Sk4f* ys) { | 244 void processPoints(Sk4f* xs, Sk4f* ys) { |
188 *xs = *xs * fXScale + fXOffset; | 245 *xs = *xs * fXScale + fXOffset; |
189 *ys = *ys * fYScale + fYOffset; | 246 *ys = *ys * fYScale + fYOffset; |
190 } | 247 } |
191 | 248 |
192 template <typename Next> | 249 template <typename Next> |
193 bool maybeProcessSpan(SkPoint start, SkScalar length, int count, Next* next) { | 250 bool maybeProcessSpan(SkPoint start, SkScalar length, int count, Next* next) { |
194 SkPoint newStart = | 251 SkPoint newStart = |
195 SkPoint{X(start) * fXScale[0] + fXOffset[0], Y(start) * fYScale[0] + fYOffset[0]}; | 252 SkPoint{X(start) * fXScale[0] + fXOffset[0], Y(start) * fYScale[0] + fYOffset[0]}; |
196 SkScalar newLength = length * fXScale[0]; | 253 SkScalar newLength = length * fXScale[0]; |
197 next->pointSpan(newStart, newLength, count); | 254 next->pointSpan(newStart, newLength, count); |
198 return true; | 255 return true; |
199 } | 256 } |
200 | 257 |
201 private: | 258 private: |
202 const Sk4f fXOffset, fYOffset; | 259 const Sk4f fXOffset, fYOffset; |
203 const Sk4f fXScale, fYScale; | 260 const Sk4f fXScale, fYScale; |
204 }; | 261 }; |
205 template <typename Next = PointProcessorInterface> | 262 template <typename Next = SkLinearBitmapPipeline::PointProcessorInterface> |
206 using ScaleMatrix = PointProcessor<ScaleMatrixStrategy, Next>; | 263 using ScaleMatrix = PointProcessor<ScaleMatrixStrategy, Next>; |
207 | 264 |
208 class AffineMatrixStrategy { | 265 class AffineMatrixStrategy { |
209 public: | 266 public: |
210 AffineMatrixStrategy(SkVector offset, SkVector scale, SkVector skew) | 267 AffineMatrixStrategy(SkVector offset, SkVector scale, SkVector skew) |
211 : fXOffset{X(offset)}, fYOffset{Y(offset)} | 268 : fXOffset{X(offset)}, fYOffset{Y(offset)} |
212 , fXScale{X(scale)}, fYScale{Y(scale)} | 269 , fXScale{X(scale)}, fYScale{Y(scale)} |
213 , fXSkew{X(skew)}, fYSkew{Y(skew)} { } | 270 , fXSkew{X(skew)}, fYSkew{Y(skew)} { } |
214 void processPoints(Sk4f* xs, Sk4f* ys) { | 271 void processPoints(Sk4f* xs, Sk4f* ys) { |
215 Sk4f newXs = fXScale * *xs + fXSkew * *ys + fXOffset; | 272 Sk4f newXs = fXScale * *xs + fXSkew * *ys + fXOffset; |
216 Sk4f newYs = fYSkew * *xs + fYScale * *ys + fYOffset; | 273 Sk4f newYs = fYSkew * *xs + fYScale * *ys + fYOffset; |
217 | 274 |
218 *xs = newXs; | 275 *xs = newXs; |
219 *ys = newYs; | 276 *ys = newYs; |
220 } | 277 } |
221 | 278 |
222 template <typename Next> | 279 template <typename Next> |
223 bool maybeProcessSpan(SkPoint start, SkScalar length, int count, Next* next) { | 280 bool maybeProcessSpan(SkPoint start, SkScalar length, int count, Next* next) { |
224 return false; | 281 return false; |
225 } | 282 } |
226 | 283 |
227 private: | 284 private: |
228 const Sk4f fXOffset, fYOffset; | 285 const Sk4f fXOffset, fYOffset; |
229 const Sk4f fXScale, fYScale; | 286 const Sk4f fXScale, fYScale; |
230 const Sk4f fXSkew, fYSkew; | 287 const Sk4f fXSkew, fYSkew; |
231 }; | 288 }; |
232 template <typename Next = PointProcessorInterface> | 289 template <typename Next = SkLinearBitmapPipeline::PointProcessorInterface> |
233 using AffineMatrix = PointProcessor<AffineMatrixStrategy, Next>; | 290 using AffineMatrix = PointProcessor<AffineMatrixStrategy, Next>; |
234 | 291 |
235 static PointProcessorInterface* choose_matrix( | 292 static SkLinearBitmapPipeline::PointProcessorInterface* choose_matrix( |
236 PointProcessorInterface* next, | 293 SkLinearBitmapPipeline::PointProcessorInterface* next, |
237 const SkMatrix& inverse, | 294 const SkMatrix& inverse, |
238 SkLinearBitmapPipeline::MatrixStage* matrixProc) { | 295 SkLinearBitmapPipeline::MatrixStage* matrixProc) { |
239 if (inverse.hasPerspective()) { | 296 if (inverse.hasPerspective()) { |
240 SkFAIL("Not implemented."); | 297 SkFAIL("Not implemented."); |
241 } else if (inverse.getSkewX() != 0.0f || inverse.getSkewY() != 0.0f) { | 298 } else if (inverse.getSkewX() != 0.0f || inverse.getSkewY() != 0.0f) { |
242 matrixProc->Initialize<AffineMatrix<>>( | 299 matrixProc->Initialize<AffineMatrix<>>( |
243 next, | 300 next, |
244 SkVector{inverse.getTranslateX(), inverse.getTranslateY()}, | 301 SkVector{inverse.getTranslateX(), inverse.getTranslateY()}, |
245 SkVector{inverse.getScaleX(), inverse.getScaleY()}, | 302 SkVector{inverse.getScaleX(), inverse.getScaleY()}, |
246 SkVector{inverse.getSkewX(), inverse.getSkewY()}); | 303 SkVector{inverse.getSkewX(), inverse.getSkewY()}); |
247 } else if (inverse.getScaleX() != 1.0f || inverse.getScaleY() != 1.0f) { | 304 } else if (inverse.getScaleX() != 1.0f || inverse.getScaleY() != 1.0f) { |
248 matrixProc->Initialize<ScaleMatrix<>>( | 305 matrixProc->Initialize<ScaleMatrix<>>( |
249 next, | 306 next, |
250 SkVector{inverse.getTranslateX(), inverse.getTranslateY()}, | 307 SkVector{inverse.getTranslateX(), inverse.getTranslateY()}, |
251 SkVector{inverse.getScaleX(), inverse.getScaleY()}); | 308 SkVector{inverse.getScaleX(), inverse.getScaleY()}); |
252 } else if (inverse.getTranslateX() != 0.0f || inverse.getTranslateY() != 0.0 f) { | 309 } else if (inverse.getTranslateX() != 0.0f || inverse.getTranslateY() != 0.0 f) { |
253 matrixProc->Initialize<TranslateMatrix<>>( | 310 matrixProc->Initialize<TranslateMatrix<>>( |
254 next, | 311 next, |
255 SkVector{inverse.getTranslateX(), inverse.getTranslateY()}); | 312 SkVector{inverse.getTranslateX(), inverse.getTranslateY()}); |
256 } else { | 313 } else { |
257 matrixProc->Initialize<SkippedStage>(); | 314 matrixProc->Initialize<SkippedStage>(); |
258 return next; | 315 return next; |
259 } | 316 } |
260 return matrixProc->get(); | 317 return matrixProc->get(); |
261 } | 318 } |
262 | 319 |
263 template <typename Next = BilerpProcessorInterface> | 320 template <typename Next = SkLinearBitmapPipeline::BilerpProcessorInterface> |
264 class ExpandBilerp final : public PointProcessorInterface { | 321 class ExpandBilerp final : public SkLinearBitmapPipeline::PointProcessorInterfac e { |
265 public: | 322 public: |
266 ExpandBilerp(Next* next) : fNext{next} { } | 323 ExpandBilerp(Next* next) : fNext{next} { } |
267 | 324 |
268 void pointListFew(int n, Sk4fArg xs, Sk4fArg ys) override { | 325 void VECTORCALL pointListFew(int n, Sk4f xs, Sk4f ys) override { |
269 SkASSERT(0 < n && n < 4); | 326 SkASSERT(0 < n && n < 4); |
270 // px00 px10 px01 px11 | 327 // px00 px10 px01 px11 |
271 const Sk4f kXOffsets{-0.5f, 0.5f, -0.5f, 0.5f}, | 328 const Sk4f kXOffsets{-0.5f, 0.5f, -0.5f, 0.5f}, |
272 kYOffsets{-0.5f, -0.5f, 0.5f, 0.5f}; | 329 kYOffsets{-0.5f, -0.5f, 0.5f, 0.5f}; |
273 if (n >= 1) fNext->bilerpList(Sk4f{xs[0]} + kXOffsets, Sk4f{ys[0]} + kYO ffsets); | 330 if (n >= 1) fNext->bilerpList(Sk4f{xs[0]} + kXOffsets, Sk4f{ys[0]} + kYO ffsets); |
274 if (n >= 2) fNext->bilerpList(Sk4f{xs[1]} + kXOffsets, Sk4f{ys[1]} + kYO ffsets); | 331 if (n >= 2) fNext->bilerpList(Sk4f{xs[1]} + kXOffsets, Sk4f{ys[1]} + kYO ffsets); |
275 if (n >= 3) fNext->bilerpList(Sk4f{xs[2]} + kXOffsets, Sk4f{ys[2]} + kYO ffsets); | 332 if (n >= 3) fNext->bilerpList(Sk4f{xs[2]} + kXOffsets, Sk4f{ys[2]} + kYO ffsets); |
276 } | 333 } |
277 | 334 |
278 void pointList4(Sk4fArg xs, Sk4fArg ys) override { | 335 void VECTORCALL pointList4(Sk4f xs, Sk4f ys) override { |
279 // px00 px10 px01 px11 | 336 // px00 px10 px01 px11 |
280 const Sk4f kXOffsets{-0.5f, 0.5f, -0.5f, 0.5f}, | 337 const Sk4f kXOffsets{-0.5f, 0.5f, -0.5f, 0.5f}, |
281 kYOffsets{-0.5f, -0.5f, 0.5f, 0.5f}; | 338 kYOffsets{-0.5f, -0.5f, 0.5f, 0.5f}; |
282 fNext->bilerpList(Sk4f{xs[0]} + kXOffsets, Sk4f{ys[0]} + kYOffsets); | 339 fNext->bilerpList(Sk4f{xs[0]} + kXOffsets, Sk4f{ys[0]} + kYOffsets); |
283 fNext->bilerpList(Sk4f{xs[1]} + kXOffsets, Sk4f{ys[1]} + kYOffsets); | 340 fNext->bilerpList(Sk4f{xs[1]} + kXOffsets, Sk4f{ys[1]} + kYOffsets); |
284 fNext->bilerpList(Sk4f{xs[2]} + kXOffsets, Sk4f{ys[2]} + kYOffsets); | 341 fNext->bilerpList(Sk4f{xs[2]} + kXOffsets, Sk4f{ys[2]} + kYOffsets); |
285 fNext->bilerpList(Sk4f{xs[3]} + kXOffsets, Sk4f{ys[3]} + kYOffsets); | 342 fNext->bilerpList(Sk4f{xs[3]} + kXOffsets, Sk4f{ys[3]} + kYOffsets); |
286 } | 343 } |
287 | 344 |
288 void pointSpan(SkPoint start, SkScalar length, int count) override { | 345 void pointSpan(SkPoint start, SkScalar length, int count) override { |
289 span_fallback(start, length, count, this); | 346 span_fallback(start, length, count, this); |
290 } | 347 } |
291 | 348 |
292 private: | 349 private: |
293 Next* const fNext; | 350 Next* const fNext; |
294 }; | 351 }; |
295 | 352 |
296 static PointProcessorInterface* choose_filter( | 353 static SkLinearBitmapPipeline::PointProcessorInterface* choose_filter( |
297 BilerpProcessorInterface* next, | 354 SkLinearBitmapPipeline::BilerpProcessorInterface* next, |
298 SkFilterQuality filterQuailty, | 355 SkFilterQuality filterQuailty, |
299 SkLinearBitmapPipeline::FilterStage* filterProc) { | 356 SkLinearBitmapPipeline::FilterStage* filterProc) { |
300 if (SkFilterQuality::kNone_SkFilterQuality == filterQuailty) { | 357 if (SkFilterQuality::kNone_SkFilterQuality == filterQuailty) { |
301 filterProc->Initialize<SkippedStage>(); | 358 filterProc->Initialize<SkippedStage>(); |
302 return next; | 359 return next; |
303 } else { | 360 } else { |
304 filterProc->Initialize<ExpandBilerp<>>(next); | 361 filterProc->Initialize<ExpandBilerp<>>(next); |
305 return filterProc->get(); | 362 return filterProc->get(); |
306 } | 363 } |
307 } | 364 } |
(...skipping 21 matching lines...) Expand all Loading... | |
329 bool maybeProcessSpan(SkPoint start, SkScalar length, int count, Next* next) { | 386 bool maybeProcessSpan(SkPoint start, SkScalar length, int count, Next* next) { |
330 return false; | 387 return false; |
331 } | 388 } |
332 | 389 |
333 private: | 390 private: |
334 const Sk4f fXMin{SK_FloatNegativeInfinity}; | 391 const Sk4f fXMin{SK_FloatNegativeInfinity}; |
335 const Sk4f fYMin{SK_FloatNegativeInfinity}; | 392 const Sk4f fYMin{SK_FloatNegativeInfinity}; |
336 const Sk4f fXMax{SK_FloatInfinity}; | 393 const Sk4f fXMax{SK_FloatInfinity}; |
337 const Sk4f fYMax{SK_FloatInfinity}; | 394 const Sk4f fYMax{SK_FloatInfinity}; |
338 }; | 395 }; |
339 template <typename Next = BilerpProcessorInterface> | 396 template <typename Next = SkLinearBitmapPipeline::BilerpProcessorInterface> |
340 using Clamp = BilerpProcessor<ClampStrategy, Next>; | 397 using Clamp = BilerpProcessor<ClampStrategy, Next>; |
341 | 398 |
342 class RepeatStrategy { | 399 class RepeatStrategy { |
343 public: | 400 public: |
344 RepeatStrategy(X max) : fXMax{max}, fXInvMax{1.0f/max} { } | 401 RepeatStrategy(X max) : fXMax{max}, fXInvMax{1.0f/max} { } |
345 RepeatStrategy(Y max) : fYMax{max}, fYInvMax{1.0f/max} { } | 402 RepeatStrategy(Y max) : fYMax{max}, fYInvMax{1.0f/max} { } |
346 RepeatStrategy(SkSize max) | 403 RepeatStrategy(SkSize max) |
347 : fXMax{X(max)} | 404 : fXMax{X(max)} |
348 , fXInvMax{1.0f / X(max)} | 405 , fXInvMax{1.0f / X(max)} |
349 , fYMax{Y(max)} | 406 , fYMax{Y(max)} |
(...skipping 13 matching lines...) Expand all Loading... | |
363 return false; | 420 return false; |
364 } | 421 } |
365 | 422 |
366 private: | 423 private: |
367 const Sk4f fXMax{0.0f}; | 424 const Sk4f fXMax{0.0f}; |
368 const Sk4f fXInvMax{0.0f}; | 425 const Sk4f fXInvMax{0.0f}; |
369 const Sk4f fYMax{0.0f}; | 426 const Sk4f fYMax{0.0f}; |
370 const Sk4f fYInvMax{0.0f}; | 427 const Sk4f fYInvMax{0.0f}; |
371 }; | 428 }; |
372 | 429 |
373 template <typename Next = BilerpProcessorInterface> | 430 template <typename Next = SkLinearBitmapPipeline::BilerpProcessorInterface> |
374 using Repeat = BilerpProcessor<RepeatStrategy, Next>; | 431 using Repeat = BilerpProcessor<RepeatStrategy, Next>; |
375 | 432 |
376 static BilerpProcessorInterface* choose_tiler( | 433 static SkLinearBitmapPipeline::BilerpProcessorInterface* choose_tiler( |
377 BilerpProcessorInterface* next, | 434 SkLinearBitmapPipeline::BilerpProcessorInterface* next, |
378 SkSize dimensions, | 435 SkSize dimensions, |
379 SkShader::TileMode xMode, | 436 SkShader::TileMode xMode, |
380 SkShader::TileMode yMode, | 437 SkShader::TileMode yMode, |
381 SkLinearBitmapPipeline::TileStage* tileProcXOrBoth, | 438 SkLinearBitmapPipeline::TileStage* tileProcXOrBoth, |
382 SkLinearBitmapPipeline::TileStage* tileProcY) { | 439 SkLinearBitmapPipeline::TileStage* tileProcY) { |
383 if (xMode == yMode) { | 440 if (xMode == yMode) { |
384 switch (xMode) { | 441 switch (xMode) { |
385 case SkShader::kClamp_TileMode: | 442 case SkShader::kClamp_TileMode: |
386 tileProcXOrBoth->Initialize<Clamp<>>(next, dimensions); | 443 tileProcXOrBoth->Initialize<Clamp<>>(next, dimensions); |
387 break; | 444 break; |
(...skipping 27 matching lines...) Expand all Loading... | |
415 case SkShader::kMirror_TileMode: | 472 case SkShader::kMirror_TileMode: |
416 SkFAIL("Not implemented."); | 473 SkFAIL("Not implemented."); |
417 break; | 474 break; |
418 } | 475 } |
419 } | 476 } |
420 return tileProcXOrBoth->get(); | 477 return tileProcXOrBoth->get(); |
421 } | 478 } |
422 | 479 |
423 class sRGBFast { | 480 class sRGBFast { |
424 public: | 481 public: |
425 static Sk4f sRGBToLinear(Sk4fArg pixel) { | 482 static Sk4f VECTORCALL sRGBToLinear(Sk4f pixel) { |
426 Sk4f l = pixel * pixel; | 483 Sk4f l = pixel * pixel; |
427 return Sk4f{l[0], l[1], l[2], pixel[3]}; | 484 return Sk4f{l[0], l[1], l[2], pixel[3]}; |
428 } | 485 } |
429 }; | 486 }; |
430 | 487 |
431 template <SkColorProfileType colorProfile> | 488 template <SkColorProfileType colorProfile> |
432 class Passthrough8888 { | 489 class Passthrough8888 { |
433 public: | 490 public: |
434 Passthrough8888(int width, const uint32_t* src) | 491 Passthrough8888(int width, const uint32_t* src) |
435 : fSrc{src}, fWidth{width}{ } | 492 : fSrc{src}, fWidth{width}{ } |
436 | 493 |
437 void getFewPixels(int n, Sk4fArg xs, Sk4fArg ys, Sk4f* px0, Sk4f* px1, Sk4f* px2) { | 494 void VECTORCALL getFewPixels(int n, Sk4f xs, Sk4f ys, Sk4f* px0, Sk4f* px1, Sk4f* px2) { |
438 Sk4i XIs = SkNx_cast<int, float>(xs); | 495 Sk4i XIs = SkNx_cast<int, float>(xs); |
439 Sk4i YIs = SkNx_cast<int, float>(ys); | 496 Sk4i YIs = SkNx_cast<int, float>(ys); |
440 Sk4i bufferLoc = YIs * fWidth + XIs; | 497 Sk4i bufferLoc = YIs * fWidth + XIs; |
441 switch (n) { | 498 switch (n) { |
442 case 3: | 499 case 3: |
443 *px2 = getPixel(fSrc, bufferLoc[2]); | 500 *px2 = getPixel(fSrc, bufferLoc[2]); |
444 case 2: | 501 case 2: |
445 *px1 = getPixel(fSrc, bufferLoc[1]); | 502 *px1 = getPixel(fSrc, bufferLoc[1]); |
446 case 1: | 503 case 1: |
447 *px0 = getPixel(fSrc, bufferLoc[0]); | 504 *px0 = getPixel(fSrc, bufferLoc[0]); |
448 default: | 505 default: |
449 break; | 506 break; |
450 } | 507 } |
451 } | 508 } |
452 | 509 |
453 void get4Pixels(Sk4fArg xs, Sk4fArg ys, Sk4f* px0, Sk4f* px1, Sk4f* px2, Sk4 f* px3) { | 510 void VECTORCALL get4Pixels(Sk4f xs, Sk4f ys, Sk4f* px0, Sk4f* px1, Sk4f* px2 , Sk4f* px3) { |
454 Sk4i XIs = SkNx_cast<int, float>(xs); | 511 Sk4i XIs = SkNx_cast<int, float>(xs); |
455 Sk4i YIs = SkNx_cast<int, float>(ys); | 512 Sk4i YIs = SkNx_cast<int, float>(ys); |
456 Sk4i bufferLoc = YIs * fWidth + XIs; | 513 Sk4i bufferLoc = YIs * fWidth + XIs; |
457 *px0 = getPixel(fSrc, bufferLoc[0]); | 514 *px0 = getPixel(fSrc, bufferLoc[0]); |
458 *px1 = getPixel(fSrc, bufferLoc[1]); | 515 *px1 = getPixel(fSrc, bufferLoc[1]); |
459 *px2 = getPixel(fSrc, bufferLoc[2]); | 516 *px2 = getPixel(fSrc, bufferLoc[2]); |
460 *px3 = getPixel(fSrc, bufferLoc[3]); | 517 *px3 = getPixel(fSrc, bufferLoc[3]); |
461 } | 518 } |
462 | 519 |
463 const uint32_t* row(int y) { return fSrc + y * fWidth[0]; } | 520 const uint32_t* row(int y) { return fSrc + y * fWidth[0]; } |
(...skipping 25 matching lines...) Expand all Loading... | |
489 // +--------+--------+ | 546 // +--------+--------+ |
490 // | 547 // |
491 // | 548 // |
492 // Given a pixelxy each is multiplied by a different factor derived from the fra ctional part of x | 549 // Given a pixelxy each is multiplied by a different factor derived from the fra ctional part of x |
493 // and y: | 550 // and y: |
494 // * px00 -> (1 - x)(1 - y) = 1 - x - y + xy | 551 // * px00 -> (1 - x)(1 - y) = 1 - x - y + xy |
495 // * px10 -> x(1 - y) = x - xy | 552 // * px10 -> x(1 - y) = x - xy |
496 // * px01 -> (1 - x)y = y - xy | 553 // * px01 -> (1 - x)y = y - xy |
497 // * px11 -> xy | 554 // * px11 -> xy |
498 // So x * y is calculated first and then used to calculate all the other factors . | 555 // So x * y is calculated first and then used to calculate all the other factors . |
499 static Sk4f bilerp4(Sk4fArg xs, Sk4fArg ys, Sk4fArg px00, Sk4fArg px10, | 556 static Sk4f VECTORCALL bilerp4(Sk4f xs, Sk4f ys, Sk4f px00, Sk4f px10, |
500 Sk4fArg px01, Sk4fArg px11) { | 557 Sk4f px01, Sk4f px11) { |
501 // Calculate fractional xs and ys. | 558 // Calculate fractional xs and ys. |
502 Sk4f fxs = xs - xs.floor(); | 559 Sk4f fxs = xs - xs.floor(); |
503 Sk4f fys = ys - ys.floor(); | 560 Sk4f fys = ys - ys.floor(); |
504 Sk4f fxys{fxs * fys}; | 561 Sk4f fxys{fxs * fys}; |
505 Sk4f sum = px11 * fxys; | 562 Sk4f sum = px11 * fxys; |
506 sum = sum + px01 * (fys - fxys); | 563 sum = sum + px01 * (fys - fxys); |
507 sum = sum + px10 * (fxs - fxys); | 564 sum = sum + px10 * (fxs - fxys); |
508 sum = sum + px00 * (Sk4f{1.0f} - fxs - fys + fxys); | 565 sum = sum + px00 * (Sk4f{1.0f} - fxs - fys + fxys); |
509 return sum; | 566 return sum; |
510 } | 567 } |
511 | 568 |
512 template <typename SourceStrategy> | 569 template <typename SourceStrategy> |
513 class Sampler final : public BilerpProcessorInterface { | 570 class Sampler final : public SkLinearBitmapPipeline::BilerpProcessorInterface { |
514 public: | 571 public: |
515 template <typename... Args> | 572 template <typename... Args> |
516 Sampler(PixelPlacerInterface* next, Args&&... args) | 573 Sampler(SkLinearBitmapPipeline::PixelPlacerInterface* next, Args&&... args) |
517 : fNext{next} | 574 : fNext{next} |
518 , fStrategy{std::forward<Args>(args)...} { } | 575 , fStrategy{std::forward<Args>(args)...} { } |
519 | 576 |
520 void pointListFew(int n, Sk4fArg xs, Sk4fArg ys) override { | 577 void VECTORCALL pointListFew(int n, Sk4f xs, Sk4f ys) override { |
521 SkASSERT(0 < n && n < 4); | 578 SkASSERT(0 < n && n < 4); |
522 Sk4f px0, px1, px2; | 579 Sk4f px0, px1, px2; |
523 fStrategy.getFewPixels(n, xs, ys, &px0, &px1, &px2); | 580 fStrategy.getFewPixels(n, xs, ys, &px0, &px1, &px2); |
524 if (n >= 1) fNext->placePixel(px0); | 581 if (n >= 1) fNext->placePixel(px0); |
525 if (n >= 2) fNext->placePixel(px1); | 582 if (n >= 2) fNext->placePixel(px1); |
526 if (n >= 3) fNext->placePixel(px2); | 583 if (n >= 3) fNext->placePixel(px2); |
527 } | 584 } |
528 | 585 |
529 void pointList4(Sk4fArg xs, Sk4fArg ys) override { | 586 void VECTORCALL pointList4(Sk4f xs, Sk4f ys) override { |
530 Sk4f px0, px1, px2, px3; | 587 Sk4f px0, px1, px2, px3; |
531 fStrategy.get4Pixels(xs, ys, &px0, &px1, &px2, &px3); | 588 fStrategy.get4Pixels(xs, ys, &px0, &px1, &px2, &px3); |
532 fNext->place4Pixels(px0, px1, px2, px3); | 589 fNext->place4Pixels(px0, px1, px2, px3); |
533 } | 590 } |
534 | 591 |
535 void bilerpList(Sk4fArg xs, Sk4fArg ys) override { | 592 void VECTORCALL bilerpList(Sk4f xs, Sk4f ys) override { |
536 Sk4f px00, px10, px01, px11; | 593 Sk4f px00, px10, px01, px11; |
537 fStrategy.get4Pixels(xs, ys, &px00, &px10, &px01, &px11); | 594 fStrategy.get4Pixels(xs, ys, &px00, &px10, &px01, &px11); |
538 Sk4f pixel = bilerp4(xs, ys, px00, px10, px01, px11); | 595 Sk4f pixel = bilerp4(xs, ys, px00, px10, px01, px11); |
539 fNext->placePixel(pixel); | 596 fNext->placePixel(pixel); |
540 } | 597 } |
541 | 598 |
542 void pointSpan(SkPoint start, SkScalar length, int count) override { | 599 void pointSpan(SkPoint start, SkScalar length, int count) override { |
543 span_fallback(start, length, count, this); | 600 span_fallback(start, length, count, this); |
544 } | 601 } |
545 | 602 |
546 private: | 603 private: |
547 PixelPlacerInterface* const fNext; | 604 SkLinearBitmapPipeline::PixelPlacerInterface* const fNext; |
548 SourceStrategy fStrategy; | 605 SourceStrategy fStrategy; |
549 }; | 606 }; |
550 | 607 |
551 static BilerpProcessorInterface* choose_pixel_sampler( | 608 static SkLinearBitmapPipeline::BilerpProcessorInterface* choose_pixel_sampler( |
552 PixelPlacerInterface* next, | 609 SkLinearBitmapPipeline::PixelPlacerInterface* next, |
553 const SkPixmap& srcPixmap, | 610 const SkPixmap& srcPixmap, |
554 SkLinearBitmapPipeline::SampleStage* sampleStage) { | 611 SkLinearBitmapPipeline::SampleStage* sampleStage) { |
555 const SkImageInfo& imageInfo = srcPixmap.info(); | 612 const SkImageInfo& imageInfo = srcPixmap.info(); |
556 switch (imageInfo.colorType()) { | 613 switch (imageInfo.colorType()) { |
557 case kRGBA_8888_SkColorType: | 614 case kRGBA_8888_SkColorType: |
558 case kBGRA_8888_SkColorType: | 615 case kBGRA_8888_SkColorType: |
559 if (kN32_SkColorType == imageInfo.colorType()) { | 616 if (kN32_SkColorType == imageInfo.colorType()) { |
560 if (imageInfo.profileType() == kSRGB_SkColorProfileType) { | 617 if (imageInfo.profileType() == kSRGB_SkColorProfileType) { |
561 sampleStage->Initialize<Sampler<Passthrough8888<kSRGB_SkColo rProfileType>>>( | 618 sampleStage->Initialize<Sampler<Passthrough8888<kSRGB_SkColo rProfileType>>>( |
562 next, static_cast<int>(srcPixmap.rowBytes() / 4), | 619 next, static_cast<int>(srcPixmap.rowBytes() / 4), |
563 srcPixmap.addr32()); | 620 srcPixmap.addr32()); |
564 } else { | 621 } else { |
565 sampleStage->Initialize<Sampler<Passthrough8888<kLinear_SkCo lorProfileType>>>( | 622 sampleStage->Initialize<Sampler<Passthrough8888<kLinear_SkCo lorProfileType>>>( |
566 next, static_cast<int>(srcPixmap.rowBytes() / 4), | 623 next, static_cast<int>(srcPixmap.rowBytes() / 4), |
567 srcPixmap.addr32()); | 624 srcPixmap.addr32()); |
568 } | 625 } |
569 } else { | 626 } else { |
570 SkFAIL("Not implemented. No 8888 Swizzle"); | 627 SkFAIL("Not implemented. No 8888 Swizzle"); |
571 } | 628 } |
572 break; | 629 break; |
573 default: | 630 default: |
574 SkFAIL("Not implemented. Unsupported src"); | 631 SkFAIL("Not implemented. Unsupported src"); |
575 break; | 632 break; |
576 } | 633 } |
577 return sampleStage->get(); | 634 return sampleStage->get(); |
578 } | 635 } |
579 | 636 |
580 template <SkAlphaType alphaType> | 637 template <SkAlphaType alphaType> |
581 class PlaceFPPixel final : public PixelPlacerInterface { | 638 class PlaceFPPixel final : public SkLinearBitmapPipeline::PixelPlacerInterface { |
582 public: | 639 public: |
583 void placePixel(Sk4fArg pixel) override { | 640 void VECTORCALL placePixel(Sk4f pixel) override { |
584 PlacePixel(fDst, pixel, 0); | 641 PlacePixel(fDst, pixel, 0); |
585 fDst += 1; | 642 fDst += 1; |
586 } | 643 } |
587 | 644 |
588 void place4Pixels(Sk4fArg p0, Sk4fArg p1, Sk4fArg p2, Sk4fArg p3) override { | 645 void VECTORCALL place4Pixels(Sk4f p0, Sk4f p1, Sk4f p2, Sk4f p3) override { |
589 SkPM4f* dst = fDst; | 646 SkPM4f* dst = fDst; |
590 PlacePixel(dst, p0, 0); | 647 PlacePixel(dst, p0, 0); |
591 PlacePixel(dst, p1, 1); | 648 PlacePixel(dst, p1, 1); |
592 PlacePixel(dst, p2, 2); | 649 PlacePixel(dst, p2, 2); |
593 PlacePixel(dst, p3, 3); | 650 PlacePixel(dst, p3, 3); |
594 fDst += 4; | 651 fDst += 4; |
595 } | 652 } |
596 | 653 |
597 void setDestination(SkPM4f* dst) override { | 654 void setDestination(SkPM4f* dst) override { |
598 fDst = dst; | 655 fDst = dst; |
599 } | 656 } |
600 | 657 |
601 private: | 658 private: |
602 static void PlacePixel(SkPM4f* dst, Sk4fArg pixel, int index) { | 659 static void VECTORCALL PlacePixel(SkPM4f* dst, Sk4f pixel, int index) { |
603 Sk4f newPixel = pixel; | 660 Sk4f newPixel = pixel; |
604 if (alphaType == kUnpremul_SkAlphaType) { | 661 if (alphaType == kUnpremul_SkAlphaType) { |
605 newPixel = Premultiply(pixel); | 662 newPixel = Premultiply(pixel); |
606 } | 663 } |
607 newPixel.store(dst + index); | 664 newPixel.store(dst + index); |
608 } | 665 } |
609 static Sk4f Premultiply(Sk4fArg pixel) { | 666 static Sk4f VECTORCALL Premultiply(Sk4f pixel) { |
610 float alpha = pixel[3]; | 667 float alpha = pixel[3]; |
611 return pixel * Sk4f{alpha, alpha, alpha, 1.0f}; | 668 return pixel * Sk4f{alpha, alpha, alpha, 1.0f}; |
612 } | 669 } |
613 | 670 |
614 SkPM4f* fDst; | 671 SkPM4f* fDst; |
615 }; | 672 }; |
616 | 673 |
617 static PixelPlacerInterface* choose_pixel_placer( | 674 static SkLinearBitmapPipeline::PixelPlacerInterface* choose_pixel_placer( |
618 SkAlphaType alphaType, | 675 SkAlphaType alphaType, |
619 SkLinearBitmapPipeline::PixelStage* placerStage) { | 676 SkLinearBitmapPipeline::PixelStage* placerStage) { |
620 if (alphaType == kUnpremul_SkAlphaType) { | 677 if (alphaType == kUnpremul_SkAlphaType) { |
621 placerStage->Initialize<PlaceFPPixel<kUnpremul_SkAlphaType>>(); | 678 placerStage->Initialize<PlaceFPPixel<kUnpremul_SkAlphaType>>(); |
622 } else { | 679 } else { |
623 // kOpaque_SkAlphaType is treated the same as kPremul_SkAlphaType | 680 // kOpaque_SkAlphaType is treated the same as kPremul_SkAlphaType |
624 placerStage->Initialize<PlaceFPPixel<kPremul_SkAlphaType>>(); | 681 placerStage->Initialize<PlaceFPPixel<kPremul_SkAlphaType>>(); |
625 } | 682 } |
626 return placerStage->get(); | 683 return placerStage->get(); |
627 } | 684 } |
685 } // namespace | |
686 | |
687 SkLinearBitmapPipeline::~SkLinearBitmapPipeline() {} | |
628 | 688 |
629 SkLinearBitmapPipeline::SkLinearBitmapPipeline( | 689 SkLinearBitmapPipeline::SkLinearBitmapPipeline( |
630 const SkMatrix& inverse, | 690 const SkMatrix& inverse, |
631 SkFilterQuality filterQuality, | 691 SkFilterQuality filterQuality, |
632 SkShader::TileMode xTile, SkShader::TileMode yTile, | 692 SkShader::TileMode xTile, SkShader::TileMode yTile, |
633 const SkPixmap& srcPixmap) { | 693 const SkPixmap& srcPixmap) { |
634 SkSize size = SkSize::Make(srcPixmap.width(), srcPixmap.height()); | 694 SkSize size = SkSize::Make(srcPixmap.width(), srcPixmap.height()); |
635 const SkImageInfo& srcImageInfo = srcPixmap.info(); | 695 const SkImageInfo& srcImageInfo = srcPixmap.info(); |
636 | 696 |
637 // As the stages are built, the chooser function may skip a stage. For examp le, with the | 697 // As the stages are built, the chooser function may skip a stage. For examp le, with the |
(...skipping 13 matching lines...) Expand all Loading... | |
651 if (count == 1) { | 711 if (count == 1) { |
652 fFirstStage->pointListFew(1, Sk4f{x + 0.5f}, Sk4f{y + 0.5f}); | 712 fFirstStage->pointListFew(1, Sk4f{x + 0.5f}, Sk4f{y + 0.5f}); |
653 } else { | 713 } else { |
654 // The count and length arguments start out in a precise relation in ord er to keep the | 714 // The count and length arguments start out in a precise relation in ord er to keep the |
655 // math correct through the different stages. Count is the number of pix el to produce. | 715 // math correct through the different stages. Count is the number of pix el to produce. |
656 // Since the code samples at pixel centers, length is the distance from the center of the | 716 // Since the code samples at pixel centers, length is the distance from the center of the |
657 // first pixel to the center of the last pixel. This implies that length is count-1. | 717 // first pixel to the center of the last pixel. This implies that length is count-1. |
658 fFirstStage->pointSpan(SkPoint{x + 0.5f, y + 0.5f}, count - 1, count); | 718 fFirstStage->pointSpan(SkPoint{x + 0.5f, y + 0.5f}, count - 1, count); |
659 } | 719 } |
660 } | 720 } |
OLD | NEW |