1 /*
2  * Copyright 2016 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #ifndef SkLinearBitmapPipeline_DEFINED
9 #define SkLinearBitmapPipeline_DEFINED
10 
11 
12 #include "SkColor.h"
13 #include "SkImageInfo.h"
14 #include "SkMatrix.h"
15 #include "SkNx.h"
16 #include "SkShader.h"
17 
18 class SkLinearBitmapPipeline {
19 public:
20     SkLinearBitmapPipeline(
21         const SkMatrix& inverse,
22         SkFilterQuality filterQuality,
23         SkShader::TileMode xTile, SkShader::TileMode yTile,
24         const SkPixmap& srcPixmap);
25     ~SkLinearBitmapPipeline();
26 
27     void shadeSpan4f(int x, int y, SkPM4f* dst, int count);
28 
29     template<typename Base, size_t kSize>
30     class PolymorphicUnion {
31     public:
PolymorphicUnion()32         PolymorphicUnion() {}
33 
~PolymorphicUnion()34         ~PolymorphicUnion() { get()->~Base(); }
35 
36         template<typename Variant, typename... Args>
Initialize(Args &&...args)37         void Initialize(Args&&... args) {
38             SkASSERTF(sizeof(Variant) <= sizeof(fSpace),
39                       "Size Variant: %d, Space: %d", sizeof(Variant), sizeof(fSpace));
40 
41             new(&fSpace) Variant(std::forward<Args>(args)...);
42         };
43 
get()44         Base* get() const { return reinterpret_cast<Base*>(&fSpace); }
45         Base* operator->() const { return get(); }
46         Base& operator*() const { return *get(); }
47 
48     private:
49         struct SK_STRUCT_ALIGN(16) Space {
50             char space[kSize];
51         };
52         mutable Space fSpace;
53     };
54 
55     class PointProcessorInterface;
56     class BilerpProcessorInterface;
57     class PixelPlacerInterface;
58 
59     using MatrixStage = PolymorphicUnion<PointProcessorInterface, 112>;
60     using FilterStage = PolymorphicUnion<PointProcessorInterface,   8>;
61     using TileStage   = PolymorphicUnion<BilerpProcessorInterface, 96>;
62     using SampleStage = PolymorphicUnion<BilerpProcessorInterface, 80>;
63     using PixelStage  = PolymorphicUnion<PixelPlacerInterface,     80>;
64 
65 private:
66     PointProcessorInterface* fFirstStage;
67     MatrixStage fMatrixStage;
68     FilterStage fFilterStage;
69     TileStage   fTileXOrBothStage;
70     TileStage   fTileYStage;
71     SampleStage fSampleStage;
72     PixelStage  fPixelStage;
73 };
74 
75 #endif  // SkLinearBitmapPipeline_DEFINED
76