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