bsalomon@google.com | 77af680 | 2013-10-02 13:04:56 +0000 | [diff] [blame] | 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 "GrEffect.h" |
| 12 | #include "SkMatrix.h" |
| 13 | #include "GrTexture.h" |
| 14 | #include "GrTypes.h" |
| 15 | |
| 16 | /** |
| 17 | * Coordinates available to GrEffect subclasses for requesting transformations. Transformed |
| 18 | * coordinates are made available in the the portion of fragment shader emitted by the effect. |
| 19 | */ |
| 20 | enum GrCoordSet { |
| 21 | /** |
| 22 | * The user-space coordinates that map to the fragment being rendered. These coords account for |
| 23 | * any change of coordinate system done on the CPU by GrContext before rendering, and also are |
| 24 | * correct for draws that take explicit local coords rather than inferring them from the |
| 25 | * primitive's positions (e.g. drawVertices). These are usually the coords a GrEffect wants. |
| 26 | */ |
| 27 | kLocal_GrCoordSet, |
| 28 | |
| 29 | /** |
| 30 | * The actual vertex position. Note that GrContext may not draw using the original view matrix |
| 31 | * specified by the caller, as it may have transformed vertices into another space. These are |
| 32 | * usually not the coordinates a GrEffect wants. |
| 33 | */ |
| 34 | kPosition_GrCoordSet |
| 35 | }; |
| 36 | |
| 37 | /** |
| 38 | * A class representing a linear transformation from one of the built-in coordinate sets (local or |
| 39 | * position). GrEffects just define these transformations, and the framework does the rest of the |
| 40 | * work to make the transformed coordinates available in their fragment shader. |
| 41 | */ |
commit-bot@chromium.org | e3beb6b | 2014-04-07 19:34:38 +0000 | [diff] [blame] | 42 | class GrCoordTransform : SkNoncopyable { |
bsalomon@google.com | 77af680 | 2013-10-02 13:04:56 +0000 | [diff] [blame] | 43 | public: |
commit-bot@chromium.org | 5fd7d5c | 2013-10-04 01:20:09 +0000 | [diff] [blame] | 44 | GrCoordTransform() { SkDEBUGCODE(fInEffect = false); } |
bsalomon@google.com | 77af680 | 2013-10-02 13:04:56 +0000 | [diff] [blame] | 45 | |
| 46 | /** |
| 47 | * Create a transformation that maps [0, 1] to a texture's boundaries. |
| 48 | */ |
| 49 | GrCoordTransform(GrCoordSet sourceCoords, const GrTexture* texture) { |
commit-bot@chromium.org | 5fd7d5c | 2013-10-04 01:20:09 +0000 | [diff] [blame] | 50 | SkDEBUGCODE(fInEffect = false); |
bsalomon@google.com | 77af680 | 2013-10-02 13:04:56 +0000 | [diff] [blame] | 51 | this->reset(sourceCoords, texture); |
| 52 | } |
| 53 | |
| 54 | /** |
| 55 | * Create a transformation from a matrix. The optional texture parameter is used to infer if the |
| 56 | * framework should internally do a y reversal to account for it being upside down by Skia's |
| 57 | * coord convention. |
| 58 | */ |
| 59 | GrCoordTransform(GrCoordSet sourceCoords, const SkMatrix& m, const GrTexture* texture = NULL) { |
commit-bot@chromium.org | 5fd7d5c | 2013-10-04 01:20:09 +0000 | [diff] [blame] | 60 | SkDEBUGCODE(fInEffect = false); |
bsalomon@google.com | 77af680 | 2013-10-02 13:04:56 +0000 | [diff] [blame] | 61 | this->reset(sourceCoords, m, texture); |
| 62 | } |
| 63 | |
| 64 | void reset(GrCoordSet sourceCoords, const GrTexture* texture) { |
commit-bot@chromium.org | 5fd7d5c | 2013-10-04 01:20:09 +0000 | [diff] [blame] | 65 | SkASSERT(!fInEffect); |
bsalomon@google.com | 77af680 | 2013-10-02 13:04:56 +0000 | [diff] [blame] | 66 | SkASSERT(NULL != texture); |
| 67 | this->reset(sourceCoords, GrEffect::MakeDivByTextureWHMatrix(texture), texture); |
| 68 | } |
| 69 | |
| 70 | void reset(GrCoordSet sourceCoords, const SkMatrix& m, const GrTexture* texture = NULL) { |
commit-bot@chromium.org | 5fd7d5c | 2013-10-04 01:20:09 +0000 | [diff] [blame] | 71 | SkASSERT(!fInEffect); |
bsalomon@google.com | 77af680 | 2013-10-02 13:04:56 +0000 | [diff] [blame] | 72 | fSourceCoords = sourceCoords; |
| 73 | fMatrix = m; |
| 74 | fReverseY = NULL != texture && kBottomLeft_GrSurfaceOrigin == texture->origin(); |
| 75 | } |
| 76 | |
commit-bot@chromium.org | 5fd7d5c | 2013-10-04 01:20:09 +0000 | [diff] [blame] | 77 | GrCoordTransform& operator= (const GrCoordTransform& other) { |
| 78 | SkASSERT(!fInEffect); |
| 79 | fSourceCoords = other.fSourceCoords; |
| 80 | fMatrix = other.fMatrix; |
| 81 | fReverseY = other.fReverseY; |
| 82 | return *this; |
| 83 | } |
| 84 | |
| 85 | /** |
| 86 | * Access the matrix for editing. Note, this must be done before adding the transform to an |
| 87 | * effect, since effects are immutable. |
| 88 | */ |
| 89 | SkMatrix* accessMatrix() { |
| 90 | SkASSERT(!fInEffect); |
| 91 | return &fMatrix; |
| 92 | } |
| 93 | |
bsalomon@google.com | 77af680 | 2013-10-02 13:04:56 +0000 | [diff] [blame] | 94 | bool operator== (const GrCoordTransform& other) const { |
| 95 | return fSourceCoords == other.fSourceCoords && |
| 96 | fMatrix.cheapEqualTo(other.fMatrix) && |
| 97 | fReverseY == other.fReverseY; |
| 98 | } |
| 99 | |
| 100 | GrCoordSet sourceCoords() const { return fSourceCoords; } |
| 101 | const SkMatrix& getMatrix() const { return fMatrix; } |
| 102 | bool reverseY() const { return fReverseY; } |
| 103 | |
| 104 | private: |
| 105 | GrCoordSet fSourceCoords; |
| 106 | SkMatrix fMatrix; |
| 107 | bool fReverseY; |
| 108 | |
| 109 | typedef SkNoncopyable INHERITED; |
commit-bot@chromium.org | 5fd7d5c | 2013-10-04 01:20:09 +0000 | [diff] [blame] | 110 | |
| 111 | #ifdef SK_DEBUG |
| 112 | public: |
| 113 | void setInEffect() const { fInEffect = true; } |
| 114 | private: |
| 115 | mutable bool fInEffect; |
| 116 | #endif |
bsalomon@google.com | 77af680 | 2013-10-02 13:04:56 +0000 | [diff] [blame] | 117 | }; |
| 118 | |
| 119 | #endif |