Compute clipped src rect once in tiled bitmap draws
R=robertphillips@google.com
Author: bsalomon@google.com
Review URL: https://codereview.chromium.org/40403002
git-svn-id: http://skia.googlecode.com/svn/trunk@11962 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/include/gpu/SkGpuDevice.h b/include/gpu/SkGpuDevice.h
index 81e0324..0862514 100644
--- a/include/gpu/SkGpuDevice.h
+++ b/include/gpu/SkGpuDevice.h
@@ -184,13 +184,16 @@
/**
* Helper functions called by drawBitmapCommon. By the time these are called the SkDraw's
- * matrix has already been set on GrContext
+ * matrix, clip, and the device's render target has already been set on GrContext.
*/
+
+ // The tileSize and clippedSrcRect will be valid only if true is returned.
bool shouldTileBitmap(const SkBitmap& bitmap,
const GrTextureParams& sampler,
const SkRect* srcRectPtr,
int maxTileSize,
- int* tileSize) const;
+ int* tileSize,
+ SkIRect* clippedSrcRect) const;
void internalDrawBitmap(const SkBitmap&,
const SkRect&,
const GrTextureParams& params,
@@ -198,6 +201,7 @@
SkCanvas::DrawBitmapRectFlags flags);
void drawTiledBitmap(const SkBitmap& bitmap,
const SkRect& srcRect,
+ const SkIRect& clippedSrcRect,
const GrTextureParams& params,
const SkPaint& paint,
SkCanvas::DrawBitmapRectFlags flags,
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index db440c1..6427f77 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -1032,23 +1032,21 @@
}
}
-
bool SkGpuDevice::shouldTileBitmap(const SkBitmap& bitmap,
const GrTextureParams& params,
const SkRect* srcRectPtr,
int maxTileSize,
- int* tileSize) const {
+ int* tileSize,
+ SkIRect* clippedSrcRect) const {
// if bitmap is explictly texture backed then just use the texture
if (NULL != bitmap.getTexture()) {
return false;
}
- SkIRect clippedSrcRect;
-
// if it's larger than the max tile size, then we have no choice but tiling.
if (bitmap.width() > maxTileSize || bitmap.height() > maxTileSize) {
- determine_clipped_src_rect(fContext, bitmap, srcRectPtr, &clippedSrcRect);
- *tileSize = determine_tile_size(bitmap, clippedSrcRect, maxTileSize);
+ determine_clipped_src_rect(fContext, bitmap, srcRectPtr, clippedSrcRect);
+ *tileSize = determine_tile_size(bitmap, *clippedSrcRect, maxTileSize);
return true;
}
@@ -1076,9 +1074,9 @@
}
// Figure out how much of the src we will need based on the src rect and clipping.
- determine_clipped_src_rect(fContext, bitmap, srcRectPtr, &clippedSrcRect);
+ determine_clipped_src_rect(fContext, bitmap, srcRectPtr, clippedSrcRect);
*tileSize = kBmpSmallTileSize; // already know whole bitmap fits in one max sized tile.
- size_t usedTileBytes = get_tile_count(clippedSrcRect, kBmpSmallTileSize) *
+ size_t usedTileBytes = get_tile_count(*clippedSrcRect, kBmpSmallTileSize) *
kBmpSmallTileSize * kBmpSmallTileSize;
return usedTileBytes < 2 * bmpSize;
@@ -1219,8 +1217,10 @@
}
int tileSize;
- if (this->shouldTileBitmap(bitmap, params, srcRectPtr, maxTileSize, &tileSize)) {
- this->drawTiledBitmap(bitmap, srcRect, params, paint, flags, tileSize);
+ SkIRect clippedSrcRect;
+ if (this->shouldTileBitmap(bitmap, params, srcRectPtr, maxTileSize, &tileSize,
+ &clippedSrcRect)) {
+ this->drawTiledBitmap(bitmap, srcRect, clippedSrcRect, params, paint, flags, tileSize);
} else {
// take the simple case
this->internalDrawBitmap(bitmap, srcRect, params, paint, flags);
@@ -1231,25 +1231,12 @@
// been determined to be too large to fit in VRAM
void SkGpuDevice::drawTiledBitmap(const SkBitmap& bitmap,
const SkRect& srcRect,
+ const SkIRect& clippedSrcIRect,
const GrTextureParams& params,
const SkPaint& paint,
SkCanvas::DrawBitmapRectFlags flags,
int tileSize) {
-
- // compute clip bounds in local coordinates
- SkRect clipRect;
- {
- const GrRenderTarget* rt = fContext->getRenderTarget();
- clipRect.setWH(SkIntToScalar(rt->width()), SkIntToScalar(rt->height()));
- if (!fContext->getClip()->fClipStack->intersectRectWithClip(&clipRect)) {
- return;
- }
- SkMatrix inverse;
- if (!fContext->getMatrix().invert(&inverse)) {
- return;
- }
- inverse.mapRect(&clipRect);
- }
+ SkRect clippedSrcRect = SkRect::MakeFromIRect(clippedSrcIRect);
int nx = bitmap.width() / tileSize;
int ny = bitmap.height() / tileSize;
@@ -1261,7 +1248,7 @@
SkIntToScalar((x + 1) * tileSize),
SkIntToScalar((y + 1) * tileSize));
- if (!SkRect::Intersects(tileR, clipRect)) {
+ if (!SkRect::Intersects(tileR, clippedSrcRect)) {
continue;
}