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 248b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.orgSkFilterShader::SkFilterShader(SkReadBuffer& buffer) 25883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org : INHERITED(buffer) { 26353482251e61971a8cf3a60bbb6910f482be634freed@google.com fShader = buffer.readShader(); 27353482251e61971a8cf3a60bbb6910f482be634freed@google.com fFilter = buffer.readColorFilter(); 28883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org} 29883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org 30883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.orgSkFilterShader::~SkFilterShader() { 31883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org fFilter->unref(); 32883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org fShader->unref(); 33883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org} 34883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org 358b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.orgvoid SkFilterShader::flatten(SkWriteBuffer& buffer) const { 36883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org this->INHERITED::flatten(buffer); 37883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org buffer.writeFlattenable(fShader); 38883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org buffer.writeFlattenable(fFilter); 39883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org} 40883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org 4187fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.orguint32_t SkFilterShader::FilterShaderContext::getFlags() const { 4287fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org const SkFilterShader& filterShader = static_cast<const SkFilterShader&>(fShader); 4387fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 4487fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org uint32_t shaderF = fShaderContext->getFlags(); 4587fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org uint32_t filterF = filterShader.fFilter->getFlags(); 46883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org 47883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org // if the filter doesn't support 16bit, clear the matching bit in the shader 48883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org if (!(filterF & SkColorFilter::kHasFilter16_Flag)) { 49883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org shaderF &= ~SkShader::kHasSpan16_Flag; 50883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org } 51883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org // if the filter might change alpha, clear the opaque flag in the shader 52883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org if (!(filterF & SkColorFilter::kAlphaUnchanged_Flag)) { 53883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org shaderF &= ~(SkShader::kOpaqueAlpha_Flag | SkShader::kHasSpan16_Flag); 54883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org } 55883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org return shaderF; 56883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org} 57883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org 58ce56d965069c1649afe14319cb239e6ad670682acommit-bot@chromium.orgSkShader::Context* SkFilterShader::onCreateContext(const ContextRec& rec, void* storage) const { 5987fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org char* shaderContextStorage = (char*)storage + sizeof(FilterShaderContext); 60e901b6de3ef8dea842008a08fc81e92fb1478d61commit-bot@chromium.org SkShader::Context* shaderContext = fShader->createContext(rec, shaderContextStorage); 61a69bda8d3c0901aaa4fa683dcd2adda5d6aa428bcommit-bot@chromium.org if (NULL == shaderContext) { 62a69bda8d3c0901aaa4fa683dcd2adda5d6aa428bcommit-bot@chromium.org return NULL; 63a69bda8d3c0901aaa4fa683dcd2adda5d6aa428bcommit-bot@chromium.org } 64e901b6de3ef8dea842008a08fc81e92fb1478d61commit-bot@chromium.org return SkNEW_PLACEMENT_ARGS(storage, FilterShaderContext, (*this, shaderContext, rec)); 6587fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org} 6687fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 6787fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.orgsize_t SkFilterShader::contextSize() const { 6887fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org return sizeof(FilterShaderContext) + fShader->contextSize(); 6987fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org} 7087fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 7187fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.orgSkFilterShader::FilterShaderContext::FilterShaderContext(const SkFilterShader& filterShader, 7287fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org SkShader::Context* shaderContext, 73e901b6de3ef8dea842008a08fc81e92fb1478d61commit-bot@chromium.org const ContextRec& rec) 74e901b6de3ef8dea842008a08fc81e92fb1478d61commit-bot@chromium.org : INHERITED(filterShader, rec) 7587fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org , fShaderContext(shaderContext) {} 7687fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 7787fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.orgSkFilterShader::FilterShaderContext::~FilterShaderContext() { 7887fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org fShaderContext->~Context(); 79883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org} 80883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org 8187fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.orgvoid SkFilterShader::FilterShaderContext::shadeSpan(int x, int y, SkPMColor result[], int count) { 8287fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org const SkFilterShader& filterShader = static_cast<const SkFilterShader&>(fShader); 8387fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 8487fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org fShaderContext->shadeSpan(x, y, result, count); 8587fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org filterShader.fFilter->filterSpan(result, count, result); 86883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org} 87883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org 8887fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.orgvoid SkFilterShader::FilterShaderContext::shadeSpan16(int x, int y, uint16_t result[], int count) { 8987fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org const SkFilterShader& filterShader = static_cast<const SkFilterShader&>(fShader); 9087fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org 9187fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org SkASSERT(fShaderContext->getFlags() & SkShader::kHasSpan16_Flag); 9287fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org SkASSERT(filterShader.fFilter->getFlags() & SkColorFilter::kHasFilter16_Flag); 93883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org 9487fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org fShaderContext->shadeSpan16(x, y, result, count); 9587fcd950198a16211b3988610beebb5ca5bcf323commit-bot@chromium.org filterShader.fFilter->filterSpan16(result, count, result); 96883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org} 97883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org 980f10f7bf1fb43ca6346dc220a076773b1f19a367commit-bot@chromium.org#ifndef SK_IGNORE_TO_STRING 99883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.orgvoid SkFilterShader::toString(SkString* str) const { 100883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org str->append("SkFilterShader: ("); 101883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org 102883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org str->append("Shader: "); 103883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org fShader->toString(str); 104883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org str->append(" Filter: "); 105883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org // TODO: add "fFilter->toString(str);" once SkColorFilter::toString is added 106883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org 107883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org this->INHERITED::toString(str); 108883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org 109883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org str->append(")"); 110883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org} 111883fe7f8b13be4ae3e3f8d8f8a6d6e94d13f9392tfarina@chromium.org#endif 112