blob: 5c5e8f317c020997ec4ca8b2ba7524fd275b4239 [file] [log] [blame]
tfarina@chromium.org883fe7f2013-07-16 13:05:27 +00001/*
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"
commit-bot@chromium.org8b0e8ac2014-01-30 18:58:24 +000011#include "SkReadBuffer.h"
12#include "SkWriteBuffer.h"
tfarina@chromium.org883fe7f2013-07-16 13:05:27 +000013#include "SkShader.h"
14#include "SkString.h"
15
16SkFilterShader::SkFilterShader(SkShader* shader, SkColorFilter* filter) {
17 fShader = shader;
18 shader->ref();
19
20 fFilter = filter;
21 filter->ref();
22}
23
commit-bot@chromium.org8b0e8ac2014-01-30 18:58:24 +000024SkFilterShader::SkFilterShader(SkReadBuffer& buffer)
tfarina@chromium.org883fe7f2013-07-16 13:05:27 +000025 : INHERITED(buffer) {
reed@google.com35348222013-10-16 13:05:06 +000026 fShader = buffer.readShader();
27 fFilter = buffer.readColorFilter();
tfarina@chromium.org883fe7f2013-07-16 13:05:27 +000028}
29
30SkFilterShader::~SkFilterShader() {
31 fFilter->unref();
32 fShader->unref();
33}
34
commit-bot@chromium.org8b0e8ac2014-01-30 18:58:24 +000035void SkFilterShader::flatten(SkWriteBuffer& buffer) const {
tfarina@chromium.org883fe7f2013-07-16 13:05:27 +000036 this->INHERITED::flatten(buffer);
37 buffer.writeFlattenable(fShader);
38 buffer.writeFlattenable(fFilter);
39}
40
commit-bot@chromium.orgbc2f1dc2014-04-23 09:11:58 +000041uint32_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();
tfarina@chromium.org883fe7f2013-07-16 13:05:27 +000046
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
commit-bot@chromium.orgbc2f1dc2014-04-23 09:11:58 +000058SkShader::Context* SkFilterShader::createContext(const SkBitmap& device,
59 const SkPaint& paint,
60 const SkMatrix& matrix,
61 void* storage) const {
62 if (!this->validContext(device, paint, matrix)) {
63 return NULL;
tfarina@chromium.org883fe7f2013-07-16 13:05:27 +000064 }
commit-bot@chromium.orgbc2f1dc2014-04-23 09:11:58 +000065
66 char* shaderContextStorage = (char*)storage + sizeof(FilterShaderContext);
67 SkShader::Context* shaderContext = fShader->createContext(device, paint, matrix,
68 shaderContextStorage);
69 SkASSERT(shaderContext);
70
71 return SkNEW_PLACEMENT_ARGS(storage, FilterShaderContext,
72 (*this, shaderContext, device, paint, matrix));
tfarina@chromium.org883fe7f2013-07-16 13:05:27 +000073}
74
commit-bot@chromium.orgbc2f1dc2014-04-23 09:11:58 +000075size_t SkFilterShader::contextSize() const {
76 return sizeof(FilterShaderContext) + fShader->contextSize();
tfarina@chromium.org883fe7f2013-07-16 13:05:27 +000077}
78
commit-bot@chromium.orgbc2f1dc2014-04-23 09:11:58 +000079bool SkFilterShader::validContext(const SkBitmap& device,
80 const SkPaint& paint,
81 const SkMatrix& matrix,
82 SkMatrix* totalInverse) const {
83 return this->INHERITED::validContext(device, paint, matrix, totalInverse) &&
84 fShader->validContext(device, paint, matrix);
tfarina@chromium.org883fe7f2013-07-16 13:05:27 +000085}
86
commit-bot@chromium.orgbc2f1dc2014-04-23 09:11:58 +000087SkFilterShader::FilterShaderContext::FilterShaderContext(const SkFilterShader& filterShader,
88 SkShader::Context* shaderContext,
89 const SkBitmap& device,
90 const SkPaint& paint,
91 const SkMatrix& matrix)
92 : INHERITED(filterShader, device, paint, matrix)
93 , fShaderContext(shaderContext) {}
tfarina@chromium.org883fe7f2013-07-16 13:05:27 +000094
commit-bot@chromium.orgbc2f1dc2014-04-23 09:11:58 +000095SkFilterShader::FilterShaderContext::~FilterShaderContext() {
96 fShaderContext->~Context();
97}
98
99void SkFilterShader::FilterShaderContext::shadeSpan(int x, int y, SkPMColor result[], int count) {
100 const SkFilterShader& filterShader = static_cast<const SkFilterShader&>(fShader);
101
102 fShaderContext->shadeSpan(x, y, result, count);
103 filterShader.fFilter->filterSpan(result, count, result);
104}
105
106void SkFilterShader::FilterShaderContext::shadeSpan16(int x, int y, uint16_t result[], int count) {
107 const SkFilterShader& filterShader = static_cast<const SkFilterShader&>(fShader);
108
109 SkASSERT(fShaderContext->getFlags() & SkShader::kHasSpan16_Flag);
110 SkASSERT(filterShader.fFilter->getFlags() & SkColorFilter::kHasFilter16_Flag);
111
112 fShaderContext->shadeSpan16(x, y, result, count);
113 filterShader.fFilter->filterSpan16(result, count, result);
tfarina@chromium.org883fe7f2013-07-16 13:05:27 +0000114}
115
commit-bot@chromium.org0f10f7b2014-03-13 18:02:17 +0000116#ifndef SK_IGNORE_TO_STRING
tfarina@chromium.org883fe7f2013-07-16 13:05:27 +0000117void SkFilterShader::toString(SkString* str) const {
118 str->append("SkFilterShader: (");
119
120 str->append("Shader: ");
121 fShader->toString(str);
122 str->append(" Filter: ");
123 // TODO: add "fFilter->toString(str);" once SkColorFilter::toString is added
124
125 this->INHERITED::toString(str);
126
127 str->append(")");
128}
129#endif