blob: 868967c0aff2f241eaf2da68f644db2ef19e45b2 [file] [log] [blame]
/*
* Copyright 2021 Google LLC.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef PathTessellateOp_DEFINED
#define PathTessellateOp_DEFINED
#include "src/gpu/ganesh/ops/GrDrawOp.h"
#include "src/gpu/ganesh/tessellate/GrTessellationShader.h"
#include "src/gpu/ganesh/tessellate/PathTessellator.h"
#include "src/gpu/tessellate/Tessellation.h"
namespace skgpu::ganesh {
// Tessellates a path directly to the color buffer, using one single render pass. This currently
// only works for convex paths.
class PathTessellateOp final : public GrDrawOp {
private:
DEFINE_OP_CLASS_ID
using PatchAttribs = PathTessellator::PatchAttribs;
using PathDrawList = PathTessellator::PathDrawList;
PathTessellateOp(SkArenaAlloc* arena,
GrAAType aaType,
const GrUserStencilSettings* stencil,
const SkMatrix& viewMatrix,
const SkPath& path,
GrPaint&& paint,
const SkRect& drawBounds)
: GrDrawOp(ClassID())
, fAAType(aaType)
, fStencil(stencil)
, fTotalCombinedPathVerbCnt(path.countVerbs())
, fPathDrawList(arena->make<PathDrawList>(SkMatrix::I(), path, paint.getColor4f()))
, fPathDrawTail(&fPathDrawList->fNext)
, fProcessors(std::move(paint))
, fShaderMatrix(viewMatrix) {
SkASSERT(!path.isInverseFillType());
if (!this->headDraw().fColor.fitsInBytes()) {
fPatchAttribs |= PatchAttribs::kWideColorIfEnabled;
}
this->setBounds(drawBounds, HasAABloat::kNo, IsHairline::kNo);
}
PathDrawList& headDraw() { return *fPathDrawList; }
void prepareTessellator(const GrTessellationShader::ProgramArgs&, GrAppliedClip&& clip);
// GrDrawOp overrides.
const char* name() const override { return "PathTessellateOp"; }
bool usesMSAA() const override { return fAAType == GrAAType::kMSAA; }
void visitProxies(const GrVisitProxyFunc&) const override;
GrProcessorSet::Analysis finalize(const GrCaps&, const GrAppliedClip*, GrClampType) override;
bool usesStencil() const override { return !fStencil->isUnused(); }
CombineResult onCombineIfPossible(GrOp*, SkArenaAlloc*, const GrCaps&) override;
void onPrePrepare(GrRecordingContext*, const GrSurfaceProxyView&, GrAppliedClip*,
const GrDstProxyView&, GrXferBarrierFlags, GrLoadOp colorLoadOp) override;
void onPrepare(GrOpFlushState*) override;
void onExecute(GrOpFlushState*, const SkRect& chainBounds) override;
const GrAAType fAAType;
const GrUserStencilSettings* const fStencil;
int fTotalCombinedPathVerbCnt;
PatchAttribs fPatchAttribs = PatchAttribs::kNone;
PathDrawList* const fPathDrawList;
PathDrawList** fPathDrawTail;
GrProcessorSet fProcessors;
SkMatrix fShaderMatrix;
// Decided during prepareTessellator.
PathTessellator* fTessellator = nullptr;
const GrProgramInfo* fTessellationProgram = nullptr;
friend class GrOp; // For ctor.
};
} // namespace skgpu::ganesh
#endif // PathTessellateOp_DEFINED