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

Side by Side Diff: src/gpu/text/GrBatchFontCache.cpp

Issue 1985163002: Remove GrFontScaler class (Closed) Base URL: https://chromium.googlesource.com/skia.git@rmkey
Patch Set: remove comments Created 4 years, 7 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/text/GrBatchFontCache.h ('k') | src/gpu/text/GrFontScaler.h » ('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 #include "GrBatchFontCache.h" 8 #include "GrBatchFontCache.h"
9 #include "GrContext.h" 9 #include "GrContext.h"
10 #include "GrGpu.h" 10 #include "GrGpu.h"
11 #include "GrRectanizer.h" 11 #include "GrRectanizer.h"
12 #include "GrResourceProvider.h" 12 #include "GrResourceProvider.h"
13 #include "GrSurfacePriv.h" 13 #include "GrSurfacePriv.h"
14 #include "SkString.h" 14 #include "SkString.h"
15 15
16 #include "SkDistanceFieldGen.h" 16 #include "SkDistanceFieldGen.h"
17 17
18 ///////////////////////////////////////////////////////////////////////////////
19
20 bool GrBatchFontCache::initAtlas(GrMaskFormat format) { 18 bool GrBatchFontCache::initAtlas(GrMaskFormat format) {
21 int index = MaskFormatToAtlasIndex(format); 19 int index = MaskFormatToAtlasIndex(format);
22 if (!fAtlases[index]) { 20 if (!fAtlases[index]) {
23 GrPixelConfig config = MaskFormatToPixelConfig(format); 21 GrPixelConfig config = MaskFormatToPixelConfig(format);
24 int width = fAtlasConfigs[index].fWidth; 22 int width = fAtlasConfigs[index].fWidth;
25 int height = fAtlasConfigs[index].fHeight; 23 int height = fAtlasConfigs[index].fHeight;
26 int numPlotsX = fAtlasConfigs[index].numPlotsX(); 24 int numPlotsX = fAtlasConfigs[index].numPlotsX();
27 int numPlotsY = fAtlasConfigs[index].numPlotsY(); 25 int numPlotsY = fAtlasConfigs[index].numPlotsY();
28 26
29 fAtlases[index] = 27 fAtlases[index] =
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
138 if (fAtlases[i]) { 136 if (fAtlases[i]) {
139 delete fAtlases[i]; 137 delete fAtlases[i];
140 fAtlases[i] = nullptr; 138 fAtlases[i] = nullptr;
141 } 139 }
142 } 140 }
143 memcpy(fAtlasConfigs, configs, sizeof(fAtlasConfigs)); 141 memcpy(fAtlasConfigs, configs, sizeof(fAtlasConfigs));
144 } 142 }
145 143
146 /////////////////////////////////////////////////////////////////////////////// 144 ///////////////////////////////////////////////////////////////////////////////
147 145
146 static inline GrMaskFormat get_packed_glyph_mask_format(const SkGlyph& glyph) {
bsalomon 2016/05/17 19:11:04 This code is from GrFontScaler.cpp. Copied, pasted
147 SkMask::Format format = static_cast<SkMask::Format>(glyph.fMaskFormat);
148 switch (format) {
149 case SkMask::kBW_Format:
150 // fall through to kA8 -- we store BW glyphs in our 8-bit cache
151 case SkMask::kA8_Format:
152 return kA8_GrMaskFormat;
153 case SkMask::kLCD16_Format:
154 return kA565_GrMaskFormat;
155 case SkMask::kARGB32_Format:
156 return kARGB_GrMaskFormat;
157 default:
158 SkDEBUGFAIL("unsupported SkMask::Format");
159 return kA8_GrMaskFormat;
160 }
161 }
162
163 static inline bool get_packed_glyph_bounds(SkGlyphCache* cache, const SkGlyph& g lyph,
164 SkIRect* bounds) {
165 #if 1
166 // crbug:510931
167 // Retrieving the image from the cache can actually change the mask format.
168 cache->findImage(glyph);
169 #endif
170 bounds->setXYWH(glyph.fLeft, glyph.fTop, glyph.fWidth, glyph.fHeight);
171
172 return true;
173 }
174
175 static inline bool get_packed_glyph_df_bounds(SkGlyphCache* cache, const SkGlyph & glyph,
176 SkIRect* bounds) {
177 #if 1
178 // crbug:510931
179 // Retrieving the image from the cache can actually change the mask format.
180 cache->findImage(glyph);
181 #endif
182 bounds->setXYWH(glyph.fLeft, glyph.fTop, glyph.fWidth, glyph.fHeight);
183 bounds->outset(SK_DistanceFieldPad, SK_DistanceFieldPad);
184
185 return true;
186 }
187
188 // expands each bit in a bitmask to 0 or ~0 of type INT_TYPE. Used to expand a B W glyph mask to
189 // A8, RGB565, or RGBA8888.
190 template <typename INT_TYPE>
191 static void expand_bits(INT_TYPE* dst,
192 const uint8_t* src,
193 int width,
194 int height,
195 int dstRowBytes,
196 int srcRowBytes) {
197 for (int i = 0; i < height; ++i) {
198 int rowWritesLeft = width;
199 const uint8_t* s = src;
200 INT_TYPE* d = dst;
201 while (rowWritesLeft > 0) {
202 unsigned mask = *s++;
203 for (int i = 7; i >= 0 && rowWritesLeft; --i, --rowWritesLeft) {
204 *d++ = (mask & (1 << i)) ? (INT_TYPE)(~0UL) : 0;
205 }
206 }
207 dst = reinterpret_cast<INT_TYPE*>(reinterpret_cast<intptr_t>(dst) + dstR owBytes);
208 src += srcRowBytes;
209 }
210 }
211
212 static bool get_packed_glyph_image(SkGlyphCache* cache, const SkGlyph& glyph, in t width,
213 int height, int dstRB, GrMaskFormat expectedM askFormat,
214 void* dst) {
215 SkASSERT(glyph.fWidth == width);
216 SkASSERT(glyph.fHeight == height);
217 const void* src = cache->findImage(glyph);
218 if (nullptr == src) {
219 return false;
220 }
221
222 // crbug:510931
223 // Retrieving the image from the cache can actually change the mask format. This case is very
224 // uncommon so for now we just draw a clear box for these glyphs.
225 if (get_packed_glyph_mask_format(glyph) != expectedMaskFormat) {
226 const int bpp = GrMaskFormatBytesPerPixel(expectedMaskFormat);
227 for (int y = 0; y < height; y++) {
228 sk_bzero(dst, width * bpp);
229 dst = (char*)dst + dstRB;
230 }
231 return true;
232 }
233
234 int srcRB = glyph.rowBytes();
235 // The windows font host sometimes has BW glyphs in a non-BW strike. So it i s important here to
236 // check the glyph's format, not the strike's format, and to be able to conv ert to any of the
237 // GrMaskFormats.
238 if (SkMask::kBW_Format == glyph.fMaskFormat) {
239 // expand bits to our mask type
240 const uint8_t* bits = reinterpret_cast<const uint8_t*>(src);
241 switch (expectedMaskFormat) {
242 case kA8_GrMaskFormat:{
243 uint8_t* bytes = reinterpret_cast<uint8_t*>(dst);
244 expand_bits(bytes, bits, width, height, dstRB, srcRB);
245 break;
246 }
247 case kA565_GrMaskFormat: {
248 uint16_t* rgb565 = reinterpret_cast<uint16_t*>(dst);
249 expand_bits(rgb565, bits, width, height, dstRB, srcRB);
250 break;
251 }
252 default:
253 SkFAIL("Invalid GrMaskFormat");
254 }
255 } else if (srcRB == dstRB) {
256 memcpy(dst, src, dstRB * height);
257 } else {
258 const int bbp = GrMaskFormatBytesPerPixel(expectedMaskFormat);
259 for (int y = 0; y < height; y++) {
260 memcpy(dst, src, width * bbp);
261 src = (const char*)src + srcRB;
262 dst = (char*)dst + dstRB;
263 }
264 }
265 return true;
266 }
267
268 static bool get_packed_glyph_df_image(SkGlyphCache* cache, const SkGlyph& glyph,
269 int width, int height, void* dst) {
270 SkASSERT(glyph.fWidth + 2*SK_DistanceFieldPad == width);
271 SkASSERT(glyph.fHeight + 2*SK_DistanceFieldPad == height);
272 const void* image = cache->findImage(glyph);
273 if (nullptr == image) {
274 return false;
275 }
276 // now generate the distance field
277 SkASSERT(dst);
278 SkMask::Format maskFormat = static_cast<SkMask::Format>(glyph.fMaskFormat);
279 if (SkMask::kA8_Format == maskFormat) {
280 // make the distance field from the image
281 SkGenerateDistanceFieldFromA8Image((unsigned char*)dst,
282 (unsigned char*)image,
283 glyph.fWidth, glyph.fHeight,
284 glyph.rowBytes());
285 } else if (SkMask::kBW_Format == maskFormat) {
286 // make the distance field from the image
287 SkGenerateDistanceFieldFromBWImage((unsigned char*)dst,
288 (unsigned char*)image,
289 glyph.fWidth, glyph.fHeight,
290 glyph.rowBytes());
291 } else {
292 return false;
293 }
294
295 return true;
296 }
297
298 ///////////////////////////////////////////////////////////////////////////////
299
148 /* 300 /*
149 The text strike is specific to a given font/style/matrix setup, which is 301 The text strike is specific to a given font/style/matrix setup, which is
150 represented by the GrHostFontScaler object we are given in getGlyph(). 302 represented by the GrHostFontScaler object we are given in getGlyph().
151 303
152 We map a 32bit glyphID to a GrGlyph record, which in turn points to a 304 We map a 32bit glyphID to a GrGlyph record, which in turn points to a
153 atlas and a position within that texture. 305 atlas and a position within that texture.
154 */ 306 */
155 307
156 GrBatchTextStrike::GrBatchTextStrike(GrBatchFontCache* owner, const SkDescriptor & key) 308 GrBatchTextStrike::GrBatchTextStrike(GrBatchFontCache* owner, const SkDescriptor & key)
157 : fFontScalerKey(key) 309 : fFontScalerKey(key)
158 , fPool(9/*start allocations at 512 bytes*/) 310 , fPool(9/*start allocations at 512 bytes*/)
159 , fBatchFontCache(owner) // no need to ref, it won't go away before we do 311 , fBatchFontCache(owner) // no need to ref, it won't go away before we do
160 , fAtlasedGlyphs(0) 312 , fAtlasedGlyphs(0)
161 , fIsAbandoned(false) {} 313 , fIsAbandoned(false) {}
162 314
163 GrBatchTextStrike::~GrBatchTextStrike() { 315 GrBatchTextStrike::~GrBatchTextStrike() {
164 SkTDynamicHash<GrGlyph, GrGlyph::PackedID>::Iter iter(&fCache); 316 SkTDynamicHash<GrGlyph, GrGlyph::PackedID>::Iter iter(&fCache);
165 while (!iter.done()) { 317 while (!iter.done()) {
166 (*iter).reset(); 318 (*iter).reset();
167 ++iter; 319 ++iter;
168 } 320 }
169 } 321 }
170 322
171 GrGlyph* GrBatchTextStrike::generateGlyph(const SkGlyph& skGlyph, GrGlyph::Packe dID packed, 323 GrGlyph* GrBatchTextStrike::generateGlyph(const SkGlyph& skGlyph, GrGlyph::Packe dID packed,
172 GrFontScaler* scaler) { 324 SkGlyphCache* cache) {
173 SkIRect bounds; 325 SkIRect bounds;
174 if (GrGlyph::kDistance_MaskStyle == GrGlyph::UnpackMaskStyle(packed)) { 326 if (GrGlyph::kDistance_MaskStyle == GrGlyph::UnpackMaskStyle(packed)) {
175 if (!scaler->getPackedGlyphDFBounds(skGlyph, &bounds)) { 327 if (!get_packed_glyph_df_bounds(cache, skGlyph, &bounds)) {
176 return nullptr; 328 return nullptr;
177 } 329 }
178 } else { 330 } else {
179 if (!scaler->getPackedGlyphBounds(skGlyph, &bounds)) { 331 if (!get_packed_glyph_bounds(cache, skGlyph, &bounds)) {
180 return nullptr; 332 return nullptr;
181 } 333 }
182 } 334 }
183 GrMaskFormat format = scaler->getPackedGlyphMaskFormat(skGlyph); 335 GrMaskFormat format = get_packed_glyph_mask_format(skGlyph);
184 336
185 GrGlyph* glyph = (GrGlyph*)fPool.alloc(sizeof(GrGlyph)); 337 GrGlyph* glyph = (GrGlyph*)fPool.alloc(sizeof(GrGlyph));
186 glyph->init(packed, bounds, format); 338 glyph->init(packed, bounds, format);
187 fCache.add(glyph); 339 fCache.add(glyph);
188 return glyph; 340 return glyph;
189 } 341 }
190 342
191 void GrBatchTextStrike::removeID(GrBatchAtlas::AtlasID id) { 343 void GrBatchTextStrike::removeID(GrBatchAtlas::AtlasID id) {
192 SkTDynamicHash<GrGlyph, GrGlyph::PackedID>::Iter iter(&fCache); 344 SkTDynamicHash<GrGlyph, GrGlyph::PackedID>::Iter iter(&fCache);
193 while (!iter.done()) { 345 while (!iter.done()) {
194 if (id == (*iter).fID) { 346 if (id == (*iter).fID) {
195 (*iter).fID = GrBatchAtlas::kInvalidAtlasID; 347 (*iter).fID = GrBatchAtlas::kInvalidAtlasID;
196 fAtlasedGlyphs--; 348 fAtlasedGlyphs--;
197 SkASSERT(fAtlasedGlyphs >= 0); 349 SkASSERT(fAtlasedGlyphs >= 0);
198 } 350 }
199 ++iter; 351 ++iter;
200 } 352 }
201 } 353 }
202 354
203 bool GrBatchTextStrike::addGlyphToAtlas(GrDrawBatch::Target* target, 355 bool GrBatchTextStrike::addGlyphToAtlas(GrDrawBatch::Target* target,
204 GrGlyph* glyph, 356 GrGlyph* glyph,
205 GrFontScaler* scaler, 357 SkGlyphCache* cache,
206 GrMaskFormat expectedMaskFormat) { 358 GrMaskFormat expectedMaskFormat) {
207 SkASSERT(glyph); 359 SkASSERT(glyph);
208 SkASSERT(scaler); 360 SkASSERT(cache);
209 SkASSERT(fCache.find(glyph->fPackedID)); 361 SkASSERT(fCache.find(glyph->fPackedID));
210 362
211 int bytesPerPixel = GrMaskFormatBytesPerPixel(expectedMaskFormat); 363 int bytesPerPixel = GrMaskFormatBytesPerPixel(expectedMaskFormat);
212 364
213 size_t size = glyph->fBounds.area() * bytesPerPixel; 365 size_t size = glyph->fBounds.area() * bytesPerPixel;
214 SkAutoSMalloc<1024> storage(size); 366 SkAutoSMalloc<1024> storage(size);
215 367
216 const SkGlyph& skGlyph = scaler->grToSkGlyph(glyph->fPackedID); 368 const SkGlyph& skGlyph = GrToSkGlyph(cache, glyph->fPackedID);
217 if (GrGlyph::kDistance_MaskStyle == GrGlyph::UnpackMaskStyle(glyph->fPackedI D)) { 369 if (GrGlyph::kDistance_MaskStyle == GrGlyph::UnpackMaskStyle(glyph->fPackedI D)) {
218 if (!scaler->getPackedGlyphDFImage(skGlyph, glyph->width(), glyph->heigh t(), 370 if (!get_packed_glyph_df_image(cache, skGlyph, glyph->width(), glyph->he ight(),
219 storage.get())) { 371 storage.get())) {
220 return false; 372 return false;
221 } 373 }
222 } else { 374 } else {
223 if (!scaler->getPackedGlyphImage(skGlyph, glyph->width(), glyph->height( ), 375 if (!get_packed_glyph_image(cache, skGlyph, glyph->width(), glyph->heigh t(),
224 glyph->width() * bytesPerPixel, expecte dMaskFormat, 376 glyph->width() * bytesPerPixel, expectedMask Format,
225 storage.get())) { 377 storage.get())) {
226 return false; 378 return false;
227 } 379 }
228 } 380 }
229 381
230 bool success = fBatchFontCache->addToAtlas(this, &glyph->fID, target, expect edMaskFormat, 382 bool success = fBatchFontCache->addToAtlas(this, &glyph->fID, target, expect edMaskFormat,
231 glyph->width(), glyph->height(), 383 glyph->width(), glyph->height(),
232 storage.get(), &glyph->fAtlasLoca tion); 384 storage.get(), &glyph->fAtlasLoca tion);
233 if (success) { 385 if (success) {
234 SkASSERT(GrBatchAtlas::kInvalidAtlasID != glyph->fID); 386 SkASSERT(GrBatchAtlas::kInvalidAtlasID != glyph->fID);
235 fAtlasedGlyphs++; 387 fAtlasedGlyphs++;
236 } 388 }
237 return success; 389 return success;
238 } 390 }
OLDNEW
« no previous file with comments | « src/gpu/text/GrBatchFontCache.h ('k') | src/gpu/text/GrFontScaler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698