blob: 5f352966b8a3441d5faf603c6234788dc2e23db6 [file] [log] [blame]
egdaniel3658f382014-09-15 07:01:59 -07001/*
2 * Copyright 2014 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#include "GrOptDrawState.h"
9
10#include "GrDrawState.h"
11
egdaniel170f90b2014-09-16 12:54:40 -070012GrOptDrawState::GrOptDrawState(const GrDrawState& drawState,
13 BlendOptFlags blendOptFlags,
14 GrBlendCoeff optSrcCoeff,
15 GrBlendCoeff optDstCoeff) : INHERITED(drawState) {
egdaniel3658f382014-09-15 07:01:59 -070016 fColor = drawState.getColor();
17 fCoverage = drawState.getCoverage();
18 fViewMatrix = drawState.getViewMatrix();
19 fBlendConstant = drawState.getBlendConstant();
20 fFlagBits = drawState.getFlagBits();
21 fVAPtr = drawState.getVertexAttribs();
22 fVACount = drawState.getVertexAttribCount();
23 fVAStride = drawState.getVertexStride();
24 fStencilSettings = drawState.getStencil();
25 fDrawFace = drawState.getDrawFace();
egdaniel170f90b2014-09-16 12:54:40 -070026 fBlendOptFlags = blendOptFlags;
27 fSrcBlend = optSrcCoeff;
28 fDstBlend = optDstCoeff;
egdaniel3658f382014-09-15 07:01:59 -070029
30 memcpy(fFixedFunctionVertexAttribIndices,
31 drawState.getFixedFunctionVertexAttribIndices(),
32 sizeof(fFixedFunctionVertexAttribIndices));
33
egdaniel170f90b2014-09-16 12:54:40 -070034
egdaniel3658f382014-09-15 07:01:59 -070035 fInputColorIsUsed = true;
36 fInputCoverageIsUsed = true;
37
38 if (drawState.hasGeometryProcessor()) {
39 fGeometryProcessor.reset(SkNEW_ARGS(GrEffectStage, (*drawState.getGeometryProcessor())));
40 } else {
41 fGeometryProcessor.reset(NULL);
42 }
43
44 this->copyEffectiveColorStages(drawState);
45 this->copyEffectiveCoverageStages(drawState);
egdaniel170f90b2014-09-16 12:54:40 -070046 this->adjustFromBlendOpts();
egdaniel3658f382014-09-15 07:01:59 -070047};
48
egdaniel170f90b2014-09-16 12:54:40 -070049void GrOptDrawState::adjustFromBlendOpts() {
50
51 switch (fBlendOptFlags) {
52 case kNone_BlendOpt:
53 case kSkipDraw_BlendOptFlag:
54 break;
55 case kCoverageAsAlpha_BlendOptFlag:
56 fFlagBits |= kCoverageDrawing_StateBit;
57 break;
58 case kEmitCoverage_BlendOptFlag:
59 fColor = 0xffffffff;
60 fInputColorIsUsed = true;
61 fColorStages.reset();
62 this->removeFixedFunctionVertexAttribs(0x1 << kColor_GrVertexAttribBinding);
63 break;
64 case kEmitTransBlack_BlendOptFlag:
65 fColor = 0;
66 fCoverage = 0xff;
67 fInputColorIsUsed = true;
68 fInputCoverageIsUsed = true;
69 fColorStages.reset();
70 fCoverageStages.reset();
71 this->removeFixedFunctionVertexAttribs(0x1 << kColor_GrVertexAttribBinding |
72 0x1 << kCoverage_GrVertexAttribBinding);
73 break;
74 default:
75 SkFAIL("Unknown BlendOptFlag");
76
77 }
78}
79
egdaniel3658f382014-09-15 07:01:59 -070080void GrOptDrawState::removeFixedFunctionVertexAttribs(uint8_t removeVAFlag) {
81 int numToRemove = 0;
82 uint8_t maskCheck = 0x1;
83 // Count the number of vertex attributes that we will actually remove
84 for (int i = 0; i < kGrFixedFunctionVertexAttribBindingCnt; ++i) {
85 if ((maskCheck & removeVAFlag) && -1 != fFixedFunctionVertexAttribIndices[i]) {
86 ++numToRemove;
87 }
88 maskCheck <<= 1;
89 }
egdaniel170f90b2014-09-16 12:54:40 -070090
egdaniel3658f382014-09-15 07:01:59 -070091 fOptVA.reset(fVACount - numToRemove);
92
93 GrVertexAttrib* dst = fOptVA.get();
94 const GrVertexAttrib* src = fVAPtr;
95
96 for (int i = 0, newIdx = 0; i < fVACount; ++i, ++src) {
97 const GrVertexAttrib& currAttrib = *src;
98 if (currAttrib.fBinding < kGrFixedFunctionVertexAttribBindingCnt) {
99 uint8_t maskCheck = 0x1 << currAttrib.fBinding;
100 if (maskCheck & removeVAFlag) {
101 SkASSERT(-1 != fFixedFunctionVertexAttribIndices[currAttrib.fBinding]);
102 fFixedFunctionVertexAttribIndices[currAttrib.fBinding] = -1;
103 continue;
104 }
egdaniel170f90b2014-09-16 12:54:40 -0700105 fFixedFunctionVertexAttribIndices[currAttrib.fBinding] = newIdx;
egdaniel3658f382014-09-15 07:01:59 -0700106 }
107 memcpy(dst, src, sizeof(GrVertexAttrib));
egdaniel3658f382014-09-15 07:01:59 -0700108 ++newIdx;
109 ++dst;
110 }
111 fVACount -= numToRemove;
112 fVAPtr = fOptVA.get();
113}
114
115void GrOptDrawState::copyEffectiveColorStages(const GrDrawState& ds) {
116 int firstColorStage = 0;
117
118 // Set up color and flags for ConstantColorComponent checks
119 GrColor color;
120 uint32_t validComponentFlags;
121 if (!this->hasColorVertexAttribute()) {
122 color = ds.getColor();
123 validComponentFlags = kRGBA_GrColorComponentFlags;
124 } else {
125 if (ds.vertexColorsAreOpaque()) {
126 color = 0xFF << GrColor_SHIFT_A;
127 validComponentFlags = kA_GrColorComponentFlag;
128 } else {
129 validComponentFlags = 0;
130 color = 0; // not strictly necessary but we get false alarms from tools about uninit.
131 }
132 }
133
134 for (int i = 0; i < ds.numColorStages(); ++i) {
135 const GrEffect* effect = ds.getColorStage(i).getEffect();
136 if (!effect->willUseInputColor()) {
137 firstColorStage = i;
138 fInputColorIsUsed = false;
139 }
140 effect->getConstantColorComponents(&color, &validComponentFlags);
141 if (kRGBA_GrColorComponentFlags == validComponentFlags) {
142 firstColorStage = i + 1;
143 fColor = color;
144 fInputColorIsUsed = true;
145 this->removeFixedFunctionVertexAttribs(0x1 << kColor_GrVertexAttribBinding);
146 }
147 }
148 if (firstColorStage < ds.numColorStages()) {
149 fColorStages.reset(&ds.getColorStage(firstColorStage),
150 ds.numColorStages() - firstColorStage);
151 } else {
152 fColorStages.reset();
153 }
154}
155
156void GrOptDrawState::copyEffectiveCoverageStages(const GrDrawState& ds) {
157 int firstCoverageStage = 0;
158
159 // We do not try to optimize out constantColor coverage effects here. It is extremely rare
160 // to have a coverage effect that returns a constant value for all four channels. Thus we
161 // save having to make extra virtual calls by not checking for it.
162
163 // Don't do any optimizations on coverage stages. It should not be the case where we do not use
164 // input coverage in an effect
165#ifdef OptCoverageStages
166 for (int i = 0; i < ds.numCoverageStages(); ++i) {
167 const GrEffect* effect = ds.getCoverageStage(i).getEffect();
168 if (!effect->willUseInputColor()) {
169 firstCoverageStage = i;
170 fInputCoverageIsUsed = false;
171 }
172 }
173#endif
174 if (ds.numCoverageStages() > 0) {
175 fCoverageStages.reset(&ds.getCoverageStage(firstCoverageStage),
176 ds.numCoverageStages() - firstCoverageStage);
177 } else {
178 fCoverageStages.reset();
179 }
180}
181
182bool GrOptDrawState::operator== (const GrOptDrawState& that) const {
183 return this->isEqual(that);
184}
185