aboutsummaryrefslogtreecommitdiffhomepage
path: root/include/gpu/GrCoordTransform.h
blob: 5c16c8967981e02bcc0b4b43af7c0f4396b3d182 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/*
 * Copyright 2013 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef GrCoordTransform_DEFINED
#define GrCoordTransform_DEFINED

#include "GrProcessor.h"
#include "SkMatrix.h"
#include "GrTexture.h"
#include "GrTypes.h"
#include "GrShaderVar.h"

/**
 * A class representing a linear transformation of local coordinates. GrFragnentProcessors
 * these transformations, and the GrGeometryProcessor implements the transformation.
 */
class GrCoordTransform : SkNoncopyable {
public:
    GrCoordTransform()
        : fTexture(nullptr)
        , fNormalize(false) {
        SkDEBUGCODE(fInProcessor = false);
    }

    /**
     * Create a transformation that maps [0, 1] to a texture's boundaries. The precision is inferred
     * from the texture size and filter. The texture origin also implies whether a y-reversal should
     * be performed.
     */
    GrCoordTransform(const GrTexture* texture, GrSamplerParams::FilterMode filter) {
        SkASSERT(texture);
        SkDEBUGCODE(fInProcessor = false);
        this->reset(SkMatrix::I(), texture, filter);
    }

    /**
     * Create a transformation from a matrix. The precision is inferred from the texture size and
     * filter. The texture origin also implies whether a y-reversal should be performed.
     */
    GrCoordTransform(const SkMatrix& m, const GrTexture* texture,
                     GrSamplerParams::FilterMode filter) {
        SkDEBUGCODE(fInProcessor = false);
        SkASSERT(texture);
        this->reset(m, texture, filter);
    }

    /**
     * Create a transformation that applies the matrix to a coord set.
     */
    GrCoordTransform(const SkMatrix& m, GrSLPrecision precision = kDefault_GrSLPrecision) {
        SkDEBUGCODE(fInProcessor = false);
        this->reset(m, precision);
    }

    void reset(const SkMatrix&, const GrTexture*, GrSamplerParams::FilterMode filter,
               bool normalize = true);

    void reset(const SkMatrix& m, GrSLPrecision precision = kDefault_GrSLPrecision) {
        SkASSERT(!fInProcessor);
        fMatrix = m;
        fTexture = nullptr;
        fNormalize = false;
        fReverseY = false;
        fPrecision = precision;
    }

    GrCoordTransform& operator= (const GrCoordTransform& that) {
        SkASSERT(!fInProcessor);
        fMatrix = that.fMatrix;
        fTexture = that.fTexture;
        fNormalize = that.fNormalize;
        fReverseY = that.fReverseY;
        fPrecision = that.fPrecision;
        return *this;
    }

    /**
     * Access the matrix for editing. Note, this must be done before adding the transform to an
     * effect, since effects are immutable.
     */
    SkMatrix* accessMatrix() {
        SkASSERT(!fInProcessor);
        return &fMatrix;
    }

    bool hasSameEffectAs(const GrCoordTransform& that) const {
        if (fNormalize != that.fNormalize ||
            fReverseY != that.fReverseY ||
            fPrecision != that.fPrecision ||
            !fMatrix.cheapEqualTo(that.fMatrix)) {
            return false;
        }

        if (fNormalize) {
            SkASSERT(fTexture && that.fTexture);
            return fTexture->width() == that.fTexture->width() &&
                   fTexture->height() == that.fTexture->height();
        }

        return true;
    }

    const SkMatrix& getMatrix() const { return fMatrix; }
    const GrTexture* texture() const { return fTexture; }
    bool normalize() const { return fNormalize; }
    bool reverseY() const { return fReverseY; }
    GrSLPrecision precision() const { return fPrecision; }

private:
    // The textures' effect is to optionally normalize the final matrix, so a blind
    // equality check could be misleading
    bool operator==(const GrCoordTransform& that) const;
    bool operator!=(const GrCoordTransform& that) const;

    SkMatrix                fMatrix;
    const GrTexture*        fTexture;
    bool                    fNormalize;
    bool                    fReverseY;
    GrSLPrecision           fPrecision;
    typedef SkNoncopyable INHERITED;

#ifdef SK_DEBUG
public:
    void setInProcessor() const { fInProcessor = true; }
private:
    mutable bool fInProcessor;
#endif
};

#endif