1883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org/* 2883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org * Copyright 2013 Google Inc. 3883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org * 4883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org * Use of this source code is governed by a BSD-style license that can be 5883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org * found in the LICENSE file. 6883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org */ 7883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org 8883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org#include "SkFilterShader.h" 9883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org 10883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org#include "SkColorFilter.h" 118b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org#include "SkReadBuffer.h" 128b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org#include "SkWriteBuffer.h" 13883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org#include "SkShader.h" 14883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org#include "SkString.h" 15883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org 16883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.orgSkFilterShader::SkFilterShader(SkShader* shader, SkColorFilter* filter) { 17883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org fShader = shader; 18883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org shader->ref(); 19883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org 20883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org fFilter = filter; 21883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org filter->ref(); 22883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org} 23883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org 249fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING 259fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reedSkFilterShader::SkFilterShader(SkReadBuffer& buffer) : INHERITED(buffer) { 26353482251e61971a8cf3a60bbb6910f482be634freed@google.com fShader = buffer.readShader(); 27353482251e61971a8cf3a60bbb6910f482be634freed@google.com fFilter = buffer.readColorFilter(); 28883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org} 299fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed#endif 30883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org 31883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.orgSkFilterShader::~SkFilterShader() { 32883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org fFilter->unref(); 33883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org fShader->unref(); 34883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org} 35883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org 369fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reedSkFlattenable* SkFilterShader::CreateProc(SkReadBuffer& buffer) { 379fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed SkAutoTUnref<SkShader> shader(buffer.readShader()); 389fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed SkAutoTUnref<SkColorFilter> filter(buffer.readColorFilter()); 399fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed if (!shader.get() || !filter.get()) { 409fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed return NULL; 419fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed } 429fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed return SkNEW_ARGS(SkFilterShader, (shader, filter)); 439fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed} 449fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed 458b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.orgvoid SkFilterShader::flatten(SkWriteBuffer& buffer) const { 46883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org buffer.writeFlattenable(fShader); 47883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org buffer.writeFlattenable(fFilter); 48883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org} 49883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org 5087fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.orguint32_t SkFilterShader::FilterShaderContext::getFlags() const { 5187fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org const SkFilterShader& filterShader = static_cast<const SkFilterShader&>(fShader); 5287fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 5387fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org uint32_t shaderF = fShaderContext->getFlags(); 5487fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org uint32_t filterF = filterShader.fFilter->getFlags(); 55883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org 56883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org // if the filter doesn't support 16bit, clear the matching bit in the shader 57883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org if (!(filterF & SkColorFilter::kHasFilter16_Flag)) { 58883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org shaderF &= ~SkShader::kHasSpan16_Flag; 59883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org } 60883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org // if the filter might change alpha, clear the opaque flag in the shader 61883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org if (!(filterF & SkColorFilter::kAlphaUnchanged_Flag)) { 62883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org shaderF &= ~(SkShader::kOpaqueAlpha_Flag | SkShader::kHasSpan16_Flag); 63883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org } 64883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org return shaderF; 65883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org} 66883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org 67ce56d965069c1649afe14319cb239e6ad670682acommit-bot@chromium.orgSkShader::Context* SkFilterShader::onCreateContext(const ContextRec& rec, void* storage) const { 6887fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org char* shaderContextStorage = (char*)storage + sizeof(FilterShaderContext); 69e901b6de3ef8dea842008a08fc81e92fb1478d61commit-bot@chromium.org SkShader::Context* shaderContext = fShader->createContext(rec, shaderContextStorage); 70a69bda8d3c0901aaa4fa683dcd2adda5d6aa428bcommit-bot@chromium.org if (NULL == shaderContext) { 71a69bda8d3c0901aaa4fa683dcd2adda5d6aa428bcommit-bot@chromium.org return NULL; 72a69bda8d3c0901aaa4fa683dcd2adda5d6aa428bcommit-bot@chromium.org } 73e901b6de3ef8dea842008a08fc81e92fb1478d61commit-bot@chromium.org return SkNEW_PLACEMENT_ARGS(storage, FilterShaderContext, (*this, shaderContext, rec)); 7487fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org} 7587fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 7687fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.orgsize_t SkFilterShader::contextSize() const { 7787fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org return sizeof(FilterShaderContext) + fShader->contextSize(); 7887fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org} 7987fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 8087fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.orgSkFilterShader::FilterShaderContext::FilterShaderContext(const SkFilterShader& filterShader, 8187fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org SkShader::Context* shaderContext, 82e901b6de3ef8dea842008a08fc81e92fb1478d61commit-bot@chromium.org const ContextRec& rec) 83e901b6de3ef8dea842008a08fc81e92fb1478d61commit-bot@chromium.org : INHERITED(filterShader, rec) 8487fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org , fShaderContext(shaderContext) {} 8587fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 8687fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.orgSkFilterShader::FilterShaderContext::~FilterShaderContext() { 8787fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org fShaderContext->~Context(); 88883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org} 89883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org 9087fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.orgvoid SkFilterShader::FilterShaderContext::shadeSpan(int x, int y, SkPMColor result[], int count) { 9187fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org const SkFilterShader& filterShader = static_cast<const SkFilterShader&>(fShader); 9287fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 9387fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org fShaderContext->shadeSpan(x, y, result, count); 9487fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org filterShader.fFilter->filterSpan(result, count, result); 95883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org} 96883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org 9787fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.orgvoid SkFilterShader::FilterShaderContext::shadeSpan16(int x, int y, uint16_t result[], int count) { 9887fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org const SkFilterShader& filterShader = static_cast<const SkFilterShader&>(fShader); 9987fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 10087fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org SkASSERT(fShaderContext->getFlags() & SkShader::kHasSpan16_Flag); 10187fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org SkASSERT(filterShader.fFilter->getFlags() & SkColorFilter::kHasFilter16_Flag); 102883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org 10387fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org fShaderContext->shadeSpan16(x, y, result, count); 10487fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org filterShader.fFilter->filterSpan16(result, count, result); 105883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org} 106883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org 1070f10f7bf1fb43ca6346dc220a076773b1f19a367commit-bot@chromium.org#ifndef SK_IGNORE_TO_STRING 108883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.orgvoid SkFilterShader::toString(SkString* str) const { 109883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org str->append("SkFilterShader: ("); 110883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org 111883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org str->append("Shader: "); 112883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org fShader->toString(str); 113883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org str->append(" Filter: "); 114883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org // TODO: add "fFilter->toString(str);" once SkColorFilter::toString is added 115883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org 116883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org this->INHERITED::toString(str); 117883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org 118883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org str->append(")"); 119883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org} 120883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org#endif 121