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

Side by Side Diff: src/gpu/GrStencilAndCoverTextContext.cpp

Issue 1381873003: Use SkTextBlob for nvpr color bitmap fallbacks (Closed) Base URL: https://skia.googlesource.com/skia.git@upload2_textrun
Patch Set: Fix msvc build Created 5 years, 2 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/GrStencilAndCoverTextContext.h ('k') | no next file » | 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 2014 Google Inc. 2 * Copyright 2014 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 "GrStencilAndCoverTextContext.h" 8 #include "GrStencilAndCoverTextContext.h"
9 #include "GrAtlasTextContext.h" 9 #include "GrAtlasTextContext.h"
10 #include "GrDrawContext.h" 10 #include "GrDrawContext.h"
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
85 int scalarsPerPosition, 85 int scalarsPerPosition,
86 const SkPoint& offset, 86 const SkPoint& offset,
87 const SkIRect& regionClipBounds ) { 87 const SkIRect& regionClipBounds ) {
88 TextRun run(skPaint); 88 TextRun run(skPaint);
89 run.setPosText(text, byteLength, pos, scalarsPerPosition, offset, fContext, &fSurfaceProps); 89 run.setPosText(text, byteLength, pos, scalarsPerPosition, offset, fContext, &fSurfaceProps);
90 run.draw(dc, rt, clip, paint, viewMatrix, regionClipBounds, fFallbackTextCon text, skPaint); 90 run.draw(dc, rt, clip, paint, viewMatrix, regionClipBounds, fFallbackTextCon text, skPaint);
91 } 91 }
92 92
93 //////////////////////////////////////////////////////////////////////////////// //////////////////// 93 //////////////////////////////////////////////////////////////////////////////// ////////////////////
94 94
95 class GrStencilAndCoverTextContext::FallbackBlobBuilder {
96 public:
97 FallbackBlobBuilder() : fBuffIdx(0) {}
98
99 bool isInitialized() const { return SkToBool(fBuilder); }
100
101 void init(const SkPaint& font, SkScalar textRatio);
102
103 void appendGlyph(uint16_t glyphId, const SkPoint& pos);
104
105 const SkTextBlob* buildIfInitialized();
106
107 private:
108 enum { kWriteBufferSize = 1024 };
109
110 void flush();
111
112 SkAutoTDelete<SkTextBlobBuilder> fBuilder;
113 SkPaint fFont;
114 int fBuffIdx;
115 uint16_t fGlyphIds[kWriteBufferSize];
116 SkPoint fPositions[kWriteBufferSize];
117 };
118
119 //////////////////////////////////////////////////////////////////////////////// ////////////////////
120
95 GrStencilAndCoverTextContext::TextRun::TextRun(const SkPaint& fontAndStroke) 121 GrStencilAndCoverTextContext::TextRun::TextRun(const SkPaint& fontAndStroke)
96 : fStroke(fontAndStroke), 122 : fStroke(fontAndStroke),
97 fFont(fontAndStroke) { 123 fFont(fontAndStroke) {
98 SkASSERT(!fStroke.isHairlineStyle()); // Hairlines are not supported. 124 SkASSERT(!fStroke.isHairlineStyle()); // Hairlines are not supported.
99 125
100 // Setting to "fill" ensures that no strokes get baked into font outlines. ( We use the GPU path 126 // Setting to "fill" ensures that no strokes get baked into font outlines. ( We use the GPU path
101 // rendering API for stroking). 127 // rendering API for stroking).
102 fFont.setStyle(SkPaint::kFill_Style); 128 fFont.setStyle(SkPaint::kFill_Style);
103 129
104 if (fFont.isFakeBoldText() && SkStrokeRec::kStroke_Style != fStroke.getStyle ()) { 130 if (fFont.isFakeBoldText() && SkStrokeRec::kStroke_Style != fStroke.getStyle ()) {
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
191 x -= alignX; 217 x -= alignX;
192 y -= alignY; 218 y -= alignY;
193 } 219 }
194 220
195 SkAutoKern autokern; 221 SkAutoKern autokern;
196 222
197 SkFixed fixedSizeRatio = SkScalarToFixed(fTextRatio); 223 SkFixed fixedSizeRatio = SkScalarToFixed(fTextRatio);
198 224
199 SkFixed fx = SkScalarToFixed(x); 225 SkFixed fx = SkScalarToFixed(x);
200 SkFixed fy = SkScalarToFixed(y); 226 SkFixed fy = SkScalarToFixed(y);
227 FallbackBlobBuilder fallback;
201 while (text < stop) { 228 while (text < stop) {
202 const SkGlyph& glyph = glyphCacheProc(glyphCache, &text, 0, 0); 229 const SkGlyph& glyph = glyphCacheProc(glyphCache, &text, 0, 0);
203 fx += SkFixedMul(autokern.adjust(glyph), fixedSizeRatio); 230 fx += SkFixedMul(autokern.adjust(glyph), fixedSizeRatio);
204 if (glyph.fWidth) { 231 if (glyph.fWidth) {
205 this->appendGlyph(glyph, SkPoint::Make(SkFixedToScalar(fx), SkFixedT oScalar(fy))); 232 this->appendGlyph(glyph, SkPoint::Make(SkFixedToScalar(fx), SkFixedT oScalar(fy)),
233 &fallback);
206 } 234 }
207 235
208 fx += SkFixedMul(glyph.fAdvanceX, fixedSizeRatio); 236 fx += SkFixedMul(glyph.fAdvanceX, fixedSizeRatio);
209 fy += SkFixedMul(glyph.fAdvanceY, fixedSizeRatio); 237 fy += SkFixedMul(glyph.fAdvanceY, fixedSizeRatio);
210 } 238 }
239
240 fFallbackTextBlob.reset(fallback.buildIfInitialized());
211 } 241 }
212 242
213 void GrStencilAndCoverTextContext::TextRun::setPosText(const char text[], size_t byteLength, 243 void GrStencilAndCoverTextContext::TextRun::setPosText(const char text[], size_t byteLength,
214 const SkScalar pos[], int scalarsPerPosition, 244 const SkScalar pos[], int scalarsPerPosition,
215 const SkPoint& offset, Gr Context* ctx, 245 const SkPoint& offset, Gr Context* ctx,
216 const SkSurfaceProps* sur faceProps) { 246 const SkSurfaceProps* sur faceProps) {
217 SkASSERT(byteLength == 0 || text != nullptr); 247 SkASSERT(byteLength == 0 || text != nullptr);
218 SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition); 248 SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition);
219 249
220 SkAutoGlyphCacheNoGamma autoGlyphCache(fFont, surfaceProps, nullptr); 250 SkAutoGlyphCacheNoGamma autoGlyphCache(fFont, surfaceProps, nullptr);
221 SkGlyphCache* glyphCache = autoGlyphCache.getCache(); 251 SkGlyphCache* glyphCache = autoGlyphCache.getCache();
222 252
223 fDraw.reset(GrPathRangeDraw::Create(this->createGlyphs(ctx, glyphCache), 253 fDraw.reset(GrPathRangeDraw::Create(this->createGlyphs(ctx, glyphCache),
224 GrPathRendering::kTranslate_PathTransfor mType, 254 GrPathRendering::kTranslate_PathTransfor mType,
225 fFont.countText(text, byteLength))); 255 fFont.countText(text, byteLength)));
226 256
227 SkDrawCacheProc glyphCacheProc = fFont.getDrawCacheProc(); 257 SkDrawCacheProc glyphCacheProc = fFont.getDrawCacheProc();
228 258
229 const char* stop = text + byteLength; 259 const char* stop = text + byteLength;
230 260
231 SkTextMapStateProc tmsProc(SkMatrix::I(), offset, scalarsPerPosition); 261 SkTextMapStateProc tmsProc(SkMatrix::I(), offset, scalarsPerPosition);
232 SkTextAlignProc alignProc(fFont.getTextAlign()); 262 SkTextAlignProc alignProc(fFont.getTextAlign());
263 FallbackBlobBuilder fallback;
233 while (text < stop) { 264 while (text < stop) {
234 const SkGlyph& glyph = glyphCacheProc(glyphCache, &text, 0, 0); 265 const SkGlyph& glyph = glyphCacheProc(glyphCache, &text, 0, 0);
235 if (glyph.fWidth) { 266 if (glyph.fWidth) {
236 SkPoint tmsLoc; 267 SkPoint tmsLoc;
237 tmsProc(pos, &tmsLoc); 268 tmsProc(pos, &tmsLoc);
238 SkPoint loc; 269 SkPoint loc;
239 alignProc(tmsLoc, glyph, &loc); 270 alignProc(tmsLoc, glyph, &loc);
240 271
241 this->appendGlyph(glyph, loc); 272 this->appendGlyph(glyph, loc, &fallback);
242 } 273 }
243 pos += scalarsPerPosition; 274 pos += scalarsPerPosition;
244 } 275 }
276
277 fFallbackTextBlob.reset(fallback.buildIfInitialized());
245 } 278 }
246 279
247 GrPathRange* GrStencilAndCoverTextContext::TextRun::createGlyphs(GrContext* ctx, 280 GrPathRange* GrStencilAndCoverTextContext::TextRun::createGlyphs(GrContext* ctx,
248 SkGlyphCache* g lyphCache) { 281 SkGlyphCache* g lyphCache) {
249 SkTypeface* typeface = fUsingRawGlyphPaths ? fFont.getTypeface() 282 SkTypeface* typeface = fUsingRawGlyphPaths ? fFont.getTypeface()
250 : glyphCache->getScalerContext()- >getTypeface(); 283 : glyphCache->getScalerContext()- >getTypeface();
251 const SkDescriptor* desc = fUsingRawGlyphPaths ? nullptr : &glyphCache->getD escriptor(); 284 const SkDescriptor* desc = fUsingRawGlyphPaths ? nullptr : &glyphCache->getD escriptor();
252 285
253 static const GrUniqueKey::Domain kPathGlyphDomain = GrUniqueKey::GenerateDom ain(); 286 static const GrUniqueKey::Domain kPathGlyphDomain = GrUniqueKey::GenerateDom ain();
254 int strokeDataCount = fStroke.computeUniqueKeyFragmentData32Cnt(); 287 int strokeDataCount = fStroke.computeUniqueKeyFragmentData32Cnt();
(...skipping 13 matching lines...) Expand all
268 glyphs.reset(ctx->resourceProvider()->createGlyphs(typeface, desc, fStro ke)); 301 glyphs.reset(ctx->resourceProvider()->createGlyphs(typeface, desc, fStro ke));
269 ctx->resourceProvider()->assignUniqueKeyToResource(glyphKey, glyphs); 302 ctx->resourceProvider()->assignUniqueKeyToResource(glyphKey, glyphs);
270 } else { 303 } else {
271 SkASSERT(nullptr == desc || glyphs->isEqualTo(*desc)); 304 SkASSERT(nullptr == desc || glyphs->isEqualTo(*desc));
272 } 305 }
273 306
274 return glyphs.detach(); 307 return glyphs.detach();
275 } 308 }
276 309
277 inline void GrStencilAndCoverTextContext::TextRun::appendGlyph(const SkGlyph& gl yph, 310 inline void GrStencilAndCoverTextContext::TextRun::appendGlyph(const SkGlyph& gl yph,
278 const SkPoint& po s) { 311 const SkPoint& po s,
279 // Stick the glyphs we can't draw into the fallback arrays. 312 FallbackBlobBuild er* fallback) {
313 // Stick the glyphs we can't draw into the fallback text blob.
280 if (SkMask::kARGB32_Format == glyph.fMaskFormat) { 314 if (SkMask::kARGB32_Format == glyph.fMaskFormat) {
281 fFallbackIndices.push_back(glyph.getGlyphID()); 315 if (!fallback->isInitialized()) {
282 fFallbackPositions.push_back(pos); 316 fallback->init(fFont, fTextRatio);
317 }
318 fallback->appendGlyph(glyph.getGlyphID(), pos);
283 } else { 319 } else {
284 float translate[] = { fTextInverseRatio * pos.x(), fTextInverseRatio * p os.y() }; 320 float translate[] = { fTextInverseRatio * pos.x(), fTextInverseRatio * p os.y() };
285 fDraw->append(glyph.getGlyphID(), translate); 321 fDraw->append(glyph.getGlyphID(), translate);
286 } 322 }
287 } 323 }
288 324
289 void GrStencilAndCoverTextContext::TextRun::draw(GrDrawContext* dc, 325 void GrStencilAndCoverTextContext::TextRun::draw(GrDrawContext* dc,
290 GrRenderTarget* rt, 326 GrRenderTarget* rt,
291 const GrClip& clip, 327 const GrClip& clip,
292 const GrPaint& paint, 328 const GrPaint& paint,
(...skipping 18 matching lines...) Expand all
311 347
312 *pipelineBuilder.stencil() = kStencilPass; 348 *pipelineBuilder.stencil() = kStencilPass;
313 349
314 SkMatrix drawMatrix(viewMatrix); 350 SkMatrix drawMatrix(viewMatrix);
315 drawMatrix.preScale(fTextRatio, fTextRatio); 351 drawMatrix.preScale(fTextRatio, fTextRatio);
316 352
317 dc->drawPathsFromRange(&pipelineBuilder, drawMatrix, fLocalMatrix, paint .getColor(), fDraw, 353 dc->drawPathsFromRange(&pipelineBuilder, drawMatrix, fLocalMatrix, paint .getColor(), fDraw,
318 GrPathRendering::kWinding_FillType); 354 GrPathRendering::kWinding_FillType);
319 } 355 }
320 356
321 if (fFallbackIndices.count()) { 357 if (fFallbackTextBlob) {
322 SkASSERT(fFallbackPositions.count() == fFallbackIndices.count());
323
324 enum { kPreservedFlags = SkPaint::kFakeBoldText_Flag | SkPaint::kLinearT ext_Flag |
325 SkPaint::kLCDRenderText_Flag | SkPaint::kAutoHi nting_Flag };
326
327 SkPaint fallbackSkPaint(originalSkPaint); 358 SkPaint fallbackSkPaint(originalSkPaint);
328 fStroke.applyToPaint(&fallbackSkPaint); 359 fStroke.applyToPaint(&fallbackSkPaint);
329 if (!fStroke.isFillStyle()) { 360 if (!fStroke.isFillStyle()) {
330 fallbackSkPaint.setStrokeWidth(fStroke.getWidth() * fTextRatio); 361 fallbackSkPaint.setStrokeWidth(fStroke.getWidth() * fTextRatio);
331 } 362 }
332 fallbackSkPaint.setTextAlign(SkPaint::kLeft_Align); // Align has already been accounted for.
333 fallbackSkPaint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
334 fallbackSkPaint.setHinting(fFont.getHinting());
335 fallbackSkPaint.setFlags((fFont.getFlags() & kPreservedFlags) |
336 (originalSkPaint.getFlags() & ~kPreservedFlags) );
337 // No need for subpixel positioning with bitmap glyphs. TODO: revisit if non-bitmap color
338 // glyphs show up and https://code.google.com/p/skia/issues/detail?id=44 08 gets resolved.
339 fallbackSkPaint.setSubpixelText(false);
340 fallbackSkPaint.setTextSize(fFont.getTextSize() * fTextRatio);
341 363
342 fallbackTextContext->drawPosText(dc, rt, clip, paint, fallbackSkPaint, v iewMatrix, 364 fallbackTextContext->drawTextBlob(dc, rt, clip, fallbackSkPaint, viewMat rix,
343 (char*)fFallbackIndices.begin(), 365 fFallbackTextBlob, 0, 0, nullptr, regi onClipBounds);
344 sizeof(uint16_t) * fFallbackIndices.cou nt(),
345 fFallbackPositions[0].asScalars(), 2, S kPoint::Make(0, 0),
346 regionClipBounds);
347 } 366 }
348 } 367 }
368
369 //////////////////////////////////////////////////////////////////////////////// ////////////////////
370
371 void GrStencilAndCoverTextContext::FallbackBlobBuilder::init(const SkPaint& font ,
372 SkScalar textRatio) {
373 SkASSERT(!this->isInitialized());
374 fBuilder.reset(new SkTextBlobBuilder);
375 fFont = font;
376 fFont.setTextAlign(SkPaint::kLeft_Align); // The glyph positions will alread y account for align.
377 fFont.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
378 // No need for subpixel positioning with bitmap glyphs. TODO: revisit if non -bitmap color glyphs
379 // show up and https://code.google.com/p/skia/issues/detail?id=4408 gets res olved.
380 fFont.setSubpixelText(false);
381 fFont.setTextSize(fFont.getTextSize() * textRatio);
382 fBuffIdx = 0;
383 }
384
385 void GrStencilAndCoverTextContext::FallbackBlobBuilder::appendGlyph(uint16_t gly phId,
386 const SkPoin t& pos) {
387 SkASSERT(this->isInitialized());
388 if (fBuffIdx >= kWriteBufferSize) {
389 this->flush();
390 }
391 fGlyphIds[fBuffIdx] = glyphId;
392 fPositions[fBuffIdx] = pos;
393 fBuffIdx++;
394 }
395
396 void GrStencilAndCoverTextContext::FallbackBlobBuilder::flush() {
397 SkASSERT(this->isInitialized());
398 SkASSERT(fBuffIdx <= kWriteBufferSize);
399 if (!fBuffIdx) {
400 return;
401 }
402 // This will automatically merge with previous runs since we use the same fo nt.
403 const SkTextBlobBuilder::RunBuffer& buff = fBuilder->allocRunPos(fFont, fBuf fIdx);
404 memcpy(buff.glyphs, fGlyphIds, fBuffIdx * sizeof(uint16_t));
405 memcpy(buff.pos, fPositions[0].asScalars(), fBuffIdx * 2 * sizeof(SkScalar)) ;
406 fBuffIdx = 0;
407 }
408
409 const SkTextBlob* GrStencilAndCoverTextContext::FallbackBlobBuilder::buildIfInit ialized() {
410 if (!this->isInitialized()) {
411 return nullptr;
412 }
413 this->flush();
414 return fBuilder->build();
415 }
OLDNEW
« no previous file with comments | « src/gpu/GrStencilAndCoverTextContext.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698