• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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