blob: bb7e42a45898aa542a48992e0532119b72f0f223 [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
reed@google.comac10a2d2010-12-22 21:39:39 +00002/*
epoger@google.comec3ed6a2011-07-28 14:26:00 +00003 * 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.
reed@google.comac10a2d2010-12-22 21:39:39 +00007 */
8
9
epoger@google.comec3ed6a2011-07-28 14:26:00 +000010
reed@google.comac10a2d2010-12-22 21:39:39 +000011#ifndef GrSamplerState_DEFINED
12#define GrSamplerState_DEFINED
13
tomhudson@google.com07eecdc2012-04-20 18:35:38 +000014#include "GrCustomStage.h"
bsalomon@google.comc6cf7232011-02-17 16:43:10 +000015#include "GrMatrix.h"
tomhudson@google.com07eecdc2012-04-20 18:35:38 +000016#include "GrTypes.h"
reed@google.comac10a2d2010-12-22 21:39:39 +000017
bsalomon@google.comb8670992012-07-25 21:27:09 +000018#include "SkShader.h"
19
reed@google.comac10a2d2010-12-22 21:39:39 +000020class GrSamplerState {
21public:
bsalomon@google.com6aef1fb2011-05-05 12:33:22 +000022
bsalomon@google.com6aab8e32011-06-21 20:32:12 +000023 GrSamplerState()
tomhudson@google.com898e7b52012-06-01 20:42:15 +000024 : fCustomStage (NULL) {
bsalomon@google.com288d9542012-10-17 12:53:54 +000025 GR_DEBUGCODE(fSavedCoordChangeCnt = 0;)
reed@google.comac10a2d2010-12-22 21:39:39 +000026 }
27
tomhudson@google.com07eecdc2012-04-20 18:35:38 +000028 ~GrSamplerState() {
29 GrSafeUnref(fCustomStage);
bsalomon@google.com288d9542012-10-17 12:53:54 +000030 GrAssert(0 == fSavedCoordChangeCnt);
tomhudson@google.com07eecdc2012-04-20 18:35:38 +000031 }
32
bsalomon@google.com288d9542012-10-17 12:53:54 +000033 bool operator ==(const GrSamplerState& other) const {
34 // first handle cases where one or the other has no custom stage
35 if (NULL == fCustomStage) {
36 return NULL == other.fCustomStage;
37 } else if (NULL == other.fCustomStage) {
38 return false;
39 }
40
41 if (fCustomStage->getFactory() != other.fCustomStage->getFactory()) {
42 return false;
43 }
44
45 if (!fCustomStage->isEqual(*other.fCustomStage)) {
46 return false;
47 }
48
49 return fMatrix == other.fMatrix && fCoordChangeMatrix == other.fCoordChangeMatrix;
tomhudson@google.com02b1ea22012-04-30 20:19:07 +000050 }
bsalomon@google.com288d9542012-10-17 12:53:54 +000051
tomhudson@google.com02b1ea22012-04-30 20:19:07 +000052 bool operator !=(const GrSamplerState& s) const { return !(*this == s); }
53
bsalomon@google.com288d9542012-10-17 12:53:54 +000054 GrSamplerState& operator =(const GrSamplerState& other) {
55 GrSafeAssign(fCustomStage, other.fCustomStage);
56 if (NULL != fCustomStage) {
57 fMatrix = other.fMatrix;
58 fCoordChangeMatrix = other.fCoordChangeMatrix;
59 }
tomhudson@google.com02b1ea22012-04-30 20:19:07 +000060 return *this;
61 }
62
bsalomon@google.com288d9542012-10-17 12:53:54 +000063 /**
64 * This is called when the coordinate system in which the geometry is specified will change.
65 *
66 * @param matrix The transformation from the old coord system to the new one.
67 */
68 void preConcatCoordChange(const GrMatrix& matrix) { fCoordChangeMatrix.preConcat(matrix); }
69
70 class SavedCoordChange {
71 private:
72 GrMatrix fCoordChangeMatrix;
73 GR_DEBUGCODE(mutable SkAutoTUnref<GrCustomStage> fCustomStage;)
74
75 friend class GrSamplerState;
76 };
77
78 /**
79 * This gets the current coordinate system change. It is the accumulation of
80 * preConcatCoordChange calls since the custom stage was installed. It is used when then caller
81 * wants to temporarily change the source geometry coord system, draw something, and then
82 * restore the previous coord system (e.g. temporarily draw in device coords).s
83 */
84 void saveCoordChange(SavedCoordChange* savedCoordChange) const {
85 savedCoordChange->fCoordChangeMatrix = fCoordChangeMatrix;
86 GrAssert(NULL == savedCoordChange->fCustomStage.get());
87 GR_DEBUGCODE(GrSafeRef(fCustomStage);)
88 GR_DEBUGCODE(savedCoordChange->fCustomStage.reset(fCustomStage);)
89 GR_DEBUGCODE(++fSavedCoordChangeCnt);
90 }
91
92 /**
93 * This balances the saveCoordChange call.
94 */
95 void restoreCoordChange(const SavedCoordChange& savedCoordChange) {
96 fCoordChangeMatrix = savedCoordChange.fCoordChangeMatrix;
97 GrAssert(savedCoordChange.fCustomStage.get() == fCustomStage);
98 GR_DEBUGCODE(--fSavedCoordChangeCnt);
99 GR_DEBUGCODE(savedCoordChange.fCustomStage.reset(NULL);)
100 }
101
102 /**
103 * Gets the texture matrix. This is will be removed soon and be managed by GrCustomStage.
104 */
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000105 const GrMatrix& getMatrix() const { return fMatrix; }
reed@google.comac10a2d2010-12-22 21:39:39 +0000106
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000107 /**
bsalomon@google.com288d9542012-10-17 12:53:54 +0000108 * Gets the matrix to apply at draw time. This is the original texture matrix combined with
109 * any coord system changes.
bsalomon@google.comc6cf7232011-02-17 16:43:10 +0000110 */
bsalomon@google.com288d9542012-10-17 12:53:54 +0000111 void getTotalMatrix(GrMatrix* matrix) const {
112 *matrix = fMatrix;
113 matrix->preConcat(fCoordChangeMatrix);
114 }
bsalomon@google.com1ce49fc2012-09-18 14:14:49 +0000115
bsalomon@google.comaa814fe2011-12-12 18:45:07 +0000116 void reset() {
bsalomon@google.com1ce49fc2012-09-18 14:14:49 +0000117 GrSafeSetNull(fCustomStage);
bsalomon@google.com1e266f82011-12-12 16:11:33 +0000118 }
bsalomon@google.com97912912011-12-06 16:30:36 +0000119
tomhudson@google.com83e5eb82012-06-04 19:58:30 +0000120 GrCustomStage* setCustomStage(GrCustomStage* stage) {
bsalomon@google.com288d9542012-10-17 12:53:54 +0000121 GrAssert(0 == fSavedCoordChangeCnt);
tomhudson@google.com07eecdc2012-04-20 18:35:38 +0000122 GrSafeAssign(fCustomStage, stage);
bsalomon@google.comdfdb7e52012-10-16 15:19:45 +0000123 fMatrix.reset();
bsalomon@google.com288d9542012-10-17 12:53:54 +0000124 fCoordChangeMatrix.reset();
tomhudson@google.com83e5eb82012-06-04 19:58:30 +0000125 return stage;
tomhudson@google.com07eecdc2012-04-20 18:35:38 +0000126 }
bsalomon@google.comdfdb7e52012-10-16 15:19:45 +0000127
128 GrCustomStage* setCustomStage(GrCustomStage* stage, const GrMatrix& matrix) {
bsalomon@google.com288d9542012-10-17 12:53:54 +0000129 GrAssert(0 == fSavedCoordChangeCnt);
bsalomon@google.comdfdb7e52012-10-16 15:19:45 +0000130 GrSafeAssign(fCustomStage, stage);
131 fMatrix = matrix;
bsalomon@google.com288d9542012-10-17 12:53:54 +0000132 fCoordChangeMatrix.reset();
bsalomon@google.comdfdb7e52012-10-16 15:19:45 +0000133 return stage;
134 }
135
bsalomon@google.comcddaf342012-07-30 13:09:05 +0000136 const GrCustomStage* getCustomStage() const { return fCustomStage; }
tomhudson@google.com07eecdc2012-04-20 18:35:38 +0000137
reed@google.comac10a2d2010-12-22 21:39:39 +0000138private:
bsalomon@google.com288d9542012-10-17 12:53:54 +0000139 GrMatrix fCoordChangeMatrix;
140 GrMatrix fMatrix; // TODO: remove this, store in GrCustomStage
tomhudson@google.com02b1ea22012-04-30 20:19:07 +0000141 GrCustomStage* fCustomStage;
bsalomon@google.com288d9542012-10-17 12:53:54 +0000142
143 GR_DEBUGCODE(mutable int fSavedCoordChangeCnt;)
reed@google.comac10a2d2010-12-22 21:39:39 +0000144};
145
146#endif
147