| Index: src/gpu/SkGpuDevice.cpp
|
| diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
|
| index f8318c52d8409fc834be2b1a636de5d3bacd31a6..7052d2531cff56b9212f964efb6b82df33900301 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"
|
| @@ -918,6 +919,82 @@ static bool needs_texture_domain(const SkBitmap& bitmap,
|
| return needsTextureDomain;
|
| }
|
|
|
| +static void draw_aa_bitmap(GrDrawContext* drawContext, GrContext* context,
|
| + GrRenderTarget* renderTarget, const GrClip& clip,
|
| + const SkMatrix& viewMatrix, const SkMatrix& srcRectToDstRect,
|
| + const SkPaint& paint, const SkBitmap* bitmapPtr, const SkSize& dstSize) {
|
| + SkShader::TileMode tm[] = {
|
| + SkShader::kClamp_TileMode,
|
| + SkShader::kClamp_TileMode,
|
| + };
|
| +
|
| + bool doBicubic;
|
| + GrTextureParams::FilterMode textureFilterMode =
|
| + GrSkFilterQualityToGrFilterMode(paint.getFilterQuality(), viewMatrix,
|
| + srcRectToDstRect,
|
| + &doBicubic);
|
| +
|
| + // Setup texture to wrap bitmap
|
| + GrTextureParams params(tm, textureFilterMode);
|
| + SkAutoTUnref<GrTexture> texture(GrRefCachedBitmapTexture(context, *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));
|
| + }
|
| +
|
| + // The bitmap read has to be first
|
| + grPaint.addColorProcessor(fp);
|
| + if (!SkPaint2GrPaintNoShader(context, renderTarget, paint, SkColor2GrColor(paint.getColor()),
|
| + false, &grPaint)) {
|
| + return;
|
| + }
|
| +
|
| + grPaint.setColor(paintColor);
|
| +
|
| + // Setup dst rect and final matrix
|
| + SkRect dstRect = {0, 0, dstSize.fWidth, dstSize.fHeight};
|
| +
|
| + SkRect devRect;
|
| + viewMatrix.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(),
|
| + viewMatrix,
|
| + matrix,
|
| + dstRect,
|
| + devRect));
|
| +
|
| + drawContext->drawBatch(renderTarget, clip, grPaint, batch);
|
| +}
|
| +
|
| void SkGpuDevice::drawBitmapCommon(const SkDraw& draw,
|
| const SkBitmap& bitmap,
|
| const SkRect* srcRectPtr,
|
| @@ -987,11 +1064,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 +1087,25 @@ 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,
|
| + SkShader::kClamp_TileMode, SkShader::kClamp_TileMode,
|
| + &srcRectToDstRect))->unref();
|
| + SkRect dstRect = {0, 0, dstSize.fWidth, dstSize.fHeight};
|
| + this->drawRect(draw, dstRect, paintWithShader);
|
| + } else {
|
| + draw_aa_bitmap(fDrawContext, fContext, fRenderTarget, fClip, *draw.fMatrix,
|
| + srcRectToDstRect, paint, bitmapPtr, dstSize);
|
| + }
|
|
|
| return;
|
| }
|
|
|