Home | History | Annotate | Download | only in include
      1 /*
      2     Copyright 2010 Google Inc.
      3 
      4     Licensed under the Apache License, Version 2.0 (the "License");
      5     you may not use this file except in compliance with the License.
      6     You may obtain a copy of the License at
      7 
      8          http://www.apache.org/licenses/LICENSE-2.0
      9 
     10     Unless required by applicable law or agreed to in writing, software
     11     distributed under the License is distributed on an "AS IS" BASIS,
     12     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13     See the License for the specific language governing permissions and
     14     limitations under the License.
     15  */
     16 
     17 
     18 #ifndef GrSamplerState_DEFINED
     19 #define GrSamplerState_DEFINED
     20 
     21 #include "GrTypes.h"
     22 #include "GrMatrix.h"
     23 
     24 class GrSamplerState {
     25 public:
     26     enum Filter {
     27         /**
     28          * Read the closest src texel to the sample position
     29          */
     30         kNearest_Filter,
     31         /**
     32          * Blend between closest 4 src texels to sample position (tent filter)
     33          */
     34         kBilinear_Filter,
     35         /**
     36          * Average of 4 bilinear filterings spaced +/- 1 texel from sample
     37          * position in x and y. Intended for averaging 16 texels in a downsample
     38          * pass. (rasterizing such that texture samples fall exactly halfway
     39          * between texels in x and y spaced 4 texels apart.)
     40          */
     41         k4x4Downsample_Filter,
     42     };
     43 
     44     /**
     45      * The intepretation of the texture matrix depends on the sample mode. The
     46      * texture matrix is applied both when the texture coordinates are explicit
     47      * and  when vertex positions are used as texture  coordinates. In the latter
     48      * case the texture matrix is applied to the pre-view-matrix position
     49      * values.
     50      *
     51      * kNormal_SampleMode
     52      *  The post-matrix texture coordinates are in normalize space with (0,0) at
     53      *  the top-left and (1,1) at the bottom right.
     54      * kRadial_SampleMode
     55      *  The matrix specifies the radial gradient parameters.
     56      *  (0,0) in the post-matrix space is center of the radial gradient.
     57      * kRadial2_SampleMode
     58      *   Matrix transforms to space where first circle is centered at the
     59      *   origin. The second circle will be centered (x, 0) where x may be
     60      *   0 and is provided by setRadial2Params. The post-matrix space is
     61      *   normalized such that 1 is the second radius - first radius.
     62      * kSweepSampleMode
     63      *  The angle from the origin of texture coordinates in post-matrix space
     64      *  determines the gradient value.
     65      */
     66     enum SampleMode {
     67         kNormal_SampleMode,     //!< sample color directly
     68         kRadial_SampleMode,     //!< treat as radial gradient
     69         kRadial2_SampleMode,    //!< treat as 2-point radial gradient
     70         kSweep_SampleMode,      //!< treat as sweep gradient
     71     };
     72 
     73     /**
     74      * Describes how a texture is sampled when coordinates are outside the
     75      * texture border
     76      */
     77     enum WrapMode {
     78         kClamp_WrapMode,
     79         kRepeat_WrapMode,
     80         kMirror_WrapMode
     81     };
     82 
     83     /**
     84      * Default sampler state is set to clamp, use normal sampling mode, be
     85      * unfiltered, and use identity matrix.
     86      */
     87     GrSamplerState() {
     88         this->setClampNoFilter();
     89     }
     90 
     91     explicit GrSamplerState(Filter filter) {
     92         fWrapX = kClamp_WrapMode;
     93         fWrapY = kClamp_WrapMode;
     94         fSampleMode = kNormal_SampleMode;
     95         fFilter = filter;
     96         fMatrix.setIdentity();
     97         fTextureDomain.setEmpty();
     98     }
     99 
    100     GrSamplerState(WrapMode wx, WrapMode wy, Filter filter) {
    101         fWrapX = wx;
    102         fWrapY = wy;
    103         fSampleMode = kNormal_SampleMode;
    104         fFilter = filter;
    105         fMatrix.setIdentity();
    106         fTextureDomain.setEmpty();
    107     }
    108 
    109     GrSamplerState(WrapMode wx, WrapMode wy,
    110                    const GrMatrix& matrix, Filter filter) {
    111         fWrapX = wx;
    112         fWrapY = wy;
    113         fSampleMode = kNormal_SampleMode;
    114         fFilter = filter;
    115         fMatrix = matrix;
    116         fTextureDomain.setEmpty();
    117     }
    118 
    119     GrSamplerState(WrapMode wx, WrapMode wy, SampleMode sample,
    120                    const GrMatrix& matrix, Filter filter) {
    121         fWrapX = wx;
    122         fWrapY = wy;
    123         fSampleMode = sample;
    124         fMatrix = matrix;
    125         fFilter = filter;
    126         fTextureDomain.setEmpty();
    127     }
    128 
    129     WrapMode getWrapX() const { return fWrapX; }
    130     WrapMode getWrapY() const { return fWrapY; }
    131     SampleMode getSampleMode() const { return fSampleMode; }
    132     const GrMatrix& getMatrix() const { return fMatrix; }
    133     const GrRect& getTextureDomain() const { return fTextureDomain; }
    134     bool hasTextureDomain() const {return SkIntToScalar(0) != fTextureDomain.right();}
    135     Filter getFilter() const { return fFilter; }
    136 
    137     bool isGradient() const {
    138         return  kRadial_SampleMode == fSampleMode ||
    139                 kRadial2_SampleMode == fSampleMode ||
    140                 kSweep_SampleMode == fSampleMode;
    141     }
    142 
    143     void setWrapX(WrapMode mode) { fWrapX = mode; }
    144     void setWrapY(WrapMode mode) { fWrapY = mode; }
    145     void setSampleMode(SampleMode mode) { fSampleMode = mode; }
    146 
    147     /**
    148      * Sets the sampler's matrix. See SampleMode for explanation of
    149      * relationship between the matrix and sample mode.
    150      * @param matrix the matrix to set
    151      */
    152     void setMatrix(const GrMatrix& matrix) { fMatrix = matrix; }
    153 
    154     /**
    155      * Sets the sampler's texture coordinate domain to a
    156      * custom rectangle, rather than the default (0,1).
    157      * This option is currently only supported with kClamp_WrapMode
    158      */
    159     void setTextureDomain(const GrRect& textureDomain) { fTextureDomain = textureDomain; }
    160 
    161     /**
    162      *  Multiplies the current sampler matrix  a matrix
    163      *
    164      *  After this call M' = M*m where M is the old matrix, m is the parameter
    165      *  to this function, and M' is the new matrix. (We consider points to
    166      *  be column vectors so tex cood vector t is transformed by matrix X as
    167      *  t' = X*t.)
    168      *
    169      *  @param matrix   the matrix used to modify the matrix.
    170      */
    171     void preConcatMatrix(const GrMatrix& matrix) { fMatrix.preConcat(matrix); }
    172 
    173     /**
    174      * Sets filtering type.
    175      * @param filter    type of filtering to apply
    176      */
    177     void setFilter(Filter filter) { fFilter = filter; }
    178 
    179     void setClampNoFilter() {
    180         fWrapX = kClamp_WrapMode;
    181         fWrapY = kClamp_WrapMode;
    182         fSampleMode = kNormal_SampleMode;
    183         fFilter = kNearest_Filter;
    184         fMatrix.setIdentity();
    185         fTextureDomain.setEmpty();
    186     }
    187 
    188     GrScalar getRadial2CenterX1() const { return fRadial2CenterX1; }
    189     GrScalar getRadial2Radius0() const { return fRadial2Radius0; }
    190     bool     isRadial2PosRoot() const { return fRadial2PosRoot; }
    191 
    192     /**
    193      * Sets the parameters for kRadial2_SampleMode. The texture
    194      * matrix must be set so that the first point is at (0,0) and the second
    195      * point lies on the x-axis. The second radius minus the first is 1 unit.
    196      * The additional parameters to define the gradient are specified by this
    197      * function.
    198      */
    199     void setRadial2Params(GrScalar centerX1, GrScalar radius0, bool posRoot) {
    200         fRadial2CenterX1 = centerX1;
    201         fRadial2Radius0 = radius0;
    202         fRadial2PosRoot = posRoot;
    203     }
    204 
    205     static const GrSamplerState& ClampNoFilter() {
    206         return gClampNoFilter;
    207     }
    208 
    209 private:
    210     WrapMode    fWrapX;
    211     WrapMode    fWrapY;
    212     SampleMode  fSampleMode;
    213     Filter      fFilter;
    214     GrMatrix    fMatrix;
    215     GrRect      fTextureDomain;
    216 
    217     // these are undefined unless fSampleMode == kRadial2_SampleMode
    218     GrScalar    fRadial2CenterX1;
    219     GrScalar    fRadial2Radius0;
    220     bool        fRadial2PosRoot;
    221 
    222     static const GrSamplerState gClampNoFilter;
    223 };
    224 
    225 #endif
    226 
    227