Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / skia / src / core / SkFilterShader.cpp
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 #ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
25 SkFilterShader::SkFilterShader(SkReadBuffer& buffer) : INHERITED(buffer) {
26     fShader = buffer.readShader();
27     fFilter = buffer.readColorFilter();
28 }
29 #endif
30
31 SkFilterShader::~SkFilterShader() {
32     fFilter->unref();
33     fShader->unref();
34 }
35
36 SkFlattenable* SkFilterShader::CreateProc(SkReadBuffer& buffer) {
37     SkAutoTUnref<SkShader> shader(buffer.readShader());
38     SkAutoTUnref<SkColorFilter> filter(buffer.readColorFilter());
39     if (!shader.get() || !filter.get()) {
40         return NULL;
41     }
42     return SkNEW_ARGS(SkFilterShader, (shader, filter));
43 }
44
45 void SkFilterShader::flatten(SkWriteBuffer& buffer) const {
46     buffer.writeFlattenable(fShader);
47     buffer.writeFlattenable(fFilter);
48 }
49
50 uint32_t SkFilterShader::FilterShaderContext::getFlags() const {
51     const SkFilterShader& filterShader = static_cast<const SkFilterShader&>(fShader);
52
53     uint32_t shaderF = fShaderContext->getFlags();
54     uint32_t filterF = filterShader.fFilter->getFlags();
55
56     // if the filter doesn't support 16bit, clear the matching bit in the shader
57     if (!(filterF & SkColorFilter::kHasFilter16_Flag)) {
58         shaderF &= ~SkShader::kHasSpan16_Flag;
59     }
60     // if the filter might change alpha, clear the opaque flag in the shader
61     if (!(filterF & SkColorFilter::kAlphaUnchanged_Flag)) {
62         shaderF &= ~(SkShader::kOpaqueAlpha_Flag | SkShader::kHasSpan16_Flag);
63     }
64     return shaderF;
65 }
66
67 SkShader::Context* SkFilterShader::onCreateContext(const ContextRec& rec, void* storage) const {
68     char* shaderContextStorage = (char*)storage + sizeof(FilterShaderContext);
69     SkShader::Context* shaderContext = fShader->createContext(rec, shaderContextStorage);
70     if (NULL == shaderContext) {
71         return NULL;
72     }
73     return SkNEW_PLACEMENT_ARGS(storage, FilterShaderContext, (*this, shaderContext, rec));
74 }
75
76 size_t SkFilterShader::contextSize() const {
77     return sizeof(FilterShaderContext) + fShader->contextSize();
78 }
79
80 SkFilterShader::FilterShaderContext::FilterShaderContext(const SkFilterShader& filterShader,
81                                                          SkShader::Context* shaderContext,
82                                                          const ContextRec& rec)
83     : INHERITED(filterShader, rec)
84     , fShaderContext(shaderContext) {}
85
86 SkFilterShader::FilterShaderContext::~FilterShaderContext() {
87     fShaderContext->~Context();
88 }
89
90 void SkFilterShader::FilterShaderContext::shadeSpan(int x, int y, SkPMColor result[], int count) {
91     const SkFilterShader& filterShader = static_cast<const SkFilterShader&>(fShader);
92
93     fShaderContext->shadeSpan(x, y, result, count);
94     filterShader.fFilter->filterSpan(result, count, result);
95 }
96
97 void SkFilterShader::FilterShaderContext::shadeSpan16(int x, int y, uint16_t result[], int count) {
98     const SkFilterShader& filterShader = static_cast<const SkFilterShader&>(fShader);
99
100     SkASSERT(fShaderContext->getFlags() & SkShader::kHasSpan16_Flag);
101     SkASSERT(filterShader.fFilter->getFlags() & SkColorFilter::kHasFilter16_Flag);
102
103     fShaderContext->shadeSpan16(x, y, result, count);
104     filterShader.fFilter->filterSpan16(result, count, result);
105 }
106
107 #ifndef SK_IGNORE_TO_STRING
108 void SkFilterShader::toString(SkString* str) const {
109     str->append("SkFilterShader: (");
110
111     str->append("Shader: ");
112     fShader->toString(str);
113     str->append(" Filter: ");
114     // TODO: add "fFilter->toString(str);" once SkColorFilter::toString is added
115
116     this->INHERITED::toString(str);
117
118     str->append(")");
119 }
120 #endif