diff options
author | bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2011-10-12 19:53:16 +0000 |
---|---|---|
committer | bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2011-10-12 19:53:16 +0000 |
commit | d38f137e9b813f8193675ebd3dfbfe8bc42639e9 (patch) | |
tree | 1e670c378d7b31a4538fde3c2b3e4e29b72c05b5 /include/gpu/GrSamplerState.h | |
parent | 4d5cb45f3e3e62633304b4911d131cdd02dfd541 (diff) |
Move gpu/include/* to include/gpu and gpu/src/* to src/gpu
Review URL: http://codereview.appspot.com/5250070/
git-svn-id: http://skia.googlecode.com/svn/trunk@2471 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'include/gpu/GrSamplerState.h')
-rw-r--r-- | include/gpu/GrSamplerState.h | 265 |
1 files changed, 265 insertions, 0 deletions
diff --git a/include/gpu/GrSamplerState.h b/include/gpu/GrSamplerState.h new file mode 100644 index 0000000000..324472c972 --- /dev/null +++ b/include/gpu/GrSamplerState.h @@ -0,0 +1,265 @@ + +/* + * Copyright 2010 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + + + +#ifndef GrSamplerState_DEFINED +#define GrSamplerState_DEFINED + +#include "GrTypes.h" +#include "GrMatrix.h" + +#define MAX_KERNEL_WIDTH 25 + +class GrSamplerState { +public: + enum Filter { + /** + * Read the closest src texel to the sample position + */ + kNearest_Filter, + /** + * Blend between closest 4 src texels to sample position (tent filter) + */ + kBilinear_Filter, + /** + * Average of 4 bilinear filterings spaced +/- 1 texel from sample + * position in x and y. Intended for averaging 16 texels in a downsample + * pass. (rasterizing such that texture samples fall exactly halfway + * between texels in x and y spaced 4 texels apart.) Only supported + * on shader backends. + */ + k4x4Downsample_Filter, + /** + * Apply a separable convolution kernel. + */ + kConvolution_Filter + }; + + /** + * The intepretation of the texture matrix depends on the sample mode. The + * texture matrix is applied both when the texture coordinates are explicit + * and when vertex positions are used as texture coordinates. In the latter + * case the texture matrix is applied to the pre-view-matrix position + * values. + * + * kNormal_SampleMode + * The post-matrix texture coordinates are in normalize space with (0,0) at + * the top-left and (1,1) at the bottom right. + * kRadial_SampleMode + * The matrix specifies the radial gradient parameters. + * (0,0) in the post-matrix space is center of the radial gradient. + * kRadial2_SampleMode + * Matrix transforms to space where first circle is centered at the + * origin. The second circle will be centered (x, 0) where x may be + * 0 and is provided by setRadial2Params. The post-matrix space is + * normalized such that 1 is the second radius - first radius. + * kSweepSampleMode + * The angle from the origin of texture coordinates in post-matrix space + * determines the gradient value. + */ + enum SampleMode { + kNormal_SampleMode, //!< sample color directly + kRadial_SampleMode, //!< treat as radial gradient + kRadial2_SampleMode, //!< treat as 2-point radial gradient + kSweep_SampleMode, //!< treat as sweep gradient + }; + + /** + * Describes how a texture is sampled when coordinates are outside the + * texture border + */ + enum WrapMode { + kClamp_WrapMode, + kRepeat_WrapMode, + kMirror_WrapMode + }; + + /** + * Default sampler state is set to clamp, use normal sampling mode, be + * unfiltered, and use identity matrix. + */ + GrSamplerState() + : fRadial2CenterX1() + , fRadial2Radius0() + , fRadial2PosRoot() { + this->setClampNoFilter(); + } + + explicit GrSamplerState(Filter filter) + : fRadial2CenterX1() + , fRadial2Radius0() + , fRadial2PosRoot() { + fWrapX = kClamp_WrapMode; + fWrapY = kClamp_WrapMode; + fSampleMode = kNormal_SampleMode; + fFilter = filter; + fMatrix.setIdentity(); + fTextureDomain.setEmpty(); + } + + GrSamplerState(WrapMode wx, WrapMode wy, Filter filter) + : fRadial2CenterX1() + , fRadial2Radius0() + , fRadial2PosRoot() { + fWrapX = wx; + fWrapY = wy; + fSampleMode = kNormal_SampleMode; + fFilter = filter; + fMatrix.setIdentity(); + fTextureDomain.setEmpty(); + } + + GrSamplerState(WrapMode wx, WrapMode wy, + const GrMatrix& matrix, Filter filter) + : fRadial2CenterX1() + , fRadial2Radius0() + , fRadial2PosRoot() { + fWrapX = wx; + fWrapY = wy; + fSampleMode = kNormal_SampleMode; + fFilter = filter; + fMatrix = matrix; + fTextureDomain.setEmpty(); + } + + GrSamplerState(WrapMode wx, WrapMode wy, SampleMode sample, + const GrMatrix& matrix, Filter filter) + : fRadial2CenterX1() + , fRadial2Radius0() + , fRadial2PosRoot() { + fWrapX = wx; + fWrapY = wy; + fSampleMode = sample; + fMatrix = matrix; + fFilter = filter; + fTextureDomain.setEmpty(); + } + + WrapMode getWrapX() const { return fWrapX; } + WrapMode getWrapY() const { return fWrapY; } + SampleMode getSampleMode() const { return fSampleMode; } + const GrMatrix& getMatrix() const { return fMatrix; } + const GrRect& getTextureDomain() const { return fTextureDomain; } + bool hasTextureDomain() const {return SkIntToScalar(0) != fTextureDomain.right();} + Filter getFilter() const { return fFilter; } + int getKernelWidth() const { return fKernelWidth; } + const float* getKernel() const { return fKernel; } + const float* getImageIncrement() const { return fImageIncrement; } + + bool isGradient() const { + return kRadial_SampleMode == fSampleMode || + kRadial2_SampleMode == fSampleMode || + kSweep_SampleMode == fSampleMode; + } + + void setWrapX(WrapMode mode) { fWrapX = mode; } + void setWrapY(WrapMode mode) { fWrapY = mode; } + void setSampleMode(SampleMode mode) { fSampleMode = mode; } + + /** + * Sets the sampler's matrix. See SampleMode for explanation of + * relationship between the matrix and sample mode. + * @param matrix the matrix to set + */ + void setMatrix(const GrMatrix& matrix) { fMatrix = matrix; } + + /** + * Sets the sampler's texture coordinate domain to a + * custom rectangle, rather than the default (0,1). + * This option is currently only supported with kClamp_WrapMode + */ + void setTextureDomain(const GrRect& textureDomain) { fTextureDomain = textureDomain; } + + /** + * Multiplies the current sampler matrix a matrix + * + * After this call M' = M*m where M is the old matrix, m is the parameter + * to this function, and M' is the new matrix. (We consider points to + * be column vectors so tex cood vector t is transformed by matrix X as + * t' = X*t.) + * + * @param matrix the matrix used to modify the matrix. + */ + void preConcatMatrix(const GrMatrix& matrix) { fMatrix.preConcat(matrix); } + + /** + * Sets filtering type. + * @param filter type of filtering to apply + */ + void setFilter(Filter filter) { fFilter = filter; } + + void setClampNoFilter() { + fWrapX = kClamp_WrapMode; + fWrapY = kClamp_WrapMode; + fSampleMode = kNormal_SampleMode; + fFilter = kNearest_Filter; + fMatrix.setIdentity(); + fTextureDomain.setEmpty(); + } + + GrScalar getRadial2CenterX1() const { return fRadial2CenterX1; } + GrScalar getRadial2Radius0() const { return fRadial2Radius0; } + bool isRadial2PosRoot() const { return fRadial2PosRoot; } + // do the radial gradient params lead to a linear (rather than quadratic) + // equation. + bool radial2IsDegenerate() const { return GR_Scalar1 == fRadial2CenterX1; } + + /** + * Sets the parameters for kRadial2_SampleMode. The texture + * matrix must be set so that the first point is at (0,0) and the second + * point lies on the x-axis. The second radius minus the first is 1 unit. + * The additional parameters to define the gradient are specified by this + * function. + */ + void setRadial2Params(GrScalar centerX1, GrScalar radius0, bool posRoot) { + fRadial2CenterX1 = centerX1; + fRadial2Radius0 = radius0; + fRadial2PosRoot = posRoot; + } + + void setConvolutionParams(int kernelWidth, const float* kernel, float imageIncrement[2]) { + GrAssert(kernelWidth >= 0 && kernelWidth <= MAX_KERNEL_WIDTH); + fKernelWidth = kernelWidth; + if (NULL != kernel) { + memcpy(fKernel, kernel, kernelWidth * sizeof(float)); + } + if (NULL != imageIncrement) { + memcpy(fImageIncrement, imageIncrement, sizeof(fImageIncrement)); + } else { + memset(fImageIncrement, 0, sizeof(fImageIncrement)); + } + } + + static const GrSamplerState& ClampNoFilter() { + return gClampNoFilter; + } + +private: + WrapMode fWrapX; + WrapMode fWrapY; + SampleMode fSampleMode; + Filter fFilter; + GrMatrix fMatrix; + GrRect fTextureDomain; + + // these are undefined unless fSampleMode == kRadial2_SampleMode + GrScalar fRadial2CenterX1; + GrScalar fRadial2Radius0; + bool fRadial2PosRoot; + + // These are undefined unless fFilter == kConvolution_Filter + int fKernelWidth; + float fKernel[MAX_KERNEL_WIDTH]; + float fImageIncrement[2]; + + static const GrSamplerState gClampNoFilter; +}; + +#endif + |