drawBitmapImage can batch across AA rects

BUG=464835

Committed: https://skia.googlesource.com/skia/+/0d4bcea0d570041434ac3de2df2bd9063138fdb5

Review URL: https://codereview.chromium.org/1293543002
This commit is contained in:
joshualitt 2015-08-17 10:51:22 -07:00 committed by Commit bot
parent b279668c64
commit a61c817272
3 changed files with 114 additions and 18 deletions

View File

@ -39,6 +39,7 @@
#include "SkUtils.h" #include "SkUtils.h"
#include "SkVertState.h" #include "SkVertState.h"
#include "SkXfermode.h" #include "SkXfermode.h"
#include "batches/GrRectBatchFactory.h"
#include "effects/GrBicubicEffect.h" #include "effects/GrBicubicEffect.h"
#include "effects/GrDashingEffect.h" #include "effects/GrDashingEffect.h"
#include "effects/GrSimpleTextureEffect.h" #include "effects/GrSimpleTextureEffect.h"
@ -918,6 +919,82 @@ static bool needs_texture_domain(const SkBitmap& bitmap,
return needsTextureDomain; 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, &params));
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, void SkGpuDevice::drawBitmapCommon(const SkDraw& draw,
const SkBitmap& bitmap, const SkBitmap& bitmap,
const SkRect* srcRectPtr, const SkRect* srcRectPtr,
@ -987,11 +1064,11 @@ void SkGpuDevice::drawBitmapCommon(const SkDraw& draw,
// through drawRect, which supports mask filters. // through drawRect, which supports mask filters.
SkBitmap tmp; // subset of bitmap, if necessary SkBitmap tmp; // subset of bitmap, if necessary
const SkBitmap* bitmapPtr = &bitmap; const SkBitmap* bitmapPtr = &bitmap;
SkMatrix localM; SkMatrix srcRectToDstRect;
if (srcRectPtr) { if (srcRectPtr) {
localM.setTranslate(-srcRectPtr->fLeft, -srcRectPtr->fTop); srcRectToDstRect.setTranslate(-srcRectPtr->fLeft, -srcRectPtr->fTop);
localM.postScale(dstSize.fWidth / srcRectPtr->width(), srcRectToDstRect.postScale(dstSize.fWidth / srcRectPtr->width(),
dstSize.fHeight / srcRectPtr->height()); dstSize.fHeight / srcRectPtr->height());
// In bleed mode we position and trim the bitmap based on the src rect which is // 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 // 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 // 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); srcRect.offset(-offset.fX, -offset.fY);
// The source rect has changed so update the matrix // The source rect has changed so update the matrix
localM.preTranslate(offset.fX, offset.fY); srcRectToDstRect.preTranslate(offset.fX, offset.fY);
} }
} else { } else {
localM.reset(); srcRectToDstRect.reset();
} }
SkPaint paintWithShader(paint); // If we have a maskfilter then we can't batch, so we take a slow path. However, we fast
paintWithShader.setShader(SkShader::CreateBitmapShader(*bitmapPtr, // path the case where we are drawing an AA rect so we can batch many drawImageRect calls
SkShader::kClamp_TileMode, SkShader::kClamp_TileMode, &localM))->unref(); if (paint.getMaskFilter()) {
SkRect dstRect = {0, 0, dstSize.fWidth, dstSize.fHeight}; SkPaint paintWithShader(paint);
this->drawRect(draw, dstRect, paintWithShader); 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; return;
} }

View File

@ -250,12 +250,15 @@ private:
// Make verts point to vertex color and then set all the color and coverage vertex attrs // Make verts point to vertex color and then set all the color and coverage vertex attrs
// values. // values.
verts += sizeof(SkPoint); verts += sizeof(SkPoint);
// The coverage offset is always the last vertex attribute
intptr_t coverageOffset = vertexStride - sizeof(GrColor) - sizeof(SkPoint);
for (int i = 0; i < 4; ++i) { for (int i = 0; i < 4; ++i) {
if (tweakAlphaForCoverage) { if (tweakAlphaForCoverage) {
*reinterpret_cast<GrColor*>(verts + i * vertexStride) = 0; *reinterpret_cast<GrColor*>(verts + i * vertexStride) = 0;
} else { } else {
*reinterpret_cast<GrColor*>(verts + i * vertexStride) = args.fColor; *reinterpret_cast<GrColor*>(verts + i * vertexStride) = args.fColor;
*reinterpret_cast<float*>(verts + i * vertexStride + sizeof(GrColor)) = 0; *reinterpret_cast<float*>(verts + i * vertexStride + coverageOffset) = 0;
} }
} }
@ -278,7 +281,7 @@ private:
} else { } else {
*reinterpret_cast<GrColor*>(verts + i * vertexStride) = args.fColor; *reinterpret_cast<GrColor*>(verts + i * vertexStride) = args.fColor;
*reinterpret_cast<float*>(verts + i * vertexStride + *reinterpret_cast<float*>(verts + i * vertexStride +
sizeof(GrColor)) = innerCoverage; coverageOffset) = innerCoverage;
} }
} }
} }
@ -392,7 +395,7 @@ public:
} }
SkMatrix localCoordMatrix; SkMatrix localCoordMatrix;
localCoordMatrix.setConcat(args.fLocalMatrix, invViewMatrix); localCoordMatrix.setConcat(args.fLocalMatrix, invViewMatrix);
SkPoint* fan0Loc = reinterpret_cast<SkPoint*>(vertices + vertexStride - sizeof(SkPoint)); SkPoint* fan0Loc = reinterpret_cast<SkPoint*>(vertices + sizeof(SkPoint) + sizeof(GrColor));
localCoordMatrix.mapPointsWithStride(fan0Loc, fan0Pos, vertexStride, 8); localCoordMatrix.mapPointsWithStride(fan0Loc, fan0Pos, vertexStride, 8);
} }
}; };

View File

@ -23,10 +23,10 @@ class SkStrokeRec;
namespace GrRectBatchFactory { namespace GrRectBatchFactory {
inline GrDrawBatch* CreateFillBW(GrColor color, inline GrDrawBatch* CreateFillBW(GrColor color,
const SkMatrix& viewMatrix, const SkMatrix& viewMatrix,
const SkRect& rect, const SkRect& rect,
const SkRect* localRect, const SkRect* localRect,
const SkMatrix* localMatrix) { const SkMatrix* localMatrix) {
return GrBWFillRectBatch::Create(color, viewMatrix, rect, localRect, localMatrix); return GrBWFillRectBatch::Create(color, viewMatrix, rect, localRect, localMatrix);
} }
@ -37,6 +37,14 @@ inline GrDrawBatch* CreateFillAA(GrColor color,
return GrAAFillRectBatch::Create(color, viewMatrix, rect, devRect); return GrAAFillRectBatch::Create(color, viewMatrix, rect, devRect);
} }
inline GrDrawBatch* CreateFillAA(GrColor color,
const SkMatrix& viewMatrix,
const SkMatrix& localMatrix,
const SkRect& rect,
const SkRect& devRect) {
return GrAAFillRectBatch::Create(color, viewMatrix, localMatrix, rect, devRect);
}
GrDrawBatch* CreateStrokeBW(GrColor color, GrDrawBatch* CreateStrokeBW(GrColor color,
const SkMatrix& viewMatrix, const SkMatrix& viewMatrix,
const SkRect& rect, const SkRect& rect,