/* * Copyright 2015 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef GrMeshDrawOp_DEFINED #define GrMeshDrawOp_DEFINED #include "include/core/SkRefCnt.h" #include "include/private/gpu/ganesh/GrTypesPriv.h" #include "src/gpu/ganesh/GrAppliedClip.h" #include "src/gpu/ganesh/ops/GrDrawOp.h" #include #include #include class GrBuffer; class GrCaps; class GrDstProxyView; class GrGeometryProcessor; class GrMeshDrawTarget; class GrOpFlushState; class GrProgramInfo; class GrRecordingContext; class GrSurfaceProxy; class GrSurfaceProxyView; class SkArenaAlloc; enum class GrXferBarrierFlags; struct GrSimpleMesh; /** * Base class for mesh-drawing GrDrawOps. */ class GrMeshDrawOp : public GrDrawOp { public: static bool CanUpgradeAAOnMerge(GrAAType aa1, GrAAType aa2) { return (aa1 == GrAAType::kNone && aa2 == GrAAType::kCoverage) || (aa1 == GrAAType::kCoverage && aa2 == GrAAType::kNone); } protected: GrMeshDrawOp(uint32_t classID); void createProgramInfo(const GrCaps* caps, SkArenaAlloc* arena, const GrSurfaceProxyView& writeView, bool usesMSAASurface, GrAppliedClip&& appliedClip, const GrDstProxyView& dstProxyView, GrXferBarrierFlags renderPassXferBarriers, GrLoadOp colorLoadOp) { this->onCreateProgramInfo(caps, arena, writeView, usesMSAASurface, std::move(appliedClip), dstProxyView, renderPassXferBarriers, colorLoadOp); } void createProgramInfo(GrMeshDrawTarget*); /** Helper for rendering repeating meshes using a patterned index buffer. This class creates the space for the vertices and flushes the draws to the GrMeshDrawTarget. */ class PatternHelper { public: PatternHelper(GrMeshDrawTarget*, GrPrimitiveType, size_t vertexStride, sk_sp indexBuffer, int verticesPerRepetition, int indicesPerRepetition, int repeatCount, int maxRepetitions); /** Called to issue draws to the GrMeshDrawTarget.*/ void recordDraw(GrMeshDrawTarget*, const GrGeometryProcessor*) const; void recordDraw(GrMeshDrawTarget*, const GrGeometryProcessor*, const GrSurfaceProxy* const primProcProxies[]) const; void* vertices() const { return fVertices; } GrSimpleMesh* mesh() { return fMesh; } protected: PatternHelper() = default; void init(GrMeshDrawTarget*, GrPrimitiveType, size_t vertexStride, sk_sp indexBuffer, int verticesPerRepetition, int indicesPerRepetition, int repeatCount, int maxRepetitions); private: void* fVertices = nullptr; GrSimpleMesh* fMesh = nullptr; GrPrimitiveType fPrimitiveType; }; /** A specialization of InstanceHelper for quad rendering. * It only draws non-antialiased indexed quads. */ class QuadHelper : private PatternHelper { public: QuadHelper() = delete; QuadHelper(GrMeshDrawTarget*, size_t vertexStride, int quadsToDraw); using PatternHelper::mesh; using PatternHelper::recordDraw; using PatternHelper::vertices; private: using INHERITED = PatternHelper; }; static bool CombinedQuadCountWillOverflow(GrAAType aaType, bool willBeUpgradedToAA, int combinedQuadCount); virtual void onPrePrepareDraws(GrRecordingContext*, const GrSurfaceProxyView& writeView, GrAppliedClip*, const GrDstProxyView&, GrXferBarrierFlags renderPassXferBarriers, GrLoadOp colorLoadOp); private: virtual GrProgramInfo* programInfo() = 0; // This method is responsible for creating all the programInfos required // by this op. virtual void onCreateProgramInfo(const GrCaps*, SkArenaAlloc*, const GrSurfaceProxyView& writeView, bool usesMSAASurface, GrAppliedClip&&, const GrDstProxyView&, GrXferBarrierFlags renderPassXferBarriers, GrLoadOp colorLoadOp) = 0; void onPrePrepare(GrRecordingContext* context, const GrSurfaceProxyView& writeView, GrAppliedClip* clip, const GrDstProxyView& dstProxyView, GrXferBarrierFlags renderPassXferBarriers, GrLoadOp colorLoadOp) final { this->onPrePrepareDraws(context, writeView, clip, dstProxyView, renderPassXferBarriers, colorLoadOp); } void onPrepare(GrOpFlushState* state) final; virtual void onPrepareDraws(GrMeshDrawTarget*) = 0; using INHERITED = GrDrawOp; }; #endif