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(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 #ifndef SK_IGNORE_TO_STRING
     75 void SkColorFilterShader::toString(SkString* str) const {
     76     str->append("SkColorFilterShader: (");
     77 
     78     str->append("Shader: ");
     79     as_SB(fShader)->toString(str);
     80     str->append(" Filter: ");
     81     // TODO: add "fFilter->toString(str);" once SkColorFilter::toString is added
     82 
     83     this->INHERITED::toString(str);
     84 
     85     str->append(")");
     86 }
     87 #endif
     88 
     89 ///////////////////////////////////////////////////////////////////////////////////////////////////
     90 
     91 sk_sp<SkShader> SkShader::makeWithColorFilter(sk_sp<SkColorFilter> filter) const {
     92     SkShader* base = const_cast<SkShader*>(this);
     93     if (!filter) {
     94         return sk_ref_sp(base);
     95     }
     96     return sk_make_sp<SkColorFilterShader>(sk_ref_sp(base), filter);
     97 }
     98