diff options
author | mtklein@google.com <mtklein@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2013-08-26 16:21:35 +0000 |
---|---|---|
committer | mtklein@google.com <mtklein@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2013-08-26 16:21:35 +0000 |
commit | 0dc546c37c7dff3885188054d191cf852d899e32 (patch) | |
tree | d1d0d976c8e5d489d66b2680ee75c93c918810bd | |
parent | 62aa8d614893acbc9a4b97746f3daa278d41e088 (diff) |
Implement highQualityFilter16 so GM doesn't crash when you give it resources.
Testing consisted of:
1) ninja -C out/Debug gm && gm -i resources --match mandrill_512 -w /tmp/gm
2) notice that gm didn't segfault
3) look in /tmp/gm and see a bunch of handsome monkeys
BUG=skia:1517
R=humper@google.com
Review URL: https://codereview.chromium.org/22801016
git-svn-id: http://skia.googlecode.com/svn/trunk@10917 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r-- | src/core/SkBitmapFilter.cpp | 41 | ||||
-rw-r--r-- | src/core/SkBitmapProcState.cpp | 5 | ||||
-rw-r--r-- | src/core/SkBitmapProcState.h | 16 | ||||
-rw-r--r-- | src/opts/opts_check_SSE2.cpp | 2 |
4 files changed, 42 insertions, 22 deletions
diff --git a/src/core/SkBitmapFilter.cpp b/src/core/SkBitmapFilter.cpp index 5128d9b5dc..c607e6814b 100644 --- a/src/core/SkBitmapFilter.cpp +++ b/src/core/SkBitmapFilter.cpp @@ -22,9 +22,10 @@ // the image is rotated or has some other complex transformation applied. // Scaled images will usually be rescaled directly before rasterization. -void highQualityFilter(const SkBitmapProcState& s, int x, int y, - SkPMColor* SK_RESTRICT colors, int count) { +namespace { +template <typename Color, typename ColorPacker> +void highQualityFilter(ColorPacker pack, const SkBitmapProcState& s, int x, int y, Color* SK_RESTRICT colors, int count) { const int maxX = s.fBitmap->width() - 1; const int maxY = s.fBitmap->height() - 1; @@ -70,12 +71,27 @@ void highQualityFilter(const SkBitmapProcState& s, int x, int y, int g = SkClampMax(SkScalarRoundToInt(fg), a); int b = SkClampMax(SkScalarRoundToInt(fb), a); - *colors++ = SkPackARGB32(a, r, g, b); + *colors++ = pack(a, r, g, b); x++; } } +uint16_t PackTo565(int /*a*/, int r, int g, int b) { + return SkPack888ToRGB16(r, g, b); +} + +} // namespace + +void highQualityFilter32(const SkBitmapProcState& s, int x, int y, SkPMColor* SK_RESTRICT colors, int count) { + highQualityFilter(&SkPackARGB32, s, x, y, colors, count); +} + +void highQualityFilter16(const SkBitmapProcState& s, int x, int y, uint16_t* SK_RESTRICT colors, int count) { + highQualityFilter(&PackTo565, s, x, y, colors, count); +} + + SK_CONF_DECLARE(const char *, c_bitmapFilter, "bitmap.filter", "mitchell", "Which scanline bitmap filter to use [mitchell, lanczos, hamming, gaussian, triangle, box]"); SkBitmapFilter *SkBitmapFilter::Allocate() { @@ -98,34 +114,35 @@ SkBitmapFilter *SkBitmapFilter::Allocate() { return NULL; } -SkBitmapProcState::ShaderProc32 -SkBitmapProcState::chooseBitmapFilterProc() { - +bool SkBitmapProcState::setBitmapFilterProcs() { if (fFilterLevel != SkPaint::kHigh_FilterLevel) { - return NULL; + return false; } if (fAlphaScale != 256) { - return NULL; + return false; } // TODO: consider supporting other configs (e.g. 565, A8) if (fBitmap->config() != SkBitmap::kARGB_8888_Config) { - return NULL; + return false; } // TODO: consider supporting repeat and mirror if (SkShader::kClamp_TileMode != fTileModeX || SkShader::kClamp_TileMode != fTileModeY) { - return NULL; + return false; } + // TODO: is this right? do we want fBitmapFilter allocated even if we can't set shader procs? if (fInvType & (SkMatrix::kAffine_Mask | SkMatrix::kScale_Mask)) { fBitmapFilter = SkBitmapFilter::Allocate(); } if (fInvType & SkMatrix::kScale_Mask) { - return highQualityFilter; + fShaderProc32 = highQualityFilter32; + fShaderProc16 = highQualityFilter16; + return true; } else { - return NULL; + return false; } } diff --git a/src/core/SkBitmapProcState.cpp b/src/core/SkBitmapProcState.cpp index b48f8384c9..390582d161 100644 --- a/src/core/SkBitmapProcState.cpp +++ b/src/core/SkBitmapProcState.cpp @@ -376,8 +376,7 @@ bool SkBitmapProcState::chooseProcs(const SkMatrix& inv, const SkPaint& paint) { SkASSERT(fInvType > SkMatrix::kTranslate_Mask); - fShaderProc32 = this->chooseBitmapFilterProc(); - if (!fShaderProc32) { + if (!this->setBitmapFilterProcs()) { fFilterLevel = SkPaint::kLow_FilterLevel; } } @@ -404,7 +403,7 @@ bool SkBitmapProcState::chooseProcs(const SkMatrix& inv, const SkPaint& paint) { // No need to do this if we're doing HQ sampling; if filter quality is // still set to HQ by the time we get here, then we must have installed - // the shader proc above and can skip all this. + // the shader procs above and can skip all this. if (fFilterLevel < SkPaint::kHigh_FilterLevel) { diff --git a/src/core/SkBitmapProcState.h b/src/core/SkBitmapProcState.h index e138ed2698..3a1d7bad62 100644 --- a/src/core/SkBitmapProcState.h +++ b/src/core/SkBitmapProcState.h @@ -166,7 +166,9 @@ private: SkBitmapFilter* fBitmapFilter; - ShaderProc32 chooseBitmapFilterProc(); + // If supported, sets fShaderProc32 and fShaderProc16 and returns true, + // otherwise returns false. + bool setBitmapFilterProcs(); // Return false if we failed to setup for fast translate (e.g. overflow) bool setupForTranslate(); @@ -208,9 +210,9 @@ void S32_opaque_D32_filter_DX(const SkBitmapProcState& s, const uint32_t xy[], void S32_alpha_D32_filter_DX(const SkBitmapProcState& s, const uint32_t xy[], int count, SkPMColor colors[]); void S32_opaque_D32_filter_DXDY(const SkBitmapProcState& s, - const uint32_t xy[], int count, SkPMColor colors[]); + const uint32_t xy[], int count, SkPMColor colors[]); void S32_alpha_D32_filter_DXDY(const SkBitmapProcState& s, - const uint32_t xy[], int count, SkPMColor colors[]); + const uint32_t xy[], int count, SkPMColor colors[]); void ClampX_ClampY_filter_scale(const SkBitmapProcState& s, uint32_t xy[], int count, int x, int y); void ClampX_ClampY_nofilter_scale(const SkBitmapProcState& s, uint32_t xy[], @@ -220,10 +222,12 @@ void ClampX_ClampY_filter_affine(const SkBitmapProcState& s, void ClampX_ClampY_nofilter_affine(const SkBitmapProcState& s, uint32_t xy[], int count, int x, int y); void S32_D16_filter_DX(const SkBitmapProcState& s, - const uint32_t* xy, int count, uint16_t* colors); + const uint32_t* xy, int count, uint16_t* colors); -void highQualityFilter(const SkBitmapProcState &s, int x, int y, - SkPMColor *SK_RESTRICT colors, int count); +void highQualityFilter32(const SkBitmapProcState &s, int x, int y, + SkPMColor *SK_RESTRICT colors, int count); +void highQualityFilter16(const SkBitmapProcState &s, int x, int y, + uint16_t *SK_RESTRICT colors, int count); #endif diff --git a/src/opts/opts_check_SSE2.cpp b/src/opts/opts_check_SSE2.cpp index 9b6f775d9a..8d43390a22 100644 --- a/src/opts/opts_check_SSE2.cpp +++ b/src/opts/opts_check_SSE2.cpp @@ -155,7 +155,7 @@ void SkBitmapProcState::platformProcs() { fMatrixProc = ClampX_ClampY_nofilter_affine_SSE2; } if (c_hqfilter_sse) { - if (fShaderProc32 == highQualityFilter) { + if (fShaderProc32 == highQualityFilter32) { fShaderProc32 = highQualityFilter_SSE2; } } |