diff options
author | reed <reed@google.com> | 2015-03-03 06:41:45 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-03-03 06:41:45 -0800 |
commit | cff10b21a9934afc540d121b493b204335829589 (patch) | |
tree | f696624f21c4a45a052250cb9a18460e8aea0c0d | |
parent | 3ebb16df938099dcbb6645ca08365e6d1dde8ddd (diff) |
change colorfilter to return an array of frag processors
BUG=skia:
Review URL: https://codereview.chromium.org/973593002
-rw-r--r-- | gm/tablecolorfilter.cpp | 75 | ||||
-rw-r--r-- | include/core/SkColorFilter.h | 17 | ||||
-rw-r--r-- | include/effects/SkColorCubeFilter.h | 2 | ||||
-rw-r--r-- | include/effects/SkColorMatrixFilter.h | 2 | ||||
-rw-r--r-- | include/effects/SkLumaColorFilter.h | 2 | ||||
-rw-r--r-- | include/effects/SkModeColorFilter.h | 2 | ||||
-rw-r--r-- | src/core/SkColorFilter.cpp | 13 | ||||
-rw-r--r-- | src/effects/SkColorCubeFilter.cpp | 12 | ||||
-rw-r--r-- | src/effects/SkColorFilters.cpp | 13 | ||||
-rw-r--r-- | src/effects/SkColorMatrixFilter.cpp | 12 | ||||
-rw-r--r-- | src/effects/SkLumaColorFilter.cpp | 13 | ||||
-rw-r--r-- | src/effects/SkPerlinNoiseShader.cpp | 6 | ||||
-rw-r--r-- | src/effects/SkTableColorFilter.cpp | 22 | ||||
-rw-r--r-- | src/gpu/SkGr.cpp | 9 | ||||
-rw-r--r-- | tests/GpuColorFilterTest.cpp | 8 |
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(); } } |