blob: ced5223f0651d7d9db78a0cf828a3746d12f3bca [file] [log] [blame]
/*
* Copyright 2022 Google LLC
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "src/gpu/graphite/render/MiddleOutFanRenderStep.h"
#include "src/gpu/graphite/DrawParams.h"
#include "src/gpu/graphite/DrawWriter.h"
#include "src/gpu/graphite/PipelineData.h"
#include "src/gpu/graphite/render/CommonDepthStencilSettings.h"
#include "src/gpu/tessellate/FixedCountBufferUtils.h"
#include "src/gpu/tessellate/MiddleOutPolygonTriangulator.h"
namespace skgpu::graphite {
MiddleOutFanRenderStep::MiddleOutFanRenderStep(bool evenOdd)
: RenderStep("MiddleOutFanRenderStep",
evenOdd ? "even-odd" : "winding",
Flags::kRequiresMSAA,
/*uniforms=*/{{"localToDevice", SkSLType::kFloat4x4}},
PrimitiveType::kTriangles,
evenOdd ? kEvenOddStencilPass : kWindingStencilPass,
/*vertexAttrs=*/
{{"position", VertexAttribType::kFloat2, SkSLType::kFloat2},
{"depth", VertexAttribType::kFloat, SkSLType::kFloat},
{"ssboIndices", VertexAttribType::kUShort2, SkSLType::kUShort2}},
/*instanceAttrs=*/{}) {}
MiddleOutFanRenderStep::~MiddleOutFanRenderStep() {}
std::string MiddleOutFanRenderStep::vertexSkSL() const {
return R"(
float4 devPosition = localToDevice * float4(position, 0.0, 1.0);
devPosition.z = depth;
stepLocalCoords = position;
)";
}
void MiddleOutFanRenderStep::writeVertices(DrawWriter* writer,
const DrawParams& params,
skvx::ushort2 ssboIndices) const {
// TODO: Have Shape provide a path-like iterator so we don't actually have to convert non
// paths to SkPath just to iterate their pts/verbs
SkPath path = params.geometry().shape().asPath();
const int maxTrianglesInFans = std::max(path.countVerbs() - 2, 0);
float depth = params.order().depthAsFloat();
DrawWriter::Vertices verts{*writer};
verts.reserve(maxTrianglesInFans * 3);
for (tess::PathMiddleOutFanIter it(path); !it.done();) {
for (auto [p0, p1, p2] : it.nextStack()) {
verts.append(3) << p0 << depth << ssboIndices
<< p1 << depth << ssboIndices
<< p2 << depth << ssboIndices;
}
}
}
void MiddleOutFanRenderStep::writeUniformsAndTextures(const DrawParams& params,
PipelineDataGatherer* gatherer) const {
SkDEBUGCODE(UniformExpectationsValidator uev(gatherer, this->uniforms());)
gatherer->write(params.transform().matrix());
}
} // namespace skgpu::graphite