SkColorFilterShader.cpp revision 06ca8ec87cf6fab57cadd043a5ac18c4154a4129
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 83061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed#include "SkColorFilterShader.h" 93061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed#include "SkReadBuffer.h" 103061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed#include "SkWriteBuffer.h" 113061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed#include "SkShader.h" 123061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed#include "SkString.h" 133061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed 143061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed#if SK_SUPPORT_GPU 153061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed#include "GrFragmentProcessor.h" 163061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed#endif 173061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed 18d053ce9c54d4e5937a142278359e5a4cde18095ereedSkColorFilterShader::SkColorFilterShader(sk_sp<SkShader> shader, sk_sp<SkColorFilter> filter) 19d053ce9c54d4e5937a142278359e5a4cde18095ereed : fShader(std::move(shader)) 20d053ce9c54d4e5937a142278359e5a4cde18095ereed , fFilter(std::move(filter)) 213061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed{ 22d053ce9c54d4e5937a142278359e5a4cde18095ereed SkASSERT(fShader); 23d053ce9c54d4e5937a142278359e5a4cde18095ereed SkASSERT(fFilter); 243061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed} 253061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed 2660c9b58b3214b0154c931656e91e39b230e987d8reedsk_sp<SkFlattenable> SkColorFilterShader::CreateProc(SkReadBuffer& buffer) { 278a21c9fe7f5fef9e87115defef27bd7218419f28reed auto shader = buffer.readShader(); 28d053ce9c54d4e5937a142278359e5a4cde18095ereed auto filter = buffer.readColorFilter(); 29d053ce9c54d4e5937a142278359e5a4cde18095ereed if (!shader || !filter) { 303061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed return nullptr; 313061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed } 3260c9b58b3214b0154c931656e91e39b230e987d8reed return sk_make_sp<SkColorFilterShader>(shader, filter); 333061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed} 343061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed 353061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reedvoid SkColorFilterShader::flatten(SkWriteBuffer& buffer) const { 36d053ce9c54d4e5937a142278359e5a4cde18095ereed buffer.writeFlattenable(fShader.get()); 37d053ce9c54d4e5937a142278359e5a4cde18095ereed buffer.writeFlattenable(fFilter.get()); 383061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed} 393061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed 403061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reeduint32_t SkColorFilterShader::FilterShaderContext::getFlags() const { 413061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed const SkColorFilterShader& filterShader = static_cast<const SkColorFilterShader&>(fShader); 423061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed 433061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed uint32_t shaderF = fShaderContext->getFlags(); 443061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed uint32_t filterF = filterShader.fFilter->getFlags(); 453061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed 463b69b82b22ba854f9a8e9f1ccb54f0d9022c0bd8reed // If the filter does not support a given feature, but sure to clear the corresponding flag 473b69b82b22ba854f9a8e9f1ccb54f0d9022c0bd8reed // in the shader flags. 483b69b82b22ba854f9a8e9f1ccb54f0d9022c0bd8reed // 493061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed if (!(filterF & SkColorFilter::kAlphaUnchanged_Flag)) { 503061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed shaderF &= ~SkShader::kOpaqueAlpha_Flag; 513061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed } 523061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed return shaderF; 533061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed} 543061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed 553061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reedSkShader::Context* SkColorFilterShader::onCreateContext(const ContextRec& rec, 563061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed void* storage) const { 573061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed char* shaderContextStorage = (char*)storage + sizeof(FilterShaderContext); 583061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed SkShader::Context* shaderContext = fShader->createContext(rec, shaderContextStorage); 593061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed if (nullptr == shaderContext) { 603061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed return nullptr; 613061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed } 623061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed return new (storage) FilterShaderContext(*this, shaderContext, rec); 633061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed} 643061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed 65773ceda51ca120b686ba2d1aff1b6d5173143be0reedsize_t SkColorFilterShader::onContextSize(const ContextRec& rec) const { 66a0cee5f30e9254187a6bb943e6b8a9296214c353reed return sizeof(FilterShaderContext) + fShader->contextSize(rec); 673061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed} 683061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed 693061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reedSkColorFilterShader::FilterShaderContext::FilterShaderContext( 703061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed const SkColorFilterShader& filterShader, 713061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed SkShader::Context* shaderContext, 723061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed const ContextRec& rec) 733061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed : INHERITED(filterShader, rec) 743061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed , fShaderContext(shaderContext) 753061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed{} 763061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed 773061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reedSkColorFilterShader::FilterShaderContext::~FilterShaderContext() { 783061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed fShaderContext->~Context(); 793061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed} 803061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed 813061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reedvoid SkColorFilterShader::FilterShaderContext::shadeSpan(int x, int y, SkPMColor result[], 823061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed int count) { 833061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed const SkColorFilterShader& filterShader = static_cast<const SkColorFilterShader&>(fShader); 843061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed 853061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed fShaderContext->shadeSpan(x, y, result, count); 863061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed filterShader.fFilter->filterSpan(result, count, result); 873061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed} 883061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed 893b69b82b22ba854f9a8e9f1ccb54f0d9022c0bd8reedvoid SkColorFilterShader::FilterShaderContext::shadeSpan4f(int x, int y, SkPM4f result[], 903b69b82b22ba854f9a8e9f1ccb54f0d9022c0bd8reed int count) { 913b69b82b22ba854f9a8e9f1ccb54f0d9022c0bd8reed const SkColorFilterShader& filterShader = static_cast<const SkColorFilterShader&>(fShader); 923b69b82b22ba854f9a8e9f1ccb54f0d9022c0bd8reed 933b69b82b22ba854f9a8e9f1ccb54f0d9022c0bd8reed fShaderContext->shadeSpan4f(x, y, result, count); 943b69b82b22ba854f9a8e9f1ccb54f0d9022c0bd8reed filterShader.fFilter->filterSpan4f(result, count, result); 953b69b82b22ba854f9a8e9f1ccb54f0d9022c0bd8reed} 963b69b82b22ba854f9a8e9f1ccb54f0d9022c0bd8reed 973061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed#if SK_SUPPORT_GPU 983061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed///////////////////////////////////////////////////////////////////// 993061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed 10006ca8ec87cf6fab57cadd043a5ac18c4154a4129bungemansk_sp<GrFragmentProcessor> SkColorFilterShader::asFragmentProcessor( 101982eb7f377a0c771345276558072deb2fcea0d3ebrianosman GrContext* context, 102982eb7f377a0c771345276558072deb2fcea0d3ebrianosman const SkMatrix& viewM, 103982eb7f377a0c771345276558072deb2fcea0d3ebrianosman const SkMatrix* localMatrix, 104982eb7f377a0c771345276558072deb2fcea0d3ebrianosman SkFilterQuality fq, 105982eb7f377a0c771345276558072deb2fcea0d3ebrianosman SkSourceGammaTreatment gammaTreatment) const { 1063061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed 10706ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman sk_sp<GrFragmentProcessor> fp1(fShader->asFragmentProcessor(context, viewM, localMatrix, fq, 10806ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman gammaTreatment)); 10906ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman if (!fp1) { 1103061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed return nullptr; 1113061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed } 1123061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed 11306ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman sk_sp<GrFragmentProcessor> fp2(fFilter->asFragmentProcessor(context)); 11406ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman if (!fp2) { 11506ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman return fp1; 1163061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed } 1173061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed 11806ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman sk_sp<GrFragmentProcessor> fpSeries[] = { std::move(fp1), std::move(fp2) }; 1193061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed return GrFragmentProcessor::RunInSeries(fpSeries, 2); 1203061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed} 1213061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed#endif 1223061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed 1233061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed#ifndef SK_IGNORE_TO_STRING 1243061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reedvoid SkColorFilterShader::toString(SkString* str) const { 1253061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed str->append("SkColorFilterShader: ("); 1263061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed 1273061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed str->append("Shader: "); 1283061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed fShader->toString(str); 1293061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed str->append(" Filter: "); 1303061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed // TODO: add "fFilter->toString(str);" once SkColorFilter::toString is added 1313061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed 1323061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed this->INHERITED::toString(str); 1333061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed 1343061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed str->append(")"); 1353061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed} 1363061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed#endif 1373061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed 1383061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed/////////////////////////////////////////////////////////////////////////////////////////////////// 1393061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed 140d053ce9c54d4e5937a142278359e5a4cde18095ereedsk_sp<SkShader> SkShader::makeWithColorFilter(sk_sp<SkColorFilter> filter) const { 1413061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed SkShader* base = const_cast<SkShader*>(this); 1423061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed if (!filter) { 143150835e779ceb24e2b540f58958cbff2a0ab9942reed return sk_ref_sp(base); 1443061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed } 145d053ce9c54d4e5937a142278359e5a4cde18095ereed return sk_make_sp<SkColorFilterShader>(sk_ref_sp(base), filter); 1463061af4a5f2b8ef00fc4a34b04cf99dfb780f1a1reed} 147