Brian Salomon | 92ce594 | 2017-01-18 11:01:10 -0500 | [diff] [blame] | 1 | /* |
| 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 Klein | c0bd9f9 | 2019-04-23 12:05:21 -0500 | [diff] [blame] | 11 | #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 Salomon | 92ce594 | 2017-01-18 11:01:10 -0500 | [diff] [blame] | 16 | |
Chris Dalton | b8fff0d | 2019-03-05 10:11:58 -0700 | [diff] [blame] | 17 | struct GrUserStencilSettings; |
Brian Salomon | 5298dc8 | 2017-02-22 11:52:03 -0500 | [diff] [blame] | 18 | class GrAppliedClip; |
Brian Salomon | 92ce594 | 2017-01-18 11:01:10 -0500 | [diff] [blame] | 19 | class GrXPFactory; |
| 20 | |
Brian Salomon | 91326c3 | 2017-08-09 16:02:19 -0400 | [diff] [blame] | 21 | class GrProcessorSet { |
Brian Salomon | 6d4b65e | 2017-05-03 17:06:09 -0400 | [diff] [blame] | 22 | private: |
| 23 | // Arbitrary constructor arg for empty set and analysis |
| 24 | enum class Empty { kEmpty }; |
| 25 | |
Brian Salomon | 92ce594 | 2017-01-18 11:01:10 -0500 | [diff] [blame] | 26 | public: |
Brian Salomon | 91326c3 | 2017-08-09 16:02:19 -0400 | [diff] [blame] | 27 | GrProcessorSet(GrPaint&&); |
| 28 | GrProcessorSet(SkBlendMode); |
Brian Salomon | aff329b | 2017-08-11 09:40:37 -0400 | [diff] [blame] | 29 | GrProcessorSet(std::unique_ptr<GrFragmentProcessor> colorFP); |
Brian Salomon | 91326c3 | 2017-08-09 16:02:19 -0400 | [diff] [blame] | 30 | GrProcessorSet(GrProcessorSet&&); |
| 31 | GrProcessorSet(const GrProcessorSet&) = delete; |
| 32 | GrProcessorSet& operator=(const GrProcessorSet&) = delete; |
Brian Salomon | 92ce594 | 2017-01-18 11:01:10 -0500 | [diff] [blame] | 33 | |
Brian Salomon | 54d212e | 2017-03-21 14:22:38 -0400 | [diff] [blame] | 34 | ~GrProcessorSet(); |
| 35 | |
John Stiles | 29d3e22 | 2020-07-21 17:28:12 -0400 | [diff] [blame] | 36 | bool hasColorFragmentProcessor() const { return fColorFragmentProcessor != nullptr; } |
| 37 | bool hasCoverageFragmentProcessor() const { return fCoverageFragmentProcessor != nullptr; } |
Brian Salomon | 92ce594 | 2017-01-18 11:01:10 -0500 | [diff] [blame] | 38 | |
John Stiles | 29d3e22 | 2020-07-21 17:28:12 -0400 | [diff] [blame] | 39 | const GrFragmentProcessor* colorFragmentProcessor() const { |
| 40 | return fColorFragmentProcessor.get(); |
Brian Salomon | 92ce594 | 2017-01-18 11:01:10 -0500 | [diff] [blame] | 41 | } |
John Stiles | 29d3e22 | 2020-07-21 17:28:12 -0400 | [diff] [blame] | 42 | const GrFragmentProcessor* coverageFragmentProcessor() const { |
| 43 | return fCoverageFragmentProcessor.get(); |
Brian Salomon | 92ce594 | 2017-01-18 11:01:10 -0500 | [diff] [blame] | 44 | } |
| 45 | |
Chris Dalton | 2224100 | 2021-02-04 09:47:40 -0700 | [diff] [blame] | 46 | bool usesVaryingCoords() const { |
| 47 | return (fColorFragmentProcessor && fColorFragmentProcessor->usesVaryingCoords()) || |
| 48 | (fCoverageFragmentProcessor && fCoverageFragmentProcessor->usesVaryingCoords()); |
| 49 | } |
| 50 | |
Brian Salomon | 48d1b4c | 2017-04-08 07:38:53 -0400 | [diff] [blame] | 51 | const GrXferProcessor* xferProcessor() const { |
| 52 | SkASSERT(this->isFinalized()); |
| 53 | return fXP.fProcessor; |
| 54 | } |
Brian Salomon | d61c9d9 | 2017-04-10 10:54:25 -0400 | [diff] [blame] | 55 | sk_sp<const GrXferProcessor> refXferProcessor() const { |
| 56 | SkASSERT(this->isFinalized()); |
| 57 | return sk_ref_sp(fXP.fProcessor); |
| 58 | } |
Brian Salomon | 92ce594 | 2017-01-18 11:01:10 -0500 | [diff] [blame] | 59 | |
John Stiles | d3feb6f | 2020-07-23 18:18:12 -0400 | [diff] [blame] | 60 | std::unique_ptr<GrFragmentProcessor> detachColorFragmentProcessor() { |
John Stiles | 29d3e22 | 2020-07-21 17:28:12 -0400 | [diff] [blame] | 61 | return std::move(fColorFragmentProcessor); |
Brian Salomon | aff329b | 2017-08-11 09:40:37 -0400 | [diff] [blame] | 62 | } |
| 63 | |
John Stiles | d3feb6f | 2020-07-23 18:18:12 -0400 | [diff] [blame] | 64 | std::unique_ptr<GrFragmentProcessor> detachCoverageFragmentProcessor() { |
John Stiles | 29d3e22 | 2020-07-21 17:28:12 -0400 | [diff] [blame] | 65 | return std::move(fCoverageFragmentProcessor); |
Brian Salomon | aff329b | 2017-08-11 09:40:37 -0400 | [diff] [blame] | 66 | } |
| 67 | |
Brian Salomon | 48d1b4c | 2017-04-08 07:38:53 -0400 | [diff] [blame] | 68 | /** Comparisons are only legal on finalized processor sets. */ |
Brian Salomon | 54d212e | 2017-03-21 14:22:38 -0400 | [diff] [blame] | 69 | bool operator==(const GrProcessorSet& that) const; |
| 70 | bool operator!=(const GrProcessorSet& that) const { return !(*this == that); } |
| 71 | |
Brian Salomon | 5298dc8 | 2017-02-22 11:52:03 -0500 | [diff] [blame] | 72 | /** |
Brian Salomon | 48d1b4c | 2017-04-08 07:38:53 -0400 | [diff] [blame] | 73 | * This is used to report results of processor analysis when a processor set is finalized (see |
| 74 | * below). |
Brian Salomon | 5298dc8 | 2017-02-22 11:52:03 -0500 | [diff] [blame] | 75 | */ |
Brian Salomon | a811b12 | 2017-03-30 08:21:32 -0400 | [diff] [blame] | 76 | class Analysis { |
Brian Salomon | 5298dc8 | 2017-02-22 11:52:03 -0500 | [diff] [blame] | 77 | public: |
Brian Salomon | 48d1b4c | 2017-04-08 07:38:53 -0400 | [diff] [blame] | 78 | Analysis(const Analysis&) = default; |
| 79 | Analysis() { *reinterpret_cast<uint32_t*>(this) = 0; } |
Brian Salomon | 8d2f90b | 2017-03-13 09:11:58 -0400 | [diff] [blame] | 80 | |
Brian Salomon | 48d1b4c | 2017-04-08 07:38:53 -0400 | [diff] [blame] | 81 | bool isInitialized() const { return fIsInitialized; } |
Brian Salomon | bfafcba | 2017-03-02 08:49:19 -0500 | [diff] [blame] | 82 | bool usesLocalCoords() const { return fUsesLocalCoords; } |
Brian Salomon | 3185384 | 2017-03-28 16:32:05 -0400 | [diff] [blame] | 83 | bool requiresDstTexture() const { return fRequiresDstTexture; } |
Chris Dalton | 945ee65 | 2019-01-23 09:10:36 -0700 | [diff] [blame] | 84 | bool requiresNonOverlappingDraws() const { return fRequiresNonOverlappingDraws; } |
Brian Salomon | 5298dc8 | 2017-02-22 11:52:03 -0500 | [diff] [blame] | 85 | bool isCompatibleWithCoverageAsAlpha() const { return fCompatibleWithCoverageAsAlpha; } |
Brian Salomon | 41f9c3c | 2019-03-25 11:06:12 -0400 | [diff] [blame] | 86 | // Indicates whether all color fragment processors were eliminated in the analysis. |
| 87 | bool hasColorFragmentProcessor() const { return fHasColorFragmentProcessor; } |
Brian Salomon | 48d1b4c | 2017-04-08 07:38:53 -0400 | [diff] [blame] | 88 | |
| 89 | bool inputColorIsIgnored() const { return fInputColorType == kIgnored_InputColorType; } |
| 90 | bool inputColorIsOverridden() const { |
| 91 | return fInputColorType == kOverridden_InputColorType; |
Brian Salomon | c0b642c | 2017-03-27 13:09:36 -0400 | [diff] [blame] | 92 | } |
Greg Daniel | 9a18b08 | 2020-08-14 14:03:50 -0400 | [diff] [blame] | 93 | bool usesNonCoherentHWBlending() const { return fUsesNonCoherentHWBlending; } |
Chris Dalton | f2fb80f | 2020-12-03 12:37:59 -0700 | [diff] [blame] | 94 | bool unaffectedByDstValue() const { return fUnaffectedByDstValue; } |
Brian Salomon | 5298dc8 | 2017-02-22 11:52:03 -0500 | [diff] [blame] | 95 | |
| 96 | private: |
Brian Salomon | 6d4b65e | 2017-05-03 17:06:09 -0400 | [diff] [blame] | 97 | constexpr Analysis(Empty) |
| 98 | : fUsesLocalCoords(false) |
| 99 | , fCompatibleWithCoverageAsAlpha(true) |
| 100 | , fRequiresDstTexture(false) |
Chris Dalton | 945ee65 | 2019-01-23 09:10:36 -0700 | [diff] [blame] | 101 | , fRequiresNonOverlappingDraws(false) |
Brian Salomon | 41f9c3c | 2019-03-25 11:06:12 -0400 | [diff] [blame] | 102 | , fHasColorFragmentProcessor(false) |
Brian Salomon | 6d4b65e | 2017-05-03 17:06:09 -0400 | [diff] [blame] | 103 | , fIsInitialized(true) |
Greg Daniel | 9a18b08 | 2020-08-14 14:03:50 -0400 | [diff] [blame] | 104 | , fUsesNonCoherentHWBlending(false) |
Chris Dalton | f2fb80f | 2020-12-03 12:37:59 -0700 | [diff] [blame] | 105 | , fUnaffectedByDstValue(false) |
Brian Salomon | 6d4b65e | 2017-05-03 17:06:09 -0400 | [diff] [blame] | 106 | , fInputColorType(kOriginal_InputColorType) {} |
Brian Salomon | 48d1b4c | 2017-04-08 07:38:53 -0400 | [diff] [blame] | 107 | enum InputColorType : uint32_t { |
| 108 | kOriginal_InputColorType, |
| 109 | kOverridden_InputColorType, |
| 110 | kIgnored_InputColorType |
| 111 | }; |
Brian Salomon | 5298dc8 | 2017-02-22 11:52:03 -0500 | [diff] [blame] | 112 | |
Brian Salomon | 48d1b4c | 2017-04-08 07:38:53 -0400 | [diff] [blame] | 113 | // MSVS 2015 won't pack different underlying types |
| 114 | using PackedBool = uint32_t; |
| 115 | using PackedInputColorType = uint32_t; |
Brian Salomon | 5298dc8 | 2017-02-22 11:52:03 -0500 | [diff] [blame] | 116 | |
Brian Salomon | 8d2f90b | 2017-03-13 09:11:58 -0400 | [diff] [blame] | 117 | PackedBool fUsesLocalCoords : 1; |
| 118 | PackedBool fCompatibleWithCoverageAsAlpha : 1; |
Brian Salomon | 3185384 | 2017-03-28 16:32:05 -0400 | [diff] [blame] | 119 | PackedBool fRequiresDstTexture : 1; |
Chris Dalton | 945ee65 | 2019-01-23 09:10:36 -0700 | [diff] [blame] | 120 | PackedBool fRequiresNonOverlappingDraws : 1; |
Brian Salomon | 41f9c3c | 2019-03-25 11:06:12 -0400 | [diff] [blame] | 121 | PackedBool fHasColorFragmentProcessor : 1; |
Brian Salomon | 48d1b4c | 2017-04-08 07:38:53 -0400 | [diff] [blame] | 122 | PackedBool fIsInitialized : 1; |
Greg Daniel | 9a18b08 | 2020-08-14 14:03:50 -0400 | [diff] [blame] | 123 | PackedBool fUsesNonCoherentHWBlending : 1; |
Chris Dalton | f2fb80f | 2020-12-03 12:37:59 -0700 | [diff] [blame] | 124 | PackedBool fUnaffectedByDstValue : 1; |
Brian Salomon | 48d1b4c | 2017-04-08 07:38:53 -0400 | [diff] [blame] | 125 | PackedInputColorType fInputColorType : 2; |
Brian Salomon | 70288c0 | 2017-03-24 12:27:17 -0400 | [diff] [blame] | 126 | |
| 127 | friend class GrProcessorSet; |
Brian Salomon | 5298dc8 | 2017-02-22 11:52:03 -0500 | [diff] [blame] | 128 | }; |
Brian Salomon | 4dea72a | 2019-12-18 10:43:10 -0500 | [diff] [blame] | 129 | static_assert(sizeof(Analysis) <= sizeof(uint32_t)); |
Brian Salomon | 5298dc8 | 2017-02-22 11:52:03 -0500 | [diff] [blame] | 130 | |
Brian Salomon | 48d1b4c | 2017-04-08 07:38:53 -0400 | [diff] [blame] | 131 | /** |
| 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 Dalton | 133944a | 2018-11-16 23:30:29 -0500 | [diff] [blame] | 135 | * indicated by the returned Analysis's inputColorIsOverridden(). 'inputColorOverride' will not |
Brian Salomon | 48d1b4c | 2017-04-08 07:38:53 -0400 | [diff] [blame] | 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 | */ |
Chris Dalton | 6ce447a | 2019-06-23 18:07:38 -0600 | [diff] [blame] | 145 | Analysis finalize( |
| 146 | const GrProcessorAnalysisColor&, const GrProcessorAnalysisCoverage, |
| 147 | const GrAppliedClip*, const GrUserStencilSettings*, bool hasMixedSampledCoverage, |
| 148 | const GrCaps&, GrClampType, SkPMColor4f* inputColorOverride); |
Brian Salomon | 48d1b4c | 2017-04-08 07:38:53 -0400 | [diff] [blame] | 149 | |
| 150 | bool isFinalized() const { return SkToBool(kFinalized_Flag & fFlags); } |
Brian Salomon | 70288c0 | 2017-03-24 12:27:17 -0400 | [diff] [blame] | 151 | |
Brian Salomon | 44acb5b | 2017-07-18 19:59:24 -0400 | [diff] [blame] | 152 | /** These are valid only for non-LCD coverage. */ |
Brian Salomon | 292bf7a | 2017-05-17 09:43:55 -0400 | [diff] [blame] | 153 | static const GrProcessorSet& EmptySet(); |
Brian Salomon | 91326c3 | 2017-08-09 16:02:19 -0400 | [diff] [blame] | 154 | static GrProcessorSet MakeEmptySet(); |
John Stiles | ec9b4aa | 2020-08-07 13:05:14 -0400 | [diff] [blame] | 155 | static constexpr Analysis EmptySetAnalysis() { return Analysis(Empty::kEmpty); } |
Brian Salomon | 6d4b65e | 2017-05-03 17:06:09 -0400 | [diff] [blame] | 156 | |
John Stiles | 8d9bf64 | 2020-08-12 15:07:45 -0400 | [diff] [blame] | 157 | #if GR_TEST_UTILS |
Brian Salomon | 82dfd3d | 2017-06-14 12:30:35 -0400 | [diff] [blame] | 158 | SkString dumpProcessors() const; |
Brian Osman | 9a390ac | 2018-11-12 09:47:48 -0500 | [diff] [blame] | 159 | #endif |
Brian Salomon | 82dfd3d | 2017-06-14 12:30:35 -0400 | [diff] [blame] | 160 | |
Brian Salomon | c241b58 | 2019-11-27 08:57:17 -0500 | [diff] [blame] | 161 | void visitProxies(const GrOp::VisitProxyFunc& func) const; |
Robert Phillips | b493eeb | 2017-09-13 13:10:52 -0400 | [diff] [blame] | 162 | |
Brian Salomon | 92ce594 | 2017-01-18 11:01:10 -0500 | [diff] [blame] | 163 | private: |
Brian Salomon | 6d4b65e | 2017-05-03 17:06:09 -0400 | [diff] [blame] | 164 | GrProcessorSet(Empty) : fXP((const GrXferProcessor*)nullptr), fFlags(kFinalized_Flag) {} |
Brian Salomon | 6d4b65e | 2017-05-03 17:06:09 -0400 | [diff] [blame] | 165 | |
Robert Phillips | b493eeb | 2017-09-13 13:10:52 -0400 | [diff] [blame] | 166 | int numFragmentProcessors() const { |
John Stiles | 29d3e22 | 2020-07-21 17:28:12 -0400 | [diff] [blame] | 167 | return (fColorFragmentProcessor ? 1 : 0) + (fCoverageFragmentProcessor ? 1 : 0); |
Robert Phillips | b493eeb | 2017-09-13 13:10:52 -0400 | [diff] [blame] | 168 | } |
| 169 | |
Brian Salomon | e23bffd | 2017-06-02 11:01:10 -0400 | [diff] [blame] | 170 | enum Flags : uint16_t { kFinalized_Flag = 0x1 }; |
Brian Salomon | 8d2f90b | 2017-03-13 09:11:58 -0400 | [diff] [blame] | 171 | |
Brian Salomon | 48d1b4c | 2017-04-08 07:38:53 -0400 | [diff] [blame] | 172 | union XP { |
| 173 | XP(const GrXPFactory* factory) : fFactory(factory) {} |
Brian Salomon | 6d4b65e | 2017-05-03 17:06:09 -0400 | [diff] [blame] | 174 | XP(const GrXferProcessor* processor) : fProcessor(processor) {} |
Brian Salomon | 91326c3 | 2017-08-09 16:02:19 -0400 | [diff] [blame] | 175 | explicit XP(XP&& that) : fProcessor(that.fProcessor) { |
| 176 | SkASSERT(fProcessor == that.fProcessor); |
| 177 | that.fProcessor = nullptr; |
| 178 | } |
Brian Salomon | 48d1b4c | 2017-04-08 07:38:53 -0400 | [diff] [blame] | 179 | 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 Stiles | 29d3e22 | 2020-07-21 17:28:12 -0400 | [diff] [blame] | 188 | std::unique_ptr<GrFragmentProcessor> fColorFragmentProcessor; |
| 189 | std::unique_ptr<GrFragmentProcessor> fCoverageFragmentProcessor; |
Brian Salomon | 48d1b4c | 2017-04-08 07:38:53 -0400 | [diff] [blame] | 190 | XP fXP; |
John Stiles | 29d3e22 | 2020-07-21 17:28:12 -0400 | [diff] [blame] | 191 | uint8_t fFlags = 0; |
Brian Salomon | 92ce594 | 2017-01-18 11:01:10 -0500 | [diff] [blame] | 192 | }; |
| 193 | |
| 194 | #endif |