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

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

Issue 700283002: Remove 1d glyph positions from nvpr text (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Formatting Created 6 years, 1 month 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
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 "GrBitmapTextContext.h" 9 #include "GrBitmapTextContext.h"
10 #include "GrDrawTarget.h" 10 #include "GrDrawTarget.h"
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
81 // too. This in turn has the side-effect that NVPR can not stroke the paths, 81 // too. This in turn has the side-effect that NVPR can not stroke the paths,
82 // as the stroke in NVPR is defined in object-space. 82 // as the stroke in NVPR is defined in object-space.
83 // NOTE: here we have following coincidence that works at the moment: 83 // NOTE: here we have following coincidence that works at the moment:
84 // - When using the device-space glyphs, the transforms we pass to NVPR 84 // - When using the device-space glyphs, the transforms we pass to NVPR
85 // instanced drawing are the global transforms, and the view transform is 85 // instanced drawing are the global transforms, and the view transform is
86 // identity. NVPR can not use non-affine transforms in the instanced 86 // identity. NVPR can not use non-affine transforms in the instanced
87 // drawing. This is taken care of by SkDraw::ShouldDrawTextAsPaths since it 87 // drawing. This is taken care of by SkDraw::ShouldDrawTextAsPaths since it
88 // will turn off the use of device-space glyphs when perspective transforms 88 // will turn off the use of device-space glyphs when perspective transforms
89 // are in use. 89 // are in use.
90 90
91 this->init(paint, skPaint, byteLength, kMaxAccuracy_RenderMode, SkPoint::Mak e(0, 0)); 91 this->init(paint, skPaint, byteLength, kMaxAccuracy_RenderMode);
92 92
93 // Transform our starting point. 93 // Transform our starting point.
94 if (fNeedsDeviceSpaceGlyphs) { 94 if (fNeedsDeviceSpaceGlyphs) {
95 SkPoint loc; 95 SkPoint loc;
96 fContextInitialMatrix.mapXY(x, y, &loc); 96 fContextInitialMatrix.mapXY(x, y, &loc);
97 x = loc.fX; 97 x = loc.fX;
98 y = loc.fY; 98 y = loc.fY;
99 } 99 }
100 100
101 SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc(); 101 SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc();
102 102
103 fTransformType = GrPathRendering::kTranslate_PathTransformType;
104
105 const char* stop = text + byteLength; 103 const char* stop = text + byteLength;
106 104
107 // Measure first if needed. 105 // Measure first if needed.
108 if (fSkPaint.getTextAlign() != SkPaint::kLeft_Align) { 106 if (fSkPaint.getTextAlign() != SkPaint::kLeft_Align) {
109 SkFixed stopX = 0; 107 SkFixed stopX = 0;
110 SkFixed stopY = 0; 108 SkFixed stopY = 0;
111 109
112 const char* textPtr = text; 110 const char* textPtr = text;
113 while (textPtr < stop) { 111 while (textPtr < stop) {
114 // We don't need x, y here, since all subpixel variants will have th e 112 // We don't need x, y here, since all subpixel variants will have th e
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
168 } 166 }
169 167
170 // This is the fast path. Here we do not bake in the device-transform to 168 // This is the fast path. Here we do not bake in the device-transform to
171 // the glyph outline or the advances. This is because we do not need to 169 // the glyph outline or the advances. This is because we do not need to
172 // position the glyphs at all, since the caller has done the positioning. 170 // position the glyphs at all, since the caller has done the positioning.
173 // The positioning is based on SkPaint::measureText of individual 171 // The positioning is based on SkPaint::measureText of individual
174 // glyphs. That already uses glyph cache without device transforms. Device 172 // glyphs. That already uses glyph cache without device transforms. Device
175 // transform is not part of SkPaint::measureText API, and thus we use the 173 // transform is not part of SkPaint::measureText API, and thus we use the
176 // same glyphs as what were measured. 174 // same glyphs as what were measured.
177 175
178 this->init(paint, skPaint, byteLength, kMaxPerformance_RenderMode, offset); 176 this->init(paint, skPaint, byteLength, kMaxPerformance_RenderMode);
179 177
180 SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc(); 178 SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc();
181 179
182 const char* stop = text + byteLength; 180 const char* stop = text + byteLength;
183 181
184 if (SkPaint::kLeft_Align == fSkPaint.getTextAlign()) { 182 SkTextMapStateProc tmsProc(SkMatrix::I(), offset, scalarsPerPosition);
185 if (1 == scalarsPerPosition) { 183 SkTextAlignProcScalar alignProc(fSkPaint.getTextAlign());
186 fTransformType = GrPathRendering::kTranslateX_PathTransformType; 184 while (text < stop) {
187 while (text < stop) { 185 const SkGlyph& glyph = glyphCacheProc(fGlyphCache, &text, 0, 0);
188 const SkGlyph& glyph = glyphCacheProc(fGlyphCache, &text, 0, 0); 186 if (glyph.fWidth) {
189 if (glyph.fWidth) { 187 SkPoint tmsLoc;
190 this->appendGlyph(glyph.getGlyphID(), *pos); 188 tmsProc(pos, &tmsLoc);
191 } 189 SkPoint loc;
192 pos++; 190 alignProc(tmsLoc, glyph, &loc);
193 } 191
194 } else { 192 this->appendGlyph(glyph.getGlyphID(), loc.x(), loc.y());
195 SkASSERT(2 == scalarsPerPosition);
196 fTransformType = GrPathRendering::kTranslate_PathTransformType;
197 while (text < stop) {
198 const SkGlyph& glyph = glyphCacheProc(fGlyphCache, &text, 0, 0);
199 if (glyph.fWidth) {
200 this->appendGlyph(glyph.getGlyphID(), pos[0], pos[1]);
201 }
202 pos += 2;
203 }
204 } 193 }
205 } else { 194 pos += scalarsPerPosition;
206 fTransformType = GrPathRendering::kTranslate_PathTransformType;
207 SkTextMapStateProc tmsProc(SkMatrix::I(), SkPoint::Make(0, 0), scalarsPe rPosition);
208 SkTextAlignProcScalar alignProc(fSkPaint.getTextAlign());
209 while (text < stop) {
210 const SkGlyph& glyph = glyphCacheProc(fGlyphCache, &text, 0, 0);
211 if (glyph.fWidth) {
212 SkPoint tmsLoc;
213 tmsProc(pos, &tmsLoc);
214 SkPoint loc;
215 alignProc(tmsLoc, glyph, &loc);
216
217 this->appendGlyph(glyph.getGlyphID(), loc.x(), loc.y());
218 }
219 pos += scalarsPerPosition;
220 }
221 } 195 }
222 196
223 this->finish(); 197 this->finish();
224 } 198 }
225 199
226 static GrPathRange* get_gr_glyphs(GrContext* ctx, 200 static GrPathRange* get_gr_glyphs(GrContext* ctx,
227 const SkTypeface* typeface, 201 const SkTypeface* typeface,
228 const SkDescriptor* desc, 202 const SkDescriptor* desc,
229 const SkStrokeRec& stroke) { 203 const SkStrokeRec& stroke) {
230 static const GrCacheID::Domain gGlyphsDomain = GrCacheID::GenerateDomain(); 204 static const GrCacheID::Domain gGlyphsDomain = GrCacheID::GenerateDomain();
(...skipping 12 matching lines...) Expand all
243 glyphs.reset(ctx->getGpu()->pathRendering()->createGlyphs(typeface, desc , stroke)); 217 glyphs.reset(ctx->getGpu()->pathRendering()->createGlyphs(typeface, desc , stroke));
244 ctx->addResourceToCache(resourceKey, glyphs); 218 ctx->addResourceToCache(resourceKey, glyphs);
245 } 219 }
246 220
247 return glyphs.detach(); 221 return glyphs.detach();
248 } 222 }
249 223
250 void GrStencilAndCoverTextContext::init(const GrPaint& paint, 224 void GrStencilAndCoverTextContext::init(const GrPaint& paint,
251 const SkPaint& skPaint, 225 const SkPaint& skPaint,
252 size_t textByteLength, 226 size_t textByteLength,
253 RenderMode renderMode, 227 RenderMode renderMode) {
254 const SkPoint& textTranslate) {
255 GrTextContext::init(paint, skPaint); 228 GrTextContext::init(paint, skPaint);
256 229
257 fContextInitialMatrix = fContext->getMatrix(); 230 fContextInitialMatrix = fContext->getMatrix();
258 231
259 const bool otherBackendsWillDrawAsPaths = 232 const bool otherBackendsWillDrawAsPaths =
260 SkDraw::ShouldDrawTextAsPaths(skPaint, fContextInitialMatrix); 233 SkDraw::ShouldDrawTextAsPaths(skPaint, fContextInitialMatrix);
261 234
262 fNeedsDeviceSpaceGlyphs = !otherBackendsWillDrawAsPaths && 235 fNeedsDeviceSpaceGlyphs = !otherBackendsWillDrawAsPaths &&
263 kMaxAccuracy_RenderMode == renderMode && 236 kMaxAccuracy_RenderMode == renderMode &&
264 SkToBool(fContextInitialMatrix.getType() & 237 SkToBool(fContextInitialMatrix.getType() &
265 (SkMatrix::kScale_Mask | SkMatrix::kAffin e_Mask)); 238 (SkMatrix::kScale_Mask | SkMatrix::kAffin e_Mask));
266 239
267 if (fNeedsDeviceSpaceGlyphs) { 240 if (fNeedsDeviceSpaceGlyphs) {
268 // SkDraw::ShouldDrawTextAsPaths takes care of perspective transforms. 241 // SkDraw::ShouldDrawTextAsPaths takes care of perspective transforms.
269 SkASSERT(!fContextInitialMatrix.hasPerspective()); 242 SkASSERT(!fContextInitialMatrix.hasPerspective());
270 SkASSERT(textTranslate.isZero()); // TODO: Handle textTranslate in devic e-space usecase.
271 243
272 fTextRatio = fTextInverseRatio = 1.0f; 244 fTextRatio = fTextInverseRatio = 1.0f;
273 245
274 // Glyphs loaded by GPU path rendering have an inverted y-direction. 246 // Glyphs loaded by GPU path rendering have an inverted y-direction.
275 SkMatrix m; 247 SkMatrix m;
276 m.setScale(1, -1); 248 m.setScale(1, -1);
277 fContext->setMatrix(m); 249 fContext->setMatrix(m);
278 250
279 // Post-flip the initial matrix so we're left with just the flip after 251 // Post-flip the initial matrix so we're left with just the flip after
280 // the paint preConcats the inverse. 252 // the paint preConcats the inverse.
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
342 canUseRawPaths = SK_Scalar1 == fSkPaint.getTextScaleX() && 314 canUseRawPaths = SK_Scalar1 == fSkPaint.getTextScaleX() &&
343 0 == fSkPaint.getTextSkewX() && 315 0 == fSkPaint.getTextSkewX() &&
344 !fSkPaint.isFakeBoldText() && 316 !fSkPaint.isFakeBoldText() &&
345 !fSkPaint.isVerticalText(); 317 !fSkPaint.isVerticalText();
346 } else { 318 } else {
347 fTextRatio = fTextInverseRatio = 1.0f; 319 fTextRatio = fTextInverseRatio = 1.0f;
348 canUseRawPaths = false; 320 canUseRawPaths = false;
349 } 321 }
350 322
351 SkMatrix textMatrix; 323 SkMatrix textMatrix;
352 textMatrix.setTranslate(textTranslate.x(), textTranslate.y());
353 // Glyphs loaded by GPU path rendering have an inverted y-direction. 324 // Glyphs loaded by GPU path rendering have an inverted y-direction.
354 textMatrix.preScale(fTextRatio, -fTextRatio); 325 textMatrix.setScale(fTextRatio, -fTextRatio);
355 fPaint.localCoordChange(textMatrix); 326 fPaint.localCoordChange(textMatrix);
356 fContext->concatMatrix(textMatrix); 327 fContext->concatMatrix(textMatrix);
357 328
358 fGlyphCache = fSkPaint.detachCache(&fDeviceProperties, NULL, false); 329 fGlyphCache = fSkPaint.detachCache(&fDeviceProperties, NULL, false);
359 fGlyphs = canUseRawPaths ? 330 fGlyphs = canUseRawPaths ?
360 get_gr_glyphs(fContext, fSkPaint.getTypeface(), NULL, gpuS troke) : 331 get_gr_glyphs(fContext, fSkPaint.getTypeface(), NULL, gpuS troke) :
361 get_gr_glyphs(fContext, fGlyphCache->getScalerContext()->g etTypeface(), 332 get_gr_glyphs(fContext, fGlyphCache->getScalerContext()->g etTypeface(),
362 &fGlyphCache->getDescriptor(), gpuStroke); 333 &fGlyphCache->getDescriptor(), gpuStroke);
363 } 334 }
364 335
365 fStateRestore.set(fDrawTarget->drawState()); 336 fStateRestore.set(fDrawTarget->drawState());
366 337
367 fDrawTarget->drawState()->setFromPaint(fPaint, fContext->getMatrix(), 338 fDrawTarget->drawState()->setFromPaint(fPaint, fContext->getMatrix(),
368 fContext->getRenderTarget()); 339 fContext->getRenderTarget());
369 340
370 GR_STATIC_CONST_SAME_STENCIL(kStencilPass, 341 GR_STATIC_CONST_SAME_STENCIL(kStencilPass,
371 kZero_StencilOp, 342 kZero_StencilOp,
372 kZero_StencilOp, 343 kZero_StencilOp,
373 kNotEqual_StencilFunc, 344 kNotEqual_StencilFunc,
374 0xffff, 345 0xffff,
375 0x0000, 346 0x0000,
376 0xffff); 347 0xffff);
377 348
378 *fDrawTarget->drawState()->stencil() = kStencilPass; 349 *fDrawTarget->drawState()->stencil() = kStencilPass;
379 350
380 SkASSERT(0 == fPendingGlyphCount); 351 SkASSERT(0 == fPendingGlyphCount);
381 } 352 }
382 353
383 inline void GrStencilAndCoverTextContext::appendGlyph(uint16_t glyphID, float x) { 354 inline void GrStencilAndCoverTextContext::appendGlyph(uint16_t glyphID, float x, float y) {
384 SkASSERT(GrPathRendering::kTranslateX_PathTransformType == fTransformType);
385
386 if (fPendingGlyphCount >= kGlyphBufferSize) { 355 if (fPendingGlyphCount >= kGlyphBufferSize) {
387 this->flush(); 356 this->flush();
388 } 357 }
389
390 fIndexBuffer[fPendingGlyphCount] = glyphID;
391 fTransformBuffer[fPendingGlyphCount] = fTextInverseRatio * x;
392
393 ++fPendingGlyphCount;
394 }
395
396 inline void GrStencilAndCoverTextContext::appendGlyph(uint16_t glyphID, float x, float y) {
397 SkASSERT(GrPathRendering::kTranslate_PathTransformType == fTransformType);
398
399 if (fPendingGlyphCount >= kGlyphBufferSize) {
400 this->flush();
401 }
402 358
403 fIndexBuffer[fPendingGlyphCount] = glyphID; 359 fIndexBuffer[fPendingGlyphCount] = glyphID;
404 fTransformBuffer[2 * fPendingGlyphCount] = fTextInverseRatio * x; 360 fTransformBuffer[2 * fPendingGlyphCount] = fTextInverseRatio * x;
405 fTransformBuffer[2 * fPendingGlyphCount + 1] = -fTextInverseRatio * y; 361 fTransformBuffer[2 * fPendingGlyphCount + 1] = -fTextInverseRatio * y;
406 362
407 ++fPendingGlyphCount; 363 ++fPendingGlyphCount;
408 } 364 }
409 365
410 void GrStencilAndCoverTextContext::flush() { 366 void GrStencilAndCoverTextContext::flush() {
411 if (0 == fPendingGlyphCount) { 367 if (0 == fPendingGlyphCount) {
412 return; 368 return;
413 } 369 }
414 370
415 fDrawTarget->drawPaths(fGlyphs, fIndexBuffer, fPendingGlyphCount, 371 fDrawTarget->drawPaths(fGlyphs, fIndexBuffer, fPendingGlyphCount, fTransform Buffer,
416 fTransformBuffer, fTransformType, GrPathRendering::kW inding_FillType); 372 GrPathRendering::kTranslate_PathTransformType,
373 GrPathRendering::kWinding_FillType);
417 374
418 fPendingGlyphCount = 0; 375 fPendingGlyphCount = 0;
419 } 376 }
420 377
421 void GrStencilAndCoverTextContext::finish() { 378 void GrStencilAndCoverTextContext::finish() {
422 this->flush(); 379 this->flush();
423 380
424 fGlyphs->unref(); 381 fGlyphs->unref();
425 fGlyphs = NULL; 382 fGlyphs = NULL;
426 383
427 SkGlyphCache::AttachCache(fGlyphCache); 384 SkGlyphCache::AttachCache(fGlyphCache);
428 fGlyphCache = NULL; 385 fGlyphCache = NULL;
429 386
430 fDrawTarget->drawState()->stencil()->setDisabled(); 387 fDrawTarget->drawState()->stencil()->setDisabled();
431 fStateRestore.set(NULL); 388 fStateRestore.set(NULL);
432 fContext->setMatrix(fContextInitialMatrix); 389 fContext->setMatrix(fContextInitialMatrix);
433 GrTextContext::finish(); 390 GrTextContext::finish();
434 } 391 }
435 392
OLDNEW
« src/gpu/GrStencilAndCoverTextContext.h ('K') | « src/gpu/GrStencilAndCoverTextContext.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698