Index: src/gpu/SkGpuDevice.cpp |
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp |
index f8318c52d8409fc834be2b1a636de5d3bacd31a6..aa08e86cacf44630687d1db4b54be8b47840f978 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 modelToUV; |
bsalomon
2015/08/13 17:00:34
Let's keep are labeling consistent and not introdu
|
if (srcRectPtr) { |
- localM.setTranslate(-srcRectPtr->fLeft, -srcRectPtr->fTop); |
- localM.postScale(dstSize.fWidth / srcRectPtr->width(), |
- dstSize.fHeight / srcRectPtr->height()); |
+ modelToUV.setTranslate(-srcRectPtr->fLeft, -srcRectPtr->fTop); |
+ modelToUV.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,93 @@ 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); |
+ modelToUV.preTranslate(offset.fX, offset.fY); |
} |
} else { |
- localM.reset(); |
+ modelToUV.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, |
+ SkShader::kClamp_TileMode, SkShader::kClamp_TileMode, &modelToUV))->unref(); |
+ SkRect dstRect = {0, 0, dstSize.fWidth, dstSize.fHeight}; |
+ this->drawRect(draw, dstRect, paintWithShader); |
+ } else { |
+ SkShader::TileMode tm[] = { |
+ SkShader::kClamp_TileMode, |
+ SkShader::kClamp_TileMode, |
+ }; |
+ |
+ bool doBicubic; |
+ GrTextureParams::FilterMode textureFilterMode = |
+ GrSkFilterQualityToGrFilterMode(paint.getFilterQuality(), *draw.fMatrix, |
+ modelToUV, |
+ &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 uvToModel; |
+ if (!modelToUV.invert(&uvToModel)) { |
+ return; |
+ } |
+ matrix.preConcat(uvToModel); |
+ |
+ SkAutoTUnref<GrBatch> batch(GrRectBatchFactory::CreateFillAA(grPaint.getColor(), |
+ *draw.fMatrix, |
+ matrix, |
+ dstRect, |
+ devRect)); |
+ |
+ fDrawContext->drawBatch(fRenderTarget, fClip, grPaint, batch); |
+ } |
return; |
} |