aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-10-07 18:00:17 +0000
committerGravatar commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-10-07 18:00:17 +0000
commit6c1ee2d4e727357451c8a6fcf4a08e75890b5d6d (patch)
tree144de7ce27c8400a39866d0f53f7be49aa935cda
parentdd6cde5235d5d36607f4f1df66057d807b432b99 (diff)
Luminance-to-alpha color filter (SkLumaColorFilter).
Adding a color filter luma implementation. The plan is to convert existing clients and then deprecate SkLumaXfermode. R=bsalomon@google.com, reed@google.com, robertphillips@google.com Author: fmalita@chromium.org Review URL: https://codereview.chromium.org/25453004 git-svn-id: http://skia.googlecode.com/svn/trunk@11636 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r--bench/ColorFilterBench.cpp30
-rw-r--r--gm/lumafilter.cpp152
-rw-r--r--gyp/effects.gypi2
-rw-r--r--gyp/gmslides.gypi1
-rw-r--r--gyp/public_headers.gypi1
-rw-r--r--include/effects/SkLumaColorFilter.h46
-rw-r--r--src/effects/SkLumaColorFilter.cpp152
-rw-r--r--src/ports/SkGlobalInitialization_chromium.cpp2
-rw-r--r--src/ports/SkGlobalInitialization_default.cpp2
-rw-r--r--tests/ColorFilterTest.cpp35
10 files changed, 423 insertions, 0 deletions
diff --git a/bench/ColorFilterBench.cpp b/bench/ColorFilterBench.cpp
index e30b005964..6d98a0eabc 100644
--- a/bench/ColorFilterBench.cpp
+++ b/bench/ColorFilterBench.cpp
@@ -8,6 +8,7 @@
#include "SkCanvas.h"
#include "SkColorFilterImageFilter.h"
#include "SkColorMatrixFilter.h"
+#include "SkLumaColorFilter.h"
#include "SkTableColorFilter.h"
#define FILTER_WIDTH_SMALL SkIntToScalar(32)
@@ -314,6 +315,33 @@ private:
typedef ColorFilterBaseBench INHERITED;
};
+class LumaColorFilterBench : public ColorFilterBaseBench {
+
+public:
+ LumaColorFilterBench(bool small) : INHERITED(small) {
+ }
+
+protected:
+ virtual const char* onGetName() SK_OVERRIDE {
+ return isSmall() ? "luma_colorfilter_small" : "luma_colorfilter_large";
+ }
+
+ virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
+ SkRect r = getFilterRect();
+ SkPaint paint;
+ paint.setColor(SK_ColorRED);
+
+ for (int i = 0; i < this->getLoops(); i++) {
+ SkAutoTUnref<SkColorFilter> luma_filter(SkLumaColorFilter::Create());
+ paint.setColorFilter(luma_filter);
+ canvas->drawRect(r, paint);
+ }
+ }
+
+private:
+ typedef ColorFilterBaseBench INHERITED;
+};
+
///////////////////////////////////////////////////////////////////////////////
DEF_BENCH( return new ColorFilterDimBrightBench(true); )
@@ -325,6 +353,7 @@ DEF_BENCH( return new ColorFilterBrightBench(true); )
DEF_BENCH( return new ColorFilterBlueBench(true); )
DEF_BENCH( return new ColorFilterGrayBench(true); )
DEF_BENCH( return new TableColorFilterBench(true); )
+DEF_BENCH( return new LumaColorFilterBench(true); )
DEF_BENCH( return new ColorFilterDimBrightBench(false); )
DEF_BENCH( return new ColorFilterBrightGrayBench(false); )
@@ -335,3 +364,4 @@ DEF_BENCH( return new ColorFilterBrightBench(false); )
DEF_BENCH( return new ColorFilterBlueBench(false); )
DEF_BENCH( return new ColorFilterGrayBench(false); )
DEF_BENCH( return new TableColorFilterBench(false); )
+DEF_BENCH( return new LumaColorFilterBench(false); )
diff --git a/gm/lumafilter.cpp b/gm/lumafilter.cpp
new file mode 100644
index 0000000000..69a4f073f0
--- /dev/null
+++ b/gm/lumafilter.cpp
@@ -0,0 +1,152 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "gm.h"
+#include "SkCanvas.h"
+#include "SkGradientShader.h"
+#include "SkLumaColorFilter.h"
+
+static SkScalar kSize = 80;
+static SkScalar kInset = 10;
+static SkColor kColor1 = SkColorSetARGB(0xff, 0xff, 0xff, 0);
+static SkColor kColor2 = SkColorSetARGB(0xff, 0x80, 0xff, 0);
+
+static void draw_label(SkCanvas* canvas, const char* label,
+ const SkPoint& offset) {
+ SkPaint paint;
+ size_t len = strlen(label);
+
+ SkScalar width = paint.measureText(label, len);
+ canvas->drawText(label, len, offset.x() - width / 2, offset.y(),
+ paint);
+}
+
+static void draw_scene(SkCanvas* canvas, SkColorFilter* filter,
+ SkXfermode::Mode mode, SkShader* s1,
+ SkShader* s2) {
+ SkPaint paint;
+ paint.setAntiAlias(true);
+ SkRect r, c, bounds = SkRect::MakeWH(kSize, kSize);
+
+ c = bounds;
+ c.fRight = bounds.centerX();
+ canvas->drawRect(bounds, paint);
+
+ canvas->saveLayer(&bounds, NULL);
+
+ r = bounds;
+ r.inset(kInset, 0);
+ paint.setShader(s1);
+ paint.setColor(s1 ? SK_ColorBLACK : SkColorSetA(kColor1, 0x80));
+ canvas->drawOval(r, paint);
+ if (!s1) {
+ canvas->save();
+ canvas->clipRect(c);
+ paint.setColor(kColor1);
+ canvas->drawOval(r, paint);
+ canvas->restore();
+ }
+
+ SkPaint xferPaint;
+ xferPaint.setXfermodeMode(mode);
+ canvas->saveLayer(&bounds, &xferPaint);
+
+ r = bounds;
+ r.inset(0, kInset);
+ paint.setShader(s2);
+ paint.setColor(s2 ? SK_ColorBLACK : SkColorSetA(kColor2, 0x80));
+ paint.setColorFilter(filter);
+ canvas->drawOval(r, paint);
+ if (!s2) {
+ canvas->save();
+ canvas->clipRect(c);
+ paint.setColor(kColor2);
+ canvas->drawOval(r, paint);
+ canvas->restore();
+ }
+
+ canvas->restore();
+ canvas->restore();
+}
+
+class LumaFilterGM : public skiagm::GM {
+public:
+ LumaFilterGM() {
+ SkColor g1Colors[] = { kColor1, SkColorSetA(kColor1, 0x20) };
+ SkColor g2Colors[] = { kColor2, SkColorSetA(kColor2, 0x20) };
+ SkPoint g1Points[] = { { 0, 0 }, { 0, 100 } };
+ SkPoint g2Points[] = { { 0, 0 }, { kSize, 0 } };
+ SkScalar pos[] = { 0.2f, 1.0f };
+
+ fFilter.reset(SkLumaColorFilter::Create());
+ fGr1.reset(SkGradientShader::CreateLinear(g1Points,
+ g1Colors,
+ pos,
+ SK_ARRAY_COUNT(g1Colors),
+ SkShader::kClamp_TileMode));
+ fGr2.reset(SkGradientShader::CreateLinear(g2Points,
+ g2Colors,
+ pos,
+ SK_ARRAY_COUNT(g2Colors),
+ SkShader::kClamp_TileMode));
+ }
+
+protected:
+ virtual SkString onShortName() SK_OVERRIDE {
+ return SkString("lumafilter");
+ }
+
+ virtual SkISize onISize() SK_OVERRIDE {
+ return SkISize::Make(600, 420);
+ }
+
+ virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
+ SkXfermode::Mode modes[] = { SkXfermode::kSrcOver_Mode,
+ SkXfermode::kDstOver_Mode,
+ SkXfermode::kSrcATop_Mode,
+ SkXfermode::kDstATop_Mode,
+ SkXfermode::kSrcIn_Mode,
+ SkXfermode::kDstIn_Mode,
+ };
+ struct {
+ SkShader* fShader1;
+ SkShader* fShader2;
+ } shaders[] = {
+ { NULL, NULL },
+ { NULL, fGr2 },
+ { fGr1, NULL },
+ { fGr1, fGr2 },
+ };
+
+ SkScalar gridStep = kSize + 2 * kInset;
+ for (size_t i = 0; i < SK_ARRAY_COUNT(modes); ++i) {
+ draw_label(canvas, SkXfermode::ModeName(modes[i]),
+ SkPoint::Make(gridStep * (0.5f + i), 20));
+ }
+
+ for (size_t i = 0; i < SK_ARRAY_COUNT(shaders); ++i) {
+ canvas->save();
+ canvas->translate(kInset, gridStep * i + 30);
+ for (size_t m = 0; m < SK_ARRAY_COUNT(modes); ++m) {
+ draw_scene(canvas, fFilter, modes[m], shaders[i].fShader1,
+ shaders[i].fShader2);
+ canvas->translate(gridStep, 0);
+ }
+ canvas->restore();
+ }
+ }
+
+private:
+ SkAutoTUnref<SkColorFilter> fFilter;
+ SkAutoTUnref<SkShader> fGr1, fGr2;
+
+ typedef skiagm::GM INHERITED;
+};
+
+//////////////////////////////////////////////////////////////////////////////
+
+DEF_GM( return SkNEW(LumaFilterGM); )
diff --git a/gyp/effects.gypi b/gyp/effects.gypi
index 19e55e89ed..b640a36ff8 100644
--- a/gyp/effects.gypi
+++ b/gyp/effects.gypi
@@ -40,6 +40,7 @@
'<(skia_src_path)/effects/SkLayerRasterizer.cpp',
'<(skia_src_path)/effects/SkLerpXfermode.cpp',
'<(skia_src_path)/effects/SkLightingImageFilter.cpp',
+ '<(skia_src_path)/effects/SkLumaColorFilter.cpp',
'<(skia_src_path)/effects/SkLumaXfermode.cpp',
'<(skia_src_path)/effects/SkMagnifierImageFilter.cpp',
'<(skia_src_path)/effects/SkMatrixConvolutionImageFilter.cpp',
@@ -103,6 +104,7 @@
'<(skia_include_path)/effects/SkLayerRasterizer.h',
'<(skia_include_path)/effects/SkLerpXfermode.h',
'<(skia_include_path)/effects/SkLightingImageFilter.h',
+ '<(skia_include_path)/effects/SkLumaColorFilter.h',
'<(skia_include_path)/effects/SkLumaXfermode.h',
'<(skia_include_path)/effects/SkOffsetImageFilter.h',
'<(skia_include_path)/effects/SkMorphologyImageFilter.h',
diff --git a/gyp/gmslides.gypi b/gyp/gmslides.gypi
index 5e2dfc17e1..9307388850 100644
--- a/gyp/gmslides.gypi
+++ b/gyp/gmslides.gypi
@@ -72,6 +72,7 @@
'../gm/inversepaths.cpp',
'../gm/lerpmode.cpp',
'../gm/lighting.cpp',
+ '../gm/lumafilter.cpp',
'../gm/lumamode.cpp',
'../gm/image.cpp',
'../gm/imagefiltersbase.cpp',
diff --git a/gyp/public_headers.gypi b/gyp/public_headers.gypi
index 569ecc7dee..f84d21b40d 100644
--- a/gyp/public_headers.gypi
+++ b/gyp/public_headers.gypi
@@ -76,6 +76,7 @@
'effects/SkMergeImageFilter.h',
'effects/SkPerlinNoiseShader.h',
'effects/SkLerpXfermode.h',
+ 'effects/SkLumaColorFilter.h',
'effects/SkLumaXfermode.h',
'effects/SkRectShaderImageFilter.h',
'effects/SkMagnifierImageFilter.h',
diff --git a/include/effects/SkLumaColorFilter.h b/include/effects/SkLumaColorFilter.h
new file mode 100644
index 0000000000..fef06ab12a
--- /dev/null
+++ b/include/effects/SkLumaColorFilter.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkLumaColorFilter_DEFINED
+#define SkLumaColorFilter_DEFINED
+
+#include "SkColorFilter.h"
+
+/**
+ * Luminance-to-alpha color filter, as defined in
+ * http://www.w3.org/TR/SVG/masking.html#Masking
+ * http://www.w3.org/TR/css-masking/#MaskValues
+ *
+ * Each color is scaled by the (unpremultiplied) luminance value:
+ *
+ * C' = [Lum * a, Lum * r, Lum * g, Lum * b]
+ *
+ */
+class SK_API SkLumaColorFilter : public SkColorFilter {
+public:
+ static SkColorFilter* Create();
+
+ virtual void filterSpan(const SkPMColor src[], int count, SkPMColor[]) const SK_OVERRIDE;
+
+#if SK_SUPPORT_GPU
+ virtual GrEffectRef* asNewEffect(GrContext*) const SK_OVERRIDE;
+#endif
+
+ SkDEVCODE(virtual void toString(SkString* str) const SK_OVERRIDE;)
+ SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkLumaColorFilter)
+
+protected:
+ SkLumaColorFilter(SkFlattenableReadBuffer& buffer);
+ virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE;
+
+private:
+ SkLumaColorFilter();
+
+ typedef SkColorFilter INHERITED;
+};
+
+#endif
diff --git a/src/effects/SkLumaColorFilter.cpp b/src/effects/SkLumaColorFilter.cpp
new file mode 100644
index 0000000000..c9f1fb02c3
--- /dev/null
+++ b/src/effects/SkLumaColorFilter.cpp
@@ -0,0 +1,152 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "SkLumaColorFilter.h"
+
+#include "SkColorPriv.h"
+#include "SkString.h"
+#include "SkUnPreMultiply.h"
+
+#if SK_SUPPORT_GPU
+#include "gl/GrGLEffect.h"
+#include "GrContext.h"
+#include "GrTBackendEffectFactory.h"
+#endif
+
+void SkLumaColorFilter::filterSpan(const SkPMColor src[], int count,
+ SkPMColor dst[]) const {
+ const SkUnPreMultiply::Scale* table = SkUnPreMultiply::GetScaleTable();
+
+ for (int i = 0; i < count; ++i) {
+ SkPMColor c = src[i];
+
+ unsigned r = SkGetPackedR32(c);
+ unsigned g = SkGetPackedG32(c);
+ unsigned b = SkGetPackedB32(c);
+ unsigned a = SkGetPackedA32(c);
+
+ // No need to do anything for white (luminance == 1.0)
+ if (a != r || a != g || a != b) {
+ /*
+ * To avoid un-premultiplying multiple components, we can start
+ * with the luminance computed in PM space:
+ *
+ * Lum = i * (r / a) + j * (g / a) + k * (b / a)
+ * Lum = (i * r + j * g + k * b) / a
+ * Lum = Lum'(PM) / a
+ *
+ * Then the filter function is:
+ *
+ * C' = [ Lum * a, Lum * r, Lum * g, Lum * b ]
+ *
+ * which is equivalent to:
+ *
+ * C' = [ Lum'(PM), Lum * r, Lum * g, Lum * b ]
+ */
+ unsigned pm_lum = SkComputeLuminance(r, g, b);
+ unsigned lum = SkUnPreMultiply::ApplyScale(table[a], pm_lum);
+
+ c = SkPackARGB32(pm_lum,
+ SkMulDiv255Round(r, lum),
+ SkMulDiv255Round(g, lum),
+ SkMulDiv255Round(b, lum));
+ }
+
+ dst[i] = c;
+ }
+}
+
+SkColorFilter* SkLumaColorFilter::Create() {
+ return SkNEW(SkLumaColorFilter);
+}
+
+SkLumaColorFilter::SkLumaColorFilter()
+ : INHERITED() {
+}
+
+SkLumaColorFilter::SkLumaColorFilter(SkFlattenableReadBuffer& buffer)
+ : INHERITED(buffer) {
+}
+
+void SkLumaColorFilter::flatten(SkFlattenableWriteBuffer&) const {
+}
+
+#ifdef SK_DEVELOPER
+void SkLumaColorFilter::toString(SkString* str) const {
+ str->append("SkLumaColorFilter ");
+}
+#endif
+
+#if SK_SUPPORT_GPU
+class LumaColorFilterEffect : public GrEffect {
+public:
+ static GrEffectRef* Create() {
+ AutoEffectUnref effect(SkNEW(LumaColorFilterEffect));
+ return CreateEffectRef(effect);
+ }
+
+ static const char* Name() { return "Luminance-to-Alpha"; }
+
+ virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE {
+ return GrTBackendEffectFactory<LumaColorFilterEffect>::getInstance();
+ }
+
+ virtual void getConstantColorComponents(GrColor* color,
+ uint32_t* validFlags) const SK_OVERRIDE {
+ *validFlags = 0;
+ }
+
+ class GLEffect : public GrGLEffect {
+ public:
+ GLEffect(const GrBackendEffectFactory& factory,
+ const GrDrawEffect&)
+ : INHERITED(factory) {
+ }
+
+ static EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&) {
+ // this class always generates the same code.
+ return 0;
+ }
+
+ virtual void emitCode(GrGLShaderBuilder* builder,
+ const GrDrawEffect&,
+ EffectKey,
+ const char* outputColor,
+ const char* inputColor,
+ const TransformedCoordsArray&,
+ const TextureSamplerArray&) SK_OVERRIDE {
+ if (NULL == inputColor) {
+ inputColor = GrGLSLOnesVecf(4);
+ }
+
+ // The max() is to guard against 0 / 0 during unpremul when the incoming color is
+ // transparent black.
+ builder->fsCodeAppendf("\tfloat nonZeroAlpha = max(%s.a, 0.00001);\n", inputColor);
+ builder->fsCodeAppendf("\tfloat luma = dot(vec3(%f, %f, %f), %s.rgb);\n",
+ SK_ITU_BT709_LUM_COEFF_R,
+ SK_ITU_BT709_LUM_COEFF_G,
+ SK_ITU_BT709_LUM_COEFF_B,
+ inputColor);
+ builder->fsCodeAppendf("\t%s = vec4(%s.rgb * luma / nonZeroAlpha, luma);\n",
+ outputColor, inputColor);
+
+ }
+
+ private:
+ typedef GrGLEffect INHERITED;
+ };
+
+private:
+ virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE {
+ return true;
+ }
+};
+
+GrEffectRef* SkLumaColorFilter::asNewEffect(GrContext*) const {
+ return LumaColorFilterEffect::Create();
+}
+#endif
diff --git a/src/ports/SkGlobalInitialization_chromium.cpp b/src/ports/SkGlobalInitialization_chromium.cpp
index 6b25a4d6b0..5a8d6bbc07 100644
--- a/src/ports/SkGlobalInitialization_chromium.cpp
+++ b/src/ports/SkGlobalInitialization_chromium.cpp
@@ -13,6 +13,7 @@
#include "SkDashPathEffect.h"
#include "SkGradientShader.h"
#include "SkLayerDrawLooper.h"
+#include "SkLumaColorFilter.h"
#include "SkMallocPixelRef.h"
#include "SkXfermode.h"
#include "SkLumaXfermode.h"
@@ -25,6 +26,7 @@ void SkFlattenable::InitializeFlattenables() {
SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkCornerPathEffect)
SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDashPathEffect)
SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLayerDrawLooper)
+ SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLumaColorFilter)
SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkMallocPixelRef)
SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkMagnifierImageFilter)
diff --git a/src/ports/SkGlobalInitialization_default.cpp b/src/ports/SkGlobalInitialization_default.cpp
index 968c5ebcfa..902ec64642 100644
--- a/src/ports/SkGlobalInitialization_default.cpp
+++ b/src/ports/SkGlobalInitialization_default.cpp
@@ -46,6 +46,7 @@
#include "SkLayerRasterizer.h"
#include "SkLerpXfermode.h"
#include "SkLightingImageFilter.h"
+#include "SkLumaColorFilter.h"
#include "SkLumaXfermode.h"
#include "SkMagnifierImageFilter.h"
#include "SkMatrixConvolutionImageFilter.h"
@@ -89,6 +90,7 @@ void SkFlattenable::InitializeFlattenables() {
SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLayerDrawLooper)
SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLayerRasterizer)
SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLerpXfermode)
+ SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLumaColorFilter)
SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkPath1DPathEffect)
SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(Sk2DPathEffect)
SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLine2DPathEffect)
diff --git a/tests/ColorFilterTest.cpp b/tests/ColorFilterTest.cpp
index 4016f2193d..b333ad68f0 100644
--- a/tests/ColorFilterTest.cpp
+++ b/tests/ColorFilterTest.cpp
@@ -7,7 +7,9 @@
*/
#include "Test.h"
#include "SkColor.h"
+#include "SkColorPriv.h"
#include "SkColorFilter.h"
+#include "SkLumaColorFilter.h"
#include "SkRandom.h"
#include "SkXfermode.h"
#include "SkOrderedReadBuffer.h"
@@ -93,5 +95,38 @@ static void test_asColorMode(skiatest::Reporter* reporter) {
}
}
+///////////////////////////////////////////////////////////////////////////////
+
+static void test_lumaColorFilter(skiatest::Reporter* reporter) {
+ SkPMColor in, out;
+ SkAutoTUnref<SkColorFilter> lf(SkLumaColorFilter::Create());
+
+ // Applying luma to white is a nop (luminance(white) == 1.0)
+ for (unsigned i = 0; i < 256; ++i) {
+ in = SkPackARGB32(i, i, i, i);
+ lf->filterSpan(&in, 1, &out);
+ REPORTER_ASSERT(reporter, out == in);
+ }
+
+ // Applying luma to black yields transparent black (luminance(black) == 0)
+ for (unsigned i = 0; i < 256; ++i) {
+ in = SkPackARGB32(i, 0, 0, 0);
+ lf->filterSpan(&in, 1, &out);
+ REPORTER_ASSERT(reporter, out == SK_ColorTRANSPARENT);
+ }
+
+ // For general colors, a luma filter has an attenuating effect.
+ for (unsigned i = 1; i < 256; ++i) {
+ in = SkPackARGB32(i, i, i / 2, i / 3);
+ lf->filterSpan(&in, 1, &out);
+ REPORTER_ASSERT(reporter, out != in);
+ REPORTER_ASSERT(reporter, SkGetPackedA32(out) <= i);
+ REPORTER_ASSERT(reporter, SkGetPackedR32(out) <= i);
+ REPORTER_ASSERT(reporter, SkGetPackedG32(out) <= i / 2);
+ REPORTER_ASSERT(reporter, SkGetPackedB32(out) <= i / 3);
+ }
+}
+
#include "TestClassDef.h"
DEFINE_TESTCLASS("ColorFilter", ColorFilterTestClass, test_asColorMode)
+DEFINE_TESTCLASS("LumaColorFilter", LumaColorFilterTestClass, test_lumaColorFilter)