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