• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2012 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 GrGaussianConvolutionFragmentProcessor_DEFINED
9 #define GrGaussianConvolutionFragmentProcessor_DEFINED
10 
11 #include "include/core/SkM44.h"
12 #include "src/gpu/ganesh/GrFragmentProcessor.h"
13 #include "src/gpu/ganesh/GrProcessorUnitTest.h"
14 #include "src/gpu/ganesh/GrSamplerState.h"
15 
16 class GrSurfaceProxyView;
17 
18 /**
19  * A 1D Gaussian convolution effect. The kernel is computed as an array of 2 * half-width weights.
20  * Each texel is multiplied by it's weight and summed to determine the filtered color. The output
21  * color is set to a modulation of the filtered and input colors.
22  */
23 class GrGaussianConvolutionFragmentProcessor : public GrFragmentProcessor {
24 public:
25     enum class Direction { kX, kY };
26 
27     /**
28      * Convolve with a Gaussian kernel. Bounds limits the coords sampled by the effect along the
29      * axis indicated by Direction. The WrapMode is applied to the subset. If present, the
30      * pixelDomain indicates the domain of pixels that this effect will be called with. It should
31      * not account for outsetting due to the filter radius, this effect will handle that. It is
32      * assumed that the effect is only invoked at pixel centers within the pixelDomain, the
33      * effect will optimize for that, and may produce incorrect results if it is not the case. If
34      * pixelDomain is null then the effect will work correctly with any sample coordinates.
35      */
36     static std::unique_ptr<GrFragmentProcessor> Make(GrSurfaceProxyView,
37                                                      SkAlphaType,
38                                                      Direction,
39                                                      int halfWidth,
40                                                      float gaussianSigma,
41                                                      GrSamplerState::WrapMode,
42                                                      const SkIRect& subset,
43                                                      const SkIRect* pixelDomain,
44                                                      const GrCaps&);
45 
name()46     const char* name() const override { return "GaussianConvolution"; }
47 
clone()48     std::unique_ptr<GrFragmentProcessor> clone() const override {
49         return std::unique_ptr<GrFragmentProcessor>(
50                 new GrGaussianConvolutionFragmentProcessor(*this));
51     }
52 
53     // This was decided based on the min allowed value for the max texture
54     // samples per fragment program run in DX9SM2 (32). A sigma param of 4.0
55     // on a blur filter gives a kernel width of 25 while a sigma of 5.0
56     // would exceed a 32 wide kernel.
57     inline static constexpr int kMaxKernelRadius = 12;
58 
59 private:
60     class Impl;
61 
62     GrGaussianConvolutionFragmentProcessor(std::unique_ptr<GrFragmentProcessor>,
63                                            Direction,
64                                            int halfWidth,
65                                            float gaussianSigma);
66 
67     explicit GrGaussianConvolutionFragmentProcessor(const GrGaussianConvolutionFragmentProcessor&);
68 
69 #if GR_TEST_UTILS
onDumpInfo()70     SkString onDumpInfo() const override {
71         return SkStringPrintf("(dir=%s, radius=%d)",
72                               Direction::kX == fDirection ? "X" : "Y", fRadius);
73     }
74 #endif
75 
76     std::unique_ptr<ProgramImpl> onMakeProgramImpl() const override;
77 
78     void onAddToKey(const GrShaderCaps&, skgpu::KeyBuilder*) const override;
79 
80     bool onIsEqual(const GrFragmentProcessor&) const override;
81 
82     GR_DECLARE_FRAGMENT_PROCESSOR_TEST
83 
84     inline static const constexpr int kMaxKernelWidth = kMaxKernelRadius + 1;
85 
86     SkV2                  fOffsetsAndKernel[kMaxKernelWidth];
87     int                   fRadius;
88     Direction             fDirection;
89 
90     using INHERITED = GrFragmentProcessor;
91 };
92 
93 #endif
94