SkColorFilterShader.cpp revision 83e939bcb79790f5ae3b28c398fbcf034675a6e5
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"
103061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed#include "SkReadBuffer.h"
113061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed#include "SkWriteBuffer.h"
123061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed#include "SkShader.h"
133061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed#include "SkString.h"
143061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed
153061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed#if SK_SUPPORT_GPU
163061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed#include "GrFragmentProcessor.h"
173061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed#endif
183061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed
19d053ce9c54d4e5937a142278359e5a4cde18095ereedSkColorFilterShader::SkColorFilterShader(sk_sp<SkShader> shader, sk_sp<SkColorFilter> filter)
20d053ce9c54d4e5937a142278359e5a4cde18095ereed    : fShader(std::move(shader))
21d053ce9c54d4e5937a142278359e5a4cde18095ereed    , fFilter(std::move(filter))
223061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed{
23d053ce9c54d4e5937a142278359e5a4cde18095ereed    SkASSERT(fShader);
24d053ce9c54d4e5937a142278359e5a4cde18095ereed    SkASSERT(fFilter);
253061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed}
263061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed
2760c9b58b3214b0154c931656e91e39b230e987d8reedsk_sp<SkFlattenable> SkColorFilterShader::CreateProc(SkReadBuffer& buffer) {
288a21c9fe7f5fef9e87115defef27bd7218419f28reed    auto shader = buffer.readShader();
29d053ce9c54d4e5937a142278359e5a4cde18095ereed    auto filter = buffer.readColorFilter();
30d053ce9c54d4e5937a142278359e5a4cde18095ereed    if (!shader || !filter) {
313061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed        return nullptr;
323061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed    }
3360c9b58b3214b0154c931656e91e39b230e987d8reed    return sk_make_sp<SkColorFilterShader>(shader, filter);
343061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed}
353061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed
363061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reedvoid SkColorFilterShader::flatten(SkWriteBuffer& buffer) const {
37d053ce9c54d4e5937a142278359e5a4cde18095ereed    buffer.writeFlattenable(fShader.get());
38d053ce9c54d4e5937a142278359e5a4cde18095ereed    buffer.writeFlattenable(fFilter.get());
393061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed}
403061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed
413061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reeduint32_t SkColorFilterShader::FilterShaderContext::getFlags() const {
423061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed    const SkColorFilterShader& filterShader = static_cast<const SkColorFilterShader&>(fShader);
433061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed
443061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed    uint32_t shaderF = fShaderContext->getFlags();
453061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed    uint32_t filterF = filterShader.fFilter->getFlags();
463061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed
473b69b82b22ba854f9a8e9f1ccb54f0d9022c0bd8reed    // If the filter does not support a given feature, but sure to clear the corresponding flag
483b69b82b22ba854f9a8e9f1ccb54f0d9022c0bd8reed    // in the shader flags.
493b69b82b22ba854f9a8e9f1ccb54f0d9022c0bd8reed    //
503061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed    if (!(filterF & SkColorFilter::kAlphaUnchanged_Flag)) {
513061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed        shaderF &= ~SkShader::kOpaqueAlpha_Flag;
523061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed    }
533061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed    return shaderF;
543061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed}
553061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed
5683e939bcb79790f5ae3b28c398fbcf034675a6e5Herb DerbySkShader::Context* SkColorFilterShader::onMakeContext(const ContextRec& rec,
5783e939bcb79790f5ae3b28c398fbcf034675a6e5Herb Derby                                                      SkArenaAlloc* alloc) const {
5883e939bcb79790f5ae3b28c398fbcf034675a6e5Herb Derby    SkShader::Context* shaderContext = fShader->makeContext(rec, alloc);
593061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed    if (nullptr == shaderContext) {
603061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed        return nullptr;
613061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed    }
6283e939bcb79790f5ae3b28c398fbcf034675a6e5Herb Derby    return alloc->make<FilterShaderContext>(*this, shaderContext, rec);
633061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed}
643061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed
653061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed
663061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reedSkColorFilterShader::FilterShaderContext::FilterShaderContext(
673061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed                                                         const SkColorFilterShader& filterShader,
683061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed                                                         SkShader::Context* shaderContext,
693061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed                                                         const ContextRec& rec)
703061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed    : INHERITED(filterShader, rec)
713061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed    , fShaderContext(shaderContext)
723061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed{}
733061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed
743061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reedvoid SkColorFilterShader::FilterShaderContext::shadeSpan(int x, int y, SkPMColor result[],
753061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed                                                         int count) {
763061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed    const SkColorFilterShader& filterShader = static_cast<const SkColorFilterShader&>(fShader);
773061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed
783061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed    fShaderContext->shadeSpan(x, y, result, count);
793061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed    filterShader.fFilter->filterSpan(result, count, result);
803061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed}
813061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed
823b69b82b22ba854f9a8e9f1ccb54f0d9022c0bd8reedvoid SkColorFilterShader::FilterShaderContext::shadeSpan4f(int x, int y, SkPM4f result[],
833b69b82b22ba854f9a8e9f1ccb54f0d9022c0bd8reed                                                          int count) {
843b69b82b22ba854f9a8e9f1ccb54f0d9022c0bd8reed    const SkColorFilterShader& filterShader = static_cast<const SkColorFilterShader&>(fShader);
853b69b82b22ba854f9a8e9f1ccb54f0d9022c0bd8reed
863b69b82b22ba854f9a8e9f1ccb54f0d9022c0bd8reed    fShaderContext->shadeSpan4f(x, y, result, count);
873b69b82b22ba854f9a8e9f1ccb54f0d9022c0bd8reed    filterShader.fFilter->filterSpan4f(result, count, result);
883b69b82b22ba854f9a8e9f1ccb54f0d9022c0bd8reed}
893b69b82b22ba854f9a8e9f1ccb54f0d9022c0bd8reed
903061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed#if SK_SUPPORT_GPU
913061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed/////////////////////////////////////////////////////////////////////
923061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed
93839345d63466a4209a0985654ec033624821fd78brianosmansk_sp<GrFragmentProcessor> SkColorFilterShader::asFragmentProcessor(const AsFPArgs& args) const {
94839345d63466a4209a0985654ec033624821fd78brianosman
95839345d63466a4209a0985654ec033624821fd78brianosman    sk_sp<GrFragmentProcessor> fp1(fShader->asFragmentProcessor(args));
9606ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman    if (!fp1) {
973061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed        return nullptr;
983061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed    }
993061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed
100618d304eb394d64779be0ecdc5eff898242faa8fBrian Osman    sk_sp<GrFragmentProcessor> fp2(fFilter->asFragmentProcessor(args.fContext,
101618d304eb394d64779be0ecdc5eff898242faa8fBrian Osman                                                                args.fDstColorSpace));
10206ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman    if (!fp2) {
10306ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman        return fp1;
1043061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed    }
1053061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed
10606ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman    sk_sp<GrFragmentProcessor> fpSeries[] = { std::move(fp1), std::move(fp2) };
1073061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed    return GrFragmentProcessor::RunInSeries(fpSeries, 2);
1083061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed}
1093061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed#endif
1103061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed
1113061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed#ifndef SK_IGNORE_TO_STRING
1123061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reedvoid SkColorFilterShader::toString(SkString* str) const {
1133061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed    str->append("SkColorFilterShader: (");
1143061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed
1153061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed    str->append("Shader: ");
1163061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed    fShader->toString(str);
1173061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed    str->append(" Filter: ");
1183061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed    // TODO: add "fFilter->toString(str);" once SkColorFilter::toString is added
1193061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed
1203061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed    this->INHERITED::toString(str);
1213061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed
1223061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed    str->append(")");
1233061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed}
1243061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed#endif
1253061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed
1263061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed///////////////////////////////////////////////////////////////////////////////////////////////////
1273061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed
128d053ce9c54d4e5937a142278359e5a4cde18095ereedsk_sp<SkShader> SkShader::makeWithColorFilter(sk_sp<SkColorFilter> filter) const {
1293061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed    SkShader* base = const_cast<SkShader*>(this);
1303061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed    if (!filter) {
131150835e779ceb24e2b540f58958cbff2a0ab9942reed        return sk_ref_sp(base);
1323061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed    }
133d053ce9c54d4e5937a142278359e5a4cde18095ereed    return sk_make_sp<SkColorFilterShader>(sk_ref_sp(base), filter);
1343061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed}
135