aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar mtklein@google.com <mtklein@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-08-26 16:21:35 +0000
committerGravatar mtklein@google.com <mtklein@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-08-26 16:21:35 +0000
commit0dc546c37c7dff3885188054d191cf852d899e32 (patch)
treed1d0d976c8e5d489d66b2680ee75c93c918810bd
parent62aa8d614893acbc9a4b97746f3daa278d41e088 (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.cpp41
-rw-r--r--src/core/SkBitmapProcState.cpp5
-rw-r--r--src/core/SkBitmapProcState.h16
-rw-r--r--src/opts/opts_check_SSE2.cpp2
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;
}
}