diff options
-rw-r--r-- | src/gpu/SkGpuDevice.cpp | 107 | ||||
-rw-r--r-- | src/gpu/batches/GrAAFillRectBatch.cpp | 9 | ||||
-rw-r--r-- | src/gpu/batches/GrRectBatchFactory.h | 16 |
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, ¶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; } 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, |