aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-10-11 19:39:09 +0000
committerGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-10-11 19:39:09 +0000
commit3ab43d5c5b4d77f46dd0266618f92e5fefce2021 (patch)
tree2950bae414b8cc85a61d350f945ccc55affd52d6 /src
parent5dc26b97366934ba0f896cea02a3fec027d5d5c1 (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.cpp19
-rw-r--r--src/gpu/SkGpuDevice.cpp90
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);