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