Home | History | Annotate | Download | only in core
      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