Chromium Code Reviews| Index: src/gpu/SkGpuDevice.cpp |
| diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp |
| index f8318c52d8409fc834be2b1a636de5d3bacd31a6..4ae1c35d4a152bde37724e25c4f71b24ec048c55 100644 |
| --- a/src/gpu/SkGpuDevice.cpp |
| +++ b/src/gpu/SkGpuDevice.cpp |
| @@ -39,6 +39,7 @@ |
| #include "SkUtils.h" |
| #include "SkVertState.h" |
| #include "SkXfermode.h" |
| +#include "batches/GrRectBatchFactory.h" |
| #include "effects/GrBicubicEffect.h" |
| #include "effects/GrDashingEffect.h" |
| #include "effects/GrSimpleTextureEffect.h" |
| @@ -987,11 +988,11 @@ void SkGpuDevice::drawBitmapCommon(const SkDraw& draw, |
| // through drawRect, which supports mask filters. |
| SkBitmap tmp; // subset of bitmap, if necessary |
| const SkBitmap* bitmapPtr = &bitmap; |
| - SkMatrix localM; |
| + SkMatrix srcRectToDstRect; |
| if (srcRectPtr) { |
| - localM.setTranslate(-srcRectPtr->fLeft, -srcRectPtr->fTop); |
| - localM.postScale(dstSize.fWidth / srcRectPtr->width(), |
| - dstSize.fHeight / srcRectPtr->height()); |
| + srcRectToDstRect.setTranslate(-srcRectPtr->fLeft, -srcRectPtr->fTop); |
| + srcRectToDstRect.postScale(dstSize.fWidth / srcRectPtr->width(), |
| + dstSize.fHeight / srcRectPtr->height()); |
| // In bleed mode we position and trim the bitmap based on the src rect which is |
| // already accounted for in 'm' and 'srcRect'. In clamp mode we need to chop out |
| // the desired portion of the bitmap and then update 'm' and 'srcRect' to |
| @@ -1010,17 +1011,94 @@ void SkGpuDevice::drawBitmapCommon(const SkDraw& draw, |
| srcRect.offset(-offset.fX, -offset.fY); |
| // The source rect has changed so update the matrix |
| - localM.preTranslate(offset.fX, offset.fY); |
| + srcRectToDstRect.preTranslate(offset.fX, offset.fY); |
| } |
| } else { |
| - localM.reset(); |
| + srcRectToDstRect.reset(); |
| } |
| - SkPaint paintWithShader(paint); |
| - paintWithShader.setShader(SkShader::CreateBitmapShader(*bitmapPtr, |
| - SkShader::kClamp_TileMode, SkShader::kClamp_TileMode, &localM))->unref(); |
| - SkRect dstRect = {0, 0, dstSize.fWidth, dstSize.fHeight}; |
| - this->drawRect(draw, dstRect, paintWithShader); |
| + // If we have a maskfilter then we can't batch, so we take a slow path. However, we fast |
| + // path the case where we are drawing an AA rect so we can batch many drawImageRect calls |
| + if (paint.getMaskFilter()) { |
| + SkPaint paintWithShader(paint); |
| + paintWithShader.setShader(SkShader::CreateBitmapShader(*bitmapPtr, |
|
robertphillips
2015/08/14 18:49:20
tab over to line up with '(' ?
|
| + SkShader::kClamp_TileMode, SkShader::kClamp_TileMode, |
| + &srcRectToDstRect))->unref(); |
| + SkRect dstRect = {0, 0, dstSize.fWidth, dstSize.fHeight}; |
| + this->drawRect(draw, dstRect, paintWithShader); |
| + } else { |
|
robertphillips
2015/08/14 18:49:20
Can/should this be a subroutine ?
|
| + SkShader::TileMode tm[] = { |
| + SkShader::kClamp_TileMode, |
| + SkShader::kClamp_TileMode, |
| + }; |
| + |
| + bool doBicubic; |
| + GrTextureParams::FilterMode textureFilterMode = |
| + GrSkFilterQualityToGrFilterMode(paint.getFilterQuality(), *draw.fMatrix, |
| + srcRectToDstRect, |
| + &doBicubic); |
| + |
| + // Setup texture to wrap bitmap |
| + GrTextureParams params(tm, textureFilterMode); |
| + SkAutoTUnref<GrTexture> texture(GrRefCachedBitmapTexture(fContext, *bitmapPtr, |
| + ¶ms)); |
| + |
| + if (!texture) { |
| + SkErrorInternals::SetError(kInternalError_SkError, |
| + "Couldn't convert bitmap to texture."); |
| + return; |
| + } |
| + |
| + // Setup paint |
| + GrColor paintColor = (kAlpha_8_SkColorType == bitmapPtr->colorType()) ? |
| + SkColor2GrColor(paint.getColor()) : |
| + SkColor2GrColorJustAlpha(paint.getColor()); |
| + |
| + GrPaint grPaint; |
| + |
| + // Create and insert texture effect |
| + SkAutoTUnref<const GrFragmentProcessor> fp; |
| + if (doBicubic) { |
| + fp.reset(GrBicubicEffect::Create(grPaint.getProcessorDataManager(), texture, |
| + SkMatrix::I(), |
| + tm)); |
| + } else { |
| + fp.reset(GrSimpleTextureEffect::Create(grPaint.getProcessorDataManager(), texture, |
| + SkMatrix::I(), params)); |
| + } |
| + |
| + grPaint.addColorProcessor(fp); |
| + |
| + if (!SkPaint2GrPaint(this->context(), fRenderTarget, paint, *draw.fMatrix, true, |
| + &grPaint)) { |
| + return; |
| + } |
| + |
| + grPaint.setColor(paintColor); |
| + |
| + // Setup dst rect and final matrix |
| + SkRect dstRect = {0, 0, dstSize.fWidth, dstSize.fHeight}; |
| + |
| + SkRect devRect; |
| + draw.fMatrix->mapRect(&devRect, dstRect); |
| + |
| + SkMatrix matrix; |
| + matrix.setIDiv(bitmapPtr->width(), bitmapPtr->height()); |
| + |
| + SkMatrix dstRectToSrcRect; |
| + if (!srcRectToDstRect.invert(&dstRectToSrcRect)) { |
| + return; |
| + } |
| + matrix.preConcat(dstRectToSrcRect); |
| + |
| + SkAutoTUnref<GrDrawBatch> batch(GrRectBatchFactory::CreateFillAA(grPaint.getColor(), |
| + *draw.fMatrix, |
| + matrix, |
| + dstRect, |
| + devRect)); |
| + |
| + fDrawContext->drawBatch(fRenderTarget, fClip, grPaint, batch); |
| + } |
| return; |
| } |