1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2014 Google Inc. 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#ifndef GrMatrixConvolutionEffect_DEFINED 9cb93a386Sopenharmony_ci#define GrMatrixConvolutionEffect_DEFINED 10cb93a386Sopenharmony_ci 11cb93a386Sopenharmony_ci#include "src/gpu/GrFragmentProcessor.h" 12cb93a386Sopenharmony_ci#include <array> 13cb93a386Sopenharmony_ci#include <new> 14cb93a386Sopenharmony_ci 15cb93a386Sopenharmony_ciclass GrMatrixConvolutionEffect : public GrFragmentProcessor { 16cb93a386Sopenharmony_cipublic: 17cb93a386Sopenharmony_ci // A little bit less than the minimum # uniforms required by DX9SM2 (32). 18cb93a386Sopenharmony_ci // Allows for a 5x5 kernel (or 28x1, for that matter). 19cb93a386Sopenharmony_ci // Must be a multiple of 4, since we upload these in vec4s. 20cb93a386Sopenharmony_ci inline static constexpr int kMaxUniformSize = 28; 21cb93a386Sopenharmony_ci 22cb93a386Sopenharmony_ci static std::unique_ptr<GrFragmentProcessor> Make(GrRecordingContext*, 23cb93a386Sopenharmony_ci GrSurfaceProxyView srcView, 24cb93a386Sopenharmony_ci const SkIRect& srcBounds, 25cb93a386Sopenharmony_ci const SkISize& kernelSize, 26cb93a386Sopenharmony_ci const SkScalar* kernel, 27cb93a386Sopenharmony_ci SkScalar gain, 28cb93a386Sopenharmony_ci SkScalar bias, 29cb93a386Sopenharmony_ci const SkIPoint& kernelOffset, 30cb93a386Sopenharmony_ci GrSamplerState::WrapMode, 31cb93a386Sopenharmony_ci bool convolveAlpha, 32cb93a386Sopenharmony_ci const GrCaps&); 33cb93a386Sopenharmony_ci 34cb93a386Sopenharmony_ci const char* name() const override { return "MatrixConvolution"; } 35cb93a386Sopenharmony_ci 36cb93a386Sopenharmony_ci SkString getShaderDfxInfo() const override; 37cb93a386Sopenharmony_ci 38cb93a386Sopenharmony_ci std::unique_ptr<GrFragmentProcessor> clone() const override; 39cb93a386Sopenharmony_ci 40cb93a386Sopenharmony_ciprivate: 41cb93a386Sopenharmony_ci class Impl; 42cb93a386Sopenharmony_ci 43cb93a386Sopenharmony_ci /** 44cb93a386Sopenharmony_ci * Small kernels are represented as float-arrays and uploaded as uniforms. 45cb93a386Sopenharmony_ci * Large kernels go over the uniform limit and are uploaded as textures and sampled. 46cb93a386Sopenharmony_ci * If Float16 textures are supported, we use those. Otherwise we use A8. 47cb93a386Sopenharmony_ci */ 48cb93a386Sopenharmony_ci class KernelWrapper { 49cb93a386Sopenharmony_ci public: 50cb93a386Sopenharmony_ci struct BiasAndGain { 51cb93a386Sopenharmony_ci // Only used in A8 mode. Applied before any other math. 52cb93a386Sopenharmony_ci float fBias; 53cb93a386Sopenharmony_ci // Only used in A8 mode. Premultiplied in with user gain to save time. 54cb93a386Sopenharmony_ci float fGain; 55cb93a386Sopenharmony_ci bool operator==(const BiasAndGain&) const; 56cb93a386Sopenharmony_ci }; 57cb93a386Sopenharmony_ci using MakeResult = std::tuple<KernelWrapper, std::unique_ptr<GrFragmentProcessor>>; 58cb93a386Sopenharmony_ci static MakeResult Make(GrRecordingContext*, SkISize, const GrCaps&, const float* values); 59cb93a386Sopenharmony_ci 60cb93a386Sopenharmony_ci KernelWrapper() = default; 61cb93a386Sopenharmony_ci KernelWrapper(const KernelWrapper& that) : fSize(that.fSize) { 62cb93a386Sopenharmony_ci if (that.isSampled()) { 63cb93a386Sopenharmony_ci fBiasAndGain = that.fBiasAndGain; 64cb93a386Sopenharmony_ci } else { 65cb93a386Sopenharmony_ci new (&fArray) std::array<float, kMaxUniformSize>(that.fArray); 66cb93a386Sopenharmony_ci } 67cb93a386Sopenharmony_ci } 68cb93a386Sopenharmony_ci 69cb93a386Sopenharmony_ci bool isValid() const { return !fSize.isEmpty(); } 70cb93a386Sopenharmony_ci SkISize size() const { return fSize; } 71cb93a386Sopenharmony_ci bool isSampled() const { return fSize.area() > kMaxUniformSize; } 72cb93a386Sopenharmony_ci const std::array<float, kMaxUniformSize>& array() const { 73cb93a386Sopenharmony_ci SkASSERT(!this->isSampled()); 74cb93a386Sopenharmony_ci return fArray; 75cb93a386Sopenharmony_ci } 76cb93a386Sopenharmony_ci const BiasAndGain& biasAndGain() const { 77cb93a386Sopenharmony_ci SkASSERT(this->isSampled()); 78cb93a386Sopenharmony_ci return fBiasAndGain; 79cb93a386Sopenharmony_ci } 80cb93a386Sopenharmony_ci bool operator==(const KernelWrapper&) const; 81cb93a386Sopenharmony_ci 82cb93a386Sopenharmony_ci private: 83cb93a386Sopenharmony_ci KernelWrapper(SkISize size) : fSize(size) { 84cb93a386Sopenharmony_ci if (this->isSampled()) { 85cb93a386Sopenharmony_ci fBiasAndGain = {0.f , 1.f}; 86cb93a386Sopenharmony_ci } 87cb93a386Sopenharmony_ci } 88cb93a386Sopenharmony_ci 89cb93a386Sopenharmony_ci SkISize fSize = {}; 90cb93a386Sopenharmony_ci union { 91cb93a386Sopenharmony_ci std::array<float, kMaxUniformSize> fArray; 92cb93a386Sopenharmony_ci BiasAndGain fBiasAndGain; 93cb93a386Sopenharmony_ci }; 94cb93a386Sopenharmony_ci }; 95cb93a386Sopenharmony_ci 96cb93a386Sopenharmony_ci GrMatrixConvolutionEffect(std::unique_ptr<GrFragmentProcessor> child, 97cb93a386Sopenharmony_ci const KernelWrapper& kernel, 98cb93a386Sopenharmony_ci std::unique_ptr<GrFragmentProcessor> kernelFP, 99cb93a386Sopenharmony_ci SkScalar gain, 100cb93a386Sopenharmony_ci SkScalar bias, 101cb93a386Sopenharmony_ci const SkIPoint& kernelOffset, 102cb93a386Sopenharmony_ci bool convolveAlpha); 103cb93a386Sopenharmony_ci 104cb93a386Sopenharmony_ci explicit GrMatrixConvolutionEffect(const GrMatrixConvolutionEffect&); 105cb93a386Sopenharmony_ci 106cb93a386Sopenharmony_ci std::unique_ptr<ProgramImpl> onMakeProgramImpl() const override; 107cb93a386Sopenharmony_ci 108cb93a386Sopenharmony_ci void onAddToKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override; 109cb93a386Sopenharmony_ci 110cb93a386Sopenharmony_ci bool onIsEqual(const GrFragmentProcessor&) const override; 111cb93a386Sopenharmony_ci 112cb93a386Sopenharmony_ci KernelWrapper fKernel; 113cb93a386Sopenharmony_ci float fGain; 114cb93a386Sopenharmony_ci float fBias; 115cb93a386Sopenharmony_ci SkVector fKernelOffset; 116cb93a386Sopenharmony_ci bool fConvolveAlpha; 117cb93a386Sopenharmony_ci 118cb93a386Sopenharmony_ci GR_DECLARE_FRAGMENT_PROCESSOR_TEST 119cb93a386Sopenharmony_ci 120cb93a386Sopenharmony_ci using INHERITED = GrFragmentProcessor; 121cb93a386Sopenharmony_ci}; 122cb93a386Sopenharmony_ci 123cb93a386Sopenharmony_ci#endif 124