aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/gpu/SkGpuDevice.cpp107
-rw-r--r--src/gpu/batches/GrAAFillRectBatch.cpp9
-rw-r--r--src/gpu/batches/GrRectBatchFactory.h16
3 files changed, 114 insertions, 18 deletions
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index f8318c52d8..7052d2531c 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, &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,
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;
}
diff --git a/src/gpu/batches/GrAAFillRectBatch.cpp b/src/gpu/batches/GrAAFillRectBatch.cpp
index 94cc5ce635..d8ef3d3152 100644
--- a/src/gpu/batches/GrAAFillRectBatch.cpp
+++ b/src/gpu/batches/GrAAFillRectBatch.cpp
@@ -250,12 +250,15 @@ private:
// Make verts point to vertex color and then set all the color and coverage vertex attrs
// values.
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) {
if (tweakAlphaForCoverage) {
*reinterpret_cast<GrColor*>(verts + i * vertexStride) = 0;
} else {
*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 {
*reinterpret_cast<GrColor*>(verts + i * vertexStride) = args.fColor;
*reinterpret_cast<float*>(verts + i * vertexStride +
- sizeof(GrColor)) = innerCoverage;
+ coverageOffset) = innerCoverage;
}
}
}
@@ -392,7 +395,7 @@ public:
}
SkMatrix localCoordMatrix;
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);
}
};
diff --git a/src/gpu/batches/GrRectBatchFactory.h b/src/gpu/batches/GrRectBatchFactory.h
index 7eaec795e8..5a43a34214 100644
--- a/src/gpu/batches/GrRectBatchFactory.h
+++ b/src/gpu/batches/GrRectBatchFactory.h
@@ -23,10 +23,10 @@ class SkStrokeRec;
namespace GrRectBatchFactory {
inline GrDrawBatch* CreateFillBW(GrColor color,
- const SkMatrix& viewMatrix,
- const SkRect& rect,
- const SkRect* localRect,
- const SkMatrix* localMatrix) {
+ const SkMatrix& viewMatrix,
+ const SkRect& rect,
+ const SkRect* localRect,
+ const SkMatrix* 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);
}
+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,
const SkMatrix& viewMatrix,
const SkRect& rect,