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 88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkColorFilter.h" 9ac04fef619ad3939a25e66bdaef6f6b1e7f5ca50Herb Derby#include "SkArenaAlloc.h" 108b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org#include "SkReadBuffer.h" 11d3ebb48320cf1b7e969974673e4bd7743816985ebungeman#include "SkRefCnt.h" 125bd055c0386499f2dc8c66173a7534b75af602bfreed#include "SkString.h" 13d3ebb48320cf1b7e969974673e4bd7743816985ebungeman#include "SkTDArray.h" 14d3ebb48320cf1b7e969974673e4bd7743816985ebungeman#include "SkUnPreMultiply.h" 15db873d8677a2d4ecfe38a794a5d868301bdeeabereed#include "SkWriteBuffer.h" 16dd9ffea9ce051a49dbc6544e6aa3cb68fe987f47reed#include "SkPM4f.h" 17c5b1228141bd26d4573552a00ebeb0b85a4768dfreed#include "SkNx.h" 188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 19e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon#if SK_SUPPORT_GPU 20e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon#include "GrFragmentProcessor.h" 21e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon#endif 22d3ebb48320cf1b7e969974673e4bd7743816985ebungeman 23faba3715b8ddfaa0ce4df79bc8006e9bc7694e5bMike Reedbool SkColorFilter::asColorMode(SkColor*, SkBlendMode*) const { 2443c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com return false; 2543c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com} 2643c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com 27bada64428a52b4fc1f31a0a1982c2301ec57601creed@google.combool SkColorFilter::asColorMatrix(SkScalar matrix[20]) const { 28e5ff3cefe007d092daf9d0bc2b03f9ff87b2c34esenorblanco@chromium.org return false; 29e5ff3cefe007d092daf9d0bc2b03f9ff87b2c34esenorblanco@chromium.org} 30e5ff3cefe007d092daf9d0bc2b03f9ff87b2c34esenorblanco@chromium.org 31b2ad101313cfba9c06a3a4dc06531766bcbec73bbsalomon@google.combool SkColorFilter::asComponentTable(SkBitmap*) const { 327191840eec5ac3b5f5814e4df3cf18264b0b0a4dreed@google.com return false; 337191840eec5ac3b5f5814e4df3cf18264b0b0a4dreed@google.com} 347191840eec5ac3b5f5814e4df3cf18264b0b0a4dreed@google.com 3506ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman#if SK_SUPPORT_GPU 36618d304eb394d64779be0ecdc5eff898242faa8fBrian Osmansk_sp<GrFragmentProcessor> SkColorFilter::asFragmentProcessor(GrContext*, SkColorSpace*) const { 3706ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman return nullptr; 3806ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman} 3906ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman#endif 4006ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman 41744908e5e81f81f34288a1b5547aa4ea990ad13dMike Kleinbool SkColorFilter::appendStages(SkRasterPipeline* pipeline, 42744908e5e81f81f34288a1b5547aa4ea990ad13dMike Klein SkColorSpace* dst, 43ac04fef619ad3939a25e66bdaef6f6b1e7f5ca50Herb Derby SkArenaAlloc* scratch, 44744908e5e81f81f34288a1b5547aa4ea990ad13dMike Klein bool shaderIsOpaque) const { 45744908e5e81f81f34288a1b5547aa4ea990ad13dMike Klein return this->onAppendStages(pipeline, dst, scratch, shaderIsOpaque); 469a5c47f4effba3b48a9a8c7c144b72b532d06efemtklein} 479a5c47f4effba3b48a9a8c7c144b72b532d06efemtklein 48ac04fef619ad3939a25e66bdaef6f6b1e7f5ca50Herb Derbybool SkColorFilter::onAppendStages(SkRasterPipeline*, SkColorSpace*, SkArenaAlloc*, bool) const { 499a5c47f4effba3b48a9a8c7c144b72b532d06efemtklein return false; 509a5c47f4effba3b48a9a8c7c144b72b532d06efemtklein} 519a5c47f4effba3b48a9a8c7c144b72b532d06efemtklein 52ff723af8b6bc7179132052fbab7d77ec2a20eba2brianosmanvoid SkColorFilter::filterSpan4f(const SkPM4f src[], int count, SkPM4f result[]) const { 53c5b1228141bd26d4573552a00ebeb0b85a4768dfreed const int N = 128; 54c5b1228141bd26d4573552a00ebeb0b85a4768dfreed SkPMColor tmp[N]; 55c5b1228141bd26d4573552a00ebeb0b85a4768dfreed while (count > 0) { 56c5b1228141bd26d4573552a00ebeb0b85a4768dfreed int n = SkTMin(count, N); 57c5b1228141bd26d4573552a00ebeb0b85a4768dfreed for (int i = 0; i < n; ++i) { 58e2cddc5342d5aacacce4429441c94d1e0ff67d8cbrianosman tmp[i] = src[i].toPMColor(); 59c5b1228141bd26d4573552a00ebeb0b85a4768dfreed } 60c5b1228141bd26d4573552a00ebeb0b85a4768dfreed this->filterSpan(tmp, n, tmp); 61c5b1228141bd26d4573552a00ebeb0b85a4768dfreed for (int i = 0; i < n; ++i) { 62ff723af8b6bc7179132052fbab7d77ec2a20eba2brianosman result[i] = SkPM4f::FromPMColor(tmp[i]); 63c5b1228141bd26d4573552a00ebeb0b85a4768dfreed } 64ff723af8b6bc7179132052fbab7d77ec2a20eba2brianosman src += n; 65ff723af8b6bc7179132052fbab7d77ec2a20eba2brianosman result += n; 66c5b1228141bd26d4573552a00ebeb0b85a4768dfreed count -= n; 67f7cdb06d62bd732599c7ee407dfd76d32d671755reed } 68f7cdb06d62bd732599c7ee407dfd76d32d671755reed} 69f7cdb06d62bd732599c7ee407dfd76d32d671755reed 70bada64428a52b4fc1f31a0a1982c2301ec57601creed@google.comSkColor SkColorFilter::filterColor(SkColor c) const { 716b7aee387d3b4b2df5894b51fa1c0baf649c6540reed@google.com SkPMColor dst, src = SkPreMultiplyColor(c); 726b7aee387d3b4b2df5894b51fa1c0baf649c6540reed@google.com this->filterSpan(&src, 1, &dst); 736b7aee387d3b4b2df5894b51fa1c0baf649c6540reed@google.com return SkUnPreMultiply::PMColorToColor(dst); 746b7aee387d3b4b2df5894b51fa1c0baf649c6540reed@google.com} 756b7aee387d3b4b2df5894b51fa1c0baf649c6540reed@google.com 76f7cdb06d62bd732599c7ee407dfd76d32d671755reedSkColor4f SkColorFilter::filterColor4f(const SkColor4f& c) const { 77f7cdb06d62bd732599c7ee407dfd76d32d671755reed SkPM4f dst, src = c.premul(); 78f7cdb06d62bd732599c7ee407dfd76d32d671755reed this->filterSpan4f(&src, 1, &dst); 79f7cdb06d62bd732599c7ee407dfd76d32d671755reed return dst.unpremul(); 806d3cef930ad19b0f55543ca40f7a07030f4fe508reed} 816d3cef930ad19b0f55543ca40f7a07030f4fe508reed 82db873d8677a2d4ecfe38a794a5d868301bdeeabereed/////////////////////////////////////////////////////////////////////////////////////////////////// 83db873d8677a2d4ecfe38a794a5d868301bdeeabereed 84dc812222a7488d2a0e39b4a09c81c9f000d4b869reed/* 85dc812222a7488d2a0e39b4a09c81c9f000d4b869reed * Since colorfilters may be used on the GPU backend, and in that case we may string together 86dc812222a7488d2a0e39b4a09c81c9f000d4b869reed * many GrFragmentProcessors, we might exceed some internal instruction/resource limit. 87dc812222a7488d2a0e39b4a09c81c9f000d4b869reed * 88dc812222a7488d2a0e39b4a09c81c9f000d4b869reed * Since we don't yet know *what* those limits might be when we construct the final shader, 89dc812222a7488d2a0e39b4a09c81c9f000d4b869reed * we just set an arbitrary limit during construction. If later we find smarter ways to know what 90dc812222a7488d2a0e39b4a09c81c9f000d4b869reed * the limnits are, we can change this constant (or remove it). 91dc812222a7488d2a0e39b4a09c81c9f000d4b869reed */ 92dc812222a7488d2a0e39b4a09c81c9f000d4b869reed#define SK_MAX_COMPOSE_COLORFILTER_COUNT 4 93dc812222a7488d2a0e39b4a09c81c9f000d4b869reed 94db873d8677a2d4ecfe38a794a5d868301bdeeabereedclass SkComposeColorFilter : public SkColorFilter { 95db873d8677a2d4ecfe38a794a5d868301bdeeabereedpublic: 9636352bf5e38f45a70ee4f4fc132a38048d38206dmtklein uint32_t getFlags() const override { 97f7cdb06d62bd732599c7ee407dfd76d32d671755reed // Can only claim alphaunchanged and SkPM4f support if both our proxys do. 98db873d8677a2d4ecfe38a794a5d868301bdeeabereed return fOuter->getFlags() & fInner->getFlags(); 99db873d8677a2d4ecfe38a794a5d868301bdeeabereed } 1009d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 10136352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void filterSpan(const SkPMColor shader[], int count, SkPMColor result[]) const override { 102db873d8677a2d4ecfe38a794a5d868301bdeeabereed fInner->filterSpan(shader, count, result); 103db873d8677a2d4ecfe38a794a5d868301bdeeabereed fOuter->filterSpan(result, count, result); 104db873d8677a2d4ecfe38a794a5d868301bdeeabereed } 1059d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 106f7cdb06d62bd732599c7ee407dfd76d32d671755reed void filterSpan4f(const SkPM4f shader[], int count, SkPM4f result[]) const override { 107f7cdb06d62bd732599c7ee407dfd76d32d671755reed fInner->filterSpan4f(shader, count, result); 108f7cdb06d62bd732599c7ee407dfd76d32d671755reed fOuter->filterSpan4f(result, count, result); 109f7cdb06d62bd732599c7ee407dfd76d32d671755reed } 1109d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 111db873d8677a2d4ecfe38a794a5d868301bdeeabereed#ifndef SK_IGNORE_TO_STRING 11236352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void toString(SkString* str) const override { 113db873d8677a2d4ecfe38a794a5d868301bdeeabereed SkString outerS, innerS; 114db873d8677a2d4ecfe38a794a5d868301bdeeabereed fOuter->toString(&outerS); 115db873d8677a2d4ecfe38a794a5d868301bdeeabereed fInner->toString(&innerS); 11627bece831ddecfd33ee5fecd81ca9e6939b30e49Hal Canary // These strings can be long. SkString::appendf has limitations. 11727bece831ddecfd33ee5fecd81ca9e6939b30e49Hal Canary str->append(SkStringPrintf("SkComposeColorFilter: outer(%s) inner(%s)", outerS.c_str(), 11827bece831ddecfd33ee5fecd81ca9e6939b30e49Hal Canary innerS.c_str())); 119db873d8677a2d4ecfe38a794a5d868301bdeeabereed } 120db873d8677a2d4ecfe38a794a5d868301bdeeabereed#endif 121db873d8677a2d4ecfe38a794a5d868301bdeeabereed 122db873d8677a2d4ecfe38a794a5d868301bdeeabereed#if SK_SUPPORT_GPU 123618d304eb394d64779be0ecdc5eff898242faa8fBrian Osman sk_sp<GrFragmentProcessor> asFragmentProcessor(GrContext* context, 124618d304eb394d64779be0ecdc5eff898242faa8fBrian Osman SkColorSpace* dstColorSpace) const override { 125618d304eb394d64779be0ecdc5eff898242faa8fBrian Osman sk_sp<GrFragmentProcessor> innerFP(fInner->asFragmentProcessor(context, dstColorSpace)); 126618d304eb394d64779be0ecdc5eff898242faa8fBrian Osman sk_sp<GrFragmentProcessor> outerFP(fOuter->asFragmentProcessor(context, dstColorSpace)); 127e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon if (!innerFP || !outerFP) { 128e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon return nullptr; 129e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon } 13006ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman sk_sp<GrFragmentProcessor> series[] = { std::move(innerFP), std::move(outerFP) }; 131e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon return GrFragmentProcessor::RunInSeries(series, 2); 132cff10b21a9934afc540d121b493b204335829589reed } 133db873d8677a2d4ecfe38a794a5d868301bdeeabereed#endif 134db873d8677a2d4ecfe38a794a5d868301bdeeabereed 135db873d8677a2d4ecfe38a794a5d868301bdeeabereed SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkComposeColorFilter) 1369d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 137db873d8677a2d4ecfe38a794a5d868301bdeeabereedprotected: 13836352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void flatten(SkWriteBuffer& buffer) const override { 139d053ce9c54d4e5937a142278359e5a4cde18095ereed buffer.writeFlattenable(fOuter.get()); 140d053ce9c54d4e5937a142278359e5a4cde18095ereed buffer.writeFlattenable(fInner.get()); 141db873d8677a2d4ecfe38a794a5d868301bdeeabereed } 1429d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 143db873d8677a2d4ecfe38a794a5d868301bdeeabereedprivate: 144d053ce9c54d4e5937a142278359e5a4cde18095ereed SkComposeColorFilter(sk_sp<SkColorFilter> outer, sk_sp<SkColorFilter> inner, 145d053ce9c54d4e5937a142278359e5a4cde18095ereed int composedFilterCount) 146d053ce9c54d4e5937a142278359e5a4cde18095ereed : fOuter(std::move(outer)) 147d053ce9c54d4e5937a142278359e5a4cde18095ereed , fInner(std::move(inner)) 148dc812222a7488d2a0e39b4a09c81c9f000d4b869reed , fComposedFilterCount(composedFilterCount) 149dc812222a7488d2a0e39b4a09c81c9f000d4b869reed { 150dc812222a7488d2a0e39b4a09c81c9f000d4b869reed SkASSERT(composedFilterCount >= 2); 151dc812222a7488d2a0e39b4a09c81c9f000d4b869reed SkASSERT(composedFilterCount <= SK_MAX_COMPOSE_COLORFILTER_COUNT); 152dc812222a7488d2a0e39b4a09c81c9f000d4b869reed } 153dc812222a7488d2a0e39b4a09c81c9f000d4b869reed 15436352bf5e38f45a70ee4f4fc132a38048d38206dmtklein int privateComposedFilterCount() const override { 155dc812222a7488d2a0e39b4a09c81c9f000d4b869reed return fComposedFilterCount; 156dc812222a7488d2a0e39b4a09c81c9f000d4b869reed } 157dc812222a7488d2a0e39b4a09c81c9f000d4b869reed 158d053ce9c54d4e5937a142278359e5a4cde18095ereed sk_sp<SkColorFilter> fOuter; 159d053ce9c54d4e5937a142278359e5a4cde18095ereed sk_sp<SkColorFilter> fInner; 160d053ce9c54d4e5937a142278359e5a4cde18095ereed const int fComposedFilterCount; 161db873d8677a2d4ecfe38a794a5d868301bdeeabereed 162db873d8677a2d4ecfe38a794a5d868301bdeeabereed friend class SkColorFilter; 163db873d8677a2d4ecfe38a794a5d868301bdeeabereed 164db873d8677a2d4ecfe38a794a5d868301bdeeabereed typedef SkColorFilter INHERITED; 165db873d8677a2d4ecfe38a794a5d868301bdeeabereed}; 166db873d8677a2d4ecfe38a794a5d868301bdeeabereed 16760c9b58b3214b0154c931656e91e39b230e987d8reedsk_sp<SkFlattenable> SkComposeColorFilter::CreateProc(SkReadBuffer& buffer) { 168d053ce9c54d4e5937a142278359e5a4cde18095ereed sk_sp<SkColorFilter> outer(buffer.readColorFilter()); 169d053ce9c54d4e5937a142278359e5a4cde18095ereed sk_sp<SkColorFilter> inner(buffer.readColorFilter()); 17060c9b58b3214b0154c931656e91e39b230e987d8reed return MakeComposeFilter(std::move(outer), std::move(inner)); 171db873d8677a2d4ecfe38a794a5d868301bdeeabereed} 172db873d8677a2d4ecfe38a794a5d868301bdeeabereed 1738a8d841d485ff36b64d838575eb3735c1ddcf929reed/////////////////////////////////////////////////////////////////////////////////////////////////// 1748a8d841d485ff36b64d838575eb3735c1ddcf929reed 175d053ce9c54d4e5937a142278359e5a4cde18095ereedsk_sp<SkColorFilter> SkColorFilter::MakeComposeFilter(sk_sp<SkColorFilter> outer, 176d053ce9c54d4e5937a142278359e5a4cde18095ereed sk_sp<SkColorFilter> inner) { 177db873d8677a2d4ecfe38a794a5d868301bdeeabereed if (!outer) { 178d053ce9c54d4e5937a142278359e5a4cde18095ereed return inner; 179db873d8677a2d4ecfe38a794a5d868301bdeeabereed } 180db873d8677a2d4ecfe38a794a5d868301bdeeabereed if (!inner) { 181d053ce9c54d4e5937a142278359e5a4cde18095ereed return outer; 182db873d8677a2d4ecfe38a794a5d868301bdeeabereed } 1838a8d841d485ff36b64d838575eb3735c1ddcf929reed 1848a8d841d485ff36b64d838575eb3735c1ddcf929reed // Give the subclass a shot at a more optimal composition... 185d053ce9c54d4e5937a142278359e5a4cde18095ereed auto composition = outer->makeComposed(inner); 186dc812222a7488d2a0e39b4a09c81c9f000d4b869reed if (composition) { 187dc812222a7488d2a0e39b4a09c81c9f000d4b869reed return composition; 188dc812222a7488d2a0e39b4a09c81c9f000d4b869reed } 189dc812222a7488d2a0e39b4a09c81c9f000d4b869reed 190dc812222a7488d2a0e39b4a09c81c9f000d4b869reed int count = inner->privateComposedFilterCount() + outer->privateComposedFilterCount(); 191dc812222a7488d2a0e39b4a09c81c9f000d4b869reed if (count > SK_MAX_COMPOSE_COLORFILTER_COUNT) { 19296fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 1938a8d841d485ff36b64d838575eb3735c1ddcf929reed } 194d053ce9c54d4e5937a142278359e5a4cde18095ereed return sk_sp<SkColorFilter>(new SkComposeColorFilter(std::move(outer), std::move(inner),count)); 195db873d8677a2d4ecfe38a794a5d868301bdeeabereed} 196db873d8677a2d4ecfe38a794a5d868301bdeeabereed 197c7141eb8fba41f1e098499ef17d0bc79641d54c5reed#include "SkModeColorFilter.h" 198c7141eb8fba41f1e098499ef17d0bc79641d54c5reed 199db873d8677a2d4ecfe38a794a5d868301bdeeabereedSK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkColorFilter) 200db873d8677a2d4ecfe38a794a5d868301bdeeabereedSK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkComposeColorFilter) 201c7141eb8fba41f1e098499ef17d0bc79641d54c5reedSK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkModeColorFilter) 202db873d8677a2d4ecfe38a794a5d868301bdeeabereedSK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END 203