aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/GrCoordTransform.h
blob: 5bccf5c6d823497cfb556b875bfa20a8ff6cd18d (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
135
136
137
138
139
140
141
142
/*
 * 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 "SkMatrix.h"
#include "GrSurfaceProxyPriv.h"
#include "GrTextureProxy.h"

class GrTexture;

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

    /**
     * Create a transformation that maps [0, 1] to a proxy's boundaries. The proxy origin also
     * implies whether a y-reversal should be performed.
     */
    GrCoordTransform(GrTextureProxy* proxy) {
        SkASSERT(proxy);
        SkDEBUGCODE(fInProcessor = false);
        this->reset(SkMatrix::I(), proxy, true);
    }

    /**
     * Create a transformation from a matrix. The proxy origin also implies whether a y-reversal
     * should be performed.
     */
    GrCoordTransform(const SkMatrix& m, GrTextureProxy* proxy) {
        SkASSERT(proxy);
        SkDEBUGCODE(fInProcessor = false);
        this->reset(m, proxy, true);
    }

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

    void reset(const SkMatrix& m, GrTextureProxy* proxy, bool normalize) {
        SkASSERT(proxy);
        SkASSERT(!fInProcessor);

        fMatrix = m;
        fProxy = proxy;
        fNormalize = normalize;
        fReverseY = kBottomLeft_GrSurfaceOrigin == proxy->origin();
    }

    void reset(const SkMatrix& m) {
        SkASSERT(!fInProcessor);
        fMatrix = m;
        fProxy = nullptr;
        fNormalize = false;
        fReverseY = false;
    }

    GrCoordTransform& operator= (const GrCoordTransform& that) {
        SkASSERT(!fInProcessor);
        fMatrix = that.fMatrix;
        fProxy = that.fProxy;
        fNormalize = that.fNormalize;
        fReverseY = that.fReverseY;
        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 ||
            !fMatrix.cheapEqualTo(that.fMatrix)) {
            return false;
        }

        if (fNormalize) {
            if (fProxy->underlyingUniqueID() != that.fProxy->underlyingUniqueID()) {
                return false;
            }
        }

        return true;
    }

    const SkMatrix& getMatrix() const { return fMatrix; }
    const GrTextureProxy* proxy() const { return fProxy; }
    bool normalize() const { return fNormalize; }
    bool reverseY() const { return fReverseY; }

    // This should only ever be called at flush time after the backing texture has been
    // successfully instantiated
    GrTexture* peekTexture() const {
        SkASSERT(fProxy->priv().peekTexture());
        return fProxy->priv().peekTexture();
    }

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 GrTextureProxy*   fProxy;
    bool                    fNormalize;
    bool                    fReverseY;
    typedef SkNoncopyable INHERITED;

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

#endif