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 GrTextBlob_DEFINED 9 #define GrTextBlob_DEFINED 10 11 #include <algorithm> 12 #include <limits> 13 14 #include "include/core/SkPoint3.h" 15 #include "include/core/SkRefCnt.h" 16 #include "src/core/SkGlyphRunPainter.h" 17 #include "src/core/SkIPoint16.h" 18 #include "src/core/SkMaskFilterBase.h" 19 #include "src/core/SkOpts.h" 20 #include "src/core/SkRectPriv.h" 21 #include "src/core/SkStrikeSpec.h" 22 #include "src/core/SkTLazy.h" 23 #include "src/gpu/GrColor.h" 24 #include "src/gpu/GrSubRunAllocator.h" 25 #include "src/gpu/ops/GrMeshDrawOp.h" 26 #include "src/gpu/ops/GrOp.h" 27 28 class GrAtlasManager; 29 class GrAtlasTextOp; 30 class GrDeferredUploadTarget; 31 class GrGlyph; 32 class GrStrikeCache; 33 class GrSubRun; 34 35 class SkMatrixProvider; 36 class SkSurfaceProps; 37 class SkTextBlob; 38 class SkTextBlobRunIterator; 39 40 41 // -- GrAtlasSubRun -------------------------------------------------------------------------------- 42 // GrAtlasSubRun is the API that GrAtlasTextOp uses to generate vertex data for drawing. 43 // There are three different ways GrAtlasSubRun is specialized. 44 // * DirectMaskSubRun - this is by far the most common type of SubRun. The mask pixels are 45 // in 1:1 correspondence with the pixels on the device. The destination rectangles in this 46 // SubRun are in device space. This SubRun handles color glyphs. 47 // * TransformedMaskSubRun - handles glyph where the image in the atlas needs to be 48 // transformed to the screen. It is usually used for large color glyph which can't be 49 // drawn with paths or scaled distance fields. The destination rectangles are in source 50 // space. 51 // * SDFTSubRun - scaled distance field text handles largish single color glyphs that still 52 // can fit in the atlas; the sizes between direct SubRun, and path SubRun. The destination 53 54 class GrAtlasSubRun; 55 using GrAtlasSubRunOwner = std::unique_ptr<GrAtlasSubRun, GrSubRunAllocator::Destroyer>; 56 class GrAtlasSubRun { 57 public: 58 static constexpr int kVerticesPerGlyph = 4; 59 60 virtual ~GrAtlasSubRun() = default; 61 62 virtual size_t vertexStride(const SkMatrix& drawMatrix) const = 0; 63 virtual int glyphCount() const = 0; 64 65 virtual std::tuple<const GrClip*, GrOp::Owner> 66 makeAtlasTextOp( 67 const GrClip* clip, 68 const SkMatrixProvider& viewMatrix, 69 const SkGlyphRunList& glyphRunList, 70 const SkPaint& paint, 71 GrSurfaceDrawContext* rtc, 72 GrAtlasSubRunOwner subRun) const = 0; 73 virtual void fillVertexData( 74 void* vertexDst, int offset, int count, 75 GrColor color, const SkMatrix& positionMatrix, 76 SkIRect clip) const = 0; 77 78 virtual void testingOnly_packedGlyphIDToGrGlyph(GrStrikeCache* cache) = 0; 79 80 // This call is not thread safe. It should only be called from GrDrawOp::onPrepare which 81 // is single threaded. 82 virtual std::tuple<bool, int> regenerateAtlas( 83 int begin, int end, GrMeshDrawOp::Target* target) const = 0; 84 }; 85 86 // -- GrSubRun ------------------------------------------------------------------------------------- 87 // GrSubRun is the API the GrTextBlob uses for the SubRun. 88 // There are several types of SubRun, which can be broken into five classes: 89 // * PathSubRun - handle very large single color glyphs using paths to render the glyph. 90 // * DirectMaskSubRun - handle the majority of the glyphs where the cache entry's pixels are in 91 // 1:1 correspondence to the device pixels. 92 // * TransformedMaskSubRun - handle large bitmap/argb glyphs that need to be scaled to the screen. 93 // * SDFTSubRun - use signed distance fields to draw largish glyphs to the screen. 94 // * GrAtlasSubRun - this is an abstract class used for atlas drawing. 95 class GrSubRun; 96 using GrSubRunOwner = std::unique_ptr<GrSubRun, GrSubRunAllocator::Destroyer>; 97 class GrSubRun { 98 public: 99 virtual ~GrSubRun() = default; 100 101 // Produce GPU ops for this subRun. 102 virtual void draw(const GrClip* clip, 103 const SkMatrixProvider& viewMatrix, 104 const SkGlyphRunList& glyphRunList, 105 const SkPaint& paint, 106 GrSurfaceDrawContext* rtc) const = 0; 107 108 // Given an already cached subRun, can this subRun handle this combination paint, matrix, and 109 // position. 110 virtual bool canReuse(const SkPaint& paint, const SkMatrix& drawMatrix) const = 0; 111 112 // Return the underlying atlas SubRun if it exists. Otherwise, return nullptr. 113 // * Don't use this API. It is only to support testing. 114 virtual GrAtlasSubRun* testingOnly_atlasSubRun() = 0; 115 116 GrSubRunOwner fNext; 117 }; 118 119 struct GrSubRunList { 120 class Iterator { 121 public: 122 using value_type = GrSubRun; 123 using difference_type = ptrdiff_t; 124 using pointer = value_type*; 125 using reference = value_type&; 126 using iterator_category = std::input_iterator_tag; IteratorGrSubRunList127 Iterator(GrSubRun* subRun) : fPtr{subRun} { } 128 Iterator& operator++() { fPtr = fPtr->fNext.get(); return *this; } 129 Iterator operator++(int) { Iterator tmp(*this); operator++(); return tmp; } 130 bool operator==(const Iterator& rhs) const { return fPtr == rhs.fPtr; } 131 bool operator!=(const Iterator& rhs) const { return fPtr != rhs.fPtr; } 132 reference operator*() { return *fPtr; } 133 134 private: 135 GrSubRun* fPtr; 136 }; 137 appendGrSubRunList138 void append(GrSubRunOwner subRun) { 139 GrSubRunOwner* newTail = &subRun->fNext; 140 *fTail = std::move(subRun); 141 fTail = newTail; 142 } isEmptyGrSubRunList143 bool isEmpty() const { return fHead == nullptr; } beginGrSubRunList144 Iterator begin() { return Iterator{ fHead.get()}; } endGrSubRunList145 Iterator end() { return Iterator{nullptr}; } beginGrSubRunList146 Iterator begin() const { return Iterator{ fHead.get()}; } endGrSubRunList147 Iterator end() const { return Iterator{nullptr}; } frontGrSubRunList148 GrSubRun& front() const {return *fHead; } 149 150 GrSubRunOwner fHead{nullptr}; 151 GrSubRunOwner* fTail{&fHead}; 152 }; 153 154 // A GrTextBlob contains a fully processed SkTextBlob, suitable for nearly immediate drawing 155 // on the GPU. These are initially created with valid positions and colors, but invalid 156 // texture coordinates. 157 // 158 // A GrTextBlob contains a number of SubRuns that are created in the blob's arena. Each SubRun 159 // tracks its own GrGlyph* and vertex data. The memory is organized in the arena in the following 160 // way so that the pointers for the GrGlyph* and vertex data are known before creating the SubRun. 161 // 162 // GrGlyph*... | vertexData... | SubRun | GrGlyph*... | vertexData... | SubRun etc. 163 // 164 // In these classes, I'm trying to follow the convention about matrices and origins. 165 // * draw Matrix|Origin - describes the current draw command. 166 // * initial Matrix - describes the combined initial matrix and origin the GrTextBlob was created 167 // with. 168 // 169 // 170 class GrTextBlob final : public SkNVRefCnt<GrTextBlob>, public SkGlyphRunPainterInterface { 171 public: 172 173 // Key is not used as part of a hash map, so the hash is never taken. It's only used in a 174 // list search using operator =(). 175 struct Key { 176 static std::tuple<bool, Key> Make(const SkGlyphRunList& glyphRunList, 177 const SkPaint& paint, 178 const SkSurfaceProps& surfaceProps, 179 const GrColorInfo& colorInfo, 180 const SkMatrix& drawMatrix, 181 const GrSDFTControl& control); 182 uint32_t fUniqueID; 183 // Color may affect the gamma of the mask we generate, but in a fairly limited way. 184 // Each color is assigned to on of a fixed number of buckets based on its 185 // luminance. For each luminance bucket there is a "canonical color" that 186 // represents the bucket. This functionality is currently only supported for A8 187 SkColor fCanonicalColor; 188 SkScalar fFrameWidth; 189 SkScalar fMiterLimit; 190 SkPixelGeometry fPixelGeometry; 191 SkMaskFilterBase::BlurRec fBlurRec; 192 uint32_t fScalerContextFlags; 193 SkMatrix fDrawMatrix; 194 // Below here fields are of size 1 byte. 195 uint8_t fSetOfDrawingTypes; 196 bool fHasBlur; 197 SkPaint::Style fStyle; 198 SkPaint::Join fJoin; 199 200 bool operator==(const Key& other) const; 201 }; 202 203 SK_DECLARE_INTERNAL_LLIST_INTERFACE(GrTextBlob); 204 205 // Make a GrTextBlob and its sub runs. 206 static sk_sp<GrTextBlob> Make(const SkGlyphRunList& glyphRunList, 207 const SkPaint& paint, 208 const SkMatrix& drawMatrix, 209 const GrSDFTControl& control, 210 SkGlyphRunListPainter* painter); 211 212 ~GrTextBlob() override; 213 214 // Change memory management to handle the data after GrTextBlob, but in the same allocation 215 // of memory. Only allow placement new. 216 void operator delete(void* p); 217 void* operator new(size_t); 218 void* operator new(size_t, void* p); 219 key()220 const Key& key() { return fKey; } 221 222 void addKey(const Key& key); 223 bool hasPerspective() const; initialMatrix()224 const SkMatrix& initialMatrix() const { return fInitialMatrix; } 225 scaleBounds()226 std::tuple<SkScalar, SkScalar> scaleBounds() const { 227 return {fMaxMinScale, fMinMaxScale}; 228 } 229 230 bool canReuse(const SkPaint& paint, const SkMatrix& drawMatrix) const; 231 232 const Key& key() const; 233 size_t size() const; 234 subRunList()235 const GrSubRunList& subRunList() const { 236 return fSubRunList; 237 } 238 239 private: 240 GrTextBlob(int allocSize, const SkMatrix& drawMatrix, SkColor initialLuminance); 241 242 template<typename AddSingleMaskFormat> 243 void addMultiMaskFormat( 244 AddSingleMaskFormat addSingle, 245 const SkZip<SkGlyphVariant, SkPoint>& drawables, 246 const SkStrikeSpec& strikeSpec); 247 248 // Methods to satisfy SkGlyphRunPainterInterface 249 void processDeviceMasks(const SkZip<SkGlyphVariant, SkPoint>& drawables, 250 const SkStrikeSpec& strikeSpec) override; 251 void processSourcePaths(const SkZip<SkGlyphVariant, SkPoint>& drawables, 252 const SkFont& runFont, 253 const SkStrikeSpec& strikeSpec) override; 254 void processSourceSDFT(const SkZip<SkGlyphVariant, SkPoint>& drawables, 255 const SkStrikeSpec& strikeSpec, 256 const SkFont& runFont, 257 SkScalar minScale, 258 SkScalar maxScale) override; 259 void processSourceMasks(const SkZip<SkGlyphVariant, SkPoint>& drawables, 260 const SkStrikeSpec& strikeSpec) override; 261 262 // The allocator must come first because it needs to be destroyed last. Other fields of this 263 // structure may have pointers into it. 264 GrSubRunAllocator fAlloc; 265 266 // Owner and list of the SubRun. 267 GrSubRunList fSubRunList; 268 269 // Overall size of this struct plus vertices and glyphs at the end. 270 const int fSize; 271 272 // The initial view matrix combined with the initial origin. Used to determine if a cached 273 // subRun can be used in this draw situation. 274 const SkMatrix fInitialMatrix; 275 276 const SkColor fInitialLuminance; 277 278 Key fKey; 279 280 // We can reuse distance field text, but only if the new view matrix would not result in 281 // a mip change. Because there can be multiple runs in a blob, we track the overall 282 // maximum minimum scale, and minimum maximum scale, we can support before we need to regen 283 SkScalar fMaxMinScale{-SK_ScalarMax}; 284 SkScalar fMinMaxScale{SK_ScalarMax}; 285 286 bool fSomeGlyphsExcluded{false}; 287 }; 288 289 class GrSubRunNoCachePainter : public SkGlyphRunPainterInterface { 290 public: 291 GrSubRunNoCachePainter(GrSurfaceDrawContext* sdc, 292 GrSubRunAllocator* alloc, 293 const GrClip* clip, 294 const SkMatrixProvider& viewMatrix, 295 const SkGlyphRunList& glyphRunList, 296 const SkPaint& paint); 297 void processDeviceMasks(const SkZip<SkGlyphVariant, SkPoint>& drawables, 298 const SkStrikeSpec& strikeSpec) override; 299 void processSourceMasks(const SkZip<SkGlyphVariant, SkPoint>& drawables, 300 const SkStrikeSpec& strikeSpec) override; 301 void processSourcePaths(const SkZip<SkGlyphVariant, SkPoint>& drawables, 302 const SkFont& runFont, const SkStrikeSpec& strikeSpec) override; 303 void processSourceSDFT(const SkZip<SkGlyphVariant, SkPoint>& drawables, 304 const SkStrikeSpec& strikeSpec, const SkFont& runFont, 305 SkScalar minScale, SkScalar maxScale) override; 306 private: 307 // Draw passes ownership of the sub run to the op. 308 void draw(GrAtlasSubRunOwner subRun); 309 310 GrSurfaceDrawContext* const fSDC; 311 GrSubRunAllocator* const fAlloc; 312 const GrClip* const fClip; 313 const SkMatrixProvider& fViewMatrix; 314 const SkGlyphRunList& fGlyphRunList; 315 const SkPaint& fPaint; 316 }; 317 318 #endif // GrTextBlob_DEFINED 319