• 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 "include/core/SkM44.h"
11 #include "src/base/SkEnumBitMask.h"
12 #include "src/base/SkVx.h"
13 #include "src/core/SkSLTypeShared.h"
14 #include "src/gpu/BufferWriter.h"
15 #include "src/gpu/graphite/Attribute.h"
16 #include "src/gpu/graphite/DrawOrder.h"
17 #include "src/gpu/graphite/DrawParams.h"
18 #include "src/gpu/graphite/DrawTypes.h"
19 #include "src/gpu/graphite/DrawWriter.h"
20 #include "src/gpu/graphite/geom/Geometry.h"
21 #include "src/gpu/graphite/geom/Rect.h"
22 #include "src/gpu/graphite/geom/Shape.h"
23 #include "src/gpu/graphite/geom/Transform.h"
24 
25 namespace skgpu::graphite {
26 
CoverBoundsRenderStep(RenderStep::RenderStepID renderStepID,DepthStencilSettings dsSettings)27 CoverBoundsRenderStep::CoverBoundsRenderStep(RenderStep::RenderStepID renderStepID,
28                                              DepthStencilSettings dsSettings)
29         : RenderStep(renderStepID,
30                      Flags::kPerformsShading,
31                      /*uniforms=*/{},
32                      PrimitiveType::kTriangleStrip,
33                      dsSettings,
34                      /*vertexAttrs=*/  {},
35                      /*instanceAttrs=*/{{"bounds", VertexAttribType::kFloat4, SkSLType::kFloat4},
36                                         {"depth", VertexAttribType::kFloat, SkSLType::kFloat},
37                                         {"ssboIndices", VertexAttribType::kUInt2, SkSLType::kUInt2},
38                                         {"mat0", VertexAttribType::kFloat3, SkSLType::kFloat3},
39                                         {"mat1", VertexAttribType::kFloat3, SkSLType::kFloat3},
40                                         {"mat2", VertexAttribType::kFloat3, SkSLType::kFloat3}}) {}
41 
~CoverBoundsRenderStep()42 CoverBoundsRenderStep::~CoverBoundsRenderStep() {}
43 
vertexSkSL() const44 std::string CoverBoundsRenderStep::vertexSkSL() const {
45     // Returns the body of a vertex function, which must define a float4 devPosition variable and
46     // must write to an already-defined float2 stepLocalCoords variable.
47     return "float4 devPosition = cover_bounds_vertex_fn("
48                                          "float2(sk_VertexID / 2, sk_VertexID % 2), "
49                                          "bounds, depth, float3x3(mat0, mat1, mat2), "
50                                          "stepLocalCoords);\n";
51 }
52 
writeVertices(DrawWriter * writer,const DrawParams & params,skvx::uint2 ssboIndices) const53 void CoverBoundsRenderStep::writeVertices(DrawWriter* writer,
54                                           const DrawParams& params,
55                                           skvx::uint2 ssboIndices) const {
56     // Each instance is 4 vertices, forming 2 triangles from a single triangle strip, so no indices
57     // are needed. sk_VertexID is used to place vertex positions, so no vertex buffer is needed.
58     DrawWriter::Instances instances{*writer, {}, {}, 4};
59 
60     skvx::float4 bounds;
61     if (params.geometry().isShape() && params.geometry().shape().inverted()) {
62         // Normally all bounding boxes are sorted such that l<r and t<b. We upload an inverted
63         // rectangle [r,b,l,t] when it's an inverse fill to encode that the bounds are already in
64         // device space and then the VS will use the inverse of the transform to compute local
65         // coordinates.
66         bounds = skvx::shuffle</*R*/2, /*B*/3, /*L*/0, /*T*/1>(
67                 skvx::cast<float>(skvx::int4::Load(&params.clip().scissor())));
68     } else {
69         bounds = params.geometry().bounds().ltrb();
70     }
71 
72     // Since the local coords always have Z=0, we can discard the 3rd row and column of the matrix.
73     const SkM44& m = params.transform().matrix();
74     instances.append(1) << bounds << params.order().depthAsFloat() << ssboIndices
75                         << m.rc(0,0) << m.rc(1,0) << m.rc(3,0)
76                         << m.rc(0,1) << m.rc(1,1) << m.rc(3,1)
77                         << m.rc(0,3) << m.rc(1,3) << m.rc(3,3);
78 }
79 
writeUniformsAndTextures(const DrawParams &,PipelineDataGatherer *) const80 void CoverBoundsRenderStep::writeUniformsAndTextures(const DrawParams&,
81                                                      PipelineDataGatherer*) const {
82     // All data is uploaded as instance attributes, so no uniforms are needed.
83 }
84 
85 }  // namespace skgpu::graphite
86