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
13class GrInvariantOutput;
14
15class GrBicubicEffect : public GrFragmentProcessor {
16public:
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
102private:
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