blob: 5b5bc8e7f4824ecf356aa621b76d288df1dc7ab4 [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#ifndef GrProcessorSet_DEFINED
9#define GrProcessorSet_DEFINED
10
Mike Kleinc0bd9f92019-04-23 12:05:21 -050011#include "include/private/SkTemplates.h"
12#include "src/gpu/GrFragmentProcessor.h"
13#include "src/gpu/GrPaint.h"
14#include "src/gpu/GrProcessorAnalysis.h"
15#include "src/gpu/GrXferProcessor.h"
Brian Salomon92ce5942017-01-18 11:01:10 -050016
Chris Daltonb8fff0d2019-03-05 10:11:58 -070017struct GrUserStencilSettings;
Brian Salomon5298dc82017-02-22 11:52:03 -050018class GrAppliedClip;
Brian Salomon92ce5942017-01-18 11:01:10 -050019class GrXPFactory;
20
Brian Salomon91326c32017-08-09 16:02:19 -040021class GrProcessorSet {
Brian Salomon6d4b65e2017-05-03 17:06:09 -040022private:
23 // Arbitrary constructor arg for empty set and analysis
24 enum class Empty { kEmpty };
25
Brian Salomon92ce5942017-01-18 11:01:10 -050026public:
Brian Salomon91326c32017-08-09 16:02:19 -040027 GrProcessorSet(GrPaint&&);
28 GrProcessorSet(SkBlendMode);
Brian Salomonaff329b2017-08-11 09:40:37 -040029 GrProcessorSet(std::unique_ptr<GrFragmentProcessor> colorFP);
Brian Salomon91326c32017-08-09 16:02:19 -040030 GrProcessorSet(GrProcessorSet&&);
31 GrProcessorSet(const GrProcessorSet&) = delete;
32 GrProcessorSet& operator=(const GrProcessorSet&) = delete;
Brian Salomon92ce5942017-01-18 11:01:10 -050033
Brian Salomon54d212e2017-03-21 14:22:38 -040034 ~GrProcessorSet();
35
John Stiles29d3e222020-07-21 17:28:12 -040036 bool hasColorFragmentProcessor() const { return fColorFragmentProcessor != nullptr; }
37 bool hasCoverageFragmentProcessor() const { return fCoverageFragmentProcessor != nullptr; }
Brian Salomon92ce5942017-01-18 11:01:10 -050038
John Stiles29d3e222020-07-21 17:28:12 -040039 const GrFragmentProcessor* colorFragmentProcessor() const {
40 return fColorFragmentProcessor.get();
Brian Salomon92ce5942017-01-18 11:01:10 -050041 }
John Stiles29d3e222020-07-21 17:28:12 -040042 const GrFragmentProcessor* coverageFragmentProcessor() const {
43 return fCoverageFragmentProcessor.get();
Brian Salomon92ce5942017-01-18 11:01:10 -050044 }
45
Chris Dalton22241002021-02-04 09:47:40 -070046 bool usesVaryingCoords() const {
47 return (fColorFragmentProcessor && fColorFragmentProcessor->usesVaryingCoords()) ||
48 (fCoverageFragmentProcessor && fCoverageFragmentProcessor->usesVaryingCoords());
49 }
50
Brian Salomon48d1b4c2017-04-08 07:38:53 -040051 const GrXferProcessor* xferProcessor() const {
52 SkASSERT(this->isFinalized());
53 return fXP.fProcessor;
54 }
Brian Salomond61c9d92017-04-10 10:54:25 -040055 sk_sp<const GrXferProcessor> refXferProcessor() const {
56 SkASSERT(this->isFinalized());
57 return sk_ref_sp(fXP.fProcessor);
58 }
Brian Salomon92ce5942017-01-18 11:01:10 -050059
John Stilesd3feb6f2020-07-23 18:18:12 -040060 std::unique_ptr<GrFragmentProcessor> detachColorFragmentProcessor() {
John Stiles29d3e222020-07-21 17:28:12 -040061 return std::move(fColorFragmentProcessor);
Brian Salomonaff329b2017-08-11 09:40:37 -040062 }
63
John Stilesd3feb6f2020-07-23 18:18:12 -040064 std::unique_ptr<GrFragmentProcessor> detachCoverageFragmentProcessor() {
John Stiles29d3e222020-07-21 17:28:12 -040065 return std::move(fCoverageFragmentProcessor);
Brian Salomonaff329b2017-08-11 09:40:37 -040066 }
67
Brian Salomon48d1b4c2017-04-08 07:38:53 -040068 /** Comparisons are only legal on finalized processor sets. */
Brian Salomon54d212e2017-03-21 14:22:38 -040069 bool operator==(const GrProcessorSet& that) const;
70 bool operator!=(const GrProcessorSet& that) const { return !(*this == that); }
71
Brian Salomon5298dc82017-02-22 11:52:03 -050072 /**
Brian Salomon48d1b4c2017-04-08 07:38:53 -040073 * This is used to report results of processor analysis when a processor set is finalized (see
74 * below).
Brian Salomon5298dc82017-02-22 11:52:03 -050075 */
Brian Salomona811b122017-03-30 08:21:32 -040076 class Analysis {
Brian Salomon5298dc82017-02-22 11:52:03 -050077 public:
Brian Salomon48d1b4c2017-04-08 07:38:53 -040078 Analysis(const Analysis&) = default;
79 Analysis() { *reinterpret_cast<uint32_t*>(this) = 0; }
Brian Salomon8d2f90b2017-03-13 09:11:58 -040080
Brian Salomon48d1b4c2017-04-08 07:38:53 -040081 bool isInitialized() const { return fIsInitialized; }
Brian Salomonbfafcba2017-03-02 08:49:19 -050082 bool usesLocalCoords() const { return fUsesLocalCoords; }
Brian Salomon31853842017-03-28 16:32:05 -040083 bool requiresDstTexture() const { return fRequiresDstTexture; }
Chris Dalton945ee652019-01-23 09:10:36 -070084 bool requiresNonOverlappingDraws() const { return fRequiresNonOverlappingDraws; }
Brian Salomon5298dc82017-02-22 11:52:03 -050085 bool isCompatibleWithCoverageAsAlpha() const { return fCompatibleWithCoverageAsAlpha; }
Brian Salomon41f9c3c2019-03-25 11:06:12 -040086 // Indicates whether all color fragment processors were eliminated in the analysis.
87 bool hasColorFragmentProcessor() const { return fHasColorFragmentProcessor; }
Brian Salomon48d1b4c2017-04-08 07:38:53 -040088
89 bool inputColorIsIgnored() const { return fInputColorType == kIgnored_InputColorType; }
90 bool inputColorIsOverridden() const {
91 return fInputColorType == kOverridden_InputColorType;
Brian Salomonc0b642c2017-03-27 13:09:36 -040092 }
Greg Daniel9a18b082020-08-14 14:03:50 -040093 bool usesNonCoherentHWBlending() const { return fUsesNonCoherentHWBlending; }
Chris Daltonf2fb80f2020-12-03 12:37:59 -070094 bool unaffectedByDstValue() const { return fUnaffectedByDstValue; }
Brian Salomon5298dc82017-02-22 11:52:03 -050095
96 private:
Brian Salomon6d4b65e2017-05-03 17:06:09 -040097 constexpr Analysis(Empty)
98 : fUsesLocalCoords(false)
99 , fCompatibleWithCoverageAsAlpha(true)
100 , fRequiresDstTexture(false)
Chris Dalton945ee652019-01-23 09:10:36 -0700101 , fRequiresNonOverlappingDraws(false)
Brian Salomon41f9c3c2019-03-25 11:06:12 -0400102 , fHasColorFragmentProcessor(false)
Brian Salomon6d4b65e2017-05-03 17:06:09 -0400103 , fIsInitialized(true)
Greg Daniel9a18b082020-08-14 14:03:50 -0400104 , fUsesNonCoherentHWBlending(false)
Chris Daltonf2fb80f2020-12-03 12:37:59 -0700105 , fUnaffectedByDstValue(false)
Brian Salomon6d4b65e2017-05-03 17:06:09 -0400106 , fInputColorType(kOriginal_InputColorType) {}
Brian Salomon48d1b4c2017-04-08 07:38:53 -0400107 enum InputColorType : uint32_t {
108 kOriginal_InputColorType,
109 kOverridden_InputColorType,
110 kIgnored_InputColorType
111 };
Brian Salomon5298dc82017-02-22 11:52:03 -0500112
Brian Salomon48d1b4c2017-04-08 07:38:53 -0400113 // MSVS 2015 won't pack different underlying types
114 using PackedBool = uint32_t;
115 using PackedInputColorType = uint32_t;
Brian Salomon5298dc82017-02-22 11:52:03 -0500116
Brian Salomon8d2f90b2017-03-13 09:11:58 -0400117 PackedBool fUsesLocalCoords : 1;
118 PackedBool fCompatibleWithCoverageAsAlpha : 1;
Brian Salomon31853842017-03-28 16:32:05 -0400119 PackedBool fRequiresDstTexture : 1;
Chris Dalton945ee652019-01-23 09:10:36 -0700120 PackedBool fRequiresNonOverlappingDraws : 1;
Brian Salomon41f9c3c2019-03-25 11:06:12 -0400121 PackedBool fHasColorFragmentProcessor : 1;
Brian Salomon48d1b4c2017-04-08 07:38:53 -0400122 PackedBool fIsInitialized : 1;
Greg Daniel9a18b082020-08-14 14:03:50 -0400123 PackedBool fUsesNonCoherentHWBlending : 1;
Chris Daltonf2fb80f2020-12-03 12:37:59 -0700124 PackedBool fUnaffectedByDstValue : 1;
Brian Salomon48d1b4c2017-04-08 07:38:53 -0400125 PackedInputColorType fInputColorType : 2;
Brian Salomon70288c02017-03-24 12:27:17 -0400126
127 friend class GrProcessorSet;
Brian Salomon5298dc82017-02-22 11:52:03 -0500128 };
Brian Salomon4dea72a2019-12-18 10:43:10 -0500129 static_assert(sizeof(Analysis) <= sizeof(uint32_t));
Brian Salomon5298dc82017-02-22 11:52:03 -0500130
Brian Salomon48d1b4c2017-04-08 07:38:53 -0400131 /**
132 * This analyzes the processors given an op's input color and coverage as well as a clip. The
133 * state of the processor set may change to an equivalent but more optimal set of processors.
134 * This new state requires that the caller respect the returned 'inputColorOverride'. This is
Chris Dalton133944a2018-11-16 23:30:29 -0500135 * indicated by the returned Analysis's inputColorIsOverridden(). 'inputColorOverride' will not
Brian Salomon48d1b4c2017-04-08 07:38:53 -0400136 * be written if the analysis does not override the input color.
137 *
138 * This must be called before the processor set is used to construct a GrPipeline and may only
139 * be called once.
140 *
141 * This also puts the processors in "pending execution" state and must be called when an op
142 * that owns a processor set is recorded to ensure pending and writes are propagated to
143 * resources referred to by the processors. Otherwise, data hazards may occur.
144 */
Chris Dalton6ce447a2019-06-23 18:07:38 -0600145 Analysis finalize(
146 const GrProcessorAnalysisColor&, const GrProcessorAnalysisCoverage,
147 const GrAppliedClip*, const GrUserStencilSettings*, bool hasMixedSampledCoverage,
148 const GrCaps&, GrClampType, SkPMColor4f* inputColorOverride);
Brian Salomon48d1b4c2017-04-08 07:38:53 -0400149
150 bool isFinalized() const { return SkToBool(kFinalized_Flag & fFlags); }
Brian Salomon70288c02017-03-24 12:27:17 -0400151
Brian Salomon44acb5b2017-07-18 19:59:24 -0400152 /** These are valid only for non-LCD coverage. */
Brian Salomon292bf7a2017-05-17 09:43:55 -0400153 static const GrProcessorSet& EmptySet();
Brian Salomon91326c32017-08-09 16:02:19 -0400154 static GrProcessorSet MakeEmptySet();
John Stilesec9b4aa2020-08-07 13:05:14 -0400155 static constexpr Analysis EmptySetAnalysis() { return Analysis(Empty::kEmpty); }
Brian Salomon6d4b65e2017-05-03 17:06:09 -0400156
John Stiles8d9bf642020-08-12 15:07:45 -0400157#if GR_TEST_UTILS
Brian Salomon82dfd3d2017-06-14 12:30:35 -0400158 SkString dumpProcessors() const;
Brian Osman9a390ac2018-11-12 09:47:48 -0500159#endif
Brian Salomon82dfd3d2017-06-14 12:30:35 -0400160
Brian Salomonc241b582019-11-27 08:57:17 -0500161 void visitProxies(const GrOp::VisitProxyFunc& func) const;
Robert Phillipsb493eeb2017-09-13 13:10:52 -0400162
Brian Salomon92ce5942017-01-18 11:01:10 -0500163private:
Brian Salomon6d4b65e2017-05-03 17:06:09 -0400164 GrProcessorSet(Empty) : fXP((const GrXferProcessor*)nullptr), fFlags(kFinalized_Flag) {}
Brian Salomon6d4b65e2017-05-03 17:06:09 -0400165
Robert Phillipsb493eeb2017-09-13 13:10:52 -0400166 int numFragmentProcessors() const {
John Stiles29d3e222020-07-21 17:28:12 -0400167 return (fColorFragmentProcessor ? 1 : 0) + (fCoverageFragmentProcessor ? 1 : 0);
Robert Phillipsb493eeb2017-09-13 13:10:52 -0400168 }
169
Brian Salomone23bffd2017-06-02 11:01:10 -0400170 enum Flags : uint16_t { kFinalized_Flag = 0x1 };
Brian Salomon8d2f90b2017-03-13 09:11:58 -0400171
Brian Salomon48d1b4c2017-04-08 07:38:53 -0400172 union XP {
173 XP(const GrXPFactory* factory) : fFactory(factory) {}
Brian Salomon6d4b65e2017-05-03 17:06:09 -0400174 XP(const GrXferProcessor* processor) : fProcessor(processor) {}
Brian Salomon91326c32017-08-09 16:02:19 -0400175 explicit XP(XP&& that) : fProcessor(that.fProcessor) {
176 SkASSERT(fProcessor == that.fProcessor);
177 that.fProcessor = nullptr;
178 }
Brian Salomon48d1b4c2017-04-08 07:38:53 -0400179 const GrXPFactory* fFactory;
180 const GrXferProcessor* fProcessor;
181 };
182
183 const GrXPFactory* xpFactory() const {
184 SkASSERT(!this->isFinalized());
185 return fXP.fFactory;
186 }
187
John Stiles29d3e222020-07-21 17:28:12 -0400188 std::unique_ptr<GrFragmentProcessor> fColorFragmentProcessor;
189 std::unique_ptr<GrFragmentProcessor> fCoverageFragmentProcessor;
Brian Salomon48d1b4c2017-04-08 07:38:53 -0400190 XP fXP;
John Stiles29d3e222020-07-21 17:28:12 -0400191 uint8_t fFlags = 0;
Brian Salomon92ce5942017-01-18 11:01:10 -0500192};
193
194#endif