123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228 |
- /*
- * Copyright 2017 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
- #ifndef GrSimpleMeshDrawOpHelper_DEFINED
- #define GrSimpleMeshDrawOpHelper_DEFINED
- #include "include/private/GrRecordingContext.h"
- #include "src/gpu/GrMemoryPool.h"
- #include "src/gpu/GrOpFlushState.h"
- #include "src/gpu/GrPipeline.h"
- #include "src/gpu/GrRecordingContextPriv.h"
- #include "src/gpu/ops/GrMeshDrawOp.h"
- #include <new>
- struct SkRect;
- /**
- * This class can be used to help implement simple mesh draw ops. It reduces the amount of
- * boilerplate code to type and also provides a mechanism for optionally allocating space for a
- * GrProcessorSet based on a GrPaint. It is intended to be used by ops that construct a single
- * GrPipeline for a uniform primitive color and a GrPaint.
- */
- class GrSimpleMeshDrawOpHelper {
- public:
- struct MakeArgs;
- /**
- * This can be used by a Op class to perform allocation and initialization such that a
- * GrProcessorSet (if required) is allocated as part of the the same allocation that as
- * the Op instance. It requires that Op implements a constructor of the form:
- * Op(MakeArgs, GrColor, OpArgs...)
- * which is public or made accessible via 'friend'.
- */
- template <typename Op, typename... OpArgs>
- static std::unique_ptr<GrDrawOp> FactoryHelper(GrRecordingContext*, GrPaint&&, OpArgs...);
- // Here we allow callers to specify a subset of the GrPipeline::InputFlags upon creation.
- enum class InputFlags : uint8_t {
- kNone = 0,
- kSnapVerticesToPixelCenters = (uint8_t)GrPipeline::InputFlags::kSnapVerticesToPixelCenters,
- };
- GR_DECL_BITFIELD_CLASS_OPS_FRIENDS(InputFlags);
- GrSimpleMeshDrawOpHelper(const MakeArgs&, GrAAType, InputFlags = InputFlags::kNone);
- ~GrSimpleMeshDrawOpHelper();
- GrSimpleMeshDrawOpHelper() = delete;
- GrSimpleMeshDrawOpHelper(const GrSimpleMeshDrawOpHelper&) = delete;
- GrSimpleMeshDrawOpHelper& operator=(const GrSimpleMeshDrawOpHelper&) = delete;
- GrDrawOp::FixedFunctionFlags fixedFunctionFlags() const;
- // noneAACompatibleWithCoverage should be set to true if the op can properly render a non-AA
- // primitive merged into a coverage-based op.
- bool isCompatible(const GrSimpleMeshDrawOpHelper& that, const GrCaps&, const SkRect& thisBounds,
- const SkRect& thatBounds, bool noneAACompatibleWithCoverage = false) const;
- /**
- * Finalizes the processor set and determines whether the destination must be provided
- * to the fragment shader as a texture for blending.
- *
- * @param geometryCoverage Describes the coverage output of the op's geometry processor
- * @param geometryColor An in/out param. As input this informs processor analysis about the
- * color the op expects to output from its geometry processor. As output
- * this may be set to a known color in which case the op must output this
- * color from its geometry processor instead.
- */
- GrProcessorSet::Analysis finalizeProcessors(
- const GrCaps& caps, const GrAppliedClip* clip, bool hasMixedSampledCoverage,
- GrClampType clampType, GrProcessorAnalysisCoverage geometryCoverage,
- GrProcessorAnalysisColor* geometryColor) {
- return this->finalizeProcessors(
- caps, clip, &GrUserStencilSettings::kUnused, hasMixedSampledCoverage, clampType,
- geometryCoverage, geometryColor);
- }
- /**
- * Version of above that can be used by ops that have a constant color geometry processor
- * output. The op passes this color as 'geometryColor' and after return if 'geometryColor' has
- * changed the op must override its geometry processor color output with the new color.
- */
- GrProcessorSet::Analysis finalizeProcessors(
- const GrCaps&, const GrAppliedClip*, bool hasMixedSampledCoverage, GrClampType,
- GrProcessorAnalysisCoverage geometryCoverage, SkPMColor4f* geometryColor,
- bool* wideColor);
- bool isTrivial() const {
- return fProcessors == nullptr;
- }
- bool usesLocalCoords() const {
- SkASSERT(fDidAnalysis);
- return fUsesLocalCoords;
- }
- bool compatibleWithCoverageAsAlpha() const { return fCompatibleWithCoverageAsAlpha; }
- struct MakeArgs {
- private:
- MakeArgs() = default;
- GrProcessorSet* fProcessorSet;
- friend class GrSimpleMeshDrawOpHelper;
- };
- void visitProxies(const GrOp::VisitProxyFunc& func) const {
- if (fProcessors) {
- fProcessors->visitProxies(func);
- }
- }
- #ifdef SK_DEBUG
- SkString dumpInfo() const;
- #endif
- GrAAType aaType() const { return static_cast<GrAAType>(fAAType); }
- void setAAType(GrAAType aaType) {
- fAAType = static_cast<unsigned>(aaType);
- }
- void executeDrawsAndUploads(const GrOp*, GrOpFlushState*, const SkRect& chainBounds);
- protected:
- GrPipeline::InputFlags pipelineFlags() const { return fPipelineFlags; }
- GrProcessorSet::Analysis finalizeProcessors(
- const GrCaps& caps, const GrAppliedClip*, const GrUserStencilSettings*,
- bool hasMixedSampledCoverage, GrClampType, GrProcessorAnalysisCoverage geometryCoverage,
- GrProcessorAnalysisColor* geometryColor);
- GrProcessorSet* fProcessors;
- GrPipeline::InputFlags fPipelineFlags;
- unsigned fAAType : 2;
- unsigned fUsesLocalCoords : 1;
- unsigned fCompatibleWithCoverageAsAlpha : 1;
- SkDEBUGCODE(unsigned fMadePipeline : 1;)
- SkDEBUGCODE(unsigned fDidAnalysis : 1;)
- };
- /**
- * This class extends GrSimpleMeshDrawOpHelper to support an optional GrUserStencilSettings. This
- * uses private inheritance because it non-virtually overrides methods in the base class and should
- * never be used with a GrSimpleMeshDrawOpHelper pointer or reference.
- */
- class GrSimpleMeshDrawOpHelperWithStencil : private GrSimpleMeshDrawOpHelper {
- public:
- using MakeArgs = GrSimpleMeshDrawOpHelper::MakeArgs;
- using InputFlags = GrSimpleMeshDrawOpHelper::InputFlags;
- using GrSimpleMeshDrawOpHelper::visitProxies;
- // using declarations can't be templated, so this is a pass through function instead.
- template <typename Op, typename... OpArgs>
- static std::unique_ptr<GrDrawOp> FactoryHelper(GrRecordingContext* context, GrPaint&& paint,
- OpArgs... opArgs) {
- return GrSimpleMeshDrawOpHelper::FactoryHelper<Op, OpArgs...>(
- context, std::move(paint), std::forward<OpArgs>(opArgs)...);
- }
- GrSimpleMeshDrawOpHelperWithStencil(const MakeArgs&, GrAAType, const GrUserStencilSettings*,
- InputFlags = InputFlags::kNone);
- GrDrawOp::FixedFunctionFlags fixedFunctionFlags() const;
- GrProcessorSet::Analysis finalizeProcessors(
- const GrCaps& caps, const GrAppliedClip* clip, bool hasMixedSampledCoverage,
- GrClampType clampType, GrProcessorAnalysisCoverage geometryCoverage,
- GrProcessorAnalysisColor* geometryColor) {
- return this->INHERITED::finalizeProcessors(
- caps, clip, fStencilSettings, hasMixedSampledCoverage, clampType, geometryCoverage,
- geometryColor);
- }
- GrProcessorSet::Analysis finalizeProcessors(
- const GrCaps&, const GrAppliedClip*, bool hasMixedSampledCoverage, GrClampType,
- GrProcessorAnalysisCoverage geometryCoverage, SkPMColor4f* geometryColor, bool*
- wideColor);
- using GrSimpleMeshDrawOpHelper::aaType;
- using GrSimpleMeshDrawOpHelper::setAAType;
- using GrSimpleMeshDrawOpHelper::isTrivial;
- using GrSimpleMeshDrawOpHelper::usesLocalCoords;
- using GrSimpleMeshDrawOpHelper::compatibleWithCoverageAsAlpha;
- bool isCompatible(const GrSimpleMeshDrawOpHelperWithStencil& that, const GrCaps&,
- const SkRect& thisBounds, const SkRect& thatBounds,
- bool noneAACompatibleWithCoverage = false) const;
- void executeDrawsAndUploads(const GrOp*, GrOpFlushState*, const SkRect& chainBounds);
- #ifdef SK_DEBUG
- SkString dumpInfo() const;
- #endif
- private:
- const GrUserStencilSettings* fStencilSettings;
- typedef GrSimpleMeshDrawOpHelper INHERITED;
- };
- template <typename Op, typename... OpArgs>
- std::unique_ptr<GrDrawOp> GrSimpleMeshDrawOpHelper::FactoryHelper(GrRecordingContext* context,
- GrPaint&& paint,
- OpArgs... opArgs) {
- GrOpMemoryPool* pool = context->priv().opMemoryPool();
- MakeArgs makeArgs;
- if (paint.isTrivial()) {
- makeArgs.fProcessorSet = nullptr;
- return pool->allocate<Op>(makeArgs, paint.getColor4f(), std::forward<OpArgs>(opArgs)...);
- } else {
- char* mem = (char*) pool->allocate(sizeof(Op) + sizeof(GrProcessorSet));
- char* setMem = mem + sizeof(Op);
- auto color = paint.getColor4f();
- makeArgs.fProcessorSet = new (setMem) GrProcessorSet(std::move(paint));
- return std::unique_ptr<GrDrawOp>(new (mem) Op(makeArgs, color,
- std::forward<OpArgs>(opArgs)...));
- }
- }
- GR_MAKE_BITFIELD_CLASS_OPS(GrSimpleMeshDrawOpHelper::InputFlags)
- #endif
|