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:
parent
b279668c64
commit
a61c817272
@ -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, ¶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,
|
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;
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -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,
|
||||||
|
Loading…
Reference in New Issue
Block a user