• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2022 Google LLC
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #include "src/gpu/graphite/render/CoverBoundsRenderStep.h"
9 
10 #include "src/base/SkVx.h"
11 #include "src/gpu/graphite/DrawParams.h"
12 #include "src/gpu/graphite/DrawWriter.h"
13 #include "src/gpu/graphite/render/CommonDepthStencilSettings.h"
14 
15 namespace skgpu::graphite {
16 
CoverBoundsRenderStep(bool inverseFill)17 CoverBoundsRenderStep::CoverBoundsRenderStep(bool inverseFill)
18         : RenderStep("CoverBoundsRenderStep",
19                      inverseFill ? "inverse" : "regular",
20                      Flags::kPerformsShading,
21                      /*uniforms=*/{},
22                      PrimitiveType::kTriangleStrip,
23                      inverseFill ? kInverseCoverPass : kRegularCoverPass,
24                      /*vertexAttrs=*/{{"position",
25                                        VertexAttribType::kFloat4,
26                                        SkSLType::kFloat4}},
27                      /*instanceAttrs=*/{{"bounds", VertexAttribType::kFloat4, SkSLType::kFloat4},
28                                         {"depth", VertexAttribType::kFloat, SkSLType::kFloat},
29                                         {"ssboIndices", VertexAttribType::kUShort2, SkSLType::kUShort2},
30                                         {"mat0", VertexAttribType::kFloat3, SkSLType::kFloat3},
31                                         {"mat1", VertexAttribType::kFloat3, SkSLType::kFloat3},
32                                         {"mat2", VertexAttribType::kFloat3, SkSLType::kFloat3}})
33         , fInverseFill(inverseFill) {}
34 
~CoverBoundsRenderStep()35 CoverBoundsRenderStep::~CoverBoundsRenderStep() {}
36 
vertexSkSL() const37 std::string CoverBoundsRenderStep::vertexSkSL() const {
38     // Returns the body of a vertex function, which must define a float4 devPosition variable and
39     // must write to an already-defined float2 stepLocalCoords variable.
40     return "float4 devPosition = cover_bounds_vertex_fn("
41                                          "float2(sk_VertexID / 2, sk_VertexID % 2), "
42                                          "bounds, depth, float3x3(mat0, mat1, mat2), "
43                                          "stepLocalCoords);\n";
44 }
45 
writeVertices(DrawWriter * writer,const DrawParams & params,skvx::ushort2 ssboIndices) const46 void CoverBoundsRenderStep::writeVertices(DrawWriter* writer,
47                                           const DrawParams& params,
48                                           skvx::ushort2 ssboIndices) const {
49     // Each instance is 4 vertices, forming 2 triangles from a single triangle strip, so no indices
50     // are needed. sk_VertexID is used to place vertex positions, so no vertex buffer is needed.
51     DrawWriter::Instances instances{*writer, {}, {}, 4};
52 
53     skvx::float4 bounds;
54     const SkM44* m;
55     if (fInverseFill) {
56         // Normally all bounding boxes are sorted such that l<r and t<b. We upload an inverted
57         // rectangle [r,b,l,t] when it's an inverse fill to encode that the bounds are already in
58         // device space and then use the inverse of the transform to compute local coordinates.
59         bounds = skvx::shuffle</*R*/2, /*B*/3, /*L*/0, /*T*/1>(
60                 skvx::cast<float>(skvx::int4::Load(&params.clip().scissor())));
61         m = &params.transform().inverse();
62     } else {
63         bounds = params.geometry().bounds().ltrb();
64         m = &params.transform().matrix();
65     }
66 
67     // Since the local coords always have Z=0, we can discard the 3rd row and column of the matrix.
68     instances.append(1) << bounds << params.order().depthAsFloat() << ssboIndices
69                         << m->rc(0,0) << m->rc(1,0) << m->rc(3,0)
70                         << m->rc(0,1) << m->rc(1,1) << m->rc(3,1)
71                         << m->rc(0,3) << m->rc(1,3) << m->rc(3,3);
72 }
73 
writeUniformsAndTextures(const DrawParams &,PipelineDataGatherer *) const74 void CoverBoundsRenderStep::writeUniformsAndTextures(const DrawParams&,
75                                                      PipelineDataGatherer*) const {
76     // All data is uploaded as instance attributes, so no uniforms are needed.
77 }
78 
79 }  // namespace skgpu::graphite
80