1/*
2 * Copyright 2021 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 "experimental/graphite/src/DrawList.h"
9
10#include "experimental/graphite/src/Renderer.h"
11#include "include/core/SkShader.h"
12#include "src/gpu/BufferWriter.h"
13
14namespace skgpu {
15
16PaintParams::PaintParams(const SkColor4f& color,
17                         SkBlendMode blendMode,
18                         sk_sp<SkShader> shader)
19        : fColor(color)
20        , fBlendMode(blendMode)
21        , fShader(std::move(shader)) {
22}
23PaintParams::PaintParams(const PaintParams& other)
24        : fColor(other.fColor)
25        , fBlendMode(other.fBlendMode)
26        , fShader(other.fShader) {
27}
28PaintParams::~PaintParams() {}
29
30PaintParams& PaintParams::operator=(const PaintParams& other) {
31    fColor = other.fColor;
32    fBlendMode = other.fBlendMode;
33    fShader = other.fShader;
34    return *this;
35}
36
37sk_sp<SkShader> PaintParams::refShader() const { return fShader; }
38
39const Transform& DrawList::deduplicateTransform(const Transform& localToDevice) {
40    // TODO: This is a pretty simple deduplication strategy and doesn't take advantage of the stack
41    // knowledge that Device has.
42    if (fTransforms.empty() || fTransforms.back() != localToDevice) {
43        fTransforms.push_back(localToDevice);
44    }
45    return fTransforms.back();
46}
47
48void DrawList::stencilAndFillPath(const Transform& localToDevice,
49                                  const Shape& shape,
50                                  const Clip& clip,
51                                  DrawOrder ordering,
52                                  const PaintParams* paint) {
53    SkASSERT(localToDevice.valid());
54    SkASSERT(!shape.isEmpty() && !clip.drawBounds().isEmptyNegativeOrNaN());
55    fDraws.push_back({Renderer::StencilAndFillPath(),
56                      this->deduplicateTransform(localToDevice),
57                      shape, clip, ordering, paint, nullptr});
58    fRenderStepCount += Renderer::StencilAndFillPath().numRenderSteps();
59}
60
61void DrawList::fillConvexPath(const Transform& localToDevice,
62                              const Shape& shape,
63                              const Clip& clip,
64                              DrawOrder ordering,
65                              const PaintParams* paint) {
66    SkASSERT(localToDevice.valid());
67    SkASSERT(!shape.isEmpty() && !clip.drawBounds().isEmptyNegativeOrNaN());
68    // TODO actually record this, but for now just drop the draw since the Renderer
69    // isn't implemented yet
70    // fDraws.push_back({Renderer::FillConvexPath(),
71    //                   this->deduplicateTransform(localToDevice),
72    //                   shape, clip, ordering, paint, nullptr});
73    // fRenderStepCount += Renderer::FillConvexPath().numRenderSteps();
74}
75
76void DrawList::strokePath(const Transform& localToDevice,
77                          const Shape& shape,
78                          const StrokeParams& stroke,
79                          const Clip& clip,
80                          DrawOrder ordering,
81                          const PaintParams* paint) {
82    SkASSERT(localToDevice.valid());
83    SkASSERT(!shape.isEmpty() && !clip.drawBounds().isEmptyNegativeOrNaN());
84    // TODO actually record this, but for now just drop the draw since the Renderer
85    // isn't implemented yet
86    // fDraws.push_back({Renderer::StrokePath(),
87    //                   this->deduplicateTransform(localToDevice),
88    //                   shape, clip, ordering, paint, stroke});
89    // fRenderStepCount += Renderer::StrokePath().numRenderSteps();
90}
91
92size_t DrawList::Draw::requiredVertexSpace(int renderStep) const {
93    SkASSERT(renderStep < fRenderer.numRenderSteps());
94    return fRenderer.steps()[renderStep]->requiredVertexSpace(fShape);
95}
96
97size_t DrawList::Draw::requiredIndexSpace(int renderStep) const {
98    SkASSERT(renderStep < fRenderer.numRenderSteps());
99    return fRenderer.steps()[renderStep]->requiredIndexSpace(fShape);
100}
101
102void DrawList::Draw::writeVertices(VertexWriter vertexWriter,
103                                   IndexWriter indexWriter,
104                                   int renderStep) const {
105    SkASSERT(renderStep < fRenderer.numRenderSteps());
106    fRenderer.steps()[renderStep]->writeVertices(std::move(vertexWriter),
107                                                 std::move(indexWriter),
108                                                 fShape);
109}
110
111} // namespace skgpu
112