diff options
author | bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2012-10-11 19:39:09 +0000 |
---|---|---|
committer | bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2012-10-11 19:39:09 +0000 |
commit | 3ab43d5c5b4d77f46dd0266618f92e5fefce2021 (patch) | |
tree | 2950bae414b8cc85a61d350f945ccc55affd52d6 /src | |
parent | 5dc26b97366934ba0f896cea02a3fec027d5d5c1 (diff) |
Minimize use of SkDraw's matrix in SkGpuDevice.
R=robertphillips@google.com
Review URL: https://codereview.appspot.com/6604068
git-svn-id: http://skia.googlecode.com/svn/trunk@5906 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src')
-rw-r--r-- | src/core/SkClipStack.cpp | 19 | ||||
-rw-r--r-- | src/gpu/SkGpuDevice.cpp | 90 |
2 files changed, 64 insertions, 45 deletions
diff --git a/src/core/SkClipStack.cpp b/src/core/SkClipStack.cpp index 3c9705dcae..6fca0fc89e 100644 --- a/src/core/SkClipStack.cpp +++ b/src/core/SkClipStack.cpp @@ -567,6 +567,25 @@ void SkClipStack::getBounds(SkRect* canvFiniteBound, } } +bool SkClipStack::intersectRectWithClip(SkRect* rect) const { + SkASSERT(NULL != rect); + + SkRect bounds; + SkClipStack::BoundsType bt; + this->getBounds(&bounds, &bt); + if (bt == SkClipStack::kInsideOut_BoundsType) { + if (bounds.contains(*rect)) { + return false; + } else { + // If rect's x values are both within bound's x range we + // could clip here. Same for y. But we don't bother to check. + return true; + } + } else { + return rect->intersect(bounds); + } +} + void SkClipStack::clipDevRect(const SkRect& rect, SkRegion::Op op, bool doAA) { int32_t genID = GetNextGenID(); diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp index df7754db24..d94a8dd63e 100644 --- a/src/gpu/SkGpuDevice.cpp +++ b/src/gpu/SkGpuDevice.cpp @@ -686,7 +686,7 @@ void SkGpuDevice::drawPoints(const SkDraw& draw, SkCanvas::PointMode mode, /////////////////////////////////////////////////////////////////////////////// void SkGpuDevice::drawRect(const SkDraw& draw, const SkRect& rect, - const SkPaint& paint) { + const SkPaint& paint) { CHECK_FOR_NODRAW_ANNOTATION(paint); CHECK_SHOULD_DRAW(draw); @@ -704,7 +704,7 @@ void SkGpuDevice::drawRect(const SkDraw& draw, const SkRect& rect, usePath = true; } // until we aa rotated rects... - if (!usePath && paint.isAntiAlias() && !draw.fMatrix->rectStaysRect()) { + if (!usePath && paint.isAntiAlias() && !fContext->getMatrix().rectStaysRect()) { usePath = true; } // small miter limit means right angles show bevel... @@ -773,10 +773,9 @@ inline bool shouldDrawBlurWithCPU(const SkRect& rect, SkScalar radius) { return false; } -bool drawWithGPUMaskFilter(GrContext* context, const SkPath& path, - SkMaskFilter* filter, const SkMatrix& matrix, - const SkRegion& clip, SkBounder* bounder, - GrPaint* grp, GrPathFill pathFillType) { +bool drawWithGPUMaskFilter(GrContext* context, const SkPath& devPath, + SkMaskFilter* filter, const SkRegion& clip, + SkBounder* bounder, GrPaint* grp, GrPathFill pathFillType) { #ifdef SK_DISABLE_GPU_BLUR return false; #endif @@ -786,13 +785,13 @@ bool drawWithGPUMaskFilter(GrContext* context, const SkPath& path, return false; } SkScalar radius = info.fIgnoreTransform ? info.fRadius - : matrix.mapRadius(info.fRadius); + : context->getMatrix().mapRadius(info.fRadius); radius = SkMinScalar(radius, MAX_BLUR_RADIUS); if (radius <= 0) { return false; } - SkRect srcRect = path.getBounds(); + SkRect srcRect = devPath.getBounds(); if (shouldDrawBlurWithCPU(srcRect, radius)) { return false; } @@ -838,6 +837,8 @@ bool drawWithGPUMaskFilter(GrContext* context, const SkPath& path, SkAutoTUnref<GrTexture> blurTexture; + GrMatrix origMatrix = context->getMatrix(); + // We pass kPreserve here. We will replace the current matrix below. GrContext::AutoMatrix avm(context, GrContext::AutoMatrix::kPreserve_InitialMatrix); @@ -846,8 +847,12 @@ bool drawWithGPUMaskFilter(GrContext* context, const SkPath& path, GrContext::AutoClip ac(context, srcRect); context->clear(NULL, 0); - GrPaint tempPaint; + // Draw hard shadow to pathTexture with path top-left at origin 0,0. + GrMatrix translate; + translate.setTranslate(offset.fX, offset.fY); + + GrPaint tempPaint; if (grp->isAntiAlias()) { tempPaint.setAntiAlias(true); // AA uses the "coverage" stages on GrDrawTarget. Coverage with a dst @@ -858,11 +863,8 @@ bool drawWithGPUMaskFilter(GrContext* context, const SkPath& path, // use a zero dst coeff when dual source blending isn't available. tempPaint.setBlendFunc(kOne_GrBlendCoeff, kISC_GrBlendCoeff); } - // Draw hard shadow to pathTexture with path top-left at origin 0,0. - GrMatrix translate; - translate.setTranslate(offset.fX, offset.fY); context->setMatrix(translate); - context->drawPath(tempPaint, path, pathFillType); + context->drawPath(tempPaint, devPath, pathFillType); // switch to device coord drawing when going back to the main RT. context->setIdentityMatrix(); @@ -898,7 +900,7 @@ bool drawWithGPUMaskFilter(GrContext* context, const SkPath& path, } } - if (!grp->preConcatSamplerMatricesWithInverse(matrix)) { + if (!grp->preConcatSamplerMatricesWithInverse(origMatrix)) { return false; } @@ -916,20 +918,18 @@ bool drawWithGPUMaskFilter(GrContext* context, const SkPath& path, return true; } -bool drawWithMaskFilter(GrContext* context, const SkPath& path, - SkMaskFilter* filter, const SkMatrix& matrix, - const SkRegion& clip, SkBounder* bounder, +bool drawWithMaskFilter(GrContext* context, const SkPath& devPath, + SkMaskFilter* filter, const SkRegion& clip, SkBounder* bounder, GrPaint* grp, SkPaint::Style style) { SkMask srcM, dstM; - if (!SkDraw::DrawToMask(path, &clip.getBounds(), filter, &matrix, &srcM, - SkMask::kComputeBoundsAndRenderImage_CreateMode, - style)) { + if (!SkDraw::DrawToMask(devPath, &clip.getBounds(), filter, &context->getMatrix(), &srcM, + SkMask::kComputeBoundsAndRenderImage_CreateMode, style)) { return false; } SkAutoMaskFreeImage autoSrc(srcM.fImage); - if (!filter->filterMask(&dstM, srcM, matrix, NULL)) { + if (!filter->filterMask(&dstM, srcM, context->getMatrix(), NULL)) { return false; } // this will free-up dstM when we're done (allocated in filterMask()) @@ -945,12 +945,12 @@ bool drawWithMaskFilter(GrContext* context, const SkPath& path, // we now have a device-aligned 8bit mask in dstM, ready to be drawn using // the current clip (and identity matrix) and grpaint settings - GrContext::AutoMatrix avm(context, GrMatrix::I()); - - if (!grp->preConcatSamplerMatricesWithInverse(matrix)) { + if (!grp->preConcatSamplerMatricesWithInverse(context->getMatrix())) { return false; } + GrContext::AutoMatrix avm(context, GrMatrix::I()); + GrTextureDesc desc; desc.fWidth = dstM.fBounds.width(); desc.fHeight = dstM.fBounds.height(); @@ -1010,7 +1010,7 @@ void SkGpuDevice::drawPath(const SkDraw& draw, const SkPath& origSrcPath, // can we cheat, and threat a thin stroke as a hairline w/ coverage // if we can, we draw lots faster (raster device does this same test) SkScalar hairlineCoverage; - if (SkDrawTreatAsHairline(paint, *draw.fMatrix, &hairlineCoverage)) { + if (SkDrawTreatAsHairline(paint, fContext->getMatrix(), &hairlineCoverage)) { doFill = false; grPaint.setCoverage(SkScalarRoundToInt(hairlineCoverage * grPaint.getCoverage())); } @@ -1050,17 +1050,15 @@ void SkGpuDevice::drawPath(const SkDraw& draw, const SkPath& origSrcPath, SkPath* devPathPtr = pathIsMutable ? pathPtr : &tmpPath; // transform the path into device space - pathPtr->transform(*draw.fMatrix, devPathPtr); + pathPtr->transform(fContext->getMatrix(), devPathPtr); GrPathFill pathFillType = doFill ? skToGrFillType(devPathPtr->getFillType()) : kHairLine_GrPathFill; if (!drawWithGPUMaskFilter(fContext, *devPathPtr, paint.getMaskFilter(), - *draw.fMatrix, *draw.fClip, draw.fBounder, - &grPaint, pathFillType)) { + *draw.fClip, draw.fBounder, &grPaint, pathFillType)) { SkPaint::Style style = doFill ? SkPaint::kFill_Style : SkPaint::kStroke_Style; drawWithMaskFilter(fContext, *devPathPtr, paint.getMaskFilter(), - *draw.fMatrix, *draw.fClip, draw.fBounder, - &grPaint, style); + *draw.fClip, draw.fBounder, &grPaint, style); } return; } @@ -1235,11 +1233,11 @@ void SkGpuDevice::drawBitmapCommon(const SkDraw& draw, paintWithTexture.setShader(SkShader::CreateBitmapShader(*bitmapPtr, SkShader::kClamp_TileMode, SkShader::kClamp_TileMode))->unref(); - // Transform 'newM' needs to be concatenated to the draw matrix, + // Transform 'newM' needs to be concatenated to the current matrix, // rather than transforming the primitive directly, so that 'newM' will // also affect the behavior of the mask filter. SkMatrix drawMatrix; - drawMatrix.setConcat(*draw.fMatrix, newM); + drawMatrix.setConcat(fContext->getMatrix(), newM); SkDraw transformedDraw(draw); transformedDraw.fMatrix = &drawMatrix; @@ -1258,16 +1256,15 @@ void SkGpuDevice::drawBitmapCommon(const SkDraw& draw, if (!this->shouldTileBitmap(bitmap, params, srcRectPtr)) { // take the simple case - this->internalDrawBitmap(draw, bitmap, srcRect, m, params, &grPaint); + this->internalDrawBitmap(bitmap, srcRect, m, params, &grPaint); } else { - this->drawTiledBitmap(draw, bitmap, srcRect, m, params, &grPaint); + this->drawTiledBitmap(bitmap, srcRect, m, params, &grPaint); } } // Break 'bitmap' into several tiles to draw it since it has already // been determined to be too large to fit in VRAM -void SkGpuDevice::drawTiledBitmap(const SkDraw& draw, - const SkBitmap& bitmap, +void SkGpuDevice::drawTiledBitmap(const SkBitmap& bitmap, const SkRect& srcRect, const SkMatrix& m, const GrTextureParams& params, @@ -1279,9 +1276,13 @@ void SkGpuDevice::drawTiledBitmap(const SkDraw& draw, // compute clip bounds in local coordinates SkRect clipRect; { - clipRect.set(draw.fClip->getBounds()); + const GrRenderTarget* rt = fContext->getRenderTarget(); + clipRect.setWH(SkIntToScalar(rt->width()), SkIntToScalar(rt->height())); + if (!fContext->getClip()->fClipStack->intersectRectWithClip(&clipRect)) { + return; + } SkMatrix matrix, inverse; - matrix.setConcat(*draw.fMatrix, m); + matrix.setConcat(fContext->getMatrix(), m); if (!matrix.invert(&inverse)) { return; } @@ -1316,7 +1317,7 @@ void SkGpuDevice::drawTiledBitmap(const SkDraw& draw, tmpM.preTranslate(SkIntToScalar(iTileR.fLeft), SkIntToScalar(iTileR.fTop)); - this->internalDrawBitmap(draw, tmpB, tileR, tmpM, params, grPaint); + this->internalDrawBitmap(tmpB, tileR, tmpM, params, grPaint); } } } @@ -1372,8 +1373,7 @@ bool mayColorBleed(const SkRect& srcRect, const SkRect& transformedRect, * internalDrawBitmap assumes that the specified bitmap will fit in a texture * and that non-texture portion of the GrPaint has already been setup. */ -void SkGpuDevice::internalDrawBitmap(const SkDraw& draw, - const SkBitmap& bitmap, +void SkGpuDevice::internalDrawBitmap(const SkBitmap& bitmap, const SkRect& srcRect, const SkMatrix& m, const GrTextureParams& params, @@ -1411,11 +1411,11 @@ void SkGpuDevice::internalDrawBitmap(const SkDraw& draw, // Need texture domain if drawing a sub rect. needsTextureDomain = srcRect.width() < bitmap.width() || srcRect.height() < bitmap.height(); - if (m.rectStaysRect() && draw.fMatrix->rectStaysRect()) { + if (m.rectStaysRect() && fContext->getMatrix().rectStaysRect()) { // sampling is axis-aligned GrRect transformedRect; SkMatrix srcToDeviceMatrix(m); - srcToDeviceMatrix.postConcat(*draw.fMatrix); + srcToDeviceMatrix.postConcat(fContext->getMatrix()); srcToDeviceMatrix.mapRect(&transformedRect, srcRect); if (hasAlignedSamples(srcRect, transformedRect)) { @@ -1802,7 +1802,7 @@ void SkGpuDevice::drawText(const SkDraw& draw, const void* text, const SkPaint& paint) { CHECK_SHOULD_DRAW(draw); - if (draw.fMatrix->hasPerspective()) { + if (fContext->getMatrix().hasPerspective()) { // this guy will just call our drawPath() draw.drawText((const char*)text, byteLength, x, y, paint); } else { @@ -1829,7 +1829,7 @@ void SkGpuDevice::drawPosText(const SkDraw& draw, const void* text, const SkPaint& paint) { CHECK_SHOULD_DRAW(draw); - if (draw.fMatrix->hasPerspective()) { + if (fContext->getMatrix().hasPerspective()) { // this guy will just call our drawPath() draw.drawPosText((const char*)text, byteLength, pos, constY, scalarsPerPos, paint); |