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