blob: b4c1a60b477702f4ec30f4767760c5427635aa58 [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"
egdanielc0648242014-09-22 13:17:02 -070011#include "GrDrawTargetCaps.h"
joshualitt4973d9d2014-11-08 09:24:25 -080012#include "GrGpu.h"
egdanielb6cbc382014-11-13 11:00:34 -080013#include "GrProcOptInfo.h"
egdaniel95131432014-12-09 11:15:43 -080014#include "GrXferProcessor.h"
egdaniel3658f382014-09-15 07:01:59 -070015
egdaniel170f90b2014-09-16 12:54:40 -070016GrOptDrawState::GrOptDrawState(const GrDrawState& drawState,
joshualitt8c0f6152014-12-10 14:12:22 -080017 GrColor color,
18 uint8_t coverage,
joshualittdafa4d02014-12-04 08:59:10 -080019 const GrDrawTargetCaps& caps,
joshualitt54e0c122014-11-19 09:38:51 -080020 const ScissorState& scissorState,
joshualitt79f8fae2014-10-28 17:59:26 -070021 const GrDeviceCoordTexture* dstCopy,
joshualittdafa4d02014-12-04 08:59:10 -080022 GrGpu::DrawType drawType)
23 : fFinalized(false) {
joshualitt8c0f6152014-12-10 14:12:22 -080024 GrColor coverageColor = GrColorPackRGBA(coverage, coverage, coverage, coverage);
joshualittdafa4d02014-12-04 08:59:10 -080025 fDrawType = drawType;
egdaniel95131432014-12-09 11:15:43 -080026
joshualitt8c0f6152014-12-10 14:12:22 -080027 const GrProcOptInfo& colorPOI = drawState.colorProcInfo(color);
28 const GrProcOptInfo& coveragePOI = drawState.coverageProcInfo(coverageColor);
egdaniel95131432014-12-09 11:15:43 -080029
30 fColor = colorPOI.inputColorToEffectiveStage();
joshualitt8c0f6152014-12-10 14:12:22 -080031 fCoverage = coverage;
egdaniel95131432014-12-09 11:15:43 -080032
33 // Create XferProcessor from DS's XPFactory
34 SkAutoTUnref<GrXferProcessor> xferProcessor(
35 drawState.getXPFactory()->createXferProcessor(colorPOI, coveragePOI));
36
37 GrXferProcessor::OptFlags optFlags;
38 if (xferProcessor) {
39 fXferProcessor.reset(xferProcessor.get());
40
41 optFlags = xferProcessor->getOptimizations(colorPOI,
42 coveragePOI,
43 drawState.isCoverageDrawing(),
44 drawState.isColorWriteDisabled(),
45 drawState.getStencil().doesWrite(),
46 &fColor,
egdanielc2304142014-12-11 13:15:13 -080047 &fCoverage,
48 caps);
egdaniel95131432014-12-09 11:15:43 -080049 }
bsalomonb03c4a32014-11-20 09:56:11 -080050
51 // When path rendering the stencil settings are not always set on the draw state
52 // so we must check the draw type. In cases where we will skip drawing we simply return a
53 // null GrOptDrawState.
egdaniel95131432014-12-09 11:15:43 -080054 if (!xferProcessor || ((GrXferProcessor::kSkipDraw_OptFlag & optFlags) &&
55 GrGpu::kStencilPath_DrawType != drawType)) {
bsalomonb03c4a32014-11-20 09:56:11 -080056 // Set the fields that don't default init and return. The lack of a render target will
57 // indicate that this can be skipped.
58 fFlags = 0;
bsalomonb03c4a32014-11-20 09:56:11 -080059 fDrawFace = GrDrawState::kInvalid_DrawFace;
bsalomonb03c4a32014-11-20 09:56:11 -080060 fViewMatrix.reset();
61 return;
62 }
63
64 fRenderTarget.reset(drawState.fRenderTarget.get());
65 SkASSERT(fRenderTarget);
joshualitt54e0c122014-11-19 09:38:51 -080066 fScissorState = scissorState;
egdaniel3658f382014-09-15 07:01:59 -070067 fViewMatrix = drawState.getViewMatrix();
egdaniel3658f382014-09-15 07:01:59 -070068 fStencilSettings = drawState.getStencil();
bsalomon04ddf892014-11-19 12:36:22 -080069 fDrawFace = drawState.getDrawFace();
joshualitt9176e2c2014-11-20 07:28:52 -080070 // TODO move this out of optDrawState
71 if (dstCopy) {
72 fDstCopy = *dstCopy;
73 }
74
bsalomon04ddf892014-11-19 12:36:22 -080075 fFlags = 0;
76 if (drawState.isHWAntialias()) {
77 fFlags |= kHWAA_Flag;
78 }
79 if (drawState.isColorWriteDisabled()) {
80 fFlags |= kDisableColorWrite_Flag;
81 }
82 if (drawState.isDither()) {
83 fFlags |= kDither_Flag;
84 }
85
joshualitt8c0f6152014-12-10 14:12:22 -080086 fDescInfo.fHasVertexColor = drawState.hasGeometryProcessor() &&
87 drawState.getGeometryProcessor()->hasVertexColor();
egdaniel3658f382014-09-15 07:01:59 -070088
joshualitt8c0f6152014-12-10 14:12:22 -080089 fDescInfo.fHasVertexCoverage = drawState.hasGeometryProcessor() &&
90 drawState.getGeometryProcessor()->hasVertexCoverage();
joshualitt2dd1ae02014-12-03 06:24:10 -080091
joshualitt8c0f6152014-12-10 14:12:22 -080092 bool hasLocalCoords = drawState.hasGeometryProcessor() &&
93 drawState.getGeometryProcessor()->hasLocalCoords();
egdaniel9cf45bf2014-10-08 06:49:10 -070094
egdaniel912b3d22014-11-17 07:45:53 -080095 int firstColorStageIdx = colorPOI.firstEffectiveStageIndex();
joshualittdafa4d02014-12-04 08:59:10 -080096 fDescInfo.fInputColorIsUsed = colorPOI.inputColorIsUsed();
egdaniel912b3d22014-11-17 07:45:53 -080097 if (colorPOI.removeVertexAttrib()) {
joshualittdafa4d02014-12-04 08:59:10 -080098 fDescInfo.fHasVertexColor = false;
egdaniel912b3d22014-11-17 07:45:53 -080099 }
100
101 // TODO: Once we can handle single or four channel input into coverage stages then we can use
102 // drawState's coverageProcInfo (like color above) to set this initial information.
103 int firstCoverageStageIdx = 0;
joshualittdafa4d02014-12-04 08:59:10 -0800104 fDescInfo.fInputCoverageIsUsed = true;
egdaniel912b3d22014-11-17 07:45:53 -0800105
joshualitt8c0f6152014-12-10 14:12:22 -0800106
egdaniel95131432014-12-09 11:15:43 -0800107 GrXferProcessor::BlendInfo blendInfo;
108 fXferProcessor->getBlendInfo(&blendInfo);
egdaniel95131432014-12-09 11:15:43 -0800109
110 this->adjustProgramFromOptimizations(drawState, optFlags, colorPOI, coveragePOI,
111 &firstColorStageIdx, &firstCoverageStageIdx);
112
113 fDescInfo.fRequiresLocalCoordAttrib = hasLocalCoords;
egdaniel9cf45bf2014-10-08 06:49:10 -0700114
joshualitt8c0f6152014-12-10 14:12:22 -0800115 // Copy GeometryProcesssor from DS or ODS
116 SkASSERT(GrGpu::IsPathRenderingDrawType(drawType) ||
117 GrGpu::kStencilPath_DrawType ||
118 drawState.hasGeometryProcessor());
119 fGeometryProcessor.reset(drawState.getGeometryProcessor());
120
bsalomonae59b772014-11-19 08:23:49 -0800121 // Copy Stages from DS to ODS
bsalomonae59b772014-11-19 08:23:49 -0800122 for (int i = firstColorStageIdx; i < drawState.numColorStages(); ++i) {
123 SkNEW_APPEND_TO_TARRAY(&fFragmentStages,
124 GrPendingFragmentStage,
joshualitt2dd1ae02014-12-03 06:24:10 -0800125 (drawState.fColorStages[i], hasLocalCoords));
bsalomonae59b772014-11-19 08:23:49 -0800126 }
egdaniel95131432014-12-09 11:15:43 -0800127
egdanield9aa2182014-10-09 13:47:05 -0700128 fNumColorStages = fFragmentStages.count();
bsalomonae59b772014-11-19 08:23:49 -0800129 for (int i = firstCoverageStageIdx; i < drawState.numCoverageStages(); ++i) {
130 SkNEW_APPEND_TO_TARRAY(&fFragmentStages,
131 GrPendingFragmentStage,
joshualitt2dd1ae02014-12-03 06:24:10 -0800132 (drawState.fCoverageStages[i], hasLocalCoords));
egdaniel9cf45bf2014-10-08 06:49:10 -0700133 }
joshualitt79f8fae2014-10-28 17:59:26 -0700134
joshualitt87f48d92014-12-04 10:41:40 -0800135 // let the GP init the batch tracker
joshualitt8c0f6152014-12-10 14:12:22 -0800136 if (drawState.hasGeometryProcessor()) {
joshualitt87f48d92014-12-04 10:41:40 -0800137 GrGeometryProcessor::InitBT init;
138 init.fOutputColor = fDescInfo.fInputColorIsUsed;
139 init.fOutputCoverage = fDescInfo.fInputCoverageIsUsed;
140 init.fColor = this->getColor();
141 init.fCoverage = this->getCoverage();
142 fGeometryProcessor->initBatchTracker(&fBatchTracker, init);
143 }
egdanielc0648242014-09-22 13:17:02 -0700144}
145
egdaniel95131432014-12-09 11:15:43 -0800146void GrOptDrawState::adjustProgramFromOptimizations(const GrDrawState& ds,
147 GrXferProcessor::OptFlags flags,
148 const GrProcOptInfo& colorPOI,
149 const GrProcOptInfo& coveragePOI,
150 int* firstColorStageIdx,
151 int* firstCoverageStageIdx) {
joshualittdafa4d02014-12-04 08:59:10 -0800152 fDescInfo.fReadsDst = false;
153 fDescInfo.fReadsFragPosition = false;
egdaniela7dc0a82014-09-17 08:25:05 -0700154
egdaniel95131432014-12-09 11:15:43 -0800155 if (flags & GrXferProcessor::kClearColorStages_OptFlag) {
156 fDescInfo.fInputColorIsUsed = true;
157 *firstColorStageIdx = ds.numColorStages();
158 fDescInfo.fHasVertexColor = false;
159 } else {
160 fDescInfo.fReadsDst = colorPOI.readsDst();
161 fDescInfo.fReadsFragPosition = colorPOI.readsFragPosition();
egdaniela7dc0a82014-09-17 08:25:05 -0700162 }
egdaniel95131432014-12-09 11:15:43 -0800163
164 if (flags & GrXferProcessor::kClearCoverageStages_OptFlag) {
165 fDescInfo.fInputCoverageIsUsed = true;
166 *firstCoverageStageIdx = ds.numCoverageStages();
167 fDescInfo.fHasVertexCoverage = false;
168 } else {
169 if (coveragePOI.readsDst()) {
170 fDescInfo.fReadsDst = true;
171 }
172 if (coveragePOI.readsFragPosition()) {
173 fDescInfo.fReadsFragPosition = true;
174 }
egdaniela7dc0a82014-09-17 08:25:05 -0700175 }
176}
177
joshualittdafa4d02014-12-04 08:59:10 -0800178void GrOptDrawState::finalize(GrGpu* gpu) {
179 gpu->buildProgramDesc(*this, fDescInfo, fDrawType, &fDesc);
180 fFinalized = true;
181}
182
egdaniel89af44a2014-09-26 06:15:04 -0700183////////////////////////////////////////////////////////////////////////////////
184
egdaniel3658f382014-09-15 07:01:59 -0700185bool GrOptDrawState::operator== (const GrOptDrawState& that) const {
joshualittdafa4d02014-12-04 08:59:10 -0800186 if (fDescInfo != that.fDescInfo) {
joshualittf78c60c2014-12-04 06:01:45 -0800187 return false;
188 }
joshualittdafa4d02014-12-04 08:59:10 -0800189
190 if (!fDescInfo.fHasVertexColor && this->fColor != that.fColor) {
egdaniel89af44a2014-09-26 06:15:04 -0700191 return false;
192 }
193
194 if (this->getRenderTarget() != that.getRenderTarget() ||
joshualittdafa4d02014-12-04 08:59:10 -0800195 this->fFragmentStages.count() != that.fFragmentStages.count() ||
196 this->fNumColorStages != that.fNumColorStages ||
joshualitt54e0c122014-11-19 09:38:51 -0800197 this->fScissorState != that.fScissorState ||
egdaniel89af44a2014-09-26 06:15:04 -0700198 !this->fViewMatrix.cheapEqualTo(that.fViewMatrix) ||
joshualittdafa4d02014-12-04 08:59:10 -0800199 this->fDrawType != that.fDrawType ||
bsalomon04ddf892014-11-19 12:36:22 -0800200 this->fFlags != that.fFlags ||
egdaniel89af44a2014-09-26 06:15:04 -0700201 this->fStencilSettings != that.fStencilSettings ||
joshualitt9176e2c2014-11-20 07:28:52 -0800202 this->fDrawFace != that.fDrawFace ||
203 this->fDstCopy.texture() != that.fDstCopy.texture()) {
egdaniel89af44a2014-09-26 06:15:04 -0700204 return false;
205 }
206
joshualittdafa4d02014-12-04 08:59:10 -0800207 if (!fDescInfo.fHasVertexCoverage && this->fCoverage != that.fCoverage) {
egdaniel89af44a2014-09-26 06:15:04 -0700208 return false;
209 }
210
egdaniel89af44a2014-09-26 06:15:04 -0700211 if (this->hasGeometryProcessor()) {
212 if (!that.hasGeometryProcessor()) {
213 return false;
joshualitta5305a12014-10-10 17:47:00 -0700214 } else if (!this->getGeometryProcessor()->isEqual(*that.getGeometryProcessor())) {
egdaniel89af44a2014-09-26 06:15:04 -0700215 return false;
216 }
217 } else if (that.hasGeometryProcessor()) {
218 return false;
219 }
220
egdanielc2304142014-12-11 13:15:13 -0800221 if (!this->getXferProcessor()->isEqual(*that.getXferProcessor())) {
222 return false;
223 }
224
bsalomonae59b772014-11-19 08:23:49 -0800225 // The program desc comparison should have already assured that the stage counts match.
226 SkASSERT(this->numFragmentStages() == that.numFragmentStages());
egdanield9aa2182014-10-09 13:47:05 -0700227 for (int i = 0; i < this->numFragmentStages(); i++) {
bsalomonae59b772014-11-19 08:23:49 -0800228
229 if (this->getFragmentStage(i) != that.getFragmentStage(i)) {
egdaniel89af44a2014-09-26 06:15:04 -0700230 return false;
231 }
232 }
egdaniel89af44a2014-09-26 06:15:04 -0700233 return true;
234}
235