diff options
author | 2013-08-20 16:51:20 +0000 | |
---|---|---|
committer | 2013-08-20 16:51:20 +0000 | |
commit | 2cc0b47a9b37e4727f3025ddb080ff98b1dc162c (patch) | |
tree | cfe0436f05f27042590a436c5c8be62a945ac84b | |
parent | 9e3074e968f52eb02fdc329bb9fbe7be5e674268 (diff) |
Third (and hopefully final) change to support bleed flag in Ganesh
https://codereview.chromium.org/23172013/
git-svn-id: http://skia.googlecode.com/svn/trunk@10826 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r-- | gm/bleed.cpp | 28 | ||||
-rw-r--r-- | src/gpu/SkGpuDevice.cpp | 69 |
2 files changed, 66 insertions, 31 deletions
diff --git a/gm/bleed.cpp b/gm/bleed.cpp index fad5c0f18a..31bbe6d3f2 100644 --- a/gm/bleed.cpp +++ b/gm/bleed.cpp @@ -7,6 +7,7 @@ #include "gm.h" #include "SkCanvas.h" +#include "SkBlurMaskFilter.h" #if SK_SUPPORT_GPU #include "GrContext.h" @@ -139,6 +140,26 @@ protected: canvas->restore(); } + // Draw the center of the small bitmap with a mask filter + void drawCase4(SkCanvas* canvas, int transX, int transY, + SkCanvas::DrawBitmapRectFlags flags, bool filter) { + SkRect src = SkRect::MakeXYWH(1, 1, + kSmallTextureSize-2, + kSmallTextureSize-2); + SkRect dst = SkRect::MakeXYWH(0, 0, SkIntToScalar(kBlockSize), SkIntToScalar(kBlockSize)); + + SkPaint paint; + paint.setFilterBitmap(filter); + SkMaskFilter* mf = SkBlurMaskFilter::Create(SkIntToScalar(3), + SkBlurMaskFilter::kNormal_BlurStyle); + paint.setMaskFilter(mf)->unref(); + + canvas->save(); + canvas->translate(SkIntToScalar(transX), SkIntToScalar(transY)); + canvas->drawBitmapRectToRect(fBitmapSmall, &src, dst, &paint, flags); + canvas->restore(); + } + virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE { canvas->clear(SK_ColorGRAY); @@ -147,11 +168,13 @@ protected: this->drawCase1(canvas, kCol0X, kRow0Y, SkCanvas::kNone_DrawBitmapRectFlag, false); this->drawCase2(canvas, kCol0X, kRow1Y, SkCanvas::kNone_DrawBitmapRectFlag, false); this->drawCase3(canvas, kCol0X, kRow2Y, SkCanvas::kNone_DrawBitmapRectFlag, false); + this->drawCase4(canvas, kCol0X, kRow3Y, SkCanvas::kNone_DrawBitmapRectFlag, false); // Then draw a column with no bleeding or tiling but with filtering this->drawCase1(canvas, kCol1X, kRow0Y, SkCanvas::kNone_DrawBitmapRectFlag, true); this->drawCase2(canvas, kCol1X, kRow1Y, SkCanvas::kNone_DrawBitmapRectFlag, true); this->drawCase3(canvas, kCol1X, kRow2Y, SkCanvas::kNone_DrawBitmapRectFlag, true); + this->drawCase4(canvas, kCol1X, kRow3Y, SkCanvas::kNone_DrawBitmapRectFlag, true); #if SK_SUPPORT_GPU @@ -168,11 +191,13 @@ protected: this->drawCase1(canvas, kCol2X, kRow0Y, SkCanvas::kNone_DrawBitmapRectFlag, true); this->drawCase2(canvas, kCol2X, kRow1Y, SkCanvas::kNone_DrawBitmapRectFlag, true); this->drawCase3(canvas, kCol2X, kRow2Y, SkCanvas::kNone_DrawBitmapRectFlag, true); + this->drawCase4(canvas, kCol2X, kRow3Y, SkCanvas::kNone_DrawBitmapRectFlag, true); // Finally draw a column with all three (bleeding, tiling, and filtering) this->drawCase1(canvas, kCol3X, kRow0Y, SkCanvas::kBleed_DrawBitmapRectFlag, true); this->drawCase2(canvas, kCol3X, kRow1Y, SkCanvas::kBleed_DrawBitmapRectFlag, true); this->drawCase3(canvas, kCol3X, kRow2Y, SkCanvas::kBleed_DrawBitmapRectFlag, true); + this->drawCase4(canvas, kCol3X, kRow3Y, SkCanvas::kBleed_DrawBitmapRectFlag, true); #if SK_SUPPORT_GPU if (NULL != ctx) { @@ -194,7 +219,8 @@ private: static const int kRow0Y = kBlockSpacing; static const int kRow1Y = 2*kBlockSpacing + kBlockSize; static const int kRow2Y = 3*kBlockSpacing + 2*kBlockSize; - static const int kHeight = 4*kBlockSpacing + 3*kBlockSize; + static const int kRow3Y = 4*kBlockSpacing + 3*kBlockSize; + static const int kHeight = 5*kBlockSpacing + 4*kBlockSize; static const int kSmallTextureSize = 4; static const int kMaxTextureSize = 32; diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp index b18c78200c..d96ffb84a3 100644 --- a/src/gpu/SkGpuDevice.cpp +++ b/src/gpu/SkGpuDevice.cpp @@ -1086,6 +1086,32 @@ void SkGpuDevice::drawBitmap(const SkDraw& draw, SkCanvas::kNone_DrawBitmapRectFlag); } +// This method outsets 'iRect' by 1 all around and then clamps its extents to +// 'clamp'. 'offset' is adjusted to remain positioned over the top-left corner +// of 'iRect' for all possible outsets/clamps. +static inline void clamped_unit_outset_with_offset(SkIRect* iRect, SkPoint* offset, + const SkIRect& clamp) { + iRect->outset(1, 1); + + if (iRect->fLeft < clamp.fLeft) { + iRect->fLeft = clamp.fLeft; + } else { + offset->fX -= SK_Scalar1; + } + if (iRect->fTop < clamp.fTop) { + iRect->fTop = clamp.fTop; + } else { + offset->fY -= SK_Scalar1; + } + + if (iRect->fRight > clamp.fRight) { + iRect->fRight = clamp.fRight; + } + if (iRect->fBottom > clamp.fBottom) { + iRect->fBottom = clamp.fBottom; + } +} + void SkGpuDevice::drawBitmapCommon(const SkDraw& draw, const SkBitmap& bitmap, const SkRect* srcRectPtr, @@ -1102,8 +1128,6 @@ void SkGpuDevice::drawBitmapCommon(const SkDraw& draw, } if (paint.getMaskFilter()){ - // TODO: this path needs to be updated to respect the bleed flag - // Convert the bitmap to a shader so that the rect can be drawn // through drawRect, which supports mask filters. SkMatrix newM(m); @@ -1112,13 +1136,24 @@ void SkGpuDevice::drawBitmapCommon(const SkDraw& draw, if (NULL != srcRectPtr) { SkIRect iSrc; srcRect.roundOut(&iSrc); + + SkPoint offset = SkPoint::Make(SkIntToScalar(iSrc.fLeft), + SkIntToScalar(iSrc.fTop)); + + if (SkCanvas::kBleed_DrawBitmapRectFlag & flags) { + // In bleed mode we want to expand the src rect on all sides + // but stay within the bitmap bounds + SkIRect iClampRect = SkIRect::MakeWH(bitmap.width(), bitmap.height()); + clamped_unit_outset_with_offset(&iSrc, &offset, iClampRect); + } + if (!bitmap.extractSubset(&tmp, iSrc)) { return; // extraction failed } bitmapPtr = &tmp; - srcRect.offset(SkIntToScalar(-iSrc.fLeft), SkIntToScalar(-iSrc.fTop)); + srcRect.offset(-offset.fX, -offset.fY); // The source rect has changed so update the matrix - newM.preTranslate(SkIntToScalar(iSrc.fLeft), SkIntToScalar(iSrc.fTop)); + newM.preTranslate(offset.fX, offset.fY); } SkPaint paintWithTexture(paint); @@ -1178,32 +1213,6 @@ void SkGpuDevice::drawBitmapCommon(const SkDraw& draw, } } -// This method outsets 'iRect' by 1 all around and then clamps its extents to -// 'clamp'. 'offset' is adjusted to remain positioned over the top-left corner -// of 'iRect' despite the possible outsets/clamps. -static inline void clamped_unit_outset_with_offset(SkIRect* iRect, SkPoint* offset, - const SkIRect& clamp) { - iRect->outset(1, 1); - - if (iRect->fLeft < clamp.fLeft) { - iRect->fLeft = clamp.fLeft; - } else { - offset->fX -= SK_Scalar1; - } - if (iRect->fTop < clamp.fTop) { - iRect->fTop = clamp.fTop; - } else { - offset->fY -= SK_Scalar1; - } - - if (iRect->fRight > clamp.fRight) { - iRect->fRight = clamp.fRight; - } - if (iRect->fBottom > clamp.fBottom) { - iRect->fBottom = clamp.fBottom; - } -} - // 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 SkBitmap& bitmap, |