blob: b13175ab10194321e2190b7f24dbe196b891aa9f [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
20class GrProcessorSet : private SkNoncopyable {
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:
26 GrProcessorSet(GrPaint&& paint);
27
Brian Salomon54d212e2017-03-21 14:22:38 -040028 ~GrProcessorSet();
29
Brian Salomon92ce5942017-01-18 11:01:10 -050030 int numColorFragmentProcessors() const { return fColorFragmentProcessorCnt; }
31 int numCoverageFragmentProcessors() const {
Brian Salomon70288c02017-03-24 12:27:17 -040032 return this->numFragmentProcessors() - fColorFragmentProcessorCnt;
Brian Salomon92ce5942017-01-18 11:01:10 -050033 }
Brian Salomon70288c02017-03-24 12:27:17 -040034 int numFragmentProcessors() const {
35 return fFragmentProcessors.count() - fFragmentProcessorOffset;
36 }
Brian Salomon92ce5942017-01-18 11:01:10 -050037
38 const GrFragmentProcessor* colorFragmentProcessor(int idx) const {
39 SkASSERT(idx < fColorFragmentProcessorCnt);
Brian Salomon70288c02017-03-24 12:27:17 -040040 return fFragmentProcessors[idx + fFragmentProcessorOffset];
Brian Salomon92ce5942017-01-18 11:01:10 -050041 }
42 const GrFragmentProcessor* coverageFragmentProcessor(int idx) const {
Brian Salomon70288c02017-03-24 12:27:17 -040043 return fFragmentProcessors[idx + fColorFragmentProcessorCnt + fFragmentProcessorOffset];
Brian Salomon92ce5942017-01-18 11:01:10 -050044 }
45
Brian Salomon48d1b4c2017-04-08 07:38:53 -040046 const GrXferProcessor* xferProcessor() const {
47 SkASSERT(this->isFinalized());
48 return fXP.fProcessor;
49 }
Brian Salomond61c9d92017-04-10 10:54:25 -040050 sk_sp<const GrXferProcessor> refXferProcessor() const {
51 SkASSERT(this->isFinalized());
52 return sk_ref_sp(fXP.fProcessor);
53 }
Brian Salomon92ce5942017-01-18 11:01:10 -050054
Brian Salomonf87e2b92017-01-19 11:31:50 -050055 bool usesDistanceVectorField() const { return SkToBool(fFlags & kUseDistanceVectorField_Flag); }
Brian Salomon189098e72017-01-19 09:55:19 -050056
Brian Salomon48d1b4c2017-04-08 07:38:53 -040057 /** Comparisons are only legal on finalized processor sets. */
Brian Salomon54d212e2017-03-21 14:22:38 -040058 bool operator==(const GrProcessorSet& that) const;
59 bool operator!=(const GrProcessorSet& that) const { return !(*this == that); }
60
Brian Salomon5298dc82017-02-22 11:52:03 -050061 /**
Brian Salomon48d1b4c2017-04-08 07:38:53 -040062 * This is used to report results of processor analysis when a processor set is finalized (see
63 * below).
Brian Salomon5298dc82017-02-22 11:52:03 -050064 */
Brian Salomona811b122017-03-30 08:21:32 -040065 class Analysis {
Brian Salomon5298dc82017-02-22 11:52:03 -050066 public:
Brian Salomon48d1b4c2017-04-08 07:38:53 -040067 Analysis(const Analysis&) = default;
68 Analysis() { *reinterpret_cast<uint32_t*>(this) = 0; }
Brian Salomon8d2f90b2017-03-13 09:11:58 -040069
Brian Salomon48d1b4c2017-04-08 07:38:53 -040070 bool isInitialized() const { return fIsInitialized; }
Brian Salomonbfafcba2017-03-02 08:49:19 -050071 bool usesLocalCoords() const { return fUsesLocalCoords; }
Brian Salomon31853842017-03-28 16:32:05 -040072 bool requiresDstTexture() const { return fRequiresDstTexture; }
73 bool canCombineOverlappedStencilAndCover() const {
74 return fCanCombineOverlappedStencilAndCover;
75 }
Brian Salomon4fc77402017-03-30 16:48:26 -040076 bool requiresBarrierBetweenOverlappingDraws() const {
77 return fRequiresBarrierBetweenOverlappingDraws;
78 }
Brian Salomon5298dc82017-02-22 11:52:03 -050079 bool isCompatibleWithCoverageAsAlpha() const { return fCompatibleWithCoverageAsAlpha; }
Brian Salomon48d1b4c2017-04-08 07:38:53 -040080
81 bool inputColorIsIgnored() const { return fInputColorType == kIgnored_InputColorType; }
82 bool inputColorIsOverridden() const {
83 return fInputColorType == kOverridden_InputColorType;
Brian Salomonc0b642c2017-03-27 13:09:36 -040084 }
Brian Salomon5298dc82017-02-22 11:52:03 -050085
86 private:
Brian Salomon6d4b65e2017-05-03 17:06:09 -040087 constexpr Analysis(Empty)
88 : fUsesLocalCoords(false)
89 , fCompatibleWithCoverageAsAlpha(true)
90 , fRequiresDstTexture(false)
91 , fCanCombineOverlappedStencilAndCover(true)
92 , fRequiresBarrierBetweenOverlappingDraws(false)
93 , fIsInitialized(true)
94 , fInputColorType(kOriginal_InputColorType) {}
Brian Salomon48d1b4c2017-04-08 07:38:53 -040095 enum InputColorType : uint32_t {
96 kOriginal_InputColorType,
97 kOverridden_InputColorType,
98 kIgnored_InputColorType
99 };
Brian Salomon5298dc82017-02-22 11:52:03 -0500100
Brian Salomon48d1b4c2017-04-08 07:38:53 -0400101 // MSVS 2015 won't pack different underlying types
102 using PackedBool = uint32_t;
103 using PackedInputColorType = uint32_t;
Brian Salomon5298dc82017-02-22 11:52:03 -0500104
Brian Salomon8d2f90b2017-03-13 09:11:58 -0400105 PackedBool fUsesLocalCoords : 1;
106 PackedBool fCompatibleWithCoverageAsAlpha : 1;
Brian Salomon31853842017-03-28 16:32:05 -0400107 PackedBool fRequiresDstTexture : 1;
108 PackedBool fCanCombineOverlappedStencilAndCover : 1;
Brian Salomon4fc77402017-03-30 16:48:26 -0400109 PackedBool fRequiresBarrierBetweenOverlappingDraws : 1;
Brian Salomon48d1b4c2017-04-08 07:38:53 -0400110 PackedBool fIsInitialized : 1;
111 PackedInputColorType fInputColorType : 2;
Brian Salomon70288c02017-03-24 12:27:17 -0400112
113 friend class GrProcessorSet;
Brian Salomon5298dc82017-02-22 11:52:03 -0500114 };
Brian Salomon48d1b4c2017-04-08 07:38:53 -0400115 GR_STATIC_ASSERT(sizeof(Analysis) <= sizeof(uint32_t));
Brian Salomon5298dc82017-02-22 11:52:03 -0500116
Brian Salomon48d1b4c2017-04-08 07:38:53 -0400117 /**
118 * This analyzes the processors given an op's input color and coverage as well as a clip. The
119 * state of the processor set may change to an equivalent but more optimal set of processors.
120 * This new state requires that the caller respect the returned 'inputColorOverride'. This is
121 * indicated by the returned Analysis's inputColorIsOverriden(). 'inputColorOverride' will not
122 * be written if the analysis does not override the input color.
123 *
124 * This must be called before the processor set is used to construct a GrPipeline and may only
125 * be called once.
126 *
127 * This also puts the processors in "pending execution" state and must be called when an op
128 * that owns a processor set is recorded to ensure pending and writes are propagated to
129 * resources referred to by the processors. Otherwise, data hazards may occur.
130 */
131 Analysis finalize(const GrProcessorAnalysisColor& colorInput,
132 const GrProcessorAnalysisCoverage coverageInput, const GrAppliedClip*,
133 bool isMixedSamples, const GrCaps&, GrColor* inputColorOverride);
134
135 bool isFinalized() const { return SkToBool(kFinalized_Flag & fFlags); }
Brian Salomon70288c02017-03-24 12:27:17 -0400136
Brian Salomon292bf7a2017-05-17 09:43:55 -0400137 static const GrProcessorSet& EmptySet();
Brian Salomon6d4b65e2017-05-03 17:06:09 -0400138 static constexpr const Analysis EmptySetAnalysis() { return Analysis(Empty::kEmpty); }
139
Brian Salomon92ce5942017-01-18 11:01:10 -0500140private:
Brian Salomon6d4b65e2017-05-03 17:06:09 -0400141 GrProcessorSet(Empty) : fXP((const GrXferProcessor*)nullptr), fFlags(kFinalized_Flag) {}
Brian Salomon6d4b65e2017-05-03 17:06:09 -0400142
Brian Salomona811b122017-03-30 08:21:32 -0400143 // This absurdly large limit allows Analysis and this to pack fields together.
Brian Salomon70288c02017-03-24 12:27:17 -0400144 static constexpr int kMaxColorProcessors = UINT8_MAX;
Brian Salomon8d2f90b2017-03-13 09:11:58 -0400145
Brian Salomon611572c2017-04-28 08:57:12 -0400146 enum Flags : uint16_t { kUseDistanceVectorField_Flag = 0x1, kFinalized_Flag = 0x2 };
Brian Salomon8d2f90b2017-03-13 09:11:58 -0400147
Brian Salomon48d1b4c2017-04-08 07:38:53 -0400148 union XP {
149 XP(const GrXPFactory* factory) : fFactory(factory) {}
Brian Salomon6d4b65e2017-05-03 17:06:09 -0400150 XP(const GrXferProcessor* processor) : fProcessor(processor) {}
Brian Salomon48d1b4c2017-04-08 07:38:53 -0400151 const GrXPFactory* fFactory;
152 const GrXferProcessor* fProcessor;
153 };
154
155 const GrXPFactory* xpFactory() const {
156 SkASSERT(!this->isFinalized());
157 return fXP.fFactory;
158 }
159
Brian Salomon8d2f90b2017-03-13 09:11:58 -0400160 SkAutoSTArray<4, const GrFragmentProcessor*> fFragmentProcessors;
Brian Salomon48d1b4c2017-04-08 07:38:53 -0400161 XP fXP;
Brian Salomon6d4b65e2017-05-03 17:06:09 -0400162 uint8_t fColorFragmentProcessorCnt = 0;
Brian Salomon70288c02017-03-24 12:27:17 -0400163 uint8_t fFragmentProcessorOffset = 0;
164 uint8_t fFlags;
Brian Salomon92ce5942017-01-18 11:01:10 -0500165};
166
167#endif