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

Side by Side Diff: src/gpu/SkGpuDevice.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/SkGpuDevice.h ('k') | src/gpu/SkGr.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 2011 Google Inc. 2 * Copyright 2011 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 "SkGpuDevice.h" 8 #include "SkGpuDevice.h"
9 9
10 #include "effects/GrBicubicEffect.h" 10 #include "effects/GrBicubicEffect.h"
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
45 #include "SkErrorInternals.h" 45 #include "SkErrorInternals.h"
46 46
47 #if SK_SUPPORT_GPU 47 #if SK_SUPPORT_GPU
48 48
49 enum { kDefaultImageFilterCacheSize = 32 * 1024 * 1024 }; 49 enum { kDefaultImageFilterCacheSize = 32 * 1024 * 1024 };
50 50
51 #define CACHE_COMPATIBLE_DEVICE_TEXTURES 1 51 #define CACHE_COMPATIBLE_DEVICE_TEXTURES 1
52 52
53 #if 0 53 #if 0
54 extern bool (*gShouldDrawProc)(); 54 extern bool (*gShouldDrawProc)();
55 #define CHECK_SHOULD_DRAW(draw, forceI) \ 55 #define CHECK_SHOULD_DRAW(draw) \
56 do { \ 56 do { \
57 if (gShouldDrawProc && !gShouldDrawProc()) return; \ 57 if (gShouldDrawProc && !gShouldDrawProc()) return; \
58 this->prepareDraw(draw, forceI); \ 58 this->prepareDraw(draw); \
59 } while (0) 59 } while (0)
60 #else 60 #else
61 #define CHECK_SHOULD_DRAW(draw, forceI) this->prepareDraw(draw, forceI) 61 #define CHECK_SHOULD_DRAW(draw) this->prepareDraw(draw)
62 #endif 62 #endif
63 63
64 // This constant represents the screen alignment criterion in texels for 64 // This constant represents the screen alignment criterion in texels for
65 // requiring texture domain clamping to prevent color bleeding when drawing 65 // requiring texture domain clamping to prevent color bleeding when drawing
66 // a sub region of a larger source image. 66 // a sub region of a larger source image.
67 #define COLOR_BLEED_TOLERANCE 0.001f 67 #define COLOR_BLEED_TOLERANCE 0.001f
68 68
69 #define DO_DEFERRED_CLEAR() \ 69 #define DO_DEFERRED_CLEAR() \
70 do { \ 70 do { \
71 if (fFlags & kNeedClear_Flag) { \ 71 if (fFlags & kNeedClear_Flag) { \
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
264 fClipData.fClipStack = canvas->getClipStack(); 264 fClipData.fClipStack = canvas->getClipStack();
265 } 265 }
266 266
267 void SkGpuDevice::onDetachFromCanvas() { 267 void SkGpuDevice::onDetachFromCanvas() {
268 INHERITED::onDetachFromCanvas(); 268 INHERITED::onDetachFromCanvas();
269 fClipData.fClipStack = NULL; 269 fClipData.fClipStack = NULL;
270 } 270 }
271 271
272 // call this every draw call, to ensure that the context reflects our state, 272 // call this every draw call, to ensure that the context reflects our state,
273 // and not the state from some other canvas/device 273 // and not the state from some other canvas/device
274 void SkGpuDevice::prepareDraw(const SkDraw& draw, bool forceIdentity) { 274 void SkGpuDevice::prepareDraw(const SkDraw& draw) {
275 SkASSERT(fClipData.fClipStack); 275 SkASSERT(fClipData.fClipStack);
276 276
277 fContext->setRenderTarget(fRenderTarget); 277 fContext->setRenderTarget(fRenderTarget);
278 278
279 SkASSERT(draw.fClipStack && draw.fClipStack == fClipData.fClipStack); 279 SkASSERT(draw.fClipStack && draw.fClipStack == fClipData.fClipStack);
280 280
281 if (forceIdentity) {
282 fContext->setIdentityMatrix();
283 } else {
284 fContext->setMatrix(*draw.fMatrix);
285 }
286 fClipData.fOrigin = this->getOrigin(); 281 fClipData.fOrigin = this->getOrigin();
287 282
288 fContext->setClip(&fClipData); 283 fContext->setClip(&fClipData);
289 284
290 DO_DEFERRED_CLEAR(); 285 DO_DEFERRED_CLEAR();
291 } 286 }
292 287
293 GrRenderTarget* SkGpuDevice::accessRenderTarget() { 288 GrRenderTarget* SkGpuDevice::accessRenderTarget() {
294 DO_DEFERRED_CLEAR(); 289 DO_DEFERRED_CLEAR();
295 return fRenderTarget; 290 return fRenderTarget;
(...skipping 16 matching lines...) Expand all
312 SK_COMPILE_ASSERT(SkShader::kTwoPointRadial_BitmapType == 4, 307 SK_COMPILE_ASSERT(SkShader::kTwoPointRadial_BitmapType == 4,
313 shader_type_mismatch); 308 shader_type_mismatch);
314 SK_COMPILE_ASSERT(SkShader::kTwoPointConical_BitmapType == 5, 309 SK_COMPILE_ASSERT(SkShader::kTwoPointConical_BitmapType == 5,
315 shader_type_mismatch); 310 shader_type_mismatch);
316 SK_COMPILE_ASSERT(SkShader::kLinear_BitmapType == 6, shader_type_mismatch); 311 SK_COMPILE_ASSERT(SkShader::kLinear_BitmapType == 6, shader_type_mismatch);
317 SK_COMPILE_ASSERT(SkShader::kLast_BitmapType == 6, shader_type_mismatch); 312 SK_COMPILE_ASSERT(SkShader::kLast_BitmapType == 6, shader_type_mismatch);
318 313
319 /////////////////////////////////////////////////////////////////////////////// 314 ///////////////////////////////////////////////////////////////////////////////
320 315
321 void SkGpuDevice::drawPaint(const SkDraw& draw, const SkPaint& paint) { 316 void SkGpuDevice::drawPaint(const SkDraw& draw, const SkPaint& paint) {
322 CHECK_SHOULD_DRAW(draw, false); 317 CHECK_SHOULD_DRAW(draw);
323 GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawPaint", fContext); 318 GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawPaint", fContext);
324 319
325 GrPaint grPaint; 320 GrPaint grPaint;
326 SkPaint2GrPaintShader(this->context(), paint, true, &grPaint); 321 SkPaint2GrPaintShader(this->context(), paint, *draw.fMatrix, true, &grPaint) ;
327 322
328 fContext->drawPaint(grPaint); 323 fContext->drawPaint(grPaint, *draw.fMatrix);
329 } 324 }
330 325
331 // must be in SkCanvas::PointMode order 326 // must be in SkCanvas::PointMode order
332 static const GrPrimitiveType gPointMode2PrimtiveType[] = { 327 static const GrPrimitiveType gPointMode2PrimtiveType[] = {
333 kPoints_GrPrimitiveType, 328 kPoints_GrPrimitiveType,
334 kLines_GrPrimitiveType, 329 kLines_GrPrimitiveType,
335 kLineStrip_GrPrimitiveType 330 kLineStrip_GrPrimitiveType
336 }; 331 };
337 332
338 void SkGpuDevice::drawPoints(const SkDraw& draw, SkCanvas::PointMode mode, 333 void SkGpuDevice::drawPoints(const SkDraw& draw, SkCanvas::PointMode mode,
339 size_t count, const SkPoint pts[], const SkPaint& p aint) { 334 size_t count, const SkPoint pts[], const SkPaint& p aint) {
340 CHECK_FOR_ANNOTATION(paint); 335 CHECK_FOR_ANNOTATION(paint);
341 CHECK_SHOULD_DRAW(draw, false); 336 CHECK_SHOULD_DRAW(draw);
342 337
343 SkScalar width = paint.getStrokeWidth(); 338 SkScalar width = paint.getStrokeWidth();
344 if (width < 0) { 339 if (width < 0) {
345 return; 340 return;
346 } 341 }
347 342
348 if (paint.getPathEffect() && 2 == count && SkCanvas::kLines_PointMode == mod e) { 343 if (paint.getPathEffect() && 2 == count && SkCanvas::kLines_PointMode == mod e) {
349 GrStrokeInfo strokeInfo(paint, SkPaint::kStroke_Style); 344 GrStrokeInfo strokeInfo(paint, SkPaint::kStroke_Style);
350 GrPaint grPaint; 345 GrPaint grPaint;
351 SkPaint2GrPaintShader(this->context(), paint, true, &grPaint); 346 SkPaint2GrPaintShader(this->context(), paint, *draw.fMatrix, true, &grPa int);
352 SkPath path; 347 SkPath path;
353 path.setIsVolatile(true); 348 path.setIsVolatile(true);
354 path.moveTo(pts[0]); 349 path.moveTo(pts[0]);
355 path.lineTo(pts[1]); 350 path.lineTo(pts[1]);
356 fContext->drawPath(grPaint, path, strokeInfo); 351 fContext->drawPath(grPaint, *draw.fMatrix, path, strokeInfo);
357 return; 352 return;
358 } 353 }
359 354
360 // we only handle hairlines and paints without path effects or mask filters, 355 // we only handle hairlines and paints without path effects or mask filters,
361 // else we let the SkDraw call our drawPath() 356 // else we let the SkDraw call our drawPath()
362 if (width > 0 || paint.getPathEffect() || paint.getMaskFilter()) { 357 if (width > 0 || paint.getPathEffect() || paint.getMaskFilter()) {
363 draw.drawPoints(mode, count, pts, paint, true); 358 draw.drawPoints(mode, count, pts, paint, true);
364 return; 359 return;
365 } 360 }
366 361
367 GrPaint grPaint; 362 GrPaint grPaint;
368 SkPaint2GrPaintShader(this->context(), paint, true, &grPaint); 363 SkPaint2GrPaintShader(this->context(), paint, *draw.fMatrix, true, &grPaint) ;
369 364
370 fContext->drawVertices(grPaint, 365 fContext->drawVertices(grPaint,
366 *draw.fMatrix,
371 gPointMode2PrimtiveType[mode], 367 gPointMode2PrimtiveType[mode],
372 SkToS32(count), 368 SkToS32(count),
373 (SkPoint*)pts, 369 (SkPoint*)pts,
374 NULL, 370 NULL,
375 NULL, 371 NULL,
376 NULL, 372 NULL,
377 0); 373 0);
378 } 374 }
379 375
380 /////////////////////////////////////////////////////////////////////////////// 376 ///////////////////////////////////////////////////////////////////////////////
381 377
382 void SkGpuDevice::drawRect(const SkDraw& draw, const SkRect& rect, 378 void SkGpuDevice::drawRect(const SkDraw& draw, const SkRect& rect,
383 const SkPaint& paint) { 379 const SkPaint& paint) {
384 GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawRect", fContext); 380 GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawRect", fContext);
385 381
386 CHECK_FOR_ANNOTATION(paint); 382 CHECK_FOR_ANNOTATION(paint);
387 CHECK_SHOULD_DRAW(draw, false); 383 CHECK_SHOULD_DRAW(draw);
388 384
389 bool doStroke = paint.getStyle() != SkPaint::kFill_Style; 385 bool doStroke = paint.getStyle() != SkPaint::kFill_Style;
390 SkScalar width = paint.getStrokeWidth(); 386 SkScalar width = paint.getStrokeWidth();
391 387
392 /* 388 /*
393 We have special code for hairline strokes, miter-strokes, bevel-stroke 389 We have special code for hairline strokes, miter-strokes, bevel-stroke
394 and fills. Anything else we just call our path code. 390 and fills. Anything else we just call our path code.
395 */ 391 */
396 bool usePath = doStroke && width > 0 && 392 bool usePath = doStroke && width > 0 &&
397 (paint.getStrokeJoin() == SkPaint::kRound_Join || 393 (paint.getStrokeJoin() == SkPaint::kRound_Join ||
398 (paint.getStrokeJoin() == SkPaint::kBevel_Join && rect.isEmp ty())); 394 (paint.getStrokeJoin() == SkPaint::kBevel_Join && rect.isEmp ty()));
399 // another two reasons we might need to call drawPath... 395 // another two reasons we might need to call drawPath...
400 396
401 if (paint.getMaskFilter()) { 397 if (paint.getMaskFilter()) {
402 usePath = true; 398 usePath = true;
403 } 399 }
404 400
405 if (!usePath && paint.isAntiAlias() && !fContext->getMatrix().rectStaysRect( )) { 401 if (!usePath && paint.isAntiAlias() && !draw.fMatrix->rectStaysRect()) {
406 #if defined(SHADER_AA_FILL_RECT) || !defined(IGNORE_ROT_AA_RECT_OPT) 402 #if defined(SHADER_AA_FILL_RECT) || !defined(IGNORE_ROT_AA_RECT_OPT)
407 if (doStroke) { 403 if (doStroke) {
408 #endif 404 #endif
409 usePath = true; 405 usePath = true;
410 #if defined(SHADER_AA_FILL_RECT) || !defined(IGNORE_ROT_AA_RECT_OPT) 406 #if defined(SHADER_AA_FILL_RECT) || !defined(IGNORE_ROT_AA_RECT_OPT)
411 } else { 407 } else {
412 usePath = !fContext->getMatrix().preservesRightAngles(); 408 usePath = !draw.fMatrix->preservesRightAngles();
413 } 409 }
414 #endif 410 #endif
415 } 411 }
416 // until we can both stroke and fill rectangles 412 // until we can both stroke and fill rectangles
417 if (paint.getStyle() == SkPaint::kStrokeAndFill_Style) { 413 if (paint.getStyle() == SkPaint::kStrokeAndFill_Style) {
418 usePath = true; 414 usePath = true;
419 } 415 }
420 416
421 GrStrokeInfo strokeInfo(paint); 417 GrStrokeInfo strokeInfo(paint);
422 418
423 const SkPathEffect* pe = paint.getPathEffect(); 419 const SkPathEffect* pe = paint.getPathEffect();
424 if (!usePath && pe && !strokeInfo.isDashed()) { 420 if (!usePath && pe && !strokeInfo.isDashed()) {
425 usePath = true; 421 usePath = true;
426 } 422 }
427 423
428 if (usePath) { 424 if (usePath) {
429 SkPath path; 425 SkPath path;
430 path.setIsVolatile(true); 426 path.setIsVolatile(true);
431 path.addRect(rect); 427 path.addRect(rect);
432 this->drawPath(draw, path, paint, NULL, true); 428 this->drawPath(draw, path, paint, NULL, true);
433 return; 429 return;
434 } 430 }
435 431
436 GrPaint grPaint; 432 GrPaint grPaint;
437 SkPaint2GrPaintShader(this->context(), paint, true, &grPaint); 433 SkPaint2GrPaintShader(this->context(), paint, *draw.fMatrix, true, &grPaint) ;
438 434
439 fContext->drawRect(grPaint, rect, &strokeInfo); 435 fContext->drawRect(grPaint, *draw.fMatrix, rect, &strokeInfo);
440 } 436 }
441 437
442 /////////////////////////////////////////////////////////////////////////////// 438 ///////////////////////////////////////////////////////////////////////////////
443 439
444 void SkGpuDevice::drawRRect(const SkDraw& draw, const SkRRect& rect, 440 void SkGpuDevice::drawRRect(const SkDraw& draw, const SkRRect& rect,
445 const SkPaint& paint) { 441 const SkPaint& paint) {
446 GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawRRect", fContext); 442 GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawRRect", fContext);
447 CHECK_FOR_ANNOTATION(paint); 443 CHECK_FOR_ANNOTATION(paint);
448 CHECK_SHOULD_DRAW(draw, false); 444 CHECK_SHOULD_DRAW(draw);
449 445
450 GrPaint grPaint; 446 GrPaint grPaint;
451 SkPaint2GrPaintShader(this->context(), paint, true, &grPaint); 447 SkPaint2GrPaintShader(this->context(), paint, *draw.fMatrix, true, &grPaint) ;
452 448
453 GrStrokeInfo strokeInfo(paint); 449 GrStrokeInfo strokeInfo(paint);
454 if (paint.getMaskFilter()) { 450 if (paint.getMaskFilter()) {
455 // try to hit the fast path for drawing filtered round rects 451 // try to hit the fast path for drawing filtered round rects
456 452
457 SkRRect devRRect; 453 SkRRect devRRect;
458 if (rect.transform(fContext->getMatrix(), &devRRect)) { 454 if (rect.transform(*draw.fMatrix, &devRRect)) {
459 if (devRRect.allCornersCircular()) { 455 if (devRRect.allCornersCircular()) {
460 SkRect maskRect; 456 SkRect maskRect;
461 if (paint.getMaskFilter()->canFilterMaskGPU(devRRect.rect(), 457 if (paint.getMaskFilter()->canFilterMaskGPU(devRRect.rect(),
462 draw.fClip->getBounds(), 458 draw.fClip->getBound s(),
463 fContext->getMatrix(), 459 *draw.fMatrix,
464 &maskRect)) { 460 &maskRect)) {
465 SkIRect finalIRect; 461 SkIRect finalIRect;
466 maskRect.roundOut(&finalIRect); 462 maskRect.roundOut(&finalIRect);
467 if (draw.fClip->quickReject(finalIRect)) { 463 if (draw.fClip->quickReject(finalIRect)) {
468 // clipped out 464 // clipped out
469 return; 465 return;
470 } 466 }
471 if (paint.getMaskFilter()->directFilterRRectMaskGPU(fContext , &grPaint, 467 if (paint.getMaskFilter()->directFilterRRectMaskGPU(fContext , &grPaint,
468 *draw.fM atrix,
472 strokeIn fo.getStrokeRec(), 469 strokeIn fo.getStrokeRec(),
473 devRRect )) { 470 devRRect )) {
474 return; 471 return;
475 } 472 }
476 } 473 }
477 474
478 } 475 }
479 } 476 }
480 477
481 } 478 }
(...skipping 11 matching lines...) Expand all
493 490
494 491
495 if (usePath) { 492 if (usePath) {
496 SkPath path; 493 SkPath path;
497 path.setIsVolatile(true); 494 path.setIsVolatile(true);
498 path.addRRect(rect); 495 path.addRRect(rect);
499 this->drawPath(draw, path, paint, NULL, true); 496 this->drawPath(draw, path, paint, NULL, true);
500 return; 497 return;
501 } 498 }
502 499
503 fContext->drawRRect(grPaint, rect, strokeInfo); 500 fContext->drawRRect(grPaint, *draw.fMatrix, rect, strokeInfo);
504 } 501 }
505 502
506 void SkGpuDevice::drawDRRect(const SkDraw& draw, const SkRRect& outer, 503 void SkGpuDevice::drawDRRect(const SkDraw& draw, const SkRRect& outer,
507 const SkRRect& inner, const SkPaint& paint) { 504 const SkRRect& inner, const SkPaint& paint) {
508 SkStrokeRec stroke(paint); 505 SkStrokeRec stroke(paint);
509 if (stroke.isFillStyle()) { 506 if (stroke.isFillStyle()) {
510 507
511 CHECK_FOR_ANNOTATION(paint); 508 CHECK_FOR_ANNOTATION(paint);
512 CHECK_SHOULD_DRAW(draw, false); 509 CHECK_SHOULD_DRAW(draw);
513 510
514 GrPaint grPaint; 511 GrPaint grPaint;
515 SkPaint2GrPaintShader(this->context(), paint, true, &grPaint); 512 SkPaint2GrPaintShader(this->context(), paint, *draw.fMatrix, true, &grPa int);
516 513
517 if (NULL == paint.getMaskFilter() && NULL == paint.getPathEffect()) { 514 if (NULL == paint.getMaskFilter() && NULL == paint.getPathEffect()) {
518 fContext->drawDRRect(grPaint, outer, inner); 515 fContext->drawDRRect(grPaint, *draw.fMatrix, outer, inner);
519 return; 516 return;
520 } 517 }
521 } 518 }
522 519
523 SkPath path; 520 SkPath path;
524 path.setIsVolatile(true); 521 path.setIsVolatile(true);
525 path.addRRect(outer); 522 path.addRRect(outer);
526 path.addRRect(inner); 523 path.addRRect(inner);
527 path.setFillType(SkPath::kEvenOdd_FillType); 524 path.setFillType(SkPath::kEvenOdd_FillType);
528 525
529 this->drawPath(draw, path, paint, NULL, true); 526 this->drawPath(draw, path, paint, NULL, true);
530 } 527 }
531 528
532 529
533 ///////////////////////////////////////////////////////////////////////////// 530 /////////////////////////////////////////////////////////////////////////////
534 531
535 void SkGpuDevice::drawOval(const SkDraw& draw, const SkRect& oval, 532 void SkGpuDevice::drawOval(const SkDraw& draw, const SkRect& oval,
536 const SkPaint& paint) { 533 const SkPaint& paint) {
537 GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawOval", fContext); 534 GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawOval", fContext);
538 CHECK_FOR_ANNOTATION(paint); 535 CHECK_FOR_ANNOTATION(paint);
539 CHECK_SHOULD_DRAW(draw, false); 536 CHECK_SHOULD_DRAW(draw);
540 537
541 GrStrokeInfo strokeInfo(paint); 538 GrStrokeInfo strokeInfo(paint);
542 539
543 bool usePath = false; 540 bool usePath = false;
544 // some basic reasons we might need to call drawPath... 541 // some basic reasons we might need to call drawPath...
545 if (paint.getMaskFilter()) { 542 if (paint.getMaskFilter()) {
546 usePath = true; 543 usePath = true;
547 } else { 544 } else {
548 const SkPathEffect* pe = paint.getPathEffect(); 545 const SkPathEffect* pe = paint.getPathEffect();
549 if (pe && !strokeInfo.isDashed()) { 546 if (pe && !strokeInfo.isDashed()) {
550 usePath = true; 547 usePath = true;
551 } 548 }
552 } 549 }
553 550
554 if (usePath) { 551 if (usePath) {
555 SkPath path; 552 SkPath path;
556 path.setIsVolatile(true); 553 path.setIsVolatile(true);
557 path.addOval(oval); 554 path.addOval(oval);
558 this->drawPath(draw, path, paint, NULL, true); 555 this->drawPath(draw, path, paint, NULL, true);
559 return; 556 return;
560 } 557 }
561 558
562 GrPaint grPaint; 559 GrPaint grPaint;
563 SkPaint2GrPaintShader(this->context(), paint, true, &grPaint); 560 SkPaint2GrPaintShader(this->context(), paint, *draw.fMatrix, true, &grPaint) ;
564 561
565 fContext->drawOval(grPaint, oval, strokeInfo); 562 fContext->drawOval(grPaint, *draw.fMatrix, oval, strokeInfo);
566 } 563 }
567 564
568 #include "SkMaskFilter.h" 565 #include "SkMaskFilter.h"
569 566
570 /////////////////////////////////////////////////////////////////////////////// 567 ///////////////////////////////////////////////////////////////////////////////
571 568
572 // helpers for applying mask filters 569 // helpers for applying mask filters
573 namespace { 570 namespace {
574 571
575 // Draw a mask using the supplied paint. Since the coverage/geometry 572 // Draw a mask using the supplied paint. Since the coverage/geometry
576 // is already burnt into the mask this boils down to a rect draw. 573 // is already burnt into the mask this boils down to a rect draw.
577 // Return true if the mask was successfully drawn. 574 // Return true if the mask was successfully drawn.
578 bool draw_mask(GrContext* context, const SkRect& maskRect, 575 bool draw_mask(GrContext* context, const SkMatrix& viewMatrix, const SkRect& mas kRect,
579 GrPaint* grp, GrTexture* mask) { 576 GrPaint* grp, GrTexture* mask) {
580 GrContext::AutoMatrix am; 577 if (!grp->localCoordChangeInverse(viewMatrix)) {
581 if (!am.setIdentity(context, grp)) {
582 return false; 578 return false;
583 } 579 }
584 580
585 SkMatrix matrix; 581 SkMatrix matrix;
586 matrix.setTranslate(-maskRect.fLeft, -maskRect.fTop); 582 matrix.setTranslate(-maskRect.fLeft, -maskRect.fTop);
587 matrix.postIDiv(mask->width(), mask->height()); 583 matrix.postIDiv(mask->width(), mask->height());
588 584
589 grp->addCoverageProcessor(GrSimpleTextureEffect::Create(mask, matrix))->unre f(); 585 grp->addCoverageProcessor(GrSimpleTextureEffect::Create(mask, matrix))->unre f();
590 context->drawRect(*grp, maskRect); 586 context->drawRect(*grp, SkMatrix::I(), maskRect);
591 return true; 587 return true;
592 } 588 }
593 589
594 bool draw_with_mask_filter(GrContext* context, const SkPath& devPath, 590 bool draw_with_mask_filter(GrContext* context, const SkMatrix& viewMatrix, const SkPath& devPath,
595 SkMaskFilter* filter, const SkRegion& clip, 591 SkMaskFilter* filter, const SkRegion& clip,
596 GrPaint* grp, SkPaint::Style style) { 592 GrPaint* grp, SkPaint::Style style) {
597 SkMask srcM, dstM; 593 SkMask srcM, dstM;
598 594
599 if (!SkDraw::DrawToMask(devPath, &clip.getBounds(), filter, &context->getMat rix(), &srcM, 595 if (!SkDraw::DrawToMask(devPath, &clip.getBounds(), filter, &viewMatrix, &sr cM,
600 SkMask::kComputeBoundsAndRenderImage_CreateMode, sty le)) { 596 SkMask::kComputeBoundsAndRenderImage_CreateMode, sty le)) {
601 return false; 597 return false;
602 } 598 }
603 SkAutoMaskFreeImage autoSrc(srcM.fImage); 599 SkAutoMaskFreeImage autoSrc(srcM.fImage);
604 600
605 if (!filter->filterMask(&dstM, srcM, context->getMatrix(), NULL)) { 601 if (!filter->filterMask(&dstM, srcM, viewMatrix, NULL)) {
606 return false; 602 return false;
607 } 603 }
608 // this will free-up dstM when we're done (allocated in filterMask()) 604 // this will free-up dstM when we're done (allocated in filterMask())
609 SkAutoMaskFreeImage autoDst(dstM.fImage); 605 SkAutoMaskFreeImage autoDst(dstM.fImage);
610 606
611 if (clip.quickReject(dstM.fBounds)) { 607 if (clip.quickReject(dstM.fBounds)) {
612 return false; 608 return false;
613 } 609 }
614 610
615 // we now have a device-aligned 8bit mask in dstM, ready to be drawn using 611 // we now have a device-aligned 8bit mask in dstM, ready to be drawn using
616 // the current clip (and identity matrix) and GrPaint settings 612 // the current clip (and identity matrix) and GrPaint settings
617 GrSurfaceDesc desc; 613 GrSurfaceDesc desc;
618 desc.fWidth = dstM.fBounds.width(); 614 desc.fWidth = dstM.fBounds.width();
619 desc.fHeight = dstM.fBounds.height(); 615 desc.fHeight = dstM.fBounds.height();
620 desc.fConfig = kAlpha_8_GrPixelConfig; 616 desc.fConfig = kAlpha_8_GrPixelConfig;
621 617
622 SkAutoTUnref<GrTexture> texture( 618 SkAutoTUnref<GrTexture> texture(
623 context->refScratchTexture(desc, GrContext::kApprox_ScratchTexMatch)); 619 context->refScratchTexture(desc, GrContext::kApprox_ScratchTexMatch));
624 if (!texture) { 620 if (!texture) {
625 return false; 621 return false;
626 } 622 }
627 texture->writePixels(0, 0, desc.fWidth, desc.fHeight, desc.fConfig, 623 texture->writePixels(0, 0, desc.fWidth, desc.fHeight, desc.fConfig,
628 dstM.fImage, dstM.fRowBytes); 624 dstM.fImage, dstM.fRowBytes);
629 625
630 SkRect maskRect = SkRect::Make(dstM.fBounds); 626 SkRect maskRect = SkRect::Make(dstM.fBounds);
631 627
632 return draw_mask(context, maskRect, grp, texture); 628 return draw_mask(context, viewMatrix, maskRect, grp, texture);
633 } 629 }
634 630
635 // Create a mask of 'devPath' and place the result in 'mask'. 631 // Create a mask of 'devPath' and place the result in 'mask'.
636 GrTexture* create_mask_GPU(GrContext* context, 632 GrTexture* create_mask_GPU(GrContext* context,
637 const SkRect& maskRect, 633 const SkRect& maskRect,
638 const SkPath& devPath, 634 const SkPath& devPath,
639 const GrStrokeInfo& strokeInfo, 635 const GrStrokeInfo& strokeInfo,
640 bool doAA, 636 bool doAA,
641 int sampleCnt) { 637 int sampleCnt) {
642 GrSurfaceDesc desc; 638 GrSurfaceDesc desc;
(...skipping 27 matching lines...) Expand all
670 tempPaint.setAntiAlias(true); 666 tempPaint.setAntiAlias(true);
671 // AA uses the "coverage" stages on GrDrawTarget. Coverage with a dst 667 // AA uses the "coverage" stages on GrDrawTarget. Coverage with a dst
672 // blend coeff of zero requires dual source blending support in order 668 // blend coeff of zero requires dual source blending support in order
673 // to properly blend partially covered pixels. This means the AA 669 // to properly blend partially covered pixels. This means the AA
674 // code path may not be taken. So we use a dst blend coeff of ISA. We 670 // code path may not be taken. So we use a dst blend coeff of ISA. We
675 // could special case AA draws to a dst surface with known alpha=0 to 671 // could special case AA draws to a dst surface with known alpha=0 to
676 // use a zero dst coeff when dual source blending isn't available. 672 // use a zero dst coeff when dual source blending isn't available.
677 tempPaint.setPorterDuffXPFactory(kOne_GrBlendCoeff, kISC_GrBlendCoeff); 673 tempPaint.setPorterDuffXPFactory(kOne_GrBlendCoeff, kISC_GrBlendCoeff);
678 } 674 }
679 675
680 GrContext::AutoMatrix am;
681
682 // Draw the mask into maskTexture with the path's top-left at the origin usi ng tempPaint. 676 // Draw the mask into maskTexture with the path's top-left at the origin usi ng tempPaint.
683 SkMatrix translate; 677 SkMatrix translate;
684 translate.setTranslate(-maskRect.fLeft, -maskRect.fTop); 678 translate.setTranslate(-maskRect.fLeft, -maskRect.fTop);
685 am.set(context, translate); 679 context->drawPath(tempPaint, translate, devPath, strokeInfo);
686 context->drawPath(tempPaint, devPath, strokeInfo);
687 return mask; 680 return mask;
688 } 681 }
689 682
690 SkBitmap wrap_texture(GrTexture* texture) { 683 SkBitmap wrap_texture(GrTexture* texture) {
691 SkBitmap result; 684 SkBitmap result;
692 result.setInfo(texture->surfacePriv().info()); 685 result.setInfo(texture->surfacePriv().info());
693 result.setPixelRef(SkNEW_ARGS(SkGrPixelRef, (result.info(), texture)))->unre f(); 686 result.setPixelRef(SkNEW_ARGS(SkGrPixelRef, (result.info(), texture)))->unre f();
694 return result; 687 return result;
695 } 688 }
696 689
697 }; 690 };
698 691
699 void SkGpuDevice::drawPath(const SkDraw& draw, const SkPath& origSrcPath, 692 void SkGpuDevice::drawPath(const SkDraw& draw, const SkPath& origSrcPath,
700 const SkPaint& paint, const SkMatrix* prePathMatrix, 693 const SkPaint& paint, const SkMatrix* prePathMatrix,
701 bool pathIsMutable) { 694 bool pathIsMutable) {
702 CHECK_FOR_ANNOTATION(paint); 695 CHECK_FOR_ANNOTATION(paint);
703 CHECK_SHOULD_DRAW(draw, false); 696 CHECK_SHOULD_DRAW(draw);
704 GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawPath", fContext); 697 GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawPath", fContext);
705 698
706 SkASSERT(!pathIsMutable || origSrcPath.isVolatile()); 699 SkASSERT(!pathIsMutable || origSrcPath.isVolatile());
707 700
708 GrPaint grPaint; 701 GrPaint grPaint;
709 SkPaint2GrPaintShader(this->context(), paint, true, &grPaint); 702 SkPaint2GrPaintShader(this->context(), paint, *draw.fMatrix, true, &grPaint) ;
710 703
711 // If we have a prematrix, apply it to the path, optimizing for the case 704 // If we have a prematrix, apply it to the path, optimizing for the case
712 // where the original path can in fact be modified in place (even though 705 // where the original path can in fact be modified in place (even though
713 // its parameter type is const). 706 // its parameter type is const).
714 SkPath* pathPtr = const_cast<SkPath*>(&origSrcPath); 707 SkPath* pathPtr = const_cast<SkPath*>(&origSrcPath);
715 SkTLazy<SkPath> tmpPath; 708 SkTLazy<SkPath> tmpPath;
716 SkTLazy<SkPath> effectPath; 709 SkTLazy<SkPath> effectPath;
717 710
718 if (prePathMatrix) { 711 if (prePathMatrix) {
719 SkPath* result = pathPtr; 712 SkPath* result = pathPtr;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
753 } 746 }
754 } 747 }
755 748
756 // avoid possibly allocating a new path in transform if we can 749 // avoid possibly allocating a new path in transform if we can
757 SkPath* devPathPtr = pathIsMutable ? pathPtr : tmpPath.init(); 750 SkPath* devPathPtr = pathIsMutable ? pathPtr : tmpPath.init();
758 if (!pathIsMutable) { 751 if (!pathIsMutable) {
759 devPathPtr->setIsVolatile(true); 752 devPathPtr->setIsVolatile(true);
760 } 753 }
761 754
762 // transform the path into device space 755 // transform the path into device space
763 pathPtr->transform(fContext->getMatrix(), devPathPtr); 756 pathPtr->transform(*draw.fMatrix, devPathPtr);
764 757
765 SkRect maskRect; 758 SkRect maskRect;
766 if (paint.getMaskFilter()->canFilterMaskGPU(devPathPtr->getBounds(), 759 if (paint.getMaskFilter()->canFilterMaskGPU(devPathPtr->getBounds(),
767 draw.fClip->getBounds(), 760 draw.fClip->getBounds(),
768 fContext->getMatrix(), 761 *draw.fMatrix,
769 &maskRect)) { 762 &maskRect)) {
770 // The context's matrix may change while creating the mask, so save the CTM here to 763 // The context's matrix may change while creating the mask, so save the CTM here to
771 // pass to filterMaskGPU. 764 // pass to filterMaskGPU.
772 const SkMatrix ctm = fContext->getMatrix(); 765 const SkMatrix ctm = *draw.fMatrix;
773 766
774 SkIRect finalIRect; 767 SkIRect finalIRect;
775 maskRect.roundOut(&finalIRect); 768 maskRect.roundOut(&finalIRect);
776 if (draw.fClip->quickReject(finalIRect)) { 769 if (draw.fClip->quickReject(finalIRect)) {
777 // clipped out 770 // clipped out
778 return; 771 return;
779 } 772 }
780 773
781 if (paint.getMaskFilter()->directFilterMaskGPU(fContext, &grPaint, 774 if (paint.getMaskFilter()->directFilterMaskGPU(fContext, &grPaint, * draw.fMatrix,
782 stroke, *devPathPtr)) { 775 stroke, *devPathPtr)) {
783 // the mask filter was able to draw itself directly, so there's nothing 776 // the mask filter was able to draw itself directly, so there's nothing
784 // left to do. 777 // left to do.
785 return; 778 return;
786 } 779 }
787 780
788 781
789 SkAutoTUnref<GrTexture> mask(create_mask_GPU(fContext, maskRect, *de vPathPtr, 782 SkAutoTUnref<GrTexture> mask(create_mask_GPU(fContext, maskRect, *de vPathPtr,
790 strokeInfo, grPaint.isA ntiAlias(), 783 strokeInfo, grPaint.isA ntiAlias(),
791 fRenderTarget->numSampl es())); 784 fRenderTarget->numSampl es()));
792 if (mask) { 785 if (mask) {
793 GrTexture* filtered; 786 GrTexture* filtered;
794 787
795 if (paint.getMaskFilter()->filterMaskGPU(mask, ctm, maskRect, &f iltered, true)) { 788 if (paint.getMaskFilter()->filterMaskGPU(mask, ctm, maskRect, &f iltered, true)) {
796 // filterMaskGPU gives us ownership of a ref to the result 789 // filterMaskGPU gives us ownership of a ref to the result
797 SkAutoTUnref<GrTexture> atu(filtered); 790 SkAutoTUnref<GrTexture> atu(filtered);
798 if (draw_mask(fContext, maskRect, &grPaint, filtered)) { 791 if (draw_mask(fContext, *draw.fMatrix, maskRect, &grPaint, f iltered)) {
799 // This path is completely drawn 792 // This path is completely drawn
800 return; 793 return;
801 } 794 }
802 } 795 }
803 } 796 }
804 } 797 }
805 798
806 // draw the mask on the CPU - this is a fallthrough path in case the 799 // draw the mask on the CPU - this is a fallthrough path in case the
807 // GPU path fails 800 // GPU path fails
808 SkPaint::Style style = stroke.isHairlineStyle() ? SkPaint::kStroke_Style : 801 SkPaint::Style style = stroke.isHairlineStyle() ? SkPaint::kStroke_Style :
809 SkPaint::kFill_Style; 802 SkPaint::kFill_Style;
810 draw_with_mask_filter(fContext, *devPathPtr, paint.getMaskFilter(), 803 draw_with_mask_filter(fContext, *draw.fMatrix, *devPathPtr, paint.getMas kFilter(),
811 *draw.fClip, &grPaint, style); 804 *draw.fClip, &grPaint, style);
812 return; 805 return;
813 } 806 }
814 807
815 fContext->drawPath(grPaint, *pathPtr, strokeInfo); 808 fContext->drawPath(grPaint, *draw.fMatrix, *pathPtr, strokeInfo);
816 } 809 }
817 810
818 static const int kBmpSmallTileSize = 1 << 10; 811 static const int kBmpSmallTileSize = 1 << 10;
819 812
820 static inline int get_tile_count(const SkIRect& srcRect, int tileSize) { 813 static inline int get_tile_count(const SkIRect& srcRect, int tileSize) {
821 int tilesX = (srcRect.fRight / tileSize) - (srcRect.fLeft / tileSize) + 1; 814 int tilesX = (srcRect.fRight / tileSize) - (srcRect.fLeft / tileSize) + 1;
822 int tilesY = (srcRect.fBottom / tileSize) - (srcRect.fTop / tileSize) + 1; 815 int tilesY = (srcRect.fBottom / tileSize) - (srcRect.fTop / tileSize) + 1;
823 return tilesX * tilesY; 816 return tilesX * tilesY;
824 } 817 }
825 818
(...skipping 11 matching lines...) Expand all
837 if (maxTileTotalTileSize > 2 * smallTotalTileSize) { 830 if (maxTileTotalTileSize > 2 * smallTotalTileSize) {
838 return kBmpSmallTileSize; 831 return kBmpSmallTileSize;
839 } else { 832 } else {
840 return maxTileSize; 833 return maxTileSize;
841 } 834 }
842 } 835 }
843 836
844 // Given a bitmap, an optional src rect, and a context with a clip and matrix de termine what 837 // Given a bitmap, an optional src rect, and a context with a clip and matrix de termine what
845 // pixels from the bitmap are necessary. 838 // pixels from the bitmap are necessary.
846 static void determine_clipped_src_rect(const GrContext* context, 839 static void determine_clipped_src_rect(const GrContext* context,
840 const SkMatrix& viewMatrix,
847 const SkBitmap& bitmap, 841 const SkBitmap& bitmap,
848 const SkRect* srcRectPtr, 842 const SkRect* srcRectPtr,
849 SkIRect* clippedSrcIRect) { 843 SkIRect* clippedSrcIRect) {
850 const GrClipData* clip = context->getClip(); 844 const GrClipData* clip = context->getClip();
851 clip->getConservativeBounds(context->getRenderTarget(), clippedSrcIRect, NUL L); 845 clip->getConservativeBounds(context->getRenderTarget(), clippedSrcIRect, NUL L);
852 SkMatrix inv; 846 SkMatrix inv;
853 if (!context->getMatrix().invert(&inv)) { 847 if (!viewMatrix.invert(&inv)) {
854 clippedSrcIRect->setEmpty(); 848 clippedSrcIRect->setEmpty();
855 return; 849 return;
856 } 850 }
857 SkRect clippedSrcRect = SkRect::Make(*clippedSrcIRect); 851 SkRect clippedSrcRect = SkRect::Make(*clippedSrcIRect);
858 inv.mapRect(&clippedSrcRect); 852 inv.mapRect(&clippedSrcRect);
859 if (srcRectPtr) { 853 if (srcRectPtr) {
860 // we've setup src space 0,0 to map to the top left of the src rect. 854 // we've setup src space 0,0 to map to the top left of the src rect.
861 clippedSrcRect.offset(srcRectPtr->fLeft, srcRectPtr->fTop); 855 clippedSrcRect.offset(srcRectPtr->fLeft, srcRectPtr->fTop);
862 if (!clippedSrcRect.intersect(*srcRectPtr)) { 856 if (!clippedSrcRect.intersect(*srcRectPtr)) {
863 clippedSrcIRect->setEmpty(); 857 clippedSrcIRect->setEmpty();
864 return; 858 return;
865 } 859 }
866 } 860 }
867 clippedSrcRect.roundOut(clippedSrcIRect); 861 clippedSrcRect.roundOut(clippedSrcIRect);
868 SkIRect bmpBounds = SkIRect::MakeWH(bitmap.width(), bitmap.height()); 862 SkIRect bmpBounds = SkIRect::MakeWH(bitmap.width(), bitmap.height());
869 if (!clippedSrcIRect->intersect(bmpBounds)) { 863 if (!clippedSrcIRect->intersect(bmpBounds)) {
870 clippedSrcIRect->setEmpty(); 864 clippedSrcIRect->setEmpty();
871 } 865 }
872 } 866 }
873 867
874 bool SkGpuDevice::shouldTileBitmap(const SkBitmap& bitmap, 868 bool SkGpuDevice::shouldTileBitmap(const SkBitmap& bitmap,
869 const SkMatrix& viewMatrix,
875 const GrTextureParams& params, 870 const GrTextureParams& params,
876 const SkRect* srcRectPtr, 871 const SkRect* srcRectPtr,
877 int maxTileSize, 872 int maxTileSize,
878 int* tileSize, 873 int* tileSize,
879 SkIRect* clippedSrcRect) const { 874 SkIRect* clippedSrcRect) const {
880 // if bitmap is explictly texture backed then just use the texture 875 // if bitmap is explictly texture backed then just use the texture
881 if (bitmap.getTexture()) { 876 if (bitmap.getTexture()) {
882 return false; 877 return false;
883 } 878 }
884 879
885 // if it's larger than the max tile size, then we have no choice but tiling. 880 // if it's larger than the max tile size, then we have no choice but tiling.
886 if (bitmap.width() > maxTileSize || bitmap.height() > maxTileSize) { 881 if (bitmap.width() > maxTileSize || bitmap.height() > maxTileSize) {
887 determine_clipped_src_rect(fContext, bitmap, srcRectPtr, clippedSrcRect) ; 882 determine_clipped_src_rect(fContext, viewMatrix, bitmap, srcRectPtr, cli ppedSrcRect);
888 *tileSize = determine_tile_size(bitmap, *clippedSrcRect, maxTileSize); 883 *tileSize = determine_tile_size(bitmap, *clippedSrcRect, maxTileSize);
889 return true; 884 return true;
890 } 885 }
891 886
892 if (bitmap.width() * bitmap.height() < 4 * kBmpSmallTileSize * kBmpSmallTile Size) { 887 if (bitmap.width() * bitmap.height() < 4 * kBmpSmallTileSize * kBmpSmallTile Size) {
893 return false; 888 return false;
894 } 889 }
895 890
896 // if the entire texture is already in our cache then no reason to tile it 891 // if the entire texture is already in our cache then no reason to tile it
897 if (GrIsBitmapInCache(fContext, bitmap, &params)) { 892 if (GrIsBitmapInCache(fContext, bitmap, &params)) {
898 return false; 893 return false;
899 } 894 }
900 895
901 // At this point we know we could do the draw by uploading the entire bitmap 896 // At this point we know we could do the draw by uploading the entire bitmap
902 // as a texture. However, if the texture would be large compared to the 897 // as a texture. However, if the texture would be large compared to the
903 // cache size and we don't require most of it for this draw then tile to 898 // cache size and we don't require most of it for this draw then tile to
904 // reduce the amount of upload and cache spill. 899 // reduce the amount of upload and cache spill.
905 900
906 // assumption here is that sw bitmap size is a good proxy for its size as 901 // assumption here is that sw bitmap size is a good proxy for its size as
907 // a texture 902 // a texture
908 size_t bmpSize = bitmap.getSize(); 903 size_t bmpSize = bitmap.getSize();
909 size_t cacheSize; 904 size_t cacheSize;
910 fContext->getResourceCacheLimits(NULL, &cacheSize); 905 fContext->getResourceCacheLimits(NULL, &cacheSize);
911 if (bmpSize < cacheSize / 2) { 906 if (bmpSize < cacheSize / 2) {
912 return false; 907 return false;
913 } 908 }
914 909
915 // Figure out how much of the src we will need based on the src rect and cli pping. 910 // Figure out how much of the src we will need based on the src rect and cli pping.
916 determine_clipped_src_rect(fContext, bitmap, srcRectPtr, clippedSrcRect); 911 determine_clipped_src_rect(fContext, viewMatrix, bitmap, srcRectPtr, clipped SrcRect);
917 *tileSize = kBmpSmallTileSize; // already know whole bitmap fits in one max sized tile. 912 *tileSize = kBmpSmallTileSize; // already know whole bitmap fits in one max sized tile.
918 size_t usedTileBytes = get_tile_count(*clippedSrcRect, kBmpSmallTileSize) * 913 size_t usedTileBytes = get_tile_count(*clippedSrcRect, kBmpSmallTileSize) *
919 kBmpSmallTileSize * kBmpSmallTileSize; 914 kBmpSmallTileSize * kBmpSmallTileSize;
920 915
921 return usedTileBytes < 2 * bmpSize; 916 return usedTileBytes < 2 * bmpSize;
922 } 917 }
923 918
924 void SkGpuDevice::drawBitmap(const SkDraw& origDraw, 919 void SkGpuDevice::drawBitmap(const SkDraw& origDraw,
925 const SkBitmap& bitmap, 920 const SkBitmap& bitmap,
926 const SkMatrix& m, 921 const SkMatrix& m,
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
1034 } 1029 }
1035 return needsTextureDomain; 1030 return needsTextureDomain;
1036 } 1031 }
1037 1032
1038 void SkGpuDevice::drawBitmapCommon(const SkDraw& draw, 1033 void SkGpuDevice::drawBitmapCommon(const SkDraw& draw,
1039 const SkBitmap& bitmap, 1034 const SkBitmap& bitmap,
1040 const SkRect* srcRectPtr, 1035 const SkRect* srcRectPtr,
1041 const SkSize* dstSizePtr, 1036 const SkSize* dstSizePtr,
1042 const SkPaint& paint, 1037 const SkPaint& paint,
1043 SkCanvas::DrawBitmapRectFlags flags) { 1038 SkCanvas::DrawBitmapRectFlags flags) {
1044 CHECK_SHOULD_DRAW(draw, false); 1039 CHECK_SHOULD_DRAW(draw);
1045 1040
1046 SkRect srcRect; 1041 SkRect srcRect;
1047 SkSize dstSize; 1042 SkSize dstSize;
1048 // If there is no src rect, or the src rect contains the entire bitmap then we're effectively 1043 // If there is no src rect, or the src rect contains the entire bitmap then we're effectively
1049 // in the (easier) bleed case, so update flags. 1044 // in the (easier) bleed case, so update flags.
1050 if (NULL == srcRectPtr) { 1045 if (NULL == srcRectPtr) {
1051 SkScalar w = SkIntToScalar(bitmap.width()); 1046 SkScalar w = SkIntToScalar(bitmap.width());
1052 SkScalar h = SkIntToScalar(bitmap.height()); 1047 SkScalar h = SkIntToScalar(bitmap.height());
1053 dstSize.fWidth = w; 1048 dstSize.fWidth = w;
1054 dstSize.fHeight = h; 1049 dstSize.fHeight = h;
(...skipping 15 matching lines...) Expand all
1070 // anti-aliased edges, we work around that for now by drawing directly 1065 // anti-aliased edges, we work around that for now by drawing directly
1071 // if the image size exceeds maximum texture size. 1066 // if the image size exceeds maximum texture size.
1072 int maxTextureSize = fContext->getMaxTextureSize(); 1067 int maxTextureSize = fContext->getMaxTextureSize();
1073 bool directDraw = fRenderTarget->isMultisampled() || 1068 bool directDraw = fRenderTarget->isMultisampled() ||
1074 !paint.isAntiAlias() || 1069 !paint.isAntiAlias() ||
1075 bitmap.width() > maxTextureSize || 1070 bitmap.width() > maxTextureSize ||
1076 bitmap.height() > maxTextureSize; 1071 bitmap.height() > maxTextureSize;
1077 1072
1078 // we check whether dst rect are pixel aligned 1073 // we check whether dst rect are pixel aligned
1079 if (!directDraw) { 1074 if (!directDraw) {
1080 bool staysRect = fContext->getMatrix().rectStaysRect(); 1075 bool staysRect = draw.fMatrix->rectStaysRect();
1081 1076
1082 if (staysRect) { 1077 if (staysRect) {
1083 SkRect rect; 1078 SkRect rect;
1084 SkRect dstRect = SkRect::MakeXYWH(0, 0, dstSize.fWidth, dstSize.fHei ght); 1079 SkRect dstRect = SkRect::MakeXYWH(0, 0, dstSize.fWidth, dstSize.fHei ght);
1085 fContext->getMatrix().mapRect(&rect, dstRect); 1080 draw.fMatrix->mapRect(&rect, dstRect);
1086 const SkScalar *scalars = rect.asScalars(); 1081 const SkScalar *scalars = rect.asScalars();
1087 bool isDstPixelAligned = true; 1082 bool isDstPixelAligned = true;
1088 for (int i = 0; i < 4; i++) { 1083 for (int i = 0; i < 4; i++) {
1089 if (!SkScalarIsInt(scalars[i])) { 1084 if (!SkScalarIsInt(scalars[i])) {
1090 isDstPixelAligned = false; 1085 isDstPixelAligned = false;
1091 break; 1086 break;
1092 } 1087 }
1093 } 1088 }
1094 1089
1095 if (isDstPixelAligned) 1090 if (isDstPixelAligned)
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1138 this->drawRect(draw, dstRect, paintWithShader); 1133 this->drawRect(draw, dstRect, paintWithShader);
1139 1134
1140 return; 1135 return;
1141 } 1136 }
1142 1137
1143 // If there is no mask filter than it is OK to handle the src rect -> dst re ct scaling using 1138 // If there is no mask filter than it is OK to handle the src rect -> dst re ct scaling using
1144 // the view matrix rather than a local matrix. 1139 // the view matrix rather than a local matrix.
1145 SkMatrix m; 1140 SkMatrix m;
1146 m.setScale(dstSize.fWidth / srcRect.width(), 1141 m.setScale(dstSize.fWidth / srcRect.width(),
1147 dstSize.fHeight / srcRect.height()); 1142 dstSize.fHeight / srcRect.height());
1148 fContext->concatMatrix(m); 1143 SkMatrix viewM = *draw.fMatrix;
1144 viewM.preConcat(m);
1149 1145
1150 GrTextureParams params; 1146 GrTextureParams params;
1151 SkPaint::FilterLevel paintFilterLevel = paint.getFilterLevel(); 1147 SkPaint::FilterLevel paintFilterLevel = paint.getFilterLevel();
1152 GrTextureParams::FilterMode textureFilterMode; 1148 GrTextureParams::FilterMode textureFilterMode;
1153 1149
1154 bool doBicubic = false; 1150 bool doBicubic = false;
1155 1151
1156 switch(paintFilterLevel) { 1152 switch(paintFilterLevel) {
1157 case SkPaint::kNone_FilterLevel: 1153 case SkPaint::kNone_FilterLevel:
1158 textureFilterMode = GrTextureParams::kNone_FilterMode; 1154 textureFilterMode = GrTextureParams::kNone_FilterMode;
1159 break; 1155 break;
1160 case SkPaint::kLow_FilterLevel: 1156 case SkPaint::kLow_FilterLevel:
1161 textureFilterMode = GrTextureParams::kBilerp_FilterMode; 1157 textureFilterMode = GrTextureParams::kBilerp_FilterMode;
1162 break; 1158 break;
1163 case SkPaint::kMedium_FilterLevel: 1159 case SkPaint::kMedium_FilterLevel:
1164 if (fContext->getMatrix().getMinScale() < SK_Scalar1) { 1160 if (viewM.getMinScale() < SK_Scalar1) {
1165 textureFilterMode = GrTextureParams::kMipMap_FilterMode; 1161 textureFilterMode = GrTextureParams::kMipMap_FilterMode;
1166 } else { 1162 } else {
1167 // Don't trigger MIP level generation unnecessarily. 1163 // Don't trigger MIP level generation unnecessarily.
1168 textureFilterMode = GrTextureParams::kBilerp_FilterMode; 1164 textureFilterMode = GrTextureParams::kBilerp_FilterMode;
1169 } 1165 }
1170 break; 1166 break;
1171 case SkPaint::kHigh_FilterLevel: 1167 case SkPaint::kHigh_FilterLevel:
1172 // Minification can look bad with the bicubic effect. 1168 // Minification can look bad with the bicubic effect.
1173 doBicubic = 1169 doBicubic =
1174 GrBicubicEffect::ShouldUseBicubic(fContext->getMatrix(), &textur eFilterMode); 1170 GrBicubicEffect::ShouldUseBicubic(viewM, &textureFilterMode);
1175 break; 1171 break;
1176 default: 1172 default:
1177 SkErrorInternals::SetError( kInvalidPaint_SkError, 1173 SkErrorInternals::SetError( kInvalidPaint_SkError,
1178 "Sorry, I don't understand the filtering " 1174 "Sorry, I don't understand the filtering "
1179 "mode you asked for. Falling back to " 1175 "mode you asked for. Falling back to "
1180 "MIPMaps."); 1176 "MIPMaps.");
1181 textureFilterMode = GrTextureParams::kMipMap_FilterMode; 1177 textureFilterMode = GrTextureParams::kMipMap_FilterMode;
1182 break; 1178 break;
1183 } 1179 }
1184 1180
1185 int tileFilterPad; 1181 int tileFilterPad;
1186 if (doBicubic) { 1182 if (doBicubic) {
1187 tileFilterPad = GrBicubicEffect::kFilterTexelPad; 1183 tileFilterPad = GrBicubicEffect::kFilterTexelPad;
1188 } else if (GrTextureParams::kNone_FilterMode == textureFilterMode) { 1184 } else if (GrTextureParams::kNone_FilterMode == textureFilterMode) {
1189 tileFilterPad = 0; 1185 tileFilterPad = 0;
1190 } else { 1186 } else {
1191 tileFilterPad = 1; 1187 tileFilterPad = 1;
1192 } 1188 }
1193 params.setFilterMode(textureFilterMode); 1189 params.setFilterMode(textureFilterMode);
1194 1190
1195 int maxTileSize = fContext->getMaxTextureSize() - 2 * tileFilterPad; 1191 int maxTileSize = fContext->getMaxTextureSize() - 2 * tileFilterPad;
1196 int tileSize; 1192 int tileSize;
1197 1193
1198 SkIRect clippedSrcRect; 1194 SkIRect clippedSrcRect;
1199 if (this->shouldTileBitmap(bitmap, params, srcRectPtr, maxTileSize, &tileSiz e, 1195 if (this->shouldTileBitmap(bitmap, viewM, params, srcRectPtr, maxTileSize, & tileSize,
1200 &clippedSrcRect)) { 1196 &clippedSrcRect)) {
1201 this->drawTiledBitmap(bitmap, srcRect, clippedSrcRect, params, paint, fl ags, tileSize, 1197 this->drawTiledBitmap(bitmap, viewM, srcRect, clippedSrcRect, params, pa int, flags,
1202 doBicubic); 1198 tileSize, doBicubic);
1203 } else { 1199 } else {
1204 // take the simple case 1200 // take the simple case
1205 bool needsTextureDomain = needs_texture_domain(bitmap, 1201 bool needsTextureDomain = needs_texture_domain(bitmap,
1206 srcRect, 1202 srcRect,
1207 params, 1203 params,
1208 fContext->getMatrix(), 1204 viewM,
1209 doBicubic); 1205 doBicubic);
1210 this->internalDrawBitmap(bitmap, 1206 this->internalDrawBitmap(bitmap,
1207 viewM,
1211 srcRect, 1208 srcRect,
1212 params, 1209 params,
1213 paint, 1210 paint,
1214 flags, 1211 flags,
1215 doBicubic, 1212 doBicubic,
1216 needsTextureDomain); 1213 needsTextureDomain);
1217 } 1214 }
1218 } 1215 }
1219 1216
1220 // Break 'bitmap' into several tiles to draw it since it has already 1217 // Break 'bitmap' into several tiles to draw it since it has already
1221 // been determined to be too large to fit in VRAM 1218 // been determined to be too large to fit in VRAM
1222 void SkGpuDevice::drawTiledBitmap(const SkBitmap& bitmap, 1219 void SkGpuDevice::drawTiledBitmap(const SkBitmap& bitmap,
1220 const SkMatrix& viewMatrix,
1223 const SkRect& srcRect, 1221 const SkRect& srcRect,
1224 const SkIRect& clippedSrcIRect, 1222 const SkIRect& clippedSrcIRect,
1225 const GrTextureParams& params, 1223 const GrTextureParams& params,
1226 const SkPaint& paint, 1224 const SkPaint& paint,
1227 SkCanvas::DrawBitmapRectFlags flags, 1225 SkCanvas::DrawBitmapRectFlags flags,
1228 int tileSize, 1226 int tileSize,
1229 bool bicubic) { 1227 bool bicubic) {
1230 // The following pixel lock is technically redundant, but it is desirable 1228 // The following pixel lock is technically redundant, but it is desirable
1231 // to lock outside of the tile loop to prevent redecoding the whole image 1229 // to lock outside of the tile loop to prevent redecoding the whole image
1232 // at each tile in cases where 'bitmap' holds an SkDiscardablePixelRef that 1230 // at each tile in cases where 'bitmap' holds an SkDiscardablePixelRef that
(...skipping 19 matching lines...) Expand all
1252 continue; 1250 continue;
1253 } 1251 }
1254 1252
1255 SkBitmap tmpB; 1253 SkBitmap tmpB;
1256 SkIRect iTileR; 1254 SkIRect iTileR;
1257 tileR.roundOut(&iTileR); 1255 tileR.roundOut(&iTileR);
1258 SkPoint offset = SkPoint::Make(SkIntToScalar(iTileR.fLeft), 1256 SkPoint offset = SkPoint::Make(SkIntToScalar(iTileR.fLeft),
1259 SkIntToScalar(iTileR.fTop)); 1257 SkIntToScalar(iTileR.fTop));
1260 1258
1261 // Adjust the context matrix to draw at the right x,y in device spac e 1259 // Adjust the context matrix to draw at the right x,y in device spac e
1260 SkMatrix viewM = viewMatrix;
1262 SkMatrix tmpM; 1261 SkMatrix tmpM;
1263 GrContext::AutoMatrix am;
1264 tmpM.setTranslate(offset.fX - srcRect.fLeft, offset.fY - srcRect.fTo p); 1262 tmpM.setTranslate(offset.fX - srcRect.fLeft, offset.fY - srcRect.fTo p);
1265 am.setPreConcat(fContext, tmpM); 1263 viewM.preConcat(tmpM);
1266 1264
1267 if (GrTextureParams::kNone_FilterMode != params.filterMode() || bicu bic) { 1265 if (GrTextureParams::kNone_FilterMode != params.filterMode() || bicu bic) {
1268 SkIRect iClampRect; 1266 SkIRect iClampRect;
1269 1267
1270 if (SkCanvas::kBleed_DrawBitmapRectFlag & flags) { 1268 if (SkCanvas::kBleed_DrawBitmapRectFlag & flags) {
1271 // In bleed mode we want to always expand the tile on all ed ges 1269 // In bleed mode we want to always expand the tile on all ed ges
1272 // but stay within the bitmap bounds 1270 // but stay within the bitmap bounds
1273 iClampRect = SkIRect::MakeWH(bitmap.width(), bitmap.height() ); 1271 iClampRect = SkIRect::MakeWH(bitmap.width(), bitmap.height() );
1274 } else { 1272 } else {
1275 // In texture-domain/clamp mode we only want to expand the 1273 // In texture-domain/clamp mode we only want to expand the
1276 // tile on edges interior to "srcRect" (i.e., we want to 1274 // tile on edges interior to "srcRect" (i.e., we want to
1277 // not bleed across the original clamped edges) 1275 // not bleed across the original clamped edges)
1278 srcRect.roundOut(&iClampRect); 1276 srcRect.roundOut(&iClampRect);
1279 } 1277 }
1280 int outset = bicubic ? GrBicubicEffect::kFilterTexelPad : 1; 1278 int outset = bicubic ? GrBicubicEffect::kFilterTexelPad : 1;
1281 clamped_outset_with_offset(&iTileR, outset, &offset, iClampRect) ; 1279 clamped_outset_with_offset(&iTileR, outset, &offset, iClampRect) ;
1282 } 1280 }
1283 1281
1284 if (bitmap.extractSubset(&tmpB, iTileR)) { 1282 if (bitmap.extractSubset(&tmpB, iTileR)) {
1285 // now offset it to make it "local" to our tmp bitmap 1283 // now offset it to make it "local" to our tmp bitmap
1286 tileR.offset(-offset.fX, -offset.fY); 1284 tileR.offset(-offset.fX, -offset.fY);
1287 GrTextureParams paramsTemp = params; 1285 GrTextureParams paramsTemp = params;
1288 bool needsTextureDomain = needs_texture_domain(bitmap, 1286 bool needsTextureDomain = needs_texture_domain(bitmap,
1289 srcRect, 1287 srcRect,
1290 paramsTemp, 1288 paramsTemp,
1291 fContext->getMatr ix(), 1289 viewM,
1292 bicubic); 1290 bicubic);
1293 this->internalDrawBitmap(tmpB, 1291 this->internalDrawBitmap(tmpB,
1292 viewM,
1294 tileR, 1293 tileR,
1295 paramsTemp, 1294 paramsTemp,
1296 paint, 1295 paint,
1297 flags, 1296 flags,
1298 bicubic, 1297 bicubic,
1299 needsTextureDomain); 1298 needsTextureDomain);
1300 } 1299 }
1301 } 1300 }
1302 } 1301 }
1303 } 1302 }
1304 1303
1305 1304
1306 /* 1305 /*
1307 * This is called by drawBitmap(), which has to handle images that may be too 1306 * This is called by drawBitmap(), which has to handle images that may be too
1308 * large to be represented by a single texture. 1307 * large to be represented by a single texture.
1309 * 1308 *
1310 * internalDrawBitmap assumes that the specified bitmap will fit in a texture 1309 * internalDrawBitmap assumes that the specified bitmap will fit in a texture
1311 * and that non-texture portion of the GrPaint has already been setup. 1310 * and that non-texture portion of the GrPaint has already been setup.
1312 */ 1311 */
1313 void SkGpuDevice::internalDrawBitmap(const SkBitmap& bitmap, 1312 void SkGpuDevice::internalDrawBitmap(const SkBitmap& bitmap,
1313 const SkMatrix& viewMatrix,
1314 const SkRect& srcRect, 1314 const SkRect& srcRect,
1315 const GrTextureParams& params, 1315 const GrTextureParams& params,
1316 const SkPaint& paint, 1316 const SkPaint& paint,
1317 SkCanvas::DrawBitmapRectFlags flags, 1317 SkCanvas::DrawBitmapRectFlags flags,
1318 bool bicubic, 1318 bool bicubic,
1319 bool needsTextureDomain) { 1319 bool needsTextureDomain) {
1320 SkASSERT(bitmap.width() <= fContext->getMaxTextureSize() && 1320 SkASSERT(bitmap.width() <= fContext->getMaxTextureSize() &&
1321 bitmap.height() <= fContext->getMaxTextureSize()); 1321 bitmap.height() <= fContext->getMaxTextureSize());
1322 1322
1323 GrTexture* texture; 1323 GrTexture* texture;
(...skipping 28 matching lines...) Expand all
1352 top = paintRect.top() + border; 1352 top = paintRect.top() + border;
1353 bottom = paintRect.bottom() - border; 1353 bottom = paintRect.bottom() - border;
1354 } else { 1354 } else {
1355 top = bottom = SkScalarHalf(paintRect.top() + paintRect.bottom()); 1355 top = bottom = SkScalarHalf(paintRect.top() + paintRect.bottom());
1356 } 1356 }
1357 textureDomain.setLTRB(left, top, right, bottom); 1357 textureDomain.setLTRB(left, top, right, bottom);
1358 if (bicubic) { 1358 if (bicubic) {
1359 fp.reset(GrBicubicEffect::Create(texture, SkMatrix::I(), textureDoma in)); 1359 fp.reset(GrBicubicEffect::Create(texture, SkMatrix::I(), textureDoma in));
1360 } else { 1360 } else {
1361 fp.reset(GrTextureDomainEffect::Create(texture, 1361 fp.reset(GrTextureDomainEffect::Create(texture,
1362 SkMatrix::I(), 1362 SkMatrix::I(),
1363 textureDomain, 1363 textureDomain,
1364 GrTextureDomain::kClamp_M ode, 1364 GrTextureDomain::kClamp_Mode,
1365 params.filterMode())); 1365 params.filterMode()));
1366 } 1366 }
1367 } else if (bicubic) { 1367 } else if (bicubic) {
1368 SkASSERT(GrTextureParams::kNone_FilterMode == params.filterMode()); 1368 SkASSERT(GrTextureParams::kNone_FilterMode == params.filterMode());
1369 SkShader::TileMode tileModes[2] = { params.getTileModeX(), params.getTil eModeY() }; 1369 SkShader::TileMode tileModes[2] = { params.getTileModeX(), params.getTil eModeY() };
1370 fp.reset(GrBicubicEffect::Create(texture, SkMatrix::I(), tileModes)); 1370 fp.reset(GrBicubicEffect::Create(texture, SkMatrix::I(), tileModes));
1371 } else { 1371 } else {
1372 fp.reset(GrSimpleTextureEffect::Create(texture, SkMatrix::I(), params)); 1372 fp.reset(GrSimpleTextureEffect::Create(texture, SkMatrix::I(), params));
1373 } 1373 }
1374 1374
1375 // Construct a GrPaint by setting the bitmap texture as the first effect and then configuring 1375 // Construct a GrPaint by setting the bitmap texture as the first effect and then configuring
1376 // the rest from the SkPaint. 1376 // the rest from the SkPaint.
1377 GrPaint grPaint; 1377 GrPaint grPaint;
1378 grPaint.addColorProcessor(fp); 1378 grPaint.addColorProcessor(fp);
1379 bool alphaOnly = !(kAlpha_8_SkColorType == bitmap.colorType()); 1379 bool alphaOnly = !(kAlpha_8_SkColorType == bitmap.colorType());
1380 GrColor paintColor = (alphaOnly) ? SkColor2GrColorJustAlpha(paint.getColor() ) : 1380 GrColor paintColor = (alphaOnly) ? SkColor2GrColorJustAlpha(paint.getColor() ) :
1381 SkColor2GrColor(paint.getColor()); 1381 SkColor2GrColor(paint.getColor());
1382 SkPaint2GrPaintNoShader(this->context(), paint, paintColor, false, &grPaint) ; 1382 SkPaint2GrPaintNoShader(this->context(), paint, paintColor, false, &grPaint) ;
1383 1383
1384 fContext->drawRectToRect(grPaint, dstRect, paintRect); 1384 fContext->drawRectToRect(grPaint, viewMatrix, dstRect, paintRect);
1385 } 1385 }
1386 1386
1387 bool SkGpuDevice::filterTexture(GrContext* context, GrTexture* texture, 1387 bool SkGpuDevice::filterTexture(GrContext* context, GrTexture* texture,
1388 const SkImageFilter* filter, 1388 const SkImageFilter* filter,
1389 const SkImageFilter::Context& ctx, 1389 const SkImageFilter::Context& ctx,
1390 SkBitmap* result, SkIPoint* offset) { 1390 SkBitmap* result, SkIPoint* offset) {
1391 SkASSERT(filter); 1391 SkASSERT(filter);
1392 1392
1393 // FIXME: plumb actual surface props such that we don't have to lie about th e flags here 1393 // FIXME: plumb actual surface props such that we don't have to lie about th e flags here
1394 // (https://code.google.com/p/skia/issues/detail?id=3148). 1394 // (https://code.google.com/p/skia/issues/detail?id=3148).
1395 SkDeviceImageFilterProxy proxy(this, SkSurfaceProps(0, getLeakyProperties(). pixelGeometry())); 1395 SkDeviceImageFilterProxy proxy(this, SkSurfaceProps(0, getLeakyProperties(). pixelGeometry()));
1396 1396
1397 if (filter->canFilterImageGPU()) { 1397 if (filter->canFilterImageGPU()) {
1398 // Save the render target and set it to NULL, so we don't accidentally d raw to it in the 1398 // Save the render target and set it to NULL, so we don't accidentally d raw to it in the
1399 // filter. Also set the clip wide open and the matrix to identity. 1399 // filter. Also set the clip wide open and the matrix to identity.
1400 GrContext::AutoWideOpenIdentityDraw awo(context, NULL); 1400 GrContext::AutoWideOpenIdentityDraw awo(context, NULL);
1401 return filter->filterImageGPU(&proxy, wrap_texture(texture), ctx, result , offset); 1401 return filter->filterImageGPU(&proxy, wrap_texture(texture), ctx, result , offset);
1402 } else { 1402 } else {
1403 return false; 1403 return false;
1404 } 1404 }
1405 } 1405 }
1406 1406
1407 void SkGpuDevice::drawSprite(const SkDraw& draw, const SkBitmap& bitmap, 1407 void SkGpuDevice::drawSprite(const SkDraw& draw, const SkBitmap& bitmap,
1408 int left, int top, const SkPaint& paint) { 1408 int left, int top, const SkPaint& paint) {
1409 // drawSprite is defined to be in device coords. 1409 // drawSprite is defined to be in device coords.
1410 CHECK_SHOULD_DRAW(draw, true); 1410 CHECK_SHOULD_DRAW(draw);
1411 1411
1412 SkAutoLockPixels alp(bitmap, !bitmap.getTexture()); 1412 SkAutoLockPixels alp(bitmap, !bitmap.getTexture());
1413 if (!bitmap.getTexture() && !bitmap.readyToDraw()) { 1413 if (!bitmap.getTexture() && !bitmap.readyToDraw()) {
1414 return; 1414 return;
1415 } 1415 }
1416 1416
1417 int w = bitmap.width(); 1417 int w = bitmap.width();
1418 int h = bitmap.height(); 1418 int h = bitmap.height();
1419 1419
1420 GrTexture* texture; 1420 GrTexture* texture;
(...skipping 25 matching lines...) Expand all
1446 } 1446 }
1447 } 1447 }
1448 1448
1449 GrPaint grPaint; 1449 GrPaint grPaint;
1450 grPaint.addColorTextureProcessor(texture, SkMatrix::I()); 1450 grPaint.addColorTextureProcessor(texture, SkMatrix::I());
1451 1451
1452 SkPaint2GrPaintNoShader(this->context(), paint, SkColor2GrColorJustAlpha(pai nt.getColor()), 1452 SkPaint2GrPaintNoShader(this->context(), paint, SkColor2GrColorJustAlpha(pai nt.getColor()),
1453 false, &grPaint); 1453 false, &grPaint);
1454 1454
1455 fContext->drawRectToRect(grPaint, 1455 fContext->drawRectToRect(grPaint,
1456 SkMatrix::I(),
1456 SkRect::MakeXYWH(SkIntToScalar(left), 1457 SkRect::MakeXYWH(SkIntToScalar(left),
1457 SkIntToScalar(top), 1458 SkIntToScalar(top),
1458 SkIntToScalar(w), 1459 SkIntToScalar(w),
1459 SkIntToScalar(h)), 1460 SkIntToScalar(h)),
1460 SkRect::MakeXYWH(0, 1461 SkRect::MakeXYWH(0,
1461 0, 1462 0,
1462 SK_Scalar1 * w / texture->width(), 1463 SK_Scalar1 * w / texture->width(),
1463 SK_Scalar1 * h / texture->height() )); 1464 SK_Scalar1 * h / texture->height() ));
1464 } 1465 }
1465 1466
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
1513 int x, int y, const SkPaint& paint) { 1514 int x, int y, const SkPaint& paint) {
1514 // clear of the source device must occur before CHECK_SHOULD_DRAW 1515 // clear of the source device must occur before CHECK_SHOULD_DRAW
1515 GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawDevice", fContext); 1516 GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawDevice", fContext);
1516 SkGpuDevice* dev = static_cast<SkGpuDevice*>(device); 1517 SkGpuDevice* dev = static_cast<SkGpuDevice*>(device);
1517 if (dev->fFlags & kNeedClear_Flag) { 1518 if (dev->fFlags & kNeedClear_Flag) {
1518 // TODO: could check here whether we really need to draw at all 1519 // TODO: could check here whether we really need to draw at all
1519 dev->clearAll(); 1520 dev->clearAll();
1520 } 1521 }
1521 1522
1522 // drawDevice is defined to be in device coords. 1523 // drawDevice is defined to be in device coords.
1523 CHECK_SHOULD_DRAW(draw, true); 1524 CHECK_SHOULD_DRAW(draw);
1524 1525
1525 GrRenderTarget* devRT = dev->accessRenderTarget(); 1526 GrRenderTarget* devRT = dev->accessRenderTarget();
1526 GrTexture* devTex; 1527 GrTexture* devTex;
1527 if (NULL == (devTex = devRT->asTexture())) { 1528 if (NULL == (devTex = devRT->asTexture())) {
1528 return; 1529 return;
1529 } 1530 }
1530 1531
1531 const SkImageInfo ii = dev->imageInfo(); 1532 const SkImageInfo ii = dev->imageInfo();
1532 int w = ii.width(); 1533 int w = ii.width();
1533 int h = ii.height(); 1534 int h = ii.height();
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1566 SkRect dstRect = SkRect::MakeXYWH(SkIntToScalar(x), 1567 SkRect dstRect = SkRect::MakeXYWH(SkIntToScalar(x),
1567 SkIntToScalar(y), 1568 SkIntToScalar(y),
1568 SkIntToScalar(w), 1569 SkIntToScalar(w),
1569 SkIntToScalar(h)); 1570 SkIntToScalar(h));
1570 1571
1571 // The device being drawn may not fill up its texture (e.g. saveLayer uses a pproximate 1572 // The device being drawn may not fill up its texture (e.g. saveLayer uses a pproximate
1572 // scratch texture). 1573 // scratch texture).
1573 SkRect srcRect = SkRect::MakeWH(SK_Scalar1 * w / devTex->width(), 1574 SkRect srcRect = SkRect::MakeWH(SK_Scalar1 * w / devTex->width(),
1574 SK_Scalar1 * h / devTex->height()); 1575 SK_Scalar1 * h / devTex->height());
1575 1576
1576 fContext->drawRectToRect(grPaint, dstRect, srcRect); 1577 fContext->drawRectToRect(grPaint, SkMatrix::I(), dstRect, srcRect);
1577 } 1578 }
1578 1579
1579 bool SkGpuDevice::canHandleImageFilter(const SkImageFilter* filter) { 1580 bool SkGpuDevice::canHandleImageFilter(const SkImageFilter* filter) {
1580 return filter->canFilterImageGPU(); 1581 return filter->canFilterImageGPU();
1581 } 1582 }
1582 1583
1583 bool SkGpuDevice::filterImage(const SkImageFilter* filter, const SkBitmap& src, 1584 bool SkGpuDevice::filterImage(const SkImageFilter* filter, const SkBitmap& src,
1584 const SkImageFilter::Context& ctx, 1585 const SkImageFilter::Context& ctx,
1585 SkBitmap* result, SkIPoint* offset) { 1586 SkBitmap* result, SkIPoint* offset) {
1586 // want explicitly our impl, so guard against a subclass of us overriding it 1587 // want explicitly our impl, so guard against a subclass of us overriding it
(...skipping 22 matching lines...) Expand all
1609 kTriangleStrip_GrPrimitiveType, 1610 kTriangleStrip_GrPrimitiveType,
1610 kTriangleFan_GrPrimitiveType, 1611 kTriangleFan_GrPrimitiveType,
1611 }; 1612 };
1612 1613
1613 void SkGpuDevice::drawVertices(const SkDraw& draw, SkCanvas::VertexMode vmode, 1614 void SkGpuDevice::drawVertices(const SkDraw& draw, SkCanvas::VertexMode vmode,
1614 int vertexCount, const SkPoint vertices[], 1615 int vertexCount, const SkPoint vertices[],
1615 const SkPoint texs[], const SkColor colors[], 1616 const SkPoint texs[], const SkColor colors[],
1616 SkXfermode* xmode, 1617 SkXfermode* xmode,
1617 const uint16_t indices[], int indexCount, 1618 const uint16_t indices[], int indexCount,
1618 const SkPaint& paint) { 1619 const SkPaint& paint) {
1619 CHECK_SHOULD_DRAW(draw, false); 1620 CHECK_SHOULD_DRAW(draw);
1620
1621 GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawVertices", fContext); 1621 GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawVertices", fContext);
1622 1622
1623 const uint16_t* outIndices; 1623 const uint16_t* outIndices;
1624 SkAutoTDeleteArray<uint16_t> outAlloc(NULL); 1624 SkAutoTDeleteArray<uint16_t> outAlloc(NULL);
1625 GrPrimitiveType primType; 1625 GrPrimitiveType primType;
1626 GrPaint grPaint; 1626 GrPaint grPaint;
1627 1627
1628 // If both textures and vertex-colors are NULL, strokes hairlines with the p aint's color. 1628 // If both textures and vertex-colors are NULL, strokes hairlines with the p aint's color.
1629 if ((NULL == texs || NULL == paint.getShader()) && NULL == colors) { 1629 if ((NULL == texs || NULL == paint.getShader()) && NULL == colors) {
1630 1630
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1671 i += 6; 1671 i += 6;
1672 } 1672 }
1673 } else { 1673 } else {
1674 outIndices = indices; 1674 outIndices = indices;
1675 primType = gVertexMode2PrimitiveType[vmode]; 1675 primType = gVertexMode2PrimitiveType[vmode];
1676 1676
1677 if (NULL == texs || NULL == paint.getShader()) { 1677 if (NULL == texs || NULL == paint.getShader()) {
1678 SkPaint2GrPaintNoShader(this->context(), paint, SkColor2GrColor(pain t.getColor()), 1678 SkPaint2GrPaintNoShader(this->context(), paint, SkColor2GrColor(pain t.getColor()),
1679 NULL == colors, &grPaint); 1679 NULL == colors, &grPaint);
1680 } else { 1680 } else {
1681 SkPaint2GrPaintShader(this->context(), paint, NULL == colors, &grPai nt); 1681 SkPaint2GrPaintShader(this->context(), paint, *draw.fMatrix, NULL == colors, &grPaint);
1682 } 1682 }
1683 } 1683 }
1684 1684
1685 #if 0 1685 #if 0
1686 if (xmode && texs && colors) { 1686 if (xmode && texs && colors) {
1687 if (!SkXfermode::IsMode(xmode, SkXfermode::kModulate_Mode)) { 1687 if (!SkXfermode::IsMode(xmode, SkXfermode::kModulate_Mode)) {
1688 SkDebugf("Unsupported vertex-color/texture xfer mode.\n"); 1688 SkDebugf("Unsupported vertex-color/texture xfer mode.\n");
1689 return; 1689 return;
1690 } 1690 }
1691 } 1691 }
1692 #endif 1692 #endif
1693 1693
1694 SkAutoSTMalloc<128, GrColor> convertedColors(0); 1694 SkAutoSTMalloc<128, GrColor> convertedColors(0);
1695 if (colors) { 1695 if (colors) {
1696 // need to convert byte order and from non-PM to PM 1696 // need to convert byte order and from non-PM to PM
1697 convertedColors.reset(vertexCount); 1697 convertedColors.reset(vertexCount);
1698 SkColor color; 1698 SkColor color;
1699 for (int i = 0; i < vertexCount; ++i) { 1699 for (int i = 0; i < vertexCount; ++i) {
1700 color = colors[i]; 1700 color = colors[i];
1701 if (paint.getAlpha() != 255) { 1701 if (paint.getAlpha() != 255) {
1702 color = SkColorSetA(color, SkMulDiv255Round(SkColorGetA(color), paint.getAlpha())); 1702 color = SkColorSetA(color, SkMulDiv255Round(SkColorGetA(color), paint.getAlpha()));
1703 } 1703 }
1704 convertedColors[i] = SkColor2GrColor(color); 1704 convertedColors[i] = SkColor2GrColor(color);
1705 } 1705 }
1706 colors = convertedColors.get(); 1706 colors = convertedColors.get();
1707 } 1707 }
1708 fContext->drawVertices(grPaint, 1708 fContext->drawVertices(grPaint,
1709 *draw.fMatrix,
1709 primType, 1710 primType,
1710 vertexCount, 1711 vertexCount,
1711 vertices, 1712 vertices,
1712 texs, 1713 texs,
1713 colors, 1714 colors,
1714 outIndices, 1715 outIndices,
1715 indexCount); 1716 indexCount);
1716 } 1717 }
1717 1718
1718 /////////////////////////////////////////////////////////////////////////////// 1719 ///////////////////////////////////////////////////////////////////////////////
1719 1720
1720 void SkGpuDevice::drawText(const SkDraw& draw, const void* text, 1721 void SkGpuDevice::drawText(const SkDraw& draw, const void* text,
1721 size_t byteLength, SkScalar x, SkScalar y, 1722 size_t byteLength, SkScalar x, SkScalar y,
1722 const SkPaint& paint) { 1723 const SkPaint& paint) {
1723 CHECK_SHOULD_DRAW(draw, false); 1724 CHECK_SHOULD_DRAW(draw);
1724 GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawText", fContext); 1725 GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawText", fContext);
1725 1726
1726 GrPaint grPaint; 1727 GrPaint grPaint;
1727 SkPaint2GrPaintShader(this->context(), paint, true, &grPaint); 1728 SkPaint2GrPaintShader(this->context(), paint, *draw.fMatrix, true, &grPaint) ;
1728 1729
1729 SkDEBUGCODE(this->validate();) 1730 SkDEBUGCODE(this->validate();)
1730 1731
1731 if (!fTextContext->drawText(grPaint, paint, (const char *)text, byteLength, x, y)) { 1732 if (!fTextContext->drawText(grPaint, paint, *draw.fMatrix, (const char *)tex t, byteLength, x,
1733 y)) {
1732 // this will just call our drawPath() 1734 // this will just call our drawPath()
1733 draw.drawText_asPaths((const char*)text, byteLength, x, y, paint); 1735 draw.drawText_asPaths((const char*)text, byteLength, x, y, paint);
1734 } 1736 }
1735 } 1737 }
1736 1738
1737 void SkGpuDevice::drawPosText(const SkDraw& draw, const void* text, size_t byteL ength, 1739 void SkGpuDevice::drawPosText(const SkDraw& draw, const void* text, size_t byteL ength,
1738 const SkScalar pos[], int scalarsPerPos, 1740 const SkScalar pos[], int scalarsPerPos,
1739 const SkPoint& offset, const SkPaint& paint) { 1741 const SkPoint& offset, const SkPaint& paint) {
1740 GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawPosText", fContext); 1742 GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawPosText", fContext);
1741 CHECK_SHOULD_DRAW(draw, false); 1743 CHECK_SHOULD_DRAW(draw);
1742 1744
1743 GrPaint grPaint; 1745 GrPaint grPaint;
1744 SkPaint2GrPaintShader(this->context(), paint, true, &grPaint); 1746 SkPaint2GrPaintShader(this->context(), paint, *draw.fMatrix, true, &grPaint) ;
1745 1747
1746 SkDEBUGCODE(this->validate();) 1748 SkDEBUGCODE(this->validate();)
1747 1749
1748 if (!fTextContext->drawPosText(grPaint, paint, (const char *)text, byteLengt h, pos, 1750 if (!fTextContext->drawPosText(grPaint, paint, *draw.fMatrix, (const char *) text, byteLength,
1749 scalarsPerPos, offset)) { 1751 pos, scalarsPerPos, offset)) {
1750 // this will just call our drawPath() 1752 // this will just call our drawPath()
1751 draw.drawPosText_asPaths((const char*)text, byteLength, pos, scalarsPerP os, offset, paint); 1753 draw.drawPosText_asPaths((const char*)text, byteLength, pos, scalarsPerP os, offset, paint);
1752 } 1754 }
1753 } 1755 }
1754 1756
1755 void SkGpuDevice::drawTextOnPath(const SkDraw& draw, const void* text, 1757 void SkGpuDevice::drawTextOnPath(const SkDraw& draw, const void* text,
1756 size_t len, const SkPath& path, 1758 size_t len, const SkPath& path,
1757 const SkMatrix* m, const SkPaint& paint) { 1759 const SkMatrix* m, const SkPaint& paint) {
1758 CHECK_SHOULD_DRAW(draw, false); 1760 CHECK_SHOULD_DRAW(draw);
1759 1761
1760 SkASSERT(draw.fDevice == this); 1762 SkASSERT(draw.fDevice == this);
1761 draw.drawTextOnPath((const char*)text, len, path, m, paint); 1763 draw.drawTextOnPath((const char*)text, len, path, m, paint);
1762 } 1764 }
1763 1765
1764 /////////////////////////////////////////////////////////////////////////////// 1766 ///////////////////////////////////////////////////////////////////////////////
1765 1767
1766 bool SkGpuDevice::onShouldDisableLCD(const SkPaint& paint) const { 1768 bool SkGpuDevice::onShouldDisableLCD(const SkPaint& paint) const {
1767 if (paint.getShader() || 1769 if (paint.getShader() ||
1768 !SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrcOver_Mode) || 1770 !SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrcOver_Mode) ||
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
1881 #endif 1883 #endif
1882 } 1884 }
1883 1885
1884 SkImageFilter::Cache* SkGpuDevice::getImageFilterCache() { 1886 SkImageFilter::Cache* SkGpuDevice::getImageFilterCache() {
1885 // We always return a transient cache, so it is freed after each 1887 // We always return a transient cache, so it is freed after each
1886 // filter traversal. 1888 // filter traversal.
1887 return SkImageFilter::Cache::Create(kDefaultImageFilterCacheSize); 1889 return SkImageFilter::Cache::Create(kDefaultImageFilterCacheSize);
1888 } 1890 }
1889 1891
1890 #endif 1892 #endif
OLDNEW
« no previous file with comments | « src/gpu/SkGpuDevice.h ('k') | src/gpu/SkGr.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698