GrSimpleMeshDrawOpHelper.h 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  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 GrSimpleMeshDrawOpHelper_DEFINED
  8. #define GrSimpleMeshDrawOpHelper_DEFINED
  9. #include "include/private/GrRecordingContext.h"
  10. #include "src/gpu/GrMemoryPool.h"
  11. #include "src/gpu/GrOpFlushState.h"
  12. #include "src/gpu/GrPipeline.h"
  13. #include "src/gpu/GrRecordingContextPriv.h"
  14. #include "src/gpu/ops/GrMeshDrawOp.h"
  15. #include <new>
  16. struct SkRect;
  17. /**
  18. * This class can be used to help implement simple mesh draw ops. It reduces the amount of
  19. * boilerplate code to type and also provides a mechanism for optionally allocating space for a
  20. * GrProcessorSet based on a GrPaint. It is intended to be used by ops that construct a single
  21. * GrPipeline for a uniform primitive color and a GrPaint.
  22. */
  23. class GrSimpleMeshDrawOpHelper {
  24. public:
  25. struct MakeArgs;
  26. /**
  27. * This can be used by a Op class to perform allocation and initialization such that a
  28. * GrProcessorSet (if required) is allocated as part of the the same allocation that as
  29. * the Op instance. It requires that Op implements a constructor of the form:
  30. * Op(MakeArgs, GrColor, OpArgs...)
  31. * which is public or made accessible via 'friend'.
  32. */
  33. template <typename Op, typename... OpArgs>
  34. static std::unique_ptr<GrDrawOp> FactoryHelper(GrRecordingContext*, GrPaint&&, OpArgs...);
  35. // Here we allow callers to specify a subset of the GrPipeline::InputFlags upon creation.
  36. enum class InputFlags : uint8_t {
  37. kNone = 0,
  38. kSnapVerticesToPixelCenters = (uint8_t)GrPipeline::InputFlags::kSnapVerticesToPixelCenters,
  39. };
  40. GR_DECL_BITFIELD_CLASS_OPS_FRIENDS(InputFlags);
  41. GrSimpleMeshDrawOpHelper(const MakeArgs&, GrAAType, InputFlags = InputFlags::kNone);
  42. ~GrSimpleMeshDrawOpHelper();
  43. GrSimpleMeshDrawOpHelper() = delete;
  44. GrSimpleMeshDrawOpHelper(const GrSimpleMeshDrawOpHelper&) = delete;
  45. GrSimpleMeshDrawOpHelper& operator=(const GrSimpleMeshDrawOpHelper&) = delete;
  46. GrDrawOp::FixedFunctionFlags fixedFunctionFlags() const;
  47. // noneAACompatibleWithCoverage should be set to true if the op can properly render a non-AA
  48. // primitive merged into a coverage-based op.
  49. bool isCompatible(const GrSimpleMeshDrawOpHelper& that, const GrCaps&, const SkRect& thisBounds,
  50. const SkRect& thatBounds, bool noneAACompatibleWithCoverage = false) const;
  51. /**
  52. * Finalizes the processor set and determines whether the destination must be provided
  53. * to the fragment shader as a texture for blending.
  54. *
  55. * @param geometryCoverage Describes the coverage output of the op's geometry processor
  56. * @param geometryColor An in/out param. As input this informs processor analysis about the
  57. * color the op expects to output from its geometry processor. As output
  58. * this may be set to a known color in which case the op must output this
  59. * color from its geometry processor instead.
  60. */
  61. GrProcessorSet::Analysis finalizeProcessors(
  62. const GrCaps& caps, const GrAppliedClip* clip, bool hasMixedSampledCoverage,
  63. GrClampType clampType, GrProcessorAnalysisCoverage geometryCoverage,
  64. GrProcessorAnalysisColor* geometryColor) {
  65. return this->finalizeProcessors(
  66. caps, clip, &GrUserStencilSettings::kUnused, hasMixedSampledCoverage, clampType,
  67. geometryCoverage, geometryColor);
  68. }
  69. /**
  70. * Version of above that can be used by ops that have a constant color geometry processor
  71. * output. The op passes this color as 'geometryColor' and after return if 'geometryColor' has
  72. * changed the op must override its geometry processor color output with the new color.
  73. */
  74. GrProcessorSet::Analysis finalizeProcessors(
  75. const GrCaps&, const GrAppliedClip*, bool hasMixedSampledCoverage, GrClampType,
  76. GrProcessorAnalysisCoverage geometryCoverage, SkPMColor4f* geometryColor,
  77. bool* wideColor);
  78. bool isTrivial() const {
  79. return fProcessors == nullptr;
  80. }
  81. bool usesLocalCoords() const {
  82. SkASSERT(fDidAnalysis);
  83. return fUsesLocalCoords;
  84. }
  85. bool compatibleWithCoverageAsAlpha() const { return fCompatibleWithCoverageAsAlpha; }
  86. struct MakeArgs {
  87. private:
  88. MakeArgs() = default;
  89. GrProcessorSet* fProcessorSet;
  90. friend class GrSimpleMeshDrawOpHelper;
  91. };
  92. void visitProxies(const GrOp::VisitProxyFunc& func) const {
  93. if (fProcessors) {
  94. fProcessors->visitProxies(func);
  95. }
  96. }
  97. #ifdef SK_DEBUG
  98. SkString dumpInfo() const;
  99. #endif
  100. GrAAType aaType() const { return static_cast<GrAAType>(fAAType); }
  101. void setAAType(GrAAType aaType) {
  102. fAAType = static_cast<unsigned>(aaType);
  103. }
  104. void executeDrawsAndUploads(const GrOp*, GrOpFlushState*, const SkRect& chainBounds);
  105. protected:
  106. GrPipeline::InputFlags pipelineFlags() const { return fPipelineFlags; }
  107. GrProcessorSet::Analysis finalizeProcessors(
  108. const GrCaps& caps, const GrAppliedClip*, const GrUserStencilSettings*,
  109. bool hasMixedSampledCoverage, GrClampType, GrProcessorAnalysisCoverage geometryCoverage,
  110. GrProcessorAnalysisColor* geometryColor);
  111. GrProcessorSet* fProcessors;
  112. GrPipeline::InputFlags fPipelineFlags;
  113. unsigned fAAType : 2;
  114. unsigned fUsesLocalCoords : 1;
  115. unsigned fCompatibleWithCoverageAsAlpha : 1;
  116. SkDEBUGCODE(unsigned fMadePipeline : 1;)
  117. SkDEBUGCODE(unsigned fDidAnalysis : 1;)
  118. };
  119. /**
  120. * This class extends GrSimpleMeshDrawOpHelper to support an optional GrUserStencilSettings. This
  121. * uses private inheritance because it non-virtually overrides methods in the base class and should
  122. * never be used with a GrSimpleMeshDrawOpHelper pointer or reference.
  123. */
  124. class GrSimpleMeshDrawOpHelperWithStencil : private GrSimpleMeshDrawOpHelper {
  125. public:
  126. using MakeArgs = GrSimpleMeshDrawOpHelper::MakeArgs;
  127. using InputFlags = GrSimpleMeshDrawOpHelper::InputFlags;
  128. using GrSimpleMeshDrawOpHelper::visitProxies;
  129. // using declarations can't be templated, so this is a pass through function instead.
  130. template <typename Op, typename... OpArgs>
  131. static std::unique_ptr<GrDrawOp> FactoryHelper(GrRecordingContext* context, GrPaint&& paint,
  132. OpArgs... opArgs) {
  133. return GrSimpleMeshDrawOpHelper::FactoryHelper<Op, OpArgs...>(
  134. context, std::move(paint), std::forward<OpArgs>(opArgs)...);
  135. }
  136. GrSimpleMeshDrawOpHelperWithStencil(const MakeArgs&, GrAAType, const GrUserStencilSettings*,
  137. InputFlags = InputFlags::kNone);
  138. GrDrawOp::FixedFunctionFlags fixedFunctionFlags() const;
  139. GrProcessorSet::Analysis finalizeProcessors(
  140. const GrCaps& caps, const GrAppliedClip* clip, bool hasMixedSampledCoverage,
  141. GrClampType clampType, GrProcessorAnalysisCoverage geometryCoverage,
  142. GrProcessorAnalysisColor* geometryColor) {
  143. return this->INHERITED::finalizeProcessors(
  144. caps, clip, fStencilSettings, hasMixedSampledCoverage, clampType, geometryCoverage,
  145. geometryColor);
  146. }
  147. GrProcessorSet::Analysis finalizeProcessors(
  148. const GrCaps&, const GrAppliedClip*, bool hasMixedSampledCoverage, GrClampType,
  149. GrProcessorAnalysisCoverage geometryCoverage, SkPMColor4f* geometryColor, bool*
  150. wideColor);
  151. using GrSimpleMeshDrawOpHelper::aaType;
  152. using GrSimpleMeshDrawOpHelper::setAAType;
  153. using GrSimpleMeshDrawOpHelper::isTrivial;
  154. using GrSimpleMeshDrawOpHelper::usesLocalCoords;
  155. using GrSimpleMeshDrawOpHelper::compatibleWithCoverageAsAlpha;
  156. bool isCompatible(const GrSimpleMeshDrawOpHelperWithStencil& that, const GrCaps&,
  157. const SkRect& thisBounds, const SkRect& thatBounds,
  158. bool noneAACompatibleWithCoverage = false) const;
  159. void executeDrawsAndUploads(const GrOp*, GrOpFlushState*, const SkRect& chainBounds);
  160. #ifdef SK_DEBUG
  161. SkString dumpInfo() const;
  162. #endif
  163. private:
  164. const GrUserStencilSettings* fStencilSettings;
  165. typedef GrSimpleMeshDrawOpHelper INHERITED;
  166. };
  167. template <typename Op, typename... OpArgs>
  168. std::unique_ptr<GrDrawOp> GrSimpleMeshDrawOpHelper::FactoryHelper(GrRecordingContext* context,
  169. GrPaint&& paint,
  170. OpArgs... opArgs) {
  171. GrOpMemoryPool* pool = context->priv().opMemoryPool();
  172. MakeArgs makeArgs;
  173. if (paint.isTrivial()) {
  174. makeArgs.fProcessorSet = nullptr;
  175. return pool->allocate<Op>(makeArgs, paint.getColor4f(), std::forward<OpArgs>(opArgs)...);
  176. } else {
  177. char* mem = (char*) pool->allocate(sizeof(Op) + sizeof(GrProcessorSet));
  178. char* setMem = mem + sizeof(Op);
  179. auto color = paint.getColor4f();
  180. makeArgs.fProcessorSet = new (setMem) GrProcessorSet(std::move(paint));
  181. return std::unique_ptr<GrDrawOp>(new (mem) Op(makeArgs, color,
  182. std::forward<OpArgs>(opArgs)...));
  183. }
  184. }
  185. GR_MAKE_BITFIELD_CLASS_OPS(GrSimpleMeshDrawOpHelper::InputFlags)
  186. #endif