Home | History | Annotate | Download | only in gpu
      1 /*
      2  * Copyright 2013 Google Inc.
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 #ifndef GrCoordTransform_DEFINED
      9 #define GrCoordTransform_DEFINED
     10 
     11 #include "GrProcessor.h"
     12 #include "SkMatrix.h"
     13 #include "GrTexture.h"
     14 #include "GrTypes.h"
     15 #include "GrShaderVar.h"
     16 
     17 class GrTextureProxy;
     18 
     19 /**
     20  * A class representing a linear transformation of local coordinates. GrFragnentProcessors
     21  * these transformations, and the GrGeometryProcessor implements the transformation.
     22  */
     23 class GrCoordTransform : SkNoncopyable {
     24 public:
     25     GrCoordTransform()
     26         : fTexture(nullptr)
     27         , fNormalize(false)
     28         , fReverseY(false)
     29         , fPrecision(kDefault_GrSLPrecision) {
     30         SkDEBUGCODE(fInProcessor = false);
     31     }
     32 
     33     /**
     34      * Create a transformation that maps [0, 1] to a texture's boundaries. The precision is inferred
     35      * from the texture size and filter. The texture origin also implies whether a y-reversal should
     36      * be performed.
     37      */
     38     GrCoordTransform(const GrTexture* texture, GrSamplerParams::FilterMode filter) {
     39         SkASSERT(texture);
     40         SkDEBUGCODE(fInProcessor = false);
     41         this->reset(SkMatrix::I(), texture, filter);
     42     }
     43 
     44     GrCoordTransform(GrResourceProvider* resourceProvider, GrTextureProxy* proxy,
     45                      GrSamplerParams::FilterMode filter) {
     46         SkASSERT(proxy);
     47         SkDEBUGCODE(fInProcessor = false);
     48         this->reset(resourceProvider, SkMatrix::I(), proxy, filter);
     49     }
     50 
     51     /**
     52      * Create a transformation from a matrix. The precision is inferred from the texture size and
     53      * filter. The texture origin also implies whether a y-reversal should be performed.
     54      */
     55     GrCoordTransform(const SkMatrix& m, const GrTexture* texture,
     56                      GrSamplerParams::FilterMode filter) {
     57         SkASSERT(texture);
     58         SkDEBUGCODE(fInProcessor = false);
     59         this->reset(m, texture, filter);
     60     }
     61 
     62     GrCoordTransform(GrResourceProvider* resourceProvider, const SkMatrix& m,
     63                      GrTextureProxy* proxy, GrSamplerParams::FilterMode filter) {
     64         SkASSERT(proxy);
     65         SkDEBUGCODE(fInProcessor = false);
     66         this->reset(resourceProvider, m, proxy, filter);
     67     }
     68 
     69     /**
     70      * Create a transformation that applies the matrix to a coord set.
     71      */
     72     GrCoordTransform(const SkMatrix& m, GrSLPrecision precision = kDefault_GrSLPrecision) {
     73         SkDEBUGCODE(fInProcessor = false);
     74         this->reset(m, precision);
     75     }
     76 
     77     // MDB TODO: rm the GrTexture* flavor of reset
     78     void reset(const SkMatrix&, const GrTexture*, GrSamplerParams::FilterMode filter,
     79                bool normalize = true);
     80 
     81     void reset(GrResourceProvider*, const SkMatrix&, GrTextureProxy*,
     82                GrSamplerParams::FilterMode filter, bool normalize = true);
     83 
     84     void reset(const SkMatrix& m, GrSLPrecision precision = kDefault_GrSLPrecision) {
     85         SkASSERT(!fInProcessor);
     86         fMatrix = m;
     87         fTexture = nullptr;
     88         fNormalize = false;
     89         fReverseY = false;
     90         fPrecision = precision;
     91     }
     92 
     93     GrCoordTransform& operator= (const GrCoordTransform& that) {
     94         SkASSERT(!fInProcessor);
     95         fMatrix = that.fMatrix;
     96         fTexture = that.fTexture;
     97         fNormalize = that.fNormalize;
     98         fReverseY = that.fReverseY;
     99         fPrecision = that.fPrecision;
    100         return *this;
    101     }
    102 
    103     /**
    104      * Access the matrix for editing. Note, this must be done before adding the transform to an
    105      * effect, since effects are immutable.
    106      */
    107     SkMatrix* accessMatrix() {
    108         SkASSERT(!fInProcessor);
    109         return &fMatrix;
    110     }
    111 
    112     bool hasSameEffectAs(const GrCoordTransform& that) const {
    113         if (fNormalize != that.fNormalize ||
    114             fReverseY != that.fReverseY ||
    115             fPrecision != that.fPrecision ||
    116             !fMatrix.cheapEqualTo(that.fMatrix)) {
    117             return false;
    118         }
    119 
    120         if (fNormalize) {
    121             SkASSERT(fTexture && that.fTexture);
    122             return fTexture->width() == that.fTexture->width() &&
    123                    fTexture->height() == that.fTexture->height();
    124         }
    125 
    126         return true;
    127     }
    128 
    129     const SkMatrix& getMatrix() const { return fMatrix; }
    130     const GrTexture* texture() const { return fTexture; }
    131     bool normalize() const { return fNormalize; }
    132     bool reverseY() const { return fReverseY; }
    133     GrSLPrecision precision() const { return fPrecision; }
    134 
    135 private:
    136     // The textures' effect is to optionally normalize the final matrix, so a blind
    137     // equality check could be misleading
    138     bool operator==(const GrCoordTransform& that) const;
    139     bool operator!=(const GrCoordTransform& that) const;
    140 
    141     SkMatrix                fMatrix;
    142     const GrTexture*        fTexture;
    143     bool                    fNormalize;
    144     bool                    fReverseY;
    145     GrSLPrecision           fPrecision;
    146     typedef SkNoncopyable INHERITED;
    147 
    148 #ifdef SK_DEBUG
    149 public:
    150     void setInProcessor() const { fInProcessor = true; }
    151 private:
    152     mutable bool fInProcessor;
    153 #endif
    154 };
    155 
    156 #endif
    157