| Index: src/core/SkColorFilterShader.cpp
|
| diff --git a/src/core/SkColorFilterShader.cpp b/src/core/SkColorFilterShader.cpp
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..dc90f95762a3398c5f2a964510e75c2803aa4491
|
| --- /dev/null
|
| +++ b/src/core/SkColorFilterShader.cpp
|
| @@ -0,0 +1,136 @@
|
| +/*
|
| + * Copyright 2013 Google Inc.
|
| + *
|
| + * Use of this source code is governed by a BSD-style license that can be
|
| + * found in the LICENSE file.
|
| + */
|
| +
|
| +#include "SkColorFilterShader.h"
|
| +#include "SkReadBuffer.h"
|
| +#include "SkWriteBuffer.h"
|
| +#include "SkShader.h"
|
| +#include "SkString.h"
|
| +
|
| +#if SK_SUPPORT_GPU
|
| +#include "GrFragmentProcessor.h"
|
| +#endif
|
| +
|
| +SkColorFilterShader::SkColorFilterShader(SkShader* shader, SkColorFilter* filter)
|
| + : fShader(SkRef(shader))
|
| + , fFilter(SkRef(filter))
|
| +{
|
| + SkASSERT(shader);
|
| + SkASSERT(filter);
|
| +}
|
| +
|
| +SkFlattenable* SkColorFilterShader::CreateProc(SkReadBuffer& buffer) {
|
| + SkAutoTUnref<SkShader> shader(buffer.readShader());
|
| + SkAutoTUnref<SkColorFilter> filter(buffer.readColorFilter());
|
| + if (!shader.get() || !filter.get()) {
|
| + return nullptr;
|
| + }
|
| + return new SkColorFilterShader(shader, filter);
|
| +}
|
| +
|
| +void SkColorFilterShader::flatten(SkWriteBuffer& buffer) const {
|
| + buffer.writeFlattenable(fShader);
|
| + buffer.writeFlattenable(fFilter);
|
| +}
|
| +
|
| +uint32_t SkColorFilterShader::FilterShaderContext::getFlags() const {
|
| + const SkColorFilterShader& filterShader = static_cast<const SkColorFilterShader&>(fShader);
|
| +
|
| + uint32_t shaderF = fShaderContext->getFlags();
|
| + uint32_t filterF = filterShader.fFilter->getFlags();
|
| +
|
| + // if the filter might change alpha, clear the opaque flag in the shader
|
| + if (!(filterF & SkColorFilter::kAlphaUnchanged_Flag)) {
|
| + shaderF &= ~SkShader::kOpaqueAlpha_Flag;
|
| + }
|
| + return shaderF;
|
| +}
|
| +
|
| +SkShader::Context* SkColorFilterShader::onCreateContext(const ContextRec& rec,
|
| + void* storage) const {
|
| + char* shaderContextStorage = (char*)storage + sizeof(FilterShaderContext);
|
| + SkShader::Context* shaderContext = fShader->createContext(rec, shaderContextStorage);
|
| + if (nullptr == shaderContext) {
|
| + return nullptr;
|
| + }
|
| + return new (storage) FilterShaderContext(*this, shaderContext, rec);
|
| +}
|
| +
|
| +size_t SkColorFilterShader::contextSize() const {
|
| + return sizeof(FilterShaderContext) + fShader->contextSize();
|
| +}
|
| +
|
| +SkColorFilterShader::FilterShaderContext::FilterShaderContext(
|
| + const SkColorFilterShader& filterShader,
|
| + SkShader::Context* shaderContext,
|
| + const ContextRec& rec)
|
| + : INHERITED(filterShader, rec)
|
| + , fShaderContext(shaderContext)
|
| +{}
|
| +
|
| +SkColorFilterShader::FilterShaderContext::~FilterShaderContext() {
|
| + fShaderContext->~Context();
|
| +}
|
| +
|
| +void SkColorFilterShader::FilterShaderContext::shadeSpan(int x, int y, SkPMColor result[],
|
| + int count) {
|
| + const SkColorFilterShader& filterShader = static_cast<const SkColorFilterShader&>(fShader);
|
| +
|
| + fShaderContext->shadeSpan(x, y, result, count);
|
| + filterShader.fFilter->filterSpan(result, count, result);
|
| +}
|
| +
|
| +#if SK_SUPPORT_GPU
|
| +/////////////////////////////////////////////////////////////////////
|
| +
|
| +const GrFragmentProcessor* SkColorFilterShader::asFragmentProcessor(
|
| + GrContext* context,
|
| + const SkMatrix& viewM,
|
| + const SkMatrix* localMatrix,
|
| + SkFilterQuality fq) const {
|
| +
|
| + SkAutoTUnref<const GrFragmentProcessor> fp1(fShader->asFragmentProcessor(context, viewM,
|
| + localMatrix, fq));
|
| + if (!fp1.get()) {
|
| + return nullptr;
|
| + }
|
| +
|
| + SkAutoTUnref<const GrFragmentProcessor> fp2(fFilter->asFragmentProcessor(context));
|
| + if (!fp2.get()) {
|
| + return fp1.release();
|
| + }
|
| +
|
| + const GrFragmentProcessor* fpSeries[] = { fp1.get(), fp2.get() };
|
| +
|
| + return GrFragmentProcessor::RunInSeries(fpSeries, 2);
|
| +}
|
| +#endif
|
| +
|
| +#ifndef SK_IGNORE_TO_STRING
|
| +void SkColorFilterShader::toString(SkString* str) const {
|
| + str->append("SkColorFilterShader: (");
|
| +
|
| + str->append("Shader: ");
|
| + fShader->toString(str);
|
| + str->append(" Filter: ");
|
| + // TODO: add "fFilter->toString(str);" once SkColorFilter::toString is added
|
| +
|
| + this->INHERITED::toString(str);
|
| +
|
| + str->append(")");
|
| +}
|
| +#endif
|
| +
|
| +///////////////////////////////////////////////////////////////////////////////////////////////////
|
| +
|
| +SkShader* SkShader::newWithColorFilter(SkColorFilter* filter) const {
|
| + SkShader* base = const_cast<SkShader*>(this);
|
| + if (!filter) {
|
| + return SkRef(base);
|
| + }
|
| + return new SkColorFilterShader(base, filter);
|
| +}
|
|
|