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 /**
     18  * Coordinates available to GrProcessor subclasses for requesting transformations. Transformed
     19  * coordinates are made available in the the portion of fragment shader emitted by the effect.
     20  *
     21  * The precision of the shader var that interpolates the transformed coordinates can be specified.
     22  */
     23 enum GrCoordSet {
     24     /**
     25      * The user-space coordinates that map to the fragment being rendered. This is the space in
     26      * which SkShader operates. It is usually the space in which geometry passed to SkCanvas is
     27      * specified (before the view matrix is applied). However, some draw calls take explicit local
     28      * coords that map onto the geometry (e.g. drawVertices, drawBitmapRectToRect).
     29      */
     30     kLocal_GrCoordSet,
     31 
     32     /**
     33      * The device space position of the fragment being shaded.
     34      */
     35     kDevice_GrCoordSet,
     36 };
     37 
     38 /**
     39  * A class representing a linear transformation from one of the built-in coordinate sets (local or
     40  * position). GrProcessors just define these transformations, and the framework does the rest of the
     41  * work to make the transformed coordinates available in their fragment shader.
     42  */
     43 class GrCoordTransform : SkNoncopyable {
     44 public:
     45     GrCoordTransform() : fSourceCoords(kLocal_GrCoordSet) { SkDEBUGCODE(fInProcessor = false); }
     46 
     47     /**
     48      * Create a transformation that maps [0, 1] to a texture's boundaries. The precision is inferred
     49      * from the texture size and filter. The texture origin also implies whether a y-reversal should
     50      * be performed.
     51      */
     52     GrCoordTransform(GrCoordSet sourceCoords,
     53                      const GrTexture* texture,
     54                      GrTextureParams::FilterMode filter) {
     55         SkASSERT(texture);
     56         SkDEBUGCODE(fInProcessor = false);
     57         this->reset(sourceCoords, texture, filter);
     58     }
     59 
     60     /**
     61      * Create a transformation from a matrix. The precision is inferred from the texture size and
     62      * filter. The texture origin also implies whether a y-reversal should be performed.
     63      */
     64     GrCoordTransform(GrCoordSet sourceCoords, const SkMatrix& m,
     65                      const GrTexture* texture, GrTextureParams::FilterMode filter) {
     66         SkDEBUGCODE(fInProcessor = false);
     67         SkASSERT(texture);
     68         this->reset(sourceCoords, m, texture, filter);
     69     }
     70 
     71     /**
     72      * Create a transformation that applies the matrix to a coord set.
     73      */
     74     GrCoordTransform(GrCoordSet sourceCoords, const SkMatrix& m,
     75                      GrSLPrecision precision = kDefault_GrSLPrecision) {
     76         SkDEBUGCODE(fInProcessor = false);
     77         this->reset(sourceCoords, m, precision);
     78     }
     79 
     80     void reset(GrCoordSet sourceCoords, const GrTexture* texture,
     81                GrTextureParams::FilterMode filter) {
     82         SkASSERT(!fInProcessor);
     83         SkASSERT(texture);
     84         this->reset(sourceCoords, MakeDivByTextureWHMatrix(texture), texture, filter);
     85     }
     86 
     87     void reset(GrCoordSet, const SkMatrix&, const GrTexture*, GrTextureParams::FilterMode filter);
     88     void reset(GrCoordSet sourceCoords, const SkMatrix& m,
     89                GrSLPrecision precision = kDefault_GrSLPrecision);
     90 
     91     GrCoordTransform& operator= (const GrCoordTransform& that) {
     92         SkASSERT(!fInProcessor);
     93         fSourceCoords = that.fSourceCoords;
     94         fMatrix = that.fMatrix;
     95         fReverseY = that.fReverseY;
     96         fPrecision = that.fPrecision;
     97         return *this;
     98     }
     99 
    100     /**
    101      * Access the matrix for editing. Note, this must be done before adding the transform to an
    102      * effect, since effects are immutable.
    103      */
    104     SkMatrix* accessMatrix() {
    105         SkASSERT(!fInProcessor);
    106         return &fMatrix;
    107     }
    108 
    109     bool operator==(const GrCoordTransform& that) const {
    110         return fSourceCoords == that.fSourceCoords &&
    111                fMatrix.cheapEqualTo(that.fMatrix) &&
    112                fReverseY == that.fReverseY &&
    113                fPrecision == that.fPrecision;
    114     }
    115 
    116     bool operator!=(const GrCoordTransform& that) const { return !(*this == that); }
    117 
    118     GrCoordSet sourceCoords() const { return fSourceCoords; }
    119     const SkMatrix& getMatrix() const { return fMatrix; }
    120     bool reverseY() const { return fReverseY; }
    121     GrSLPrecision precision() const { return fPrecision; }
    122 
    123     /** Useful for effects that want to insert a texture matrix that is implied by the texture
    124         dimensions */
    125     static inline SkMatrix MakeDivByTextureWHMatrix(const GrTexture* texture) {
    126         SkASSERT(texture);
    127         SkMatrix mat;
    128         (void)mat.setIDiv(texture->width(), texture->height());
    129         return mat;
    130     }
    131 
    132 private:
    133     GrCoordSet              fSourceCoords;
    134     SkMatrix                fMatrix;
    135     bool                    fReverseY;
    136     GrSLPrecision           fPrecision;
    137     typedef SkNoncopyable INHERITED;
    138 
    139 #ifdef SK_DEBUG
    140 public:
    141     void setInProcessor() const { fInProcessor = true; }
    142 private:
    143     mutable bool fInProcessor;
    144 #endif
    145 };
    146 
    147 #endif
    148