SkColorFilter.cpp revision 25f3805efa465bc3f804f192fe1ee64450f01d7c
1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/* 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2006 The Android Open Source Project 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * 4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */ 7ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 8ac04fef619ad3939a25e66bdaef6f6b1e7f5ca50Herb Derby#include "SkArenaAlloc.h" 94e92b821f0396fe7ca1bd6498d0f044fb49e59c8Mike Klein#include "SkColorFilter.h" 104e92b821f0396fe7ca1bd6498d0f044fb49e59c8Mike Klein#include "SkColorSpaceXformer.h" 114e92b821f0396fe7ca1bd6498d0f044fb49e59c8Mike Klein#include "SkNx.h" 124e92b821f0396fe7ca1bd6498d0f044fb49e59c8Mike Klein#include "SkPM4f.h" 136dfcecad33c949e775a3fd0a58637721ab5e295eMike Klein#include "SkRasterPipeline.h" 148b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org#include "SkReadBuffer.h" 15d3ebb48320cf1b7e969974673e4bd7743816985ebungeman#include "SkRefCnt.h" 165bd055c0386499f2dc8c66173a7534b75af602bfreed#include "SkString.h" 17d3ebb48320cf1b7e969974673e4bd7743816985ebungeman#include "SkTDArray.h" 18d3ebb48320cf1b7e969974673e4bd7743816985ebungeman#include "SkUnPreMultiply.h" 19db873d8677a2d4ecfe38a794a5d868301bdeeabereed#include "SkWriteBuffer.h" 206dfcecad33c949e775a3fd0a58637721ab5e295eMike Klein#include "../jumper/SkJumper.h" 218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 22e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon#if SK_SUPPORT_GPU 23e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon#include "GrFragmentProcessor.h" 24e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon#endif 25d3ebb48320cf1b7e969974673e4bd7743816985ebungeman 26faba3715b8ddfaa0ce4df79bc8006e9bc7694e5bMike Reedbool SkColorFilter::asColorMode(SkColor*, SkBlendMode*) const { 2743c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com return false; 2843c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com} 2943c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com 30bada64428a52b4fc1f31a0a1982c2301ec57601creed@google.combool SkColorFilter::asColorMatrix(SkScalar matrix[20]) const { 31e5ff3cefe007d092daf9d0bc2b03f9ff87b2c34esenorblanco@chromium.org return false; 32e5ff3cefe007d092daf9d0bc2b03f9ff87b2c34esenorblanco@chromium.org} 33e5ff3cefe007d092daf9d0bc2b03f9ff87b2c34esenorblanco@chromium.org 34b2ad101313cfba9c06a3a4dc06531766bcbec73bbsalomon@google.combool SkColorFilter::asComponentTable(SkBitmap*) const { 357191840eec5ac3b5f5814e4df3cf18264b0b0a4dreed@google.com return false; 367191840eec5ac3b5f5814e4df3cf18264b0b0a4dreed@google.com} 377191840eec5ac3b5f5814e4df3cf18264b0b0a4dreed@google.com 3806ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman#if SK_SUPPORT_GPU 39618d304eb394d64779be0ecdc5eff898242faa8fBrian Osmansk_sp<GrFragmentProcessor> SkColorFilter::asFragmentProcessor(GrContext*, SkColorSpace*) const { 4006ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman return nullptr; 4106ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman} 4206ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman#endif 4306ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman 446dfcecad33c949e775a3fd0a58637721ab5e295eMike Kleinvoid SkColorFilter::appendStages(SkRasterPipeline* p, 456dfcecad33c949e775a3fd0a58637721ab5e295eMike Klein SkColorSpace* dstCS, 466dfcecad33c949e775a3fd0a58637721ab5e295eMike Klein SkArenaAlloc* alloc, 47744908e5e81f81f34288a1b5547aa4ea990ad13dMike Klein bool shaderIsOpaque) const { 48fdf31035a9639c2d377bdf2ddb404d269f8ca42aMike Klein this->onAppendStages(p, dstCS, alloc, shaderIsOpaque); 49fdf31035a9639c2d377bdf2ddb404d269f8ca42aMike Klein} 506dfcecad33c949e775a3fd0a58637721ab5e295eMike Klein 51fdf31035a9639c2d377bdf2ddb404d269f8ca42aMike Kleinvoid SkColorFilter::onAppendStages(SkRasterPipeline* p, 52fdf31035a9639c2d377bdf2ddb404d269f8ca42aMike Klein SkColorSpace* dstCS, 53fdf31035a9639c2d377bdf2ddb404d269f8ca42aMike Klein SkArenaAlloc* alloc, 54fdf31035a9639c2d377bdf2ddb404d269f8ca42aMike Klein bool) const { 556dfcecad33c949e775a3fd0a58637721ab5e295eMike Klein struct Ctx : SkJumper_CallbackCtx { 566dfcecad33c949e775a3fd0a58637721ab5e295eMike Klein sk_sp<SkColorFilter> cf; 576dfcecad33c949e775a3fd0a58637721ab5e295eMike Klein }; 586dfcecad33c949e775a3fd0a58637721ab5e295eMike Klein auto ctx = alloc->make<Ctx>(); 59b8fbab2a1c79764e490e65ebc80288cdc0494237Mike Klein ctx->cf = dstCS ? SkColorSpaceXformer::Make(sk_ref_sp(dstCS))->apply(this) 60b8fbab2a1c79764e490e65ebc80288cdc0494237Mike Klein : sk_ref_sp(const_cast<SkColorFilter*>(this)); 616dfcecad33c949e775a3fd0a58637721ab5e295eMike Klein ctx->fn = [](SkJumper_CallbackCtx* arg, int active_pixels) { 626dfcecad33c949e775a3fd0a58637721ab5e295eMike Klein auto ctx = (Ctx*)arg; 636dfcecad33c949e775a3fd0a58637721ab5e295eMike Klein auto buf = (SkPM4f*)ctx->rgba; 6425f3805efa465bc3f804f192fe1ee64450f01d7cMike Reed ctx->cf->onFilterStage(buf, active_pixels, buf); 656dfcecad33c949e775a3fd0a58637721ab5e295eMike Klein }; 666dfcecad33c949e775a3fd0a58637721ab5e295eMike Klein p->append(SkRasterPipeline::callback, ctx); 679a5c47f4effba3b48a9a8c7c144b72b532d06efemtklein} 689a5c47f4effba3b48a9a8c7c144b72b532d06efemtklein 69bada64428a52b4fc1f31a0a1982c2301ec57601creed@google.comSkColor SkColorFilter::filterColor(SkColor c) const { 706b7aee387d3b4b2df5894b51fa1c0baf649c6540reed@google.com SkPMColor dst, src = SkPreMultiplyColor(c); 716b7aee387d3b4b2df5894b51fa1c0baf649c6540reed@google.com this->filterSpan(&src, 1, &dst); 726b7aee387d3b4b2df5894b51fa1c0baf649c6540reed@google.com return SkUnPreMultiply::PMColorToColor(dst); 736b7aee387d3b4b2df5894b51fa1c0baf649c6540reed@google.com} 746b7aee387d3b4b2df5894b51fa1c0baf649c6540reed@google.com 7525f3805efa465bc3f804f192fe1ee64450f01d7cMike Reed#include "SkRasterPipeline.h" 76f7cdb06d62bd732599c7ee407dfd76d32d671755reedSkColor4f SkColorFilter::filterColor4f(const SkColor4f& c) const { 77f7cdb06d62bd732599c7ee407dfd76d32d671755reed SkPM4f dst, src = c.premul(); 7825f3805efa465bc3f804f192fe1ee64450f01d7cMike Reed 7925f3805efa465bc3f804f192fe1ee64450f01d7cMike Reed SkSTArenaAlloc<128> alloc; 8025f3805efa465bc3f804f192fe1ee64450f01d7cMike Reed SkRasterPipeline pipeline(&alloc); 8125f3805efa465bc3f804f192fe1ee64450f01d7cMike Reed 8225f3805efa465bc3f804f192fe1ee64450f01d7cMike Reed pipeline.append(SkRasterPipeline::constant_color, &src); 8325f3805efa465bc3f804f192fe1ee64450f01d7cMike Reed this->onAppendStages(&pipeline, nullptr, &alloc, c.fA == 1); 8425f3805efa465bc3f804f192fe1ee64450f01d7cMike Reed SkPM4f* dstPtr = &dst; 8525f3805efa465bc3f804f192fe1ee64450f01d7cMike Reed pipeline.append(SkRasterPipeline::store_f32, &dstPtr); 8625f3805efa465bc3f804f192fe1ee64450f01d7cMike Reed pipeline.run(0,1); 8725f3805efa465bc3f804f192fe1ee64450f01d7cMike Reed 88f7cdb06d62bd732599c7ee407dfd76d32d671755reed return dst.unpremul(); 896d3cef930ad19b0f55543ca40f7a07030f4fe508reed} 906d3cef930ad19b0f55543ca40f7a07030f4fe508reed 91db873d8677a2d4ecfe38a794a5d868301bdeeabereed/////////////////////////////////////////////////////////////////////////////////////////////////// 92db873d8677a2d4ecfe38a794a5d868301bdeeabereed 93dc812222a7488d2a0e39b4a09c81c9f000d4b869reed/* 94dc812222a7488d2a0e39b4a09c81c9f000d4b869reed * Since colorfilters may be used on the GPU backend, and in that case we may string together 95dc812222a7488d2a0e39b4a09c81c9f000d4b869reed * many GrFragmentProcessors, we might exceed some internal instruction/resource limit. 96dc812222a7488d2a0e39b4a09c81c9f000d4b869reed * 97dc812222a7488d2a0e39b4a09c81c9f000d4b869reed * Since we don't yet know *what* those limits might be when we construct the final shader, 98dc812222a7488d2a0e39b4a09c81c9f000d4b869reed * we just set an arbitrary limit during construction. If later we find smarter ways to know what 99dc812222a7488d2a0e39b4a09c81c9f000d4b869reed * the limnits are, we can change this constant (or remove it). 100dc812222a7488d2a0e39b4a09c81c9f000d4b869reed */ 101dc812222a7488d2a0e39b4a09c81c9f000d4b869reed#define SK_MAX_COMPOSE_COLORFILTER_COUNT 4 102dc812222a7488d2a0e39b4a09c81c9f000d4b869reed 103db873d8677a2d4ecfe38a794a5d868301bdeeabereedclass SkComposeColorFilter : public SkColorFilter { 104db873d8677a2d4ecfe38a794a5d868301bdeeabereedpublic: 10536352bf5e38f45a70ee4f4fc132a38048d38206dmtklein uint32_t getFlags() const override { 106f7cdb06d62bd732599c7ee407dfd76d32d671755reed // Can only claim alphaunchanged and SkPM4f support if both our proxys do. 107db873d8677a2d4ecfe38a794a5d868301bdeeabereed return fOuter->getFlags() & fInner->getFlags(); 108db873d8677a2d4ecfe38a794a5d868301bdeeabereed } 1099d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 11036352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void filterSpan(const SkPMColor shader[], int count, SkPMColor result[]) const override { 111db873d8677a2d4ecfe38a794a5d868301bdeeabereed fInner->filterSpan(shader, count, result); 112db873d8677a2d4ecfe38a794a5d868301bdeeabereed fOuter->filterSpan(result, count, result); 113db873d8677a2d4ecfe38a794a5d868301bdeeabereed } 1149d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 115db873d8677a2d4ecfe38a794a5d868301bdeeabereed#ifndef SK_IGNORE_TO_STRING 11636352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void toString(SkString* str) const override { 117db873d8677a2d4ecfe38a794a5d868301bdeeabereed SkString outerS, innerS; 118db873d8677a2d4ecfe38a794a5d868301bdeeabereed fOuter->toString(&outerS); 119db873d8677a2d4ecfe38a794a5d868301bdeeabereed fInner->toString(&innerS); 12027bece831ddecfd33ee5fecd81ca9e6939b30e49Hal Canary // These strings can be long. SkString::appendf has limitations. 12127bece831ddecfd33ee5fecd81ca9e6939b30e49Hal Canary str->append(SkStringPrintf("SkComposeColorFilter: outer(%s) inner(%s)", outerS.c_str(), 12227bece831ddecfd33ee5fecd81ca9e6939b30e49Hal Canary innerS.c_str())); 123db873d8677a2d4ecfe38a794a5d868301bdeeabereed } 124db873d8677a2d4ecfe38a794a5d868301bdeeabereed#endif 125db873d8677a2d4ecfe38a794a5d868301bdeeabereed 126fdf31035a9639c2d377bdf2ddb404d269f8ca42aMike Klein void onAppendStages(SkRasterPipeline* p, SkColorSpace* dst, SkArenaAlloc* scratch, 1279444bdd32b4a3dcd1c5ac4099adade1b5ba167b7Mike Reed bool shaderIsOpaque) const override { 1289444bdd32b4a3dcd1c5ac4099adade1b5ba167b7Mike Reed bool innerIsOpaque = shaderIsOpaque; 1299444bdd32b4a3dcd1c5ac4099adade1b5ba167b7Mike Reed if (!(fInner->getFlags() & kAlphaUnchanged_Flag)) { 1309444bdd32b4a3dcd1c5ac4099adade1b5ba167b7Mike Reed innerIsOpaque = false; 1319444bdd32b4a3dcd1c5ac4099adade1b5ba167b7Mike Reed } 1326dfcecad33c949e775a3fd0a58637721ab5e295eMike Klein fInner->appendStages(p, dst, scratch, shaderIsOpaque); 1336dfcecad33c949e775a3fd0a58637721ab5e295eMike Klein fOuter->appendStages(p, dst, scratch, innerIsOpaque); 1349444bdd32b4a3dcd1c5ac4099adade1b5ba167b7Mike Reed } 1359444bdd32b4a3dcd1c5ac4099adade1b5ba167b7Mike Reed 136db873d8677a2d4ecfe38a794a5d868301bdeeabereed#if SK_SUPPORT_GPU 137618d304eb394d64779be0ecdc5eff898242faa8fBrian Osman sk_sp<GrFragmentProcessor> asFragmentProcessor(GrContext* context, 138618d304eb394d64779be0ecdc5eff898242faa8fBrian Osman SkColorSpace* dstColorSpace) const override { 139618d304eb394d64779be0ecdc5eff898242faa8fBrian Osman sk_sp<GrFragmentProcessor> innerFP(fInner->asFragmentProcessor(context, dstColorSpace)); 140618d304eb394d64779be0ecdc5eff898242faa8fBrian Osman sk_sp<GrFragmentProcessor> outerFP(fOuter->asFragmentProcessor(context, dstColorSpace)); 141e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon if (!innerFP || !outerFP) { 142e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon return nullptr; 143e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon } 14406ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman sk_sp<GrFragmentProcessor> series[] = { std::move(innerFP), std::move(outerFP) }; 145e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon return GrFragmentProcessor::RunInSeries(series, 2); 146cff10b21a9934afc540d121b493b204335829589reed } 147db873d8677a2d4ecfe38a794a5d868301bdeeabereed#endif 148db873d8677a2d4ecfe38a794a5d868301bdeeabereed 149db873d8677a2d4ecfe38a794a5d868301bdeeabereed SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkComposeColorFilter) 1509d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 151db873d8677a2d4ecfe38a794a5d868301bdeeabereedprotected: 15236352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void flatten(SkWriteBuffer& buffer) const override { 153d053ce9c54d4e5937a142278359e5a4cde18095ereed buffer.writeFlattenable(fOuter.get()); 154d053ce9c54d4e5937a142278359e5a4cde18095ereed buffer.writeFlattenable(fInner.get()); 155db873d8677a2d4ecfe38a794a5d868301bdeeabereed } 1569d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 157db873d8677a2d4ecfe38a794a5d868301bdeeabereedprivate: 158d053ce9c54d4e5937a142278359e5a4cde18095ereed SkComposeColorFilter(sk_sp<SkColorFilter> outer, sk_sp<SkColorFilter> inner, 159d053ce9c54d4e5937a142278359e5a4cde18095ereed int composedFilterCount) 160d053ce9c54d4e5937a142278359e5a4cde18095ereed : fOuter(std::move(outer)) 161d053ce9c54d4e5937a142278359e5a4cde18095ereed , fInner(std::move(inner)) 162dc812222a7488d2a0e39b4a09c81c9f000d4b869reed , fComposedFilterCount(composedFilterCount) 163dc812222a7488d2a0e39b4a09c81c9f000d4b869reed { 164dc812222a7488d2a0e39b4a09c81c9f000d4b869reed SkASSERT(composedFilterCount >= 2); 165dc812222a7488d2a0e39b4a09c81c9f000d4b869reed SkASSERT(composedFilterCount <= SK_MAX_COMPOSE_COLORFILTER_COUNT); 166dc812222a7488d2a0e39b4a09c81c9f000d4b869reed } 167dc812222a7488d2a0e39b4a09c81c9f000d4b869reed 16836352bf5e38f45a70ee4f4fc132a38048d38206dmtklein int privateComposedFilterCount() const override { 169dc812222a7488d2a0e39b4a09c81c9f000d4b869reed return fComposedFilterCount; 170dc812222a7488d2a0e39b4a09c81c9f000d4b869reed } 171dc812222a7488d2a0e39b4a09c81c9f000d4b869reed 172c1b879f11b937142f5478bd3b416b26be93dea23Matt Sarett bool asACompose(SkColorFilter** outer, SkColorFilter** inner) const override { 173c1b879f11b937142f5478bd3b416b26be93dea23Matt Sarett *outer = fOuter.get(); 174c1b879f11b937142f5478bd3b416b26be93dea23Matt Sarett *inner = fInner.get(); 175c1b879f11b937142f5478bd3b416b26be93dea23Matt Sarett return true; 176c1b879f11b937142f5478bd3b416b26be93dea23Matt Sarett } 177c1b879f11b937142f5478bd3b416b26be93dea23Matt Sarett 1784e92b821f0396fe7ca1bd6498d0f044fb49e59c8Mike Klein sk_sp<SkColorFilter> onMakeColorSpace(SkColorSpaceXformer* xformer) const override { 1794e92b821f0396fe7ca1bd6498d0f044fb49e59c8Mike Klein return SkColorFilter::MakeComposeFilter(xformer->apply(fOuter.get()), 1804e92b821f0396fe7ca1bd6498d0f044fb49e59c8Mike Klein xformer->apply(fInner.get())); 1814e92b821f0396fe7ca1bd6498d0f044fb49e59c8Mike Klein } 1824e92b821f0396fe7ca1bd6498d0f044fb49e59c8Mike Klein 183d053ce9c54d4e5937a142278359e5a4cde18095ereed sk_sp<SkColorFilter> fOuter; 184d053ce9c54d4e5937a142278359e5a4cde18095ereed sk_sp<SkColorFilter> fInner; 185d053ce9c54d4e5937a142278359e5a4cde18095ereed const int fComposedFilterCount; 186db873d8677a2d4ecfe38a794a5d868301bdeeabereed 187db873d8677a2d4ecfe38a794a5d868301bdeeabereed friend class SkColorFilter; 188db873d8677a2d4ecfe38a794a5d868301bdeeabereed 189db873d8677a2d4ecfe38a794a5d868301bdeeabereed typedef SkColorFilter INHERITED; 190db873d8677a2d4ecfe38a794a5d868301bdeeabereed}; 191db873d8677a2d4ecfe38a794a5d868301bdeeabereed 19260c9b58b3214b0154c931656e91e39b230e987d8reedsk_sp<SkFlattenable> SkComposeColorFilter::CreateProc(SkReadBuffer& buffer) { 193d053ce9c54d4e5937a142278359e5a4cde18095ereed sk_sp<SkColorFilter> outer(buffer.readColorFilter()); 194d053ce9c54d4e5937a142278359e5a4cde18095ereed sk_sp<SkColorFilter> inner(buffer.readColorFilter()); 19560c9b58b3214b0154c931656e91e39b230e987d8reed return MakeComposeFilter(std::move(outer), std::move(inner)); 196db873d8677a2d4ecfe38a794a5d868301bdeeabereed} 197db873d8677a2d4ecfe38a794a5d868301bdeeabereed 1988a8d841d485ff36b64d838575eb3735c1ddcf929reed/////////////////////////////////////////////////////////////////////////////////////////////////// 1998a8d841d485ff36b64d838575eb3735c1ddcf929reed 200d053ce9c54d4e5937a142278359e5a4cde18095ereedsk_sp<SkColorFilter> SkColorFilter::MakeComposeFilter(sk_sp<SkColorFilter> outer, 201d053ce9c54d4e5937a142278359e5a4cde18095ereed sk_sp<SkColorFilter> inner) { 202db873d8677a2d4ecfe38a794a5d868301bdeeabereed if (!outer) { 203d053ce9c54d4e5937a142278359e5a4cde18095ereed return inner; 204db873d8677a2d4ecfe38a794a5d868301bdeeabereed } 205db873d8677a2d4ecfe38a794a5d868301bdeeabereed if (!inner) { 206d053ce9c54d4e5937a142278359e5a4cde18095ereed return outer; 207db873d8677a2d4ecfe38a794a5d868301bdeeabereed } 2088a8d841d485ff36b64d838575eb3735c1ddcf929reed 2098a8d841d485ff36b64d838575eb3735c1ddcf929reed // Give the subclass a shot at a more optimal composition... 210d053ce9c54d4e5937a142278359e5a4cde18095ereed auto composition = outer->makeComposed(inner); 211dc812222a7488d2a0e39b4a09c81c9f000d4b869reed if (composition) { 212dc812222a7488d2a0e39b4a09c81c9f000d4b869reed return composition; 213dc812222a7488d2a0e39b4a09c81c9f000d4b869reed } 214dc812222a7488d2a0e39b4a09c81c9f000d4b869reed 215dc812222a7488d2a0e39b4a09c81c9f000d4b869reed int count = inner->privateComposedFilterCount() + outer->privateComposedFilterCount(); 216dc812222a7488d2a0e39b4a09c81c9f000d4b869reed if (count > SK_MAX_COMPOSE_COLORFILTER_COUNT) { 21796fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 2188a8d841d485ff36b64d838575eb3735c1ddcf929reed } 219d053ce9c54d4e5937a142278359e5a4cde18095ereed return sk_sp<SkColorFilter>(new SkComposeColorFilter(std::move(outer), std::move(inner),count)); 220db873d8677a2d4ecfe38a794a5d868301bdeeabereed} 221db873d8677a2d4ecfe38a794a5d868301bdeeabereed 222c7141eb8fba41f1e098499ef17d0bc79641d54c5reed#include "SkModeColorFilter.h" 223c7141eb8fba41f1e098499ef17d0bc79641d54c5reed 224db873d8677a2d4ecfe38a794a5d868301bdeeabereedSK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkColorFilter) 225db873d8677a2d4ecfe38a794a5d868301bdeeabereedSK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkComposeColorFilter) 226c7141eb8fba41f1e098499ef17d0bc79641d54c5reedSK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkModeColorFilter) 227db873d8677a2d4ecfe38a794a5d868301bdeeabereedSK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END 228