blob: 94e200454607fd34dd158105dae1e941ba2d7210 [file] [log] [blame]
Brian Salomon92ce5942017-01-18 11:01:10 -05001/*
2 * Copyright 2017 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 "GrProcessorSet.h"
Brian Salomon5298dc82017-02-22 11:52:03 -05009#include "GrAppliedClip.h"
10#include "GrCaps.h"
11#include "GrProcOptInfo.h"
Brian Salomon92ce5942017-01-18 11:01:10 -050012
13GrProcessorSet::GrProcessorSet(GrPaint&& paint) {
14 fXPFactory = paint.fXPFactory;
Brian Salomonf87e2b92017-01-19 11:31:50 -050015 fFlags = 0;
Brian Salomon8d2f90b2017-03-13 09:11:58 -040016 if (paint.numColorFragmentProcessors() <= kMaxColorProcessors) {
17 fColorFragmentProcessorCnt = paint.numColorFragmentProcessors();
18 fFragmentProcessors.reset(paint.numTotalFragmentProcessors());
19 int i = 0;
20 for (auto& fp : paint.fColorFragmentProcessors) {
21 fFragmentProcessors[i++] = fp.release();
22 }
23 for (auto& fp : paint.fCoverageFragmentProcessors) {
24 fFragmentProcessors[i++] = fp.release();
25 }
26 if (paint.usesDistanceVectorField()) {
27 fFlags |= kUseDistanceVectorField_Flag;
28 }
29 } else {
30 SkDebugf("Insane number of color fragment processors in paint. Dropping all processors.");
31 fColorFragmentProcessorCnt = 0;
Brian Salomonf87e2b92017-01-19 11:31:50 -050032 }
33 if (paint.getDisableOutputConversionToSRGB()) {
34 fFlags |= kDisableOutputConversionToSRGB_Flag;
35 }
36 if (paint.getAllowSRGBInputs()) {
37 fFlags |= kAllowSRGBInputs_Flag;
38 }
Brian Salomon92ce5942017-01-18 11:01:10 -050039}
Brian Salomon5298dc82017-02-22 11:52:03 -050040
Brian Salomon54d212e2017-03-21 14:22:38 -040041GrProcessorSet::~GrProcessorSet() {
42 if (this->isPendingExecution()) {
43 for (auto fp : fFragmentProcessors) {
44 fp->completedExecution();
45 }
46 } else {
47 for (auto fp : fFragmentProcessors) {
48 fp->unref();
49 }
50 }
51}
52
53void GrProcessorSet::makePendingExecution() {
54 SkASSERT(!(kPendingExecution_Flag & fFlags));
55 fFlags |= kPendingExecution_Flag;
56 for (int i = 0; i < fFragmentProcessors.count(); ++i) {
57 fFragmentProcessors[i]->addPendingExecution();
58 fFragmentProcessors[i]->unref();
59 }
60}
61
62bool GrProcessorSet::operator==(const GrProcessorSet& that) const {
63 if (((fFlags ^ that.fFlags) & ~kPendingExecution_Flag) ||
64 fFragmentProcessors.count() != that.fFragmentProcessors.count() ||
65 fColorFragmentProcessorCnt != that.fColorFragmentProcessorCnt) {
66 return false;
67 }
68 for (int i = 0; i < fFragmentProcessors.count(); ++i) {
69 if (!fFragmentProcessors[i]->isEqual(*that.fFragmentProcessors[i])) {
70 return false;
71 }
72 }
73 if (fXPFactory != that.fXPFactory) {
74 return false;
75 }
76 return true;
77}
78
Brian Salomon5298dc82017-02-22 11:52:03 -050079//////////////////////////////////////////////////////////////////////////////
80
Brian Salomon8d2f90b2017-03-13 09:11:58 -040081void GrProcessorSet::FragmentProcessorAnalysis::internalInit(const GrPipelineInput& colorInput,
82 const GrPipelineInput coverageInput,
83 const GrProcessorSet& processors,
84 const GrFragmentProcessor* clipFP,
85 const GrCaps& caps) {
Brian Salomon5298dc82017-02-22 11:52:03 -050086 GrProcOptInfo colorInfo(colorInput);
Brian Salomon5298dc82017-02-22 11:52:03 -050087 fCompatibleWithCoverageAsAlpha = !coverageInput.isLCDCoverage();
Brian Salomon8d2f90b2017-03-13 09:11:58 -040088 fValidInputColor = colorInput.isConstant(&fInputColor);
Brian Salomon5298dc82017-02-22 11:52:03 -050089
90 const GrFragmentProcessor* const* fps = processors.fFragmentProcessors.get();
91 colorInfo.analyzeProcessors(fps, processors.fColorFragmentProcessorCnt);
92 fCompatibleWithCoverageAsAlpha &= colorInfo.allProcessorsCompatibleWithCoverageAsAlpha();
93 fps += processors.fColorFragmentProcessorCnt;
94 int n = processors.numCoverageFragmentProcessors();
95 bool hasCoverageFP = n > 0;
Brian Salomonbfafcba2017-03-02 08:49:19 -050096 fUsesLocalCoords = colorInfo.usesLocalCoords();
97 for (int i = 0; i < n; ++i) {
Brian Salomon5298dc82017-02-22 11:52:03 -050098 if (!fps[i]->compatibleWithCoverageAsAlpha()) {
99 fCompatibleWithCoverageAsAlpha = false;
100 // Other than tests that exercise atypical behavior we expect all coverage FPs to be
101 // compatible with the coverage-as-alpha optimization.
102 GrCapsDebugf(&caps, "Coverage FP is not compatible with coverage as alpha.\n");
Brian Salomon5298dc82017-02-22 11:52:03 -0500103 }
Brian Salomonbfafcba2017-03-02 08:49:19 -0500104 fUsesLocalCoords |= fps[i]->usesLocalCoords();
Brian Salomon5298dc82017-02-22 11:52:03 -0500105 }
106
107 if (clipFP) {
108 fCompatibleWithCoverageAsAlpha &= clipFP->compatibleWithCoverageAsAlpha();
Brian Salomonbfafcba2017-03-02 08:49:19 -0500109 fUsesLocalCoords |= clipFP->usesLocalCoords();
Brian Salomon5298dc82017-02-22 11:52:03 -0500110 hasCoverageFP = true;
111 }
Brian Salomon8d2f90b2017-03-13 09:11:58 -0400112 fInitialColorProcessorsToEliminate = colorInfo.initialProcessorsToEliminate(&fInputColor);
113 fValidInputColor |= SkToBool(fInitialColorProcessorsToEliminate);
Brian Salomon5298dc82017-02-22 11:52:03 -0500114
115 bool opaque = colorInfo.isOpaque();
116 if (colorInfo.hasKnownOutputColor(&fKnownOutputColor)) {
Brian Salomon8d2f90b2017-03-13 09:11:58 -0400117 fOutputColorType = static_cast<unsigned>(opaque ? ColorType::kOpaqueConstant
118 : ColorType::kConstant);
Brian Salomon5298dc82017-02-22 11:52:03 -0500119 } else if (opaque) {
Brian Salomon8d2f90b2017-03-13 09:11:58 -0400120 fOutputColorType = static_cast<unsigned>(ColorType::kOpaque);
Brian Salomon5298dc82017-02-22 11:52:03 -0500121 } else {
Brian Salomon8d2f90b2017-03-13 09:11:58 -0400122 fOutputColorType = static_cast<unsigned>(ColorType::kUnknown);
Brian Salomon5298dc82017-02-22 11:52:03 -0500123 }
124
125 if (coverageInput.isLCDCoverage()) {
Brian Salomon8d2f90b2017-03-13 09:11:58 -0400126 fOutputCoverageType = static_cast<unsigned>(CoverageType::kLCD);
Brian Salomon5298dc82017-02-22 11:52:03 -0500127 } else {
Brian Salomon8d2f90b2017-03-13 09:11:58 -0400128 fOutputCoverageType = hasCoverageFP || !coverageInput.isSolidWhite()
129 ? static_cast<unsigned>(CoverageType::kSingleChannel)
130 : static_cast<unsigned>(CoverageType::kNone);
Brian Salomon5298dc82017-02-22 11:52:03 -0500131 }
132}
133
Brian Salomon8d2f90b2017-03-13 09:11:58 -0400134void GrProcessorSet::FragmentProcessorAnalysis::init(const GrPipelineInput& colorInput,
135 const GrPipelineInput coverageInput,
136 const GrProcessorSet& processors,
137 const GrAppliedClip* appliedClip,
138 const GrCaps& caps) {
139 const GrFragmentProcessor* clipFP =
140 appliedClip ? appliedClip->clipCoverageFragmentProcessor() : nullptr;
141 this->internalInit(colorInput, coverageInput, processors, clipFP, caps);
142 fIsInitializedWithProcessorSet = true;
Brian Salomon5298dc82017-02-22 11:52:03 -0500143}
144
145GrProcessorSet::FragmentProcessorAnalysis::FragmentProcessorAnalysis(
146 const GrPipelineInput& colorInput, const GrPipelineInput coverageInput, const GrCaps& caps)
147 : FragmentProcessorAnalysis() {
Brian Salomon8d2f90b2017-03-13 09:11:58 -0400148 this->internalInit(colorInput, coverageInput, GrProcessorSet(GrPaint()), nullptr, caps);
Brian Salomon5298dc82017-02-22 11:52:03 -0500149}