blob: a4910ebf7fa9bcdb268ea290aa44da290ec4fb15 [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
Robert Phillipsb7bfbc22020-07-01 12:55:01 -040011#include "include/gpu/GrRecordingContext.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050012#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"
Herb Derbyc76d4092020-10-07 16:46:15 -040017#include "src/gpu/ops/GrOp.h"
Mike Klein79aea6a2018-06-11 10:45:26 -040018#include <new>
Brian Salomonb4d61062017-07-12 11:24:41 -040019
20struct SkRect;
Brian Salomon6d4b65e2017-05-03 17:06:09 -040021
22/**
23 * This class can be used to help implement simple mesh draw ops. It reduces the amount of
24 * boilerplate code to type and also provides a mechanism for optionally allocating space for a
25 * GrProcessorSet based on a GrPaint. It is intended to be used by ops that construct a single
26 * GrPipeline for a uniform primitive color and a GrPaint.
27 */
28class GrSimpleMeshDrawOpHelper {
29public:
Brian Salomon6d4b65e2017-05-03 17:06:09 -040030 /**
31 * This can be used by a Op class to perform allocation and initialization such that a
Brian Salomonb4d61062017-07-12 11:24:41 -040032 * GrProcessorSet (if required) is allocated as part of the the same allocation that as
33 * the Op instance. It requires that Op implements a constructor of the form:
Herb Derbyc76d4092020-10-07 16:46:15 -040034 * Op(ProcessorSet*, GrColor, OpArgs...).
Brian Salomon6d4b65e2017-05-03 17:06:09 -040035 */
36 template <typename Op, typename... OpArgs>
Herb Derbyc76d4092020-10-07 16:46:15 -040037 static GrOp::Owner FactoryHelper(GrRecordingContext*, GrPaint&&, OpArgs&&...);
Brian Salomon6d4b65e2017-05-03 17:06:09 -040038
Chris Daltonbaa1b352019-04-03 12:03:00 -060039 // Here we allow callers to specify a subset of the GrPipeline::InputFlags upon creation.
40 enum class InputFlags : uint8_t {
41 kNone = 0,
42 kSnapVerticesToPixelCenters = (uint8_t)GrPipeline::InputFlags::kSnapVerticesToPixelCenters,
Chris Daltonc3b67eb2020-02-10 21:09:58 -070043 kConservativeRaster = (uint8_t)GrPipeline::InputFlags::kConservativeRaster,
Brian Salomonbaaf4392017-06-15 09:59:23 -040044 };
Chris Daltonbaa1b352019-04-03 12:03:00 -060045 GR_DECL_BITFIELD_CLASS_OPS_FRIENDS(InputFlags);
Brian Salomonbaaf4392017-06-15 09:59:23 -040046
Herb Derbyc76d4092020-10-07 16:46:15 -040047 GrSimpleMeshDrawOpHelper(GrProcessorSet*, GrAAType, InputFlags = InputFlags::kNone);
Brian Salomonb4d61062017-07-12 11:24:41 -040048 ~GrSimpleMeshDrawOpHelper();
Brian Salomon6d4b65e2017-05-03 17:06:09 -040049
50 GrSimpleMeshDrawOpHelper() = delete;
51 GrSimpleMeshDrawOpHelper(const GrSimpleMeshDrawOpHelper&) = delete;
52 GrSimpleMeshDrawOpHelper& operator=(const GrSimpleMeshDrawOpHelper&) = delete;
53
Brian Salomonb4d61062017-07-12 11:24:41 -040054 GrDrawOp::FixedFunctionFlags fixedFunctionFlags() const;
Brian Salomon6d4b65e2017-05-03 17:06:09 -040055
Robert Phillipsb69001f2019-10-29 12:16:35 -040056 // ignoreAAType should be set to true if the op already knows the AA settings are acceptible
Brian Salomonb4d61062017-07-12 11:24:41 -040057 bool isCompatible(const GrSimpleMeshDrawOpHelper& that, const GrCaps&, const SkRect& thisBounds,
Robert Phillipsb69001f2019-10-29 12:16:35 -040058 const SkRect& thatBounds, bool ignoreAAType = false) const;
Brian Salomon6d4b65e2017-05-03 17:06:09 -040059
Brian Salomon0088f942017-07-12 11:51:27 -040060 /**
61 * Finalizes the processor set and determines whether the destination must be provided
62 * to the fragment shader as a texture for blending.
63 *
64 * @param geometryCoverage Describes the coverage output of the op's geometry processor
65 * @param geometryColor An in/out param. As input this informs processor analysis about the
66 * color the op expects to output from its geometry processor. As output
67 * this may be set to a known color in which case the op must output this
68 * color from its geometry processor instead.
69 */
Chris Daltonb8fff0d2019-03-05 10:11:58 -070070 GrProcessorSet::Analysis finalizeProcessors(
Chris Dalton6ce447a2019-06-23 18:07:38 -060071 const GrCaps& caps, const GrAppliedClip* clip, bool hasMixedSampledCoverage,
Brian Osman5ced0bf2019-03-15 10:15:29 -040072 GrClampType clampType, GrProcessorAnalysisCoverage geometryCoverage,
73 GrProcessorAnalysisColor* geometryColor) {
Chris Dalton6ce447a2019-06-23 18:07:38 -060074 return this->finalizeProcessors(
75 caps, clip, &GrUserStencilSettings::kUnused, hasMixedSampledCoverage, clampType,
76 geometryCoverage, geometryColor);
Chris Daltonb8fff0d2019-03-05 10:11:58 -070077 }
Brian Salomon0088f942017-07-12 11:51:27 -040078
79 /**
80 * Version of above that can be used by ops that have a constant color geometry processor
81 * output. The op passes this color as 'geometryColor' and after return if 'geometryColor' has
82 * changed the op must override its geometry processor color output with the new color.
83 */
Chris Daltonb8fff0d2019-03-05 10:11:58 -070084 GrProcessorSet::Analysis finalizeProcessors(
Chris Dalton6ce447a2019-06-23 18:07:38 -060085 const GrCaps&, const GrAppliedClip*, bool hasMixedSampledCoverage, GrClampType,
Brian Osman8fa7ab42019-03-18 10:22:42 -040086 GrProcessorAnalysisCoverage geometryCoverage, SkPMColor4f* geometryColor,
87 bool* wideColor);
Brian Salomon6d4b65e2017-05-03 17:06:09 -040088
Michael Ludwigdcd48212019-01-08 15:28:57 -050089 bool isTrivial() const {
90 return fProcessors == nullptr;
91 }
92
Brian Salomon05441c42017-05-15 16:45:49 -040093 bool usesLocalCoords() const {
94 SkASSERT(fDidAnalysis);
95 return fUsesLocalCoords;
96 }
97
Brian Osman605c6d52019-03-15 12:10:35 -040098 bool compatibleWithCoverageAsAlpha() const { return fCompatibleWithCoverageAsAlpha; }
Brian Salomon28207df2017-06-05 12:25:13 -040099
Chris Dalton7eb5c0f2019-05-23 15:15:47 -0600100 void visitProxies(const GrOp::VisitProxyFunc& func) const {
Robert Phillipsb493eeb2017-09-13 13:10:52 -0400101 if (fProcessors) {
102 fProcessors->visitProxies(func);
103 }
104 }
105
John Stiles8d9bf642020-08-12 15:07:45 -0400106#if GR_TEST_UTILS
Brian Salomonb4d61062017-07-12 11:24:41 -0400107 SkString dumpInfo() const;
Brian Osman9a390ac2018-11-12 09:47:48 -0500108#endif
Michael Ludwigc6473242018-11-01 11:08:35 -0400109 GrAAType aaType() const { return static_cast<GrAAType>(fAAType); }
Brian Salomon82dfd3d2017-06-14 12:30:35 -0400110
Michael Ludwig69858532018-11-28 15:34:34 -0500111 void setAAType(GrAAType aaType) {
Robert Phillips438d9862019-11-14 12:46:05 -0500112 fAAType = static_cast<unsigned>(aaType);
Michael Ludwig69858532018-11-28 15:34:34 -0500113 }
114
Robert Phillips3968fcb2019-12-05 16:40:31 -0500115 static const GrPipeline* CreatePipeline(
Robert Phillips6c59fe42020-02-27 09:30:37 -0500116 const GrCaps*,
117 SkArenaAlloc*,
Brian Salomon8afde5f2020-04-01 16:22:00 -0400118 GrSwizzle writeViewSwizzle,
Robert Phillips6c59fe42020-02-27 09:30:37 -0500119 GrAppliedClip&&,
120 const GrXferProcessor::DstProxyView&,
121 GrProcessorSet&&,
Chris Dalton1b6a43c2020-09-25 12:21:18 -0600122 GrPipeline::InputFlags pipelineFlags);
Robert Phillips6c59fe42020-02-27 09:30:37 -0500123 static const GrPipeline* CreatePipeline(
124 GrOpFlushState*,
125 GrProcessorSet&&,
Chris Dalton1b6a43c2020-09-25 12:21:18 -0600126 GrPipeline::InputFlags pipelineFlags);
Robert Phillips6c59fe42020-02-27 09:30:37 -0500127
128 const GrPipeline* createPipeline(GrOpFlushState* flushState);
Chris Dalton07cdcfc92019-02-26 11:13:22 -0700129
Chris Dalton1b6a43c2020-09-25 12:21:18 -0600130 const GrPipeline* createPipeline(const GrCaps*,
131 SkArenaAlloc*,
132 GrSwizzle writeViewSwizzle,
133 GrAppliedClip&&,
134 const GrXferProcessor::DstProxyView&);
135
Robert Phillips4f93c572020-03-18 08:13:53 -0400136 static GrProgramInfo* CreateProgramInfo(SkArenaAlloc*,
137 const GrPipeline*,
Adlai Hollere2296f72020-11-19 13:41:26 -0500138 const GrSurfaceProxyView& writeView,
Robert Phillips4f93c572020-03-18 08:13:53 -0400139 GrGeometryProcessor*,
Greg Danield358cbe2020-09-11 09:33:54 -0400140 GrPrimitiveType,
Chris Dalton1b6a43c2020-09-25 12:21:18 -0600141 GrXferBarrierFlags renderPassXferBarriers,
Greg Daniel42dbca52020-11-20 10:22:43 -0500142 GrLoadOp colorLoadOp,
Chris Dalton1b6a43c2020-09-25 12:21:18 -0600143 const GrUserStencilSettings*
144 = &GrUserStencilSettings::kUnused);
Robert Phillips4f93c572020-03-18 08:13:53 -0400145
Robert Phillipsce978572020-02-28 11:56:44 -0500146 // Create a programInfo with the following properties:
147 // its primitive processor uses no textures
148 // it has no dynamic state besides the scissor clip
Robert Phillipsce978572020-02-28 11:56:44 -0500149 static GrProgramInfo* CreateProgramInfo(const GrCaps*,
150 SkArenaAlloc*,
Adlai Hollere2296f72020-11-19 13:41:26 -0500151 const GrSurfaceProxyView& writeView,
Robert Phillipsce978572020-02-28 11:56:44 -0500152 GrAppliedClip&&,
153 const GrXferProcessor::DstProxyView&,
154 GrGeometryProcessor*,
155 GrProcessorSet&&,
Robert Phillipsac6156c2020-02-28 16:02:40 -0500156 GrPrimitiveType,
Greg Danield358cbe2020-09-11 09:33:54 -0400157 GrXferBarrierFlags renderPassXferBarriers,
Greg Daniel42dbca52020-11-20 10:22:43 -0500158 GrLoadOp colorLoadOp,
Robert Phillipsac6156c2020-02-28 16:02:40 -0500159 GrPipeline::InputFlags pipelineFlags
160 = GrPipeline::InputFlags::kNone,
161 const GrUserStencilSettings*
Robert Phillips709e2402020-03-23 18:29:16 +0000162 = &GrUserStencilSettings::kUnused);
Robert Phillipsce978572020-02-28 11:56:44 -0500163
Robert Phillipsb58098f2020-03-02 16:25:29 -0500164 GrProgramInfo* createProgramInfo(const GrCaps*,
165 SkArenaAlloc*,
Adlai Hollere2296f72020-11-19 13:41:26 -0500166 const GrSurfaceProxyView& writeView,
Robert Phillipsb58098f2020-03-02 16:25:29 -0500167 GrAppliedClip&&,
168 const GrXferProcessor::DstProxyView&,
169 GrGeometryProcessor*,
Greg Danield358cbe2020-09-11 09:33:54 -0400170 GrPrimitiveType,
Greg Daniel42dbca52020-11-20 10:22:43 -0500171 GrXferBarrierFlags renderPassXferBarriers,
172 GrLoadOp colorLoadOp);
Robert Phillipsb58098f2020-03-02 16:25:29 -0500173
Robert Phillips3968fcb2019-12-05 16:40:31 -0500174 GrProcessorSet detachProcessorSet() {
175 return fProcessors ? std::move(*fProcessors) : GrProcessorSet::MakeEmptySet();
176 }
177
Chris Daltonbaa1b352019-04-03 12:03:00 -0600178 GrPipeline::InputFlags pipelineFlags() const { return fPipelineFlags; }
Brian Salomon6d4b65e2017-05-03 17:06:09 -0400179
Robert Phillips3968fcb2019-12-05 16:40:31 -0500180protected:
Chris Daltonb8fff0d2019-03-05 10:11:58 -0700181 GrProcessorSet::Analysis finalizeProcessors(
Chris Dalton6ce447a2019-06-23 18:07:38 -0600182 const GrCaps& caps, const GrAppliedClip*, const GrUserStencilSettings*,
183 bool hasMixedSampledCoverage, GrClampType, GrProcessorAnalysisCoverage geometryCoverage,
Brian Osman5ced0bf2019-03-15 10:15:29 -0400184 GrProcessorAnalysisColor* geometryColor);
Chris Daltonb8fff0d2019-03-05 10:11:58 -0700185
Brian Salomon6d4b65e2017-05-03 17:06:09 -0400186 GrProcessorSet* fProcessors;
Chris Daltonbaa1b352019-04-03 12:03:00 -0600187 GrPipeline::InputFlags fPipelineFlags;
Brian Salomon6d4b65e2017-05-03 17:06:09 -0400188 unsigned fAAType : 2;
Brian Salomon05441c42017-05-15 16:45:49 -0400189 unsigned fUsesLocalCoords : 1;
Brian Osman605c6d52019-03-15 12:10:35 -0400190 unsigned fCompatibleWithCoverageAsAlpha : 1;
Brian Salomonbfd18cd2017-08-09 16:27:09 -0400191 SkDEBUGCODE(unsigned fMadePipeline : 1;)
Brian Salomon05441c42017-05-15 16:45:49 -0400192 SkDEBUGCODE(unsigned fDidAnalysis : 1;)
Brian Salomon6d4b65e2017-05-03 17:06:09 -0400193};
194
Herb Derbyc76d4092020-10-07 16:46:15 -0400195template<typename Op, typename... Args>
196GrOp::Owner GrOp::MakeWithProcessorSet(
197 GrRecordingContext* context, const SkPMColor4f& color,
198 GrPaint&& paint, Args&&... args) {
Herb Derbyc9a24c92020-12-01 16:59:40 -0500199#if defined(GR_OP_ALLOCATE_USE_POOL)
Herb Derby2acd43d2020-10-27 13:38:32 -0400200 GrMemoryPool* pool = context->priv().opMemoryPool();
Herb Derbyc76d4092020-10-07 16:46:15 -0400201 char* bytes = (char*)pool->allocate(sizeof(Op) + sizeof(GrProcessorSet));
202 char* setMem = bytes + sizeof(Op);
203 GrProcessorSet* processorSet = new (setMem) GrProcessorSet{std::move(paint)};
204 return Owner{new (bytes) Op(processorSet, color, std::forward<Args>(args)...), pool};
Herb Derbyc9a24c92020-12-01 16:59:40 -0500205#else
206 char* bytes = (char*)::operator new(sizeof(Op) + sizeof(GrProcessorSet));
207 char* setMem = bytes + sizeof(Op);
208 GrProcessorSet* processorSet = new (setMem) GrProcessorSet{std::move(paint)};
209 return Owner{new (bytes) Op(processorSet, color, std::forward<Args>(args)...)};
Herb Derbyc76d4092020-10-07 16:46:15 -0400210#endif
211}
Robert Phillipsc994a932018-06-19 13:09:54 -0400212
Herb Derbyc76d4092020-10-07 16:46:15 -0400213template <typename Op, typename... OpArgs>
214GrOp::Owner GrSimpleMeshDrawOpHelper::FactoryHelper(GrRecordingContext* context,
215 GrPaint&& paint,
216 OpArgs&& ... opArgs) {
217 auto color = paint.getColor4f();
Brian Salomon6d4b65e2017-05-03 17:06:09 -0400218 if (paint.isTrivial()) {
Herb Derbyc76d4092020-10-07 16:46:15 -0400219 return GrOp::Make<Op>(context, nullptr, color, std::forward<OpArgs>(opArgs)...);
Brian Salomon6d4b65e2017-05-03 17:06:09 -0400220 } else {
Herb Derbyc76d4092020-10-07 16:46:15 -0400221 return GrOp::MakeWithProcessorSet<Op>(
222 context, color, std::move(paint), 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