• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 /*
3  * Copyright 2010 Google Inc.
4  *
5  * Use of this source code is governed by a BSD-style license that can be
6  * found in the LICENSE file.
7  */
8 
9 
10 
11 #ifndef GrEffectStage_DEFINED
12 #define GrEffectStage_DEFINED
13 
14 #include "GrBackendEffectFactory.h"
15 #include "GrEffect.h"
16 #include "SkMatrix.h"
17 #include "GrTypes.h"
18 
19 #include "SkShader.h"
20 
21 class GrEffectStage {
22 public:
GrEffectStage()23     GrEffectStage()
24     : fEffectRef (NULL) {
25         GR_DEBUGCODE(fSavedCoordChangeCnt = 0;)
26     }
27 
~GrEffectStage()28     ~GrEffectStage() {
29         GrSafeUnref(fEffectRef);
30         GrAssert(0 == fSavedCoordChangeCnt);
31     }
32 
33     bool operator ==(const GrEffectStage& other) const {
34         // first handle cases where one or the other has no effect
35         if (NULL == fEffectRef) {
36             return NULL == other.fEffectRef;
37         } else if (NULL == other.fEffectRef) {
38             return false;
39         }
40 
41         if (!(*this->getEffect())->isEqual(*other.getEffect())) {
42             return false;
43         }
44 
45         return fCoordChangeMatrix == other.fCoordChangeMatrix;
46     }
47 
48     bool operator !=(const GrEffectStage& s) const { return !(*this == s); }
49 
50     GrEffectStage& operator =(const GrEffectStage& other) {
51         GrSafeAssign(fEffectRef, other.fEffectRef);
52         if (NULL != fEffectRef) {
53             fCoordChangeMatrix = other.fCoordChangeMatrix;
54         }
55         return *this;
56     }
57 
58     /**
59      * This is called when the coordinate system in which the geometry is specified will change.
60      *
61      * @param matrix    The transformation from the old coord system to the new one.
62      */
preConcatCoordChange(const SkMatrix & matrix)63     void preConcatCoordChange(const SkMatrix& matrix) { fCoordChangeMatrix.preConcat(matrix); }
64 
65     class SavedCoordChange {
66     private:
67         SkMatrix fCoordChangeMatrix;
68         GR_DEBUGCODE(mutable SkAutoTUnref<const GrEffectRef> fEffectRef;)
69 
70         friend class GrEffectStage;
71     };
72 
73     /**
74      * This gets the current coordinate system change. It is the accumulation of
75      * preConcatCoordChange calls since the effect was installed. It is used when then caller
76      * wants to temporarily change the source geometry coord system, draw something, and then
77      * restore the previous coord system (e.g. temporarily draw in device coords).
78      */
saveCoordChange(SavedCoordChange * savedCoordChange)79     void saveCoordChange(SavedCoordChange* savedCoordChange) const {
80         savedCoordChange->fCoordChangeMatrix = fCoordChangeMatrix;
81         GrAssert(NULL == savedCoordChange->fEffectRef.get());
82         GR_DEBUGCODE(GrSafeRef(fEffectRef);)
83         GR_DEBUGCODE(savedCoordChange->fEffectRef.reset(fEffectRef);)
84         GR_DEBUGCODE(++fSavedCoordChangeCnt);
85     }
86 
87     /**
88      * This balances the saveCoordChange call.
89      */
restoreCoordChange(const SavedCoordChange & savedCoordChange)90     void restoreCoordChange(const SavedCoordChange& savedCoordChange) {
91         fCoordChangeMatrix = savedCoordChange.fCoordChangeMatrix;
92         GrAssert(savedCoordChange.fEffectRef.get() == fEffectRef);
93         GR_DEBUGCODE(--fSavedCoordChangeCnt);
94         GR_DEBUGCODE(savedCoordChange.fEffectRef.reset(NULL);)
95     }
96 
97     /**
98      * Used when storing a deferred GrDrawState. The DeferredStage allows resources owned by its
99      * GrEffect to be recycled through the cache.
100      */
101     class DeferredStage {
102     public:
DeferredStage()103         DeferredStage() : fEffect(NULL) {
104             SkDEBUGCODE(fInitialized = false;)
105         }
106 
~DeferredStage()107         ~DeferredStage() {
108             if (NULL != fEffect) {
109                 fEffect->decDeferredRefCounts();
110             }
111         }
112 
saveFrom(const GrEffectStage & stage)113         void saveFrom(const GrEffectStage& stage) {
114             GrAssert(!fInitialized);
115             if (NULL != stage.fEffectRef) {
116                 stage.fEffectRef->get()->incDeferredRefCounts();
117                 fEffect = stage.fEffectRef->get();
118                 fCoordChangeMatrix = stage.fCoordChangeMatrix;
119             }
120             SkDEBUGCODE(fInitialized = true;)
121         }
122 
restoreTo(GrEffectStage * stage)123         void restoreTo(GrEffectStage* stage) {
124             GrAssert(fInitialized);
125             const GrEffectRef* oldEffectRef = stage->fEffectRef;
126             if (NULL != fEffect) {
127                 stage->fEffectRef = GrEffect::CreateEffectRef(fEffect);
128                 stage->fCoordChangeMatrix = fCoordChangeMatrix;
129             } else {
130                 stage->fEffectRef = NULL;
131             }
132             SkSafeUnref(oldEffectRef);
133         }
134 
isEqual(const GrEffectStage & stage)135         bool isEqual(const GrEffectStage& stage) const {
136             if (NULL == stage.fEffectRef) {
137                 return NULL == fEffect;
138             } else if (NULL == fEffect) {
139                 return false;
140             }
141 
142             if (!(*stage.getEffect())->isEqual(*fEffect)) {
143                 return false;
144             }
145 
146             return fCoordChangeMatrix == stage.fCoordChangeMatrix;
147         }
148 
149     private:
150         const GrEffect*               fEffect;
151         SkMatrix                      fCoordChangeMatrix;
152         SkDEBUGCODE(bool fInitialized;)
153     };
154 
155     /**
156      * Gets the matrix representing all changes of coordinate system since the GrEffect was
157      * installed in the stage.
158      */
getCoordChangeMatrix()159     const SkMatrix& getCoordChangeMatrix() const { return fCoordChangeMatrix; }
160 
reset()161     void reset() {
162         GrSafeSetNull(fEffectRef);
163     }
164 
setEffect(const GrEffectRef * EffectRef)165     const GrEffectRef* setEffect(const GrEffectRef* EffectRef) {
166         GrAssert(0 == fSavedCoordChangeCnt);
167         GrSafeAssign(fEffectRef, EffectRef);
168         fCoordChangeMatrix.reset();
169         return EffectRef;
170     }
171 
getEffect()172     const GrEffectRef* getEffect() const { return fEffectRef; }
173 
174 private:
175     SkMatrix            fCoordChangeMatrix;
176     const GrEffectRef*  fEffectRef;
177 
178     GR_DEBUGCODE(mutable int fSavedCoordChangeCnt;)
179 };
180 
181 #endif
182