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

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

Issue 1877483002: Add clone to Stage. Rename place to mix and PolymorphicUnion to Stage. Cleanup. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Address review comments. Created 4 years, 8 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_sample.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 "SkPM4f.h" 10 #include "SkPM4f.h"
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
58 // A span represents sample points that have been mapped from destination sp ace to source 58 // A span represents sample points that have been mapped from destination sp ace to source
59 // space. Each sample point is then expanded to the four bilerp points by ad d +/- 0.5. The 59 // space. Each sample point is then expanded to the four bilerp points by ad d +/- 0.5. The
60 // resulting Y values my be off the tile. When y +/- 0.5 are more than 1 apa rt because of 60 // resulting Y values my be off the tile. When y +/- 0.5 are more than 1 apa rt because of
61 // tiling, the second Y is used to denote the retiled Y value. 61 // tiling, the second Y is used to denote the retiled Y value.
62 virtual void bilerpSpan(Span span, SkScalar y) = 0; 62 virtual void bilerpSpan(Span span, SkScalar y) = 0;
63 }; 63 };
64 64
65 class SkLinearBitmapPipeline::DestinationInterface { 65 class SkLinearBitmapPipeline::DestinationInterface {
66 public: 66 public:
67 virtual ~DestinationInterface() { } 67 virtual ~DestinationInterface() { }
68 virtual void setDestination(void* dst, int count) = 0;
69 };
70
71 class SkLinearBitmapPipeline::PixelPlacerInterface
72 : public SkLinearBitmapPipeline::DestinationInterface {
73 public:
74 virtual ~PixelPlacerInterface() { }
75 // Count is normally not needed, but in these early stages of development it is useful to 68 // Count is normally not needed, but in these early stages of development it is useful to
76 // check bounds. 69 // check bounds.
77 // TODO(herb): 4/6/2016 - remove count when code is stable. 70 // TODO(herb): 4/6/2016 - remove count when code is stable.
78 virtual void setDestination(void* dst, int count) = 0; 71 virtual void setDestination(void* dst, int count) = 0;
79 virtual void VECTORCALL placePixel(Sk4f pixel0) = 0;
80 virtual void VECTORCALL place4Pixels(Sk4f p0, Sk4f p1, Sk4f p2, Sk4f p3) = 0 ;
81 }; 72 };
82 73
74 class SkLinearBitmapPipeline::BlendProcessorInterface
75 : public SkLinearBitmapPipeline::DestinationInterface {
76 public:
77 virtual void VECTORCALL blendPixel(Sk4f pixel0) = 0;
78 virtual void VECTORCALL blend4Pixels(Sk4f p0, Sk4f p1, Sk4f p2, Sk4f p3) = 0 ;
79 };
80
81 //////////////////////////////////////////////////////////////////////////////// ////////////////////
82 // SkLinearBitmapPipeline::Stage
83 template<typename Base, size_t kSize, typename Next>
84 SkLinearBitmapPipeline::Stage<Base, kSize, Next>::~Stage() {
85 if (fIsInitialized) {
86 this->get()->~Base();
87 }
88 }
89
90 template<typename Base, size_t kSize, typename Next>
91 template<typename Variant, typename... Args>
92 void SkLinearBitmapPipeline::Stage<Base, kSize, Next>::initStage(Next* next, Arg s&& ... args) {
93 SkASSERTF(sizeof(Variant) <= sizeof(fSpace),
94 "Size Variant: %d, Space: %d", sizeof(Variant), sizeof(fSpace));
95
96 new (&fSpace) Variant(next, std::forward<Args>(args)...);
97 fStageCloner = [this](Next* nextClone, void* addr) {
98 new (addr) Variant(nextClone, (const Variant&)*this->get());
99 };
100 fIsInitialized = true;
101 };
102
103 template<typename Base, size_t kSize, typename Next>
104 template<typename Variant, typename... Args>
105 void SkLinearBitmapPipeline::Stage<Base, kSize, Next>::initSink(Args&& ... args) {
106 SkASSERTF(sizeof(Variant) <= sizeof(fSpace),
107 "Size Variant: %d, Space: %d", sizeof(Variant), sizeof(fSpace));
108 new (&fSpace) Variant(std::forward<Args>(args)...);
109 fIsInitialized = true;
110 };
111
112 template<typename Base, size_t kSize, typename Next>
113 template <typename To, typename From>
114 To* SkLinearBitmapPipeline::Stage<Base, kSize, Next>::getInterface() {
115 From* down = static_cast<From*>(this->get());
116 return static_cast<To*>(down);
117 }
118
119 template<typename Base, size_t kSize, typename Next>
120 Base* SkLinearBitmapPipeline::Stage<Base, kSize, Next>::cloneStageTo(
121 Next* next, Stage* cloneToStage) const
122 {
123 if (!fIsInitialized) return nullptr;
124 fStageCloner(next, &cloneToStage->fSpace);
125 return cloneToStage->get();
126 }
127
83 namespace { 128 namespace {
84 129
85 //////////////////////////////////////////////////////////////////////////////// //////////////////// 130 //////////////////////////////////////////////////////////////////////////////// ////////////////////
86 // Matrix Stage 131 // Matrix Stage
87 // PointProcessor uses a strategy to help complete the work of the different sta ges. The strategy 132 // PointProcessor uses a strategy to help complete the work of the different sta ges. The strategy
88 // must implement the following methods: 133 // must implement the following methods:
89 // * processPoints(xs, ys) - must mutate the xs and ys for the stage. 134 // * processPoints(xs, ys) - must mutate the xs and ys for the stage.
90 // * maybeProcessSpan(span, next) - This represents a horizontal series of pixel s 135 // * maybeProcessSpan(span, next) - This represents a horizontal series of pixel s
91 // to work over. 136 // to work over.
92 // span - encapsulation of span. 137 // span - encapsulation of span.
93 // next - a pointer to the next stage. 138 // next - a pointer to the next stage.
94 // maybeProcessSpan - returns false if it can not process the span and needs t o fallback to 139 // maybeProcessSpan - returns false if it can not process the span and needs t o fallback to
95 // point lists for processing. 140 // point lists for processing.
96 template<typename Strategy, typename Next> 141 template<typename Strategy, typename Next>
97 class MatrixStage final : public SkLinearBitmapPipeline::PointProcessorInterface { 142 class MatrixStage final : public SkLinearBitmapPipeline::PointProcessorInterface {
98 public: 143 public:
99 template <typename... Args> 144 template <typename... Args>
100 MatrixStage(Next* next, Args&&... args) 145 MatrixStage(Next* next, Args&&... args)
101 : fNext{next} 146 : fNext{next}
102 , fStrategy{std::forward<Args>(args)...}{ } 147 , fStrategy{std::forward<Args>(args)...}{ }
103 148
149 MatrixStage(Next* next, const MatrixStage& stage)
150 : fNext{next}
151 , fStrategy{stage.fStrategy} { }
152
104 void VECTORCALL pointListFew(int n, Sk4s xs, Sk4s ys) override { 153 void VECTORCALL pointListFew(int n, Sk4s xs, Sk4s ys) override {
105 fStrategy.processPoints(&xs, &ys); 154 fStrategy.processPoints(&xs, &ys);
106 fNext->pointListFew(n, xs, ys); 155 fNext->pointListFew(n, xs, ys);
107 } 156 }
108 157
109 void VECTORCALL pointList4(Sk4s xs, Sk4s ys) override { 158 void VECTORCALL pointList4(Sk4s xs, Sk4s ys) override {
110 fStrategy.processPoints(&xs, &ys); 159 fStrategy.processPoints(&xs, &ys);
111 fNext->pointList4(xs, ys); 160 fNext->pointList4(xs, ys);
112 } 161 }
113 162
(...skipping 21 matching lines...) Expand all
135 184
136 template <typename Next = SkLinearBitmapPipeline::PointProcessorInterface> 185 template <typename Next = SkLinearBitmapPipeline::PointProcessorInterface>
137 using PerspectiveMatrix = MatrixStage<PerspectiveMatrixStrategy, Next>; 186 using PerspectiveMatrix = MatrixStage<PerspectiveMatrixStrategy, Next>;
138 187
139 188
140 static SkLinearBitmapPipeline::PointProcessorInterface* choose_matrix( 189 static SkLinearBitmapPipeline::PointProcessorInterface* choose_matrix(
141 SkLinearBitmapPipeline::PointProcessorInterface* next, 190 SkLinearBitmapPipeline::PointProcessorInterface* next,
142 const SkMatrix& inverse, 191 const SkMatrix& inverse,
143 SkLinearBitmapPipeline::MatrixStage* matrixProc) { 192 SkLinearBitmapPipeline::MatrixStage* matrixProc) {
144 if (inverse.hasPerspective()) { 193 if (inverse.hasPerspective()) {
145 matrixProc->Initialize<PerspectiveMatrix<>>( 194 matrixProc->initStage<PerspectiveMatrix<>>(
146 next, 195 next,
147 SkVector{inverse.getTranslateX(), inverse.getTranslateY()}, 196 SkVector{inverse.getTranslateX(), inverse.getTranslateY()},
148 SkVector{inverse.getScaleX(), inverse.getScaleY()}, 197 SkVector{inverse.getScaleX(), inverse.getScaleY()},
149 SkVector{inverse.getSkewX(), inverse.getSkewY()}, 198 SkVector{inverse.getSkewX(), inverse.getSkewY()},
150 SkVector{inverse.getPerspX(), inverse.getPerspY()}, 199 SkVector{inverse.getPerspX(), inverse.getPerspY()},
151 inverse.get(SkMatrix::kMPersp2)); 200 inverse.get(SkMatrix::kMPersp2));
152 } else if (inverse.getSkewX() != 0.0f || inverse.getSkewY() != 0.0f) { 201 } else if (inverse.getSkewX() != 0.0f || inverse.getSkewY() != 0.0f) {
153 matrixProc->Initialize<AffineMatrix<>>( 202 matrixProc->initStage<AffineMatrix<>>(
154 next, 203 next,
155 SkVector{inverse.getTranslateX(), inverse.getTranslateY()}, 204 SkVector{inverse.getTranslateX(), inverse.getTranslateY()},
156 SkVector{inverse.getScaleX(), inverse.getScaleY()}, 205 SkVector{inverse.getScaleX(), inverse.getScaleY()},
157 SkVector{inverse.getSkewX(), inverse.getSkewY()}); 206 SkVector{inverse.getSkewX(), inverse.getSkewY()});
158 } else if (inverse.getScaleX() != 1.0f || inverse.getScaleY() != 1.0f) { 207 } else if (inverse.getScaleX() != 1.0f || inverse.getScaleY() != 1.0f) {
159 matrixProc->Initialize<ScaleMatrix<>>( 208 matrixProc->initStage<ScaleMatrix<>>(
160 next, 209 next,
161 SkVector{inverse.getTranslateX(), inverse.getTranslateY()}, 210 SkVector{inverse.getTranslateX(), inverse.getTranslateY()},
162 SkVector{inverse.getScaleX(), inverse.getScaleY()}); 211 SkVector{inverse.getScaleX(), inverse.getScaleY()});
163 } else if (inverse.getTranslateX() != 0.0f || inverse.getTranslateY() != 0.0 f) { 212 } else if (inverse.getTranslateX() != 0.0f || inverse.getTranslateY() != 0.0 f) {
164 matrixProc->Initialize<TranslateMatrix<>>( 213 matrixProc->initStage<TranslateMatrix<>>(
165 next, 214 next,
166 SkVector{inverse.getTranslateX(), inverse.getTranslateY()}); 215 SkVector{inverse.getTranslateX(), inverse.getTranslateY()});
167 } else { 216 } else {
168 return next; 217 return next;
169 } 218 }
170 return matrixProc->get(); 219 return matrixProc->get();
171 } 220 }
172 221
173 //////////////////////////////////////////////////////////////////////////////// //////////////////// 222 //////////////////////////////////////////////////////////////////////////////// ////////////////////
174 // Tile Stage 223 // Tile Stage
175 224
176 template<typename XStrategy, typename YStrategy, typename Next> 225 template<typename XStrategy, typename YStrategy, typename Next>
177 class NearestTileStage final : public SkLinearBitmapPipeline::PointProcessorInte rface { 226 class NearestTileStage final : public SkLinearBitmapPipeline::PointProcessorInte rface {
178 public: 227 public:
179 template <typename... Args> 228 template <typename... Args>
180 NearestTileStage(Next* next, SkISize dimensions) 229 NearestTileStage(Next* next, SkISize dimensions)
181 : fNext{next} 230 : fNext{next}
182 , fXStrategy{dimensions.width()} 231 , fXStrategy{dimensions.width()}
183 , fYStrategy{dimensions.height()}{ } 232 , fYStrategy{dimensions.height()}{ }
184 233
234 NearestTileStage(Next* next, const NearestTileStage& stage)
235 : fNext{next}
236 , fXStrategy{stage.fXStrategy}
237 , fYStrategy{stage.fYStrategy} { }
238
185 void VECTORCALL pointListFew(int n, Sk4s xs, Sk4s ys) override { 239 void VECTORCALL pointListFew(int n, Sk4s xs, Sk4s ys) override {
186 fXStrategy.tileXPoints(&xs); 240 fXStrategy.tileXPoints(&xs);
187 fYStrategy.tileYPoints(&ys); 241 fYStrategy.tileYPoints(&ys);
188 fNext->pointListFew(n, xs, ys); 242 fNext->pointListFew(n, xs, ys);
189 } 243 }
190 244
191 void VECTORCALL pointList4(Sk4s xs, Sk4s ys) override { 245 void VECTORCALL pointList4(Sk4s xs, Sk4s ys) override {
192 fXStrategy.tileXPoints(&xs); 246 fXStrategy.tileXPoints(&xs);
193 fYStrategy.tileYPoints(&ys); 247 fYStrategy.tileYPoints(&ys);
194 fNext->pointList4(xs, ys); 248 fNext->pointList4(xs, ys);
(...skipping 16 matching lines...) Expand all
211 Next* const fNext; 265 Next* const fNext;
212 XStrategy fXStrategy; 266 XStrategy fXStrategy;
213 YStrategy fYStrategy; 267 YStrategy fYStrategy;
214 }; 268 };
215 269
216 template<typename XStrategy, typename YStrategy, typename Next> 270 template<typename XStrategy, typename YStrategy, typename Next>
217 class BilerpTileStage final : public SkLinearBitmapPipeline::PointProcessorInter face { 271 class BilerpTileStage final : public SkLinearBitmapPipeline::PointProcessorInter face {
218 public: 272 public:
219 template <typename... Args> 273 template <typename... Args>
220 BilerpTileStage(Next* next, SkISize dimensions) 274 BilerpTileStage(Next* next, SkISize dimensions)
221 : fXMax(dimensions.width()) 275 : fNext{next}
276 , fXMax(dimensions.width())
222 , fYMax(dimensions.height()) 277 , fYMax(dimensions.height())
223 , fNext{next}
224 , fXStrategy{dimensions.width()} 278 , fXStrategy{dimensions.width()}
225 , fYStrategy{dimensions.height()}{ } 279 , fYStrategy{dimensions.height()} { }
280
281 BilerpTileStage(Next* next, const BilerpTileStage& stage)
282 : fNext{next}
283 , fXMax{stage.fXMax}
284 , fYMax{stage.fYMax}
285 , fXStrategy{stage.fXStrategy}
286 , fYStrategy{stage.fYStrategy} { }
226 287
227 void VECTORCALL pointListFew(int n, Sk4s xs, Sk4s ys) override { 288 void VECTORCALL pointListFew(int n, Sk4s xs, Sk4s ys) override {
228 fXStrategy.tileXPoints(&xs); 289 fXStrategy.tileXPoints(&xs);
229 fYStrategy.tileYPoints(&ys); 290 fYStrategy.tileYPoints(&ys);
230 // TODO: check to see if xs and ys are in range then just call pointList Few on next. 291 // TODO: check to see if xs and ys are in range then just call pointList Few on next.
231 if (n >= 1) this->bilerpPoint(xs[0], ys[0]); 292 if (n >= 1) this->bilerpPoint(xs[0], ys[0]);
232 if (n >= 2) this->bilerpPoint(xs[1], ys[1]); 293 if (n >= 2) this->bilerpPoint(xs[1], ys[1]);
233 if (n >= 3) this->bilerpPoint(xs[2], ys[2]); 294 if (n >= 3) this->bilerpPoint(xs[2], ys[2]);
234 } 295 }
235 296
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
332 this->yProcessSpan(center); 393 this->yProcessSpan(center);
333 } 394 }
334 if (!leftEdge.isEmpty()) { 395 if (!leftEdge.isEmpty()) {
335 this->handleEdges(leftEdge, dx); 396 this->handleEdges(leftEdge, dx);
336 } 397 }
337 398
338 } 399 }
339 } 400 }
340 } 401 }
341 402
403 Next* const fNext;
342 SkScalar fXMax; 404 SkScalar fXMax;
343 SkScalar fYMax; 405 SkScalar fYMax;
344 Next* const fNext;
345 XStrategy fXStrategy; 406 XStrategy fXStrategy;
346 YStrategy fYStrategy; 407 YStrategy fYStrategy;
347 }; 408 };
348 409
349 template <typename XStrategy, typename YStrategy, typename Next> 410 template <typename XStrategy, typename YStrategy, typename Next>
350 void make_tile_stage( 411 void make_tile_stage(
351 SkFilterQuality filterQuality, SkISize dimensions, 412 SkFilterQuality filterQuality, SkISize dimensions,
352 Next* next, SkLinearBitmapPipeline::TileStage* tileStage) { 413 Next* next, SkLinearBitmapPipeline::TileStage* tileStage) {
353 if (filterQuality == kNone_SkFilterQuality) { 414 if (filterQuality == kNone_SkFilterQuality) {
354 tileStage->Initialize<NearestTileStage<XStrategy, YStrategy, Next>>(next , dimensions); 415 tileStage->initStage<NearestTileStage<XStrategy, YStrategy, Next>>(next, dimensions);
355 } else { 416 } else {
356 tileStage->Initialize<BilerpTileStage<XStrategy, YStrategy, Next>>(next, dimensions); 417 tileStage->initStage<BilerpTileStage<XStrategy, YStrategy, Next>>(next, dimensions);
357 } 418 }
358 } 419 }
359 template <typename XStrategy> 420 template <typename XStrategy>
360 void choose_tiler_ymode( 421 void choose_tiler_ymode(
361 SkShader::TileMode yMode, SkFilterQuality filterQuality, SkISize dimensions, 422 SkShader::TileMode yMode, SkFilterQuality filterQuality, SkISize dimensions,
362 SkLinearBitmapPipeline::SampleProcessorInterface* next, 423 SkLinearBitmapPipeline::SampleProcessorInterface* next,
363 SkLinearBitmapPipeline::TileStage* tileStage) { 424 SkLinearBitmapPipeline::TileStage* tileStage) {
364 switch (yMode) { 425 switch (yMode) {
365 case SkShader::kClamp_TileMode: 426 case SkShader::kClamp_TileMode:
366 make_tile_stage<XStrategy, YClampStrategy>(filterQuality, dimensions , next, tileStage); 427 make_tile_stage<XStrategy, YClampStrategy>(filterQuality, dimensions , next, tileStage);
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
406 467
407 //////////////////////////////////////////////////////////////////////////////// //////////////////// 468 //////////////////////////////////////////////////////////////////////////////// ////////////////////
408 // Source Sampling Stage 469 // Source Sampling Stage
409 template <typename SourceStrategy, typename Next> 470 template <typename SourceStrategy, typename Next>
410 class NearestNeighborSampler final : public SkLinearBitmapPipeline::SampleProces sorInterface { 471 class NearestNeighborSampler final : public SkLinearBitmapPipeline::SampleProces sorInterface {
411 public: 472 public:
412 template <typename... Args> 473 template <typename... Args>
413 NearestNeighborSampler(Next* next, Args&&... args) 474 NearestNeighborSampler(Next* next, Args&&... args)
414 : fSampler{next, std::forward<Args>(args)...} { } 475 : fSampler{next, std::forward<Args>(args)...} { }
415 476
477 NearestNeighborSampler(Next* next, const NearestNeighborSampler& sampler)
478 : fSampler{next, sampler.fSampler} { }
479
416 void VECTORCALL pointListFew(int n, Sk4s xs, Sk4s ys) override { 480 void VECTORCALL pointListFew(int n, Sk4s xs, Sk4s ys) override {
417 fSampler.nearestListFew(n, xs, ys); 481 fSampler.nearestListFew(n, xs, ys);
418 } 482 }
419 483
420 void VECTORCALL pointList4(Sk4s xs, Sk4s ys) override { 484 void VECTORCALL pointList4(Sk4s xs, Sk4s ys) override {
421 fSampler.nearestList4(xs, ys); 485 fSampler.nearestList4(xs, ys);
422 } 486 }
423 487
424 void pointSpan(Span span) override { 488 void pointSpan(Span span) override {
425 fSampler.nearestSpan(span); 489 fSampler.nearestSpan(span);
(...skipping 18 matching lines...) Expand all
444 GeneralSampler<SourceStrategy, Next> fSampler; 508 GeneralSampler<SourceStrategy, Next> fSampler;
445 }; 509 };
446 510
447 template <typename SourceStrategy, typename Next> 511 template <typename SourceStrategy, typename Next>
448 class BilerpSampler final : public SkLinearBitmapPipeline::SampleProcessorInterf ace { 512 class BilerpSampler final : public SkLinearBitmapPipeline::SampleProcessorInterf ace {
449 public: 513 public:
450 template <typename... Args> 514 template <typename... Args>
451 BilerpSampler(Next* next, Args&&... args) 515 BilerpSampler(Next* next, Args&&... args)
452 : fSampler{next, std::forward<Args>(args)...} { } 516 : fSampler{next, std::forward<Args>(args)...} { }
453 517
518 BilerpSampler(Next* next, const BilerpSampler& sampler)
519 : fSampler{next, sampler.fSampler} { }
520
454 void VECTORCALL pointListFew(int n, Sk4s xs, Sk4s ys) override { 521 void VECTORCALL pointListFew(int n, Sk4s xs, Sk4s ys) override {
455 fSampler.bilerpListFew(n, xs, ys); 522 fSampler.bilerpListFew(n, xs, ys);
456 } 523 }
457 524
458 void VECTORCALL pointList4(Sk4s xs, Sk4s ys) override { 525 void VECTORCALL pointList4(Sk4s xs, Sk4s ys) override {
459 fSampler.bilerpList4(xs, ys); 526 fSampler.bilerpList4(xs, ys);
460 } 527 }
461 528
462 void pointSpan(Span span) override { 529 void pointSpan(Span span) override {
463 fSampler.bilerpSpan(span); 530 fSampler.bilerpSpan(span);
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
547 private: 614 private:
548 const uint32_t* pixelAddress(int32_t x, int32_t y) { 615 const uint32_t* pixelAddress(int32_t x, int32_t y) {
549 return &fSrc[fWidth * y + x]; 616 return &fSrc[fWidth * y + x];
550 } 617 }
551 const uint32_t* const fSrc; 618 const uint32_t* const fSrc;
552 const int32_t fWidth; 619 const int32_t fWidth;
553 uint32_t* fDest; 620 uint32_t* fDest;
554 uint32_t* fEnd; 621 uint32_t* fEnd;
555 }; 622 };
556 623
557 using Placer = SkLinearBitmapPipeline::PixelPlacerInterface; 624 using Blender = SkLinearBitmapPipeline::BlendProcessorInterface;
558 625
559 template<template <typename, typename> class Sampler> 626 template<template <typename, typename> class Sampler>
560 static SkLinearBitmapPipeline::SampleProcessorInterface* choose_pixel_sampler_ba se( 627 static SkLinearBitmapPipeline::SampleProcessorInterface* choose_pixel_sampler_ba se(
561 Placer* next, 628 Blender* next,
562 const SkPixmap& srcPixmap, 629 const SkPixmap& srcPixmap,
563 SkLinearBitmapPipeline::SampleStage* sampleStage) { 630 SkLinearBitmapPipeline::SampleStage* sampleStage) {
564 const SkImageInfo& imageInfo = srcPixmap.info(); 631 const SkImageInfo& imageInfo = srcPixmap.info();
565 switch (imageInfo.colorType()) { 632 switch (imageInfo.colorType()) {
566 case kRGBA_8888_SkColorType: 633 case kRGBA_8888_SkColorType:
567 if (imageInfo.profileType() == kSRGB_SkColorProfileType) { 634 if (imageInfo.profileType() == kSRGB_SkColorProfileType) {
568 sampleStage->Initialize<Sampler<Pixel8888SRGB, Placer>>(next, sr cPixmap); 635 sampleStage->initStage<Sampler<Pixel8888SRGB, Blender>>(next, sr cPixmap);
569 } else { 636 } else {
570 sampleStage->Initialize<Sampler<Pixel8888LRGB, Placer>>(next, sr cPixmap); 637 sampleStage->initStage<Sampler<Pixel8888LRGB, Blender>>(next, sr cPixmap);
571 } 638 }
572 break; 639 break;
573 case kBGRA_8888_SkColorType: 640 case kBGRA_8888_SkColorType:
574 if (imageInfo.profileType() == kSRGB_SkColorProfileType) { 641 if (imageInfo.profileType() == kSRGB_SkColorProfileType) {
575 sampleStage->Initialize<Sampler<Pixel8888SBGR, Placer>>(next, sr cPixmap); 642 sampleStage->initStage<Sampler<Pixel8888SBGR, Blender>>(next, sr cPixmap);
576 } else { 643 } else {
577 sampleStage->Initialize<Sampler<Pixel8888LBGR, Placer>>(next, sr cPixmap); 644 sampleStage->initStage<Sampler<Pixel8888LBGR, Blender>>(next, sr cPixmap);
578 } 645 }
579 break; 646 break;
580 case kIndex_8_SkColorType: 647 case kIndex_8_SkColorType:
581 if (imageInfo.profileType() == kSRGB_SkColorProfileType) { 648 if (imageInfo.profileType() == kSRGB_SkColorProfileType) {
582 sampleStage->Initialize<Sampler<PixelIndex8SRGB, Placer>>(next, srcPixmap); 649 sampleStage->initStage<Sampler<PixelIndex8SRGB, Blender>>(next, srcPixmap);
583 } else { 650 } else {
584 sampleStage->Initialize<Sampler<PixelIndex8LRGB, Placer>>(next, srcPixmap); 651 sampleStage->initStage<Sampler<PixelIndex8LRGB, Blender>>(next, srcPixmap);
585 } 652 }
586 break; 653 break;
587 default: 654 default:
588 SkFAIL("Not implemented. Unsupported src"); 655 SkFAIL("Not implemented. Unsupported src");
589 break; 656 break;
590 } 657 }
591 return sampleStage->get(); 658 return sampleStage->get();
592 } 659 }
593 660
594 SkLinearBitmapPipeline::SampleProcessorInterface* choose_pixel_sampler( 661 SkLinearBitmapPipeline::SampleProcessorInterface* choose_pixel_sampler(
595 Placer* next, 662 Blender* next,
596 SkFilterQuality filterQuality, 663 SkFilterQuality filterQuality,
597 const SkPixmap& srcPixmap, 664 const SkPixmap& srcPixmap,
598 SkLinearBitmapPipeline::SampleStage* sampleStage) { 665 SkLinearBitmapPipeline::SampleStage* sampleStage)
666 {
599 if (filterQuality == kNone_SkFilterQuality) { 667 if (filterQuality == kNone_SkFilterQuality) {
600 return choose_pixel_sampler_base<NearestNeighborSampler>(next, srcPixmap , sampleStage); 668 return choose_pixel_sampler_base<NearestNeighborSampler>(next, srcPixmap , sampleStage);
601 } else { 669 } else {
602 return choose_pixel_sampler_base<BilerpSampler>(next, srcPixmap, sampleS tage); 670 return choose_pixel_sampler_base<BilerpSampler>(next, srcPixmap, sampleS tage);
603 } 671 }
604 } 672 }
605 673
606 //////////////////////////////////////////////////////////////////////////////// //////////////////// 674 //////////////////////////////////////////////////////////////////////////////// ////////////////////
607 // Pixel Placement Stage 675 // Pixel Blender Stage
608 template <SkAlphaType alphaType> 676 template <SkAlphaType alphaType>
609 class PlaceFPPixel final : public SkLinearBitmapPipeline::PixelPlacerInterface { 677 class SrcFPPixel final : public SkLinearBitmapPipeline::BlendProcessorInterface {
610 public: 678 public:
611 PlaceFPPixel(float postAlpha) : fPostAlpha{postAlpha} { } 679 SrcFPPixel(float postAlpha) : fPostAlpha{postAlpha} { }
612 680 SrcFPPixel(const SrcFPPixel& Blender) : fPostAlpha(Blender.fPostAlpha) {}
613 void VECTORCALL placePixel(Sk4f pixel) override { 681 void VECTORCALL blendPixel(Sk4f pixel) override {
614 SkASSERT(fDst + 1 <= fEnd ); 682 SkASSERT(fDst + 1 <= fEnd );
615 PlacePixel(fDst, pixel, 0); 683 SrcPixel(fDst, pixel, 0);
616 fDst += 1; 684 fDst += 1;
617 } 685 }
618 686
619 void VECTORCALL place4Pixels(Sk4f p0, Sk4f p1, Sk4f p2, Sk4f p3) override { 687 void VECTORCALL blend4Pixels(Sk4f p0, Sk4f p1, Sk4f p2, Sk4f p3) override {
620 SkASSERT(fDst + 4 <= fEnd); 688 SkASSERT(fDst + 4 <= fEnd);
621 SkPM4f* dst = fDst; 689 SkPM4f* dst = fDst;
622 PlacePixel(dst, p0, 0); 690 SrcPixel(dst, p0, 0);
623 PlacePixel(dst, p1, 1); 691 SrcPixel(dst, p1, 1);
624 PlacePixel(dst, p2, 2); 692 SrcPixel(dst, p2, 2);
625 PlacePixel(dst, p3, 3); 693 SrcPixel(dst, p3, 3);
626 fDst += 4; 694 fDst += 4;
627 } 695 }
628 696
629 void setDestination(void* dst, int count) override { 697 void setDestination(void* dst, int count) override {
630 fDst = static_cast<SkPM4f*>(dst); 698 fDst = static_cast<SkPM4f*>(dst);
631 fEnd = fDst + count; 699 fEnd = fDst + count;
632 } 700 }
633 701
634 private: 702 private:
635 void VECTORCALL PlacePixel(SkPM4f* dst, Sk4f pixel, int index) { 703 void VECTORCALL SrcPixel(SkPM4f* dst, Sk4f pixel, int index) {
636 Sk4f newPixel = pixel; 704 Sk4f newPixel = pixel;
637 if (alphaType == kUnpremul_SkAlphaType) { 705 if (alphaType == kUnpremul_SkAlphaType) {
638 newPixel = Premultiply(pixel); 706 newPixel = Premultiply(pixel);
639 } 707 }
640 newPixel = newPixel * fPostAlpha; 708 newPixel = newPixel * fPostAlpha;
641 newPixel.store(dst + index); 709 newPixel.store(dst + index);
642 } 710 }
643 static Sk4f VECTORCALL Premultiply(Sk4f pixel) { 711 static Sk4f VECTORCALL Premultiply(Sk4f pixel) {
644 float alpha = pixel[3]; 712 float alpha = pixel[3];
645 return pixel * Sk4f{alpha, alpha, alpha, 1.0f}; 713 return pixel * Sk4f{alpha, alpha, alpha, 1.0f};
646 } 714 }
647 715
648 SkPM4f* fDst; 716 SkPM4f* fDst;
649 SkPM4f* fEnd; 717 SkPM4f* fEnd;
650 Sk4f fPostAlpha; 718 Sk4f fPostAlpha;
651 }; 719 };
652 720
653 static SkLinearBitmapPipeline::PixelPlacerInterface* choose_pixel_placer( 721 static SkLinearBitmapPipeline::BlendProcessorInterface* choose_blender(
654 SkAlphaType alphaType, 722 SkAlphaType alphaType,
655 float postAlpha, 723 float postAlpha,
656 SkLinearBitmapPipeline::PixelStage* placerStage) { 724 SkLinearBitmapPipeline::BlenderStage* blenderStage) {
657 if (alphaType == kUnpremul_SkAlphaType) { 725 if (alphaType == kUnpremul_SkAlphaType) {
658 placerStage->Initialize<PlaceFPPixel<kUnpremul_SkAlphaType>>(postAlpha); 726 blenderStage->initSink<SrcFPPixel<kUnpremul_SkAlphaType>>(postAlpha);
659 } else { 727 } else {
660 // kOpaque_SkAlphaType is treated the same as kPremul_SkAlphaType 728 // kOpaque_SkAlphaType is treated the same as kPremul_SkAlphaType
661 placerStage->Initialize<PlaceFPPixel<kPremul_SkAlphaType>>(postAlpha); 729 blenderStage->initSink<SrcFPPixel<kPremul_SkAlphaType>>(postAlpha);
662 } 730 }
663 return placerStage->get(); 731 return blenderStage->get();
664 } 732 }
665 } // namespace 733 } // namespace
666 734
667 //////////////////////////////////////////////////////////////////////////////// //////////////////// 735 //////////////////////////////////////////////////////////////////////////////// ////////////////////
736 // SkLinearBitmapPipeline
668 SkLinearBitmapPipeline::~SkLinearBitmapPipeline() {} 737 SkLinearBitmapPipeline::~SkLinearBitmapPipeline() {}
669 738
670 SkLinearBitmapPipeline::SkLinearBitmapPipeline( 739 SkLinearBitmapPipeline::SkLinearBitmapPipeline(
671 const SkMatrix& inverse, 740 const SkMatrix& inverse,
672 SkFilterQuality filterQuality, 741 SkFilterQuality filterQuality,
673 SkShader::TileMode xTile, SkShader::TileMode yTile, 742 SkShader::TileMode xTile, SkShader::TileMode yTile,
674 float postAlpha, 743 float postAlpha,
675 const SkPixmap& srcPixmap) 744 const SkPixmap& srcPixmap)
676 { 745 {
677 SkISize dimensions = srcPixmap.info().dimensions(); 746 SkISize dimensions = srcPixmap.info().dimensions();
(...skipping 14 matching lines...) Expand all
692 SkScalar dx = adjustedInverse.getScaleX(); 761 SkScalar dx = adjustedInverse.getScaleX();
693 762
694 // If it is an index 8 color type, the sampler converts to unpremul for bett er fidelity. 763 // If it is an index 8 color type, the sampler converts to unpremul for bett er fidelity.
695 SkAlphaType alphaType = srcImageInfo.alphaType(); 764 SkAlphaType alphaType = srcImageInfo.alphaType();
696 if (srcPixmap.colorType() == kIndex_8_SkColorType) { 765 if (srcPixmap.colorType() == kIndex_8_SkColorType) {
697 alphaType = kUnpremul_SkAlphaType; 766 alphaType = kUnpremul_SkAlphaType;
698 } 767 }
699 768
700 // As the stages are built, the chooser function may skip a stage. For examp le, with the 769 // As the stages are built, the chooser function may skip a stage. For examp le, with the
701 // identity matrix, the matrix stage is skipped, and the tilerStage is the f irst stage. 770 // identity matrix, the matrix stage is skipped, and the tilerStage is the f irst stage.
702 auto placementStage = choose_pixel_placer(alphaType, postAlpha, &fPixelStage ); 771 auto blenderStage = choose_blender(alphaType, postAlpha, &fBlenderStage);
703 auto samplerStage = choose_pixel_sampler(placementStage, 772 auto samplerStage = choose_pixel_sampler(blenderStage, filterQuality, srcPix map, &fSampleStage);
704 filterQuality, srcPixmap, &fSampl eStage); 773 auto tilerStage = choose_tiler(samplerStage, dimensions, xTile, yTile,
705 auto tilerStage = choose_tiler(samplerStage, 774 filterQuality, dx, &fTileStage);
706 dimensions, xTile, yTile, filterQuality, dx, &fTiler); 775 fFirstStage = choose_matrix(tilerStage, adjustedInverse, &fMatrixStage );
707 fFirstStage = choose_matrix(tilerStage, adjustedInverse, &fMatrixSta ge); 776 fLastStage = blenderStage;
708 fLastStage = placementStage;
709
710 } 777 }
711 778
712 void SkLinearBitmapPipeline::shadeSpan4f(int x, int y, SkPM4f* dst, int count) { 779 void SkLinearBitmapPipeline::shadeSpan4f(int x, int y, SkPM4f* dst, int count) {
713 SkASSERT(count > 0); 780 SkASSERT(count > 0);
714 fLastStage->setDestination(dst, count); 781 fLastStage->setDestination(dst, count);
715 782
716 // The count and length arguments start out in a precise relation in order t o keep the 783 // The count and length arguments start out in a precise relation in order t o keep the
717 // math correct through the different stages. Count is the number of pixel t o produce. 784 // math correct through the different stages. Count is the number of pixel t o produce.
718 // Since the code samples at pixel centers, length is the distance from the center of the 785 // Since the code samples at pixel centers, length is the distance from the center of the
719 // first pixel to the center of the last pixel. This implies that length is count-1. 786 // first pixel to the center of the last pixel. This implies that length is count-1.
720 fFirstStage->pointSpan(Span{{x + 0.5f, y + 0.5f}, count - 1.0f, count}); 787 fFirstStage->pointSpan(Span{{x + 0.5f, y + 0.5f}, count - 1.0f, count});
721 } 788 }
OLDNEW
« no previous file with comments | « src/core/SkLinearBitmapPipeline.h ('k') | src/core/SkLinearBitmapPipeline_sample.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698