GrProcessorAnalysis.h 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. /*
  2. * Copyright 2014 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 GrProcessorAnalysis_DEFINED
  8. #define GrProcessorAnalysis_DEFINED
  9. #include "include/private/SkColorData.h"
  10. class GrDrawOp;
  11. class GrFragmentProcessor;
  12. class GrProcessorAnalysisColor {
  13. public:
  14. enum class Opaque {
  15. kNo,
  16. kYes,
  17. };
  18. constexpr GrProcessorAnalysisColor(Opaque opaque = Opaque::kNo)
  19. : fFlags(opaque == Opaque::kYes ? kIsOpaque_Flag : 0)
  20. , fColor(SK_PMColor4fTRANSPARENT) {}
  21. GrProcessorAnalysisColor(const SkPMColor4f& color) { this->setToConstant(color); }
  22. void setToConstant(const SkPMColor4f& color) {
  23. fColor = color;
  24. if (color.isOpaque()) {
  25. fFlags = kColorIsKnown_Flag | kIsOpaque_Flag;
  26. } else {
  27. fFlags = kColorIsKnown_Flag;
  28. }
  29. }
  30. void setToUnknown() { fFlags = 0; }
  31. void setToUnknownOpaque() { fFlags = kIsOpaque_Flag; }
  32. bool isUnknown() const { return SkToBool(fFlags == 0); }
  33. bool isOpaque() const { return SkToBool(kIsOpaque_Flag & fFlags); }
  34. bool isConstant(SkPMColor4f* color = nullptr) const {
  35. if (kColorIsKnown_Flag & fFlags) {
  36. if (color) {
  37. *color = fColor;
  38. }
  39. return true;
  40. }
  41. return false;
  42. }
  43. bool operator==(const GrProcessorAnalysisColor& that) const {
  44. if (fFlags != that.fFlags) {
  45. return false;
  46. }
  47. return (kColorIsKnown_Flag & fFlags) ? fColor == that.fColor : true;
  48. }
  49. /** The returned value reflects the common properties of the two inputs. */
  50. static GrProcessorAnalysisColor Combine(const GrProcessorAnalysisColor& a,
  51. const GrProcessorAnalysisColor& b) {
  52. GrProcessorAnalysisColor result;
  53. uint32_t commonFlags = a.fFlags & b.fFlags;
  54. if ((kColorIsKnown_Flag & commonFlags) && a.fColor == b.fColor) {
  55. result.fColor = a.fColor;
  56. result.fFlags = a.fFlags;
  57. } else if (kIsOpaque_Flag & commonFlags) {
  58. result.fFlags = kIsOpaque_Flag;
  59. }
  60. return result;
  61. }
  62. private:
  63. enum Flags {
  64. kColorIsKnown_Flag = 0x1,
  65. kIsOpaque_Flag = 0x2,
  66. };
  67. uint32_t fFlags;
  68. SkPMColor4f fColor;
  69. };
  70. enum class GrProcessorAnalysisCoverage { kNone, kSingleChannel, kLCD };
  71. /**
  72. * GrColorFragmentProcessorAnalysis gathers invariant data from a set of color fragment processor.
  73. * It is used to recognize optimizations that can simplify the generated shader or make blending
  74. * more effecient.
  75. */
  76. class GrColorFragmentProcessorAnalysis {
  77. public:
  78. GrColorFragmentProcessorAnalysis() = delete;
  79. GrColorFragmentProcessorAnalysis(const GrProcessorAnalysisColor& input,
  80. const GrFragmentProcessor* const* processors,
  81. int cnt);
  82. bool isOpaque() const { return fIsOpaque; }
  83. /**
  84. * Are all the fragment processors compatible with conflating coverage with color prior to the
  85. * the first fragment processor. This result assumes that processors that should be eliminated
  86. * as indicated by initialProcessorsToEliminate() are in fact eliminated.
  87. */
  88. bool allProcessorsCompatibleWithCoverageAsAlpha() const {
  89. return fCompatibleWithCoverageAsAlpha;
  90. }
  91. /**
  92. * Do any of the fragment processors require local coords. This result assumes that
  93. * processors that should be eliminated as indicated by initialProcessorsToEliminate() are in
  94. * fact eliminated.
  95. */
  96. bool usesLocalCoords() const { return fUsesLocalCoords; }
  97. /**
  98. * If we detected that the result after the first N processors is a known color then we
  99. * eliminate those N processors and replace the GrDrawOp's color input to the GrPipeline with
  100. * the known output of the Nth processor, so that the Nth+1 fragment processor (or the XP if
  101. * there are only N processors) sees its expected input. If this returns 0 then there are no
  102. * processors to eliminate.
  103. */
  104. int initialProcessorsToEliminate(SkPMColor4f* newPipelineInputColor) const {
  105. if (fProcessorsToEliminate > 0) {
  106. *newPipelineInputColor = fLastKnownOutputColor;
  107. }
  108. return fProcessorsToEliminate;
  109. }
  110. /**
  111. * Provides known information about the last processor's output color.
  112. */
  113. GrProcessorAnalysisColor outputColor() const {
  114. if (fKnowOutputColor) {
  115. return fLastKnownOutputColor;
  116. }
  117. return fIsOpaque ? GrProcessorAnalysisColor::Opaque::kYes
  118. : GrProcessorAnalysisColor::Opaque::kNo;
  119. }
  120. private:
  121. bool fIsOpaque;
  122. bool fCompatibleWithCoverageAsAlpha;
  123. bool fUsesLocalCoords;
  124. bool fKnowOutputColor;
  125. int fProcessorsToEliminate;
  126. SkPMColor4f fLastKnownOutputColor;
  127. };
  128. #endif