1 /* 2 * Copyright 2015 Google Inc. 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 sktext_gpu_TextBlob_DEFINED 9 #define sktext_gpu_TextBlob_DEFINED 10 11 #include <algorithm> 12 #include <limits> 13 14 #include "include/core/SkRefCnt.h" 15 #include "include/private/chromium/Slug.h" 16 #include "src/base/SkTInternalLList.h" 17 #include "src/core/SkMaskFilterBase.h" 18 #include "src/text/gpu/SubRunContainer.h" 19 20 class SkMatrixProvider; 21 class SkStrikeClient; 22 class SkSurfaceProps; 23 class SkTextBlob; 24 class SkTextBlobRunIterator; 25 26 namespace sktext { 27 class GlyphRunList; 28 namespace gpu { 29 class Glyph; 30 class StrikeCache; 31 } 32 } 33 34 #if defined(SK_GANESH) // Ganesh support 35 #include "src/gpu/ganesh/GrColor.h" 36 #include "src/gpu/ganesh/ops/GrOp.h" 37 class GrAtlasManager; 38 class GrDeferredUploadTarget; 39 class GrMeshDrawTarget; 40 namespace skgpu::v1 { class SurfaceDrawContext; } 41 #endif 42 43 namespace sktext::gpu { 44 45 // -- TextBlob ----------------------------------------------------------------------------------- 46 // A TextBlob contains a fully processed SkTextBlob, suitable for nearly immediate drawing 47 // on the GPU. These are initially created with valid positions and colors, but with invalid 48 // texture coordinates. 49 // 50 // A TextBlob contains a number of SubRuns that are created in the blob's arena. Each SubRun 51 // tracks its own glyph and position data. 52 // 53 // In these classes, I'm trying to follow the convention about matrices and origins. 54 // * drawMatrix and drawOrigin - describes transformations for the current draw command. 55 // * positionMatrix - is equal to drawMatrix * [drawOrigin-as-translation-matrix] 56 // * initial Matrix - describes the combined initial matrix and origin the TextBlob was created 57 // with. 58 // 59 // 60 class TextBlob final : public SkRefCnt { 61 public: 62 // Key is not used as part of a hash map, so the hash is never taken. It's only used in a 63 // list search using operator =(). 64 struct Key { 65 static std::tuple<bool, Key> Make(const GlyphRunList& glyphRunList, 66 const SkPaint& paint, 67 const SkMatrix& drawMatrix, 68 const SkStrikeDeviceInfo& strikeDevice); 69 uint32_t fUniqueID; 70 // Color may affect the gamma of the mask we generate, but in a fairly limited way. 71 // Each color is assigned to on of a fixed number of buckets based on its 72 // luminance. For each luminance bucket there is a "canonical color" that 73 // represents the bucket. This functionality is currently only supported for A8 74 SkColor fCanonicalColor; 75 SkScalar fFrameWidth; 76 SkScalar fMiterLimit; 77 SkPixelGeometry fPixelGeometry; 78 SkMaskFilterBase::BlurRec fBlurRec; 79 uint32_t fScalerContextFlags; 80 SkMatrix fPositionMatrix; 81 // Below here fields are of size 1 byte. 82 bool fHasSomeDirectSubRuns; 83 bool fHasBlur; 84 SkPaint::Style fStyle; 85 SkPaint::Join fJoin; 86 87 bool operator==(const Key& other) const; 88 }; 89 90 SK_DECLARE_INTERNAL_LLIST_INTERFACE(TextBlob); 91 92 // Make a TextBlob and its sub runs. 93 static sk_sp<TextBlob> Make(const sktext::GlyphRunList& glyphRunList, 94 const SkPaint& paint, 95 const SkMatrix& positionMatrix, 96 SkStrikeDeviceInfo strikeDeviceInfo, 97 StrikeForGPUCacheInterface* strikeCache); 98 99 TextBlob(SubRunAllocator&& alloc, 100 SubRunContainerOwner subRuns, 101 int totalMemorySize, 102 SkColor initialLuminance); 103 104 ~TextBlob() override; 105 106 // Change memory management to handle the data after TextBlob, but in the same allocation 107 // of memory. Only allow placement new. 108 void operator delete(void* p); 109 void* operator new(size_t); 110 void* operator new(size_t, void* p); 111 key()112 const Key& key() { return fKey; } 113 114 void addKey(const Key& key); 115 bool hasPerspective() const; 116 117 bool canReuse(const SkPaint& paint, const SkMatrix& positionMatrix) const; 118 119 const Key& key() const; size()120 size_t size() const { return SkTo<size_t>(fSize); } 121 122 #if defined(SK_GANESH) 123 void draw(SkCanvas*, 124 const GrClip* clip, 125 const SkMatrixProvider& viewMatrix, 126 SkPoint drawOrigin, 127 const SkPaint& paint, 128 skgpu::v1::SurfaceDrawContext* sdc); 129 #endif 130 #if defined(SK_GRAPHITE) 131 void draw(SkCanvas*, 132 SkPoint drawOrigin, 133 const SkPaint& paint, 134 skgpu::graphite::Device* device); 135 #endif 136 const AtlasSubRun* testingOnlyFirstSubRun() const; 137 138 private: 139 // The allocator must come first because it needs to be destroyed last. Other fields of this 140 // structure may have pointers into it. 141 SubRunAllocator fAlloc; 142 143 SubRunContainerOwner fSubRuns; 144 145 // Overall size of this struct plus vertices and glyphs at the end. 146 const int fSize; 147 148 const SkColor fInitialLuminance; 149 150 Key fKey; 151 }; 152 153 } // namespace sktext::gpu 154 155 namespace skgpu::v1 { 156 sk_sp<sktext::gpu::Slug> MakeSlug(const SkMatrixProvider& drawMatrix, 157 const sktext::GlyphRunList& glyphRunList, 158 const SkPaint& initialPaint, 159 const SkPaint& drawingPaint, 160 SkStrikeDeviceInfo strikeDeviceInfo, 161 sktext::StrikeForGPUCacheInterface* strikeCache); 162 } // namespace skgpu::v1 163 #endif // sktext_gpu_TextBlob_DEFINED 164