| 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 19 matching lines...) Expand all Loading... |
| 30 extern bool (*gShouldDrawProc)(); | 30 extern bool (*gShouldDrawProc)(); |
| 31 #define CHECK_SHOULD_DRAW(draw, forceI) \ | 31 #define CHECK_SHOULD_DRAW(draw, forceI) \ |
| 32 do { \ | 32 do { \ |
| 33 if (gShouldDrawProc && !gShouldDrawProc()) return; \ | 33 if (gShouldDrawProc && !gShouldDrawProc()) return; \ |
| 34 this->prepareDraw(draw, forceI); \ | 34 this->prepareDraw(draw, forceI); \ |
| 35 } while (0) | 35 } while (0) |
| 36 #else | 36 #else |
| 37 #define CHECK_SHOULD_DRAW(draw, forceI) this->prepareDraw(draw, forceI) | 37 #define CHECK_SHOULD_DRAW(draw, forceI) this->prepareDraw(draw, forceI) |
| 38 #endif | 38 #endif |
| 39 | 39 |
| 40 // we use the same texture slot on GrPaint for bitmaps and shaders | 40 // we use the same effect slot on GrPaint for bitmaps and shaders (since drawBit
map, drawSprite, |
| 41 // (since drawBitmap, drawSprite, and drawDevice ignore skia's shader) | 41 // and drawDevice ignore SkShader) |
| 42 enum { | 42 enum { |
| 43 kBitmapTextureIdx = 0, | 43 kShaderEffectIdx = 0, |
| 44 kShaderTextureIdx = 0, | 44 kBitmapEffectIdx = 0, |
| 45 kColorFilterTextureIdx = 1 | 45 kColorFilterEffectIdx = 1, |
| 46 kXfermodeEffectIdx = 2, |
| 46 }; | 47 }; |
| 47 | 48 |
| 48 #define MAX_BLUR_SIGMA 4.0f | 49 #define MAX_BLUR_SIGMA 4.0f |
| 49 // FIXME: This value comes from from SkBlurMaskFilter.cpp. | 50 // FIXME: This value comes from from SkBlurMaskFilter.cpp. |
| 50 // Should probably be put in a common header someplace. | 51 // Should probably be put in a common header someplace. |
| 51 #define MAX_BLUR_RADIUS SkIntToScalar(128) | 52 #define MAX_BLUR_RADIUS SkIntToScalar(128) |
| 52 // This constant approximates the scaling done in the software path's | 53 // This constant approximates the scaling done in the software path's |
| 53 // "high quality" mode, in SkBlurMask::Blur() (1 / sqrt(3)). | 54 // "high quality" mode, in SkBlurMask::Blur() (1 / sqrt(3)). |
| 54 // IMHO, it actually should be 1: we blur "less" than we should do | 55 // IMHO, it actually should be 1: we blur "less" than we should do |
| 55 // according to the CSS and canvas specs, simply because Safari does the same. | 56 // according to the CSS and canvas specs, simply because Safari does the same. |
| (...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 436 } | 437 } |
| 437 | 438 |
| 438 SkGpuRenderTarget* SkGpuDevice::accessRenderTarget() { | 439 SkGpuRenderTarget* SkGpuDevice::accessRenderTarget() { |
| 439 DO_DEFERRED_CLEAR(); | 440 DO_DEFERRED_CLEAR(); |
| 440 return (SkGpuRenderTarget*)fRenderTarget; | 441 return (SkGpuRenderTarget*)fRenderTarget; |
| 441 } | 442 } |
| 442 | 443 |
| 443 bool SkGpuDevice::bindDeviceAsTexture(GrPaint* paint) { | 444 bool SkGpuDevice::bindDeviceAsTexture(GrPaint* paint) { |
| 444 GrTexture* texture = fRenderTarget->asTexture(); | 445 GrTexture* texture = fRenderTarget->asTexture(); |
| 445 if (NULL != texture) { | 446 if (NULL != texture) { |
| 446 paint->colorStage(kBitmapTextureIdx)->setEffect( | 447 paint->colorStage(kBitmapEffectIdx)->setEffect( |
| 447 GrSimpleTextureEffect::Create(texture, SkMatrix::I()))->unref(); | 448 GrSimpleTextureEffect::Create(texture, SkMatrix::I()))->unref(); |
| 448 return true; | 449 return true; |
| 449 } | 450 } |
| 450 return false; | 451 return false; |
| 451 } | 452 } |
| 452 | 453 |
| 453 /////////////////////////////////////////////////////////////////////////////// | 454 /////////////////////////////////////////////////////////////////////////////// |
| 454 | 455 |
| 455 SK_COMPILE_ASSERT(SkShader::kNone_BitmapType == 0, shader_type_mismatch); | 456 SK_COMPILE_ASSERT(SkShader::kNone_BitmapType == 0, shader_type_mismatch); |
| 456 SK_COMPILE_ASSERT(SkShader::kDefault_BitmapType == 1, shader_type_mismatch); | 457 SK_COMPILE_ASSERT(SkShader::kDefault_BitmapType == 1, shader_type_mismatch); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 479 | 480 |
| 480 grPaint->setDither(skPaint.isDither()); | 481 grPaint->setDither(skPaint.isDither()); |
| 481 grPaint->setAntiAlias(skPaint.isAntiAlias()); | 482 grPaint->setAntiAlias(skPaint.isAntiAlias()); |
| 482 | 483 |
| 483 SkXfermode::Coeff sm = SkXfermode::kOne_Coeff; | 484 SkXfermode::Coeff sm = SkXfermode::kOne_Coeff; |
| 484 SkXfermode::Coeff dm = SkXfermode::kISA_Coeff; | 485 SkXfermode::Coeff dm = SkXfermode::kISA_Coeff; |
| 485 | 486 |
| 486 SkXfermode* mode = skPaint.getXfermode(); | 487 SkXfermode* mode = skPaint.getXfermode(); |
| 487 GrEffectRef* xferEffect = NULL; | 488 GrEffectRef* xferEffect = NULL; |
| 488 if (SkXfermode::AsNewEffect(mode, dev->context(), &xferEffect, &sm, &dm)) { | 489 if (SkXfermode::AsNewEffect(mode, dev->context(), &xferEffect, &sm, &dm)) { |
| 489 // We're not ready for xfermode effects yet | 490 SkSafeUnref(grPaint->colorStage(kXfermodeEffectIdx)->setEffect(xferEffec
t)); |
| 490 GrAssert(NULL == xferEffect); | |
| 491 } else { | 491 } else { |
| 492 //SkDEBUGCODE(SkDebugf("Unsupported xfer mode.\n");) | 492 //SkDEBUGCODE(SkDebugf("Unsupported xfer mode.\n");) |
| 493 #if 0 | 493 #if 0 |
| 494 return false; | 494 return false; |
| 495 #endif | 495 #endif |
| 496 } | 496 } |
| 497 grPaint->setBlendFunc(sk_blend_to_grblend(sm), sk_blend_to_grblend(dm)); | 497 grPaint->setBlendFunc(sk_blend_to_grblend(sm), sk_blend_to_grblend(dm)); |
| 498 | 498 |
| 499 if (justAlpha) { | 499 if (justAlpha) { |
| 500 uint8_t alpha = skPaint.getAlpha(); | 500 uint8_t alpha = skPaint.getAlpha(); |
| 501 grPaint->setColor(GrColorPackRGBA(alpha, alpha, alpha, alpha)); | 501 grPaint->setColor(GrColorPackRGBA(alpha, alpha, alpha, alpha)); |
| 502 // justAlpha is currently set to true only if there is a texture, | 502 // justAlpha is currently set to true only if there is a texture, |
| 503 // so constantColor should not also be true. | 503 // so constantColor should not also be true. |
| 504 GrAssert(!constantColor); | 504 GrAssert(!constantColor); |
| 505 } else { | 505 } else { |
| 506 grPaint->setColor(SkColor2GrColor(skPaint.getColor())); | 506 grPaint->setColor(SkColor2GrColor(skPaint.getColor())); |
| 507 GrAssert(!grPaint->isColorStageEnabled(kShaderTextureIdx)); | 507 GrAssert(!grPaint->isColorStageEnabled(kShaderEffectIdx)); |
| 508 } | 508 } |
| 509 | 509 |
| 510 SkColorFilter* colorFilter = skPaint.getColorFilter(); | 510 SkColorFilter* colorFilter = skPaint.getColorFilter(); |
| 511 if (NULL != colorFilter) { | 511 if (NULL != colorFilter) { |
| 512 // if the source color is a constant then apply the filter here once rat
her than per pixel | 512 // if the source color is a constant then apply the filter here once rat
her than per pixel |
| 513 // in a shader. | 513 // in a shader. |
| 514 if (constantColor) { | 514 if (constantColor) { |
| 515 SkColor filtered = colorFilter->filterColor(skPaint.getColor()); | 515 SkColor filtered = colorFilter->filterColor(skPaint.getColor()); |
| 516 grPaint->setColor(SkColor2GrColor(filtered)); | 516 grPaint->setColor(SkColor2GrColor(filtered)); |
| 517 } else { | 517 } else { |
| 518 SkAutoTUnref<GrEffectRef> effect(colorFilter->asNewEffect(dev->conte
xt())); | 518 SkAutoTUnref<GrEffectRef> effect(colorFilter->asNewEffect(dev->conte
xt())); |
| 519 if (NULL != effect.get()) { | 519 if (NULL != effect.get()) { |
| 520 grPaint->colorStage(kColorFilterTextureIdx)->setEffect(effect); | 520 grPaint->colorStage(kColorFilterEffectIdx)->setEffect(effect); |
| 521 } else { | 521 } else { |
| 522 // TODO: rewrite this using asNewEffect() | 522 // TODO: rewrite this using asNewEffect() |
| 523 SkColor color; | 523 SkColor color; |
| 524 SkXfermode::Mode filterMode; | 524 SkXfermode::Mode filterMode; |
| 525 if (colorFilter->asColorMode(&color, &filterMode)) { | 525 if (colorFilter->asColorMode(&color, &filterMode)) { |
| 526 grPaint->setXfermodeColorFilter(filterMode, SkColor2GrColor(
color)); | 526 grPaint->setXfermodeColorFilter(filterMode, SkColor2GrColor(
color)); |
| 527 } | 527 } |
| 528 } | 528 } |
| 529 } | 529 } |
| 530 } | 530 } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 542 GrPaint* grPaint) { | 542 GrPaint* grPaint) { |
| 543 SkShader* shader = skPaint.getShader(); | 543 SkShader* shader = skPaint.getShader(); |
| 544 if (NULL == shader) { | 544 if (NULL == shader) { |
| 545 return skPaint2GrPaintNoShader(dev, skPaint, false, constantColor, grPai
nt); | 545 return skPaint2GrPaintNoShader(dev, skPaint, false, constantColor, grPai
nt); |
| 546 } else if (!skPaint2GrPaintNoShader(dev, skPaint, true, false, grPaint)) { | 546 } else if (!skPaint2GrPaintNoShader(dev, skPaint, true, false, grPaint)) { |
| 547 return false; | 547 return false; |
| 548 } | 548 } |
| 549 | 549 |
| 550 SkAutoTUnref<GrEffectRef> effect(shader->asNewEffect(dev->context(), skPaint
)); | 550 SkAutoTUnref<GrEffectRef> effect(shader->asNewEffect(dev->context(), skPaint
)); |
| 551 if (NULL != effect.get()) { | 551 if (NULL != effect.get()) { |
| 552 grPaint->colorStage(kShaderTextureIdx)->setEffect(effect); | 552 grPaint->colorStage(kShaderEffectIdx)->setEffect(effect); |
| 553 return true; | 553 return true; |
| 554 } | 554 } |
| 555 | 555 |
| 556 // We still don't have SkColorShader::asNewEffect() implemented. | 556 // We still don't have SkColorShader::asNewEffect() implemented. |
| 557 SkShader::GradientInfo info; | 557 SkShader::GradientInfo info; |
| 558 SkColor color; | 558 SkColor color; |
| 559 | 559 |
| 560 info.fColors = &color; | 560 info.fColors = &color; |
| 561 info.fColorOffsets = NULL; | 561 info.fColorOffsets = NULL; |
| 562 info.fColorCount = 1; | 562 info.fColorCount = 1; |
| (...skipping 808 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1371 } | 1371 } |
| 1372 textureDomain.setLTRB(left, top, right, bottom); | 1372 textureDomain.setLTRB(left, top, right, bottom); |
| 1373 effect.reset(GrTextureDomainEffect::Create(texture, | 1373 effect.reset(GrTextureDomainEffect::Create(texture, |
| 1374 SkMatrix::I(), | 1374 SkMatrix::I(), |
| 1375 textureDomain, | 1375 textureDomain, |
| 1376 GrTextureDomainEffect::kClamp
_WrapMode, | 1376 GrTextureDomainEffect::kClamp
_WrapMode, |
| 1377 params.isBilerp())); | 1377 params.isBilerp())); |
| 1378 } else { | 1378 } else { |
| 1379 effect.reset(GrSimpleTextureEffect::Create(texture, SkMatrix::I(), param
s)); | 1379 effect.reset(GrSimpleTextureEffect::Create(texture, SkMatrix::I(), param
s)); |
| 1380 } | 1380 } |
| 1381 grPaint->colorStage(kBitmapTextureIdx)->setEffect(effect); | 1381 grPaint->colorStage(kBitmapEffectIdx)->setEffect(effect); |
| 1382 fContext->drawRectToRect(*grPaint, dstRect, paintRect, &m); | 1382 fContext->drawRectToRect(*grPaint, dstRect, paintRect, &m); |
| 1383 } | 1383 } |
| 1384 | 1384 |
| 1385 namespace { | 1385 namespace { |
| 1386 | 1386 |
| 1387 void apply_effect(GrContext* context, | 1387 void apply_effect(GrContext* context, |
| 1388 GrTexture* srcTexture, | 1388 GrTexture* srcTexture, |
| 1389 GrTexture* dstTexture, | 1389 GrTexture* dstTexture, |
| 1390 const GrRect& rect, | 1390 const GrRect& rect, |
| 1391 GrEffectRef* effect) { | 1391 GrEffectRef* effect) { |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1453 } | 1453 } |
| 1454 | 1454 |
| 1455 int w = bitmap.width(); | 1455 int w = bitmap.width(); |
| 1456 int h = bitmap.height(); | 1456 int h = bitmap.height(); |
| 1457 | 1457 |
| 1458 GrPaint grPaint; | 1458 GrPaint grPaint; |
| 1459 if(!skPaint2GrPaintNoShader(this, paint, true, false, &grPaint)) { | 1459 if(!skPaint2GrPaintNoShader(this, paint, true, false, &grPaint)) { |
| 1460 return; | 1460 return; |
| 1461 } | 1461 } |
| 1462 | 1462 |
| 1463 GrEffectStage* stage = grPaint.colorStage(kBitmapTextureIdx); | 1463 GrEffectStage* stage = grPaint.colorStage(kBitmapEffectIdx); |
| 1464 | 1464 |
| 1465 GrTexture* texture; | 1465 GrTexture* texture; |
| 1466 stage->reset(); | 1466 stage->reset(); |
| 1467 // draw sprite uses the default texture params | 1467 // draw sprite uses the default texture params |
| 1468 SkAutoCachedTexture act(this, bitmap, NULL, &texture); | 1468 SkAutoCachedTexture act(this, bitmap, NULL, &texture); |
| 1469 grPaint.colorStage(kBitmapTextureIdx)->setEffect( | 1469 grPaint.colorStage(kBitmapEffectIdx)->setEffect( |
| 1470 GrSimpleTextureEffect::Create(texture, SkMatrix::I()))->unref(); | 1470 GrSimpleTextureEffect::Create(texture, SkMatrix::I()))->unref(); |
| 1471 | 1471 |
| 1472 SkImageFilter* filter = paint.getImageFilter(); | 1472 SkImageFilter* filter = paint.getImageFilter(); |
| 1473 if (NULL != filter) { | 1473 if (NULL != filter) { |
| 1474 SkBitmap filterBitmap; | 1474 SkBitmap filterBitmap; |
| 1475 if (filter_texture(this, fContext, texture, filter, w, h, &filterBitmap)
) { | 1475 if (filter_texture(this, fContext, texture, filter, w, h, &filterBitmap)
) { |
| 1476 grPaint.colorStage(kBitmapTextureIdx)->setEffect( | 1476 grPaint.colorStage(kBitmapEffectIdx)->setEffect( |
| 1477 GrSimpleTextureEffect::Create((GrTexture*) filterBitmap.getTextu
re(), SkMatrix::I()))->unref(); | 1477 GrSimpleTextureEffect::Create((GrTexture*) filterBitmap.getTextu
re(), SkMatrix::I()))->unref(); |
| 1478 texture = (GrTexture*) filterBitmap.getTexture(); | 1478 texture = (GrTexture*) filterBitmap.getTexture(); |
| 1479 w = filterBitmap.width(); | 1479 w = filterBitmap.width(); |
| 1480 h = filterBitmap.height(); | 1480 h = filterBitmap.height(); |
| 1481 } | 1481 } |
| 1482 } | 1482 } |
| 1483 | 1483 |
| 1484 fContext->drawRectToRect(grPaint, | 1484 fContext->drawRectToRect(grPaint, |
| 1485 GrRect::MakeXYWH(SkIntToScalar(left), | 1485 GrRect::MakeXYWH(SkIntToScalar(left), |
| 1486 SkIntToScalar(top), | 1486 SkIntToScalar(top), |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1526 SkGpuDevice* dev = static_cast<SkGpuDevice*>(device); | 1526 SkGpuDevice* dev = static_cast<SkGpuDevice*>(device); |
| 1527 if (dev->fNeedClear) { | 1527 if (dev->fNeedClear) { |
| 1528 // TODO: could check here whether we really need to draw at all | 1528 // TODO: could check here whether we really need to draw at all |
| 1529 dev->clear(0x0); | 1529 dev->clear(0x0); |
| 1530 } | 1530 } |
| 1531 | 1531 |
| 1532 // drawDevice is defined to be in device coords. | 1532 // drawDevice is defined to be in device coords. |
| 1533 CHECK_SHOULD_DRAW(draw, true); | 1533 CHECK_SHOULD_DRAW(draw, true); |
| 1534 | 1534 |
| 1535 GrPaint grPaint; | 1535 GrPaint grPaint; |
| 1536 grPaint.colorStage(kBitmapTextureIdx)->reset(); | 1536 grPaint.colorStage(kBitmapEffectIdx)->reset(); |
| 1537 if (!dev->bindDeviceAsTexture(&grPaint) || | 1537 if (!dev->bindDeviceAsTexture(&grPaint) || |
| 1538 !skPaint2GrPaintNoShader(this, paint, true, false, &grPaint)) { | 1538 !skPaint2GrPaintNoShader(this, paint, true, false, &grPaint)) { |
| 1539 return; | 1539 return; |
| 1540 } | 1540 } |
| 1541 | 1541 |
| 1542 GrTexture* devTex = (*grPaint.getColorStage(kBitmapTextureIdx).getEffect())-
>texture(0); | 1542 GrTexture* devTex = (*grPaint.getColorStage(kBitmapEffectIdx).getEffect())->
texture(0); |
| 1543 SkASSERT(NULL != devTex); | 1543 SkASSERT(NULL != devTex); |
| 1544 | 1544 |
| 1545 const SkBitmap& bm = dev->accessBitmap(false); | 1545 const SkBitmap& bm = dev->accessBitmap(false); |
| 1546 int w = bm.width(); | 1546 int w = bm.width(); |
| 1547 int h = bm.height(); | 1547 int h = bm.height(); |
| 1548 | 1548 |
| 1549 SkImageFilter* filter = paint.getImageFilter(); | 1549 SkImageFilter* filter = paint.getImageFilter(); |
| 1550 if (NULL != filter) { | 1550 if (NULL != filter) { |
| 1551 SkBitmap filterBitmap; | 1551 SkBitmap filterBitmap; |
| 1552 if (filter_texture(this, fContext, devTex, filter, w, h, &filterBitmap))
{ | 1552 if (filter_texture(this, fContext, devTex, filter, w, h, &filterBitmap))
{ |
| 1553 grPaint.colorStage(kBitmapTextureIdx)->setEffect( | 1553 grPaint.colorStage(kBitmapEffectIdx)->setEffect( |
| 1554 GrSimpleTextureEffect::Create((GrTexture*) filterBitmap.getTextu
re(), SkMatrix::I()))->unref(); | 1554 GrSimpleTextureEffect::Create((GrTexture*) filterBitmap.getTextu
re(), SkMatrix::I()))->unref(); |
| 1555 devTex = (GrTexture*) filterBitmap.getTexture(); | 1555 devTex = (GrTexture*) filterBitmap.getTexture(); |
| 1556 w = filterBitmap.width(); | 1556 w = filterBitmap.width(); |
| 1557 h = filterBitmap.height(); | 1557 h = filterBitmap.height(); |
| 1558 } | 1558 } |
| 1559 } | 1559 } |
| 1560 | 1560 |
| 1561 GrRect dstRect = GrRect::MakeXYWH(SkIntToScalar(x), | 1561 GrRect dstRect = GrRect::MakeXYWH(SkIntToScalar(x), |
| 1562 SkIntToScalar(y), | 1562 SkIntToScalar(y), |
| 1563 SkIntToScalar(w), | 1563 SkIntToScalar(w), |
| (...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1836 GrTexture* texture, | 1836 GrTexture* texture, |
| 1837 bool needClear) | 1837 bool needClear) |
| 1838 : SkDevice(make_bitmap(context, texture->asRenderTarget())) { | 1838 : SkDevice(make_bitmap(context, texture->asRenderTarget())) { |
| 1839 | 1839 |
| 1840 GrAssert(texture && texture->asRenderTarget()); | 1840 GrAssert(texture && texture->asRenderTarget()); |
| 1841 // This constructor is called from onCreateCompatibleDevice. It has locked t
he RT in the texture | 1841 // This constructor is called from onCreateCompatibleDevice. It has locked t
he RT in the texture |
| 1842 // cache. We pass true for the third argument so that it will get unlocked. | 1842 // cache. We pass true for the third argument so that it will get unlocked. |
| 1843 this->initFromRenderTarget(context, texture->asRenderTarget(), true); | 1843 this->initFromRenderTarget(context, texture->asRenderTarget(), true); |
| 1844 fNeedClear = needClear; | 1844 fNeedClear = needClear; |
| 1845 } | 1845 } |
| OLD | NEW |