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 |