OLD | NEW |
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 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
204 return SkNEW_ARGS(SkGpuDevice, (texture->asRenderTarget(), props, flags)); | 204 return SkNEW_ARGS(SkGpuDevice, (texture->asRenderTarget(), props, flags)); |
205 } | 205 } |
206 | 206 |
207 SkGpuDevice::~SkGpuDevice() { | 207 SkGpuDevice::~SkGpuDevice() { |
208 if (fDrawProcs) { | 208 if (fDrawProcs) { |
209 delete fDrawProcs; | 209 delete fDrawProcs; |
210 } | 210 } |
211 | 211 |
212 delete fTextContext; | 212 delete fTextContext; |
213 | 213 |
214 // The GrContext takes a ref on the target. We don't want to cause the rende
r | |
215 // target to be unnecessarily kept alive. | |
216 if (fContext->getRenderTarget() == fRenderTarget) { | |
217 fContext->setRenderTarget(NULL); | |
218 } | |
219 | |
220 if (fContext->getClip() == &fClipData) { | 214 if (fContext->getClip() == &fClipData) { |
221 fContext->setClip(NULL); | 215 fContext->setClip(NULL); |
222 } | 216 } |
223 | 217 |
224 fRenderTarget->unref(); | 218 fRenderTarget->unref(); |
225 fContext->unref(); | 219 fContext->unref(); |
226 } | 220 } |
227 | 221 |
228 /////////////////////////////////////////////////////////////////////////////// | 222 /////////////////////////////////////////////////////////////////////////////// |
229 | 223 |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
279 void SkGpuDevice::onDetachFromCanvas() { | 273 void SkGpuDevice::onDetachFromCanvas() { |
280 INHERITED::onDetachFromCanvas(); | 274 INHERITED::onDetachFromCanvas(); |
281 fClipData.fClipStack.reset(NULL); | 275 fClipData.fClipStack.reset(NULL); |
282 } | 276 } |
283 | 277 |
284 // call this every draw call, to ensure that the context reflects our state, | 278 // call this every draw call, to ensure that the context reflects our state, |
285 // and not the state from some other canvas/device | 279 // and not the state from some other canvas/device |
286 void SkGpuDevice::prepareDraw(const SkDraw& draw) { | 280 void SkGpuDevice::prepareDraw(const SkDraw& draw) { |
287 SkASSERT(fClipData.fClipStack); | 281 SkASSERT(fClipData.fClipStack); |
288 | 282 |
289 fContext->setRenderTarget(fRenderTarget); | |
290 | |
291 SkASSERT(draw.fClipStack && draw.fClipStack == fClipData.fClipStack); | 283 SkASSERT(draw.fClipStack && draw.fClipStack == fClipData.fClipStack); |
292 | 284 |
293 fClipData.fOrigin = this->getOrigin(); | 285 fClipData.fOrigin = this->getOrigin(); |
294 | 286 |
295 fContext->setClip(&fClipData); | 287 fContext->setClip(&fClipData); |
296 | 288 |
297 DO_DEFERRED_CLEAR(); | 289 DO_DEFERRED_CLEAR(); |
298 } | 290 } |
299 | 291 |
300 GrRenderTarget* SkGpuDevice::accessRenderTarget() { | 292 GrRenderTarget* SkGpuDevice::accessRenderTarget() { |
(...skipping 22 matching lines...) Expand all Loading... |
323 SK_COMPILE_ASSERT(SkShader::kLinear_BitmapType == 6, shader_type_mismatch); | 315 SK_COMPILE_ASSERT(SkShader::kLinear_BitmapType == 6, shader_type_mismatch); |
324 SK_COMPILE_ASSERT(SkShader::kLast_BitmapType == 6, shader_type_mismatch); | 316 SK_COMPILE_ASSERT(SkShader::kLast_BitmapType == 6, shader_type_mismatch); |
325 | 317 |
326 /////////////////////////////////////////////////////////////////////////////// | 318 /////////////////////////////////////////////////////////////////////////////// |
327 | 319 |
328 void SkGpuDevice::drawPaint(const SkDraw& draw, const SkPaint& paint) { | 320 void SkGpuDevice::drawPaint(const SkDraw& draw, const SkPaint& paint) { |
329 CHECK_SHOULD_DRAW(draw); | 321 CHECK_SHOULD_DRAW(draw); |
330 GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawPaint", fContext); | 322 GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawPaint", fContext); |
331 | 323 |
332 GrPaint grPaint; | 324 GrPaint grPaint; |
333 SkPaint2GrPaintShader(this->context(), paint, *draw.fMatrix, true, &grPaint)
; | 325 SkPaint2GrPaintShader(this->context(), fRenderTarget, paint, *draw.fMatrix,
true, &grPaint); |
334 | 326 |
335 fContext->drawPaint(grPaint, *draw.fMatrix); | 327 fContext->drawPaint(fRenderTarget, grPaint, *draw.fMatrix); |
336 } | 328 } |
337 | 329 |
338 // must be in SkCanvas::PointMode order | 330 // must be in SkCanvas::PointMode order |
339 static const GrPrimitiveType gPointMode2PrimtiveType[] = { | 331 static const GrPrimitiveType gPointMode2PrimtiveType[] = { |
340 kPoints_GrPrimitiveType, | 332 kPoints_GrPrimitiveType, |
341 kLines_GrPrimitiveType, | 333 kLines_GrPrimitiveType, |
342 kLineStrip_GrPrimitiveType | 334 kLineStrip_GrPrimitiveType |
343 }; | 335 }; |
344 | 336 |
345 void SkGpuDevice::drawPoints(const SkDraw& draw, SkCanvas::PointMode mode, | 337 void SkGpuDevice::drawPoints(const SkDraw& draw, SkCanvas::PointMode mode, |
346 size_t count, const SkPoint pts[], const SkPaint& p
aint) { | 338 size_t count, const SkPoint pts[], const SkPaint& p
aint) { |
347 CHECK_FOR_ANNOTATION(paint); | 339 CHECK_FOR_ANNOTATION(paint); |
348 CHECK_SHOULD_DRAW(draw); | 340 CHECK_SHOULD_DRAW(draw); |
349 | 341 |
350 SkScalar width = paint.getStrokeWidth(); | 342 SkScalar width = paint.getStrokeWidth(); |
351 if (width < 0) { | 343 if (width < 0) { |
352 return; | 344 return; |
353 } | 345 } |
354 | 346 |
355 if (paint.getPathEffect() && 2 == count && SkCanvas::kLines_PointMode == mod
e) { | 347 if (paint.getPathEffect() && 2 == count && SkCanvas::kLines_PointMode == mod
e) { |
356 GrStrokeInfo strokeInfo(paint, SkPaint::kStroke_Style); | 348 GrStrokeInfo strokeInfo(paint, SkPaint::kStroke_Style); |
357 GrPaint grPaint; | 349 GrPaint grPaint; |
358 SkPaint2GrPaintShader(this->context(), paint, *draw.fMatrix, true, &grPa
int); | 350 SkPaint2GrPaintShader(this->context(), fRenderTarget, paint, *draw.fMatr
ix, true, &grPaint); |
359 SkPath path; | 351 SkPath path; |
360 path.setIsVolatile(true); | 352 path.setIsVolatile(true); |
361 path.moveTo(pts[0]); | 353 path.moveTo(pts[0]); |
362 path.lineTo(pts[1]); | 354 path.lineTo(pts[1]); |
363 fContext->drawPath(grPaint, *draw.fMatrix, path, strokeInfo); | 355 fContext->drawPath(fRenderTarget, grPaint, *draw.fMatrix, path, strokeIn
fo); |
364 return; | 356 return; |
365 } | 357 } |
366 | 358 |
367 // we only handle hairlines and paints without path effects or mask filters, | 359 // we only handle hairlines and paints without path effects or mask filters, |
368 // else we let the SkDraw call our drawPath() | 360 // else we let the SkDraw call our drawPath() |
369 if (width > 0 || paint.getPathEffect() || paint.getMaskFilter()) { | 361 if (width > 0 || paint.getPathEffect() || paint.getMaskFilter()) { |
370 draw.drawPoints(mode, count, pts, paint, true); | 362 draw.drawPoints(mode, count, pts, paint, true); |
371 return; | 363 return; |
372 } | 364 } |
373 | 365 |
374 GrPaint grPaint; | 366 GrPaint grPaint; |
375 SkPaint2GrPaintShader(this->context(), paint, *draw.fMatrix, true, &grPaint)
; | 367 SkPaint2GrPaintShader(this->context(), fRenderTarget, paint, *draw.fMatrix,
true, &grPaint); |
376 | 368 |
377 fContext->drawVertices(grPaint, | 369 fContext->drawVertices(fRenderTarget, |
| 370 grPaint, |
378 *draw.fMatrix, | 371 *draw.fMatrix, |
379 gPointMode2PrimtiveType[mode], | 372 gPointMode2PrimtiveType[mode], |
380 SkToS32(count), | 373 SkToS32(count), |
381 (SkPoint*)pts, | 374 (SkPoint*)pts, |
382 NULL, | 375 NULL, |
383 NULL, | 376 NULL, |
384 NULL, | 377 NULL, |
385 0); | 378 0); |
386 } | 379 } |
387 | 380 |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
435 | 428 |
436 if (usePath) { | 429 if (usePath) { |
437 SkPath path; | 430 SkPath path; |
438 path.setIsVolatile(true); | 431 path.setIsVolatile(true); |
439 path.addRect(rect); | 432 path.addRect(rect); |
440 this->drawPath(draw, path, paint, NULL, true); | 433 this->drawPath(draw, path, paint, NULL, true); |
441 return; | 434 return; |
442 } | 435 } |
443 | 436 |
444 GrPaint grPaint; | 437 GrPaint grPaint; |
445 SkPaint2GrPaintShader(this->context(), paint, *draw.fMatrix, true, &grPaint)
; | 438 SkPaint2GrPaintShader(this->context(), fRenderTarget, paint, *draw.fMatrix,
true, &grPaint); |
446 | 439 |
447 fContext->drawRect(grPaint, *draw.fMatrix, rect, &strokeInfo); | 440 fContext->drawRect(fRenderTarget, grPaint, *draw.fMatrix, rect, &strokeInfo)
; |
448 } | 441 } |
449 | 442 |
450 /////////////////////////////////////////////////////////////////////////////// | 443 /////////////////////////////////////////////////////////////////////////////// |
451 | 444 |
452 void SkGpuDevice::drawRRect(const SkDraw& draw, const SkRRect& rect, | 445 void SkGpuDevice::drawRRect(const SkDraw& draw, const SkRRect& rect, |
453 const SkPaint& paint) { | 446 const SkPaint& paint) { |
454 GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawRRect", fContext); | 447 GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawRRect", fContext); |
455 CHECK_FOR_ANNOTATION(paint); | 448 CHECK_FOR_ANNOTATION(paint); |
456 CHECK_SHOULD_DRAW(draw); | 449 CHECK_SHOULD_DRAW(draw); |
457 | 450 |
458 GrPaint grPaint; | 451 GrPaint grPaint; |
459 SkPaint2GrPaintShader(this->context(), paint, *draw.fMatrix, true, &grPaint)
; | 452 SkPaint2GrPaintShader(this->context(), fRenderTarget, paint, *draw.fMatrix,
true, &grPaint); |
460 | 453 |
461 GrStrokeInfo strokeInfo(paint); | 454 GrStrokeInfo strokeInfo(paint); |
462 if (paint.getMaskFilter()) { | 455 if (paint.getMaskFilter()) { |
463 // try to hit the fast path for drawing filtered round rects | 456 // try to hit the fast path for drawing filtered round rects |
464 | 457 |
465 SkRRect devRRect; | 458 SkRRect devRRect; |
466 if (rect.transform(*draw.fMatrix, &devRRect)) { | 459 if (rect.transform(*draw.fMatrix, &devRRect)) { |
467 if (devRRect.allCornersCircular()) { | 460 if (devRRect.allCornersCircular()) { |
468 SkRect maskRect; | 461 SkRect maskRect; |
469 if (paint.getMaskFilter()->canFilterMaskGPU(devRRect.rect(), | 462 if (paint.getMaskFilter()->canFilterMaskGPU(devRRect.rect(), |
470 draw.fClip->getBound
s(), | 463 draw.fClip->getBound
s(), |
471 *draw.fMatrix, | 464 *draw.fMatrix, |
472 &maskRect)) { | 465 &maskRect)) { |
473 SkIRect finalIRect; | 466 SkIRect finalIRect; |
474 maskRect.roundOut(&finalIRect); | 467 maskRect.roundOut(&finalIRect); |
475 if (draw.fClip->quickReject(finalIRect)) { | 468 if (draw.fClip->quickReject(finalIRect)) { |
476 // clipped out | 469 // clipped out |
477 return; | 470 return; |
478 } | 471 } |
479 if (paint.getMaskFilter()->directFilterRRectMaskGPU(fContext
, &grPaint, | 472 if (paint.getMaskFilter()->directFilterRRectMaskGPU(fContext
, |
| 473 fRenderT
arget, |
| 474 &grPaint
, |
480 *draw.fM
atrix, | 475 *draw.fM
atrix, |
481 strokeIn
fo.getStrokeRec(), | 476 strokeIn
fo.getStrokeRec(), |
482 devRRect
)) { | 477 devRRect
)) { |
483 return; | 478 return; |
484 } | 479 } |
485 } | 480 } |
486 | 481 |
487 } | 482 } |
488 } | 483 } |
489 | 484 |
(...skipping 12 matching lines...) Expand all Loading... |
502 | 497 |
503 | 498 |
504 if (usePath) { | 499 if (usePath) { |
505 SkPath path; | 500 SkPath path; |
506 path.setIsVolatile(true); | 501 path.setIsVolatile(true); |
507 path.addRRect(rect); | 502 path.addRRect(rect); |
508 this->drawPath(draw, path, paint, NULL, true); | 503 this->drawPath(draw, path, paint, NULL, true); |
509 return; | 504 return; |
510 } | 505 } |
511 | 506 |
512 fContext->drawRRect(grPaint, *draw.fMatrix, rect, strokeInfo); | 507 fContext->drawRRect(fRenderTarget, grPaint, *draw.fMatrix, rect, strokeInfo)
; |
513 } | 508 } |
514 | 509 |
515 void SkGpuDevice::drawDRRect(const SkDraw& draw, const SkRRect& outer, | 510 void SkGpuDevice::drawDRRect(const SkDraw& draw, const SkRRect& outer, |
516 const SkRRect& inner, const SkPaint& paint) { | 511 const SkRRect& inner, const SkPaint& paint) { |
517 SkStrokeRec stroke(paint); | 512 SkStrokeRec stroke(paint); |
518 if (stroke.isFillStyle()) { | 513 if (stroke.isFillStyle()) { |
519 | 514 |
520 CHECK_FOR_ANNOTATION(paint); | 515 CHECK_FOR_ANNOTATION(paint); |
521 CHECK_SHOULD_DRAW(draw); | 516 CHECK_SHOULD_DRAW(draw); |
522 | 517 |
523 GrPaint grPaint; | 518 GrPaint grPaint; |
524 SkPaint2GrPaintShader(this->context(), paint, *draw.fMatrix, true, &grPa
int); | 519 SkPaint2GrPaintShader(this->context(), fRenderTarget, paint, *draw.fMatr
ix, true, &grPaint); |
525 | 520 |
526 if (NULL == paint.getMaskFilter() && NULL == paint.getPathEffect()) { | 521 if (NULL == paint.getMaskFilter() && NULL == paint.getPathEffect()) { |
527 fContext->drawDRRect(grPaint, *draw.fMatrix, outer, inner); | 522 fContext->drawDRRect(fRenderTarget, grPaint, *draw.fMatrix, outer, i
nner); |
528 return; | 523 return; |
529 } | 524 } |
530 } | 525 } |
531 | 526 |
532 SkPath path; | 527 SkPath path; |
533 path.setIsVolatile(true); | 528 path.setIsVolatile(true); |
534 path.addRRect(outer); | 529 path.addRRect(outer); |
535 path.addRRect(inner); | 530 path.addRRect(inner); |
536 path.setFillType(SkPath::kEvenOdd_FillType); | 531 path.setFillType(SkPath::kEvenOdd_FillType); |
537 | 532 |
(...skipping 24 matching lines...) Expand all Loading... |
562 | 557 |
563 if (usePath) { | 558 if (usePath) { |
564 SkPath path; | 559 SkPath path; |
565 path.setIsVolatile(true); | 560 path.setIsVolatile(true); |
566 path.addOval(oval); | 561 path.addOval(oval); |
567 this->drawPath(draw, path, paint, NULL, true); | 562 this->drawPath(draw, path, paint, NULL, true); |
568 return; | 563 return; |
569 } | 564 } |
570 | 565 |
571 GrPaint grPaint; | 566 GrPaint grPaint; |
572 SkPaint2GrPaintShader(this->context(), paint, *draw.fMatrix, true, &grPaint)
; | 567 SkPaint2GrPaintShader(this->context(), fRenderTarget, paint, *draw.fMatrix,
true, &grPaint); |
573 | 568 |
574 fContext->drawOval(grPaint, *draw.fMatrix, oval, strokeInfo); | 569 fContext->drawOval(fRenderTarget, grPaint, *draw.fMatrix, oval, strokeInfo); |
575 } | 570 } |
576 | 571 |
577 #include "SkMaskFilter.h" | 572 #include "SkMaskFilter.h" |
578 | 573 |
579 /////////////////////////////////////////////////////////////////////////////// | 574 /////////////////////////////////////////////////////////////////////////////// |
580 | 575 |
581 // helpers for applying mask filters | 576 // helpers for applying mask filters |
582 namespace { | 577 namespace { |
583 | 578 |
584 // Draw a mask using the supplied paint. Since the coverage/geometry | 579 // Draw a mask using the supplied paint. Since the coverage/geometry |
585 // is already burnt into the mask this boils down to a rect draw. | 580 // is already burnt into the mask this boils down to a rect draw. |
586 // Return true if the mask was successfully drawn. | 581 // Return true if the mask was successfully drawn. |
587 bool draw_mask(GrContext* context, const SkMatrix& viewMatrix, const SkRect& mas
kRect, | 582 bool draw_mask(GrContext* context, |
588 GrPaint* grp, GrTexture* mask) { | 583 GrRenderTarget* rt, |
| 584 const SkMatrix& viewMatrix, |
| 585 const SkRect& maskRect, |
| 586 GrPaint* grp, |
| 587 GrTexture* mask) { |
589 SkMatrix matrix; | 588 SkMatrix matrix; |
590 matrix.setTranslate(-maskRect.fLeft, -maskRect.fTop); | 589 matrix.setTranslate(-maskRect.fLeft, -maskRect.fTop); |
591 matrix.postIDiv(mask->width(), mask->height()); | 590 matrix.postIDiv(mask->width(), mask->height()); |
592 | 591 |
593 grp->addCoverageProcessor(GrSimpleTextureEffect::Create(mask, matrix, | 592 grp->addCoverageProcessor(GrSimpleTextureEffect::Create(mask, matrix, |
594 kDevice_GrCoordSet))
->unref(); | 593 kDevice_GrCoordSet))
->unref(); |
595 | 594 |
596 SkMatrix inverse; | 595 SkMatrix inverse; |
597 if (!viewMatrix.invert(&inverse)) { | 596 if (!viewMatrix.invert(&inverse)) { |
598 return false; | 597 return false; |
599 } | 598 } |
600 context->drawNonAARectWithLocalMatrix(*grp, SkMatrix::I(), maskRect, inverse
); | 599 context->drawNonAARectWithLocalMatrix(rt, *grp, SkMatrix::I(), maskRect, inv
erse); |
601 return true; | 600 return true; |
602 } | 601 } |
603 | 602 |
604 bool draw_with_mask_filter(GrContext* context, const SkMatrix& viewMatrix, const
SkPath& devPath, | 603 bool draw_with_mask_filter(GrContext* context, |
605 SkMaskFilter* filter, const SkRegion& clip, | 604 GrRenderTarget* rt, |
606 GrPaint* grp, SkPaint::Style style) { | 605 const SkMatrix& viewMatrix, |
| 606 const SkPath& devPath, |
| 607 SkMaskFilter* filter, |
| 608 const SkRegion& clip, |
| 609 GrPaint* grp, |
| 610 SkPaint::Style style) { |
607 SkMask srcM, dstM; | 611 SkMask srcM, dstM; |
608 | 612 |
609 if (!SkDraw::DrawToMask(devPath, &clip.getBounds(), filter, &viewMatrix, &sr
cM, | 613 if (!SkDraw::DrawToMask(devPath, &clip.getBounds(), filter, &viewMatrix, &sr
cM, |
610 SkMask::kComputeBoundsAndRenderImage_CreateMode, sty
le)) { | 614 SkMask::kComputeBoundsAndRenderImage_CreateMode, sty
le)) { |
611 return false; | 615 return false; |
612 } | 616 } |
613 SkAutoMaskFreeImage autoSrc(srcM.fImage); | 617 SkAutoMaskFreeImage autoSrc(srcM.fImage); |
614 | 618 |
615 if (!filter->filterMask(&dstM, srcM, viewMatrix, NULL)) { | 619 if (!filter->filterMask(&dstM, srcM, viewMatrix, NULL)) { |
616 return false; | 620 return false; |
(...skipping 15 matching lines...) Expand all Loading... |
632 SkAutoTUnref<GrTexture> texture( | 636 SkAutoTUnref<GrTexture> texture( |
633 context->refScratchTexture(desc, GrContext::kApprox_ScratchTexMatch)); | 637 context->refScratchTexture(desc, GrContext::kApprox_ScratchTexMatch)); |
634 if (!texture) { | 638 if (!texture) { |
635 return false; | 639 return false; |
636 } | 640 } |
637 texture->writePixels(0, 0, desc.fWidth, desc.fHeight, desc.fConfig, | 641 texture->writePixels(0, 0, desc.fWidth, desc.fHeight, desc.fConfig, |
638 dstM.fImage, dstM.fRowBytes); | 642 dstM.fImage, dstM.fRowBytes); |
639 | 643 |
640 SkRect maskRect = SkRect::Make(dstM.fBounds); | 644 SkRect maskRect = SkRect::Make(dstM.fBounds); |
641 | 645 |
642 return draw_mask(context, viewMatrix, maskRect, grp, texture); | 646 return draw_mask(context, rt, viewMatrix, maskRect, grp, texture); |
643 } | 647 } |
644 | 648 |
645 // Create a mask of 'devPath' and place the result in 'mask'. | 649 // Create a mask of 'devPath' and place the result in 'mask'. |
646 GrTexture* create_mask_GPU(GrContext* context, | 650 GrTexture* create_mask_GPU(GrContext* context, |
| 651 GrRenderTarget* rt, |
647 const SkRect& maskRect, | 652 const SkRect& maskRect, |
648 const SkPath& devPath, | 653 const SkPath& devPath, |
649 const GrStrokeInfo& strokeInfo, | 654 const GrStrokeInfo& strokeInfo, |
650 bool doAA, | 655 bool doAA, |
651 int sampleCnt) { | 656 int sampleCnt) { |
652 GrSurfaceDesc desc; | 657 GrSurfaceDesc desc; |
653 desc.fFlags = kRenderTarget_GrSurfaceFlag; | 658 desc.fFlags = kRenderTarget_GrSurfaceFlag; |
654 desc.fWidth = SkScalarCeilToInt(maskRect.width()); | 659 desc.fWidth = SkScalarCeilToInt(maskRect.width()); |
655 desc.fHeight = SkScalarCeilToInt(maskRect.height()); | 660 desc.fHeight = SkScalarCeilToInt(maskRect.height()); |
656 desc.fSampleCnt = doAA ? sampleCnt : 0; | 661 desc.fSampleCnt = doAA ? sampleCnt : 0; |
657 // We actually only need A8, but it often isn't supported as a | 662 // We actually only need A8, but it often isn't supported as a |
658 // render target so default to RGBA_8888 | 663 // render target so default to RGBA_8888 |
659 desc.fConfig = kRGBA_8888_GrPixelConfig; | 664 desc.fConfig = kRGBA_8888_GrPixelConfig; |
660 | 665 |
661 if (context->isConfigRenderable(kAlpha_8_GrPixelConfig, | 666 if (context->isConfigRenderable(kAlpha_8_GrPixelConfig, |
662 desc.fSampleCnt > 0)) { | 667 desc.fSampleCnt > 0)) { |
663 desc.fConfig = kAlpha_8_GrPixelConfig; | 668 desc.fConfig = kAlpha_8_GrPixelConfig; |
664 } | 669 } |
665 | 670 |
666 GrTexture* mask = context->refScratchTexture(desc,GrContext::kApprox_Scratch
TexMatch); | 671 GrTexture* mask = context->refScratchTexture(desc,GrContext::kApprox_Scratch
TexMatch); |
667 if (NULL == mask) { | 672 if (NULL == mask) { |
668 return NULL; | 673 return NULL; |
669 } | 674 } |
670 | 675 |
671 SkRect clipRect = SkRect::MakeWH(maskRect.width(), maskRect.height()); | 676 SkRect clipRect = SkRect::MakeWH(maskRect.width(), maskRect.height()); |
672 | 677 |
673 GrContext::AutoRenderTarget art(context, mask->asRenderTarget()); | |
674 GrContext::AutoClip ac(context, clipRect); | 678 GrContext::AutoClip ac(context, clipRect); |
675 | 679 |
676 context->clear(NULL, 0x0, true, mask->asRenderTarget()); | 680 context->clear(NULL, 0x0, true, mask->asRenderTarget()); |
677 | 681 |
678 GrPaint tempPaint; | 682 GrPaint tempPaint; |
679 tempPaint.setAntiAlias(doAA); | 683 tempPaint.setAntiAlias(doAA); |
680 tempPaint.setCoverageSetOpXPFactory(SkRegion::kReplace_Op); | 684 tempPaint.setCoverageSetOpXPFactory(SkRegion::kReplace_Op); |
681 | 685 |
682 // Draw the mask into maskTexture with the path's top-left at the origin usi
ng tempPaint. | 686 // Draw the mask into maskTexture with the path's top-left at the origin usi
ng tempPaint. |
683 SkMatrix translate; | 687 SkMatrix translate; |
684 translate.setTranslate(-maskRect.fLeft, -maskRect.fTop); | 688 translate.setTranslate(-maskRect.fLeft, -maskRect.fTop); |
685 context->drawPath(tempPaint, translate, devPath, strokeInfo); | 689 context->drawPath(mask->asRenderTarget(), tempPaint, translate, devPath, str
okeInfo); |
686 return mask; | 690 return mask; |
687 } | 691 } |
688 | 692 |
689 SkBitmap wrap_texture(GrTexture* texture) { | 693 SkBitmap wrap_texture(GrTexture* texture) { |
690 SkBitmap result; | 694 SkBitmap result; |
691 result.setInfo(texture->surfacePriv().info()); | 695 result.setInfo(texture->surfacePriv().info()); |
692 result.setPixelRef(SkNEW_ARGS(SkGrPixelRef, (result.info(), texture)))->unre
f(); | 696 result.setPixelRef(SkNEW_ARGS(SkGrPixelRef, (result.info(), texture)))->unre
f(); |
693 return result; | 697 return result; |
694 } | 698 } |
695 | 699 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
734 // should I push prePathMatrix on our MV stack temporarily, instead | 738 // should I push prePathMatrix on our MV stack temporarily, instead |
735 // of applying it here? See SkDraw.cpp | 739 // of applying it here? See SkDraw.cpp |
736 pathPtr->transform(*prePathMatrix, result); | 740 pathPtr->transform(*prePathMatrix, result); |
737 pathPtr = result; | 741 pathPtr = result; |
738 } | 742 } |
739 } | 743 } |
740 // at this point we're done with prePathMatrix | 744 // at this point we're done with prePathMatrix |
741 SkDEBUGCODE(prePathMatrix = (const SkMatrix*)0x50FF8001;) | 745 SkDEBUGCODE(prePathMatrix = (const SkMatrix*)0x50FF8001;) |
742 | 746 |
743 GrPaint grPaint; | 747 GrPaint grPaint; |
744 SkPaint2GrPaintShader(this->context(), paint, viewMatrix, true, &grPaint); | 748 SkPaint2GrPaintShader(this->context(), fRenderTarget, paint, viewMatrix, tru
e, &grPaint); |
745 | 749 |
746 const SkRect* cullRect = NULL; // TODO: what is our bounds? | 750 const SkRect* cullRect = NULL; // TODO: what is our bounds? |
747 SkStrokeRec* strokePtr = strokeInfo.getStrokeRecPtr(); | 751 SkStrokeRec* strokePtr = strokeInfo.getStrokeRecPtr(); |
748 if (pathEffect && pathEffect->filterPath(effectPath.init(), *pathPtr, stroke
Ptr, | 752 if (pathEffect && pathEffect->filterPath(effectPath.init(), *pathPtr, stroke
Ptr, |
749 cullRect)) { | 753 cullRect)) { |
750 pathPtr = effectPath.get(); | 754 pathPtr = effectPath.get(); |
751 pathIsMutable = true; | 755 pathIsMutable = true; |
752 strokeInfo.removeDash(); | 756 strokeInfo.removeDash(); |
753 } | 757 } |
754 | 758 |
(...skipping 22 matching lines...) Expand all Loading... |
777 draw.fClip->getBounds(), | 781 draw.fClip->getBounds(), |
778 viewMatrix, | 782 viewMatrix, |
779 &maskRect)) { | 783 &maskRect)) { |
780 SkIRect finalIRect; | 784 SkIRect finalIRect; |
781 maskRect.roundOut(&finalIRect); | 785 maskRect.roundOut(&finalIRect); |
782 if (draw.fClip->quickReject(finalIRect)) { | 786 if (draw.fClip->quickReject(finalIRect)) { |
783 // clipped out | 787 // clipped out |
784 return; | 788 return; |
785 } | 789 } |
786 | 790 |
787 if (paint.getMaskFilter()->directFilterMaskGPU(fContext, &grPaint, v
iewMatrix, | 791 if (paint.getMaskFilter()->directFilterMaskGPU(fContext, |
788 stroke, *devPathPtr))
{ | 792 fRenderTarget, |
| 793 &grPaint, |
| 794 viewMatrix, |
| 795 stroke, |
| 796 *devPathPtr)) { |
789 // the mask filter was able to draw itself directly, so there's
nothing | 797 // the mask filter was able to draw itself directly, so there's
nothing |
790 // left to do. | 798 // left to do. |
791 return; | 799 return; |
792 } | 800 } |
793 | 801 |
794 | 802 |
795 SkAutoTUnref<GrTexture> mask(create_mask_GPU(fContext, maskRect, *de
vPathPtr, | 803 SkAutoTUnref<GrTexture> mask(create_mask_GPU(fContext, |
796 strokeInfo, grPaint.isA
ntiAlias(), | 804 fRenderTarget, |
| 805 maskRect, |
| 806 *devPathPtr, |
| 807 strokeInfo, |
| 808 grPaint.isAntiAlias(), |
797 fRenderTarget->numSampl
es())); | 809 fRenderTarget->numSampl
es())); |
798 if (mask) { | 810 if (mask) { |
799 GrTexture* filtered; | 811 GrTexture* filtered; |
800 | 812 |
801 if (paint.getMaskFilter()->filterMaskGPU(mask, viewMatrix, maskR
ect, &filtered, true)) { | 813 if (paint.getMaskFilter()->filterMaskGPU(mask, viewMatrix, maskR
ect, &filtered, true)) { |
802 // filterMaskGPU gives us ownership of a ref to the result | 814 // filterMaskGPU gives us ownership of a ref to the result |
803 SkAutoTUnref<GrTexture> atu(filtered); | 815 SkAutoTUnref<GrTexture> atu(filtered); |
804 if (draw_mask(fContext, viewMatrix, maskRect, &grPaint, filt
ered)) { | 816 if (draw_mask(fContext, fRenderTarget, viewMatrix, maskRect,
&grPaint, |
| 817 filtered)) { |
805 // This path is completely drawn | 818 // This path is completely drawn |
806 return; | 819 return; |
807 } | 820 } |
808 } | 821 } |
809 } | 822 } |
810 } | 823 } |
811 | 824 |
812 // draw the mask on the CPU - this is a fallthrough path in case the | 825 // draw the mask on the CPU - this is a fallthrough path in case the |
813 // GPU path fails | 826 // GPU path fails |
814 SkPaint::Style style = stroke.isHairlineStyle() ? SkPaint::kStroke_Style
: | 827 SkPaint::Style style = stroke.isHairlineStyle() ? SkPaint::kStroke_Style
: |
815 SkPaint::kFill_Style; | 828 SkPaint::kFill_Style; |
816 draw_with_mask_filter(fContext, viewMatrix, *devPathPtr, paint.getMaskFi
lter(), | 829 draw_with_mask_filter(fContext, fRenderTarget, viewMatrix, *devPathPtr, |
817 *draw.fClip, &grPaint, style); | 830 paint.getMaskFilter(), *draw.fClip, &grPaint, styl
e); |
818 return; | 831 return; |
819 } | 832 } |
820 | 833 |
821 fContext->drawPath(grPaint, viewMatrix, *pathPtr, strokeInfo); | 834 fContext->drawPath(fRenderTarget, grPaint, viewMatrix, *pathPtr, strokeInfo)
; |
822 } | 835 } |
823 | 836 |
824 static const int kBmpSmallTileSize = 1 << 10; | 837 static const int kBmpSmallTileSize = 1 << 10; |
825 | 838 |
826 static inline int get_tile_count(const SkIRect& srcRect, int tileSize) { | 839 static inline int get_tile_count(const SkIRect& srcRect, int tileSize) { |
827 int tilesX = (srcRect.fRight / tileSize) - (srcRect.fLeft / tileSize) + 1; | 840 int tilesX = (srcRect.fRight / tileSize) - (srcRect.fLeft / tileSize) + 1; |
828 int tilesY = (srcRect.fBottom / tileSize) - (srcRect.fTop / tileSize) + 1; | 841 int tilesY = (srcRect.fBottom / tileSize) - (srcRect.fTop / tileSize) + 1; |
829 return tilesX * tilesY; | 842 return tilesX * tilesY; |
830 } | 843 } |
831 | 844 |
(...skipping 11 matching lines...) Expand all Loading... |
843 if (maxTileTotalTileSize > 2 * smallTotalTileSize) { | 856 if (maxTileTotalTileSize > 2 * smallTotalTileSize) { |
844 return kBmpSmallTileSize; | 857 return kBmpSmallTileSize; |
845 } else { | 858 } else { |
846 return maxTileSize; | 859 return maxTileSize; |
847 } | 860 } |
848 } | 861 } |
849 | 862 |
850 // Given a bitmap, an optional src rect, and a context with a clip and matrix de
termine what | 863 // Given a bitmap, an optional src rect, and a context with a clip and matrix de
termine what |
851 // pixels from the bitmap are necessary. | 864 // pixels from the bitmap are necessary. |
852 static void determine_clipped_src_rect(const GrContext* context, | 865 static void determine_clipped_src_rect(const GrContext* context, |
| 866 const GrRenderTarget* rt, |
853 const SkMatrix& viewMatrix, | 867 const SkMatrix& viewMatrix, |
854 const SkBitmap& bitmap, | 868 const SkBitmap& bitmap, |
855 const SkRect* srcRectPtr, | 869 const SkRect* srcRectPtr, |
856 SkIRect* clippedSrcIRect) { | 870 SkIRect* clippedSrcIRect) { |
857 const GrClipData* clip = context->getClip(); | 871 const GrClipData* clip = context->getClip(); |
858 clip->getConservativeBounds(context->getRenderTarget(), clippedSrcIRect, NUL
L); | 872 clip->getConservativeBounds(rt, clippedSrcIRect, NULL); |
859 SkMatrix inv; | 873 SkMatrix inv; |
860 if (!viewMatrix.invert(&inv)) { | 874 if (!viewMatrix.invert(&inv)) { |
861 clippedSrcIRect->setEmpty(); | 875 clippedSrcIRect->setEmpty(); |
862 return; | 876 return; |
863 } | 877 } |
864 SkRect clippedSrcRect = SkRect::Make(*clippedSrcIRect); | 878 SkRect clippedSrcRect = SkRect::Make(*clippedSrcIRect); |
865 inv.mapRect(&clippedSrcRect); | 879 inv.mapRect(&clippedSrcRect); |
866 if (srcRectPtr) { | 880 if (srcRectPtr) { |
867 // we've setup src space 0,0 to map to the top left of the src rect. | 881 // we've setup src space 0,0 to map to the top left of the src rect. |
868 clippedSrcRect.offset(srcRectPtr->fLeft, srcRectPtr->fTop); | 882 clippedSrcRect.offset(srcRectPtr->fLeft, srcRectPtr->fTop); |
(...skipping 16 matching lines...) Expand all Loading... |
885 int maxTileSize, | 899 int maxTileSize, |
886 int* tileSize, | 900 int* tileSize, |
887 SkIRect* clippedSrcRect) const { | 901 SkIRect* clippedSrcRect) const { |
888 // if bitmap is explictly texture backed then just use the texture | 902 // if bitmap is explictly texture backed then just use the texture |
889 if (bitmap.getTexture()) { | 903 if (bitmap.getTexture()) { |
890 return false; | 904 return false; |
891 } | 905 } |
892 | 906 |
893 // if it's larger than the max tile size, then we have no choice but tiling. | 907 // if it's larger than the max tile size, then we have no choice but tiling. |
894 if (bitmap.width() > maxTileSize || bitmap.height() > maxTileSize) { | 908 if (bitmap.width() > maxTileSize || bitmap.height() > maxTileSize) { |
895 determine_clipped_src_rect(fContext, viewMatrix, bitmap, srcRectPtr, cli
ppedSrcRect); | 909 determine_clipped_src_rect(fContext, fRenderTarget, viewMatrix, bitmap,
srcRectPtr, |
| 910 clippedSrcRect); |
896 *tileSize = determine_tile_size(bitmap, *clippedSrcRect, maxTileSize); | 911 *tileSize = determine_tile_size(bitmap, *clippedSrcRect, maxTileSize); |
897 return true; | 912 return true; |
898 } | 913 } |
899 | 914 |
900 if (bitmap.width() * bitmap.height() < 4 * kBmpSmallTileSize * kBmpSmallTile
Size) { | 915 if (bitmap.width() * bitmap.height() < 4 * kBmpSmallTileSize * kBmpSmallTile
Size) { |
901 return false; | 916 return false; |
902 } | 917 } |
903 | 918 |
904 // if the entire texture is already in our cache then no reason to tile it | 919 // if the entire texture is already in our cache then no reason to tile it |
905 if (GrIsBitmapInCache(fContext, bitmap, ¶ms)) { | 920 if (GrIsBitmapInCache(fContext, bitmap, ¶ms)) { |
906 return false; | 921 return false; |
907 } | 922 } |
908 | 923 |
909 // At this point we know we could do the draw by uploading the entire bitmap | 924 // At this point we know we could do the draw by uploading the entire bitmap |
910 // as a texture. However, if the texture would be large compared to the | 925 // as a texture. However, if the texture would be large compared to the |
911 // cache size and we don't require most of it for this draw then tile to | 926 // cache size and we don't require most of it for this draw then tile to |
912 // reduce the amount of upload and cache spill. | 927 // reduce the amount of upload and cache spill. |
913 | 928 |
914 // assumption here is that sw bitmap size is a good proxy for its size as | 929 // assumption here is that sw bitmap size is a good proxy for its size as |
915 // a texture | 930 // a texture |
916 size_t bmpSize = bitmap.getSize(); | 931 size_t bmpSize = bitmap.getSize(); |
917 size_t cacheSize; | 932 size_t cacheSize; |
918 fContext->getResourceCacheLimits(NULL, &cacheSize); | 933 fContext->getResourceCacheLimits(NULL, &cacheSize); |
919 if (bmpSize < cacheSize / 2) { | 934 if (bmpSize < cacheSize / 2) { |
920 return false; | 935 return false; |
921 } | 936 } |
922 | 937 |
923 // Figure out how much of the src we will need based on the src rect and cli
pping. | 938 // Figure out how much of the src we will need based on the src rect and cli
pping. |
924 determine_clipped_src_rect(fContext, viewMatrix, bitmap, srcRectPtr, clipped
SrcRect); | 939 determine_clipped_src_rect(fContext, fRenderTarget, viewMatrix, bitmap, srcR
ectPtr, |
| 940 clippedSrcRect); |
925 *tileSize = kBmpSmallTileSize; // already know whole bitmap fits in one max
sized tile. | 941 *tileSize = kBmpSmallTileSize; // already know whole bitmap fits in one max
sized tile. |
926 size_t usedTileBytes = get_tile_count(*clippedSrcRect, kBmpSmallTileSize) * | 942 size_t usedTileBytes = get_tile_count(*clippedSrcRect, kBmpSmallTileSize) * |
927 kBmpSmallTileSize * kBmpSmallTileSize; | 943 kBmpSmallTileSize * kBmpSmallTileSize; |
928 | 944 |
929 return usedTileBytes < 2 * bmpSize; | 945 return usedTileBytes < 2 * bmpSize; |
930 } | 946 } |
931 | 947 |
932 void SkGpuDevice::drawBitmap(const SkDraw& origDraw, | 948 void SkGpuDevice::drawBitmap(const SkDraw& origDraw, |
933 const SkBitmap& bitmap, | 949 const SkBitmap& bitmap, |
934 const SkMatrix& m, | 950 const SkMatrix& m, |
(...skipping 450 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1385 fp.reset(GrSimpleTextureEffect::Create(texture, SkMatrix::I(), params)); | 1401 fp.reset(GrSimpleTextureEffect::Create(texture, SkMatrix::I(), params)); |
1386 } | 1402 } |
1387 | 1403 |
1388 // Construct a GrPaint by setting the bitmap texture as the first effect and
then configuring | 1404 // Construct a GrPaint by setting the bitmap texture as the first effect and
then configuring |
1389 // the rest from the SkPaint. | 1405 // the rest from the SkPaint. |
1390 GrPaint grPaint; | 1406 GrPaint grPaint; |
1391 grPaint.addColorProcessor(fp); | 1407 grPaint.addColorProcessor(fp); |
1392 bool alphaOnly = !(kAlpha_8_SkColorType == bitmap.colorType()); | 1408 bool alphaOnly = !(kAlpha_8_SkColorType == bitmap.colorType()); |
1393 GrColor paintColor = (alphaOnly) ? SkColor2GrColorJustAlpha(paint.getColor()
) : | 1409 GrColor paintColor = (alphaOnly) ? SkColor2GrColorJustAlpha(paint.getColor()
) : |
1394 SkColor2GrColor(paint.getColor()); | 1410 SkColor2GrColor(paint.getColor()); |
1395 SkPaint2GrPaintNoShader(this->context(), paint, paintColor, false, &grPaint)
; | 1411 SkPaint2GrPaintNoShader(this->context(), fRenderTarget, paint, paintColor, f
alse, &grPaint); |
1396 | 1412 |
1397 fContext->drawNonAARectToRect(grPaint, viewMatrix, dstRect, paintRect); | 1413 fContext->drawNonAARectToRect(fRenderTarget, grPaint, viewMatrix, dstRect, p
aintRect); |
1398 } | 1414 } |
1399 | 1415 |
1400 bool SkGpuDevice::filterTexture(GrContext* context, GrTexture* texture, | 1416 bool SkGpuDevice::filterTexture(GrContext* context, GrTexture* texture, |
1401 const SkImageFilter* filter, | 1417 const SkImageFilter* filter, |
1402 const SkImageFilter::Context& ctx, | 1418 const SkImageFilter::Context& ctx, |
1403 SkBitmap* result, SkIPoint* offset) { | 1419 SkBitmap* result, SkIPoint* offset) { |
1404 SkASSERT(filter); | 1420 SkASSERT(filter); |
1405 | 1421 |
1406 // FIXME: plumb actual surface props such that we don't have to lie about th
e flags here | 1422 // FIXME: plumb actual surface props such that we don't have to lie about th
e flags here |
1407 // (https://code.google.com/p/skia/issues/detail?id=3148). | 1423 // (https://code.google.com/p/skia/issues/detail?id=3148). |
1408 SkDeviceImageFilterProxy proxy(this, SkSurfaceProps(0, getLeakyProperties().
pixelGeometry())); | 1424 SkDeviceImageFilterProxy proxy(this, SkSurfaceProps(0, getLeakyProperties().
pixelGeometry())); |
1409 | 1425 |
1410 if (filter->canFilterImageGPU()) { | 1426 if (filter->canFilterImageGPU()) { |
1411 // Save the render target and set it to NULL, so we don't accidentally d
raw to it in the | 1427 // Set the clip wide open and the matrix to identity. |
1412 // filter. Also set the clip wide open and the matrix to identity. | 1428 GrContext::AutoWideOpenIdentityDraw awo(context); |
1413 GrContext::AutoWideOpenIdentityDraw awo(context, NULL); | |
1414 return filter->filterImageGPU(&proxy, wrap_texture(texture), ctx, result
, offset); | 1429 return filter->filterImageGPU(&proxy, wrap_texture(texture), ctx, result
, offset); |
1415 } else { | 1430 } else { |
1416 return false; | 1431 return false; |
1417 } | 1432 } |
1418 } | 1433 } |
1419 | 1434 |
1420 void SkGpuDevice::drawSprite(const SkDraw& draw, const SkBitmap& bitmap, | 1435 void SkGpuDevice::drawSprite(const SkDraw& draw, const SkBitmap& bitmap, |
1421 int left, int top, const SkPaint& paint) { | 1436 int left, int top, const SkPaint& paint) { |
1422 // drawSprite is defined to be in device coords. | 1437 // drawSprite is defined to be in device coords. |
1423 CHECK_SHOULD_DRAW(draw); | 1438 CHECK_SHOULD_DRAW(draw); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1455 left += offset.x(); | 1470 left += offset.x(); |
1456 top += offset.y(); | 1471 top += offset.y(); |
1457 } else { | 1472 } else { |
1458 return; | 1473 return; |
1459 } | 1474 } |
1460 } | 1475 } |
1461 | 1476 |
1462 GrPaint grPaint; | 1477 GrPaint grPaint; |
1463 grPaint.addColorTextureProcessor(texture, SkMatrix::I()); | 1478 grPaint.addColorTextureProcessor(texture, SkMatrix::I()); |
1464 | 1479 |
1465 SkPaint2GrPaintNoShader(this->context(), paint, SkColor2GrColorJustAlpha(pai
nt.getColor()), | 1480 SkPaint2GrPaintNoShader(this->context(), fRenderTarget, paint, |
1466 false, &grPaint); | 1481 SkColor2GrColorJustAlpha(paint.getColor()), false, &
grPaint); |
1467 | 1482 |
1468 fContext->drawNonAARectToRect(grPaint, | 1483 fContext->drawNonAARectToRect(fRenderTarget, |
| 1484 grPaint, |
1469 SkMatrix::I(), | 1485 SkMatrix::I(), |
1470 SkRect::MakeXYWH(SkIntToScalar(left), | 1486 SkRect::MakeXYWH(SkIntToScalar(left), |
1471 SkIntToScalar(top), | 1487 SkIntToScalar(top), |
1472 SkIntToScalar(w), | 1488 SkIntToScalar(w), |
1473 SkIntToScalar(h)), | 1489 SkIntToScalar(h)), |
1474 SkRect::MakeXYWH(0, | 1490 SkRect::MakeXYWH(0, |
1475 0, | 1491 0, |
1476 SK_Scalar1 * w / texture->wid
th(), | 1492 SK_Scalar1 * w / texture->wid
th(), |
1477 SK_Scalar1 * h / texture->hei
ght())); | 1493 SK_Scalar1 * h / texture->hei
ght())); |
1478 } | 1494 } |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1567 x += offset.fX; | 1583 x += offset.fX; |
1568 y += offset.fY; | 1584 y += offset.fY; |
1569 } else { | 1585 } else { |
1570 return; | 1586 return; |
1571 } | 1587 } |
1572 } | 1588 } |
1573 | 1589 |
1574 GrPaint grPaint; | 1590 GrPaint grPaint; |
1575 grPaint.addColorTextureProcessor(devTex, SkMatrix::I()); | 1591 grPaint.addColorTextureProcessor(devTex, SkMatrix::I()); |
1576 | 1592 |
1577 SkPaint2GrPaintNoShader(this->context(), paint, SkColor2GrColorJustAlpha(pai
nt.getColor()), | 1593 SkPaint2GrPaintNoShader(this->context(), fRenderTarget, paint, |
1578 false, &grPaint); | 1594 SkColor2GrColorJustAlpha(paint.getColor()), false, &
grPaint); |
1579 | 1595 |
1580 SkRect dstRect = SkRect::MakeXYWH(SkIntToScalar(x), | 1596 SkRect dstRect = SkRect::MakeXYWH(SkIntToScalar(x), |
1581 SkIntToScalar(y), | 1597 SkIntToScalar(y), |
1582 SkIntToScalar(w), | 1598 SkIntToScalar(w), |
1583 SkIntToScalar(h)); | 1599 SkIntToScalar(h)); |
1584 | 1600 |
1585 // The device being drawn may not fill up its texture (e.g. saveLayer uses a
pproximate | 1601 // The device being drawn may not fill up its texture (e.g. saveLayer uses a
pproximate |
1586 // scratch texture). | 1602 // scratch texture). |
1587 SkRect srcRect = SkRect::MakeWH(SK_Scalar1 * w / devTex->width(), | 1603 SkRect srcRect = SkRect::MakeWH(SK_Scalar1 * w / devTex->width(), |
1588 SK_Scalar1 * h / devTex->height()); | 1604 SK_Scalar1 * h / devTex->height()); |
1589 | 1605 |
1590 fContext->drawNonAARectToRect(grPaint, SkMatrix::I(), dstRect, srcRect); | 1606 fContext->drawNonAARectToRect(fRenderTarget, grPaint, SkMatrix::I(), dstRect
, srcRect); |
1591 } | 1607 } |
1592 | 1608 |
1593 bool SkGpuDevice::canHandleImageFilter(const SkImageFilter* filter) { | 1609 bool SkGpuDevice::canHandleImageFilter(const SkImageFilter* filter) { |
1594 return filter->canFilterImageGPU(); | 1610 return filter->canFilterImageGPU(); |
1595 } | 1611 } |
1596 | 1612 |
1597 bool SkGpuDevice::filterImage(const SkImageFilter* filter, const SkBitmap& src, | 1613 bool SkGpuDevice::filterImage(const SkImageFilter* filter, const SkBitmap& src, |
1598 const SkImageFilter::Context& ctx, | 1614 const SkImageFilter::Context& ctx, |
1599 SkBitmap* result, SkIPoint* offset) { | 1615 SkBitmap* result, SkIPoint* offset) { |
1600 // want explicitly our impl, so guard against a subclass of us overriding it | 1616 // want explicitly our impl, so guard against a subclass of us overriding it |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1641 // If both textures and vertex-colors are NULL, strokes hairlines with the p
aint's color. | 1657 // If both textures and vertex-colors are NULL, strokes hairlines with the p
aint's color. |
1642 if ((NULL == texs || NULL == paint.getShader()) && NULL == colors) { | 1658 if ((NULL == texs || NULL == paint.getShader()) && NULL == colors) { |
1643 | 1659 |
1644 texs = NULL; | 1660 texs = NULL; |
1645 | 1661 |
1646 SkPaint copy(paint); | 1662 SkPaint copy(paint); |
1647 copy.setStyle(SkPaint::kStroke_Style); | 1663 copy.setStyle(SkPaint::kStroke_Style); |
1648 copy.setStrokeWidth(0); | 1664 copy.setStrokeWidth(0); |
1649 | 1665 |
1650 // we ignore the shader if texs is null. | 1666 // we ignore the shader if texs is null. |
1651 SkPaint2GrPaintNoShader(this->context(), copy, SkColor2GrColor(copy.getC
olor()), | 1667 SkPaint2GrPaintNoShader(this->context(), fRenderTarget, copy, |
1652 NULL == colors, &grPaint); | 1668 SkColor2GrColor(copy.getColor()), NULL == colors
, &grPaint); |
1653 | 1669 |
1654 primType = kLines_GrPrimitiveType; | 1670 primType = kLines_GrPrimitiveType; |
1655 int triangleCount = 0; | 1671 int triangleCount = 0; |
1656 int n = (NULL == indices) ? vertexCount : indexCount; | 1672 int n = (NULL == indices) ? vertexCount : indexCount; |
1657 switch (vmode) { | 1673 switch (vmode) { |
1658 case SkCanvas::kTriangles_VertexMode: | 1674 case SkCanvas::kTriangles_VertexMode: |
1659 triangleCount = n / 3; | 1675 triangleCount = n / 3; |
1660 break; | 1676 break; |
1661 case SkCanvas::kTriangleStrip_VertexMode: | 1677 case SkCanvas::kTriangleStrip_VertexMode: |
1662 case SkCanvas::kTriangleFan_VertexMode: | 1678 case SkCanvas::kTriangleFan_VertexMode: |
(...skipping 18 matching lines...) Expand all Loading... |
1681 auxIndices[i + 3] = state.f2; | 1697 auxIndices[i + 3] = state.f2; |
1682 auxIndices[i + 4] = state.f2; | 1698 auxIndices[i + 4] = state.f2; |
1683 auxIndices[i + 5] = state.f0; | 1699 auxIndices[i + 5] = state.f0; |
1684 i += 6; | 1700 i += 6; |
1685 } | 1701 } |
1686 } else { | 1702 } else { |
1687 outIndices = indices; | 1703 outIndices = indices; |
1688 primType = gVertexMode2PrimitiveType[vmode]; | 1704 primType = gVertexMode2PrimitiveType[vmode]; |
1689 | 1705 |
1690 if (NULL == texs || NULL == paint.getShader()) { | 1706 if (NULL == texs || NULL == paint.getShader()) { |
1691 SkPaint2GrPaintNoShader(this->context(), paint, SkColor2GrColor(pain
t.getColor()), | 1707 SkPaint2GrPaintNoShader(this->context(), fRenderTarget, paint, |
| 1708 SkColor2GrColor(paint.getColor()), |
1692 NULL == colors, &grPaint); | 1709 NULL == colors, &grPaint); |
1693 } else { | 1710 } else { |
1694 SkPaint2GrPaintShader(this->context(), paint, *draw.fMatrix, NULL ==
colors, &grPaint); | 1711 SkPaint2GrPaintShader(this->context(), fRenderTarget, paint, *draw.f
Matrix, |
| 1712 NULL == colors, &grPaint); |
1695 } | 1713 } |
1696 } | 1714 } |
1697 | 1715 |
1698 #if 0 | 1716 #if 0 |
1699 if (xmode && texs && colors) { | 1717 if (xmode && texs && colors) { |
1700 if (!SkXfermode::IsMode(xmode, SkXfermode::kModulate_Mode)) { | 1718 if (!SkXfermode::IsMode(xmode, SkXfermode::kModulate_Mode)) { |
1701 SkDebugf("Unsupported vertex-color/texture xfer mode.\n"); | 1719 SkDebugf("Unsupported vertex-color/texture xfer mode.\n"); |
1702 return; | 1720 return; |
1703 } | 1721 } |
1704 } | 1722 } |
1705 #endif | 1723 #endif |
1706 | 1724 |
1707 SkAutoSTMalloc<128, GrColor> convertedColors(0); | 1725 SkAutoSTMalloc<128, GrColor> convertedColors(0); |
1708 if (colors) { | 1726 if (colors) { |
1709 // need to convert byte order and from non-PM to PM | 1727 // need to convert byte order and from non-PM to PM |
1710 convertedColors.reset(vertexCount); | 1728 convertedColors.reset(vertexCount); |
1711 SkColor color; | 1729 SkColor color; |
1712 for (int i = 0; i < vertexCount; ++i) { | 1730 for (int i = 0; i < vertexCount; ++i) { |
1713 color = colors[i]; | 1731 color = colors[i]; |
1714 if (paint.getAlpha() != 255) { | 1732 if (paint.getAlpha() != 255) { |
1715 color = SkColorSetA(color, SkMulDiv255Round(SkColorGetA(color),
paint.getAlpha())); | 1733 color = SkColorSetA(color, SkMulDiv255Round(SkColorGetA(color),
paint.getAlpha())); |
1716 } | 1734 } |
1717 convertedColors[i] = SkColor2GrColor(color); | 1735 convertedColors[i] = SkColor2GrColor(color); |
1718 } | 1736 } |
1719 colors = convertedColors.get(); | 1737 colors = convertedColors.get(); |
1720 } | 1738 } |
1721 fContext->drawVertices(grPaint, | 1739 fContext->drawVertices(fRenderTarget, |
| 1740 grPaint, |
1722 *draw.fMatrix, | 1741 *draw.fMatrix, |
1723 primType, | 1742 primType, |
1724 vertexCount, | 1743 vertexCount, |
1725 vertices, | 1744 vertices, |
1726 texs, | 1745 texs, |
1727 colors, | 1746 colors, |
1728 outIndices, | 1747 outIndices, |
1729 indexCount); | 1748 indexCount); |
1730 } | 1749 } |
1731 | 1750 |
1732 /////////////////////////////////////////////////////////////////////////////// | 1751 /////////////////////////////////////////////////////////////////////////////// |
1733 | 1752 |
1734 void SkGpuDevice::drawText(const SkDraw& draw, const void* text, | 1753 void SkGpuDevice::drawText(const SkDraw& draw, const void* text, |
1735 size_t byteLength, SkScalar x, SkScalar y, | 1754 size_t byteLength, SkScalar x, SkScalar y, |
1736 const SkPaint& paint) { | 1755 const SkPaint& paint) { |
1737 CHECK_SHOULD_DRAW(draw); | 1756 CHECK_SHOULD_DRAW(draw); |
1738 GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawText", fContext); | 1757 GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawText", fContext); |
1739 | 1758 |
1740 GrPaint grPaint; | 1759 GrPaint grPaint; |
1741 SkPaint2GrPaintShader(this->context(), paint, *draw.fMatrix, true, &grPaint)
; | 1760 SkPaint2GrPaintShader(this->context(), fRenderTarget, paint, *draw.fMatrix,
true, &grPaint); |
1742 | 1761 |
1743 SkDEBUGCODE(this->validate();) | 1762 SkDEBUGCODE(this->validate();) |
1744 | 1763 |
1745 if (!fTextContext->drawText(grPaint, paint, *draw.fMatrix, (const char *)tex
t, byteLength, x, | 1764 if (!fTextContext->drawText(fRenderTarget, grPaint, paint, *draw.fMatrix, (c
onst char *)text, |
1746 y)) { | 1765 byteLength, x, y)) { |
1747 // this will just call our drawPath() | 1766 // this will just call our drawPath() |
1748 draw.drawText_asPaths((const char*)text, byteLength, x, y, paint); | 1767 draw.drawText_asPaths((const char*)text, byteLength, x, y, paint); |
1749 } | 1768 } |
1750 } | 1769 } |
1751 | 1770 |
1752 void SkGpuDevice::drawPosText(const SkDraw& draw, const void* text, size_t byteL
ength, | 1771 void SkGpuDevice::drawPosText(const SkDraw& draw, const void* text, size_t byteL
ength, |
1753 const SkScalar pos[], int scalarsPerPos, | 1772 const SkScalar pos[], int scalarsPerPos, |
1754 const SkPoint& offset, const SkPaint& paint) { | 1773 const SkPoint& offset, const SkPaint& paint) { |
1755 GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawPosText", fContext); | 1774 GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice::drawPosText", fContext); |
1756 CHECK_SHOULD_DRAW(draw); | 1775 CHECK_SHOULD_DRAW(draw); |
1757 | 1776 |
1758 GrPaint grPaint; | 1777 GrPaint grPaint; |
1759 SkPaint2GrPaintShader(this->context(), paint, *draw.fMatrix, true, &grPaint)
; | 1778 SkPaint2GrPaintShader(this->context(), fRenderTarget, paint, *draw.fMatrix,
true, &grPaint); |
1760 | 1779 |
1761 SkDEBUGCODE(this->validate();) | 1780 SkDEBUGCODE(this->validate();) |
1762 | 1781 |
1763 if (!fTextContext->drawPosText(grPaint, paint, *draw.fMatrix, (const char *)
text, byteLength, | 1782 if (!fTextContext->drawPosText(fRenderTarget, grPaint, paint, *draw.fMatrix,
(const char *)text, |
1764 pos, scalarsPerPos, offset)) { | 1783 byteLength, pos, scalarsPerPos, offset)) { |
1765 // this will just call our drawPath() | 1784 // this will just call our drawPath() |
1766 draw.drawPosText_asPaths((const char*)text, byteLength, pos, scalarsPerP
os, offset, paint); | 1785 draw.drawPosText_asPaths((const char*)text, byteLength, pos, scalarsPerP
os, offset, paint); |
1767 } | 1786 } |
1768 } | 1787 } |
1769 | 1788 |
1770 void SkGpuDevice::drawTextOnPath(const SkDraw& draw, const void* text, | 1789 void SkGpuDevice::drawTextOnPath(const SkDraw& draw, const void* text, |
1771 size_t len, const SkPath& path, | 1790 size_t len, const SkPath& path, |
1772 const SkMatrix* m, const SkPaint& paint) { | 1791 const SkMatrix* m, const SkPaint& paint) { |
1773 CHECK_SHOULD_DRAW(draw); | 1792 CHECK_SHOULD_DRAW(draw); |
1774 | 1793 |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1895 #endif | 1914 #endif |
1896 } | 1915 } |
1897 | 1916 |
1898 SkImageFilter::Cache* SkGpuDevice::getImageFilterCache() { | 1917 SkImageFilter::Cache* SkGpuDevice::getImageFilterCache() { |
1899 // We always return a transient cache, so it is freed after each | 1918 // We always return a transient cache, so it is freed after each |
1900 // filter traversal. | 1919 // filter traversal. |
1901 return SkImageFilter::Cache::Create(kDefaultImageFilterCacheSize); | 1920 return SkImageFilter::Cache::Create(kDefaultImageFilterCacheSize); |
1902 } | 1921 } |
1903 | 1922 |
1904 #endif | 1923 #endif |
OLD | NEW |