1 | /* |
2 | * Copyright 2013 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 GrBicubicTextureEffect_DEFINED |
9 | #define GrBicubicTextureEffect_DEFINED |
10 | |
11 | #include "src/gpu/glsl/GrGLSLFragmentProcessor.h" |
12 | |
13 | class GrInvariantOutput; |
14 | |
15 | class GrBicubicEffect : public GrFragmentProcessor { |
16 | public: |
17 | enum { |
18 | kFilterTexelPad = 2, // Given a src rect in texels to be filtered, this number of |
19 | // surrounding texels are needed by the kernel in x and y. |
20 | }; |
21 | |
22 | enum class Kernel { |
23 | kMitchell, |
24 | kCatmullRom, |
25 | }; |
26 | |
27 | enum class Direction { |
28 | /** Apply bicubic kernel in local coord x, nearest neighbor in y. */ |
29 | kX, |
30 | /** Apply bicubic kernel in local coord y, nearest neighbor in x. */ |
31 | kY, |
32 | /** Apply bicubic in both x and y. */ |
33 | kXY |
34 | }; |
35 | |
36 | const char* name() const override { return "Bicubic" ; } |
37 | |
38 | std::unique_ptr<GrFragmentProcessor> clone() const override { |
39 | return std::unique_ptr<GrFragmentProcessor>(new GrBicubicEffect(*this)); |
40 | } |
41 | |
42 | /** |
43 | * Create a bicubic filter effect with specified texture matrix with clamp wrap mode. |
44 | */ |
45 | static std::unique_ptr<GrFragmentProcessor> Make(GrSurfaceProxyView view, |
46 | SkAlphaType, |
47 | const SkMatrix&, |
48 | Kernel, |
49 | Direction); |
50 | |
51 | /** |
52 | * Create a bicubic filter effect for a texture with arbitrary wrap modes. |
53 | */ |
54 | static std::unique_ptr<GrFragmentProcessor> Make(GrSurfaceProxyView view, |
55 | SkAlphaType, |
56 | const SkMatrix&, |
57 | const GrSamplerState::WrapMode wrapX, |
58 | const GrSamplerState::WrapMode wrapY, |
59 | Kernel, |
60 | Direction, |
61 | const GrCaps&); |
62 | |
63 | /** |
64 | * Create a bicubic filter effect for a subset of a texture, specified by a texture coordinate |
65 | * rectangle subset. The WrapModes apply to the subset. |
66 | */ |
67 | static std::unique_ptr<GrFragmentProcessor> MakeSubset(GrSurfaceProxyView view, |
68 | SkAlphaType, |
69 | const SkMatrix&, |
70 | const GrSamplerState::WrapMode wrapX, |
71 | const GrSamplerState::WrapMode wrapY, |
72 | const SkRect& subset, |
73 | Kernel, |
74 | Direction, |
75 | const GrCaps&); |
76 | |
77 | /** |
78 | * Same as above but provides a known 'domain' that bounds the coords at which bicubic sampling |
79 | * occurs. Note that this is a bound on the coords after transformed by the matrix parameter. |
80 | */ |
81 | static std::unique_ptr<GrFragmentProcessor> MakeSubset(GrSurfaceProxyView view, |
82 | SkAlphaType, |
83 | const SkMatrix&, |
84 | const GrSamplerState::WrapMode wrapX, |
85 | const GrSamplerState::WrapMode wrapY, |
86 | const SkRect& subset, |
87 | const SkRect& domain, |
88 | Kernel, |
89 | Direction, |
90 | const GrCaps&); |
91 | |
92 | /** |
93 | * Make a bicubic filter of a another fragment processor. The bicubic filter assumes that the |
94 | * discrete samples of the provided processor are at half-integer coords. |
95 | */ |
96 | static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor>, |
97 | SkAlphaType, |
98 | const SkMatrix&, |
99 | Kernel, |
100 | Direction); |
101 | |
102 | private: |
103 | class Impl; |
104 | |
105 | enum class Clamp { |
106 | kUnpremul, // clamps rgba to 0..1 |
107 | kPremul, // clamps a to 0..1 and rgb to 0..a |
108 | }; |
109 | |
110 | GrBicubicEffect(std::unique_ptr<GrFragmentProcessor>, |
111 | Kernel, |
112 | Direction, |
113 | Clamp); |
114 | |
115 | explicit GrBicubicEffect(const GrBicubicEffect&); |
116 | |
117 | GrGLSLFragmentProcessor* onCreateGLSLInstance() const override; |
118 | |
119 | void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override; |
120 | |
121 | bool onIsEqual(const GrFragmentProcessor&) const override; |
122 | |
123 | SkPMColor4f constantOutputForConstantInput(const SkPMColor4f&) const override; |
124 | |
125 | Kernel fKernel; |
126 | Direction fDirection; |
127 | Clamp fClamp; |
128 | |
129 | GR_DECLARE_FRAGMENT_PROCESSOR_TEST |
130 | |
131 | typedef GrFragmentProcessor INHERITED; |
132 | }; |
133 | |
134 | #endif |
135 | |