blob: 7e04f761b230fc745e293db46a5b8b002d88c756 [file] [log] [blame]
* Copyright 2011 Google Inc.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
#include "SkColorMatrixFilter.h"
#include "SkColorSpace.h"
#include "SkColorSpaceXformer.h"
#include "GrFragmentProcessor.h"
static SkScalar byte_to_scale(U8CPU byte) {
if (0xFF == byte) {
// want to get this exact
return 1;
} else {
return byte * 0.00392156862745f;
// If we can't reduce to a mode filter in MakeLightingFilter(), this is the general case.
// We operate as a matrix color filter, but remember our input colors in case we're asked
// to onMakeColorSpace() a new filter.
class SkLightingColorFilter : public SkColorFilter {
SkLightingColorFilter(SkColor mul, SkColor add) : fMul(mul), fAdd(add) {
SkColorMatrix matrix;
fMatrixFilter = SkColorFilter::MakeMatrixFilterRowMajor255(matrix.fMat);
// Overriding this method is the class' raison d'etre.
sk_sp<SkColorFilter> onMakeColorSpace(SkColorSpaceXformer* xformer) const override {
SkColor add = xformer->apply(fAdd);
if (add != fAdd) {
return sk_make_sp<SkLightingColorFilter>(fMul, add);
return this->INHERITED::onMakeColorSpace(xformer);
// Let fMatrixFilter handle all the other calls directly.
uint32_t getFlags() const override {
return fMatrixFilter->getFlags();
bool asColorMatrix(SkScalar matrix[20]) const override {
return fMatrixFilter->asColorMatrix(matrix);
void onAppendStages(SkRasterPipeline* p, SkColorSpace* cs, SkArenaAlloc* alloc,
bool shaderIsOpaque) const override {
fMatrixFilter->appendStages(p, cs, alloc, shaderIsOpaque);
// TODO: might want to remember we're a lighting color filter through serialization?
void flatten(SkWriteBuffer& buf) const override { return fMatrixFilter->flatten(buf); }
std::unique_ptr<GrFragmentProcessor> asFragmentProcessor(
GrContext* ctx, const GrColorSpaceInfo& csi) const override {
return fMatrixFilter->asFragmentProcessor(ctx, csi);
Factory getFactory() const override { return fMatrixFilter->getFactory(); }
const char* getTypeName() const override { return fMatrixFilter->getTypeName(); }
SkColor fMul, fAdd;
sk_sp<SkColorFilter> fMatrixFilter;
typedef SkColorFilter INHERITED;
sk_sp<SkColorFilter> SkColorMatrixFilter::MakeLightingFilter(SkColor mul, SkColor add) {
const SkColor opaqueAlphaMask = SK_ColorBLACK;
// omit the alpha and compare only the RGB values
if (0 == (add & ~opaqueAlphaMask)) {
return SkColorFilter::MakeModeFilter(mul | opaqueAlphaMask, SkBlendMode::kModulate);
return sk_make_sp<SkLightingColorFilter>(mul, add);