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