Home | History | Annotate | Download | only in shaders
      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