Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1063)

Side by Side Diff: src/gpu/text/GrAtlasTextBlob.h

Issue 1606943002: A few more small changes to make GrAtlasTextBlob nearly self contained (Closed) Base URL: https://skia.googlesource.com/skia.git@cleanuptext16
Patch Set: cleanup Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/gpu/batches/GrAtlasTextBatch.cpp ('k') | src/gpu/text/GrAtlasTextBlob.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2015 Google Inc. 2 * Copyright 2015 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #ifndef GrAtlasTextBlob_DEFINED 8 #ifndef GrAtlasTextBlob_DEFINED
9 #define GrAtlasTextBlob_DEFINED 9 #define GrAtlasTextBlob_DEFINED
10 10
(...skipping 27 matching lines...) Expand all
38 * the GrAtlas will not evict anything the Blob needs. 38 * the GrAtlas will not evict anything the Blob needs.
39 * 39 *
40 * Note: This struct should really be named GrCachedAtasTextBlob, but that is to o verbose. 40 * Note: This struct should really be named GrCachedAtasTextBlob, but that is to o verbose.
41 * 41 *
42 * *WARNING* If you add new fields to this struct, then you may need to to updat e AssertEqual 42 * *WARNING* If you add new fields to this struct, then you may need to to updat e AssertEqual
43 */ 43 */
44 class GrAtlasTextBlob : public SkNVRefCnt<GrAtlasTextBlob> { 44 class GrAtlasTextBlob : public SkNVRefCnt<GrAtlasTextBlob> {
45 public: 45 public:
46 SK_DECLARE_INTERNAL_LLIST_INTERFACE(GrAtlasTextBlob); 46 SK_DECLARE_INTERNAL_LLIST_INTERFACE(GrAtlasTextBlob);
47 47
48 GrAtlasTextBlob()
49 : fMaxMinScale(-SK_ScalarMax)
50 , fMinMaxScale(SK_ScalarMax)
51 , fTextType(0) {}
52
53 ~GrAtlasTextBlob() {
54 for (int i = 0; i < fRunCount; i++) {
55 fRuns[i].~Run();
56 }
57 }
58
59 struct Key {
60 Key() {
61 sk_bzero(this, sizeof(Key));
62 }
63 uint32_t fUniqueID;
64 // Color may affect the gamma of the mask we generate, but in a fairly l imited way.
65 // Each color is assigned to on of a fixed number of buckets based on it s
66 // luminance. For each luminance bucket there is a "canonical color" tha t
67 // represents the bucket. This functionality is currently only supporte d for A8
68 SkColor fCanonicalColor;
69 SkPaint::Style fStyle;
70 SkPixelGeometry fPixelGeometry;
71 bool fHasBlur;
72
73 bool operator==(const Key& other) const {
74 return 0 == memcmp(this, &other, sizeof(Key));
75 }
76 };
77
78 static const Key& GetKey(const GrAtlasTextBlob& blob) {
79 return blob.fKey;
80 }
81
82 static uint32_t Hash(const Key& key) {
83 return SkChecksum::Murmur3(&key, sizeof(Key));
84 }
85
86 void operator delete(void* p) {
87 GrAtlasTextBlob* blob = reinterpret_cast<GrAtlasTextBlob*>(p);
88 blob->fPool->release(p);
89 }
90 void* operator new(size_t) {
91 SkFAIL("All blobs are created by placement new.");
92 return sk_malloc_throw(0);
93 }
94
95 void* operator new(size_t, void* p) { return p; }
96 void operator delete(void* target, void* placement) {
97 ::operator delete(target, placement);
98 }
99
100 bool hasDistanceField() const { return SkToBool(fTextType & kHasDistanceFiel d_TextType); }
101 bool hasBitmap() const { return SkToBool(fTextType & kHasBitmap_TextType); }
102 void setHasDistanceField() { fTextType |= kHasDistanceField_TextType; }
103 void setHasBitmap() { fTextType |= kHasBitmap_TextType; }
104
105 void push_back_run(int currRun) {
106 SkASSERT(currRun < fRunCount);
107 if (currRun > 0) {
108 Run::SubRunInfo& newRun = fRuns[currRun].fSubRunInfo.back();
109 Run::SubRunInfo& lastRun = fRuns[currRun - 1].fSubRunInfo.back();
110 newRun.setAsSuccessor(lastRun);
111 }
112 }
113
114 // sets the last subrun of runIndex to use distance field text
115 void setSubRunHasDistanceFields(int runIndex, bool hasLCD) {
116 Run& run = fRuns[runIndex];
117 Run::SubRunInfo& subRun = run.fSubRunInfo.back();
118 subRun.setUseLCDText(hasLCD);
119 subRun.setDrawAsDistanceFields();
120 }
121
122 void setRunDrawAsPaths(int runIndex) {
123 fRuns[runIndex].fDrawAsPaths = true;
124 }
125
126 void setMinAndMaxScale(SkScalar scaledMax, SkScalar scaledMin) {
127 // we init fMaxMinScale and fMinMaxScale in the constructor
128 fMaxMinScale = SkMaxScalar(scaledMax, fMaxMinScale);
129 fMinMaxScale = SkMinScalar(scaledMin, fMinMaxScale);
130 }
131
132 // inits the override descriptor on the current run. All following subruns must use this
133 // descriptor
134 void initOverride(int runIndex) {
135 Run& run = fRuns[runIndex];
136 // Push back a new subrun to fill and set the override descriptor
137 run.push_back();
138 run.fOverrideDescriptor.reset(new SkAutoDescriptor);
139 }
140
141 SkGlyphCache* setupCache(int runIndex,
142 const SkSurfaceProps& props,
143 const SkPaint& skPaint,
144 const SkMatrix* viewMatrix,
145 bool noGamma);
146
147 // Appends a glyph to the blob. If the glyph is too large, the glyph will b e appended
148 // as a path.
149 void appendGlyph(int runIndex,
150 const SkRect& positions,
151 GrColor color,
152 GrBatchTextStrike* strike,
153 GrGlyph* glyph,
154 GrFontScaler* scaler, const SkGlyph& skGlyph,
155 SkScalar x, SkScalar y, SkScalar scale, bool applyVM);
156
157 static size_t GetVertexStride(GrMaskFormat maskFormat) {
158 switch (maskFormat) {
159 case kA8_GrMaskFormat:
160 return kGrayTextVASize;
161 case kARGB_GrMaskFormat:
162 return kColorTextVASize;
163 default:
164 return kLCDTextVASize;
165 }
166 }
167
168 bool mustRegenerate(SkScalar* outTransX, SkScalar* outTransY, const SkPaint& paint,
169 GrColor color, const SkMaskFilter::BlurRec& blurRec,
170 const SkMatrix& viewMatrix, SkScalar x, SkScalar y);
171
172 // flush a GrAtlasTextBlob associated with a SkTextBlob
173 void flushCached(GrContext* context,
174 GrDrawContext* dc,
175 const SkTextBlob* blob,
176 const SkSurfaceProps& props,
177 const GrDistanceFieldAdjustTable* distanceAdjustTable,
178 const SkPaint& skPaint,
179 const GrPaint& grPaint,
180 SkDrawFilter* drawFilter,
181 const GrClip& clip,
182 const SkMatrix& viewMatrix,
183 const SkIRect& clipBounds,
184 SkScalar x, SkScalar y,
185 SkScalar transX, SkScalar transY);
186
187 // flush a throwaway GrAtlasTextBlob *not* associated with an SkTextBlob
188 void flushThrowaway(GrContext* context,
189 GrDrawContext* dc,
190 const SkSurfaceProps& props,
191 const GrDistanceFieldAdjustTable* distanceAdjustTable,
192 const SkPaint& skPaint,
193 const GrPaint& grPaint,
194 const GrClip& clip,
195 const SkIRect& clipBounds);
196
197 // position + local coord
198 static const size_t kColorTextVASize = sizeof(SkPoint) + sizeof(SkIPoint16);
199 static const size_t kGrayTextVASize = sizeof(SkPoint) + sizeof(GrColor) + si zeof(SkIPoint16);
200 static const size_t kLCDTextVASize = kGrayTextVASize;
201 static const int kVerticesPerGlyph = 4;
202
203 #ifdef CACHE_SANITY_CHECK
204 static void AssertEqual(const GrAtlasTextBlob&, const GrAtlasTextBlob&);
205 size_t fSize;
206 #endif
207
208 // The color here is the GrPaint color, and it is used to determine whether we
209 // have to regenerate LCD text blobs.
210 // We use this color vs the SkPaint color because it has the colorfilter app lied.
211 void initReusableBlob(GrColor color, const SkMatrix& viewMatrix, SkScalar x, SkScalar y) {
212 fPaintColor = color;
213 fViewMatrix = viewMatrix;
214 fX = x;
215 fY = y;
216 }
217
218 void initThrowawayBlob(const SkMatrix& viewMatrix) {
219 fViewMatrix = viewMatrix;
220 }
221
222 GrDrawBatch* test_createBatch(int glyphCount, int run, int subRun,
223 GrColor color, SkScalar transX, SkScalar trans Y,
224 const SkPaint& skPaint, const SkSurfaceProps& props,
225 const GrDistanceFieldAdjustTable* distanceAdju stTable,
226 GrBatchFontCache* cache);
227
228 private:
229 void appendLargeGlyph(GrGlyph* glyph, GrFontScaler* scaler, const SkGlyph& s kGlyph,
230 SkScalar x, SkScalar y, SkScalar scale, bool applyVM);
231
232 inline void flushRun(GrDrawContext* dc, GrPipelineBuilder* pipelineBuilder,
233 int run, GrColor color,
234 SkScalar transX, SkScalar transY,
235 const SkPaint& skPaint, const SkSurfaceProps& props,
236 const GrDistanceFieldAdjustTable* distanceAdjustTable,
237 GrBatchFontCache* cache);
238
239 void flushBigGlyphs(GrContext* context, GrDrawContext* dc,
240 const GrClip& clip, const SkPaint& skPaint,
241 SkScalar transX, SkScalar transY,
242 const SkIRect& clipBounds);
243
244 void flushRunAsPaths(GrContext* context,
245 GrDrawContext* dc,
246 const SkSurfaceProps& props,
247 const SkTextBlobRunIterator& it,
248 const GrClip& clip, const SkPaint& skPaint,
249 SkDrawFilter* drawFilter, const SkMatrix& viewMatrix,
250 const SkIRect& clipBounds, SkScalar x, SkScalar y);
251
48 /* 252 /*
49 * Each Run inside of the blob can have its texture coordinates regenerated if required. 253 * Each Run inside of the blob can have its texture coordinates regenerated if required.
50 * To determine if regeneration is necessary, fAtlasGeneration is used. If there have been 254 * To determine if regeneration is necessary, fAtlasGeneration is used. If there have been
51 * any evictions inside of the atlas, then we will simply regenerate Runs. We could track 255 * any evictions inside of the atlas, then we will simply regenerate Runs. We could track
52 * this at a more fine grained level, but its not clear if this is worth it, as evictions 256 * this at a more fine grained level, but its not clear if this is worth it, as evictions
53 * should be fairly rare. 257 * should be fairly rare.
54 * 258 *
55 * One additional point, each run can contain glyphs with any of the three m ask formats. 259 * One additional point, each run can contain glyphs with any of the three m ask formats.
56 * We call these SubRuns. Because a subrun must be a contiguous range, we h ave to create 260 * We call these SubRuns. Because a subrun must be a contiguous range, we h ave to create
57 * a new subrun each time the mask format changes in a run. In theory, a ru n can have as 261 * a new subrun each time the mask format changes in a run. In theory, a ru n can have as
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
170 374
171 // Distance field text cannot draw coloremoji, and so has to fall back. However, 375 // Distance field text cannot draw coloremoji, and so has to fall back. However,
172 // though the distance field text and the coloremoji may share the same run, they 376 // though the distance field text and the coloremoji may share the same run, they
173 // will have different descriptors. If fOverrideDescriptor is non-nullp tr, then it 377 // will have different descriptors. If fOverrideDescriptor is non-nullp tr, then it
174 // will be used in place of the run's descriptor to regen texture coords 378 // will be used in place of the run's descriptor to regen texture coords
175 SkAutoTDelete<SkAutoDescriptor> fOverrideDescriptor; // df properties 379 SkAutoTDelete<SkAutoDescriptor> fOverrideDescriptor; // df properties
176 bool fInitialized; 380 bool fInitialized;
177 bool fDrawAsPaths; 381 bool fDrawAsPaths;
178 }; 382 };
179 383
384 inline GrDrawBatch* createBatch(const Run::SubRunInfo& info,
385 int glyphCount, int run, int subRun,
386 GrColor color, SkScalar transX, SkScalar tra nsY,
387 const SkPaint& skPaint, const SkSurfaceProps & props,
388 const GrDistanceFieldAdjustTable* distanceAd justTable,
389 GrBatchFontCache* cache);
390
180 struct BigGlyph { 391 struct BigGlyph {
181 BigGlyph(const SkPath& path, SkScalar vx, SkScalar vy, SkScalar scale, b ool applyVM) 392 BigGlyph(const SkPath& path, SkScalar vx, SkScalar vy, SkScalar scale, b ool applyVM)
182 : fPath(path) 393 : fPath(path)
183 , fVx(vx) 394 , fVx(vx)
184 , fVy(vy) 395 , fVy(vy)
185 , fScale(scale) 396 , fScale(scale)
186 , fApplyVM(applyVM) {} 397 , fApplyVM(applyVM) {}
187 SkPath fPath; 398 SkPath fPath;
188 SkScalar fVx; 399 SkScalar fVx;
189 SkScalar fVy; 400 SkScalar fVy;
190 SkScalar fScale; 401 SkScalar fScale;
191 bool fApplyVM; 402 bool fApplyVM;
192 }; 403 };
193 404
194 struct Key {
195 Key() {
196 sk_bzero(this, sizeof(Key));
197 }
198 uint32_t fUniqueID;
199 // Color may affect the gamma of the mask we generate, but in a fairly l imited way.
200 // Each color is assigned to on of a fixed number of buckets based on it s
201 // luminance. For each luminance bucket there is a "canonical color" tha t
202 // represents the bucket. This functionality is currently only supporte d for A8
203 SkColor fCanonicalColor;
204 SkPaint::Style fStyle;
205 SkPixelGeometry fPixelGeometry;
206 bool fHasBlur;
207
208 bool operator==(const Key& other) const {
209 return 0 == memcmp(this, &other, sizeof(Key));
210 }
211 };
212
213 struct StrokeInfo { 405 struct StrokeInfo {
214 SkScalar fFrameWidth; 406 SkScalar fFrameWidth;
215 SkScalar fMiterLimit; 407 SkScalar fMiterLimit;
216 SkPaint::Join fJoin; 408 SkPaint::Join fJoin;
217 }; 409 };
218 410
219 enum TextType { 411 enum TextType {
220 kHasDistanceField_TextType = 0x1, 412 kHasDistanceField_TextType = 0x1,
221 kHasBitmap_TextType = 0x2, 413 kHasBitmap_TextType = 0x2,
222 }; 414 };
(...skipping 13 matching lines...) Expand all
236 SkScalar fY; 428 SkScalar fY;
237 429
238 // We can reuse distance field text, but only if the new viewmatrix would no t result in 430 // We can reuse distance field text, but only if the new viewmatrix would no t result in
239 // a mip change. Because there can be multiple runs in a blob, we track the overall 431 // a mip change. Because there can be multiple runs in a blob, we track the overall
240 // maximum minimum scale, and minimum maximum scale, we can support before w e need to regen 432 // maximum minimum scale, and minimum maximum scale, we can support before w e need to regen
241 SkScalar fMaxMinScale; 433 SkScalar fMaxMinScale;
242 SkScalar fMinMaxScale; 434 SkScalar fMinMaxScale;
243 int fRunCount; 435 int fRunCount;
244 uint8_t fTextType; 436 uint8_t fTextType;
245 437
246 GrAtlasTextBlob() 438 friend class GrAtlasTextBatch; // We might be able to get rid of this friend ing
247 : fMaxMinScale(-SK_ScalarMax) 439 friend class GrTextBlobCache; // Needs to access the key
248 , fMinMaxScale(SK_ScalarMax)
249 , fTextType(0) {}
250
251 ~GrAtlasTextBlob() {
252 for (int i = 0; i < fRunCount; i++) {
253 fRuns[i].~Run();
254 }
255 }
256
257 static const Key& GetKey(const GrAtlasTextBlob& blob) {
258 return blob.fKey;
259 }
260
261 static uint32_t Hash(const Key& key) {
262 return SkChecksum::Murmur3(&key, sizeof(Key));
263 }
264
265 void operator delete(void* p) {
266 GrAtlasTextBlob* blob = reinterpret_cast<GrAtlasTextBlob*>(p);
267 blob->fPool->release(p);
268 }
269 void* operator new(size_t) {
270 SkFAIL("All blobs are created by placement new.");
271 return sk_malloc_throw(0);
272 }
273
274 void* operator new(size_t, void* p) { return p; }
275 void operator delete(void* target, void* placement) {
276 ::operator delete(target, placement);
277 }
278
279 bool hasDistanceField() const { return SkToBool(fTextType & kHasDistanceFiel d_TextType); }
280 bool hasBitmap() const { return SkToBool(fTextType & kHasBitmap_TextType); }
281 void setHasDistanceField() { fTextType |= kHasDistanceField_TextType; }
282 void setHasBitmap() { fTextType |= kHasBitmap_TextType; }
283
284 void push_back_run(int currRun) {
285 SkASSERT(currRun < fRunCount);
286 if (currRun > 0) {
287 Run::SubRunInfo& newRun = fRuns[currRun].fSubRunInfo.back();
288 Run::SubRunInfo& lastRun = fRuns[currRun - 1].fSubRunInfo.back();
289 newRun.setAsSuccessor(lastRun);
290 }
291 }
292
293 // sets the last subrun of runIndex to use distance field text
294 void setSubRunHasDistanceFields(int runIndex, bool hasLCD) {
295 Run& run = fRuns[runIndex];
296 Run::SubRunInfo& subRun = run.fSubRunInfo.back();
297 subRun.setUseLCDText(hasLCD);
298 subRun.setDrawAsDistanceFields();
299 }
300
301 // inits the override descriptor on the current run. All following subruns must use this
302 // descriptor
303 void initOverride(int runIndex) {
304 Run& run = fRuns[runIndex];
305 // Push back a new subrun to fill and set the override descriptor
306 run.push_back();
307 run.fOverrideDescriptor.reset(new SkAutoDescriptor);
308 }
309
310 SkGlyphCache* setupCache(int runIndex,
311 const SkSurfaceProps& props,
312 const SkPaint& skPaint,
313 const SkMatrix* viewMatrix,
314 bool noGamma);
315
316 // Appends a glyph to the blob. If the glyph is too large, the glyph will b e appended
317 // as a path.
318 void appendGlyph(int runIndex,
319 const SkRect& positions,
320 GrColor color,
321 GrBatchTextStrike* strike,
322 GrGlyph* glyph,
323 GrFontScaler* scaler, const SkGlyph& skGlyph,
324 SkScalar x, SkScalar y, SkScalar scale, bool applyVM);
325
326 static size_t GetVertexStride(GrMaskFormat maskFormat) {
327 switch (maskFormat) {
328 case kA8_GrMaskFormat:
329 return kGrayTextVASize;
330 case kARGB_GrMaskFormat:
331 return kColorTextVASize;
332 default:
333 return kLCDTextVASize;
334 }
335 }
336
337 bool mustRegenerate(SkScalar* outTransX, SkScalar* outTransY, const SkPaint& paint,
338 GrColor color, const SkMaskFilter::BlurRec& blurRec,
339 const SkMatrix& viewMatrix, SkScalar x, SkScalar y);
340
341 // flush a GrAtlasTextBlob associated with a SkTextBlob
342 void flushCached(GrContext* context,
343 GrDrawContext* dc,
344 const SkTextBlob* blob,
345 const SkSurfaceProps& props,
346 const GrDistanceFieldAdjustTable* distanceAdjustTable,
347 const SkPaint& skPaint,
348 const GrPaint& grPaint,
349 SkDrawFilter* drawFilter,
350 const GrClip& clip,
351 const SkMatrix& viewMatrix,
352 const SkIRect& clipBounds,
353 SkScalar x, SkScalar y,
354 SkScalar transX, SkScalar transY);
355
356 // flush a throwaway GrAtlasTextBlob *not* associated with an SkTextBlob
357 void flushThrowaway(GrContext* context,
358 GrDrawContext* dc,
359 const SkSurfaceProps& props,
360 const GrDistanceFieldAdjustTable* distanceAdjustTable,
361 const SkPaint& skPaint,
362 const GrPaint& grPaint,
363 const GrClip& clip,
364 const SkIRect& clipBounds);
365
366 // position + local coord
367 static const size_t kColorTextVASize = sizeof(SkPoint) + sizeof(SkIPoint16);
368 static const size_t kGrayTextVASize = sizeof(SkPoint) + sizeof(GrColor) + si zeof(SkIPoint16);
369 static const size_t kLCDTextVASize = kGrayTextVASize;
370 static const int kVerticesPerGlyph = 4;
371
372 #ifdef CACHE_SANITY_CHECK
373 static void AssertEqual(const GrAtlasTextBlob&, const GrAtlasTextBlob&);
374 size_t fSize;
375 #endif
376
377 // We'd like to inline this and make it private, but there is some test code which calls it.
378 // TODO refactor this
379 GrDrawBatch* createBatch(const Run::SubRunInfo& info,
380 int glyphCount, int run, int subRun,
381 GrColor color, SkScalar transX, SkScalar transY,
382 const SkPaint& skPaint, const SkSurfaceProps& props ,
383 const GrDistanceFieldAdjustTable* distanceAdjustTab le,
384 GrBatchFontCache* cache);
385
386 private:
387 void appendLargeGlyph(GrGlyph* glyph, GrFontScaler* scaler, const SkGlyph& s kGlyph,
388 SkScalar x, SkScalar y, SkScalar scale, bool applyVM);
389
390 inline void flushRun(GrDrawContext* dc, GrPipelineBuilder* pipelineBuilder,
391 int run, GrColor color,
392 SkScalar transX, SkScalar transY,
393 const SkPaint& skPaint, const SkSurfaceProps& props,
394 const GrDistanceFieldAdjustTable* distanceAdjustTable,
395 GrBatchFontCache* cache);
396
397 void flushBigGlyphs(GrContext* context, GrDrawContext* dc,
398 const GrClip& clip, const SkPaint& skPaint,
399 SkScalar transX, SkScalar transY,
400 const SkIRect& clipBounds);
401
402 void flushRunAsPaths(GrContext* context,
403 GrDrawContext* dc,
404 const SkSurfaceProps& props,
405 const SkTextBlobRunIterator& it,
406 const GrClip& clip, const SkPaint& skPaint,
407 SkDrawFilter* drawFilter, const SkMatrix& viewMatrix,
408 const SkIRect& clipBounds, SkScalar x, SkScalar y);
409 }; 440 };
410 441
411 #endif 442 #endif
OLDNEW
« no previous file with comments | « src/gpu/batches/GrAtlasTextBatch.cpp ('k') | src/gpu/text/GrAtlasTextBlob.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698