1 /* 2 * Copyright 2013 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #include "SkArenaAlloc.h" 9 #include "SkColorFilterShader.h" 10 #include "SkColorSpaceXformer.h" 11 #include "SkReadBuffer.h" 12 #include "SkWriteBuffer.h" 13 #include "SkShader.h" 14 #include "SkString.h" 15 16 #if SK_SUPPORT_GPU 17 #include "GrFragmentProcessor.h" 18 #endif 19 20 SkColorFilterShader::SkColorFilterShader(sk_sp<SkShader> shader, sk_sp<SkColorFilter> filter) 21 : fShader(std::move(shader)) 22 , fFilter(std::move(filter)) 23 { 24 SkASSERT(fShader); 25 SkASSERT(fFilter); 26 } 27 28 sk_sp<SkFlattenable> SkColorFilterShader::CreateProc(SkReadBuffer& buffer) { 29 auto shader = buffer.readShader(); 30 auto filter = buffer.readColorFilter(); 31 if (!shader || !filter) { 32 return nullptr; 33 } 34 return sk_make_sp<SkColorFilterShader>(shader, filter); 35 } 36 37 void SkColorFilterShader::flatten(SkWriteBuffer& buffer) const { 38 buffer.writeFlattenable(fShader.get()); 39 buffer.writeFlattenable(fFilter.get()); 40 } 41 42 bool SkColorFilterShader::onAppendStages(SkRasterPipeline* pipeline, SkColorSpace* dstCS, 43 SkArenaAlloc* alloc, const SkMatrix& ctm, 44 const SkPaint& paint, const SkMatrix* localM) const { 45 if (!as_SB(fShader)->appendStages(pipeline, dstCS, alloc, ctm, paint, localM)) { 46 return false; 47 } 48 fFilter->appendStages(pipeline, dstCS, alloc, fShader->isOpaque()); 49 return true; 50 } 51 52 sk_sp<SkShader> SkColorFilterShader::onMakeColorSpace(SkColorSpaceXformer* xformer) const { 53 return xformer->apply(fShader.get())->makeWithColorFilter(xformer->apply(fFilter.get())); 54 } 55 56 #if SK_SUPPORT_GPU 57 ///////////////////////////////////////////////////////////////////// 58 59 sk_sp<GrFragmentProcessor> SkColorFilterShader::asFragmentProcessor(const AsFPArgs& args) const { 60 61 sk_sp<GrFragmentProcessor> fp1(as_SB(fShader)->asFragmentProcessor(args)); 62 if (!fp1) { 63 return nullptr; 64 } 65 66 sk_sp<GrFragmentProcessor> fp2(fFilter->asFragmentProcessor(args.fContext, 67 args.fDstColorSpace)); 68 if (!fp2) { 69 return fp1; 70 } 71 72 sk_sp<GrFragmentProcessor> fpSeries[] = { std::move(fp1), std::move(fp2) }; 73 return GrFragmentProcessor::RunInSeries(fpSeries, 2); 74 } 75 #endif 76 77 #ifndef SK_IGNORE_TO_STRING 78 void SkColorFilterShader::toString(SkString* str) const { 79 str->append("SkColorFilterShader: ("); 80 81 str->append("Shader: "); 82 as_SB(fShader)->toString(str); 83 str->append(" Filter: "); 84 // TODO: add "fFilter->toString(str);" once SkColorFilter::toString is added 85 86 this->INHERITED::toString(str); 87 88 str->append(")"); 89 } 90 #endif 91 92 /////////////////////////////////////////////////////////////////////////////////////////////////// 93 94 sk_sp<SkShader> SkShader::makeWithColorFilter(sk_sp<SkColorFilter> filter) const { 95 SkShader* base = const_cast<SkShader*>(this); 96 if (!filter) { 97 return sk_ref_sp(base); 98 } 99 return sk_make_sp<SkColorFilterShader>(sk_ref_sp(base), filter); 100 } 101