blob: 7b39986540914b83c8fb162ee23ef51aada026f7 [file] [log] [blame]
/*
* Copyright 2020 Google LLC.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef GrTessellationShader_DEFINED
#define GrTessellationShader_DEFINED
#include "src/gpu/BufferWriter.h"
#include "src/gpu/GrGeometryProcessor.h"
#include "src/gpu/GrProgramInfo.h"
class SkArenaAlloc;
// This is a common base class for shaders in the GPU tessellator.
class GrTessellationShader : public GrGeometryProcessor {
public:
GrTessellationShader(ClassID classID, GrPrimitiveType primitiveType,
int tessellationPatchVertexCount, const SkMatrix& viewMatrix,
const SkPMColor4f& color)
: GrGeometryProcessor(classID)
, fPrimitiveType(primitiveType)
, fTessellationPatchVertexCount(tessellationPatchVertexCount)
, fViewMatrix(viewMatrix)
, fColor(color) {
if (fTessellationPatchVertexCount) {
this->setWillUseTessellationShaders();
}
}
GrPrimitiveType primitiveType() const { return fPrimitiveType; }
int tessellationPatchVertexCount() const { return fTessellationPatchVertexCount; }
const SkMatrix& viewMatrix() const { return fViewMatrix; }
const SkPMColor4f& color() const { return fColor;}
// A conic curve is written out with p3=[w,Infinity], but GPUs that don't support infinity can't
// detect this. On these platforms we also write out an extra float with each patch that
// explicitly tells the shader what type of curve it is.
inline constexpr static float kCubicCurveType = 0;
inline constexpr static float kConicCurveType = 1;
inline constexpr static float kTriangularConicCurveType = 2; // Conic curve with w=Infinity.
// Fills in a 4-point patch in such a way that the shader will recognize it as a conic.
static void WriteConicPatch(const SkPoint pts[3], float w, skgpu::VertexWriter* writer) {
// Write out the 3 conic points to patch[0..2], the weight to patch[3].x, and then set
// patch[3].y as NaN to flag this patch as a conic.
writer->writeArray(pts, 3);
*writer << w << skgpu::VertexWriter::kIEEE_32_infinity;
}
static void WriteConicPatch(const SkPoint pts[3], float w, SkPoint patch[4]) {
skgpu::VertexWriter writer(patch);
WriteConicPatch(pts, w, &writer);
}
struct ProgramArgs {
SkArenaAlloc* fArena;
const GrSurfaceProxyView& fWriteView;
bool fUsesMSAASurface;
const GrDstProxyView* fDstProxyView;
GrXferBarrierFlags fXferBarrierFlags;
GrLoadOp fColorLoadOp;
const GrCaps* fCaps;
};
static const GrPipeline* MakePipeline(const ProgramArgs&, GrAAType,
GrAppliedClip&&, GrProcessorSet&&);
static GrProgramInfo* MakeProgram(const ProgramArgs& args,
const GrTessellationShader* shader,
const GrPipeline* pipeline,
const GrUserStencilSettings* stencil) {
return args.fArena->make<GrProgramInfo>(*args.fCaps, args.fWriteView, args.fUsesMSAASurface,
pipeline, stencil, shader, shader->fPrimitiveType,
shader->fTessellationPatchVertexCount,
args.fXferBarrierFlags, args.fColorLoadOp);
}
private:
const GrPrimitiveType fPrimitiveType;
const int fTessellationPatchVertexCount;
const SkMatrix fViewMatrix;
const SkPMColor4f fColor;
};
#endif