1d8f856c32b679d9f5a9926feac005e2c0186f83ftomhudson@google.com/* 2d8f856c32b679d9f5a9926feac005e2c0186f83ftomhudson@google.com * Copyright 2012 Google Inc. 3d8f856c32b679d9f5a9926feac005e2c0186f83ftomhudson@google.com * 4d8f856c32b679d9f5a9926feac005e2c0186f83ftomhudson@google.com * Use of this source code is governed by a BSD-style license that can be 5d8f856c32b679d9f5a9926feac005e2c0186f83ftomhudson@google.com * found in the LICENSE file. 6d8f856c32b679d9f5a9926feac005e2c0186f83ftomhudson@google.com */ 7d8f856c32b679d9f5a9926feac005e2c0186f83ftomhudson@google.com 8d8f856c32b679d9f5a9926feac005e2c0186f83ftomhudson@google.com#ifndef GrConvolutionEffect_DEFINED 9d8f856c32b679d9f5a9926feac005e2c0186f83ftomhudson@google.com#define GrConvolutionEffect_DEFINED 10d8f856c32b679d9f5a9926feac005e2c0186f83ftomhudson@google.com 11b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com#include "Gr1DKernelEffect.h" 12d8f856c32b679d9f5a9926feac005e2c0186f83ftomhudson@google.com 13ae4f96a9e06df44f70c3d5f7324f5a7fabcd1026bsalomon@google.comclass GrGLConvolutionEffect; 14ae4f96a9e06df44f70c3d5f7324f5a7fabcd1026bsalomon@google.com 15b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com/** 16fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com * A convolution effect. The kernel is specified as an array of 2 * half-width 17b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com * + 1 weights. Each texel is multiplied by it's weight and summed to determine 18b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com * the output color. The output color is modulated by the input color. 19b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com */ 20b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.comclass GrConvolutionEffect : public Gr1DKernelEffect { 21d8f856c32b679d9f5a9926feac005e2c0186f83ftomhudson@google.com 22d8f856c32b679d9f5a9926feac005e2c0186f83ftomhudson@google.compublic: 23d8f856c32b679d9f5a9926feac005e2c0186f83ftomhudson@google.com 24fde2c0af2fd5aae19ab6c8b5228debd5b6209856tomhudson@google.com /// Convolve with an arbitrary user-specified kernel 25b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt static GrFragmentProcessor* Create(GrTexture* tex, 26b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt Direction dir, 27b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt int halfWidth, 28b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const float* kernel, 29b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt bool useBounds, 30b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt float bounds[2]) { 3155fad7af61c21d502acb9891d631e8aa29e3628cbsalomon return SkNEW_ARGS(GrConvolutionEffect, (tex, 3255fad7af61c21d502acb9891d631e8aa29e3628cbsalomon dir, 3355fad7af61c21d502acb9891d631e8aa29e3628cbsalomon halfWidth, 3455fad7af61c21d502acb9891d631e8aa29e3628cbsalomon kernel, 3555fad7af61c21d502acb9891d631e8aa29e3628cbsalomon useBounds, 3655fad7af61c21d502acb9891d631e8aa29e3628cbsalomon bounds)); 370ac6af49975c54c2debf41e9200af416ecd2d973bsalomon@google.com } 38b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com 39b4a55b7b68bf6b8ba8cb12927e5a627fab95ea5cbsalomon@google.com /// Convolve with a Gaussian kernel 40b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt static GrFragmentProcessor* CreateGaussian(GrTexture* tex, 41b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt Direction dir, 42b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt int halfWidth, 43b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt float gaussianSigma, 44b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt bool useBounds, 45b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt float bounds[2]) { 4655fad7af61c21d502acb9891d631e8aa29e3628cbsalomon return SkNEW_ARGS(GrConvolutionEffect, (tex, 4755fad7af61c21d502acb9891d631e8aa29e3628cbsalomon dir, 4855fad7af61c21d502acb9891d631e8aa29e3628cbsalomon halfWidth, 4955fad7af61c21d502acb9891d631e8aa29e3628cbsalomon gaussianSigma, 5055fad7af61c21d502acb9891d631e8aa29e3628cbsalomon useBounds, 5155fad7af61c21d502acb9891d631e8aa29e3628cbsalomon bounds)); 520ac6af49975c54c2debf41e9200af416ecd2d973bsalomon@google.com } 530ac6af49975c54c2debf41e9200af416ecd2d973bsalomon@google.com 54fde2c0af2fd5aae19ab6c8b5228debd5b6209856tomhudson@google.com virtual ~GrConvolutionEffect(); 55b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com 56ae4f96a9e06df44f70c3d5f7324f5a7fabcd1026bsalomon@google.com const float* kernel() const { return fKernel; } 57289efe014ad7628de7cf2c5177a42cacd1e335adbsalomon@google.com 58e8232bc6f0719f381d437483271ce3c78af3c819senorblanco@chromium.org const float* bounds() const { return fBounds; } 59e8232bc6f0719f381d437483271ce3c78af3c819senorblanco@chromium.org bool useBounds() const { return fUseBounds; } 60194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org 61ae4f96a9e06df44f70c3d5f7324f5a7fabcd1026bsalomon@google.com static const char* Name() { return "Convolution"; } 62ae4f96a9e06df44f70c3d5f7324f5a7fabcd1026bsalomon@google.com 63b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt typedef GrGLConvolutionEffect GLProcessor; 64289efe014ad7628de7cf2c5177a42cacd1e335adbsalomon@google.com 65b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE; 6668b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com 67e0e385c1d4171e065348ba17c546b3463a0bd651sugoi@google.com virtual void getConstantColorComponents(GrColor*, uint32_t* validFlags) const { 6868b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com // If the texture was opaque we could know that the output color if we knew the sum of the 6968b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com // kernel values. 7068b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com *validFlags = 0; 7168b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com } 72b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com 73b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com enum { 74b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com // This was decided based on the min allowed value for the max texture 75b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com // samples per fragment program run in DX9SM2 (32). A sigma param of 4.0 76b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com // on a blur filter gives a kernel width of 25 while a sigma of 5.0 77b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com // would exceed a 32 wide kernel. 78b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com kMaxKernelRadius = 12, 79b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com // With a C++11 we could have a constexpr version of WidthFromRadius() 80b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com // and not have to duplicate this calculation. 81b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com kMaxKernelWidth = 2 * kMaxKernelRadius + 1, 82b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com }; 83d8f856c32b679d9f5a9926feac005e2c0186f83ftomhudson@google.com 84d8f856c32b679d9f5a9926feac005e2c0186f83ftomhudson@google.comprotected: 85d8f856c32b679d9f5a9926feac005e2c0186f83ftomhudson@google.com 86b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com float fKernel[kMaxKernelWidth]; 87e8232bc6f0719f381d437483271ce3c78af3c819senorblanco@chromium.org bool fUseBounds; 88e8232bc6f0719f381d437483271ce3c78af3c819senorblanco@chromium.org float fBounds[2]; 89d8f856c32b679d9f5a9926feac005e2c0186f83ftomhudson@google.com 90d8f856c32b679d9f5a9926feac005e2c0186f83ftomhudson@google.comprivate: 910ac6af49975c54c2debf41e9200af416ecd2d973bsalomon@google.com GrConvolutionEffect(GrTexture*, Direction, 92194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org int halfWidth, 93194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org const float* kernel, 94e8232bc6f0719f381d437483271ce3c78af3c819senorblanco@chromium.org bool useBounds, 95e8232bc6f0719f381d437483271ce3c78af3c819senorblanco@chromium.org float bounds[2]); 960ac6af49975c54c2debf41e9200af416ecd2d973bsalomon@google.com 970ac6af49975c54c2debf41e9200af416ecd2d973bsalomon@google.com /// Convolve with a Gaussian kernel 980ac6af49975c54c2debf41e9200af416ecd2d973bsalomon@google.com GrConvolutionEffect(GrTexture*, Direction, 990ac6af49975c54c2debf41e9200af416ecd2d973bsalomon@google.com int halfWidth, 100194d775edcf5fa6e82098a97ad53018d70db1155senorblanco@chromium.org float gaussianSigma, 101e8232bc6f0719f381d437483271ce3c78af3c819senorblanco@chromium.org bool useBounds, 102e8232bc6f0719f381d437483271ce3c78af3c819senorblanco@chromium.org float bounds[2]); 1030ac6af49975c54c2debf41e9200af416ecd2d973bsalomon@google.com 104b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE; 10568b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com 106b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GR_DECLARE_FRAGMENT_PROCESSOR_TEST; 107d8f856c32b679d9f5a9926feac005e2c0186f83ftomhudson@google.com 108b505a128efae9debcaa9642bade90bab5525d477bsalomon@google.com typedef Gr1DKernelEffect INHERITED; 109d8f856c32b679d9f5a9926feac005e2c0186f83ftomhudson@google.com}; 110d8f856c32b679d9f5a9926feac005e2c0186f83ftomhudson@google.com 111d8f856c32b679d9f5a9926feac005e2c0186f83ftomhudson@google.com#endif 112