blob: 35bf3cc86fe319b3b10eb6d183fce8192fc1ab36 [file] [log] [blame]
Brian Salomon6d4b65e2017-05-03 17:06:09 -04001/*
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 GrSimpleMeshDrawOpHelper_DEFINED
9#define GrSimpleMeshDrawOpHelper_DEFINED
10
Mike Kleinc0bd9f92019-04-23 12:05:21 -050011#include "include/private/GrRecordingContext.h"
12#include "src/gpu/GrMemoryPool.h"
13#include "src/gpu/GrOpFlushState.h"
14#include "src/gpu/GrPipeline.h"
15#include "src/gpu/GrRecordingContextPriv.h"
16#include "src/gpu/ops/GrMeshDrawOp.h"
Mike Klein79aea6a2018-06-11 10:45:26 -040017#include <new>
Brian Salomonb4d61062017-07-12 11:24:41 -040018
19struct SkRect;
Brian Salomon6d4b65e2017-05-03 17:06:09 -040020
21/**
22 * This class can be used to help implement simple mesh draw ops. It reduces the amount of
23 * boilerplate code to type and also provides a mechanism for optionally allocating space for a
24 * GrProcessorSet based on a GrPaint. It is intended to be used by ops that construct a single
25 * GrPipeline for a uniform primitive color and a GrPaint.
26 */
27class GrSimpleMeshDrawOpHelper {
28public:
29 struct MakeArgs;
30
31 /**
32 * This can be used by a Op class to perform allocation and initialization such that a
Brian Salomonb4d61062017-07-12 11:24:41 -040033 * GrProcessorSet (if required) is allocated as part of the the same allocation that as
34 * the Op instance. It requires that Op implements a constructor of the form:
Brian Salomon6d4b65e2017-05-03 17:06:09 -040035 * Op(MakeArgs, GrColor, OpArgs...)
36 * which is public or made accessible via 'friend'.
37 */
38 template <typename Op, typename... OpArgs>
Robert Phillipsb97da532019-02-12 15:24:12 -050039 static std::unique_ptr<GrDrawOp> FactoryHelper(GrRecordingContext*, GrPaint&&, OpArgs...);
Brian Salomon6d4b65e2017-05-03 17:06:09 -040040
Chris Daltonbaa1b352019-04-03 12:03:00 -060041 // Here we allow callers to specify a subset of the GrPipeline::InputFlags upon creation.
42 enum class InputFlags : uint8_t {
43 kNone = 0,
44 kSnapVerticesToPixelCenters = (uint8_t)GrPipeline::InputFlags::kSnapVerticesToPixelCenters,
Brian Salomonbaaf4392017-06-15 09:59:23 -040045 };
Chris Daltonbaa1b352019-04-03 12:03:00 -060046 GR_DECL_BITFIELD_CLASS_OPS_FRIENDS(InputFlags);
Brian Salomonbaaf4392017-06-15 09:59:23 -040047
Chris Daltonbaa1b352019-04-03 12:03:00 -060048 GrSimpleMeshDrawOpHelper(const MakeArgs&, GrAAType, InputFlags = InputFlags::kNone);
Brian Salomonb4d61062017-07-12 11:24:41 -040049 ~GrSimpleMeshDrawOpHelper();
Brian Salomon6d4b65e2017-05-03 17:06:09 -040050
51 GrSimpleMeshDrawOpHelper() = delete;
52 GrSimpleMeshDrawOpHelper(const GrSimpleMeshDrawOpHelper&) = delete;
53 GrSimpleMeshDrawOpHelper& operator=(const GrSimpleMeshDrawOpHelper&) = delete;
54
Brian Salomonb4d61062017-07-12 11:24:41 -040055 GrDrawOp::FixedFunctionFlags fixedFunctionFlags() const;
Brian Salomon6d4b65e2017-05-03 17:06:09 -040056
Michael Ludwig69858532018-11-28 15:34:34 -050057 // noneAACompatibleWithCoverage should be set to true if the op can properly render a non-AA
58 // primitive merged into a coverage-based op.
Brian Salomonb4d61062017-07-12 11:24:41 -040059 bool isCompatible(const GrSimpleMeshDrawOpHelper& that, const GrCaps&, const SkRect& thisBounds,
Michael Ludwig69858532018-11-28 15:34:34 -050060 const SkRect& thatBounds, bool noneAACompatibleWithCoverage = false) const;
Brian Salomon6d4b65e2017-05-03 17:06:09 -040061
Brian Salomon0088f942017-07-12 11:51:27 -040062 /**
63 * Finalizes the processor set and determines whether the destination must be provided
64 * to the fragment shader as a texture for blending.
65 *
66 * @param geometryCoverage Describes the coverage output of the op's geometry processor
67 * @param geometryColor An in/out param. As input this informs processor analysis about the
68 * color the op expects to output from its geometry processor. As output
69 * this may be set to a known color in which case the op must output this
70 * color from its geometry processor instead.
71 */
Chris Daltonb8fff0d2019-03-05 10:11:58 -070072 GrProcessorSet::Analysis finalizeProcessors(
Chris Dalton6ce447a2019-06-23 18:07:38 -060073 const GrCaps& caps, const GrAppliedClip* clip, bool hasMixedSampledCoverage,
Brian Osman5ced0bf2019-03-15 10:15:29 -040074 GrClampType clampType, GrProcessorAnalysisCoverage geometryCoverage,
75 GrProcessorAnalysisColor* geometryColor) {
Chris Dalton6ce447a2019-06-23 18:07:38 -060076 return this->finalizeProcessors(
77 caps, clip, &GrUserStencilSettings::kUnused, hasMixedSampledCoverage, clampType,
78 geometryCoverage, geometryColor);
Chris Daltonb8fff0d2019-03-05 10:11:58 -070079 }
Brian Salomon0088f942017-07-12 11:51:27 -040080
81 /**
82 * Version of above that can be used by ops that have a constant color geometry processor
83 * output. The op passes this color as 'geometryColor' and after return if 'geometryColor' has
84 * changed the op must override its geometry processor color output with the new color.
85 */
Chris Daltonb8fff0d2019-03-05 10:11:58 -070086 GrProcessorSet::Analysis finalizeProcessors(
Chris Dalton6ce447a2019-06-23 18:07:38 -060087 const GrCaps&, const GrAppliedClip*, bool hasMixedSampledCoverage, GrClampType,
Brian Osman8fa7ab42019-03-18 10:22:42 -040088 GrProcessorAnalysisCoverage geometryCoverage, SkPMColor4f* geometryColor,
89 bool* wideColor);
Brian Salomon6d4b65e2017-05-03 17:06:09 -040090
Michael Ludwigdcd48212019-01-08 15:28:57 -050091 bool isTrivial() const {
92 return fProcessors == nullptr;
93 }
94
Brian Salomon05441c42017-05-15 16:45:49 -040095 bool usesLocalCoords() const {
96 SkASSERT(fDidAnalysis);
97 return fUsesLocalCoords;
98 }
99
Brian Osman605c6d52019-03-15 12:10:35 -0400100 bool compatibleWithCoverageAsAlpha() const { return fCompatibleWithCoverageAsAlpha; }
Brian Salomon28207df2017-06-05 12:25:13 -0400101
Brian Salomon6d4b65e2017-05-03 17:06:09 -0400102 struct MakeArgs {
103 private:
104 MakeArgs() = default;
105
106 GrProcessorSet* fProcessorSet;
Brian Salomon6d4b65e2017-05-03 17:06:09 -0400107
108 friend class GrSimpleMeshDrawOpHelper;
109 };
110
Chris Dalton7eb5c0f2019-05-23 15:15:47 -0600111 void visitProxies(const GrOp::VisitProxyFunc& func) const {
Robert Phillipsb493eeb2017-09-13 13:10:52 -0400112 if (fProcessors) {
113 fProcessors->visitProxies(func);
114 }
115 }
116
Brian Osman9a390ac2018-11-12 09:47:48 -0500117#ifdef SK_DEBUG
Brian Salomonb4d61062017-07-12 11:24:41 -0400118 SkString dumpInfo() const;
Brian Osman9a390ac2018-11-12 09:47:48 -0500119#endif
Michael Ludwigc6473242018-11-01 11:08:35 -0400120 GrAAType aaType() const { return static_cast<GrAAType>(fAAType); }
Brian Salomon82dfd3d2017-06-14 12:30:35 -0400121
Michael Ludwig69858532018-11-28 15:34:34 -0500122 void setAAType(GrAAType aaType) {
123 fAAType = static_cast<unsigned>(aaType);
124 }
125
Chris Dalton07cdcfc92019-02-26 11:13:22 -0700126 void executeDrawsAndUploads(const GrOp*, GrOpFlushState*, const SkRect& chainBounds);
127
Brian Salomon6d4b65e2017-05-03 17:06:09 -0400128protected:
Chris Daltonbaa1b352019-04-03 12:03:00 -0600129 GrPipeline::InputFlags pipelineFlags() const { return fPipelineFlags; }
Brian Salomon6d4b65e2017-05-03 17:06:09 -0400130
Chris Daltonb8fff0d2019-03-05 10:11:58 -0700131 GrProcessorSet::Analysis finalizeProcessors(
Chris Dalton6ce447a2019-06-23 18:07:38 -0600132 const GrCaps& caps, const GrAppliedClip*, const GrUserStencilSettings*,
133 bool hasMixedSampledCoverage, GrClampType, GrProcessorAnalysisCoverage geometryCoverage,
Brian Osman5ced0bf2019-03-15 10:15:29 -0400134 GrProcessorAnalysisColor* geometryColor);
Chris Daltonb8fff0d2019-03-05 10:11:58 -0700135
Brian Salomon6d4b65e2017-05-03 17:06:09 -0400136 GrProcessorSet* fProcessors;
Chris Daltonbaa1b352019-04-03 12:03:00 -0600137 GrPipeline::InputFlags fPipelineFlags;
Brian Salomon6d4b65e2017-05-03 17:06:09 -0400138 unsigned fAAType : 2;
Brian Salomon05441c42017-05-15 16:45:49 -0400139 unsigned fUsesLocalCoords : 1;
Brian Osman605c6d52019-03-15 12:10:35 -0400140 unsigned fCompatibleWithCoverageAsAlpha : 1;
Brian Salomonbfd18cd2017-08-09 16:27:09 -0400141 SkDEBUGCODE(unsigned fMadePipeline : 1;)
Brian Salomon05441c42017-05-15 16:45:49 -0400142 SkDEBUGCODE(unsigned fDidAnalysis : 1;)
Brian Salomon6d4b65e2017-05-03 17:06:09 -0400143};
144
145/**
146 * This class extends GrSimpleMeshDrawOpHelper to support an optional GrUserStencilSettings. This
147 * uses private inheritance because it non-virtually overrides methods in the base class and should
148 * never be used with a GrSimpleMeshDrawOpHelper pointer or reference.
149 */
150class GrSimpleMeshDrawOpHelperWithStencil : private GrSimpleMeshDrawOpHelper {
151public:
152 using MakeArgs = GrSimpleMeshDrawOpHelper::MakeArgs;
Chris Daltonbaa1b352019-04-03 12:03:00 -0600153 using InputFlags = GrSimpleMeshDrawOpHelper::InputFlags;
Brian Salomon49348902018-06-26 09:12:38 -0400154
Robert Phillipsb493eeb2017-09-13 13:10:52 -0400155 using GrSimpleMeshDrawOpHelper::visitProxies;
Brian Salomon6d4b65e2017-05-03 17:06:09 -0400156
157 // using declarations can't be templated, so this is a pass through function instead.
158 template <typename Op, typename... OpArgs>
Robert Phillipsb97da532019-02-12 15:24:12 -0500159 static std::unique_ptr<GrDrawOp> FactoryHelper(GrRecordingContext* context, GrPaint&& paint,
Robert Phillips7c525e62018-06-12 10:11:12 -0400160 OpArgs... opArgs) {
Brian Salomon6d4b65e2017-05-03 17:06:09 -0400161 return GrSimpleMeshDrawOpHelper::FactoryHelper<Op, OpArgs...>(
Robert Phillips7c525e62018-06-12 10:11:12 -0400162 context, std::move(paint), std::forward<OpArgs>(opArgs)...);
Brian Salomon6d4b65e2017-05-03 17:06:09 -0400163 }
164
Brian Salomonb4d61062017-07-12 11:24:41 -0400165 GrSimpleMeshDrawOpHelperWithStencil(const MakeArgs&, GrAAType, const GrUserStencilSettings*,
Chris Daltonbaa1b352019-04-03 12:03:00 -0600166 InputFlags = InputFlags::kNone);
Brian Salomon6d4b65e2017-05-03 17:06:09 -0400167
Brian Salomonb4d61062017-07-12 11:24:41 -0400168 GrDrawOp::FixedFunctionFlags fixedFunctionFlags() const;
Brian Salomon6d4b65e2017-05-03 17:06:09 -0400169
Chris Daltonb8fff0d2019-03-05 10:11:58 -0700170 GrProcessorSet::Analysis finalizeProcessors(
Chris Dalton6ce447a2019-06-23 18:07:38 -0600171 const GrCaps& caps, const GrAppliedClip* clip, bool hasMixedSampledCoverage,
Brian Osman5ced0bf2019-03-15 10:15:29 -0400172 GrClampType clampType, GrProcessorAnalysisCoverage geometryCoverage,
173 GrProcessorAnalysisColor* geometryColor) {
Chris Daltonb8fff0d2019-03-05 10:11:58 -0700174 return this->INHERITED::finalizeProcessors(
Chris Dalton6ce447a2019-06-23 18:07:38 -0600175 caps, clip, fStencilSettings, hasMixedSampledCoverage, clampType, geometryCoverage,
176 geometryColor);
Chris Daltonb8fff0d2019-03-05 10:11:58 -0700177 }
178
179 GrProcessorSet::Analysis finalizeProcessors(
Chris Dalton6ce447a2019-06-23 18:07:38 -0600180 const GrCaps&, const GrAppliedClip*, bool hasMixedSampledCoverage, GrClampType,
181 GrProcessorAnalysisCoverage geometryCoverage, SkPMColor4f* geometryColor, bool*
182 wideColor);
Chris Daltonb8fff0d2019-03-05 10:11:58 -0700183
Michael Ludwigdcd48212019-01-08 15:28:57 -0500184 using GrSimpleMeshDrawOpHelper::aaType;
185 using GrSimpleMeshDrawOpHelper::setAAType;
186 using GrSimpleMeshDrawOpHelper::isTrivial;
Brian Salomon05441c42017-05-15 16:45:49 -0400187 using GrSimpleMeshDrawOpHelper::usesLocalCoords;
Brian Osman605c6d52019-03-15 12:10:35 -0400188 using GrSimpleMeshDrawOpHelper::compatibleWithCoverageAsAlpha;
Brian Salomon6d4b65e2017-05-03 17:06:09 -0400189
Brian Salomonb4d61062017-07-12 11:24:41 -0400190 bool isCompatible(const GrSimpleMeshDrawOpHelperWithStencil& that, const GrCaps&,
Michael Ludwig69858532018-11-28 15:34:34 -0500191 const SkRect& thisBounds, const SkRect& thatBounds,
192 bool noneAACompatibleWithCoverage = false) const;
Brian Salomon6d4b65e2017-05-03 17:06:09 -0400193
Chris Dalton07cdcfc92019-02-26 11:13:22 -0700194 void executeDrawsAndUploads(const GrOp*, GrOpFlushState*, const SkRect& chainBounds);
Brian Salomon6d4b65e2017-05-03 17:06:09 -0400195
Brian Osman9a390ac2018-11-12 09:47:48 -0500196#ifdef SK_DEBUG
Brian Salomonb4d61062017-07-12 11:24:41 -0400197 SkString dumpInfo() const;
Brian Osman9a390ac2018-11-12 09:47:48 -0500198#endif
Brian Salomon82dfd3d2017-06-14 12:30:35 -0400199
Brian Salomon6d4b65e2017-05-03 17:06:09 -0400200private:
201 const GrUserStencilSettings* fStencilSettings;
202 typedef GrSimpleMeshDrawOpHelper INHERITED;
203};
204
205template <typename Op, typename... OpArgs>
Robert Phillipsb97da532019-02-12 15:24:12 -0500206std::unique_ptr<GrDrawOp> GrSimpleMeshDrawOpHelper::FactoryHelper(GrRecordingContext* context,
Robert Phillips7c525e62018-06-12 10:11:12 -0400207 GrPaint&& paint,
Brian Salomon6d4b65e2017-05-03 17:06:09 -0400208 OpArgs... opArgs) {
Robert Phillips9da87e02019-02-04 13:26:26 -0500209 GrOpMemoryPool* pool = context->priv().opMemoryPool();
Robert Phillipsc994a932018-06-19 13:09:54 -0400210
Brian Salomon6d4b65e2017-05-03 17:06:09 -0400211 MakeArgs makeArgs;
Robert Phillips7c525e62018-06-12 10:11:12 -0400212
Brian Salomon6d4b65e2017-05-03 17:06:09 -0400213 if (paint.isTrivial()) {
214 makeArgs.fProcessorSet = nullptr;
Brian Osmancf860852018-10-31 14:04:39 -0400215 return pool->allocate<Op>(makeArgs, paint.getColor4f(), std::forward<OpArgs>(opArgs)...);
Brian Salomon6d4b65e2017-05-03 17:06:09 -0400216 } else {
Robert Phillipsc994a932018-06-19 13:09:54 -0400217 char* mem = (char*) pool->allocate(sizeof(Op) + sizeof(GrProcessorSet));
Brian Salomon6d4b65e2017-05-03 17:06:09 -0400218 char* setMem = mem + sizeof(Op);
Mike Kleinad6487372018-12-12 09:40:40 -0500219 auto color = paint.getColor4f();
Brian Salomon6d4b65e2017-05-03 17:06:09 -0400220 makeArgs.fProcessorSet = new (setMem) GrProcessorSet(std::move(paint));
Mike Kleinad6487372018-12-12 09:40:40 -0500221 return std::unique_ptr<GrDrawOp>(new (mem) Op(makeArgs, color,
Robert Phillipsc994a932018-06-19 13:09:54 -0400222 std::forward<OpArgs>(opArgs)...));
Brian Salomon6d4b65e2017-05-03 17:06:09 -0400223 }
224}
225
Chris Daltonbaa1b352019-04-03 12:03:00 -0600226GR_MAKE_BITFIELD_CLASS_OPS(GrSimpleMeshDrawOpHelper::InputFlags)
Brian Salomonbaaf4392017-06-15 09:59:23 -0400227
Brian Salomon6d4b65e2017-05-03 17:06:09 -0400228#endif