GrGaussianConvolutionFragmentProcessor.h 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  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. #ifndef GrGaussianConvolutionFragmentProcessor_DEFINED
  8. #define GrGaussianConvolutionFragmentProcessor_DEFINED
  9. #include "src/gpu/GrCoordTransform.h"
  10. #include "src/gpu/GrFragmentProcessor.h"
  11. #include "src/gpu/effects/GrTextureDomain.h"
  12. /**
  13. * A 1D Gaussian convolution effect. The kernel is computed as an array of 2 * half-width weights.
  14. * Each texel is multiplied by it's weight and summed to determine the filtered color. The output
  15. * color is set to a modulation of the filtered and input colors.
  16. */
  17. class GrGaussianConvolutionFragmentProcessor : public GrFragmentProcessor {
  18. public:
  19. enum class Direction { kX, kY };
  20. /// Convolve with a Gaussian kernel
  21. static std::unique_ptr<GrFragmentProcessor> Make(sk_sp<GrTextureProxy> proxy,
  22. Direction dir,
  23. int halfWidth,
  24. float gaussianSigma,
  25. GrTextureDomain::Mode mode,
  26. int* bounds) {
  27. return std::unique_ptr<GrFragmentProcessor>(new GrGaussianConvolutionFragmentProcessor(
  28. std::move(proxy), dir, halfWidth, gaussianSigma, mode, bounds));
  29. }
  30. const float* kernel() const { return fKernel; }
  31. const int* bounds() const { return fBounds; }
  32. bool useBounds() const { return fMode != GrTextureDomain::kIgnore_Mode; }
  33. int radius() const { return fRadius; }
  34. int width() const { return 2 * fRadius + 1; }
  35. Direction direction() const { return fDirection; }
  36. GrTextureDomain::Mode mode() const { return fMode; }
  37. const char* name() const override { return "GaussianConvolution"; }
  38. #ifdef SK_DEBUG
  39. SkString dumpInfo() const override {
  40. SkString str;
  41. str.appendf("dir: %s radius: %d bounds: [%d %d]",
  42. Direction::kX == fDirection ? "X" : "Y",
  43. fRadius,
  44. fBounds[0], fBounds[1]);
  45. return str;
  46. }
  47. #endif
  48. std::unique_ptr<GrFragmentProcessor> clone() const override {
  49. return std::unique_ptr<GrFragmentProcessor>(
  50. new GrGaussianConvolutionFragmentProcessor(*this));
  51. }
  52. // This was decided based on the min allowed value for the max texture
  53. // samples per fragment program run in DX9SM2 (32). A sigma param of 4.0
  54. // on a blur filter gives a kernel width of 25 while a sigma of 5.0
  55. // would exceed a 32 wide kernel.
  56. static const int kMaxKernelRadius = 12;
  57. // With a C++11 we could have a constexpr version of WidthFromRadius()
  58. // and not have to duplicate this calculation.
  59. static const int kMaxKernelWidth = 2 * kMaxKernelRadius + 1;
  60. private:
  61. /// Convolve with a Gaussian kernel
  62. GrGaussianConvolutionFragmentProcessor(sk_sp<GrTextureProxy>, Direction,
  63. int halfWidth, float gaussianSigma,
  64. GrTextureDomain::Mode mode, int bounds[2]);
  65. explicit GrGaussianConvolutionFragmentProcessor(const GrGaussianConvolutionFragmentProcessor&);
  66. GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
  67. void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
  68. bool onIsEqual(const GrFragmentProcessor&) const override;
  69. const TextureSampler& onTextureSampler(int) const override { return fTextureSampler; }
  70. GR_DECLARE_FRAGMENT_PROCESSOR_TEST
  71. GrCoordTransform fCoordTransform;
  72. TextureSampler fTextureSampler;
  73. // TODO: Inline the kernel constants into the generated shader code. This may involve pulling
  74. // some of the logic from SkGpuBlurUtils into this class related to radius/sigma calculations.
  75. float fKernel[kMaxKernelWidth];
  76. int fBounds[2];
  77. int fRadius;
  78. Direction fDirection;
  79. GrTextureDomain::Mode fMode;
  80. typedef GrFragmentProcessor INHERITED;
  81. };
  82. #endif