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 |
robertphillips
2013/07/12 12:54:33
reset -> rest?
bsalomon
2013/07/12 13:38:59
Done.
| |
1345 // the reset 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 |