blob: 813a3dcdd76279ff27947a03d163a7c71f491a54 [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
Brian Salomonb4d61062017-07-12 11:24:41 -040011#include "GrMeshDrawOp.h"
Brian Salomon6d4b65e2017-05-03 17:06:09 -040012#include "GrOpFlushState.h"
13#include "GrPipeline.h"
Brian Salomonb4d61062017-07-12 11:24:41 -040014
15struct SkRect;
Brian Salomon6d4b65e2017-05-03 17:06:09 -040016
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 */
23class GrSimpleMeshDrawOpHelper {
24public:
25 struct MakeArgs;
26
27 /**
28 * This can be used by a Op class to perform allocation and initialization such that a
Brian Salomonb4d61062017-07-12 11:24:41 -040029 * GrProcessorSet (if required) is allocated as part of the the same allocation that as
30 * the Op instance. It requires that Op implements a constructor of the form:
Brian Salomon6d4b65e2017-05-03 17:06:09 -040031 * Op(MakeArgs, GrColor, OpArgs...)
32 * which is public or made accessible via 'friend'.
33 */
34 template <typename Op, typename... OpArgs>
35 static std::unique_ptr<GrDrawOp> FactoryHelper(GrPaint&& paint, OpArgs... opArgs);
36
Brian Salomonbaaf4392017-06-15 09:59:23 -040037 enum class Flags : uint32_t {
38 kNone = 0x0,
39 kSnapVerticesToPixelCenters = 0x1,
40 };
41 GR_DECL_BITFIELD_CLASS_OPS_FRIENDS(Flags);
42
Brian Salomonb4d61062017-07-12 11:24:41 -040043 GrSimpleMeshDrawOpHelper(const MakeArgs&, GrAAType, Flags = Flags::kNone);
44 ~GrSimpleMeshDrawOpHelper();
Brian Salomon6d4b65e2017-05-03 17:06:09 -040045
46 GrSimpleMeshDrawOpHelper() = delete;
47 GrSimpleMeshDrawOpHelper(const GrSimpleMeshDrawOpHelper&) = delete;
48 GrSimpleMeshDrawOpHelper& operator=(const GrSimpleMeshDrawOpHelper&) = delete;
49
Brian Salomonb4d61062017-07-12 11:24:41 -040050 GrDrawOp::FixedFunctionFlags fixedFunctionFlags() const;
Brian Salomon6d4b65e2017-05-03 17:06:09 -040051
Brian Salomonb4d61062017-07-12 11:24:41 -040052 bool isCompatible(const GrSimpleMeshDrawOpHelper& that, const GrCaps&, const SkRect& thisBounds,
53 const SkRect& thatBounds) const;
Brian Salomon6d4b65e2017-05-03 17:06:09 -040054
Brian Salomonb4d61062017-07-12 11:24:41 -040055 GrDrawOp::RequiresDstTexture xpRequiresDstTexture(const GrCaps&, const GrAppliedClip*,
Brian Salomonf86d37b2017-06-16 10:04:34 -040056 GrProcessorAnalysisCoverage geometryCoverage,
Brian Salomonb4d61062017-07-12 11:24:41 -040057 GrColor* color);
Brian Salomon6d4b65e2017-05-03 17:06:09 -040058
Brian Salomon05441c42017-05-15 16:45:49 -040059 bool usesLocalCoords() const {
60 SkASSERT(fDidAnalysis);
61 return fUsesLocalCoords;
62 }
63
Brian Salomon28207df2017-06-05 12:25:13 -040064 bool compatibleWithAlphaAsCoverage() const { return fCompatibleWithAlphaAsCoveage; }
65
Brian Salomon6d4b65e2017-05-03 17:06:09 -040066 GrPipeline* makePipeline(GrMeshDrawOp::Target* target) const {
67 return target->allocPipeline(this->pipelineInitArgs(target));
68 }
69
70 struct MakeArgs {
71 private:
72 MakeArgs() = default;
73
74 GrProcessorSet* fProcessorSet;
75 uint32_t fSRGBFlags;
76
77 friend class GrSimpleMeshDrawOpHelper;
78 };
79
Brian Salomonb4d61062017-07-12 11:24:41 -040080 SkString dumpInfo() const;
Brian Salomon82dfd3d2017-06-14 12:30:35 -040081
Brian Salomon6d4b65e2017-05-03 17:06:09 -040082protected:
83 GrAAType aaType() const { return static_cast<GrAAType>(fAAType); }
84 uint32_t pipelineFlags() const { return fPipelineFlags; }
85 const GrProcessorSet& processors() const {
86 return fProcessors ? *fProcessors : GrProcessorSet::EmptySet();
87 }
88
Brian Salomonb4d61062017-07-12 11:24:41 -040089 GrPipeline::InitArgs pipelineInitArgs(GrMeshDrawOp::Target* target) const;
Brian Salomon6d4b65e2017-05-03 17:06:09 -040090
91private:
92 GrProcessorSet* fProcessors;
93 unsigned fPipelineFlags : 8;
94 unsigned fAAType : 2;
Brian Salomona4677b52017-05-04 12:39:56 -040095 unsigned fRequiresDstTexture : 1;
Brian Salomon05441c42017-05-15 16:45:49 -040096 unsigned fUsesLocalCoords : 1;
Brian Salomon28207df2017-06-05 12:25:13 -040097 unsigned fCompatibleWithAlphaAsCoveage : 1;
Brian Salomon05441c42017-05-15 16:45:49 -040098 SkDEBUGCODE(unsigned fDidAnalysis : 1;)
Brian Salomon6d4b65e2017-05-03 17:06:09 -040099};
100
101/**
102 * This class extends GrSimpleMeshDrawOpHelper to support an optional GrUserStencilSettings. This
103 * uses private inheritance because it non-virtually overrides methods in the base class and should
104 * never be used with a GrSimpleMeshDrawOpHelper pointer or reference.
105 */
106class GrSimpleMeshDrawOpHelperWithStencil : private GrSimpleMeshDrawOpHelper {
107public:
108 using MakeArgs = GrSimpleMeshDrawOpHelper::MakeArgs;
Brian Salomonbaaf4392017-06-15 09:59:23 -0400109 using Flags = GrSimpleMeshDrawOpHelper::Flags;
Brian Salomon6d4b65e2017-05-03 17:06:09 -0400110
111 // using declarations can't be templated, so this is a pass through function instead.
112 template <typename Op, typename... OpArgs>
113 static std::unique_ptr<GrDrawOp> FactoryHelper(GrPaint&& paint, OpArgs... opArgs) {
114 return GrSimpleMeshDrawOpHelper::FactoryHelper<Op, OpArgs...>(
115 std::move(paint), std::forward<OpArgs>(opArgs)...);
116 }
117
Brian Salomonb4d61062017-07-12 11:24:41 -0400118 GrSimpleMeshDrawOpHelperWithStencil(const MakeArgs&, GrAAType, const GrUserStencilSettings*,
119 Flags = Flags::kNone);
Brian Salomon6d4b65e2017-05-03 17:06:09 -0400120
Brian Salomonb4d61062017-07-12 11:24:41 -0400121 GrDrawOp::FixedFunctionFlags fixedFunctionFlags() const;
Brian Salomon6d4b65e2017-05-03 17:06:09 -0400122
123 using GrSimpleMeshDrawOpHelper::xpRequiresDstTexture;
Brian Salomon05441c42017-05-15 16:45:49 -0400124 using GrSimpleMeshDrawOpHelper::usesLocalCoords;
Brian Salomonbaaf4392017-06-15 09:59:23 -0400125 using GrSimpleMeshDrawOpHelper::compatibleWithAlphaAsCoverage;
Brian Salomon6d4b65e2017-05-03 17:06:09 -0400126
Brian Salomonb4d61062017-07-12 11:24:41 -0400127 bool isCompatible(const GrSimpleMeshDrawOpHelperWithStencil& that, const GrCaps&,
128 const SkRect& thisBounds, const SkRect& thatBounds) const;
Brian Salomon6d4b65e2017-05-03 17:06:09 -0400129
Brian Salomonb4d61062017-07-12 11:24:41 -0400130 const GrPipeline* makePipeline(GrMeshDrawOp::Target*) const;
Brian Salomon6d4b65e2017-05-03 17:06:09 -0400131
Brian Salomonb4d61062017-07-12 11:24:41 -0400132 SkString dumpInfo() const;
Brian Salomon82dfd3d2017-06-14 12:30:35 -0400133
Brian Salomon6d4b65e2017-05-03 17:06:09 -0400134private:
135 const GrUserStencilSettings* fStencilSettings;
136 typedef GrSimpleMeshDrawOpHelper INHERITED;
137};
138
139template <typename Op, typename... OpArgs>
140std::unique_ptr<GrDrawOp> GrSimpleMeshDrawOpHelper::FactoryHelper(GrPaint&& paint,
141 OpArgs... opArgs) {
142 MakeArgs makeArgs;
143 makeArgs.fSRGBFlags = GrPipeline::SRGBFlagsFromPaint(paint);
144 GrColor color = paint.getColor();
145 if (paint.isTrivial()) {
146 makeArgs.fProcessorSet = nullptr;
147 return std::unique_ptr<GrDrawOp>(new Op(makeArgs, color, std::forward<OpArgs>(opArgs)...));
148 } else {
149 char* mem = (char*)GrOp::operator new(sizeof(Op) + sizeof(GrProcessorSet));
150 char* setMem = mem + sizeof(Op);
151 makeArgs.fProcessorSet = new (setMem) GrProcessorSet(std::move(paint));
152 return std::unique_ptr<GrDrawOp>(
153 new (mem) Op(makeArgs, color, std::forward<OpArgs>(opArgs)...));
154 }
155}
156
Brian Salomonbaaf4392017-06-15 09:59:23 -0400157GR_MAKE_BITFIELD_CLASS_OPS(GrSimpleMeshDrawOpHelper::Flags)
158
Brian Salomon6d4b65e2017-05-03 17:06:09 -0400159#endif