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

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

Issue 808703006: remove view matrix from context (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: one more fix Created 6 years 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') | src/gpu/GrTextContext.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 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 22 matching lines...) Expand all
33 GrStencilAndCoverTextContext* textContext = SkNEW_ARGS(GrStencilAndCoverText Context, 33 GrStencilAndCoverTextContext* textContext = SkNEW_ARGS(GrStencilAndCoverText Context,
34 (context, props)); 34 (context, props));
35 textContext->fFallbackTextContext = GrBitmapTextContext::Create(context, pro ps); 35 textContext->fFallbackTextContext = GrBitmapTextContext::Create(context, pro ps);
36 36
37 return textContext; 37 return textContext;
38 } 38 }
39 39
40 GrStencilAndCoverTextContext::~GrStencilAndCoverTextContext() { 40 GrStencilAndCoverTextContext::~GrStencilAndCoverTextContext() {
41 } 41 }
42 42
43 bool GrStencilAndCoverTextContext::canDraw(const SkPaint& paint) { 43 bool GrStencilAndCoverTextContext::canDraw(const SkPaint& paint, const SkMatrix& viewMatrix) {
44 if (paint.getRasterizer()) { 44 if (paint.getRasterizer()) {
45 return false; 45 return false;
46 } 46 }
47 if (paint.getMaskFilter()) { 47 if (paint.getMaskFilter()) {
48 return false; 48 return false;
49 } 49 }
50 if (paint.getPathEffect()) { 50 if (paint.getPathEffect()) {
51 return false; 51 return false;
52 } 52 }
53 53
54 // No hairlines unless we can map the 1 px width to the object space. 54 // No hairlines unless we can map the 1 px width to the object space.
55 if (paint.getStyle() == SkPaint::kStroke_Style 55 if (paint.getStyle() == SkPaint::kStroke_Style
56 && paint.getStrokeWidth() == 0 56 && paint.getStrokeWidth() == 0
57 && fContext->getMatrix().hasPerspective()) { 57 && viewMatrix.hasPerspective()) {
58 return false; 58 return false;
59 } 59 }
60 60
61 // No color bitmap fonts. 61 // No color bitmap fonts.
62 SkScalerContext::Rec rec; 62 SkScalerContext::Rec rec;
63 SkScalerContext::MakeRec(paint, &fDeviceProperties, NULL, &rec); 63 SkScalerContext::MakeRec(paint, &fDeviceProperties, NULL, &rec);
64 return rec.getFormat() != SkMask::kARGB32_Format; 64 return rec.getFormat() != SkMask::kARGB32_Format;
65 } 65 }
66 66
67 void GrStencilAndCoverTextContext::onDrawText(const GrPaint& paint, 67 void GrStencilAndCoverTextContext::onDrawText(const GrPaint& paint,
68 const SkPaint& skPaint, 68 const SkPaint& skPaint,
69 const SkMatrix& viewMatrix,
69 const char text[], 70 const char text[],
70 size_t byteLength, 71 size_t byteLength,
71 SkScalar x, SkScalar y) { 72 SkScalar x, SkScalar y) {
72 SkASSERT(byteLength == 0 || text != NULL); 73 SkASSERT(byteLength == 0 || text != NULL);
73 74
74 if (text == NULL || byteLength == 0 /*|| fRC->isEmpty()*/) { 75 if (text == NULL || byteLength == 0 /*|| fRC->isEmpty()*/) {
75 return; 76 return;
76 } 77 }
77 78
78 // This is the slow path, mainly used by Skia unit tests. The other 79 // This is the slow path, mainly used by Skia unit tests. The other
79 // backends (8888, gpu, ...) use device-space dependent glyph caches. In 80 // backends (8888, gpu, ...) use device-space dependent glyph caches. In
80 // order to match the glyph positions that the other code paths produce, we 81 // order to match the glyph positions that the other code paths produce, we
81 // must also use device-space dependent glyph cache. This has the 82 // must also use device-space dependent glyph cache. This has the
82 // side-effect that the glyph shape outline will be in device-space, 83 // side-effect that the glyph shape outline will be in device-space,
83 // too. This in turn has the side-effect that NVPR can not stroke the paths, 84 // too. This in turn has the side-effect that NVPR can not stroke the paths,
84 // as the stroke in NVPR is defined in object-space. 85 // as the stroke in NVPR is defined in object-space.
85 // NOTE: here we have following coincidence that works at the moment: 86 // NOTE: here we have following coincidence that works at the moment:
86 // - When using the device-space glyphs, the transforms we pass to NVPR 87 // - When using the device-space glyphs, the transforms we pass to NVPR
87 // instanced drawing are the global transforms, and the view transform is 88 // instanced drawing are the global transforms, and the view transform is
88 // identity. NVPR can not use non-affine transforms in the instanced 89 // identity. NVPR can not use non-affine transforms in the instanced
89 // drawing. This is taken care of by SkDraw::ShouldDrawTextAsPaths since it 90 // drawing. This is taken care of by SkDraw::ShouldDrawTextAsPaths since it
90 // will turn off the use of device-space glyphs when perspective transforms 91 // will turn off the use of device-space glyphs when perspective transforms
91 // are in use. 92 // are in use.
92 93
93 this->init(paint, skPaint, byteLength, kMaxAccuracy_RenderMode); 94 this->init(paint, skPaint, byteLength, kMaxAccuracy_RenderMode, viewMatrix);
94 95
95 // Transform our starting point. 96 // Transform our starting point.
96 if (fUsingDeviceSpaceGlyphs) { 97 if (fUsingDeviceSpaceGlyphs) {
97 SkPoint loc; 98 SkPoint loc;
98 fContextInitialMatrix.mapXY(x, y, &loc); 99 fContextInitialMatrix.mapXY(x, y, &loc);
99 x = loc.fX; 100 x = loc.fX;
100 y = loc.fY; 101 y = loc.fY;
101 } 102 }
102 103
103 SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc(); 104 SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc();
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
147 148
148 fx += SkFixedMul_portable(glyph.fAdvanceX, fixedSizeRatio); 149 fx += SkFixedMul_portable(glyph.fAdvanceX, fixedSizeRatio);
149 fy += SkFixedMul_portable(glyph.fAdvanceY, fixedSizeRatio); 150 fy += SkFixedMul_portable(glyph.fAdvanceY, fixedSizeRatio);
150 } 151 }
151 152
152 this->finish(); 153 this->finish();
153 } 154 }
154 155
155 void GrStencilAndCoverTextContext::onDrawPosText(const GrPaint& paint, 156 void GrStencilAndCoverTextContext::onDrawPosText(const GrPaint& paint,
156 const SkPaint& skPaint, 157 const SkPaint& skPaint,
158 const SkMatrix& viewMatrix,
157 const char text[], 159 const char text[],
158 size_t byteLength, 160 size_t byteLength,
159 const SkScalar pos[], 161 const SkScalar pos[],
160 int scalarsPerPosition, 162 int scalarsPerPosition,
161 const SkPoint& offset) { 163 const SkPoint& offset) {
162 SkASSERT(byteLength == 0 || text != NULL); 164 SkASSERT(byteLength == 0 || text != NULL);
163 SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition); 165 SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition);
164 166
165 // nothing to draw 167 // nothing to draw
166 if (text == NULL || byteLength == 0/* || fRC->isEmpty()*/) { 168 if (text == NULL || byteLength == 0/* || fRC->isEmpty()*/) {
167 return; 169 return;
168 } 170 }
169 171
170 // This is the fast path. Here we do not bake in the device-transform to 172 // 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 173 // 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. 174 // position the glyphs at all, since the caller has done the positioning.
173 // The positioning is based on SkPaint::measureText of individual 175 // The positioning is based on SkPaint::measureText of individual
174 // glyphs. That already uses glyph cache without device transforms. Device 176 // glyphs. That already uses glyph cache without device transforms. Device
175 // transform is not part of SkPaint::measureText API, and thus we use the 177 // transform is not part of SkPaint::measureText API, and thus we use the
176 // same glyphs as what were measured. 178 // same glyphs as what were measured.
177 179
178 this->init(paint, skPaint, byteLength, kMaxPerformance_RenderMode); 180 this->init(paint, skPaint, byteLength, kMaxPerformance_RenderMode, viewMatri x);
179 181
180 SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc(); 182 SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc();
181 183
182 const char* stop = text + byteLength; 184 const char* stop = text + byteLength;
183 185
184 SkTextMapStateProc tmsProc(SkMatrix::I(), offset, scalarsPerPosition); 186 SkTextMapStateProc tmsProc(SkMatrix::I(), offset, scalarsPerPosition);
185 SkTextAlignProcScalar alignProc(fSkPaint.getTextAlign()); 187 SkTextAlignProcScalar alignProc(fSkPaint.getTextAlign());
186 while (text < stop) { 188 while (text < stop) {
187 const SkGlyph& glyph = glyphCacheProc(fGlyphCache, &text, 0, 0); 189 const SkGlyph& glyph = glyphCacheProc(fGlyphCache, &text, 0, 0);
188 if (glyph.fWidth) { 190 if (glyph.fWidth) {
(...skipping 30 matching lines...) Expand all
219 glyphs.reset(ctx->getGpu()->pathRendering()->createGlyphs(typeface, desc , stroke)); 221 glyphs.reset(ctx->getGpu()->pathRendering()->createGlyphs(typeface, desc , stroke));
220 ctx->addResourceToCache(resourceKey, glyphs); 222 ctx->addResourceToCache(resourceKey, glyphs);
221 } 223 }
222 224
223 return glyphs.detach(); 225 return glyphs.detach();
224 } 226 }
225 227
226 void GrStencilAndCoverTextContext::init(const GrPaint& paint, 228 void GrStencilAndCoverTextContext::init(const GrPaint& paint,
227 const SkPaint& skPaint, 229 const SkPaint& skPaint,
228 size_t textByteLength, 230 size_t textByteLength,
229 RenderMode renderMode) { 231 RenderMode renderMode,
232 const SkMatrix& viewMatrix) {
230 GrTextContext::init(paint, skPaint); 233 GrTextContext::init(paint, skPaint);
231 234
232 fContextInitialMatrix = fContext->getMatrix(); 235 fContextInitialMatrix = viewMatrix;
236 fViewMatrix = viewMatrix;
233 237
234 const bool otherBackendsWillDrawAsPaths = 238 const bool otherBackendsWillDrawAsPaths =
235 SkDraw::ShouldDrawTextAsPaths(skPaint, fContextInitialMatrix); 239 SkDraw::ShouldDrawTextAsPaths(skPaint, fContextInitialMatrix);
236 240
237 fUsingDeviceSpaceGlyphs = !otherBackendsWillDrawAsPaths && 241 fUsingDeviceSpaceGlyphs = !otherBackendsWillDrawAsPaths &&
238 kMaxAccuracy_RenderMode == renderMode && 242 kMaxAccuracy_RenderMode == renderMode &&
239 SkToBool(fContextInitialMatrix.getType() & 243 SkToBool(fContextInitialMatrix.getType() &
240 (SkMatrix::kScale_Mask | SkMatrix::kAffin e_Mask)); 244 (SkMatrix::kScale_Mask | SkMatrix::kAffin e_Mask));
241 245
242 if (fUsingDeviceSpaceGlyphs) { 246 if (fUsingDeviceSpaceGlyphs) {
243 // SkDraw::ShouldDrawTextAsPaths takes care of perspective transforms. 247 // SkDraw::ShouldDrawTextAsPaths takes care of perspective transforms.
244 SkASSERT(!fContextInitialMatrix.hasPerspective()); 248 SkASSERT(!fContextInitialMatrix.hasPerspective());
245 249
246 // The whole shape (including stroke) will be baked into the glyph outli nes. Make 250 // The whole shape (including stroke) will be baked into the glyph outli nes. Make
247 // NVPR just fill the baked shapes. 251 // NVPR just fill the baked shapes.
248 fStroke = SkStrokeRec(SkStrokeRec::kFill_InitStyle); 252 fStroke = SkStrokeRec(SkStrokeRec::kFill_InitStyle);
249 253
250 fTextRatio = fTextInverseRatio = 1.0f; 254 fTextRatio = fTextInverseRatio = 1.0f;
251 255
252 // Glyphs loaded by GPU path rendering have an inverted y-direction. 256 // Glyphs loaded by GPU path rendering have an inverted y-direction.
253 SkMatrix m; 257 SkMatrix m;
254 m.setScale(1, -1); 258 m.setScale(1, -1);
255 fContext->setMatrix(m); 259 fViewMatrix = m;
256 260
257 // Post-flip the initial matrix so we're left with just the flip after 261 // Post-flip the initial matrix so we're left with just the flip after
258 // the paint preConcats the inverse. 262 // the paint preConcats the inverse.
259 m = fContextInitialMatrix; 263 m = fContextInitialMatrix;
260 m.postScale(1, -1); 264 m.postScale(1, -1);
261 fPaint.localCoordChangeInverse(m); 265 fPaint.localCoordChangeInverse(m);
262 266
263 fGlyphCache = fSkPaint.detachCache(&fDeviceProperties, &fContextInitialM atrix, 267 fGlyphCache = fSkPaint.detachCache(&fDeviceProperties, &fContextInitialM atrix,
264 true /*ignoreGamma*/); 268 true /*ignoreGamma*/);
265 fGlyphs = get_gr_glyphs(fContext, fGlyphCache->getScalerContext()->getTy peface(), 269 fGlyphs = get_gr_glyphs(fContext, fGlyphCache->getScalerContext()->getTy peface(),
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
321 !fSkPaint.isVerticalText(); 325 !fSkPaint.isVerticalText();
322 } else { 326 } else {
323 fTextRatio = fTextInverseRatio = 1.0f; 327 fTextRatio = fTextInverseRatio = 1.0f;
324 canUseRawPaths = false; 328 canUseRawPaths = false;
325 } 329 }
326 330
327 SkMatrix textMatrix; 331 SkMatrix textMatrix;
328 // Glyphs loaded by GPU path rendering have an inverted y-direction. 332 // Glyphs loaded by GPU path rendering have an inverted y-direction.
329 textMatrix.setScale(fTextRatio, -fTextRatio); 333 textMatrix.setScale(fTextRatio, -fTextRatio);
330 fPaint.localCoordChange(textMatrix); 334 fPaint.localCoordChange(textMatrix);
331 fContext->concatMatrix(textMatrix); 335 fViewMatrix.preConcat(textMatrix);
332 336
333 fGlyphCache = fSkPaint.detachCache(&fDeviceProperties, NULL, true /*igno reGamma*/); 337 fGlyphCache = fSkPaint.detachCache(&fDeviceProperties, NULL, true /*igno reGamma*/);
334 fGlyphs = canUseRawPaths ? 338 fGlyphs = canUseRawPaths ?
335 get_gr_glyphs(fContext, fSkPaint.getTypeface(), NULL, fStr oke) : 339 get_gr_glyphs(fContext, fSkPaint.getTypeface(), NULL, fStr oke) :
336 get_gr_glyphs(fContext, fGlyphCache->getScalerContext()->g etTypeface(), 340 get_gr_glyphs(fContext, fGlyphCache->getScalerContext()->g etTypeface(),
337 &fGlyphCache->getDescriptor(), fStroke); 341 &fGlyphCache->getDescriptor(), fStroke);
338 } 342 }
339 343
340 fStateRestore.set(&fDrawState); 344 fStateRestore.set(&fDrawState);
341 345
342 fDrawState.setFromPaint(fPaint, fContext->getMatrix(), fContext->getRenderTa rget()); 346 fDrawState.setFromPaint(fPaint, fViewMatrix, fContext->getRenderTarget());
343 347
344 GR_STATIC_CONST_SAME_STENCIL(kStencilPass, 348 GR_STATIC_CONST_SAME_STENCIL(kStencilPass,
345 kZero_StencilOp, 349 kZero_StencilOp,
346 kZero_StencilOp, 350 kZero_StencilOp,
347 kNotEqual_StencilFunc, 351 kNotEqual_StencilFunc,
348 0xffff, 352 0xffff,
349 0x0000, 353 0x0000,
350 0xffff); 354 0xffff);
351 355
352 *fDrawState.stencil() = kStencilPass; 356 *fDrawState.stencil() = kStencilPass;
353 357
354 SkASSERT(0 == fQueuedGlyphCount); 358 SkASSERT(0 == fQueuedGlyphCount);
355 SkASSERT(kGlyphBufferSize == fFallbackGlyphsIdx); 359 SkASSERT(kGlyphBufferSize == fFallbackGlyphsIdx);
356 } 360 }
357 361
358 bool GrStencilAndCoverTextContext::mapToFallbackContext(GrContext::AutoMatrix& a utoMatrix, 362 bool GrStencilAndCoverTextContext::mapToFallbackContext(SkMatrix* inverse) {
359 SkMatrix* inverse) {
360 // The current view matrix is flipped because GPU path rendering glyphs have an 363 // The current view matrix is flipped because GPU path rendering glyphs have an
361 // inverted y-direction. Unflip the view matrix for the fallback context. If using 364 // inverted y-direction. Unflip the view matrix for the fallback context. If using
362 // device-space glyphs, we'll also need to restore the original view matrix since 365 // device-space glyphs, we'll also need to restore the original view matrix since
363 // we moved that transfomation into our local glyph cache for this scenario. Also 366 // we moved that transfomation into our local glyph cache for this scenario. Also
364 // track the inverse operation so the caller can unmap the paint and glyph p ositions. 367 // track the inverse operation so the caller can unmap the paint and glyph p ositions.
365 if (fUsingDeviceSpaceGlyphs) { 368 if (fUsingDeviceSpaceGlyphs) {
366 autoMatrix.set(fContext, fContextInitialMatrix); 369 fViewMatrix = fContextInitialMatrix;
367 if (!fContextInitialMatrix.invert(inverse)) { 370 if (!fContextInitialMatrix.invert(inverse)) {
368 return false; 371 return false;
369 } 372 }
370 inverse->preScale(1, -1); 373 inverse->preScale(1, -1);
371 } else { 374 } else {
372 inverse->setScale(1, -1); 375 inverse->setScale(1, -1);
373 const SkMatrix& unflip = *inverse; // unflip is equal to its own inverse . 376 const SkMatrix& unflip = *inverse; // unflip is equal to its own inverse .
374 autoMatrix.setPreConcat(fContext, unflip); 377 fViewMatrix.preConcat(unflip);
375 } 378 }
376 return true; 379 return true;
377 } 380 }
378 381
379 inline void GrStencilAndCoverTextContext::appendGlyph(const SkGlyph& glyph, cons t SkPoint& pos) { 382 inline void GrStencilAndCoverTextContext::appendGlyph(const SkGlyph& glyph, cons t SkPoint& pos) {
380 if (fQueuedGlyphCount >= fFallbackGlyphsIdx) { 383 if (fQueuedGlyphCount >= fFallbackGlyphsIdx) {
381 SkASSERT(fQueuedGlyphCount == fFallbackGlyphsIdx); 384 SkASSERT(fQueuedGlyphCount == fFallbackGlyphsIdx);
382 this->flush(); 385 this->flush();
383 } 386 }
384 387
(...skipping 29 matching lines...) Expand all
414 417
415 GrPaint paintFallback(fPaint); 418 GrPaint paintFallback(fPaint);
416 419
417 SkPaint skPaintFallback(fSkPaint); 420 SkPaint skPaintFallback(fSkPaint);
418 if (!fUsingDeviceSpaceGlyphs) { 421 if (!fUsingDeviceSpaceGlyphs) {
419 fStroke.applyToPaint(&skPaintFallback); 422 fStroke.applyToPaint(&skPaintFallback);
420 } 423 }
421 skPaintFallback.setTextAlign(SkPaint::kLeft_Align); // Align has already been accounted for. 424 skPaintFallback.setTextAlign(SkPaint::kLeft_Align); // Align has already been accounted for.
422 skPaintFallback.setTextEncoding(SkPaint::kGlyphID_TextEncoding); 425 skPaintFallback.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
423 426
424 GrContext::AutoMatrix autoMatrix;
425 SkMatrix inverse; 427 SkMatrix inverse;
426 if (this->mapToFallbackContext(autoMatrix, &inverse)) { 428 if (this->mapToFallbackContext(&inverse)) {
427 paintFallback.localCoordChangeInverse(inverse); 429 paintFallback.localCoordChangeInverse(inverse);
428 inverse.mapPoints(&fGlyphPositions[fFallbackGlyphsIdx], fallbackGlyp hCount); 430 inverse.mapPoints(&fGlyphPositions[fFallbackGlyphsIdx], fallbackGlyp hCount);
429 } 431 }
430 432
431 fFallbackTextContext->drawPosText(paintFallback, skPaintFallback, 433 fFallbackTextContext->drawPosText(paintFallback, skPaintFallback, fViewM atrix,
432 (char*)&fGlyphIndices[fFallbackGlyphsI dx], 434 (char*)&fGlyphIndices[fFallbackGlyphsI dx],
433 2 * fallbackGlyphCount, 435 2 * fallbackGlyphCount,
434 get_xy_scalar_array(&fGlyphPositions[f FallbackGlyphsIdx]), 436 get_xy_scalar_array(&fGlyphPositions[f FallbackGlyphsIdx]),
435 2, SkPoint::Make(0, 0)); 437 2, SkPoint::Make(0, 0));
436 438
437 fFallbackGlyphsIdx = kGlyphBufferSize; 439 fFallbackGlyphsIdx = kGlyphBufferSize;
438 } 440 }
439 } 441 }
440 442
441 void GrStencilAndCoverTextContext::finish() { 443 void GrStencilAndCoverTextContext::finish() {
442 this->flush(); 444 this->flush();
443 445
444 fGlyphs->unref(); 446 fGlyphs->unref();
445 fGlyphs = NULL; 447 fGlyphs = NULL;
446 448
447 SkGlyphCache::AttachCache(fGlyphCache); 449 SkGlyphCache::AttachCache(fGlyphCache);
448 fGlyphCache = NULL; 450 fGlyphCache = NULL;
449 451
450 fDrawState.stencil()->setDisabled(); 452 fDrawState.stencil()->setDisabled();
451 fStateRestore.set(NULL); 453 fStateRestore.set(NULL);
452 fContext->setMatrix(fContextInitialMatrix); 454 fViewMatrix = fContextInitialMatrix;
453 GrTextContext::finish(); 455 GrTextContext::finish();
454 } 456 }
455 457
OLDNEW
« no previous file with comments | « src/gpu/GrStencilAndCoverTextContext.h ('k') | src/gpu/GrTextContext.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698