13061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed/*
23061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed * Copyright 2013 Google Inc.
33061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed *
43061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed * Use of this source code is governed by a BSD-style license that can be
53061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed * found in the LICENSE file.
63061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed */
73061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed
883e939bcb79790f5ae3b28c398fbcf034675a6e5Herb Derby#include "SkArenaAlloc.h"
93061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed#include "SkColorFilterShader.h"
1072266eeca036b5216a9bfa0bb68cb0fbb9bbb57bMatt Sarett#include "SkColorSpaceXformer.h"
113061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed#include "SkReadBuffer.h"
123061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed#include "SkWriteBuffer.h"
133061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed#include "SkShader.h"
143061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed#include "SkString.h"
153061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed
163061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed#if SK_SUPPORT_GPU
173061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed#include "GrFragmentProcessor.h"
183061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed#endif
193061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed
20d053ce9c54d4e5937a142278359e5a4cde18095ereedSkColorFilterShader::SkColorFilterShader(sk_sp<SkShader> shader, sk_sp<SkColorFilter> filter)
21d053ce9c54d4e5937a142278359e5a4cde18095ereed    : fShader(std::move(shader))
22d053ce9c54d4e5937a142278359e5a4cde18095ereed    , fFilter(std::move(filter))
233061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed{
24d053ce9c54d4e5937a142278359e5a4cde18095ereed    SkASSERT(fShader);
25d053ce9c54d4e5937a142278359e5a4cde18095ereed    SkASSERT(fFilter);
263061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed}
273061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed
2860c9b58b3214b0154c931656e91e39b230e987d8reedsk_sp<SkFlattenable> SkColorFilterShader::CreateProc(SkReadBuffer& buffer) {
298a21c9fe7f5fef9e87115defef27bd7218419f28reed    auto shader = buffer.readShader();
30d053ce9c54d4e5937a142278359e5a4cde18095ereed    auto filter = buffer.readColorFilter();
31d053ce9c54d4e5937a142278359e5a4cde18095ereed    if (!shader || !filter) {
323061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed        return nullptr;
333061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed    }
3460c9b58b3214b0154c931656e91e39b230e987d8reed    return sk_make_sp<SkColorFilterShader>(shader, filter);
353061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed}
363061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed
373061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reedvoid SkColorFilterShader::flatten(SkWriteBuffer& buffer) const {
38d053ce9c54d4e5937a142278359e5a4cde18095ereed    buffer.writeFlattenable(fShader.get());
39d053ce9c54d4e5937a142278359e5a4cde18095ereed    buffer.writeFlattenable(fFilter.get());
403061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed}
413061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed
421d8c42eb903b66035ecf4d45b03dfeb1ad07b957Mike Reedbool SkColorFilterShader::onAppendStages(const StageRec& rec) const {
431d8c42eb903b66035ecf4d45b03dfeb1ad07b957Mike Reed    if (!as_SB(fShader)->appendStages(rec)) {
442aab8022a614422aa21a2b9bccb6583e77d3c2f1Mike Reed        return false;
452aab8022a614422aa21a2b9bccb6583e77d3c2f1Mike Reed    }
461d8c42eb903b66035ecf4d45b03dfeb1ad07b957Mike Reed    fFilter->appendStages(rec.fPipeline, rec.fDstCS, rec.fAlloc, fShader->isOpaque());
472aab8022a614422aa21a2b9bccb6583e77d3c2f1Mike Reed    return true;
482aab8022a614422aa21a2b9bccb6583e77d3c2f1Mike Reed}
492aab8022a614422aa21a2b9bccb6583e77d3c2f1Mike Reed
5072266eeca036b5216a9bfa0bb68cb0fbb9bbb57bMatt Sarettsk_sp<SkShader> SkColorFilterShader::onMakeColorSpace(SkColorSpaceXformer* xformer) const {
512814d9148671b8bdbf40a192dcbe485199fd3230Mike Klein    return xformer->apply(fShader.get())->makeWithColorFilter(xformer->apply(fFilter.get()));
5272266eeca036b5216a9bfa0bb68cb0fbb9bbb57bMatt Sarett}
533061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed
543061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed#if SK_SUPPORT_GPU
553061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed/////////////////////////////////////////////////////////////////////
563061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed
57aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomonstd::unique_ptr<GrFragmentProcessor> SkColorFilterShader::asFragmentProcessor(
58e3429e62b0d020b27de3daa55893953eff581c4fMike Reed        const GrFPArgs& args) const {
59aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon    auto fp1 = as_SB(fShader)->asFragmentProcessor(args);
6006ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman    if (!fp1) {
613061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed        return nullptr;
623061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed    }
633061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed
644cbb6e6d551e8bea2c040b1aa9dce253cffb9af0Brian Salomon    auto fp2 = fFilter->asFragmentProcessor(args.fContext, *args.fDstColorSpaceInfo);
6506ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman    if (!fp2) {
6606ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman        return fp1;
673061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed    }
683061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed
69aff329b8e9b239bca1d93b13a914fbef45ccf7feBrian Salomon    std::unique_ptr<GrFragmentProcessor> fpSeries[] = { std::move(fp1), std::move(fp2) };
703061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed    return GrFragmentProcessor::RunInSeries(fpSeries, 2);
713061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed}
723061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed#endif
733061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed
743061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed#ifndef SK_IGNORE_TO_STRING
753061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reedvoid SkColorFilterShader::toString(SkString* str) const {
763061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed    str->append("SkColorFilterShader: (");
773061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed
783061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed    str->append("Shader: ");
794aed13889bd9085337e0d4c20df28686687b833bFlorin Malita    as_SB(fShader)->toString(str);
803061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed    str->append(" Filter: ");
813061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed    // TODO: add "fFilter->toString(str);" once SkColorFilter::toString is added
823061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed
833061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed    this->INHERITED::toString(str);
843061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed
853061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed    str->append(")");
863061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed}
873061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed#endif
883061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed
893061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed///////////////////////////////////////////////////////////////////////////////////////////////////
903061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed
91d053ce9c54d4e5937a142278359e5a4cde18095ereedsk_sp<SkShader> SkShader::makeWithColorFilter(sk_sp<SkColorFilter> filter) const {
923061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed    SkShader* base = const_cast<SkShader*>(this);
933061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed    if (!filter) {
94150835e779ceb24e2b540f58958cbff2a0ab9942reed        return sk_ref_sp(base);
953061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed    }
96d053ce9c54d4e5937a142278359e5a4cde18095ereed    return sk_make_sp<SkColorFilterShader>(sk_ref_sp(base), filter);
973061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed}
98