1 /*
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 "GrProcOptInfo.h"
9 
10 #include "GrBatch.h"
11 #include "GrFragmentProcessor.h"
12 #include "GrFragmentStage.h"
13 #include "GrGeometryProcessor.h"
14 
calcColorWithBatch(const GrBatch * batch,const GrFragmentStage * stages,int stageCount)15 void GrProcOptInfo::calcColorWithBatch(const GrBatch* batch,
16                                        const GrFragmentStage* stages,
17                                        int stageCount) {
18     GrInitInvariantOutput out;
19     batch->getInvariantOutputColor(&out);
20     fInOut.reset(out);
21     this->internalCalc(stages, stageCount, batch->willReadFragmentPosition());
22 }
23 
calcCoverageWithBatch(const GrBatch * batch,const GrFragmentStage * stages,int stageCount)24 void GrProcOptInfo::calcCoverageWithBatch(const GrBatch* batch,
25                                           const GrFragmentStage* stages,
26                                           int stageCount) {
27     GrInitInvariantOutput out;
28     batch->getInvariantOutputCoverage(&out);
29     fInOut.reset(out);
30     this->internalCalc(stages, stageCount, batch->willReadFragmentPosition());
31 }
32 
calcColorWithPrimProc(const GrPrimitiveProcessor * primProc,const GrFragmentStage * stages,int stageCount)33 void GrProcOptInfo::calcColorWithPrimProc(const GrPrimitiveProcessor* primProc,
34                                           const GrFragmentStage* stages,
35                                           int stageCount) {
36     GrInitInvariantOutput out;
37     primProc->getInvariantOutputColor(&out);
38     fInOut.reset(out);
39     this->internalCalc(stages, stageCount, primProc->willReadFragmentPosition());
40 }
41 
calcCoverageWithPrimProc(const GrPrimitiveProcessor * primProc,const GrFragmentStage * stages,int stageCount)42 void GrProcOptInfo::calcCoverageWithPrimProc(const GrPrimitiveProcessor* primProc,
43                                              const GrFragmentStage* stages,
44                                              int stageCount) {
45     GrInitInvariantOutput out;
46     primProc->getInvariantOutputCoverage(&out);
47     fInOut.reset(out);
48     this->internalCalc(stages, stageCount, primProc->willReadFragmentPosition());
49 }
50 
calcWithInitialValues(const GrFragmentStage * stages,int stageCount,GrColor startColor,GrColorComponentFlags flags,bool areCoverageStages)51 void GrProcOptInfo::calcWithInitialValues(const GrFragmentStage* stages,
52                                           int stageCount,
53                                           GrColor startColor,
54                                           GrColorComponentFlags flags,
55                                           bool areCoverageStages) {
56     GrInitInvariantOutput out;
57     out.fIsSingleComponent = areCoverageStages;
58     out.fColor = startColor;
59     out.fValidFlags = flags;
60     fInOut.reset(out);
61     this->internalCalc(stages, stageCount, false);
62 }
63 
internalCalc(const GrFragmentStage * stages,int stageCount,bool initWillReadFragmentPosition)64 void GrProcOptInfo::internalCalc(const GrFragmentStage* stages,
65                                  int stageCount,
66                                  bool initWillReadFragmentPosition) {
67     fFirstEffectStageIndex = 0;
68     fInputColorIsUsed = true;
69     fInputColor = fInOut.color();
70     fReadsFragPosition = initWillReadFragmentPosition;
71 
72     for (int i = 0; i < stageCount; ++i) {
73         const GrFragmentProcessor* processor = stages[i].processor();
74         fInOut.resetWillUseInputColor();
75         processor->computeInvariantOutput(&fInOut);
76         SkDEBUGCODE(fInOut.validate());
77         if (!fInOut.willUseInputColor()) {
78             fFirstEffectStageIndex = i;
79             fInputColorIsUsed = false;
80             // Reset these since we don't care if previous stages read these values
81             fReadsFragPosition = initWillReadFragmentPosition;
82         }
83         if (processor->willReadFragmentPosition()) {
84             fReadsFragPosition = true;
85         }
86         if (kRGBA_GrColorComponentFlags == fInOut.validFlags()) {
87             fFirstEffectStageIndex = i + 1;
88             fInputColor = fInOut.color();
89             fInputColorIsUsed = true;
90             // Since we are clearing all previous color stages we are in a state where we have found
91             // zero stages that don't multiply the inputColor.
92             fInOut.resetNonMulStageFound();
93             // Reset these since we don't care if previous stages read these values
94             fReadsFragPosition = initWillReadFragmentPosition;
95         }
96     }
97 }
98