diff options
author | 2011-06-30 22:16:06 +0000 | |
---|---|---|
committer | 2011-06-30 22:16:06 +0000 | |
commit | 22c8bb8ebddcf695035b7f9c7f47405ae160b485 (patch) | |
tree | 7c31425a504294ec1e2a646f0ac3ae5789120772 | |
parent | 3582bf9e3d94feac5d4cc64fdb646dd68a3e4b18 (diff) |
Fixing several issues with rendering blurred bitmaps with Ganesh
BUG=http://code.google.com/p/skia/issues/detail?id=305
REVIEW=http://codereview.appspot.com/4630073/
git-svn-id: http://skia.googlecode.com/svn/trunk@1775 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r-- | include/core/SkBitmap.h | 2 | ||||
-rwxr-xr-x | samplecode/SampleTextureDomain.cpp | 10 | ||||
-rw-r--r-- | src/gpu/SkGpuDevice.cpp | 49 |
3 files changed, 40 insertions, 21 deletions
diff --git a/include/core/SkBitmap.h b/include/core/SkBitmap.h index 58af571b95..469252aefe 100644 --- a/include/core/SkBitmap.h +++ b/include/core/SkBitmap.h @@ -464,7 +464,7 @@ public: */ inline SkPMColor getIndex8Color(int x, int y) const; - /** Set dst to be a setset of this bitmap. If possible, it will share the + /** Set dst to be a subset of this bitmap. If possible, it will share the pixel memory, and just point into a subset of it. However, if the config does not support this, a local copy will be made and associated with the dst bitmap. If the subset rectangle, intersected with the bitmap's diff --git a/samplecode/SampleTextureDomain.cpp b/samplecode/SampleTextureDomain.cpp index 1f895e5d91..939dbcd1c6 100755 --- a/samplecode/SampleTextureDomain.cpp +++ b/samplecode/SampleTextureDomain.cpp @@ -77,15 +77,21 @@ protected: SkMaskFilter* mf = SkBlurMaskFilter::Create( 5, SkBlurMaskFilter::kNormal_BlurStyle, - SkBlurMaskFilter::kHighQuality_BlurFlag); + SkBlurMaskFilter::kHighQuality_BlurFlag | + SkBlurMaskFilter::kIgnoreTransform_BlurFlag ); paint.setMaskFilter(mf)->unref(); canvas->drawBitmapRect(deviceBitmap, &srcRect, dstRect, &paint); - // Blur and a rotation + NULL src rect + // Blur and a rotation + NULL src rect + transform applies to filter // This should not trigger the texture domain code // but it will test a code path in SkGpuDevice::drawBitmap // that handles blurs with rects transformed to non- // orthogonal rects. It also tests the NULL src rect handling + mf = SkBlurMaskFilter::Create( + 3, + SkBlurMaskFilter::kNormal_BlurStyle, + SkBlurMaskFilter::kHighQuality_BlurFlag); + paint.setMaskFilter(mf)->unref(); dstRect.setXYWH(-150.0f, -150.0f, 300.0f, 300.0f); canvas->translate(550, 550); canvas->rotate(45); diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp index 4f2d7c48c1..af31ee57b2 100644 --- a/src/gpu/SkGpuDevice.cpp +++ b/src/gpu/SkGpuDevice.cpp @@ -962,33 +962,46 @@ void SkGpuDevice::drawBitmap(const SkDraw& draw, } if (paint.getMaskFilter()){ - SkBitmap tmp; // storage if we need a subset of bitmap + SkBitmap tmpBitmap; // local copy of bitmap const SkBitmap* bitmapPtr = &bitmap; - if (srcRectPtr) { - if (!bitmap.extractSubset(&tmp, srcRect)) { - return; // extraction failed - } - bitmapPtr = &tmp; + + // FIXME : texture-backed bitmaps not yet supported + SkAutoLockPixels alp(bitmap); + if (!bitmap.getPixels()) + return; + + // A temporary copy of the bitmap may be necessary + // to prevent color bleeding if a sub rect is used + if (NULL != srcRectPtr) { + tmpBitmap.setConfig(bitmap.config(), srcRect.width(), + srcRect.height()); + + size_t pixelOffset = srcRect.fTop * bitmap.rowBytes() + + srcRect.fLeft * bitmap.bytesPerPixel(); + tmpBitmap.copyPixelsFrom( + (uint8_t*)bitmap.getPixels() + pixelOffset, + bitmap.getSafeSize() - pixelOffset, + bitmap.rowBytes()); + + bitmapPtr = &tmpBitmap; } + SkPaint paintWithTexture(paint); paintWithTexture.setShader(SkShader::CreateBitmapShader( *bitmapPtr, SkShader::kClamp_TileMode, SkShader::kClamp_TileMode))->unref(); paintWithTexture.getShader()->setLocalMatrix(m); SkRect ScalarRect; - ScalarRect.set(srcRect); + ScalarRect.setXYWH(0, 0, srcRect.width(), srcRect.height()); - if (m.rectStaysRect()) { - // Preferred drawing method, optimized for rectangles - m.mapRect(&ScalarRect); - this->drawRect(draw, ScalarRect, paintWithTexture); - } else { - // Slower drawing method, for warped or rotated rectangles - SkPath path; - path.addRect(ScalarRect); - path.transform(m); - this->drawPath(draw, path, paintWithTexture, NULL, true); - } + // Transform 'm' must be applied globally so that it will + // affect the blur radius. + SkMatrix matrix = *draw.fMatrix; + matrix.preConcat(m); + SkDraw myDraw(draw); + myDraw.fMatrix = &matrix; + + this->drawRect(myDraw, ScalarRect, paintWithTexture); return; } |