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 #ifndef skgpu_graphite_DrawList_DEFINED 9 #define skgpu_graphite_DrawList_DEFINED 10 11 #include "include/core/SkPaint.h" 12 #include "src/base/SkTBlockList.h" 13 14 #include "src/gpu/graphite/DrawOrder.h" 15 #include "src/gpu/graphite/DrawParams.h" 16 #include "src/gpu/graphite/PaintParams.h" 17 #include "src/gpu/graphite/geom/Geometry.h" 18 #include "src/gpu/graphite/geom/Transform_graphite.h" 19 20 #include <limits> 21 #include <optional> 22 23 namespace skgpu::graphite { 24 25 class Renderer; 26 27 /** 28 * A DrawList represents a collection of drawing commands (and related clip/shading state) in 29 * a form that closely mirrors what can be rendered efficiently and directly by the GPU backend 30 * (while balancing how much pre-processing to do for draws that might get eliminated later due to 31 * occlusion culling). 32 * 33 * A draw command combines: 34 * - a shape 35 * - a transform 36 * - a primitive clip (not affected by the transform) 37 * - optional shading description (shader, color filter, blend mode, etc) 38 * - a draw ordering (compressed painters index, stencil set, and write/test depth) 39 * 40 * Commands are accumulated in an arbitrary order and then sorted by increasing sort z when the list 41 * is prepared into an actual command buffer. The result of a draw command is the rasterization of 42 * the transformed shape, restricted by its primitive clip (e.g. a scissor rect) and a depth test 43 * of "GREATER" vs. its write/test z. (A test of GREATER, as opposed to GEQUAL, avoids double hits 44 * for draws that may have overlapping geometry, e.g. stroking.) If the command has a shading 45 * description, the color buffer will be modified; if not, it will be a depth-only draw. 46 * 47 * In addition to sorting the collected commands, the command list can be optimized during 48 * preparation. Commands that are fully occluded by later operations can be skipped entirely without 49 * affecting the final results. Adjacent commands (post sort) that would use equivalent GPU 50 * pipelines are merged to produce fewer (but larger) operations on the GPU. 51 * 52 * Other than flush-time optimizations (sort, cull, and merge), the command list does what you tell 53 * it to. Draw-specific simplification, style application, and advanced clipping should be handled 54 * at a higher layer. 55 */ 56 class DrawList { 57 public: 58 // The maximum number of draw calls that can be recorded into a DrawList before it must be 59 // converted to a DrawPass. The true fundamental limit is imposed by the limits of the depth 60 // attachment and precision of CompressedPaintersOrder and PaintDepth. These values can be 61 // shared by multiple draw calls so it's more difficult to reason about how much room is left 62 // in a DrawList. Limiting it to this keeps tracking simple and ensures that the sequences in 63 // DrawOrder cannot overflow since they are always less than or equal to the number of draws. 64 static constexpr int kMaxDraws = std::numeric_limits<uint16_t>::max(); 65 66 // DrawList requires that all Transforms be valid and asserts as much; invalid transforms should 67 // be detected at the Device level or similar. The provided Renderer must be compatible with the 68 // 'shape' and 'stroke' parameters. If the renderer uses coverage AA, 'ordering' must have a 69 // compressed painters order that reflects that. If the renderer uses stencil, the 'ordering' 70 // must have a valid stencil index as well. 71 void recordDraw(const Renderer* renderer, 72 const Transform& localToDevice, 73 const Geometry& geometry, 74 const Clip& clip, 75 DrawOrder ordering, 76 const PaintParams* paint, 77 const StrokeStyle* stroke); 78 drawCount()79 int drawCount() const { return fDraws.count(); } renderStepCount()80 int renderStepCount() const { return fRenderStepCount; } 81 82 private: 83 friend class DrawPass; 84 85 struct Draw { 86 const Renderer* fRenderer; // Owned by SharedContext of Recorder that recorded the draw 87 DrawParams fDrawParams; // The DrawParam's transform is owned by fTransforms of the DrawList 88 std::optional<PaintParams> fPaintParams; // Not present implies depth-only draw 89 DrawDraw90 Draw(const Renderer* renderer, const Transform& transform, const Geometry& geometry, 91 const Clip& clip, DrawOrder order, const PaintParams* paint, 92 const StrokeStyle* stroke) 93 : fRenderer(renderer) 94 , fDrawParams(transform, geometry, clip, order, stroke) 95 , fPaintParams(paint ? std::optional<PaintParams>(*paint) : std::nullopt) {} 96 }; 97 98 // The returned Transform reference remains valid for the lifetime of the DrawList. 99 const Transform& deduplicateTransform(const Transform&); 100 101 SkTBlockList<Transform, 16> fTransforms; 102 SkTBlockList<Draw, 16> fDraws; 103 104 // Running total of RenderSteps for all draws, assuming nothing is culled 105 int fRenderStepCount; 106 }; 107 108 } // namespace skgpu::graphite 109 110 #endif // skgpu_graphite_DrawList_DEFINED 111