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(const StageRec& rec) const { 43 if (!as_SB(fShader)->appendStages(rec)) { 44 return false; 45 } 46 fFilter->appendStages(rec.fPipeline, rec.fDstCS, rec.fAlloc, fShader->isOpaque()); 47 return true; 48 } 49 50 sk_sp<SkShader> SkColorFilterShader::onMakeColorSpace(SkColorSpaceXformer* xformer) const { 51 return xformer->apply(fShader.get())->makeWithColorFilter(xformer->apply(fFilter.get())); 52 } 53 54 #if SK_SUPPORT_GPU 55 ///////////////////////////////////////////////////////////////////// 56 57 std::unique_ptr<GrFragmentProcessor> SkColorFilterShader::asFragmentProcessor( 58 const GrFPArgs& args) const { 59 auto fp1 = as_SB(fShader)->asFragmentProcessor(args); 60 if (!fp1) { 61 return nullptr; 62 } 63 64 auto fp2 = fFilter->asFragmentProcessor(args.fContext, *args.fDstColorSpaceInfo); 65 if (!fp2) { 66 return fp1; 67 } 68 69 std::unique_ptr<GrFragmentProcessor> fpSeries[] = { std::move(fp1), std::move(fp2) }; 70 return GrFragmentProcessor::RunInSeries(fpSeries, 2); 71 } 72 #endif 73 74 /////////////////////////////////////////////////////////////////////////////////////////////////// 75 76 sk_sp<SkShader> SkShader::makeWithColorFilter(sk_sp<SkColorFilter> filter) const { 77 SkShader* base = const_cast<SkShader*>(this); 78 if (!filter) { 79 return sk_ref_sp(base); 80 } 81 return sk_make_sp<SkColorFilterShader>(sk_ref_sp(base), filter); 82 } 83