aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar reed <reed@google.com>2015-03-03 06:41:45 -0800
committerGravatar Commit bot <commit-bot@chromium.org>2015-03-03 06:41:45 -0800
commitcff10b21a9934afc540d121b493b204335829589 (patch)
treef696624f21c4a45a052250cb9a18460e8aea0c0d
parent3ebb16df938099dcbb6645ca08365e6d1dde8ddd (diff)
change colorfilter to return an array of frag processors
-rw-r--r--gm/tablecolorfilter.cpp75
-rw-r--r--include/core/SkColorFilter.h17
-rw-r--r--include/effects/SkColorCubeFilter.h2
-rw-r--r--include/effects/SkColorMatrixFilter.h2
-rw-r--r--include/effects/SkLumaColorFilter.h2
-rw-r--r--include/effects/SkModeColorFilter.h2
-rw-r--r--src/core/SkColorFilter.cpp13
-rw-r--r--src/effects/SkColorCubeFilter.cpp12
-rw-r--r--src/effects/SkColorFilters.cpp13
-rw-r--r--src/effects/SkColorMatrixFilter.cpp12
-rw-r--r--src/effects/SkLumaColorFilter.cpp13
-rw-r--r--src/effects/SkPerlinNoiseShader.cpp6
-rw-r--r--src/effects/SkTableColorFilter.cpp22
-rw-r--r--src/gpu/SkGr.cpp9
-rw-r--r--tests/GpuColorFilterTest.cpp8
15 files changed, 155 insertions, 53 deletions
diff --git a/gm/tablecolorfilter.cpp b/gm/tablecolorfilter.cpp
index 2acb15c677..0d6da8f475 100644
--- a/gm/tablecolorfilter.cpp
+++ b/gm/tablecolorfilter.cpp
@@ -193,16 +193,29 @@ DEF_GM( return new TableColorFilterGM; )
//////////////////////////////////////////////////////////////////////////////
class ComposeColorFilterGM : public skiagm::GM {
+ enum {
+ COLOR_COUNT = 3,
+ MODE_COUNT = 4,
+ };
+ const SkColor* fColors;
+ const SkXfermode::Mode* fModes;
+ SkString fName;
+
public:
- ComposeColorFilterGM() {}
+ ComposeColorFilterGM(const SkColor colors[], const SkXfermode::Mode modes[],
+ const char suffix[])
+ : fColors(colors), fModes(modes)
+ {
+ fName.printf("colorcomposefilter_%s", suffix);
+ }
protected:
virtual SkString onShortName() {
- return SkString("composecolorfilter");
+ return fName;
}
virtual SkISize onISize() {
- return SkISize::Make(730, 730);
+ return SkISize::Make(790, 790);
}
virtual void onDraw(SkCanvas* canvas) {
@@ -211,20 +224,12 @@ protected:
canvas->drawColor(0xFFDDDDDD);
- SkColor colors[] = { SK_ColorCYAN, SK_ColorMAGENTA, SK_ColorYELLOW };
- SkXfermode::Mode modes[] = {
- SkXfermode::kOverlay_Mode,
- SkXfermode::kDarken_Mode,
- SkXfermode::kColorBurn_Mode,
- SkXfermode::kExclusion_Mode,
- };
-
- const int MODES = SK_ARRAY_COUNT(modes) * SK_ARRAY_COUNT(colors);
+ const int MODES = MODE_COUNT * COLOR_COUNT;
SkAutoTUnref<SkColorFilter> filters[MODES];
int index = 0;
- for (size_t i = 0; i < SK_ARRAY_COUNT(modes); ++i) {
- for (size_t j = 0; j < SK_ARRAY_COUNT(colors); ++j) {
- filters[index++].reset(SkColorFilter::CreateModeFilter(colors[j], modes[i]));
+ for (int i = 0; i < MODE_COUNT; ++i) {
+ for (int j = 0; j < COLOR_COUNT; ++j) {
+ filters[index++].reset(SkColorFilter::CreateModeFilter(fColors[j], fModes[i]));
}
}
@@ -235,9 +240,27 @@ protected:
canvas->translate(spacer, spacer);
- for (size_t y = 0; y < MODES; ++y) {
+ canvas->drawRect(r, paint); // orig
+
+ for (int i = 0; i < MODES; ++i) {
+ paint.setColorFilter(filters[i]);
+
+ canvas->save();
+ canvas->translate((i + 1) * (r.width() + spacer), 0);
+ canvas->drawRect(r, paint);
+ canvas->restore();
+
+ canvas->save();
+ canvas->translate(0, (i + 1) * (r.width() + spacer));
+ canvas->drawRect(r, paint);
+ canvas->restore();
+ }
+
+ canvas->translate(r.width() + spacer, r.width() + spacer);
+
+ for (int y = 0; y < MODES; ++y) {
canvas->save();
- for (size_t x = 0; x < MODES; ++x) {
+ for (int x = 0; x < MODES; ++x) {
SkAutoTUnref<SkColorFilter> compose(SkColorFilter::CreateComposeFilter(filters[y],
filters[x]));
paint.setColorFilter(compose);
@@ -252,5 +275,21 @@ protected:
private:
typedef GM INHERITED;
};
-DEF_GM( return new ComposeColorFilterGM; )
+const SkColor gColors0[] = { SK_ColorCYAN, SK_ColorMAGENTA, SK_ColorYELLOW };
+const SkXfermode::Mode gModes0[] = {
+ SkXfermode::kOverlay_Mode,
+ SkXfermode::kDarken_Mode,
+ SkXfermode::kColorBurn_Mode,
+ SkXfermode::kExclusion_Mode,
+};
+DEF_GM( return new ComposeColorFilterGM(gColors0, gModes0, "wacky"); )
+
+const SkColor gColors1[] = { 0x80FF0000, 0x8000FF00, 0x800000FF };
+const SkXfermode::Mode gModes1[] = {
+ SkXfermode::kSrcOver_Mode,
+ SkXfermode::kXor_Mode,
+ SkXfermode::kDstOut_Mode,
+ SkXfermode::kSrcATop_Mode,
+};
+DEF_GM( return new ComposeColorFilterGM(gColors1, gModes1, "alpha"); )
diff --git a/include/core/SkColorFilter.h b/include/core/SkColorFilter.h
index 31a4365a3c..14d33069f0 100644
--- a/include/core/SkColorFilter.h
+++ b/include/core/SkColorFilter.h
@@ -1,4 +1,3 @@
-
/*
* Copyright 2006 The Android Open Source Project
*
@@ -6,12 +5,12 @@
* found in the LICENSE file.
*/
-
#ifndef SkColorFilter_DEFINED
#define SkColorFilter_DEFINED
#include "SkColor.h"
#include "SkFlattenable.h"
+#include "SkTDArray.h"
#include "SkXfermode.h"
class SkBitmap;
@@ -138,10 +137,18 @@ public:
*/
static SkColorFilter* CreateComposeFilter(SkColorFilter* outer, SkColorFilter* inner);
- /** A subclass may implement this factory function to work with the GPU backend. If the return
- is non-NULL then the caller owns a ref on the returned object.
+ /**
+ * A subclass may implement this factory function to work with the GPU backend.
+ * If it returns true, then 1 or more fragment processors will have been appended to the
+ * array, each of which has been ref'd, so that the caller is responsible for calling unref()
+ * on them when they are finished. If more than one processor is appended, they will be
+ * applied in FIFO order.
+ *
+ * If the subclass returns false, then it should not modify the array at all.
*/
- virtual GrFragmentProcessor* asFragmentProcessor(GrContext*) const;
+ virtual bool asFragmentProcessors(GrContext*, SkTDArray<GrFragmentProcessor*>*) const {
+ return false;
+ }
SK_TO_STRING_PUREVIRT()
diff --git a/include/effects/SkColorCubeFilter.h b/include/effects/SkColorCubeFilter.h
index 1d4d0fd17d..4500a0c292 100644
--- a/include/effects/SkColorCubeFilter.h
+++ b/include/effects/SkColorCubeFilter.h
@@ -25,7 +25,7 @@ public:
uint32_t getFlags() const SK_OVERRIDE;
#if SK_SUPPORT_GPU
- GrFragmentProcessor* asFragmentProcessor(GrContext*) const SK_OVERRIDE;
+ bool asFragmentProcessors(GrContext*, SkTDArray<GrFragmentProcessor*>*) const SK_OVERRIDE;
#endif
SK_TO_STRING_OVERRIDE()
diff --git a/include/effects/SkColorMatrixFilter.h b/include/effects/SkColorMatrixFilter.h
index ff806072a2..58f37ffe4b 100644
--- a/include/effects/SkColorMatrixFilter.h
+++ b/include/effects/SkColorMatrixFilter.h
@@ -28,7 +28,7 @@ public:
SkColorFilter* newComposed(const SkColorFilter*) const SK_OVERRIDE;
#if SK_SUPPORT_GPU
- GrFragmentProcessor* asFragmentProcessor(GrContext*) const SK_OVERRIDE;
+ bool asFragmentProcessors(GrContext*, SkTDArray<GrFragmentProcessor*>*) const SK_OVERRIDE;
#endif
struct State {
diff --git a/include/effects/SkLumaColorFilter.h b/include/effects/SkLumaColorFilter.h
index c7bb2db8bc..c970e8c115 100644
--- a/include/effects/SkLumaColorFilter.h
+++ b/include/effects/SkLumaColorFilter.h
@@ -28,7 +28,7 @@ public:
void filterSpan(const SkPMColor src[], int count, SkPMColor[]) const SK_OVERRIDE;
#if SK_SUPPORT_GPU
- GrFragmentProcessor* asFragmentProcessor(GrContext*) const SK_OVERRIDE;
+ bool asFragmentProcessors(GrContext*, SkTDArray<GrFragmentProcessor*>*) const SK_OVERRIDE;
#endif
SK_TO_STRING_OVERRIDE()
diff --git a/include/effects/SkModeColorFilter.h b/include/effects/SkModeColorFilter.h
index 16c6e13359..4bb7a43db4 100644
--- a/include/effects/SkModeColorFilter.h
+++ b/include/effects/SkModeColorFilter.h
@@ -40,7 +40,7 @@ public:
#endif
#if SK_SUPPORT_GPU
- GrFragmentProcessor* asFragmentProcessor(GrContext*) const SK_OVERRIDE;
+ bool asFragmentProcessors(GrContext*, SkTDArray<GrFragmentProcessor*>*) const SK_OVERRIDE;
#endif
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkModeColorFilter)
diff --git a/src/core/SkColorFilter.cpp b/src/core/SkColorFilter.cpp
index 2a78058106..fd76dd1c9b 100644
--- a/src/core/SkColorFilter.cpp
+++ b/src/core/SkColorFilter.cpp
@@ -37,10 +37,6 @@ SkColor SkColorFilter::filterColor(SkColor c) const {
return SkUnPreMultiply::PMColorToColor(dst);
}
-GrFragmentProcessor* SkColorFilter::asFragmentProcessor(GrContext*) const {
- return NULL;
-}
-
///////////////////////////////////////////////////////////////////////////////////////////////////
class SkComposeColorFilter : public SkColorFilter {
@@ -75,10 +71,13 @@ public:
}
#endif
-#if 0 // TODO: should we support composing the fragments?
#if SK_SUPPORT_GPU
- GrFragmentProcessor* asFragmentProcessor(GrContext*) const SK_OVERRIDE;
-#endif
+ bool asFragmentProcessors(GrContext* context,
+ SkTDArray<GrFragmentProcessor*>* array) const SK_OVERRIDE {
+ bool hasFrags = fInner->asFragmentProcessors(context, array);
+ hasFrags |= fOuter->asFragmentProcessors(context, array);
+ return hasFrags;
+ }
#endif
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkComposeColorFilter)
diff --git a/src/effects/SkColorCubeFilter.cpp b/src/effects/SkColorCubeFilter.cpp
index f71f4719b4..e2aade75e5 100644
--- a/src/effects/SkColorCubeFilter.cpp
+++ b/src/effects/SkColorCubeFilter.cpp
@@ -337,7 +337,8 @@ void GrColorCubeEffect::GLProcessor::GenKey(const GrProcessor& proc,
const GrGLCaps&, GrProcessorKeyBuilder* b) {
}
-GrFragmentProcessor* SkColorCubeFilter::asFragmentProcessor(GrContext* context) const {
+bool SkColorCubeFilter::asFragmentProcessors(GrContext* context,
+ SkTDArray<GrFragmentProcessor*>* array) const {
static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain();
GrUniqueKey key;
GrUniqueKey::Builder builder(&key, kDomain, 2);
@@ -358,6 +359,13 @@ GrFragmentProcessor* SkColorCubeFilter::asFragmentProcessor(GrContext* context)
}
}
- return textureCube ? GrColorCubeEffect::Create(textureCube) : NULL;
+ GrFragmentProcessor* frag = textureCube ? GrColorCubeEffect::Create(textureCube) : NULL;
+ if (frag) {
+ if (array) {
+ *array->append() = frag;
+ }
+ return true;
+ }
+ return false;
}
#endif
diff --git a/src/effects/SkColorFilters.cpp b/src/effects/SkColorFilters.cpp
index 10e6958570..6f7d6886f8 100644
--- a/src/effects/SkColorFilters.cpp
+++ b/src/effects/SkColorFilters.cpp
@@ -366,11 +366,18 @@ GrFragmentProcessor* ModeColorFilterEffect::TestCreate(SkRandom* rand,
return ModeColorFilterEffect::Create(color, mode);
}
-GrFragmentProcessor* SkModeColorFilter::asFragmentProcessor(GrContext*) const {
+bool SkModeColorFilter::asFragmentProcessors(GrContext*,
+ SkTDArray<GrFragmentProcessor*>* array) const {
if (SkXfermode::kDst_Mode != fMode) {
- return ModeColorFilterEffect::Create(SkColor2GrColor(fColor), fMode);
+ GrFragmentProcessor* frag = ModeColorFilterEffect::Create(SkColor2GrColor(fColor), fMode);
+ if (frag) {
+ if (array) {
+ *array->append() = frag;
+ }
+ return true;
+ }
}
- return NULL;
+ return false;
}
#endif
diff --git a/src/effects/SkColorMatrixFilter.cpp b/src/effects/SkColorMatrixFilter.cpp
index 6ab4a67487..bb3b6dda78 100644
--- a/src/effects/SkColorMatrixFilter.cpp
+++ b/src/effects/SkColorMatrixFilter.cpp
@@ -494,8 +494,16 @@ GrFragmentProcessor* ColorMatrixEffect::TestCreate(SkRandom* random,
return ColorMatrixEffect::Create(colorMatrix);
}
-GrFragmentProcessor* SkColorMatrixFilter::asFragmentProcessor(GrContext*) const {
- return ColorMatrixEffect::Create(fMatrix);
+bool SkColorMatrixFilter::asFragmentProcessors(GrContext*,
+ SkTDArray<GrFragmentProcessor*>* array) const {
+ GrFragmentProcessor* frag = ColorMatrixEffect::Create(fMatrix);
+ if (frag) {
+ if (array) {
+ *array->append() = frag;
+ }
+ return true;
+ }
+ return false;
}
#endif
diff --git a/src/effects/SkLumaColorFilter.cpp b/src/effects/SkLumaColorFilter.cpp
index 20e0659dfe..b7860e0a0b 100644
--- a/src/effects/SkLumaColorFilter.cpp
+++ b/src/effects/SkLumaColorFilter.cpp
@@ -119,7 +119,16 @@ private:
}
};
-GrFragmentProcessor* SkLumaColorFilter::asFragmentProcessor(GrContext*) const {
- return LumaColorFilterEffect::Create();
+bool SkLumaColorFilter::asFragmentProcessors(GrContext*,
+ SkTDArray<GrFragmentProcessor*>* array) const {
+
+ GrFragmentProcessor* frag = LumaColorFilterEffect::Create();
+ if (frag) {
+ if (array) {
+ *array->append() = frag;
+ }
+ return true;
+ }
+ return false;
}
#endif
diff --git a/src/effects/SkPerlinNoiseShader.cpp b/src/effects/SkPerlinNoiseShader.cpp
index b721296afe..6e53253f29 100644
--- a/src/effects/SkPerlinNoiseShader.cpp
+++ b/src/effects/SkPerlinNoiseShader.cpp
@@ -967,7 +967,11 @@ bool SkPerlinNoiseShader::asFragmentProcessor(GrContext* context, const SkPaint&
}
SkAutoTUnref<SkColorFilter> cf(SkColorFilter::CreateModeFilter(
clearColor, SkXfermode::kSrc_Mode));
- *fp = cf->asFragmentProcessor(context);
+ SkTDArray<GrFragmentProcessor*> array;
+ if (cf->asFragmentProcessors(context, &array)) {
+ SkASSERT(1 == array.count()); // modecolorfilter only returns one
+ *fp = array[0]; // transfer ownership to fp
+ }
return true;
}
diff --git a/src/effects/SkTableColorFilter.cpp b/src/effects/SkTableColorFilter.cpp
index d6c3e5f032..073bc18805 100644
--- a/src/effects/SkTableColorFilter.cpp
+++ b/src/effects/SkTableColorFilter.cpp
@@ -44,7 +44,7 @@ public:
SkColorFilter* newComposed(const SkColorFilter* inner) const SK_OVERRIDE;
#if SK_SUPPORT_GPU
- GrFragmentProcessor* asFragmentProcessor(GrContext* context) const SK_OVERRIDE;
+ bool asFragmentProcessors(GrContext*, SkTDArray<GrFragmentProcessor*>*) const SK_OVERRIDE;
#endif
void filterSpan(const SkPMColor src[], int count, SkPMColor dst[]) const SK_OVERRIDE;
@@ -567,14 +567,28 @@ GrFragmentProcessor* ColorTableEffect::TestCreate(SkRandom* random,
(flags & (1 << 2)) ? luts[2] : NULL,
(flags & (1 << 3)) ? luts[3] : NULL
));
- return filter->asFragmentProcessor(context);
+
+ SkTDArray<GrFragmentProcessor*> array;
+ if (filter->asFragmentProcessors(context, &array)) {
+ SkASSERT(1 == array.count()); // TableColorFilter only returns 1
+ return array[0];
+ }
+ return NULL;
}
-GrFragmentProcessor* SkTable_ColorFilter::asFragmentProcessor(GrContext* context) const {
+bool SkTable_ColorFilter::asFragmentProcessors(GrContext* context,
+ SkTDArray<GrFragmentProcessor*>* array) const {
SkBitmap bitmap;
this->asComponentTable(&bitmap);
- return ColorTableEffect::Create(context, bitmap, fFlags);
+ GrFragmentProcessor* frag = ColorTableEffect::Create(context, bitmap, fFlags);
+ if (frag) {
+ if (array) {
+ *array->append() = frag;
+ }
+ return true;
+ }
+ return false;
}
#endif // SK_SUPPORT_GPU
diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp
index 401a50eca8..ff6f7fa098 100644
--- a/src/gpu/SkGr.cpp
+++ b/src/gpu/SkGr.cpp
@@ -662,9 +662,12 @@ void SkPaint2GrPaintNoShader(GrContext* context, GrRenderTarget* rt, const SkPai
SkColor filtered = colorFilter->filterColor(skPaint.getColor());
grPaint->setColor(SkColor2GrColor(filtered));
} else {
- SkAutoTUnref<GrFragmentProcessor> fp(colorFilter->asFragmentProcessor(context));
- if (fp.get()) {
- grPaint->addColorProcessor(fp);
+ SkTDArray<GrFragmentProcessor*> array;
+ if (colorFilter->asFragmentProcessors(context, &array)) {
+ for (int i = 0; i < array.count(); ++i) {
+ grPaint->addColorProcessor(array[i]);
+ array[i]->unref();
+ }
}
}
}
diff --git a/tests/GpuColorFilterTest.cpp b/tests/GpuColorFilterTest.cpp
index bf0ba3046a..037734eebc 100644
--- a/tests/GpuColorFilterTest.cpp
+++ b/tests/GpuColorFilterTest.cpp
@@ -99,14 +99,18 @@ static void test_getConstantColorComponents(skiatest::Reporter* reporter, GrCont
for (size_t i = 0; i < SK_ARRAY_COUNT(filterTests); ++i) {
const GetConstantComponentTestCase& test = filterTests[i];
SkAutoTUnref<SkColorFilter> cf(SkColorFilter::CreateModeFilter(test.filterColor, test.filterMode));
- SkAutoTUnref<GrFragmentProcessor> effect(cf->asFragmentProcessor(grContext));
+ SkTDArray<GrFragmentProcessor*> array;
+ bool hasFrag = cf->asFragmentProcessors(grContext, &array);
+ REPORTER_ASSERT(reporter, hasFrag);
+ REPORTER_ASSERT(reporter, 1 == array.count());
GrInvariantOutput inout(test.inputColor,
static_cast<GrColorComponentFlags>(test.inputComponents),
false);
- effect->computeInvariantOutput(&inout);
+ array[0]->computeInvariantOutput(&inout);
REPORTER_ASSERT(reporter, filterColor(inout.color(), inout.validFlags()) == test.outputColor);
REPORTER_ASSERT(reporter, test.outputComponents == inout.validFlags());
+ array[0]->unref();
}
}