blob: 8d28f446b27912d2d6e6687ef54485a73a93e326 [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,
joshualitt71c92602015-01-14 08:12:47 -080017 const GrPrimitiveProcessor* primProc,
joshualittdafa4d02014-12-04 08:59:10 -080018 const GrDrawTargetCaps& caps,
bsalomon3e791242014-12-17 13:43:13 -080019 const GrScissorState& scissorState,
joshualitt79f8fae2014-10-28 17:59:26 -070020 const GrDeviceCoordTexture* dstCopy,
joshualitt873ad0e2015-01-20 09:08:51 -080021 GrGpu::DrawType drawType) {
joshualittdafa4d02014-12-04 08:59:10 -080022 fDrawType = drawType;
egdaniel95131432014-12-09 11:15:43 -080023
joshualitt873ad0e2015-01-20 09:08:51 -080024 const GrProcOptInfo& colorPOI = drawState.colorProcInfo(primProc);
25 const GrProcOptInfo& coveragePOI = drawState.coverageProcInfo(primProc);
egdaniel95131432014-12-09 11:15:43 -080026
27 // Create XferProcessor from DS's XPFactory
28 SkAutoTUnref<GrXferProcessor> xferProcessor(
29 drawState.getXPFactory()->createXferProcessor(colorPOI, coveragePOI));
30
joshualitt9b989322014-12-15 14:16:27 -080031 GrColor overrideColor = GrColor_ILLEGAL;
32 if (colorPOI.firstEffectiveStageIndex() != 0) {
33 overrideColor = colorPOI.inputColorToEffectiveStage();
34 }
35
egdaniel95131432014-12-09 11:15:43 -080036 GrXferProcessor::OptFlags optFlags;
37 if (xferProcessor) {
38 fXferProcessor.reset(xferProcessor.get());
39
40 optFlags = xferProcessor->getOptimizations(colorPOI,
41 coveragePOI,
egdaniel95131432014-12-09 11:15:43 -080042 drawState.getStencil().doesWrite(),
joshualitt9b989322014-12-15 14:16:27 -080043 &overrideColor,
egdanielc2304142014-12-11 13:15:13 -080044 caps);
egdaniel95131432014-12-09 11:15:43 -080045 }
bsalomonb03c4a32014-11-20 09:56:11 -080046
47 // When path rendering the stencil settings are not always set on the draw state
48 // so we must check the draw type. In cases where we will skip drawing we simply return a
49 // null GrOptDrawState.
bsalomon3e791242014-12-17 13:43:13 -080050 if (!xferProcessor || (GrXferProcessor::kSkipDraw_OptFlag & optFlags)) {
bsalomonb03c4a32014-11-20 09:56:11 -080051 // Set the fields that don't default init and return. The lack of a render target will
52 // indicate that this can be skipped.
53 fFlags = 0;
bsalomonb03c4a32014-11-20 09:56:11 -080054 fDrawFace = GrDrawState::kInvalid_DrawFace;
bsalomonb03c4a32014-11-20 09:56:11 -080055 return;
56 }
57
58 fRenderTarget.reset(drawState.fRenderTarget.get());
59 SkASSERT(fRenderTarget);
joshualitt54e0c122014-11-19 09:38:51 -080060 fScissorState = scissorState;
egdaniel3658f382014-09-15 07:01:59 -070061 fStencilSettings = drawState.getStencil();
bsalomon04ddf892014-11-19 12:36:22 -080062 fDrawFace = drawState.getDrawFace();
joshualitt9176e2c2014-11-20 07:28:52 -080063 // TODO move this out of optDrawState
64 if (dstCopy) {
65 fDstCopy = *dstCopy;
66 }
67
bsalomon04ddf892014-11-19 12:36:22 -080068 fFlags = 0;
69 if (drawState.isHWAntialias()) {
70 fFlags |= kHWAA_Flag;
71 }
bsalomon04ddf892014-11-19 12:36:22 -080072 if (drawState.isDither()) {
73 fFlags |= kDither_Flag;
74 }
75
egdaniel912b3d22014-11-17 07:45:53 -080076 int firstColorStageIdx = colorPOI.firstEffectiveStageIndex();
egdaniel912b3d22014-11-17 07:45:53 -080077
78 // TODO: Once we can handle single or four channel input into coverage stages then we can use
79 // drawState's coverageProcInfo (like color above) to set this initial information.
80 int firstCoverageStageIdx = 0;
egdaniel912b3d22014-11-17 07:45:53 -080081
egdaniel95131432014-12-09 11:15:43 -080082 GrXferProcessor::BlendInfo blendInfo;
83 fXferProcessor->getBlendInfo(&blendInfo);
egdaniel95131432014-12-09 11:15:43 -080084
85 this->adjustProgramFromOptimizations(drawState, optFlags, colorPOI, coveragePOI,
86 &firstColorStageIdx, &firstCoverageStageIdx);
87
egdaniel71e236c2015-01-20 06:34:51 -080088 fDescInfo.fReadsDst = fXferProcessor->willReadDstColor();
89
joshualitt290c09b2014-12-19 13:45:20 -080090 bool usesLocalCoords = false;
91
bsalomonae59b772014-11-19 08:23:49 -080092 // Copy Stages from DS to ODS
bsalomonae59b772014-11-19 08:23:49 -080093 for (int i = firstColorStageIdx; i < drawState.numColorStages(); ++i) {
94 SkNEW_APPEND_TO_TARRAY(&fFragmentStages,
95 GrPendingFragmentStage,
joshualitt40d4bd82014-12-29 09:04:40 -080096 (drawState.fColorStages[i]));
joshualitt290c09b2014-12-19 13:45:20 -080097 usesLocalCoords = usesLocalCoords ||
joshualitt40d4bd82014-12-29 09:04:40 -080098 drawState.fColorStages[i].processor()->usesLocalCoords();
bsalomonae59b772014-11-19 08:23:49 -080099 }
egdaniel95131432014-12-09 11:15:43 -0800100
egdanield9aa2182014-10-09 13:47:05 -0700101 fNumColorStages = fFragmentStages.count();
bsalomonae59b772014-11-19 08:23:49 -0800102 for (int i = firstCoverageStageIdx; i < drawState.numCoverageStages(); ++i) {
103 SkNEW_APPEND_TO_TARRAY(&fFragmentStages,
104 GrPendingFragmentStage,
joshualitt40d4bd82014-12-29 09:04:40 -0800105 (drawState.fCoverageStages[i]));
joshualitt290c09b2014-12-19 13:45:20 -0800106 usesLocalCoords = usesLocalCoords ||
joshualitt40d4bd82014-12-29 09:04:40 -0800107 drawState.fCoverageStages[i].processor()->usesLocalCoords();
egdaniel9cf45bf2014-10-08 06:49:10 -0700108 }
joshualitt79f8fae2014-10-28 17:59:26 -0700109
joshualitt87f48d92014-12-04 10:41:40 -0800110 // let the GP init the batch tracker
joshualitt873ad0e2015-01-20 09:08:51 -0800111 fInitBT.fColorIgnored = SkToBool(optFlags & GrXferProcessor::kIgnoreColor_OptFlag);
112 fInitBT.fOverrideColor = fInitBT.fColorIgnored ? GrColor_ILLEGAL : overrideColor;
113 fInitBT.fCoverageIgnored = SkToBool(optFlags & GrXferProcessor::kIgnoreCoverage_OptFlag);
114 fInitBT.fUsesLocalCoords = usesLocalCoords;
egdanielc0648242014-09-22 13:17:02 -0700115}
116
egdaniel95131432014-12-09 11:15:43 -0800117void GrOptDrawState::adjustProgramFromOptimizations(const GrDrawState& ds,
118 GrXferProcessor::OptFlags flags,
119 const GrProcOptInfo& colorPOI,
120 const GrProcOptInfo& coveragePOI,
121 int* firstColorStageIdx,
122 int* firstCoverageStageIdx) {
joshualittdafa4d02014-12-04 08:59:10 -0800123 fDescInfo.fReadsFragPosition = false;
egdaniela7dc0a82014-09-17 08:25:05 -0700124
joshualitt9b989322014-12-15 14:16:27 -0800125 if ((flags & GrXferProcessor::kIgnoreColor_OptFlag) ||
126 (flags & GrXferProcessor::kOverrideColor_OptFlag)) {
egdaniel95131432014-12-09 11:15:43 -0800127 *firstColorStageIdx = ds.numColorStages();
egdaniel95131432014-12-09 11:15:43 -0800128 } else {
egdaniel95131432014-12-09 11:15:43 -0800129 fDescInfo.fReadsFragPosition = colorPOI.readsFragPosition();
egdaniela7dc0a82014-09-17 08:25:05 -0700130 }
egdaniel95131432014-12-09 11:15:43 -0800131
joshualitt9b989322014-12-15 14:16:27 -0800132 if (flags & GrXferProcessor::kIgnoreCoverage_OptFlag) {
egdaniel95131432014-12-09 11:15:43 -0800133 *firstCoverageStageIdx = ds.numCoverageStages();
egdaniel95131432014-12-09 11:15:43 -0800134 } else {
egdaniel95131432014-12-09 11:15:43 -0800135 if (coveragePOI.readsFragPosition()) {
136 fDescInfo.fReadsFragPosition = true;
137 }
egdaniela7dc0a82014-09-17 08:25:05 -0700138 }
139}
140
egdaniel89af44a2014-09-26 06:15:04 -0700141////////////////////////////////////////////////////////////////////////////////
142
joshualitt873ad0e2015-01-20 09:08:51 -0800143bool GrOptDrawState::isEqual(const GrOptDrawState& that) const {
egdaniel89af44a2014-09-26 06:15:04 -0700144 if (this->getRenderTarget() != that.getRenderTarget() ||
joshualittdafa4d02014-12-04 08:59:10 -0800145 this->fFragmentStages.count() != that.fFragmentStages.count() ||
146 this->fNumColorStages != that.fNumColorStages ||
joshualitt54e0c122014-11-19 09:38:51 -0800147 this->fScissorState != that.fScissorState ||
joshualittdafa4d02014-12-04 08:59:10 -0800148 this->fDrawType != that.fDrawType ||
bsalomon04ddf892014-11-19 12:36:22 -0800149 this->fFlags != that.fFlags ||
egdaniel89af44a2014-09-26 06:15:04 -0700150 this->fStencilSettings != that.fStencilSettings ||
joshualitt9176e2c2014-11-20 07:28:52 -0800151 this->fDrawFace != that.fDrawFace ||
152 this->fDstCopy.texture() != that.fDstCopy.texture()) {
egdaniel89af44a2014-09-26 06:15:04 -0700153 return false;
154 }
155
egdanielc2304142014-12-11 13:15:13 -0800156 if (!this->getXferProcessor()->isEqual(*that.getXferProcessor())) {
157 return false;
158 }
159
bsalomonae59b772014-11-19 08:23:49 -0800160 // The program desc comparison should have already assured that the stage counts match.
161 SkASSERT(this->numFragmentStages() == that.numFragmentStages());
egdanield9aa2182014-10-09 13:47:05 -0700162 for (int i = 0; i < this->numFragmentStages(); i++) {
bsalomonae59b772014-11-19 08:23:49 -0800163
164 if (this->getFragmentStage(i) != that.getFragmentStage(i)) {
egdaniel89af44a2014-09-26 06:15:04 -0700165 return false;
166 }
167 }
egdaniel89af44a2014-09-26 06:15:04 -0700168 return true;
169}
170