1 /* 2 * Copyright 2023 Google LLC 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 GrPerlinNoise2Effect_DEFINED 9 #define GrPerlinNoise2Effect_DEFINED 10 11 #include "include/core/SkAlphaType.h" 12 #include "include/core/SkMatrix.h" 13 #include "include/core/SkPoint.h" 14 #include "include/core/SkSamplingOptions.h" 15 #include "include/core/SkString.h" 16 #include "include/private/SkSLSampleUsage.h" 17 #include "src/gpu/ganesh/GrCaps.h" 18 #include "src/gpu/ganesh/GrFragmentProcessor.h" 19 #include "src/gpu/ganesh/GrProcessorUnitTest.h" 20 #include "src/gpu/ganesh/GrSamplerState.h" 21 #include "src/gpu/ganesh/GrSurfaceProxyView.h" 22 #include "src/gpu/ganesh/effects/GrTextureEffect.h" 23 #include "src/gpu/ganesh/glsl/GrGLSLProgramDataManager.h" 24 #include "src/shaders/SkPerlinNoiseShaderImpl.h" 25 26 #include <memory> 27 #include <utility> 28 29 namespace skgpu { 30 class KeyBuilder; 31 } 32 struct GrShaderCaps; 33 enum class SkPerlinNoiseShaderType; 34 35 class GrPerlinNoise2Effect : public GrFragmentProcessor { 36 public: Make(SkPerlinNoiseShaderType type,int numOctaves,bool stitchTiles,std::unique_ptr<SkPerlinNoiseShader::PaintingData> paintingData,GrSurfaceProxyView permutationsView,GrSurfaceProxyView noiseView,const GrCaps & caps)37 static std::unique_ptr<GrFragmentProcessor> Make( 38 SkPerlinNoiseShaderType type, 39 int numOctaves, 40 bool stitchTiles, 41 std::unique_ptr<SkPerlinNoiseShader::PaintingData> paintingData, 42 GrSurfaceProxyView permutationsView, 43 GrSurfaceProxyView noiseView, 44 const GrCaps& caps) { 45 static constexpr GrSamplerState kRepeatXSampler = {GrSamplerState::WrapMode::kRepeat, 46 GrSamplerState::WrapMode::kClamp, 47 GrSamplerState::Filter::kNearest}; 48 auto permutationsFP = GrTextureEffect::Make(std::move(permutationsView), 49 kPremul_SkAlphaType, 50 SkMatrix::I(), 51 kRepeatXSampler, 52 caps); 53 auto noiseFP = GrTextureEffect::Make( 54 std::move(noiseView), kPremul_SkAlphaType, SkMatrix::I(), kRepeatXSampler, caps); 55 56 return std::unique_ptr<GrFragmentProcessor>( 57 new GrPerlinNoise2Effect(type, 58 numOctaves, 59 stitchTiles, 60 std::move(paintingData), 61 std::move(permutationsFP), 62 std::move(noiseFP))); 63 } 64 name()65 const char* name() const override { return "PerlinNoise"; } 66 clone()67 std::unique_ptr<GrFragmentProcessor> clone() const override { 68 return std::unique_ptr<GrFragmentProcessor>(new GrPerlinNoise2Effect(*this)); 69 } 70 stitchData()71 const SkPerlinNoiseShader::StitchData& stitchData() const { 72 return fPaintingData->fStitchDataInit; 73 } 74 type()75 SkPerlinNoiseShaderType type() const { return fType; } stitchTiles()76 bool stitchTiles() const { return fStitchTiles; } baseFrequency()77 const SkVector& baseFrequency() const { return fPaintingData->fBaseFrequency; } numOctaves()78 int numOctaves() const { return fNumOctaves; } 79 80 private: 81 class Impl : public ProgramImpl { 82 public: 83 SkString emitHelper(EmitArgs& args); 84 void emitCode(EmitArgs&) override; 85 86 private: 87 void onSetData(const GrGLSLProgramDataManager&, const GrFragmentProcessor&) override; 88 89 GrGLSLProgramDataManager::UniformHandle fStitchDataUni; 90 GrGLSLProgramDataManager::UniformHandle fBaseFrequencyUni; 91 }; 92 onMakeProgramImpl()93 std::unique_ptr<ProgramImpl> onMakeProgramImpl() const override { 94 return std::make_unique<Impl>(); 95 } 96 97 void onAddToKey(const GrShaderCaps& caps, skgpu::KeyBuilder* b) const override; 98 onIsEqual(const GrFragmentProcessor & sBase)99 bool onIsEqual(const GrFragmentProcessor& sBase) const override { 100 const GrPerlinNoise2Effect& s = sBase.cast<GrPerlinNoise2Effect>(); 101 return fType == s.fType && 102 fPaintingData->fBaseFrequency == s.fPaintingData->fBaseFrequency && 103 fNumOctaves == s.fNumOctaves && fStitchTiles == s.fStitchTiles && 104 fPaintingData->fStitchDataInit == s.fPaintingData->fStitchDataInit; 105 } 106 GrPerlinNoise2Effect(SkPerlinNoiseShaderType type,int numOctaves,bool stitchTiles,std::unique_ptr<SkPerlinNoiseShader::PaintingData> paintingData,std::unique_ptr<GrFragmentProcessor> permutationsFP,std::unique_ptr<GrFragmentProcessor> noiseFP)107 GrPerlinNoise2Effect(SkPerlinNoiseShaderType type, 108 int numOctaves, 109 bool stitchTiles, 110 std::unique_ptr<SkPerlinNoiseShader::PaintingData> paintingData, 111 std::unique_ptr<GrFragmentProcessor> permutationsFP, 112 std::unique_ptr<GrFragmentProcessor> noiseFP) 113 : GrFragmentProcessor(kGrPerlinNoise2Effect_ClassID, kNone_OptimizationFlags) 114 , fType(type) 115 , fNumOctaves(numOctaves) 116 , fStitchTiles(stitchTiles) 117 , fPaintingData(std::move(paintingData)) { 118 this->registerChild(std::move(permutationsFP), SkSL::SampleUsage::Explicit()); 119 this->registerChild(std::move(noiseFP), SkSL::SampleUsage::Explicit()); 120 this->setUsesSampleCoordsDirectly(); 121 } 122 GrPerlinNoise2Effect(const GrPerlinNoise2Effect & that)123 GrPerlinNoise2Effect(const GrPerlinNoise2Effect& that) 124 : GrFragmentProcessor(that) 125 , fType(that.fType) 126 , fNumOctaves(that.fNumOctaves) 127 , fStitchTiles(that.fStitchTiles) 128 , fPaintingData(new SkPerlinNoiseShader::PaintingData(*that.fPaintingData)) {} 129 130 GR_DECLARE_FRAGMENT_PROCESSOR_TEST 131 132 SkPerlinNoiseShaderType fType; 133 int fNumOctaves; 134 bool fStitchTiles; 135 136 std::unique_ptr<SkPerlinNoiseShader::PaintingData> fPaintingData; 137 }; 138 139 #endif 140