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

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

Issue 1722703002: Add spans for matrix ops. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Switch to maybeProcessSpan. Created 4 years, 10 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 | « no previous file | no next file » | 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 #include "SkPM4f.h" 9 #include "SkPM4f.h"
10 10
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
47 while (count >= 4) { 47 while (count >= 4) {
48 stage->pointList4(Xs, Ys); 48 stage->pointList4(Xs, Ys);
49 Xs = Xs + fourDx; 49 Xs = Xs + fourDx;
50 count -= 4; 50 count -= 4;
51 } 51 }
52 if (count > 0) { 52 if (count > 0) {
53 stage->pointListFew(count, Xs, Ys); 53 stage->pointListFew(count, Xs, Ys);
54 } 54 }
55 } 55 }
56 56
57 // PointProcessor uses a strategy to help complete the work of the different sta ges. The strategy
58 // must implement the following methods:
59 // * processPoints(xs, ys) - must mutate the xs and ys for the stage.
60 // * maybeProcessSpan(start, length, count) - This represents a horizontal serie s of pixels
61 // to work over.
62 // start - is the starting pixel. This is in destination space before the matr ix stage, and in
63 // source space after the matrix stage.
64 // 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.
66 // count - the number of pixels in source space to produce.
67 // next - a pointer to the next stage.
68 // maybeProcessSpan - returns false if it can not process the span and needs t o fallback to
69 // point lists for processing.
57 template<typename Strategy, typename Next> 70 template<typename Strategy, typename Next>
58 class PointProcessor final : public PointProcessorInterface { 71 class PointProcessor final : public PointProcessorInterface {
59 public: 72 public:
60 template <typename... Args> 73 template <typename... Args>
61 PointProcessor(Next* next, Args&&... args) 74 PointProcessor(Next* next, Args&&... args)
62 : fNext{next} 75 : fNext{next}
63 , fStrategy{std::forward<Args>(args)...}{ } 76 , fStrategy{std::forward<Args>(args)...}{ }
64 77
65 void pointListFew(int n, Sk4fArg xs, Sk4fArg ys) override { 78 void pointListFew(int n, Sk4fArg xs, Sk4fArg ys) override {
66 Sk4f newXs = xs; 79 Sk4f newXs = xs;
67 Sk4f newYs = ys; 80 Sk4f newYs = ys;
68 fStrategy.processPoints(&newXs, &newYs); 81 fStrategy.processPoints(&newXs, &newYs);
69 fNext->pointListFew(n, newXs, newYs); 82 fNext->pointListFew(n, newXs, newYs);
70 } 83 }
71 84
72 void pointList4(Sk4fArg xs, Sk4fArg ys) override { 85 void pointList4(Sk4fArg xs, Sk4fArg ys) override {
73 Sk4f newXs = xs; 86 Sk4f newXs = xs;
74 Sk4f newYs = ys; 87 Sk4f newYs = ys;
75 fStrategy.processPoints(&newXs, &newYs); 88 fStrategy.processPoints(&newXs, &newYs);
76 fNext->pointList4(newXs, newYs); 89 fNext->pointList4(newXs, newYs);
77 } 90 }
78 91
79 void pointSpan(SkPoint start, SkScalar length, int count) override { 92 void pointSpan(SkPoint start, SkScalar length, int count) override {
80 span_fallback(start, length, count, this); 93 if (!fStrategy.maybeProcessSpan(start, length, count, fNext)) {
94 span_fallback(start, length, count, this);
95 }
81 } 96 }
82 97
83 private: 98 private:
84 Next* const fNext; 99 Next* const fNext;
85 Strategy fStrategy; 100 Strategy fStrategy;
86 }; 101 };
87 102
103 // See PointProcessor for responsibilities of Strategy.
88 template<typename Strategy, typename Next> 104 template<typename Strategy, typename Next>
89 class BilerpProcessor final : public BilerpProcessorInterface { 105 class BilerpProcessor final : public BilerpProcessorInterface {
90 public: 106 public:
91 template <typename... Args> 107 template <typename... Args>
92 BilerpProcessor(Next* next, Args&&... args) 108 BilerpProcessor(Next* next, Args&&... args)
93 : fNext{next} 109 : fNext{next}
94 , fStrategy{std::forward<Args>(args)...}{ } 110 , fStrategy{std::forward<Args>(args)...}{ }
95 111
96 void pointListFew(int n, Sk4fArg xs, Sk4fArg ys) override { 112 void pointListFew(int n, Sk4fArg xs, Sk4fArg ys) override {
97 Sk4f newXs = xs; 113 Sk4f newXs = xs;
(...skipping 10 matching lines...) Expand all
108 } 124 }
109 125
110 void bilerpList(Sk4fArg xs, Sk4fArg ys) override { 126 void bilerpList(Sk4fArg xs, Sk4fArg ys) override {
111 Sk4f newXs = xs; 127 Sk4f newXs = xs;
112 Sk4f newYs = ys; 128 Sk4f newYs = ys;
113 fStrategy.processPoints(&newXs, &newYs); 129 fStrategy.processPoints(&newXs, &newYs);
114 fNext->bilerpList(newXs, newYs); 130 fNext->bilerpList(newXs, newYs);
115 } 131 }
116 132
117 void pointSpan(SkPoint start, SkScalar length, int count) override { 133 void pointSpan(SkPoint start, SkScalar length, int count) override {
118 span_fallback(start, length, count, this); 134 if (!fStrategy.maybeProcessSpan(start, length, count, fNext)) {
135 span_fallback(start, length, count, this);
136 }
119 } 137 }
120 138
121 private: 139 private:
122 Next* const fNext; 140 Next* const fNext;
123 Strategy fStrategy; 141 Strategy fStrategy;
124 }; 142 };
125 143
126 class SkippedStage final : public BilerpProcessorInterface { 144 class SkippedStage final : public BilerpProcessorInterface {
127 void pointListFew(int n, Sk4fArg xs, Sk4fArg ys) override { 145 void pointListFew(int n, Sk4fArg xs, Sk4fArg ys) override {
128 SkFAIL("Skipped stage."); 146 SkFAIL("Skipped stage.");
129 } 147 }
130 void pointList4(Sk4fArg Xs, Sk4fArg Ys) override { 148 void pointList4(Sk4fArg Xs, Sk4fArg Ys) override {
131 SkFAIL("Skipped stage."); 149 SkFAIL("Skipped stage.");
132 } 150 }
133 void bilerpList(Sk4fArg xs, Sk4fArg ys) override { 151 void bilerpList(Sk4fArg xs, Sk4fArg ys) override {
134 SkFAIL("Skipped stage."); 152 SkFAIL("Skipped stage.");
135 } 153 }
136 void pointSpan(SkPoint start, SkScalar length, int count) override { 154 void pointSpan(SkPoint start, SkScalar length, int count) override {
137 SkFAIL("Skipped stage."); 155 SkFAIL("Skipped stage.");
138 } 156 }
139 }; 157 };
140 158
141 class TranslateMatrixStrategy { 159 class TranslateMatrixStrategy {
142 public: 160 public:
143 TranslateMatrixStrategy(SkVector offset) 161 TranslateMatrixStrategy(SkVector offset)
144 : fXOffset{X(offset)} 162 : fXOffset{X(offset)}
145 , fYOffset{Y(offset)} { } 163 , fYOffset{Y(offset)} { }
164
146 void processPoints(Sk4f* xs, Sk4f* ys) { 165 void processPoints(Sk4f* xs, Sk4f* ys) {
147 *xs = *xs + fXOffset; 166 *xs = *xs + fXOffset;
148 *ys = *ys + fYOffset; 167 *ys = *ys + fYOffset;
149 } 168 }
150 169
170 template <typename Next>
171 bool maybeProcessSpan(SkPoint start, SkScalar length, int count, Next* next) {
172 next->pointSpan(start + SkPoint{fXOffset[0], fYOffset[0]}, length, count );
173 return true;
174 }
175
151 private: 176 private:
152 const Sk4f fXOffset, fYOffset; 177 const Sk4f fXOffset, fYOffset;
153 }; 178 };
154 template <typename Next = PointProcessorInterface> 179 template <typename Next = PointProcessorInterface>
155 using TranslateMatrix = PointProcessor<TranslateMatrixStrategy, Next>; 180 using TranslateMatrix = PointProcessor<TranslateMatrixStrategy, Next>;
156 181
157 class ScaleMatrixStrategy { 182 class ScaleMatrixStrategy {
158 public: 183 public:
159 ScaleMatrixStrategy(SkVector offset, SkVector scale) 184 ScaleMatrixStrategy(SkVector offset, SkVector scale)
160 : fXOffset{X(offset)}, fYOffset{Y(offset)} 185 : fXOffset{X(offset)}, fYOffset{Y(offset)}
161 , fXScale{X(scale)}, fYScale{Y(scale)} { } 186 , fXScale{X(scale)}, fYScale{Y(scale)} { }
162 void processPoints(Sk4f* xs, Sk4f* ys) { 187 void processPoints(Sk4f* xs, Sk4f* ys) {
163 *xs = *xs * fXScale + fXOffset; 188 *xs = *xs * fXScale + fXOffset;
164 *ys = *ys * fYScale + fYOffset; 189 *ys = *ys * fYScale + fYOffset;
165 } 190 }
166 191
192 template <typename Next>
193 bool maybeProcessSpan(SkPoint start, SkScalar length, int count, Next* next) {
194 SkPoint newStart =
195 SkPoint{X(start) * fXScale[0] + fXOffset[0], Y(start) * fYScale[0] + fYOffset[0]};
196 SkScalar newLength = length * fXScale[0];
197 next->pointSpan(newStart, newLength, count);
198 return true;
199 }
200
167 private: 201 private:
168 const Sk4f fXOffset, fYOffset; 202 const Sk4f fXOffset, fYOffset;
169 const Sk4f fXScale, fYScale; 203 const Sk4f fXScale, fYScale;
170 }; 204 };
171 template <typename Next = PointProcessorInterface> 205 template <typename Next = PointProcessorInterface>
172 using ScaleMatrix = PointProcessor<ScaleMatrixStrategy, Next>; 206 using ScaleMatrix = PointProcessor<ScaleMatrixStrategy, Next>;
173 207
174 class AffineMatrixStrategy { 208 class AffineMatrixStrategy {
175 public: 209 public:
176 AffineMatrixStrategy(SkVector offset, SkVector scale, SkVector skew) 210 AffineMatrixStrategy(SkVector offset, SkVector scale, SkVector skew)
177 : fXOffset{X(offset)}, fYOffset{Y(offset)} 211 : fXOffset{X(offset)}, fYOffset{Y(offset)}
178 , fXScale{X(scale)}, fYScale{Y(scale)} 212 , fXScale{X(scale)}, fYScale{Y(scale)}
179 , fXSkew{X(skew)}, fYSkew{Y(skew)} { } 213 , fXSkew{X(skew)}, fYSkew{Y(skew)} { }
180 void processPoints(Sk4f* xs, Sk4f* ys) { 214 void processPoints(Sk4f* xs, Sk4f* ys) {
181 Sk4f newXs = fXScale * *xs + fXSkew * *ys + fXOffset; 215 Sk4f newXs = fXScale * *xs + fXSkew * *ys + fXOffset;
182 Sk4f newYs = fYSkew * *xs + fYScale * *ys + fYOffset; 216 Sk4f newYs = fYSkew * *xs + fYScale * *ys + fYOffset;
183 217
184 *xs = newXs; 218 *xs = newXs;
185 *ys = newYs; 219 *ys = newYs;
186 } 220 }
187 221
222 template <typename Next>
223 bool maybeProcessSpan(SkPoint start, SkScalar length, int count, Next* next) {
224 return false;
225 }
226
188 private: 227 private:
189 const Sk4f fXOffset, fYOffset; 228 const Sk4f fXOffset, fYOffset;
190 const Sk4f fXScale, fYScale; 229 const Sk4f fXScale, fYScale;
191 const Sk4f fXSkew, fYSkew; 230 const Sk4f fXSkew, fYSkew;
192 }; 231 };
193 template <typename Next = PointProcessorInterface> 232 template <typename Next = PointProcessorInterface>
194 using AffineMatrix = PointProcessor<AffineMatrixStrategy, Next>; 233 using AffineMatrix = PointProcessor<AffineMatrixStrategy, Next>;
195 234
196 static PointProcessorInterface* choose_matrix( 235 static PointProcessorInterface* choose_matrix(
197 PointProcessorInterface* next, 236 PointProcessorInterface* next,
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
279 : fXMin{0.0f} 318 : fXMin{0.0f}
280 , fYMin{0.0f} 319 , fYMin{0.0f}
281 , fXMax{X(max) - 1.0f} 320 , fXMax{X(max) - 1.0f}
282 , fYMax{Y(max) - 1.0f} { } 321 , fYMax{Y(max) - 1.0f} { }
283 322
284 void processPoints(Sk4f* xs, Sk4f* ys) { 323 void processPoints(Sk4f* xs, Sk4f* ys) {
285 *xs = Sk4f::Min(Sk4f::Max(*xs, fXMin), fXMax); 324 *xs = Sk4f::Min(Sk4f::Max(*xs, fXMin), fXMax);
286 *ys = Sk4f::Min(Sk4f::Max(*ys, fYMin), fYMax); 325 *ys = Sk4f::Min(Sk4f::Max(*ys, fYMin), fYMax);
287 } 326 }
288 327
328 template <typename Next>
329 bool maybeProcessSpan(SkPoint start, SkScalar length, int count, Next* next) {
330 return false;
331 }
332
289 private: 333 private:
290 const Sk4f fXMin{SK_FloatNegativeInfinity}; 334 const Sk4f fXMin{SK_FloatNegativeInfinity};
291 const Sk4f fYMin{SK_FloatNegativeInfinity}; 335 const Sk4f fYMin{SK_FloatNegativeInfinity};
292 const Sk4f fXMax{SK_FloatInfinity}; 336 const Sk4f fXMax{SK_FloatInfinity};
293 const Sk4f fYMax{SK_FloatInfinity}; 337 const Sk4f fYMax{SK_FloatInfinity};
294 }; 338 };
295 template <typename Next = BilerpProcessorInterface> 339 template <typename Next = BilerpProcessorInterface>
296 using Clamp = BilerpProcessor<ClampStrategy, Next>; 340 using Clamp = BilerpProcessor<ClampStrategy, Next>;
297 341
298 class RepeatStrategy { 342 class RepeatStrategy {
299 public: 343 public:
300 RepeatStrategy(X max) : fXMax{max}, fXInvMax{1.0f/max} { } 344 RepeatStrategy(X max) : fXMax{max}, fXInvMax{1.0f/max} { }
301 RepeatStrategy(Y max) : fYMax{max}, fYInvMax{1.0f/max} { } 345 RepeatStrategy(Y max) : fYMax{max}, fYInvMax{1.0f/max} { }
302 RepeatStrategy(SkSize max) 346 RepeatStrategy(SkSize max)
303 : fXMax{X(max)} 347 : fXMax{X(max)}
304 , fXInvMax{1.0f / X(max)} 348 , fXInvMax{1.0f / X(max)}
305 , fYMax{Y(max)} 349 , fYMax{Y(max)}
306 , fYInvMax{1.0f / Y(max)} { } 350 , fYInvMax{1.0f / Y(max)} { }
307 351
308 void processPoints(Sk4f* xs, Sk4f* ys) { 352 void processPoints(Sk4f* xs, Sk4f* ys) {
309 Sk4f divX = (*xs * fXInvMax).floor(); 353 Sk4f divX = (*xs * fXInvMax).floor();
310 Sk4f divY = (*ys * fYInvMax).floor(); 354 Sk4f divY = (*ys * fYInvMax).floor();
311 Sk4f baseX = (divX * fXMax); 355 Sk4f baseX = (divX * fXMax);
312 Sk4f baseY = (divY * fYMax); 356 Sk4f baseY = (divY * fYMax);
313 *xs = *xs - baseX; 357 *xs = *xs - baseX;
314 *ys = *ys - baseY; 358 *ys = *ys - baseY;
315 } 359 }
316 360
361 template <typename Next>
362 bool maybeProcessSpan(SkPoint start, SkScalar length, int count, Next* next) {
363 return false;
364 }
365
317 private: 366 private:
318 const Sk4f fXMax{0.0f}; 367 const Sk4f fXMax{0.0f};
319 const Sk4f fXInvMax{0.0f}; 368 const Sk4f fXInvMax{0.0f};
320 const Sk4f fYMax{0.0f}; 369 const Sk4f fYMax{0.0f};
321 const Sk4f fYInvMax{0.0f}; 370 const Sk4f fYInvMax{0.0f};
322 }; 371 };
323 372
324 template <typename Next = BilerpProcessorInterface> 373 template <typename Next = BilerpProcessorInterface>
325 using Repeat = BilerpProcessor<RepeatStrategy, Next>; 374 using Repeat = BilerpProcessor<RepeatStrategy, Next>;
326 375
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after
602 if (count == 1) { 651 if (count == 1) {
603 fFirstStage->pointListFew(1, Sk4f{x + 0.5f}, Sk4f{y + 0.5f}); 652 fFirstStage->pointListFew(1, Sk4f{x + 0.5f}, Sk4f{y + 0.5f});
604 } else { 653 } else {
605 // The count and length arguments start out in a precise relation in ord er to keep the 654 // The count and length arguments start out in a precise relation in ord er to keep the
606 // math correct through the different stages. Count is the number of pix el to produce. 655 // math correct through the different stages. Count is the number of pix el to produce.
607 // Since the code samples at pixel centers, length is the distance from the center of the 656 // Since the code samples at pixel centers, length is the distance from the center of the
608 // first pixel to the center of the last pixel. This implies that length is count-1. 657 // first pixel to the center of the last pixel. This implies that length is count-1.
609 fFirstStage->pointSpan(SkPoint{x + 0.5f, y + 0.5f}, count - 1, count); 658 fFirstStage->pointSpan(SkPoint{x + 0.5f, y + 0.5f}, count - 1, count);
610 } 659 }
611 } 660 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698