Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(254)

Unified Diff: src/gpu/SkGpuDevice.cpp

Issue 264303008: Disable filtering in draw Bitmap operation when pixels are aligned (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « include/gpu/SkGpuDevice.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/gpu/SkGpuDevice.cpp
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index 4af16109a4b6df1481c65ce98306277f732ce5ca..a767f4dfc34262fc71b728865a6d46ba03a8e66b 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -1137,6 +1137,74 @@ static inline void clamped_outset_with_offset(SkIRect* iRect,
}
}
+static bool has_aligned_samples(const SkRect& srcRect,
+ const SkRect& transformedRect) {
+ // detect pixel disalignment
+ if (SkScalarAbs(SkScalarRoundToScalar(transformedRect.left()) -
+ transformedRect.left()) < COLOR_BLEED_TOLERANCE &&
+ SkScalarAbs(SkScalarRoundToScalar(transformedRect.top()) -
+ transformedRect.top()) < COLOR_BLEED_TOLERANCE &&
+ SkScalarAbs(transformedRect.width() - srcRect.width()) <
+ COLOR_BLEED_TOLERANCE &&
+ SkScalarAbs(transformedRect.height() - srcRect.height()) <
+ COLOR_BLEED_TOLERANCE) {
+ return true;
+ }
+ return false;
+}
+
+static bool may_color_bleed(const SkRect& srcRect,
+ const SkRect& transformedRect,
+ const SkMatrix& m) {
+ // Only gets called if has_aligned_samples returned false.
+ // So we can assume that sampling is axis aligned but not texel aligned.
+ SkASSERT(!has_aligned_samples(srcRect, transformedRect));
+ SkRect innerSrcRect(srcRect), innerTransformedRect,
+ outerTransformedRect(transformedRect);
+ innerSrcRect.inset(SK_ScalarHalf, SK_ScalarHalf);
+ m.mapRect(&innerTransformedRect, innerSrcRect);
+
+ // The gap between outerTransformedRect and innerTransformedRect
+ // represents the projection of the source border area, which is
+ // problematic for color bleeding. We must check whether any
+ // destination pixels sample the border area.
+ outerTransformedRect.inset(COLOR_BLEED_TOLERANCE, COLOR_BLEED_TOLERANCE);
+ innerTransformedRect.outset(COLOR_BLEED_TOLERANCE, COLOR_BLEED_TOLERANCE);
+ SkIRect outer, inner;
+ outerTransformedRect.round(&outer);
+ innerTransformedRect.round(&inner);
+ // If the inner and outer rects round to the same result, it means the
+ // border does not overlap any pixel centers. Yay!
+ return inner != outer;
+}
+
+bool SkGpuDevice::needsTextureDomain(const SkBitmap& bitmap,
+ const SkRect& srcRect,
+ GrTextureParams &params,
+ bool bicubic) {
+ bool needsTextureDomain = false;
+
+ if (bicubic || params.filterMode() != GrTextureParams::kNone_FilterMode) {
+ // Need texture domain if drawing a sub rect
+ needsTextureDomain = srcRect.width() < bitmap.width() ||
+ srcRect.height() < bitmap.height();
+ if (!bicubic && needsTextureDomain && fContext->getMatrix().rectStaysRect()) {
+ const SkMatrix& matrix = fContext->getMatrix();
bsalomon 2014/05/08 14:13:23 Is accessing the matrix the only reason why this i
+ // sampling is axis-aligned
+ SkRect transformedRect;
+ matrix.mapRect(&transformedRect, srcRect);
+
+ if (has_aligned_samples(srcRect, transformedRect)) {
+ params.setFilterMode(GrTextureParams::kNone_FilterMode);
+ needsTextureDomain = false;
+ } else {
+ needsTextureDomain = may_color_bleed(srcRect, transformedRect, matrix);
+ }
+ }
+ }
+ return needsTextureDomain;
+}
+
void SkGpuDevice::drawBitmapCommon(const SkDraw& draw,
const SkBitmap& bitmap,
const SkRect* srcRectPtr,
@@ -1275,7 +1343,14 @@ void SkGpuDevice::drawBitmapCommon(const SkDraw& draw,
doBicubic);
} else {
// take the simple case
- this->internalDrawBitmap(bitmap, srcRect, params, paint, flags, doBicubic);
+ bool needsTextureDomain = this->needsTextureDomain(bitmap, srcRect, params, doBicubic);
+ this->internalDrawBitmap(bitmap,
+ srcRect,
+ params,
+ paint,
+ flags,
+ doBicubic,
+ needsTextureDomain);
}
}
@@ -1341,54 +1416,23 @@ void SkGpuDevice::drawTiledBitmap(const SkBitmap& bitmap,
if (bitmap.extractSubset(&tmpB, iTileR)) {
// now offset it to make it "local" to our tmp bitmap
tileR.offset(-offset.fX, -offset.fY);
-
- this->internalDrawBitmap(tmpB, tileR, params, paint, flags, bicubic);
+ GrTextureParams paramsTemp = params;
+ bool needsTextureDomain = this->needsTextureDomain(bitmap,
+ srcRect,
+ paramsTemp,
+ bicubic);
+ this->internalDrawBitmap(tmpB,
+ tileR,
+ paramsTemp,
+ paint,
+ flags,
+ bicubic,
+ needsTextureDomain);
}
}
}
}
-static bool has_aligned_samples(const SkRect& srcRect,
- const SkRect& transformedRect) {
- // detect pixel disalignment
- if (SkScalarAbs(SkScalarRoundToScalar(transformedRect.left()) -
- transformedRect.left()) < COLOR_BLEED_TOLERANCE &&
- SkScalarAbs(SkScalarRoundToScalar(transformedRect.top()) -
- transformedRect.top()) < COLOR_BLEED_TOLERANCE &&
- SkScalarAbs(transformedRect.width() - srcRect.width()) <
- COLOR_BLEED_TOLERANCE &&
- SkScalarAbs(transformedRect.height() - srcRect.height()) <
- COLOR_BLEED_TOLERANCE) {
- return true;
- }
- return false;
-}
-
-static bool may_color_bleed(const SkRect& srcRect,
- const SkRect& transformedRect,
- const SkMatrix& m) {
- // Only gets called if has_aligned_samples returned false.
- // So we can assume that sampling is axis aligned but not texel aligned.
- SkASSERT(!has_aligned_samples(srcRect, transformedRect));
- SkRect innerSrcRect(srcRect), innerTransformedRect,
- outerTransformedRect(transformedRect);
- innerSrcRect.inset(SK_ScalarHalf, SK_ScalarHalf);
- m.mapRect(&innerTransformedRect, innerSrcRect);
-
- // The gap between outerTransformedRect and innerTransformedRect
- // represents the projection of the source border area, which is
- // problematic for color bleeding. We must check whether any
- // destination pixels sample the border area.
- outerTransformedRect.inset(COLOR_BLEED_TOLERANCE, COLOR_BLEED_TOLERANCE);
- innerTransformedRect.outset(COLOR_BLEED_TOLERANCE, COLOR_BLEED_TOLERANCE);
- SkIRect outer, inner;
- outerTransformedRect.round(&outer);
- innerTransformedRect.round(&inner);
- // If the inner and outer rects round to the same result, it means the
- // border does not overlap any pixel centers. Yay!
- return inner != outer;
-}
-
/*
* This is called by drawBitmap(), which has to handle images that may be too
@@ -1402,7 +1446,8 @@ void SkGpuDevice::internalDrawBitmap(const SkBitmap& bitmap,
const GrTextureParams& params,
const SkPaint& paint,
SkCanvas::DrawBitmapRectFlags flags,
- bool bicubic) {
+ bool bicubic,
+ bool needsTextureDomain) {
SkASSERT(bitmap.width() <= fContext->getMaxTextureSize() &&
bitmap.height() <= fContext->getMaxTextureSize());
@@ -1421,31 +1466,9 @@ void SkGpuDevice::internalDrawBitmap(const SkBitmap& bitmap,
SkScalarMul(srcRect.fRight, wInv),
SkScalarMul(srcRect.fBottom, hInv));
- bool needsTextureDomain = false;
- if (!(flags & SkCanvas::kBleed_DrawBitmapRectFlag) &&
- (bicubic || params.filterMode() != GrTextureParams::kNone_FilterMode)) {
- // Need texture domain if drawing a sub rect
- needsTextureDomain = srcRect.width() < bitmap.width() ||
- srcRect.height() < bitmap.height();
- if (!bicubic && needsTextureDomain && fContext->getMatrix().rectStaysRect()) {
- const SkMatrix& matrix = fContext->getMatrix();
- // sampling is axis-aligned
- SkRect transformedRect;
- matrix.mapRect(&transformedRect, srcRect);
-
- if (has_aligned_samples(srcRect, transformedRect)) {
- // We could also turn off filtering here (but we already did a cache lookup with
- // params).
- needsTextureDomain = false;
- } else {
- needsTextureDomain = may_color_bleed(srcRect, transformedRect, matrix);
- }
- }
- }
-
SkRect textureDomain = SkRect::MakeEmpty();
SkAutoTUnref<GrEffectRef> effect;
- if (needsTextureDomain) {
+ if (needsTextureDomain && !(flags & SkCanvas::kBleed_DrawBitmapRectFlag)) {
// Use a constrained texture domain to avoid color bleeding
SkScalar left, top, right, bottom;
if (srcRect.width() > SK_Scalar1) {
« no previous file with comments | « include/gpu/SkGpuDevice.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698