xref: /aosp_15_r20/external/skia/src/text/gpu/VertexFiller.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1 /*
2 * Copyright 2023 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 #ifndef sktext_gpu_VertexFiller_DEFINED
8 #define sktext_gpu_VertexFiller_DEFINED
9 
10 #include "include/core/SkMatrix.h"
11 #include "include/core/SkPoint.h"
12 #include "include/core/SkRect.h"
13 #include "include/core/SkScalar.h"
14 #include "include/core/SkSpan.h"
15 #include "include/core/SkTypes.h"
16 #include "include/private/base/SkTLogic.h"
17 #include "src/base/SkVx.h"
18 
19 #include <optional>
20 #include <tuple>
21 
22 class SkReadBuffer;
23 class SkWriteBuffer;
24 
25 #if defined(SK_GANESH) || defined(SK_USE_LEGACY_GANESH_TEXT_APIS)
26 #include "src/gpu/ganesh/GrColor.h"
27 #include "src/gpu/ganesh/ops/AtlasTextOp.h"
28 
29 #include <cstddef>
30 #endif  // defined(SK_GANESH) || defined(SK_USE_LEGACY_GANESH_TEXT_APIS)
31 
32 namespace skgpu {
33 enum class MaskFormat : int;
34 
35 namespace graphite {
36 class DrawWriter;
37 class Rect;
38 class Transform;
39 }
40 }
41 
42 namespace sktext::gpu {
43 class Glyph;
44 class SubRunAllocator;
45 
46 enum FillerType {
47     kIsDirect,
48     kIsTransformed
49 };
50 
51 // -- VertexFiller ---------------------------------------------------------------------------------
52 // The VertexFiller assumes that all points, glyph atlas entries, and bounds are created with
53 // respect to the CreationMatrix. This assumes that mapping any point, mask or bounds through the
54 // CreationMatrix will result in the proper device position. In order to draw using an arbitrary
55 // PositionMatrix, calculate a
56 //
57 //    viewDifference = [PositionMatrix] * [CreationMatrix] ^ -1.
58 //
59 // The viewDifference is used to map all points, masks and bounds to position to the device
60 // respecting the PositionMatrix.
61 class VertexFiller {
62 public:
63     VertexFiller(skgpu::MaskFormat maskFormat,
64                  const SkMatrix &creationMatrix,
65                  SkRect creationBounds,
66                  SkSpan<const SkPoint> leftTop,
67                  bool canDrawDirect);
68 
69     static VertexFiller Make(skgpu::MaskFormat maskType,
70                              const SkMatrix &creationMatrix,
71                              SkRect creationBounds,
72                              SkSpan<const SkPoint> positions,
73                              SubRunAllocator *alloc,
74                              FillerType fillerType);
75 
76     static std::optional<VertexFiller> MakeFromBuffer(SkReadBuffer &buffer,
77                                                       SubRunAllocator *alloc);
78 
unflattenSize()79     int unflattenSize() const { return fLeftTop.size_bytes(); }
80 
81     void flatten(SkWriteBuffer &buffer) const;
82 
83 #if defined(SK_GANESH) || defined(SK_USE_LEGACY_GANESH_TEXT_APIS)
84     size_t vertexStride(const SkMatrix &matrix) const;
85 
86     void fillVertexData(int offset, int count,
87                         SkSpan<const Glyph*> glyphs,
88                         GrColor color,
89                         const SkMatrix& positionMatrix,
90                         SkIRect clip,
91                         void* vertexBuffer) const;
92 
93     skgpu::ganesh::AtlasTextOp::MaskType opMaskType() const;
94 #endif  // defined(SK_GANESH) || defined(SK_USE_LEGACY_GANESH_TEXT_APIS)
95 
96     // This is only available if the graphite backend is compiled in (see GraphiteVertexFiller.cpp)
97     void fillInstanceData(skgpu::graphite::DrawWriter* dw,
98                           int offset, int count,
99                           unsigned short flags,
100                           skvx::uint2 ssboIndex,
101                           SkSpan<const Glyph*> glyphs,
102                           SkScalar depth) const;
103 
104     std::tuple<skgpu::graphite::Rect, skgpu::graphite::Transform> boundsAndDeviceMatrix(
105             const skgpu::graphite::Transform& localToDevice, SkPoint drawOrigin) const;
106 
107     // Return true if the positionMatrix represents an integer translation. Return the device
108     // bounding box of all the glyphs. If the bounding box is empty, then something went singular
109     // and this operation should be dropped.
110     std::tuple<bool, SkRect> deviceRectAndCheckTransform(const SkMatrix &positionMatrix) const;
111 
grMaskType()112     skgpu::MaskFormat grMaskType() const { return fMaskType; }
113     bool isLCD() const;
114 
count()115     int count() const { return SkCount(fLeftTop); }
116 
117 private:
118     SkMatrix viewDifference(const SkMatrix &positionMatrix) const;
119 
120     const skgpu::MaskFormat fMaskType;
121     const bool fCanDrawDirect;
122     const SkMatrix fCreationMatrix;
123     const SkRect fCreationBounds;
124     const SkSpan<const SkPoint> fLeftTop;
125 };
126 
127 }  // namespace sktext::gpu
128 
129 #endif
130