3 * Copyright 2010 Google Inc.
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
11 #ifndef GrEffectStage_DEFINED
12 #define GrEffectStage_DEFINED
14 #include "GrBackendEffectFactory.h"
23 explicit GrEffectStage(const GrEffect* effect, int attrIndex0 = -1, int attrIndex1 = -1)
24 : fEffect(SkRef(effect)) {
25 fCoordChangeMatrixSet = false;
26 fVertexAttribIndices[0] = attrIndex0;
27 fVertexAttribIndices[1] = attrIndex1;
30 GrEffectStage(const GrEffectStage& other) {
34 GrEffectStage& operator= (const GrEffectStage& other) {
35 fCoordChangeMatrixSet = other.fCoordChangeMatrixSet;
36 if (other.fCoordChangeMatrixSet) {
37 fCoordChangeMatrix = other.fCoordChangeMatrix;
39 fEffect.reset(SkRef(other.fEffect.get()));
40 memcpy(fVertexAttribIndices, other.fVertexAttribIndices, sizeof(fVertexAttribIndices));
44 static bool AreCompatible(const GrEffectStage& a, const GrEffectStage& b,
45 bool usingExplicitLocalCoords) {
46 SkASSERT(NULL != a.fEffect.get());
47 SkASSERT(NULL != b.fEffect.get());
49 if (!a.getEffect()->isEqual(*b.getEffect())) {
53 // We always track the coord change matrix, but it has no effect when explicit local coords
55 if (usingExplicitLocalCoords) {
59 if (a.fCoordChangeMatrixSet != b.fCoordChangeMatrixSet) {
63 if (!a.fCoordChangeMatrixSet) {
67 return a.fCoordChangeMatrix == b.fCoordChangeMatrix;
71 * This is called when the coordinate system in which the geometry is specified will change.
73 * @param matrix The transformation from the old coord system in which geometry is specified
74 * to the new one from which it will actually be drawn.
76 void localCoordChange(const SkMatrix& matrix) {
77 if (fCoordChangeMatrixSet) {
78 fCoordChangeMatrix.preConcat(matrix);
80 fCoordChangeMatrixSet = true;
81 fCoordChangeMatrix = matrix;
85 class SavedCoordChange {
87 bool fCoordChangeMatrixSet;
88 SkMatrix fCoordChangeMatrix;
89 SkDEBUGCODE(mutable SkAutoTUnref<const GrEffect> fEffect;)
91 friend class GrEffectStage;
95 * This gets the current coordinate system change. It is the accumulation of
96 * localCoordChange calls since the effect was installed. It is used when then caller
97 * wants to temporarily change the source geometry coord system, draw something, and then
98 * restore the previous coord system (e.g. temporarily draw in device coords).
100 void saveCoordChange(SavedCoordChange* savedCoordChange) const {
101 savedCoordChange->fCoordChangeMatrixSet = fCoordChangeMatrixSet;
102 if (fCoordChangeMatrixSet) {
103 savedCoordChange->fCoordChangeMatrix = fCoordChangeMatrix;
105 SkASSERT(NULL == savedCoordChange->fEffect.get());
106 SkDEBUGCODE(SkRef(fEffect.get());)
107 SkDEBUGCODE(savedCoordChange->fEffect.reset(fEffect.get());)
111 * This balances the saveCoordChange call.
113 void restoreCoordChange(const SavedCoordChange& savedCoordChange) {
114 fCoordChangeMatrixSet = savedCoordChange.fCoordChangeMatrixSet;
115 if (fCoordChangeMatrixSet) {
116 fCoordChangeMatrix = savedCoordChange.fCoordChangeMatrix;
118 SkASSERT(savedCoordChange.fEffect.get() == fEffect);
119 SkDEBUGCODE(savedCoordChange.fEffect.reset(NULL);)
123 * Gets the matrix representing all changes of coordinate system since the GrEffect was
124 * installed in the stage.
126 const SkMatrix& getCoordChangeMatrix() const {
127 if (fCoordChangeMatrixSet) {
128 return fCoordChangeMatrix;
130 return SkMatrix::I();
134 const GrEffect* getEffect() const { return fEffect.get(); }
136 const int* getVertexAttribIndices() const { return fVertexAttribIndices; }
137 int getVertexAttribIndexCount() const { return fEffect->numVertexAttribs(); }
140 bool fCoordChangeMatrixSet;
141 SkMatrix fCoordChangeMatrix;
142 SkAutoTUnref<const GrEffect> fEffect;
143 int fVertexAttribIndices[2];