blob: 023c4dfd6b0b7ab9560750c1e28104fbc2eeaf69 [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
11#include "GrFragmentProcessor.h"
12#include "GrPaint.h"
Brian Salomona811b122017-03-30 08:21:32 -040013#include "GrProcessorAnalysis.h"
Brian Salomon92ce5942017-01-18 11:01:10 -050014#include "SkTemplates.h"
Hal Canaryce78bad2017-05-04 14:15:40 -040015#include "GrXferProcessor.h"
Brian Salomon92ce5942017-01-18 11:01:10 -050016
Brian Salomon5298dc82017-02-22 11:52:03 -050017class GrAppliedClip;
Brian Salomon92ce5942017-01-18 11:01:10 -050018class GrXPFactory;
19
Brian Salomon91326c32017-08-09 16:02:19 -040020class GrProcessorSet {
Brian Salomon6d4b65e2017-05-03 17:06:09 -040021private:
22 // Arbitrary constructor arg for empty set and analysis
23 enum class Empty { kEmpty };
24
Brian Salomon92ce5942017-01-18 11:01:10 -050025public:
Brian Salomon91326c32017-08-09 16:02:19 -040026 GrProcessorSet(GrPaint&&);
27 GrProcessorSet(SkBlendMode);
Brian Salomonaff329b2017-08-11 09:40:37 -040028 GrProcessorSet(std::unique_ptr<GrFragmentProcessor> colorFP);
Brian Salomon91326c32017-08-09 16:02:19 -040029 GrProcessorSet(GrProcessorSet&&);
30 GrProcessorSet(const GrProcessorSet&) = delete;
31 GrProcessorSet& operator=(const GrProcessorSet&) = delete;
Brian Salomon92ce5942017-01-18 11:01:10 -050032
Brian Salomon54d212e2017-03-21 14:22:38 -040033 ~GrProcessorSet();
34
Brian Salomon92ce5942017-01-18 11:01:10 -050035 int numColorFragmentProcessors() const { return fColorFragmentProcessorCnt; }
36 int numCoverageFragmentProcessors() const {
Brian Salomon70288c02017-03-24 12:27:17 -040037 return this->numFragmentProcessors() - fColorFragmentProcessorCnt;
Brian Salomon92ce5942017-01-18 11:01:10 -050038 }
Brian Salomon70288c02017-03-24 12:27:17 -040039 int numFragmentProcessors() const {
40 return fFragmentProcessors.count() - fFragmentProcessorOffset;
41 }
Brian Salomon92ce5942017-01-18 11:01:10 -050042
43 const GrFragmentProcessor* colorFragmentProcessor(int idx) const {
44 SkASSERT(idx < fColorFragmentProcessorCnt);
Brian Salomonaff329b2017-08-11 09:40:37 -040045 return fFragmentProcessors[idx + fFragmentProcessorOffset].get();
Brian Salomon92ce5942017-01-18 11:01:10 -050046 }
47 const GrFragmentProcessor* coverageFragmentProcessor(int idx) const {
Brian Salomonaff329b2017-08-11 09:40:37 -040048 return fFragmentProcessors[idx + fColorFragmentProcessorCnt +
49 fFragmentProcessorOffset].get();
Brian Salomon92ce5942017-01-18 11:01:10 -050050 }
51
Brian Salomon48d1b4c2017-04-08 07:38:53 -040052 const GrXferProcessor* xferProcessor() const {
53 SkASSERT(this->isFinalized());
54 return fXP.fProcessor;
55 }
Brian Salomond61c9d92017-04-10 10:54:25 -040056 sk_sp<const GrXferProcessor> refXferProcessor() const {
57 SkASSERT(this->isFinalized());
58 return sk_ref_sp(fXP.fProcessor);
59 }
Brian Salomon92ce5942017-01-18 11:01:10 -050060
Brian Salomonaff329b2017-08-11 09:40:37 -040061 std::unique_ptr<const GrFragmentProcessor> detachColorFragmentProcessor(int idx) {
62 SkASSERT(idx < fColorFragmentProcessorCnt);
63 return std::move(fFragmentProcessors[idx + fFragmentProcessorOffset]);
64 }
65
66 std::unique_ptr<const GrFragmentProcessor> detachCoverageFragmentProcessor(int idx) {
67 return std::move(
68 fFragmentProcessors[idx + fFragmentProcessorOffset + fColorFragmentProcessorCnt]);
69 }
70
Brian Salomon48d1b4c2017-04-08 07:38:53 -040071 /** Comparisons are only legal on finalized processor sets. */
Brian Salomon54d212e2017-03-21 14:22:38 -040072 bool operator==(const GrProcessorSet& that) const;
73 bool operator!=(const GrProcessorSet& that) const { return !(*this == that); }
74
Brian Salomon5298dc82017-02-22 11:52:03 -050075 /**
Brian Salomon48d1b4c2017-04-08 07:38:53 -040076 * This is used to report results of processor analysis when a processor set is finalized (see
77 * below).
Brian Salomon5298dc82017-02-22 11:52:03 -050078 */
Brian Salomona811b122017-03-30 08:21:32 -040079 class Analysis {
Brian Salomon5298dc82017-02-22 11:52:03 -050080 public:
Brian Salomon48d1b4c2017-04-08 07:38:53 -040081 Analysis(const Analysis&) = default;
82 Analysis() { *reinterpret_cast<uint32_t*>(this) = 0; }
Brian Salomon8d2f90b2017-03-13 09:11:58 -040083
Brian Salomon48d1b4c2017-04-08 07:38:53 -040084 bool isInitialized() const { return fIsInitialized; }
Brian Salomonbfafcba2017-03-02 08:49:19 -050085 bool usesLocalCoords() const { return fUsesLocalCoords; }
Brian Salomon31853842017-03-28 16:32:05 -040086 bool requiresDstTexture() const { return fRequiresDstTexture; }
87 bool canCombineOverlappedStencilAndCover() const {
88 return fCanCombineOverlappedStencilAndCover;
89 }
Brian Salomon4fc77402017-03-30 16:48:26 -040090 bool requiresBarrierBetweenOverlappingDraws() const {
91 return fRequiresBarrierBetweenOverlappingDraws;
92 }
Brian Salomon5298dc82017-02-22 11:52:03 -050093 bool isCompatibleWithCoverageAsAlpha() const { return fCompatibleWithCoverageAsAlpha; }
Brian Salomon48d1b4c2017-04-08 07:38:53 -040094
95 bool inputColorIsIgnored() const { return fInputColorType == kIgnored_InputColorType; }
96 bool inputColorIsOverridden() const {
97 return fInputColorType == kOverridden_InputColorType;
Brian Salomonc0b642c2017-03-27 13:09:36 -040098 }
Brian Salomon5298dc82017-02-22 11:52:03 -050099
100 private:
Brian Salomon6d4b65e2017-05-03 17:06:09 -0400101 constexpr Analysis(Empty)
102 : fUsesLocalCoords(false)
103 , fCompatibleWithCoverageAsAlpha(true)
104 , fRequiresDstTexture(false)
105 , fCanCombineOverlappedStencilAndCover(true)
106 , fRequiresBarrierBetweenOverlappingDraws(false)
107 , fIsInitialized(true)
108 , fInputColorType(kOriginal_InputColorType) {}
Brian Salomon48d1b4c2017-04-08 07:38:53 -0400109 enum InputColorType : uint32_t {
110 kOriginal_InputColorType,
111 kOverridden_InputColorType,
112 kIgnored_InputColorType
113 };
Brian Salomon5298dc82017-02-22 11:52:03 -0500114
Brian Salomon48d1b4c2017-04-08 07:38:53 -0400115 // MSVS 2015 won't pack different underlying types
116 using PackedBool = uint32_t;
117 using PackedInputColorType = uint32_t;
Brian Salomon5298dc82017-02-22 11:52:03 -0500118
Brian Salomon8d2f90b2017-03-13 09:11:58 -0400119 PackedBool fUsesLocalCoords : 1;
120 PackedBool fCompatibleWithCoverageAsAlpha : 1;
Brian Salomon31853842017-03-28 16:32:05 -0400121 PackedBool fRequiresDstTexture : 1;
122 PackedBool fCanCombineOverlappedStencilAndCover : 1;
Brian Salomon4fc77402017-03-30 16:48:26 -0400123 PackedBool fRequiresBarrierBetweenOverlappingDraws : 1;
Brian Salomon48d1b4c2017-04-08 07:38:53 -0400124 PackedBool fIsInitialized : 1;
125 PackedInputColorType fInputColorType : 2;
Brian Salomon70288c02017-03-24 12:27:17 -0400126
127 friend class GrProcessorSet;
Brian Salomon5298dc82017-02-22 11:52:03 -0500128 };
Brian Salomon48d1b4c2017-04-08 07:38:53 -0400129 GR_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
135 * indicated by the returned Analysis's inputColorIsOverriden(). 'inputColorOverride' will not
136 * 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 */
145 Analysis finalize(const GrProcessorAnalysisColor& colorInput,
146 const GrProcessorAnalysisCoverage coverageInput, const GrAppliedClip*,
147 bool isMixedSamples, const GrCaps&, GrColor* inputColorOverride);
148
149 bool isFinalized() const { return SkToBool(kFinalized_Flag & fFlags); }
Brian Salomon70288c02017-03-24 12:27:17 -0400150
Brian Salomon44acb5b2017-07-18 19:59:24 -0400151 /** These are valid only for non-LCD coverage. */
Brian Salomon292bf7a2017-05-17 09:43:55 -0400152 static const GrProcessorSet& EmptySet();
Brian Salomon91326c32017-08-09 16:02:19 -0400153 static GrProcessorSet MakeEmptySet();
Brian Salomon6d4b65e2017-05-03 17:06:09 -0400154 static constexpr const Analysis EmptySetAnalysis() { return Analysis(Empty::kEmpty); }
155
Brian Salomon82dfd3d2017-06-14 12:30:35 -0400156 SkString dumpProcessors() const;
157
Brian Salomon92ce5942017-01-18 11:01:10 -0500158private:
Brian Salomon6d4b65e2017-05-03 17:06:09 -0400159 GrProcessorSet(Empty) : fXP((const GrXferProcessor*)nullptr), fFlags(kFinalized_Flag) {}
Brian Salomon6d4b65e2017-05-03 17:06:09 -0400160
Brian Salomona811b122017-03-30 08:21:32 -0400161 // This absurdly large limit allows Analysis and this to pack fields together.
Brian Salomon70288c02017-03-24 12:27:17 -0400162 static constexpr int kMaxColorProcessors = UINT8_MAX;
Brian Salomon8d2f90b2017-03-13 09:11:58 -0400163
Brian Salomone23bffd2017-06-02 11:01:10 -0400164 enum Flags : uint16_t { kFinalized_Flag = 0x1 };
Brian Salomon8d2f90b2017-03-13 09:11:58 -0400165
Brian Salomon48d1b4c2017-04-08 07:38:53 -0400166 union XP {
167 XP(const GrXPFactory* factory) : fFactory(factory) {}
Brian Salomon6d4b65e2017-05-03 17:06:09 -0400168 XP(const GrXferProcessor* processor) : fProcessor(processor) {}
Brian Salomon91326c32017-08-09 16:02:19 -0400169 explicit XP(XP&& that) : fProcessor(that.fProcessor) {
170 SkASSERT(fProcessor == that.fProcessor);
171 that.fProcessor = nullptr;
172 }
Brian Salomon48d1b4c2017-04-08 07:38:53 -0400173 const GrXPFactory* fFactory;
174 const GrXferProcessor* fProcessor;
175 };
176
177 const GrXPFactory* xpFactory() const {
178 SkASSERT(!this->isFinalized());
179 return fXP.fFactory;
180 }
181
Brian Salomonaff329b2017-08-11 09:40:37 -0400182 SkAutoSTArray<4, std::unique_ptr<const GrFragmentProcessor>> fFragmentProcessors;
Brian Salomon48d1b4c2017-04-08 07:38:53 -0400183 XP fXP;
Brian Salomon6d4b65e2017-05-03 17:06:09 -0400184 uint8_t fColorFragmentProcessorCnt = 0;
Brian Salomon70288c02017-03-24 12:27:17 -0400185 uint8_t fFragmentProcessorOffset = 0;
186 uint8_t fFlags;
Brian Salomon92ce5942017-01-18 11:01:10 -0500187};
188
189#endif