| 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/GrTextureDomainEffect.h" | 10 #include "effects/GrTextureDomainEffect.h" |
| (...skipping 20 matching lines...) Expand all Loading... |
| 31 extern bool (*gShouldDrawProc)(); | 31 extern bool (*gShouldDrawProc)(); |
| 32 #define CHECK_SHOULD_DRAW(draw, forceI) \ | 32 #define CHECK_SHOULD_DRAW(draw, forceI) \ |
| 33 do { \ | 33 do { \ |
| 34 if (gShouldDrawProc && !gShouldDrawProc()) return; \ | 34 if (gShouldDrawProc && !gShouldDrawProc()) return; \ |
| 35 this->prepareDraw(draw, forceI); \ | 35 this->prepareDraw(draw, forceI); \ |
| 36 } while (0) | 36 } while (0) |
| 37 #else | 37 #else |
| 38 #define CHECK_SHOULD_DRAW(draw, forceI) this->prepareDraw(draw, forceI) | 38 #define CHECK_SHOULD_DRAW(draw, forceI) this->prepareDraw(draw, forceI) |
| 39 #endif | 39 #endif |
| 40 | 40 |
| 41 // we use the same effect slot on GrPaint for bitmaps and shaders (since drawBit
map, drawSprite, | |
| 42 // and drawDevice ignore SkShader) | |
| 43 enum { | |
| 44 kShaderEffectIdx = 0, | |
| 45 kBitmapEffectIdx = 0, | |
| 46 kColorFilterEffectIdx = 1, | |
| 47 kXfermodeEffectIdx = 2, | |
| 48 }; | |
| 49 | |
| 50 // This constant represents the screen alignment criterion in texels for | 41 // This constant represents the screen alignment criterion in texels for |
| 51 // requiring texture domain clamping to prevent color bleeding when drawing | 42 // requiring texture domain clamping to prevent color bleeding when drawing |
| 52 // a sub region of a larger source image. | 43 // a sub region of a larger source image. |
| 53 #define COLOR_BLEED_TOLERANCE SkFloatToScalar(0.001f) | 44 #define COLOR_BLEED_TOLERANCE SkFloatToScalar(0.001f) |
| 54 | 45 |
| 55 #define DO_DEFERRED_CLEAR() \ | 46 #define DO_DEFERRED_CLEAR() \ |
| 56 do { \ | 47 do { \ |
| 57 if (fNeedClear) { \ | 48 if (fNeedClear) { \ |
| 58 this->clear(SK_ColorTRANSPARENT); \ | 49 this->clear(SK_ColorTRANSPARENT); \ |
| 59 } \ | 50 } \ |
| (...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 435 fContext->setClip(&fClipData); | 426 fContext->setClip(&fClipData); |
| 436 | 427 |
| 437 DO_DEFERRED_CLEAR(); | 428 DO_DEFERRED_CLEAR(); |
| 438 } | 429 } |
| 439 | 430 |
| 440 GrRenderTarget* SkGpuDevice::accessRenderTarget() { | 431 GrRenderTarget* SkGpuDevice::accessRenderTarget() { |
| 441 DO_DEFERRED_CLEAR(); | 432 DO_DEFERRED_CLEAR(); |
| 442 return fRenderTarget; | 433 return fRenderTarget; |
| 443 } | 434 } |
| 444 | 435 |
| 445 bool SkGpuDevice::bindDeviceAsTexture(GrPaint* paint) { | |
| 446 GrTexture* texture = fRenderTarget->asTexture(); | |
| 447 if (NULL != texture) { | |
| 448 paint->colorStage(kBitmapEffectIdx)->setEffect( | |
| 449 GrSimpleTextureEffect::Create(texture, SkMatrix::I()))->unref(); | |
| 450 return true; | |
| 451 } | |
| 452 return false; | |
| 453 } | |
| 454 | |
| 455 /////////////////////////////////////////////////////////////////////////////// | 436 /////////////////////////////////////////////////////////////////////////////// |
| 456 | 437 |
| 457 SK_COMPILE_ASSERT(SkShader::kNone_BitmapType == 0, shader_type_mismatch); | 438 SK_COMPILE_ASSERT(SkShader::kNone_BitmapType == 0, shader_type_mismatch); |
| 458 SK_COMPILE_ASSERT(SkShader::kDefault_BitmapType == 1, shader_type_mismatch); | 439 SK_COMPILE_ASSERT(SkShader::kDefault_BitmapType == 1, shader_type_mismatch); |
| 459 SK_COMPILE_ASSERT(SkShader::kRadial_BitmapType == 2, shader_type_mismatch); | 440 SK_COMPILE_ASSERT(SkShader::kRadial_BitmapType == 2, shader_type_mismatch); |
| 460 SK_COMPILE_ASSERT(SkShader::kSweep_BitmapType == 3, shader_type_mismatch); | 441 SK_COMPILE_ASSERT(SkShader::kSweep_BitmapType == 3, shader_type_mismatch); |
| 461 SK_COMPILE_ASSERT(SkShader::kTwoPointRadial_BitmapType == 4, | 442 SK_COMPILE_ASSERT(SkShader::kTwoPointRadial_BitmapType == 4, |
| 462 shader_type_mismatch); | 443 shader_type_mismatch); |
| 463 SK_COMPILE_ASSERT(SkShader::kTwoPointConical_BitmapType == 5, | 444 SK_COMPILE_ASSERT(SkShader::kTwoPointConical_BitmapType == 5, |
| 464 shader_type_mismatch); | 445 shader_type_mismatch); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 482 grPaint->setDither(skPaint.isDither()); | 463 grPaint->setDither(skPaint.isDither()); |
| 483 grPaint->setAntiAlias(skPaint.isAntiAlias()); | 464 grPaint->setAntiAlias(skPaint.isAntiAlias()); |
| 484 | 465 |
| 485 SkXfermode::Coeff sm; | 466 SkXfermode::Coeff sm; |
| 486 SkXfermode::Coeff dm; | 467 SkXfermode::Coeff dm; |
| 487 | 468 |
| 488 SkXfermode* mode = skPaint.getXfermode(); | 469 SkXfermode* mode = skPaint.getXfermode(); |
| 489 GrEffectRef* xferEffect = NULL; | 470 GrEffectRef* xferEffect = NULL; |
| 490 if (SkXfermode::AsNewEffectOrCoeff(mode, dev->context(), &xferEffect, &sm, &
dm)) { | 471 if (SkXfermode::AsNewEffectOrCoeff(mode, dev->context(), &xferEffect, &sm, &
dm)) { |
| 491 if (NULL != xferEffect) { | 472 if (NULL != xferEffect) { |
| 492 grPaint->colorStage(kXfermodeEffectIdx)->setEffect(xferEffect)->unre
f(); | 473 grPaint->addColorEffect(xferEffect)->unref(); |
| 493 sm = SkXfermode::kOne_Coeff; | 474 sm = SkXfermode::kOne_Coeff; |
| 494 dm = SkXfermode::kZero_Coeff; | 475 dm = SkXfermode::kZero_Coeff; |
| 495 } | 476 } |
| 496 } else { | 477 } else { |
| 497 //SkDEBUGCODE(SkDebugf("Unsupported xfer mode.\n");) | 478 //SkDEBUGCODE(SkDebugf("Unsupported xfer mode.\n");) |
| 498 #if 0 | 479 #if 0 |
| 499 return false; | 480 return false; |
| 500 #else | 481 #else |
| 501 // Fall back to src-over | 482 // Fall back to src-over |
| 502 sm = SkXfermode::kOne_Coeff; | 483 sm = SkXfermode::kOne_Coeff; |
| 503 dm = SkXfermode::kISA_Coeff; | 484 dm = SkXfermode::kISA_Coeff; |
| 504 #endif | 485 #endif |
| 505 } | 486 } |
| 506 grPaint->setBlendFunc(sk_blend_to_grblend(sm), sk_blend_to_grblend(dm)); | 487 grPaint->setBlendFunc(sk_blend_to_grblend(sm), sk_blend_to_grblend(dm)); |
| 507 | 488 |
| 508 if (justAlpha) { | 489 if (justAlpha) { |
| 509 uint8_t alpha = skPaint.getAlpha(); | 490 uint8_t alpha = skPaint.getAlpha(); |
| 510 grPaint->setColor(GrColorPackRGBA(alpha, alpha, alpha, alpha)); | 491 grPaint->setColor(GrColorPackRGBA(alpha, alpha, alpha, alpha)); |
| 511 // justAlpha is currently set to true only if there is a texture, | 492 // justAlpha is currently set to true only if there is a texture, |
| 512 // so constantColor should not also be true. | 493 // so constantColor should not also be true. |
| 513 GrAssert(!constantColor); | 494 GrAssert(!constantColor); |
| 514 } else { | 495 } else { |
| 515 grPaint->setColor(SkColor2GrColor(skPaint.getColor())); | 496 grPaint->setColor(SkColor2GrColor(skPaint.getColor())); |
| 516 GrAssert(!grPaint->isColorStageEnabled(kShaderEffectIdx)); | |
| 517 } | 497 } |
| 518 | 498 |
| 519 SkColorFilter* colorFilter = skPaint.getColorFilter(); | 499 SkColorFilter* colorFilter = skPaint.getColorFilter(); |
| 520 if (NULL != colorFilter) { | 500 if (NULL != colorFilter) { |
| 521 // if the source color is a constant then apply the filter here once rat
her than per pixel | 501 // if the source color is a constant then apply the filter here once rat
her than per pixel |
| 522 // in a shader. | 502 // in a shader. |
| 523 if (constantColor) { | 503 if (constantColor) { |
| 524 SkColor filtered = colorFilter->filterColor(skPaint.getColor()); | 504 SkColor filtered = colorFilter->filterColor(skPaint.getColor()); |
| 525 grPaint->setColor(SkColor2GrColor(filtered)); | 505 grPaint->setColor(SkColor2GrColor(filtered)); |
| 526 } else { | 506 } else { |
| 527 SkAutoTUnref<GrEffectRef> effect(colorFilter->asNewEffect(dev->conte
xt())); | 507 SkAutoTUnref<GrEffectRef> effect(colorFilter->asNewEffect(dev->conte
xt())); |
| 528 if (NULL != effect.get()) { | 508 if (NULL != effect.get()) { |
| 529 grPaint->colorStage(kColorFilterEffectIdx)->setEffect(effect); | 509 grPaint->addColorEffect(effect); |
| 530 } else { | 510 } else { |
| 531 // TODO: rewrite this using asNewEffect() | 511 // TODO: rewrite this using asNewEffect() |
| 532 SkColor color; | 512 SkColor color; |
| 533 SkXfermode::Mode filterMode; | 513 SkXfermode::Mode filterMode; |
| 534 if (colorFilter->asColorMode(&color, &filterMode)) { | 514 if (colorFilter->asColorMode(&color, &filterMode)) { |
| 535 grPaint->setXfermodeColorFilter(filterMode, SkColor2GrColor(
color)); | 515 grPaint->setXfermodeColorFilter(filterMode, SkColor2GrColor(
color)); |
| 536 } | 516 } |
| 537 } | 517 } |
| 538 } | 518 } |
| 539 } | 519 } |
| 540 | 520 |
| 541 return true; | 521 return true; |
| 542 } | 522 } |
| 543 | 523 |
| 544 // This function is similar to skPaint2GrPaintNoShader but also converts | 524 // This function is similar to skPaint2GrPaintNoShader but also converts |
| 545 // skPaint's shader to a GrTexture/GrEffectStage if possible. The texture to | 525 // skPaint's shader to a GrTexture/GrEffectStage if possible. The texture to |
| 546 // be used is set on grPaint and returned in param act. constantColor has the | 526 // be used is set on grPaint and returned in param act. constantColor has the |
| 547 // same meaning as in skPaint2GrPaintNoShader. | 527 // same meaning as in skPaint2GrPaintNoShader. |
| 548 inline bool skPaint2GrPaintShader(SkGpuDevice* dev, | 528 inline bool skPaint2GrPaintShader(SkGpuDevice* dev, |
| 549 const SkPaint& skPaint, | 529 const SkPaint& skPaint, |
| 550 bool constantColor, | 530 bool constantColor, |
| 551 GrPaint* grPaint) { | 531 GrPaint* grPaint) { |
| 552 SkShader* shader = skPaint.getShader(); | 532 SkShader* shader = skPaint.getShader(); |
| 553 if (NULL == shader) { | 533 if (NULL == shader) { |
| 554 return skPaint2GrPaintNoShader(dev, skPaint, false, constantColor, grPai
nt); | 534 return skPaint2GrPaintNoShader(dev, skPaint, false, constantColor, grPai
nt); |
| 555 } else if (!skPaint2GrPaintNoShader(dev, skPaint, true, false, grPaint)) { | |
| 556 return false; | |
| 557 } | 535 } |
| 558 | 536 |
| 537 // setup the shader as the first color effect on the paint |
| 559 SkAutoTUnref<GrEffectRef> effect(shader->asNewEffect(dev->context(), skPaint
)); | 538 SkAutoTUnref<GrEffectRef> effect(shader->asNewEffect(dev->context(), skPaint
)); |
| 560 if (NULL != effect.get()) { | 539 if (NULL != effect.get()) { |
| 561 grPaint->colorStage(kShaderEffectIdx)->setEffect(effect); | 540 grPaint->addColorEffect(effect); |
| 562 return true; | 541 // Now setup the rest of the paint. |
| 542 return skPaint2GrPaintNoShader(dev, skPaint, true, false, grPaint); |
| 543 } else { |
| 544 // We still don't have SkColorShader::asNewEffect() implemented. |
| 545 SkShader::GradientInfo info; |
| 546 SkColor color; |
| 547 |
| 548 info.fColors = &color; |
| 549 info.fColorOffsets = NULL; |
| 550 info.fColorCount = 1; |
| 551 if (SkShader::kColor_GradientType == shader->asAGradient(&info)) { |
| 552 SkPaint copy(skPaint); |
| 553 copy.setShader(NULL); |
| 554 // modulate the paint alpha by the shader's solid color alpha |
| 555 U8CPU newA = SkMulDiv255Round(SkColorGetA(color), copy.getAlpha()); |
| 556 copy.setColor(SkColorSetA(color, newA)); |
| 557 return skPaint2GrPaintNoShader(dev, copy, false, constantColor, grPa
int); |
| 558 } else { |
| 559 return false; |
| 560 } |
| 563 } | 561 } |
| 564 | |
| 565 // We still don't have SkColorShader::asNewEffect() implemented. | |
| 566 SkShader::GradientInfo info; | |
| 567 SkColor color; | |
| 568 | |
| 569 info.fColors = &color; | |
| 570 info.fColorOffsets = NULL; | |
| 571 info.fColorCount = 1; | |
| 572 if (SkShader::kColor_GradientType == shader->asAGradient(&info)) { | |
| 573 SkPaint copy(skPaint); | |
| 574 copy.setShader(NULL); | |
| 575 // modulate the paint alpha by the shader's solid color alpha | |
| 576 U8CPU newA = SkMulDiv255Round(SkColorGetA(color), copy.getAlpha()); | |
| 577 copy.setColor(SkColorSetA(color, newA)); | |
| 578 return skPaint2GrPaintNoShader(dev, copy, false, constantColor, grPaint)
; | |
| 579 } | |
| 580 return false; | |
| 581 } | 562 } |
| 582 } | 563 } |
| 583 | 564 |
| 584 /////////////////////////////////////////////////////////////////////////////// | 565 /////////////////////////////////////////////////////////////////////////////// |
| 585 void SkGpuDevice::clear(SkColor color) { | 566 void SkGpuDevice::clear(SkColor color) { |
| 586 SkIRect rect = SkIRect::MakeWH(this->width(), this->height()); | 567 SkIRect rect = SkIRect::MakeWH(this->width(), this->height()); |
| 587 fContext->clear(&rect, SkColor2GrColor(color), fRenderTarget); | 568 fContext->clear(&rect, SkColor2GrColor(color), fRenderTarget); |
| 588 fNeedClear = false; | 569 fNeedClear = false; |
| 589 } | 570 } |
| 590 | 571 |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 762 /////////////////////////////////////////////////////////////////////////////// | 743 /////////////////////////////////////////////////////////////////////////////// |
| 763 | 744 |
| 764 // helpers for applying mask filters | 745 // helpers for applying mask filters |
| 765 namespace { | 746 namespace { |
| 766 | 747 |
| 767 // Draw a mask using the supplied paint. Since the coverage/geometry | 748 // Draw a mask using the supplied paint. Since the coverage/geometry |
| 768 // is already burnt into the mask this boils down to a rect draw. | 749 // is already burnt into the mask this boils down to a rect draw. |
| 769 // Return true if the mask was successfully drawn. | 750 // Return true if the mask was successfully drawn. |
| 770 bool draw_mask(GrContext* context, const SkRect& maskRect, | 751 bool draw_mask(GrContext* context, const SkRect& maskRect, |
| 771 GrPaint* grp, GrTexture* mask) { | 752 GrPaint* grp, GrTexture* mask) { |
| 772 | |
| 773 GrContext::AutoMatrix am; | 753 GrContext::AutoMatrix am; |
| 774 if (!am.setIdentity(context, grp)) { | 754 if (!am.setIdentity(context, grp)) { |
| 775 return false; | 755 return false; |
| 776 } | 756 } |
| 777 | 757 |
| 778 static const int MASK_IDX = GrPaint::kMaxCoverageStages - 1; | |
| 779 // we assume the last mask index is available for use | |
| 780 GrAssert(!grp->isCoverageStageEnabled(MASK_IDX)); | |
| 781 | |
| 782 SkMatrix matrix; | 758 SkMatrix matrix; |
| 783 matrix.setTranslate(-maskRect.fLeft, -maskRect.fTop); | 759 matrix.setTranslate(-maskRect.fLeft, -maskRect.fTop); |
| 784 matrix.postIDiv(mask->width(), mask->height()); | 760 matrix.postIDiv(mask->width(), mask->height()); |
| 785 | 761 |
| 786 grp->coverageStage(MASK_IDX)->reset(); | 762 grp->addCoverageEffect(GrSimpleTextureEffect::Create(mask, matrix))->unref()
; |
| 787 grp->coverageStage(MASK_IDX)->setEffect(GrSimpleTextureEffect::Create(mask,
matrix))->unref(); | |
| 788 context->drawRect(*grp, maskRect); | 763 context->drawRect(*grp, maskRect); |
| 789 return true; | 764 return true; |
| 790 } | 765 } |
| 791 | 766 |
| 792 bool draw_with_mask_filter(GrContext* context, const SkPath& devPath, | 767 bool draw_with_mask_filter(GrContext* context, const SkPath& devPath, |
| 793 SkMaskFilter* filter, const SkRegion& clip, SkBounder
* bounder, | 768 SkMaskFilter* filter, const SkRegion& clip, SkBounder
* bounder, |
| 794 GrPaint* grp, SkPaint::Style style) { | 769 GrPaint* grp, SkPaint::Style style) { |
| 795 SkMask srcM, dstM; | 770 SkMask srcM, dstM; |
| 796 | 771 |
| 797 if (!SkDraw::DrawToMask(devPath, &clip.getBounds(), filter, &context->getMat
rix(), &srcM, | 772 if (!SkDraw::DrawToMask(devPath, &clip.getBounds(), filter, &context->getMat
rix(), &srcM, |
| (...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1162 SkMatrix drawMatrix; | 1137 SkMatrix drawMatrix; |
| 1163 drawMatrix.setConcat(fContext->getMatrix(), newM); | 1138 drawMatrix.setConcat(fContext->getMatrix(), newM); |
| 1164 SkDraw transformedDraw(draw); | 1139 SkDraw transformedDraw(draw); |
| 1165 transformedDraw.fMatrix = &drawMatrix; | 1140 transformedDraw.fMatrix = &drawMatrix; |
| 1166 | 1141 |
| 1167 this->drawRect(transformedDraw, srcRect, paintWithTexture); | 1142 this->drawRect(transformedDraw, srcRect, paintWithTexture); |
| 1168 | 1143 |
| 1169 return; | 1144 return; |
| 1170 } | 1145 } |
| 1171 | 1146 |
| 1172 GrPaint grPaint; | |
| 1173 | |
| 1174 bool alphaOnly = !(SkBitmap::kA8_Config == bitmap.config()); | |
| 1175 if (!skPaint2GrPaintNoShader(this, paint, alphaOnly, false, &grPaint)) { | |
| 1176 return; | |
| 1177 } | |
| 1178 GrTextureParams params; | 1147 GrTextureParams params; |
| 1179 params.setBilerp(paint.isFilterBitmap()); | 1148 params.setBilerp(paint.isFilterBitmap()); |
| 1180 | 1149 |
| 1181 if (!this->shouldTileBitmap(bitmap, params, srcRectPtr)) { | 1150 if (!this->shouldTileBitmap(bitmap, params, srcRectPtr)) { |
| 1182 // take the simple case | 1151 // take the simple case |
| 1183 this->internalDrawBitmap(bitmap, srcRect, m, params, &grPaint); | 1152 this->internalDrawBitmap(bitmap, srcRect, m, params, paint); |
| 1184 } else { | 1153 } else { |
| 1185 this->drawTiledBitmap(bitmap, srcRect, m, params, &grPaint); | 1154 this->drawTiledBitmap(bitmap, srcRect, m, params, paint); |
| 1186 } | 1155 } |
| 1187 } | 1156 } |
| 1188 | 1157 |
| 1189 // Break 'bitmap' into several tiles to draw it since it has already | 1158 // Break 'bitmap' into several tiles to draw it since it has already |
| 1190 // been determined to be too large to fit in VRAM | 1159 // been determined to be too large to fit in VRAM |
| 1191 void SkGpuDevice::drawTiledBitmap(const SkBitmap& bitmap, | 1160 void SkGpuDevice::drawTiledBitmap(const SkBitmap& bitmap, |
| 1192 const SkRect& srcRect, | 1161 const SkRect& srcRect, |
| 1193 const SkMatrix& m, | 1162 const SkMatrix& m, |
| 1194 const GrTextureParams& params, | 1163 const GrTextureParams& params, |
| 1195 GrPaint* grPaint) { | 1164 const SkPaint& paint) { |
| 1196 const int maxTextureSize = fContext->getMaxTextureSize(); | 1165 const int maxTextureSize = fContext->getMaxTextureSize(); |
| 1197 | 1166 |
| 1198 int tileSize = determine_tile_size(bitmap, srcRect, maxTextureSize); | 1167 int tileSize = determine_tile_size(bitmap, srcRect, maxTextureSize); |
| 1199 | 1168 |
| 1200 // compute clip bounds in local coordinates | 1169 // compute clip bounds in local coordinates |
| 1201 SkRect clipRect; | 1170 SkRect clipRect; |
| 1202 { | 1171 { |
| 1203 const GrRenderTarget* rt = fContext->getRenderTarget(); | 1172 const GrRenderTarget* rt = fContext->getRenderTarget(); |
| 1204 clipRect.setWH(SkIntToScalar(rt->width()), SkIntToScalar(rt->height())); | 1173 clipRect.setWH(SkIntToScalar(rt->width()), SkIntToScalar(rt->height())); |
| 1205 if (!fContext->getClip()->fClipStack->intersectRectWithClip(&clipRect))
{ | 1174 if (!fContext->getClip()->fClipStack->intersectRectWithClip(&clipRect))
{ |
| (...skipping 28 matching lines...) Expand all Loading... |
| 1234 SkBitmap tmpB; | 1203 SkBitmap tmpB; |
| 1235 SkIRect iTileR; | 1204 SkIRect iTileR; |
| 1236 tileR.roundOut(&iTileR); | 1205 tileR.roundOut(&iTileR); |
| 1237 if (bitmap.extractSubset(&tmpB, iTileR)) { | 1206 if (bitmap.extractSubset(&tmpB, iTileR)) { |
| 1238 // now offset it to make it "local" to our tmp bitmap | 1207 // now offset it to make it "local" to our tmp bitmap |
| 1239 tileR.offset(SkIntToScalar(-iTileR.fLeft), SkIntToScalar(-iTileR
.fTop)); | 1208 tileR.offset(SkIntToScalar(-iTileR.fLeft), SkIntToScalar(-iTileR
.fTop)); |
| 1240 SkMatrix tmpM(m); | 1209 SkMatrix tmpM(m); |
| 1241 tmpM.preTranslate(SkIntToScalar(iTileR.fLeft), | 1210 tmpM.preTranslate(SkIntToScalar(iTileR.fLeft), |
| 1242 SkIntToScalar(iTileR.fTop)); | 1211 SkIntToScalar(iTileR.fTop)); |
| 1243 | 1212 |
| 1244 this->internalDrawBitmap(tmpB, tileR, tmpM, params, grPaint); | 1213 this->internalDrawBitmap(tmpB, tileR, tmpM, params, paint); |
| 1245 } | 1214 } |
| 1246 } | 1215 } |
| 1247 } | 1216 } |
| 1248 } | 1217 } |
| 1249 | 1218 |
| 1250 namespace { | 1219 namespace { |
| 1251 | 1220 |
| 1252 bool hasAlignedSamples(const SkRect& srcRect, const SkRect& transformedRect) { | 1221 bool hasAlignedSamples(const SkRect& srcRect, const SkRect& transformedRect) { |
| 1253 // detect pixel disalignment | 1222 // detect pixel disalignment |
| 1254 if (SkScalarAbs(SkScalarRoundToScalar(transformedRect.left()) - | 1223 if (SkScalarAbs(SkScalarRoundToScalar(transformedRect.left()) - |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1294 * This is called by drawBitmap(), which has to handle images that may be too | 1263 * This is called by drawBitmap(), which has to handle images that may be too |
| 1295 * large to be represented by a single texture. | 1264 * large to be represented by a single texture. |
| 1296 * | 1265 * |
| 1297 * internalDrawBitmap assumes that the specified bitmap will fit in a texture | 1266 * internalDrawBitmap assumes that the specified bitmap will fit in a texture |
| 1298 * and that non-texture portion of the GrPaint has already been setup. | 1267 * and that non-texture portion of the GrPaint has already been setup. |
| 1299 */ | 1268 */ |
| 1300 void SkGpuDevice::internalDrawBitmap(const SkBitmap& bitmap, | 1269 void SkGpuDevice::internalDrawBitmap(const SkBitmap& bitmap, |
| 1301 const SkRect& srcRect, | 1270 const SkRect& srcRect, |
| 1302 const SkMatrix& m, | 1271 const SkMatrix& m, |
| 1303 const GrTextureParams& params, | 1272 const GrTextureParams& params, |
| 1304 GrPaint* grPaint) { | 1273 const SkPaint& paint) { |
| 1305 SkASSERT(bitmap.width() <= fContext->getMaxTextureSize() && | 1274 SkASSERT(bitmap.width() <= fContext->getMaxTextureSize() && |
| 1306 bitmap.height() <= fContext->getMaxTextureSize()); | 1275 bitmap.height() <= fContext->getMaxTextureSize()); |
| 1307 | 1276 |
| 1308 GrTexture* texture; | 1277 GrTexture* texture; |
| 1309 SkAutoCachedTexture act(this, bitmap, ¶ms, &texture); | 1278 SkAutoCachedTexture act(this, bitmap, ¶ms, &texture); |
| 1310 if (NULL == texture) { | 1279 if (NULL == texture) { |
| 1311 return; | 1280 return; |
| 1312 } | 1281 } |
| 1313 | 1282 |
| 1314 GrRect dstRect(srcRect); | 1283 GrRect dstRect(srcRect); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1364 } | 1333 } |
| 1365 textureDomain.setLTRB(left, top, right, bottom); | 1334 textureDomain.setLTRB(left, top, right, bottom); |
| 1366 effect.reset(GrTextureDomainEffect::Create(texture, | 1335 effect.reset(GrTextureDomainEffect::Create(texture, |
| 1367 SkMatrix::I(), | 1336 SkMatrix::I(), |
| 1368 textureDomain, | 1337 textureDomain, |
| 1369 GrTextureDomainEffect::kClamp
_WrapMode, | 1338 GrTextureDomainEffect::kClamp
_WrapMode, |
| 1370 params.isBilerp())); | 1339 params.isBilerp())); |
| 1371 } else { | 1340 } else { |
| 1372 effect.reset(GrSimpleTextureEffect::Create(texture, SkMatrix::I(), param
s)); | 1341 effect.reset(GrSimpleTextureEffect::Create(texture, SkMatrix::I(), param
s)); |
| 1373 } | 1342 } |
| 1374 grPaint->colorStage(kBitmapEffectIdx)->setEffect(effect); | 1343 |
| 1375 fContext->drawRectToRect(*grPaint, dstRect, paintRect, &m); | 1344 // Construct a GrPaint by setting the bitmap texture as the first effect and
then configuring |
| 1345 // the rest from the SkPaint. |
| 1346 GrPaint grPaint; |
| 1347 grPaint.addColorEffect(effect); |
| 1348 bool alphaOnly = !(SkBitmap::kA8_Config == bitmap.config()); |
| 1349 if (!skPaint2GrPaintNoShader(this, paint, alphaOnly, false, &grPaint)) { |
| 1350 return; |
| 1351 } |
| 1352 |
| 1353 fContext->drawRectToRect(grPaint, dstRect, paintRect, &m); |
| 1376 } | 1354 } |
| 1377 | 1355 |
| 1378 static bool filter_texture(SkDevice* device, GrContext* context, | 1356 static bool filter_texture(SkDevice* device, GrContext* context, |
| 1379 GrTexture* texture, SkImageFilter* filter, | 1357 GrTexture* texture, SkImageFilter* filter, |
| 1380 int w, int h, SkBitmap* result, SkIPoint* offset) { | 1358 int w, int h, SkBitmap* result, SkIPoint* offset) { |
| 1381 GrAssert(filter); | 1359 GrAssert(filter); |
| 1382 SkDeviceImageFilterProxy proxy(device); | 1360 SkDeviceImageFilterProxy proxy(device); |
| 1383 | 1361 |
| 1384 if (filter->canFilterImageGPU()) { | 1362 if (filter->canFilterImageGPU()) { |
| 1385 // Save the render target and set it to NULL, so we don't accidentally d
raw to it in the | 1363 // Save the render target and set it to NULL, so we don't accidentally d
raw to it in the |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1397 CHECK_SHOULD_DRAW(draw, true); | 1375 CHECK_SHOULD_DRAW(draw, true); |
| 1398 | 1376 |
| 1399 SkAutoLockPixels alp(bitmap, !bitmap.getTexture()); | 1377 SkAutoLockPixels alp(bitmap, !bitmap.getTexture()); |
| 1400 if (!bitmap.getTexture() && !bitmap.readyToDraw()) { | 1378 if (!bitmap.getTexture() && !bitmap.readyToDraw()) { |
| 1401 return; | 1379 return; |
| 1402 } | 1380 } |
| 1403 | 1381 |
| 1404 int w = bitmap.width(); | 1382 int w = bitmap.width(); |
| 1405 int h = bitmap.height(); | 1383 int h = bitmap.height(); |
| 1406 | 1384 |
| 1407 GrPaint grPaint; | |
| 1408 if(!skPaint2GrPaintNoShader(this, paint, true, false, &grPaint)) { | |
| 1409 return; | |
| 1410 } | |
| 1411 | |
| 1412 GrEffectStage* stage = grPaint.colorStage(kBitmapEffectIdx); | |
| 1413 | |
| 1414 GrTexture* texture; | 1385 GrTexture* texture; |
| 1415 stage->reset(); | |
| 1416 // draw sprite uses the default texture params | 1386 // draw sprite uses the default texture params |
| 1417 SkAutoCachedTexture act(this, bitmap, NULL, &texture); | 1387 SkAutoCachedTexture act(this, bitmap, NULL, &texture); |
| 1418 grPaint.colorStage(kBitmapEffectIdx)->setEffect( | |
| 1419 GrSimpleTextureEffect::Create(texture, SkMatrix::I()))->unref(); | |
| 1420 | 1388 |
| 1421 SkImageFilter* filter = paint.getImageFilter(); | 1389 SkImageFilter* filter = paint.getImageFilter(); |
| 1422 SkIPoint offset = SkIPoint::Make(0, 0); | 1390 SkIPoint offset = SkIPoint::Make(0, 0); |
| 1423 if (NULL != filter) { | 1391 if (NULL != filter) { |
| 1424 SkBitmap filterBitmap; | 1392 SkBitmap filterBitmap; |
| 1425 if (filter_texture(this, fContext, texture, filter, w, h, &filterBitmap,
&offset)) { | 1393 if (filter_texture(this, fContext, texture, filter, w, h, &filterBitmap,
&offset)) { |
| 1426 grPaint.colorStage(kBitmapEffectIdx)->setEffect( | 1394 texture = (GrTexture*) filterBitmap.getTexture(); |
| 1427 GrSimpleTextureEffect::Create(filterBitmap.getTexture(), SkMatri
x::I()))->unref(); | |
| 1428 texture = filterBitmap.getTexture(); | |
| 1429 w = filterBitmap.width(); | 1395 w = filterBitmap.width(); |
| 1430 h = filterBitmap.height(); | 1396 h = filterBitmap.height(); |
| 1431 } | 1397 } |
| 1432 } | 1398 } |
| 1433 | 1399 |
| 1400 GrPaint grPaint; |
| 1401 grPaint.addColorTextureEffect(texture, SkMatrix::I()); |
| 1402 |
| 1403 if(!skPaint2GrPaintNoShader(this, paint, true, false, &grPaint)) { |
| 1404 return; |
| 1405 } |
| 1406 |
| 1434 fContext->drawRectToRect(grPaint, | 1407 fContext->drawRectToRect(grPaint, |
| 1435 GrRect::MakeXYWH(SkIntToScalar(left), | 1408 GrRect::MakeXYWH(SkIntToScalar(left), |
| 1436 SkIntToScalar(top), | 1409 SkIntToScalar(top), |
| 1437 SkIntToScalar(w), | 1410 SkIntToScalar(w), |
| 1438 SkIntToScalar(h)), | 1411 SkIntToScalar(h)), |
| 1439 GrRect::MakeXYWH(SkIntToScalar(offset.fX), | 1412 GrRect::MakeXYWH(SkIntToScalar(offset.fX), |
| 1440 SkIntToScalar(offset.fY), | 1413 SkIntToScalar(offset.fY), |
| 1441 SK_Scalar1 * w / texture->width(), | 1414 SK_Scalar1 * w / texture->width(), |
| 1442 SK_Scalar1 * h / texture->height()
)); | 1415 SK_Scalar1 * h / texture->height()
)); |
| 1443 } | 1416 } |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1477 // clear of the source device must occur before CHECK_SHOULD_DRAW | 1450 // clear of the source device must occur before CHECK_SHOULD_DRAW |
| 1478 SkGpuDevice* dev = static_cast<SkGpuDevice*>(device); | 1451 SkGpuDevice* dev = static_cast<SkGpuDevice*>(device); |
| 1479 if (dev->fNeedClear) { | 1452 if (dev->fNeedClear) { |
| 1480 // TODO: could check here whether we really need to draw at all | 1453 // TODO: could check here whether we really need to draw at all |
| 1481 dev->clear(0x0); | 1454 dev->clear(0x0); |
| 1482 } | 1455 } |
| 1483 | 1456 |
| 1484 // drawDevice is defined to be in device coords. | 1457 // drawDevice is defined to be in device coords. |
| 1485 CHECK_SHOULD_DRAW(draw, true); | 1458 CHECK_SHOULD_DRAW(draw, true); |
| 1486 | 1459 |
| 1487 GrPaint grPaint; | 1460 GrRenderTarget* devRT = device->accessRenderTarget(); |
| 1488 grPaint.colorStage(kBitmapEffectIdx)->reset(); | 1461 GrTexture* devTex; |
| 1489 if (!dev->bindDeviceAsTexture(&grPaint) || | 1462 if (NULL == (devTex = devRT->asTexture())) { |
| 1490 !skPaint2GrPaintNoShader(this, paint, true, false, &grPaint)) { | |
| 1491 return; | 1463 return; |
| 1492 } | 1464 } |
| 1493 | 1465 |
| 1494 GrTexture* devTex = (*grPaint.getColorStage(kBitmapEffectIdx).getEffect())->
texture(0); | |
| 1495 SkASSERT(NULL != devTex); | |
| 1496 | |
| 1497 const SkBitmap& bm = dev->accessBitmap(false); | 1466 const SkBitmap& bm = dev->accessBitmap(false); |
| 1498 int w = bm.width(); | 1467 int w = bm.width(); |
| 1499 int h = bm.height(); | 1468 int h = bm.height(); |
| 1500 | 1469 |
| 1501 SkImageFilter* filter = paint.getImageFilter(); | 1470 SkImageFilter* filter = paint.getImageFilter(); |
| 1471 |
| 1502 if (NULL != filter) { | 1472 if (NULL != filter) { |
| 1503 SkBitmap filterBitmap; | 1473 SkBitmap filterBitmap; |
| 1504 SkIPoint offset = SkIPoint::Make(0, 0); | 1474 SkIPoint offset = SkIPoint::Make(0, 0); |
| 1505 if (filter_texture(this, fContext, devTex, filter, w, h, &filterBitmap,
&offset)) { | 1475 if (filter_texture(this, fContext, devTex, filter, w, h, &filterBitmap,
&offset)) { |
| 1506 grPaint.colorStage(kBitmapEffectIdx)->setEffect( | |
| 1507 GrSimpleTextureEffect::Create(filterBitmap.getTexture(), SkMatri
x::I()))->unref(); | |
| 1508 devTex = filterBitmap.getTexture(); | 1476 devTex = filterBitmap.getTexture(); |
| 1509 w = filterBitmap.width(); | 1477 w = filterBitmap.width(); |
| 1510 h = filterBitmap.height(); | 1478 h = filterBitmap.height(); |
| 1511 x += offset.fX; | 1479 x += offset.fX; |
| 1512 y += offset.fY; | 1480 y += offset.fY; |
| 1513 } | 1481 } |
| 1514 } | 1482 } |
| 1515 | 1483 |
| 1484 GrPaint grPaint; |
| 1485 grPaint.addColorTextureEffect(devTex, SkMatrix::I()); |
| 1486 |
| 1487 if (!skPaint2GrPaintNoShader(this, paint, true, false, &grPaint)) { |
| 1488 return; |
| 1489 } |
| 1490 |
| 1516 GrRect dstRect = GrRect::MakeXYWH(SkIntToScalar(x), | 1491 GrRect dstRect = GrRect::MakeXYWH(SkIntToScalar(x), |
| 1517 SkIntToScalar(y), | 1492 SkIntToScalar(y), |
| 1518 SkIntToScalar(w), | 1493 SkIntToScalar(w), |
| 1519 SkIntToScalar(h)); | 1494 SkIntToScalar(h)); |
| 1520 | 1495 |
| 1521 // The device being drawn may not fill up its texture (saveLayer uses | 1496 // The device being drawn may not fill up its texture (e.g. saveLayer uses a
pproximate |
| 1522 // the approximate ). | 1497 // scratch texture). |
| 1523 GrRect srcRect = GrRect::MakeWH(SK_Scalar1 * w / devTex->width(), | 1498 GrRect srcRect = GrRect::MakeWH(SK_Scalar1 * w / devTex->width(), |
| 1524 SK_Scalar1 * h / devTex->height()); | 1499 SK_Scalar1 * h / devTex->height()); |
| 1525 | 1500 |
| 1526 fContext->drawRectToRect(grPaint, dstRect, srcRect); | 1501 fContext->drawRectToRect(grPaint, dstRect, srcRect); |
| 1527 } | 1502 } |
| 1528 | 1503 |
| 1529 bool SkGpuDevice::canHandleImageFilter(SkImageFilter* filter) { | 1504 bool SkGpuDevice::canHandleImageFilter(SkImageFilter* filter) { |
| 1530 return filter->canFilterImageGPU(); | 1505 return filter->canFilterImageGPU(); |
| 1531 } | 1506 } |
| 1532 | 1507 |
| (...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1785 GrTexture* texture, | 1760 GrTexture* texture, |
| 1786 bool needClear) | 1761 bool needClear) |
| 1787 : SkDevice(make_bitmap(context, texture->asRenderTarget())) { | 1762 : SkDevice(make_bitmap(context, texture->asRenderTarget())) { |
| 1788 | 1763 |
| 1789 GrAssert(texture && texture->asRenderTarget()); | 1764 GrAssert(texture && texture->asRenderTarget()); |
| 1790 // This constructor is called from onCreateCompatibleDevice. It has locked t
he RT in the texture | 1765 // This constructor is called from onCreateCompatibleDevice. It has locked t
he RT in the texture |
| 1791 // cache. We pass true for the third argument so that it will get unlocked. | 1766 // cache. We pass true for the third argument so that it will get unlocked. |
| 1792 this->initFromRenderTarget(context, texture->asRenderTarget(), true); | 1767 this->initFromRenderTarget(context, texture->asRenderTarget(), true); |
| 1793 fNeedClear = needClear; | 1768 fNeedClear = needClear; |
| 1794 } | 1769 } |
| OLD | NEW |