| 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 |