• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "GrTextureDomain.h"
12 #include "glsl/GrGLSLFragmentProcessor.h"
13 
14 class GrInvariantOutput;
15 
16 class GrBicubicEffect : public GrFragmentProcessor {
17 public:
18     enum {
19         kFilterTexelPad = 2, // Given a src rect in texels to be filtered, this number of
20                              // surrounding texels are needed by the kernel in x and y.
21     };
22 
name()23     const char* name() const override { return "Bicubic"; }
24 
clone()25     std::unique_ptr<GrFragmentProcessor> clone() const override {
26         return std::unique_ptr<GrFragmentProcessor>(new GrBicubicEffect(*this));
27     }
28 
domain()29     const GrTextureDomain& domain() const { return fDomain; }
30 
31     /**
32      * Create a Mitchell filter effect with specified texture matrix and x/y tile modes.
33      */
Make(sk_sp<GrTextureProxy> proxy,const SkMatrix & matrix,const GrSamplerState::WrapMode wrapModes[2])34     static std::unique_ptr<GrFragmentProcessor> Make(sk_sp<GrTextureProxy> proxy,
35                                                      const SkMatrix& matrix,
36                                                      const GrSamplerState::WrapMode wrapModes[2]) {
37         // Ignore the domain on x and y, since this factory relies solely on the wrap mode of the
38         // sampler to constrain texture coordinates
39         return Make(std::move(proxy), matrix, wrapModes, GrTextureDomain::kIgnore_Mode,
40                     GrTextureDomain::kIgnore_Mode);
41     }
42 
43     /**
44      * Create a Mitchell filter effect with specified texture matrix and x/y tile modes. This
45      * supports providing modes for the texture domain explicitly, in the event that it should
46      * override the behavior of the sampler's tile mode (e.g. clamp to border unsupported).
47      */
48     static std::unique_ptr<GrFragmentProcessor> Make(sk_sp<GrTextureProxy> proxy,
49                                                      const SkMatrix& matrix,
50                                                      const GrSamplerState::WrapMode wrapModes[2],
51                                                      GrTextureDomain::Mode modeX,
52                                                      GrTextureDomain::Mode modeY,
53                                                      const SkRect* domain = nullptr) {
54         SkRect resolvedDomain = domain ? *domain : GrTextureDomain::MakeTexelDomain(
55                 SkIRect::MakeWH(proxy->width(), proxy->height()), modeX, modeY);
56         return std::unique_ptr<GrFragmentProcessor>(new GrBicubicEffect(
57                 std::move(proxy), matrix, resolvedDomain, wrapModes, modeX, modeY));
58     }
59 
60     /**
61      * Create a Mitchell filter effect with a texture matrix and a domain.
62      */
Make(sk_sp<GrTextureProxy> proxy,const SkMatrix & matrix,const SkRect & domain)63     static std::unique_ptr<GrFragmentProcessor> Make(sk_sp<GrTextureProxy> proxy,
64                                                      const SkMatrix& matrix,
65                                                      const SkRect& domain) {
66         static const GrSamplerState::WrapMode kClampClamp[] = {
67                 GrSamplerState::WrapMode::kClamp, GrSamplerState::WrapMode::kClamp};
68         return Make(std::move(proxy), matrix, kClampClamp, GrTextureDomain::kClamp_Mode,
69                 GrTextureDomain::kClamp_Mode, &domain);
70     }
71 
72     /**
73      * Determines whether the bicubic effect should be used based on the transformation from the
74      * local coords to the device. Returns true if the bicubic effect should be used. filterMode
75      * is set to appropriate filtering mode to use regardless of the return result (e.g. when this
76      * returns false it may indicate that the best fallback is to use kMipMap, kBilerp, or
77      * kNearest).
78      */
79     static bool ShouldUseBicubic(const SkMatrix& localCoordsToDevice,
80                                  GrSamplerState::Filter* filterMode);
81 
82 private:
83     GrBicubicEffect(sk_sp<GrTextureProxy>, const SkMatrix& matrix, const SkRect& domain,
84                     const GrSamplerState::WrapMode wrapModes[2],
85                     GrTextureDomain::Mode modeX, GrTextureDomain::Mode modeY);
86     explicit GrBicubicEffect(const GrBicubicEffect&);
87 
88     GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
89 
90     void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
91 
92     bool onIsEqual(const GrFragmentProcessor&) const override;
93 
onTextureSampler(int)94     const TextureSampler& onTextureSampler(int) const override { return fTextureSampler; }
95 
96     GrCoordTransform fCoordTransform;
97     GrTextureDomain fDomain;
98     TextureSampler fTextureSampler;
99 
100     GR_DECLARE_FRAGMENT_PROCESSOR_TEST
101 
102     typedef GrFragmentProcessor INHERITED;
103 };
104 
105 #endif
106