GrProcessorSet.h 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  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. #ifndef GrProcessorSet_DEFINED
  8. #define GrProcessorSet_DEFINED
  9. #include "include/private/SkTemplates.h"
  10. #include "src/gpu/GrFragmentProcessor.h"
  11. #include "src/gpu/GrPaint.h"
  12. #include "src/gpu/GrProcessorAnalysis.h"
  13. #include "src/gpu/GrXferProcessor.h"
  14. struct GrUserStencilSettings;
  15. class GrAppliedClip;
  16. class GrXPFactory;
  17. class GrProcessorSet {
  18. private:
  19. // Arbitrary constructor arg for empty set and analysis
  20. enum class Empty { kEmpty };
  21. public:
  22. GrProcessorSet(GrPaint&&);
  23. GrProcessorSet(SkBlendMode);
  24. GrProcessorSet(std::unique_ptr<GrFragmentProcessor> colorFP);
  25. GrProcessorSet(GrProcessorSet&&);
  26. GrProcessorSet(const GrProcessorSet&) = delete;
  27. GrProcessorSet& operator=(const GrProcessorSet&) = delete;
  28. ~GrProcessorSet();
  29. int numColorFragmentProcessors() const { return fColorFragmentProcessorCnt; }
  30. int numCoverageFragmentProcessors() const {
  31. return this->numFragmentProcessors() - fColorFragmentProcessorCnt;
  32. }
  33. const GrFragmentProcessor* colorFragmentProcessor(int idx) const {
  34. SkASSERT(idx < fColorFragmentProcessorCnt);
  35. return fFragmentProcessors[idx + fFragmentProcessorOffset].get();
  36. }
  37. const GrFragmentProcessor* coverageFragmentProcessor(int idx) const {
  38. return fFragmentProcessors[idx + fColorFragmentProcessorCnt +
  39. fFragmentProcessorOffset].get();
  40. }
  41. const GrXferProcessor* xferProcessor() const {
  42. SkASSERT(this->isFinalized());
  43. return fXP.fProcessor;
  44. }
  45. sk_sp<const GrXferProcessor> refXferProcessor() const {
  46. SkASSERT(this->isFinalized());
  47. return sk_ref_sp(fXP.fProcessor);
  48. }
  49. std::unique_ptr<const GrFragmentProcessor> detachColorFragmentProcessor(int idx) {
  50. SkASSERT(idx < fColorFragmentProcessorCnt);
  51. return std::move(fFragmentProcessors[idx + fFragmentProcessorOffset]);
  52. }
  53. std::unique_ptr<const GrFragmentProcessor> detachCoverageFragmentProcessor(int idx) {
  54. return std::move(
  55. fFragmentProcessors[idx + fFragmentProcessorOffset + fColorFragmentProcessorCnt]);
  56. }
  57. /** Comparisons are only legal on finalized processor sets. */
  58. bool operator==(const GrProcessorSet& that) const;
  59. bool operator!=(const GrProcessorSet& that) const { return !(*this == that); }
  60. /**
  61. * This is used to report results of processor analysis when a processor set is finalized (see
  62. * below).
  63. */
  64. class Analysis {
  65. public:
  66. Analysis(const Analysis&) = default;
  67. Analysis() { *reinterpret_cast<uint32_t*>(this) = 0; }
  68. bool isInitialized() const { return fIsInitialized; }
  69. bool usesLocalCoords() const { return fUsesLocalCoords; }
  70. bool requiresDstTexture() const { return fRequiresDstTexture; }
  71. bool requiresNonOverlappingDraws() const { return fRequiresNonOverlappingDraws; }
  72. bool isCompatibleWithCoverageAsAlpha() const { return fCompatibleWithCoverageAsAlpha; }
  73. // Indicates whether all color fragment processors were eliminated in the analysis.
  74. bool hasColorFragmentProcessor() const { return fHasColorFragmentProcessor; }
  75. bool inputColorIsIgnored() const { return fInputColorType == kIgnored_InputColorType; }
  76. bool inputColorIsOverridden() const {
  77. return fInputColorType == kOverridden_InputColorType;
  78. }
  79. private:
  80. constexpr Analysis(Empty)
  81. : fUsesLocalCoords(false)
  82. , fCompatibleWithCoverageAsAlpha(true)
  83. , fRequiresDstTexture(false)
  84. , fRequiresNonOverlappingDraws(false)
  85. , fHasColorFragmentProcessor(false)
  86. , fIsInitialized(true)
  87. , fInputColorType(kOriginal_InputColorType) {}
  88. enum InputColorType : uint32_t {
  89. kOriginal_InputColorType,
  90. kOverridden_InputColorType,
  91. kIgnored_InputColorType
  92. };
  93. // MSVS 2015 won't pack different underlying types
  94. using PackedBool = uint32_t;
  95. using PackedInputColorType = uint32_t;
  96. PackedBool fUsesLocalCoords : 1;
  97. PackedBool fCompatibleWithCoverageAsAlpha : 1;
  98. PackedBool fRequiresDstTexture : 1;
  99. PackedBool fRequiresNonOverlappingDraws : 1;
  100. PackedBool fHasColorFragmentProcessor : 1;
  101. PackedBool fIsInitialized : 1;
  102. PackedInputColorType fInputColorType : 2;
  103. friend class GrProcessorSet;
  104. };
  105. GR_STATIC_ASSERT(sizeof(Analysis) <= sizeof(uint32_t));
  106. /**
  107. * This analyzes the processors given an op's input color and coverage as well as a clip. The
  108. * state of the processor set may change to an equivalent but more optimal set of processors.
  109. * This new state requires that the caller respect the returned 'inputColorOverride'. This is
  110. * indicated by the returned Analysis's inputColorIsOverridden(). 'inputColorOverride' will not
  111. * be written if the analysis does not override the input color.
  112. *
  113. * This must be called before the processor set is used to construct a GrPipeline and may only
  114. * be called once.
  115. *
  116. * This also puts the processors in "pending execution" state and must be called when an op
  117. * that owns a processor set is recorded to ensure pending and writes are propagated to
  118. * resources referred to by the processors. Otherwise, data hazards may occur.
  119. */
  120. Analysis finalize(
  121. const GrProcessorAnalysisColor&, const GrProcessorAnalysisCoverage,
  122. const GrAppliedClip*, const GrUserStencilSettings*, bool hasMixedSampledCoverage,
  123. const GrCaps&, GrClampType, SkPMColor4f* inputColorOverride);
  124. bool isFinalized() const { return SkToBool(kFinalized_Flag & fFlags); }
  125. /** These are valid only for non-LCD coverage. */
  126. static const GrProcessorSet& EmptySet();
  127. static GrProcessorSet MakeEmptySet();
  128. static constexpr const Analysis EmptySetAnalysis() { return Analysis(Empty::kEmpty); }
  129. #ifdef SK_DEBUG
  130. SkString dumpProcessors() const;
  131. #endif
  132. void visitProxies(const GrOp::VisitProxyFunc& func) const {
  133. for (int i = 0; i < this->numFragmentProcessors(); ++i) {
  134. GrFragmentProcessor::TextureAccessIter iter(this->fragmentProcessor(i));
  135. while (const GrFragmentProcessor::TextureSampler* sampler = iter.next()) {
  136. bool mipped = (GrSamplerState::Filter::kMipMap == sampler->samplerState().filter());
  137. func(sampler->proxy(), GrMipMapped(mipped));
  138. }
  139. }
  140. }
  141. private:
  142. GrProcessorSet(Empty) : fXP((const GrXferProcessor*)nullptr), fFlags(kFinalized_Flag) {}
  143. int numFragmentProcessors() const {
  144. return fFragmentProcessors.count() - fFragmentProcessorOffset;
  145. }
  146. const GrFragmentProcessor* fragmentProcessor(int idx) const {
  147. return fFragmentProcessors[idx + fFragmentProcessorOffset].get();
  148. }
  149. // This absurdly large limit allows Analysis and this to pack fields together.
  150. static constexpr int kMaxColorProcessors = UINT8_MAX;
  151. enum Flags : uint16_t { kFinalized_Flag = 0x1 };
  152. union XP {
  153. XP(const GrXPFactory* factory) : fFactory(factory) {}
  154. XP(const GrXferProcessor* processor) : fProcessor(processor) {}
  155. explicit XP(XP&& that) : fProcessor(that.fProcessor) {
  156. SkASSERT(fProcessor == that.fProcessor);
  157. that.fProcessor = nullptr;
  158. }
  159. const GrXPFactory* fFactory;
  160. const GrXferProcessor* fProcessor;
  161. };
  162. const GrXPFactory* xpFactory() const {
  163. SkASSERT(!this->isFinalized());
  164. return fXP.fFactory;
  165. }
  166. SkAutoSTArray<4, std::unique_ptr<const GrFragmentProcessor>> fFragmentProcessors;
  167. XP fXP;
  168. uint8_t fColorFragmentProcessorCnt = 0;
  169. uint8_t fFragmentProcessorOffset = 0;
  170. uint8_t fFlags;
  171. };
  172. #endif