• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2017 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 GrTextureEffect_DEFINED
9 #define GrTextureEffect_DEFINED
10 
11 #include "include/core/SkImageInfo.h"
12 #include "include/core/SkMatrix.h"
13 #include "src/gpu/GrCoordTransform.h"
14 #include "src/gpu/GrFragmentProcessor.h"
15 
16 class GrTextureEffect : public GrFragmentProcessor {
17 public:
18     /** Make from a filter. The sampler will be configured with clamp mode. */
19     static std::unique_ptr<GrFragmentProcessor> Make(
20             GrSurfaceProxyView,
21             SkAlphaType,
22             const SkMatrix& = SkMatrix::I(),
23             GrSamplerState::Filter = GrSamplerState::Filter::kNearest);
24 
25     /**
26      * Make from a full GrSamplerState. Caps are required to determine support for kClampToBorder.
27      * This will be emulated in the shader if there is no hardware support.
28      */
29     static std::unique_ptr<GrFragmentProcessor> Make(
30             GrSurfaceProxyView, SkAlphaType, const SkMatrix&, GrSamplerState, const GrCaps& caps);
31 
32     /**
33      * Makes a texture effect that samples a subset of a texture. The wrap modes of the
34      * GrSampleState are applied to the subset in the shader rather than using HW samplers.
35      * The 'subset' parameter specifies the texels in the base level. The shader code will
36      * avoid allowing bilerp filtering to read outside the texel window. However, if MIP
37      * filtering is used and a shader invocation reads from a level other than the base
38      * then it may read texel values that were computed from in part from base level texels
39      * outside the window. More specifically, we treat the MIP map case exactly like the
40      * bilerp case in terms of how the final texture coords are computed.
41      */
42     static std::unique_ptr<GrFragmentProcessor> MakeSubset(GrSurfaceProxyView,
43                                                            SkAlphaType,
44                                                            const SkMatrix&,
45                                                            GrSamplerState,
46                                                            const SkRect& subset,
47                                                            const GrCaps& caps);
48 
49     /**
50      * The same as above but also takes a 'domain' that specifies any known limit on the post-
51      * matrix texture coords that will be used to sample the texture. Specifying this requires
52      * knowledge of how this effect will be nested into a paint, the local coords used with the
53      * draw, etc. It is only used to attempt to optimize away the shader subset calculations.
54      */
55     static std::unique_ptr<GrFragmentProcessor> MakeSubset(GrSurfaceProxyView,
56                                                            SkAlphaType,
57                                                            const SkMatrix&,
58                                                            GrSamplerState,
59                                                            const SkRect& subset,
60                                                            const SkRect& domain,
61                                                            const GrCaps& caps);
62 
63     std::unique_ptr<GrFragmentProcessor> clone() const override;
64 
name()65     const char* name() const override { return "TextureEffect"; }
66 
67 private:
68     enum class ShaderMode : uint16_t {
69         kClamp         = static_cast<int>(GrSamplerState::WrapMode::kClamp),
70         kRepeat        = static_cast<int>(GrSamplerState::WrapMode::kRepeat),
71         kMirrorRepeat  = static_cast<int>(GrSamplerState::WrapMode::kMirrorRepeat),
72         kDecal         = static_cast<int>(GrSamplerState::WrapMode::kClampToBorder),
73         kNone,
74     };
75 
76     struct Sampling {
77         GrSamplerState fHWSampler;
78         ShaderMode fShaderModes[2] = {ShaderMode::kNone, ShaderMode::kNone};
79         SkRect fShaderSubset = {0, 0, 0, 0};
80         SkRect fShaderClamp  = {0, 0, 0, 0};
SamplingSampling81         Sampling(GrSamplerState::Filter filter) : fHWSampler(filter) {}
82         Sampling(const GrSurfaceProxy& proxy,
83                  GrSamplerState sampler,
84                  const SkRect&,
85                  const SkRect*,
86                  const GrCaps&);
87         inline bool usesDecal() const;
88     };
89 
90     /**
91      * Sometimes the implementation of a ShaderMode depends on which GrSamplerState::Filter is
92      * used.
93      */
94     enum class FilterLogic {
95         kNone,          // The shader isn't specialized for the filter.
96         kRepeatBilerp,  // Filter across the subset boundary for kRepeat mode
97         kRepeatMipMap,  // Logic for LOD selection with kRepeat mode.
98         kDecalFilter,   // Logic for fading to transparent black when filtering with kDecal.
99         kDecalNearest,  // Logic for hard transition to transparent black when not filtering.
100     };
101     static FilterLogic GetFilterLogic(ShaderMode mode, GrSamplerState::Filter filter);
102 
103     GrCoordTransform fCoordTransform;
104     TextureSampler fSampler;
105     SkRect fSubset;
106     SkRect fClamp;
107     ShaderMode fShaderModes[2];
108 
109     inline GrTextureEffect(GrSurfaceProxyView, SkAlphaType, const SkMatrix&, const Sampling&);
110 
111     GrTextureEffect(const GrTextureEffect& src);
112 
113     GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
114 
115     void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
116 
117     bool onIsEqual(const GrFragmentProcessor&) const override;
118 
119     const TextureSampler& onTextureSampler(int) const override;
120 
121     GR_DECLARE_FRAGMENT_PROCESSOR_TEST
122 
123     typedef GrFragmentProcessor INHERITED;
124 };
125 #endif
126