blob: b7b7ae0bdf0a21c84eaaf32038103b0f670e6d69 [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
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
Brian Salomon92ce5942017-01-18 11:01:10 -050036 int numColorFragmentProcessors() const { return fColorFragmentProcessorCnt; }
37 int numCoverageFragmentProcessors() const {
Brian Salomon70288c02017-03-24 12:27:17 -040038 return this->numFragmentProcessors() - fColorFragmentProcessorCnt;
Brian Salomon92ce5942017-01-18 11:01:10 -050039 }
Brian Salomon92ce5942017-01-18 11:01:10 -050040
41 const GrFragmentProcessor* colorFragmentProcessor(int idx) const {
42 SkASSERT(idx < fColorFragmentProcessorCnt);
Brian Salomonaff329b2017-08-11 09:40:37 -040043 return fFragmentProcessors[idx + fFragmentProcessorOffset].get();
Brian Salomon92ce5942017-01-18 11:01:10 -050044 }
45 const GrFragmentProcessor* coverageFragmentProcessor(int idx) const {
Brian Salomonaff329b2017-08-11 09:40:37 -040046 return fFragmentProcessors[idx + fColorFragmentProcessorCnt +
47 fFragmentProcessorOffset].get();
Brian Salomon92ce5942017-01-18 11:01:10 -050048 }
49
Brian Salomon48d1b4c2017-04-08 07:38:53 -040050 const GrXferProcessor* xferProcessor() const {
51 SkASSERT(this->isFinalized());
52 return fXP.fProcessor;
53 }
Brian Salomond61c9d92017-04-10 10:54:25 -040054 sk_sp<const GrXferProcessor> refXferProcessor() const {
55 SkASSERT(this->isFinalized());
56 return sk_ref_sp(fXP.fProcessor);
57 }
Brian Salomon92ce5942017-01-18 11:01:10 -050058
Brian Salomonaff329b2017-08-11 09:40:37 -040059 std::unique_ptr<const GrFragmentProcessor> detachColorFragmentProcessor(int idx) {
60 SkASSERT(idx < fColorFragmentProcessorCnt);
61 return std::move(fFragmentProcessors[idx + fFragmentProcessorOffset]);
62 }
63
64 std::unique_ptr<const GrFragmentProcessor> detachCoverageFragmentProcessor(int idx) {
65 return std::move(
66 fFragmentProcessors[idx + fFragmentProcessorOffset + fColorFragmentProcessorCnt]);
67 }
68
Brian Salomon48d1b4c2017-04-08 07:38:53 -040069 /** Comparisons are only legal on finalized processor sets. */
Brian Salomon54d212e2017-03-21 14:22:38 -040070 bool operator==(const GrProcessorSet& that) const;
71 bool operator!=(const GrProcessorSet& that) const { return !(*this == that); }
72
Brian Salomon5298dc82017-02-22 11:52:03 -050073 /**
Brian Salomon48d1b4c2017-04-08 07:38:53 -040074 * This is used to report results of processor analysis when a processor set is finalized (see
75 * below).
Brian Salomon5298dc82017-02-22 11:52:03 -050076 */
Brian Salomona811b122017-03-30 08:21:32 -040077 class Analysis {
Brian Salomon5298dc82017-02-22 11:52:03 -050078 public:
Brian Salomon48d1b4c2017-04-08 07:38:53 -040079 Analysis(const Analysis&) = default;
80 Analysis() { *reinterpret_cast<uint32_t*>(this) = 0; }
Brian Salomon8d2f90b2017-03-13 09:11:58 -040081
Brian Salomon48d1b4c2017-04-08 07:38:53 -040082 bool isInitialized() const { return fIsInitialized; }
Brian Salomonbfafcba2017-03-02 08:49:19 -050083 bool usesLocalCoords() const { return fUsesLocalCoords; }
Brian Salomon31853842017-03-28 16:32:05 -040084 bool requiresDstTexture() const { return fRequiresDstTexture; }
Chris Dalton945ee652019-01-23 09:10:36 -070085 bool requiresNonOverlappingDraws() const { return fRequiresNonOverlappingDraws; }
Brian Salomon5298dc82017-02-22 11:52:03 -050086 bool isCompatibleWithCoverageAsAlpha() const { return fCompatibleWithCoverageAsAlpha; }
Brian Salomon48d1b4c2017-04-08 07:38:53 -040087
88 bool inputColorIsIgnored() const { return fInputColorType == kIgnored_InputColorType; }
89 bool inputColorIsOverridden() const {
90 return fInputColorType == kOverridden_InputColorType;
Brian Salomonc0b642c2017-03-27 13:09:36 -040091 }
Brian Salomon5298dc82017-02-22 11:52:03 -050092
93 private:
Brian Salomon6d4b65e2017-05-03 17:06:09 -040094 constexpr Analysis(Empty)
95 : fUsesLocalCoords(false)
96 , fCompatibleWithCoverageAsAlpha(true)
97 , fRequiresDstTexture(false)
Chris Dalton945ee652019-01-23 09:10:36 -070098 , fRequiresNonOverlappingDraws(false)
Brian Salomon6d4b65e2017-05-03 17:06:09 -040099 , fIsInitialized(true)
100 , fInputColorType(kOriginal_InputColorType) {}
Brian Salomon48d1b4c2017-04-08 07:38:53 -0400101 enum InputColorType : uint32_t {
102 kOriginal_InputColorType,
103 kOverridden_InputColorType,
104 kIgnored_InputColorType
105 };
Brian Salomon5298dc82017-02-22 11:52:03 -0500106
Brian Salomon48d1b4c2017-04-08 07:38:53 -0400107 // MSVS 2015 won't pack different underlying types
108 using PackedBool = uint32_t;
109 using PackedInputColorType = uint32_t;
Brian Salomon5298dc82017-02-22 11:52:03 -0500110
Brian Salomon8d2f90b2017-03-13 09:11:58 -0400111 PackedBool fUsesLocalCoords : 1;
112 PackedBool fCompatibleWithCoverageAsAlpha : 1;
Brian Salomon31853842017-03-28 16:32:05 -0400113 PackedBool fRequiresDstTexture : 1;
Chris Dalton945ee652019-01-23 09:10:36 -0700114 PackedBool fRequiresNonOverlappingDraws : 1;
Brian Salomon48d1b4c2017-04-08 07:38:53 -0400115 PackedBool fIsInitialized : 1;
116 PackedInputColorType fInputColorType : 2;
Brian Salomon70288c02017-03-24 12:27:17 -0400117
118 friend class GrProcessorSet;
Brian Salomon5298dc82017-02-22 11:52:03 -0500119 };
Brian Salomon48d1b4c2017-04-08 07:38:53 -0400120 GR_STATIC_ASSERT(sizeof(Analysis) <= sizeof(uint32_t));
Brian Salomon5298dc82017-02-22 11:52:03 -0500121
Brian Salomon48d1b4c2017-04-08 07:38:53 -0400122 /**
123 * This analyzes the processors given an op's input color and coverage as well as a clip. The
124 * state of the processor set may change to an equivalent but more optimal set of processors.
125 * This new state requires that the caller respect the returned 'inputColorOverride'. This is
Chris Dalton133944a2018-11-16 23:30:29 -0500126 * indicated by the returned Analysis's inputColorIsOverridden(). 'inputColorOverride' will not
Brian Salomon48d1b4c2017-04-08 07:38:53 -0400127 * be written if the analysis does not override the input color.
128 *
129 * This must be called before the processor set is used to construct a GrPipeline and may only
130 * be called once.
131 *
132 * This also puts the processors in "pending execution" state and must be called when an op
133 * that owns a processor set is recorded to ensure pending and writes are propagated to
134 * resources referred to by the processors. Otherwise, data hazards may occur.
135 */
Chris Daltonb8fff0d2019-03-05 10:11:58 -0700136 Analysis finalize(const GrProcessorAnalysisColor&, const GrProcessorAnalysisCoverage,
137 const GrAppliedClip*, const GrUserStencilSettings*, GrFSAAType, const GrCaps&,
Brian Osman5ced0bf2019-03-15 10:15:29 -0400138 GrClampType, SkPMColor4f* inputColorOverride);
Brian Salomon48d1b4c2017-04-08 07:38:53 -0400139
140 bool isFinalized() const { return SkToBool(kFinalized_Flag & fFlags); }
Brian Salomon70288c02017-03-24 12:27:17 -0400141
Brian Salomon44acb5b2017-07-18 19:59:24 -0400142 /** These are valid only for non-LCD coverage. */
Brian Salomon292bf7a2017-05-17 09:43:55 -0400143 static const GrProcessorSet& EmptySet();
Brian Salomon91326c32017-08-09 16:02:19 -0400144 static GrProcessorSet MakeEmptySet();
Brian Salomon6d4b65e2017-05-03 17:06:09 -0400145 static constexpr const Analysis EmptySetAnalysis() { return Analysis(Empty::kEmpty); }
146
Brian Osman9a390ac2018-11-12 09:47:48 -0500147#ifdef SK_DEBUG
Brian Salomon82dfd3d2017-06-14 12:30:35 -0400148 SkString dumpProcessors() const;
Brian Osman9a390ac2018-11-12 09:47:48 -0500149#endif
Brian Salomon82dfd3d2017-06-14 12:30:35 -0400150
Robert Phillipsf1748f52017-09-14 14:11:24 -0400151 void visitProxies(const std::function<void(GrSurfaceProxy*)>& func) const {
Robert Phillipsb493eeb2017-09-13 13:10:52 -0400152 for (int i = 0; i < this->numFragmentProcessors(); ++i) {
153 GrFragmentProcessor::TextureAccessIter iter(this->fragmentProcessor(i));
Brian Salomone782f842018-07-31 13:53:11 -0400154 while (const GrFragmentProcessor::TextureSampler* sampler = iter.next()) {
Robert Phillipsb493eeb2017-09-13 13:10:52 -0400155 func(sampler->proxy());
156 }
157 }
158 }
159
Brian Salomon92ce5942017-01-18 11:01:10 -0500160private:
Brian Salomon6d4b65e2017-05-03 17:06:09 -0400161 GrProcessorSet(Empty) : fXP((const GrXferProcessor*)nullptr), fFlags(kFinalized_Flag) {}
Brian Salomon6d4b65e2017-05-03 17:06:09 -0400162
Robert Phillipsb493eeb2017-09-13 13:10:52 -0400163 int numFragmentProcessors() const {
164 return fFragmentProcessors.count() - fFragmentProcessorOffset;
165 }
166
167 const GrFragmentProcessor* fragmentProcessor(int idx) const {
168 return fFragmentProcessors[idx + fFragmentProcessorOffset].get();
169 }
170
Brian Salomona811b122017-03-30 08:21:32 -0400171 // This absurdly large limit allows Analysis and this to pack fields together.
Brian Salomon70288c02017-03-24 12:27:17 -0400172 static constexpr int kMaxColorProcessors = UINT8_MAX;
Brian Salomon8d2f90b2017-03-13 09:11:58 -0400173
Brian Salomone23bffd2017-06-02 11:01:10 -0400174 enum Flags : uint16_t { kFinalized_Flag = 0x1 };
Brian Salomon8d2f90b2017-03-13 09:11:58 -0400175
Brian Salomon48d1b4c2017-04-08 07:38:53 -0400176 union XP {
177 XP(const GrXPFactory* factory) : fFactory(factory) {}
Brian Salomon6d4b65e2017-05-03 17:06:09 -0400178 XP(const GrXferProcessor* processor) : fProcessor(processor) {}
Brian Salomon91326c32017-08-09 16:02:19 -0400179 explicit XP(XP&& that) : fProcessor(that.fProcessor) {
180 SkASSERT(fProcessor == that.fProcessor);
181 that.fProcessor = nullptr;
182 }
Brian Salomon48d1b4c2017-04-08 07:38:53 -0400183 const GrXPFactory* fFactory;
184 const GrXferProcessor* fProcessor;
185 };
186
187 const GrXPFactory* xpFactory() const {
188 SkASSERT(!this->isFinalized());
189 return fXP.fFactory;
190 }
191
Brian Salomonaff329b2017-08-11 09:40:37 -0400192 SkAutoSTArray<4, std::unique_ptr<const GrFragmentProcessor>> fFragmentProcessors;
Brian Salomon48d1b4c2017-04-08 07:38:53 -0400193 XP fXP;
Brian Salomon6d4b65e2017-05-03 17:06:09 -0400194 uint8_t fColorFragmentProcessorCnt = 0;
Brian Salomon70288c02017-03-24 12:27:17 -0400195 uint8_t fFragmentProcessorOffset = 0;
196 uint8_t fFlags;
Brian Salomon92ce5942017-01-18 11:01:10 -0500197};
198
199#endif