1 /* 2 * Copyright 2013 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #include "SkFilterShader.h" 9 10 #include "SkColorFilter.h" 11 #include "SkReadBuffer.h" 12 #include "SkWriteBuffer.h" 13 #include "SkShader.h" 14 #include "SkString.h" 15 16 SkFilterShader::SkFilterShader(SkShader* shader, SkColorFilter* filter) { 17 fShader = shader; 18 shader->ref(); 19 20 fFilter = filter; 21 filter->ref(); 22 } 23 24 SkFilterShader::SkFilterShader(SkReadBuffer& buffer) 25 : INHERITED(buffer) { 26 fShader = buffer.readShader(); 27 fFilter = buffer.readColorFilter(); 28 } 29 30 SkFilterShader::~SkFilterShader() { 31 fFilter->unref(); 32 fShader->unref(); 33 } 34 35 void SkFilterShader::flatten(SkWriteBuffer& buffer) const { 36 this->INHERITED::flatten(buffer); 37 buffer.writeFlattenable(fShader); 38 buffer.writeFlattenable(fFilter); 39 } 40 41 uint32_t SkFilterShader::FilterShaderContext::getFlags() const { 42 const SkFilterShader& filterShader = static_cast<const SkFilterShader&>(fShader); 43 44 uint32_t shaderF = fShaderContext->getFlags(); 45 uint32_t filterF = filterShader.fFilter->getFlags(); 46 47 // if the filter doesn't support 16bit, clear the matching bit in the shader 48 if (!(filterF & SkColorFilter::kHasFilter16_Flag)) { 49 shaderF &= ~SkShader::kHasSpan16_Flag; 50 } 51 // if the filter might change alpha, clear the opaque flag in the shader 52 if (!(filterF & SkColorFilter::kAlphaUnchanged_Flag)) { 53 shaderF &= ~(SkShader::kOpaqueAlpha_Flag | SkShader::kHasSpan16_Flag); 54 } 55 return shaderF; 56 } 57 58 SkShader::Context* SkFilterShader::onCreateContext(const ContextRec& rec, void* storage) const { 59 char* shaderContextStorage = (char*)storage + sizeof(FilterShaderContext); 60 SkShader::Context* shaderContext = fShader->createContext(rec, shaderContextStorage); 61 if (NULL == shaderContext) { 62 return NULL; 63 } 64 return SkNEW_PLACEMENT_ARGS(storage, FilterShaderContext, (*this, shaderContext, rec)); 65 } 66 67 size_t SkFilterShader::contextSize() const { 68 return sizeof(FilterShaderContext) + fShader->contextSize(); 69 } 70 71 SkFilterShader::FilterShaderContext::FilterShaderContext(const SkFilterShader& filterShader, 72 SkShader::Context* shaderContext, 73 const ContextRec& rec) 74 : INHERITED(filterShader, rec) 75 , fShaderContext(shaderContext) {} 76 77 SkFilterShader::FilterShaderContext::~FilterShaderContext() { 78 fShaderContext->~Context(); 79 } 80 81 void SkFilterShader::FilterShaderContext::shadeSpan(int x, int y, SkPMColor result[], int count) { 82 const SkFilterShader& filterShader = static_cast<const SkFilterShader&>(fShader); 83 84 fShaderContext->shadeSpan(x, y, result, count); 85 filterShader.fFilter->filterSpan(result, count, result); 86 } 87 88 void SkFilterShader::FilterShaderContext::shadeSpan16(int x, int y, uint16_t result[], int count) { 89 const SkFilterShader& filterShader = static_cast<const SkFilterShader&>(fShader); 90 91 SkASSERT(fShaderContext->getFlags() & SkShader::kHasSpan16_Flag); 92 SkASSERT(filterShader.fFilter->getFlags() & SkColorFilter::kHasFilter16_Flag); 93 94 fShaderContext->shadeSpan16(x, y, result, count); 95 filterShader.fFilter->filterSpan16(result, count, result); 96 } 97 98 #ifndef SK_IGNORE_TO_STRING 99 void SkFilterShader::toString(SkString* str) const { 100 str->append("SkFilterShader: ("); 101 102 str->append("Shader: "); 103 fShader->toString(str); 104 str->append(" Filter: "); 105 // TODO: add "fFilter->toString(str);" once SkColorFilter::toString is added 106 107 this->INHERITED::toString(str); 108 109 str->append(")"); 110 } 111 #endif 112