1845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com/* 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2006 The Android Open Source Project 3845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com * 4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 6845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com */ 78a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8c4cae85752e3e486cf4eac8cd8128f57b6f40563reed@android.com#include "SkBlitRow.h" 98a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkColorFilter.h" 108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkColorPriv.h" 118b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org#include "SkReadBuffer.h" 128b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org#include "SkWriteBuffer.h" 138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkUtils.h" 141202c2ac563cdeb07406872825706b83e335c977robertphillips@google.com#include "SkString.h" 15c0b7e10c6a68f59e1653e6c18e6bc954b3c3f0cfcommit-bot@chromium.org#include "SkValidationUtils.h" 1631b3044af4e97c662076147d119ba233a163b769reed@google.com#include "SkColorMatrixFilter.h" 1731b3044af4e97c662076147d119ba233a163b769reed@google.com 1843c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com#define ILLEGAL_XFERMODE_MODE ((SkXfermode::Mode)-1) 1943c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com 2043c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com// baseclass for filters that store a color and mode 2143c50c8c77df82c5cffb55cae2d386e59802b88freed@google.comclass SkModeColorFilter : public SkColorFilter { 2243c50c8c77df82c5cffb55cae2d386e59802b88freed@google.compublic: 2343c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com SkModeColorFilter(SkColor color) { 2443c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com fColor = color; 2543c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com fMode = ILLEGAL_XFERMODE_MODE; 268b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com this->updateCache(); 2743c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com } 2843c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com 2943c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com SkModeColorFilter(SkColor color, SkXfermode::Mode mode) { 3043c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com fColor = color; 3143c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com fMode = mode; 328b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com this->updateCache(); 3343c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com }; 341447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com 358b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com SkColor getColor() const { return fColor; } 368b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com SkXfermode::Mode getMode() const { return fMode; } 378b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com bool isModeValid() const { return ILLEGAL_XFERMODE_MODE != fMode; } 388b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com SkPMColor getPMColor() const { return fPMColor; } 39fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 40bada64428a52b4fc1f31a0a1982c2301ec57601creed@google.com virtual bool asColorMode(SkColor* color, SkXfermode::Mode* mode) const SK_OVERRIDE { 4143c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com if (ILLEGAL_XFERMODE_MODE == fMode) { 4243c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com return false; 4343c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com } 4443c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com 4543c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com if (color) { 4643c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com *color = fColor; 4743c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com } 4843c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com if (mode) { 4943c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com *mode = fMode; 5043c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com } 5143c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com return true; 5243c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com } 538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 54bada64428a52b4fc1f31a0a1982c2301ec57601creed@google.com virtual uint32_t getFlags() const SK_OVERRIDE { 558b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com return fProc16 ? (kAlphaUnchanged_Flag | kHasFilter16_Flag) : 0; 568b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com } 57fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 588b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com virtual void filterSpan(const SkPMColor shader[], int count, 59bada64428a52b4fc1f31a0a1982c2301ec57601creed@google.com SkPMColor result[]) const SK_OVERRIDE { 608b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com SkPMColor color = fPMColor; 618b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com SkXfermodeProc proc = fProc; 62fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 638b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com for (int i = 0; i < count; i++) { 648b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com result[i] = proc(color, shader[i]); 658b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com } 668b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com } 67fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 688b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com virtual void filterSpan16(const uint16_t shader[], int count, 69bada64428a52b4fc1f31a0a1982c2301ec57601creed@google.com uint16_t result[]) const SK_OVERRIDE { 708b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com SkASSERT(this->getFlags() & kHasFilter16_Flag); 71fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 728b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com SkPMColor color = fPMColor; 738b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com SkXfermodeProc16 proc16 = fProc16; 74fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 758b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com for (int i = 0; i < count; i++) { 768b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com result[i] = proc16(color, shader[i]); 778b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com } 788b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com } 79fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 800f10f7bf1fb43ca6346dc220a076773b1f19a367commit-bot@chromium.org#ifndef SK_IGNORE_TO_STRING 811202c2ac563cdeb07406872825706b83e335c977robertphillips@google.com virtual void toString(SkString* str) const SK_OVERRIDE { 821202c2ac563cdeb07406872825706b83e335c977robertphillips@google.com str->append("SkModeColorFilter: color: 0x"); 831202c2ac563cdeb07406872825706b83e335c977robertphillips@google.com str->appendHex(fColor); 841202c2ac563cdeb07406872825706b83e335c977robertphillips@google.com str->append(" mode: "); 851202c2ac563cdeb07406872825706b83e335c977robertphillips@google.com str->append(SkXfermode::ModeName(fMode)); 861202c2ac563cdeb07406872825706b83e335c977robertphillips@google.com } 871202c2ac563cdeb07406872825706b83e335c977robertphillips@google.com#endif 881202c2ac563cdeb07406872825706b83e335c977robertphillips@google.com 89a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org#if SK_SUPPORT_GPU 90a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org virtual GrEffectRef* asNewEffect(GrContext*) const SK_OVERRIDE; 91a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org#endif 928b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkModeColorFilter) 9343c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com 9443c50c8c77df82c5cffb55cae2d386e59802b88freed@google.comprotected: 958b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org virtual void flatten(SkWriteBuffer& buffer) const SK_OVERRIDE { 961447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com this->INHERITED::flatten(buffer); 97c73dd5c6880739f26216f198c757028fd28df1a4djsollen@google.com buffer.writeColor(fColor); 98c73dd5c6880739f26216f198c757028fd28df1a4djsollen@google.com buffer.writeUInt(fMode); 998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1001447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com 1018b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org SkModeColorFilter(SkReadBuffer& buffer) { 102c73dd5c6880739f26216f198c757028fd28df1a4djsollen@google.com fColor = buffer.readColor(); 103c73dd5c6880739f26216f198c757028fd28df1a4djsollen@google.com fMode = (SkXfermode::Mode)buffer.readUInt(); 104c2e9db30d393862bd3485cfe57b4ac06433f2f32commit-bot@chromium.org if (buffer.isValid()) { 105c2e9db30d393862bd3485cfe57b4ac06433f2f32commit-bot@chromium.org this->updateCache(); 106c2e9db30d393862bd3485cfe57b4ac06433f2f32commit-bot@chromium.org buffer.validate(SkIsValidMode(fMode)); 107c2e9db30d393862bd3485cfe57b4ac06433f2f32commit-bot@chromium.org } 1088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 109845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com 11043c50c8c77df82c5cffb55cae2d386e59802b88freed@google.comprivate: 11143c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com SkColor fColor; 11243c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com SkXfermode::Mode fMode; 1138b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com // cache 1148b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com SkPMColor fPMColor; 1158b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com SkXfermodeProc fProc; 1168b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com SkXfermodeProc16 fProc16; 117fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1188b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com void updateCache() { 1198b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com fPMColor = SkPreMultiplyColor(fColor); 1208b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com fProc = SkXfermode::GetProc(fMode); 1218b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com fProc16 = SkXfermode::GetProc16(fMode, fColor); 1228b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com } 123fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1241447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com typedef SkColorFilter INHERITED; 1258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 1268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 127a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org/////////////////////////////////////////////////////////////////////////////// 128a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org#if SK_SUPPORT_GPU 129a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org#include "GrBlend.h" 130a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org#include "GrEffect.h" 131a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org#include "GrEffectUnitTest.h" 132a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org#include "GrTBackendEffectFactory.h" 133a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org#include "gl/GrGLEffect.h" 134a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org#include "SkGr.h" 135a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org 136a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.orgnamespace { 137a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org/** 138a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org * A definition of blend equation for one coefficient. Generates a 139a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org * blend_coeff * value "expression". 140a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org */ 141a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.orgtemplate<typename ColorExpr> 142a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.orgstatic inline ColorExpr blend_term(SkXfermode::Coeff coeff, 143a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org const ColorExpr& src, 144a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org const ColorExpr& dst, 145a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org const ColorExpr& value) { 146a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org switch (coeff) { 147a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org default: 14888cb22b6b4816c7a9ca6c5b795965b4606f9eb7bcommit-bot@chromium.org SkFAIL("Unexpected xfer coeff."); 149a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org case SkXfermode::kZero_Coeff: /** 0 */ 150a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org return ColorExpr(0); 151a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org case SkXfermode::kOne_Coeff: /** 1 */ 152a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org return value; 153a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org case SkXfermode::kSC_Coeff: 154a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org return src * value; 155a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org case SkXfermode::kISC_Coeff: 156a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org return (ColorExpr(1) - src) * dst; 157a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org case SkXfermode::kDC_Coeff: 158a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org return dst * value; 159a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org case SkXfermode::kIDC_Coeff: 160a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org return (ColorExpr(1) - dst) * value; 161a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org case SkXfermode::kSA_Coeff: /** src alpha */ 162a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org return src.a() * value; 163a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org case SkXfermode::kISA_Coeff: /** inverse src alpha (i.e. 1 - sa) */ 164a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org return (typename ColorExpr::AExpr(1) - src.a()) * value; 165a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org case SkXfermode::kDA_Coeff: /** dst alpha */ 166a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org return dst.a() * value; 167a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org case SkXfermode::kIDA_Coeff: /** inverse dst alpha (i.e. 1 - da) */ 168a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org return (typename ColorExpr::AExpr(1) - dst.a()) * value; 169a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org } 170a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org} 171a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org/** 172a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org * Creates a color filter expression which modifies the color by 173a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org * the specified color filter. 174a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org */ 175a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.orgtemplate <typename ColorExpr> 176a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.orgstatic inline ColorExpr color_filter_expression(const SkXfermode::Mode& mode, 177a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org const ColorExpr& filterColor, 178a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org const ColorExpr& inColor) { 179a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org SkXfermode::Coeff colorCoeff; 180a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org SkXfermode::Coeff filterColorCoeff; 181a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org SkAssertResult(SkXfermode::ModeAsCoeff(mode, &filterColorCoeff, &colorCoeff)); 182a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org return blend_term(colorCoeff, filterColor, inColor, inColor) + 183a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org blend_term(filterColorCoeff, filterColor, inColor, filterColor); 184a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org} 185a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org 186a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org} 187a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org 188a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.orgclass ModeColorFilterEffect : public GrEffect { 189a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.orgpublic: 190a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org static GrEffectRef* Create(const GrColor& c, SkXfermode::Mode mode) { 191a93f4e770f22f913197bef82dc19078e12bee76bcommit-bot@chromium.org // TODO: Make the effect take the coeffs rather than mode since we already do the 192a93f4e770f22f913197bef82dc19078e12bee76bcommit-bot@chromium.org // conversion here. 193a93f4e770f22f913197bef82dc19078e12bee76bcommit-bot@chromium.org SkXfermode::Coeff srcCoeff, dstCoeff; 194a93f4e770f22f913197bef82dc19078e12bee76bcommit-bot@chromium.org if (!SkXfermode::ModeAsCoeff(mode, &srcCoeff, &dstCoeff)) { 195a93f4e770f22f913197bef82dc19078e12bee76bcommit-bot@chromium.org SkDebugf("Failing to create color filter for mode %d\n", mode); 196a93f4e770f22f913197bef82dc19078e12bee76bcommit-bot@chromium.org return NULL; 197a93f4e770f22f913197bef82dc19078e12bee76bcommit-bot@chromium.org } 198a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org AutoEffectUnref effect(SkNEW_ARGS(ModeColorFilterEffect, (c, mode))); 199a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org return CreateEffectRef(effect); 200a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org } 201a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org 202a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE; 203a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org 204a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org bool willUseFilterColor() const { 205a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org SkXfermode::Coeff dstCoeff; 206a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org SkXfermode::Coeff srcCoeff; 207a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org SkAssertResult(SkXfermode::ModeAsCoeff(fMode, &srcCoeff, &dstCoeff)); 208a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org if (SkXfermode::kZero_Coeff == srcCoeff) { 209a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org return GrBlendCoeffRefsSrc(sk_blend_to_grblend(dstCoeff)); 210a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org } 211a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org return true; 212a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org } 213a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org 214a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE { 215a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org return GrTBackendEffectFactory<ModeColorFilterEffect>::getInstance(); 216a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org } 217a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org 218a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org static const char* Name() { return "ModeColorFilterEffect"; } 219a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org 220a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org SkXfermode::Mode mode() const { return fMode; } 221a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org GrColor color() const { return fColor; } 222a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org 223a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org class GLEffect : public GrGLEffect { 224a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org public: 225a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org GLEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&) 226a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org : INHERITED(factory) { 227a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org } 228a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org 229a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org virtual void emitCode(GrGLShaderBuilder* builder, 230a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org const GrDrawEffect& drawEffect, 231a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org EffectKey key, 232a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org const char* outputColor, 233a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org const char* inputColor, 234a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org const TransformedCoordsArray& coords, 235a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org const TextureSamplerArray& samplers) SK_OVERRIDE { 236a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org SkXfermode::Mode mode = drawEffect.castEffect<ModeColorFilterEffect>().mode(); 237a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org 238a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org SkASSERT(SkXfermode::kDst_Mode != mode); 239a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org const char* colorFilterColorUniName = NULL; 240a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org if (drawEffect.castEffect<ModeColorFilterEffect>().willUseFilterColor()) { 241a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org fFilterColorUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility, 242a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org kVec4f_GrSLType, "FilterColor", 243a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org &colorFilterColorUniName); 244a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org } 245a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org 246a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org GrGLSLExpr4 filter = 247a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org color_filter_expression(mode, GrGLSLExpr4(colorFilterColorUniName), GrGLSLExpr4(inputColor)); 248a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org 249a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org builder->fsCodeAppendf("\t%s = %s;\n", outputColor, filter.c_str()); 250a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org } 251a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org 252a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) { 253a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org const ModeColorFilterEffect& colorModeFilter = drawEffect.castEffect<ModeColorFilterEffect>(); 254a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org // The SL code does not depend on filter color at the moment, so no need to represent it 255a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org // in the key. 256a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org EffectKey modeKey = colorModeFilter.mode(); 257a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org return modeKey; 258a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org } 259a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org 260a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org virtual void setData(const GrGLUniformManager& uman, const GrDrawEffect& drawEffect) SK_OVERRIDE { 261a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org if (fFilterColorUni.isValid()) { 262a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org const ModeColorFilterEffect& colorModeFilter = drawEffect.castEffect<ModeColorFilterEffect>(); 263a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org GrGLfloat c[4]; 264a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org GrColorToRGBAFloat(colorModeFilter.color(), c); 265d3baf20dd1de9940717dd50b5c9ff6061561342ecommit-bot@chromium.org uman.set4fv(fFilterColorUni, 1, c); 266a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org } 267a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org } 268a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org 269a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org private: 270a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org 271a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org GrGLUniformManager::UniformHandle fFilterColorUni; 272a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org typedef GrGLEffect INHERITED; 273a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org }; 274a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org 275a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org GR_DECLARE_EFFECT_TEST; 276a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org 277a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.orgprivate: 278a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org ModeColorFilterEffect(GrColor color, SkXfermode::Mode mode) 279a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org : fMode(mode), 280a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org fColor(color) { 281a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org 282a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org SkXfermode::Coeff dstCoeff; 283a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org SkXfermode::Coeff srcCoeff; 284a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org SkAssertResult(SkXfermode::ModeAsCoeff(fMode, &srcCoeff, &dstCoeff)); 285a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org // These could be calculated from the blend equation with template trickery.. 286a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org if (SkXfermode::kZero_Coeff == dstCoeff && !GrBlendCoeffRefsDst(sk_blend_to_grblend(srcCoeff))) { 287a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org this->setWillNotUseInputColor(); 288a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org } 289a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org } 290a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org 291a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE { 292a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org const ModeColorFilterEffect& s = CastEffect<ModeColorFilterEffect>(other); 293a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org return fMode == s.fMode && fColor == s.fColor; 294a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org } 295a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org 296a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org SkXfermode::Mode fMode; 297a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org GrColor fColor; 298a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org 299a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org typedef GrEffect INHERITED; 300a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org}; 301a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org 302a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.orgnamespace { 303a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org 304a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org/** Function color_component_to_int tries to reproduce the GLSL rounding. The spec doesn't specify 305a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org * to which direction the 0.5 goes. 306a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org */ 307a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.orgstatic inline int color_component_to_int(float value) { 308972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org return sk_float_round2int(SkTMax(0.f, SkTMin(1.f, value)) * 255.f); 309a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org} 310a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org 311a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org/** MaskedColorExpr is used to evaluate the color and valid color component flags through the 312a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org * blending equation. It has members similar to GrGLSLExpr so that it can be used with the 313a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org * templated helpers above. 314a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org */ 315a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.orgclass MaskedColorExpr { 316a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.orgpublic: 317a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org MaskedColorExpr(const float color[], uint32_t flags) 318a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org : fFlags(flags) { 319a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org fColor[0] = color[0]; 320a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org fColor[1] = color[1]; 321a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org fColor[2] = color[2]; 322a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org fColor[3] = color[3]; 323a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org } 324a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org 325a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org MaskedColorExpr(float v, uint32_t flags = kRGBA_GrColorComponentFlags) 326a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org : fFlags(flags) { 327a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org fColor[0] = v; 328a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org fColor[1] = v; 329a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org fColor[2] = v; 330a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org fColor[3] = v; 331a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org } 332a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org 333a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org MaskedColorExpr operator*(const MaskedColorExpr& other) const { 334a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org float tmp[4]; 335a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org tmp[0] = fColor[0] * other.fColor[0]; 336a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org tmp[1] = fColor[1] * other.fColor[1]; 337a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org tmp[2] = fColor[2] * other.fColor[2]; 338a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org tmp[3] = fColor[3] * other.fColor[3]; 339a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org 340a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org return MaskedColorExpr(tmp, fFlags & other.fFlags); 341a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org } 342a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org 343a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org MaskedColorExpr operator+(const MaskedColorExpr& other) const { 344a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org float tmp[4]; 345a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org tmp[0] = fColor[0] + other.fColor[0]; 346a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org tmp[1] = fColor[1] + other.fColor[1]; 347a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org tmp[2] = fColor[2] + other.fColor[2]; 348a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org tmp[3] = fColor[3] + other.fColor[3]; 349a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org 350a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org return MaskedColorExpr(tmp, fFlags & other.fFlags); 351a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org } 352a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org 353a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org MaskedColorExpr operator-(const MaskedColorExpr& other) const { 354a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org float tmp[4]; 355a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org tmp[0] = fColor[0] - other.fColor[0]; 356a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org tmp[1] = fColor[1] - other.fColor[1]; 357a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org tmp[2] = fColor[2] - other.fColor[2]; 358a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org tmp[3] = fColor[3] - other.fColor[3]; 359a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org 360a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org return MaskedColorExpr(tmp, fFlags & other.fFlags); 361a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org } 362a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org 363a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org MaskedColorExpr a() const { 364a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org uint32_t flags = (fFlags & kA_GrColorComponentFlag) ? kRGBA_GrColorComponentFlags : 0; 365a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org return MaskedColorExpr(fColor[3], flags); 366a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org } 367a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org 368a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org GrColor getColor() const { 369a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org return GrColorPackRGBA(color_component_to_int(fColor[0]), 370a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org color_component_to_int(fColor[1]), 371a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org color_component_to_int(fColor[2]), 372a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org color_component_to_int(fColor[3])); 373a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org } 374a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org 375a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org uint32_t getValidComponents() const { return fFlags; } 376a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org 377a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org typedef MaskedColorExpr AExpr; 378a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.orgprivate: 379a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org float fColor[4]; 380a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org uint32_t fFlags; 381a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org}; 382a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org 383a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org} 384a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org 385a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.orgvoid ModeColorFilterEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const { 386a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org float inputColor[4]; 387a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org GrColorToRGBAFloat(*color, inputColor); 388a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org float filterColor[4]; 389a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org GrColorToRGBAFloat(fColor, filterColor); 390a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org MaskedColorExpr result = 391a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org color_filter_expression(fMode, 392a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org MaskedColorExpr(filterColor, kRGBA_GrColorComponentFlags), 393a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org MaskedColorExpr(inputColor, *validFlags)); 394a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org 395a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org *color = result.getColor(); 396a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org *validFlags = result.getValidComponents(); 397a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org} 398a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org 399a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.orgGR_DEFINE_EFFECT_TEST(ModeColorFilterEffect); 400a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.orgGrEffectRef* ModeColorFilterEffect::TestCreate(SkRandom* rand, 401a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org GrContext*, 402a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org const GrDrawTargetCaps&, 403a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org GrTexture*[]) { 40423267ceca27aab4c29271e9ecd5ee5a87740ffb9commit-bot@chromium.org SkXfermode::Mode mode = SkXfermode::kDst_Mode; 40523267ceca27aab4c29271e9ecd5ee5a87740ffb9commit-bot@chromium.org while (SkXfermode::kDst_Mode == mode) { 40623267ceca27aab4c29271e9ecd5ee5a87740ffb9commit-bot@chromium.org mode = static_cast<SkXfermode::Mode>(rand->nextRangeU(0, SkXfermode::kLastCoeffMode)); 40723267ceca27aab4c29271e9ecd5ee5a87740ffb9commit-bot@chromium.org } 408a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org GrColor color = rand->nextU(); 40923267ceca27aab4c29271e9ecd5ee5a87740ffb9commit-bot@chromium.org return ModeColorFilterEffect::Create(color, mode); 410a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org} 411a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org 412a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.orgGrEffectRef* SkModeColorFilter::asNewEffect(GrContext*) const { 413a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org if (SkXfermode::kDst_Mode != fMode) { 414a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org return ModeColorFilterEffect::Create(SkColor2GrColor(fColor), fMode); 415a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org } 416a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org return NULL; 417a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org} 418a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org 419a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org#endif 420a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org 421a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org/////////////////////////////////////////////////////////////////////////////// 422a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org 42343c50c8c77df82c5cffb55cae2d386e59802b88freed@google.comclass Src_SkModeColorFilter : public SkModeColorFilter { 4248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 42543c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com Src_SkModeColorFilter(SkColor color) : INHERITED(color, SkXfermode::kSrc_Mode) {} 4268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4273eafe9b22141b348d9ebdba21215f02181a27d48mike@reedtribe.org virtual uint32_t getFlags() const SK_OVERRIDE { 4288b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com if (SkGetPackedA32(this->getPMColor()) == 0xFF) { 4298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return kAlphaUnchanged_Flag | kHasFilter16_Flag; 430845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com } else { 4318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return 0; 432845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com } 4338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 4348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 435845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com virtual void filterSpan(const SkPMColor shader[], int count, 4363eafe9b22141b348d9ebdba21215f02181a27d48mike@reedtribe.org SkPMColor result[]) const SK_OVERRIDE { 4378b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com sk_memset32(result, this->getPMColor(), count); 4388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 4398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 440845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com virtual void filterSpan16(const uint16_t shader[], int count, 4413eafe9b22141b348d9ebdba21215f02181a27d48mike@reedtribe.org uint16_t result[]) const SK_OVERRIDE { 4428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(this->getFlags() & kHasFilter16_Flag); 4438b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com sk_memset16(result, SkPixel32ToPixel16(this->getPMColor()), count); 4448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 4458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 446ba28d03e94dc221d6a803bf2a84a420b9159255cdjsollen@google.com SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(Src_SkModeColorFilter) 4471447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com 4488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprotected: 4498b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org Src_SkModeColorFilter(SkReadBuffer& buffer) 450845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com : INHERITED(buffer) {} 451845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com 4521447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.comprivate: 45343c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com typedef SkModeColorFilter INHERITED; 4548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 4558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 45643c50c8c77df82c5cffb55cae2d386e59802b88freed@google.comclass SrcOver_SkModeColorFilter : public SkModeColorFilter { 4578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 45843c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com SrcOver_SkModeColorFilter(SkColor color) 45943c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com : INHERITED(color, SkXfermode::kSrcOver_Mode) { 4603eafe9b22141b348d9ebdba21215f02181a27d48mike@reedtribe.org fColor32Proc = SkBlitRow::ColorProcFactory(); 46143c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com } 4628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4633eafe9b22141b348d9ebdba21215f02181a27d48mike@reedtribe.org virtual uint32_t getFlags() const SK_OVERRIDE { 4648b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com if (SkGetPackedA32(this->getPMColor()) == 0xFF) { 4658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return kAlphaUnchanged_Flag | kHasFilter16_Flag; 466845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com } else { 4678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return 0; 468845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com } 4698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 4701447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com 471845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com virtual void filterSpan(const SkPMColor shader[], int count, 4723eafe9b22141b348d9ebdba21215f02181a27d48mike@reedtribe.org SkPMColor result[]) const SK_OVERRIDE { 4738b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com fColor32Proc(result, shader, count, this->getPMColor()); 4748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 4758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 476845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com virtual void filterSpan16(const uint16_t shader[], int count, 4773eafe9b22141b348d9ebdba21215f02181a27d48mike@reedtribe.org uint16_t result[]) const SK_OVERRIDE { 4788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(this->getFlags() & kHasFilter16_Flag); 4798b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com sk_memset16(result, SkPixel32ToPixel16(this->getPMColor()), count); 4808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 4811447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com 482ba28d03e94dc221d6a803bf2a84a420b9159255cdjsollen@google.com SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SrcOver_SkModeColorFilter) 4831447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com 4848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprotected: 4858b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org SrcOver_SkModeColorFilter(SkReadBuffer& buffer) 4863eafe9b22141b348d9ebdba21215f02181a27d48mike@reedtribe.org : INHERITED(buffer) { 4873eafe9b22141b348d9ebdba21215f02181a27d48mike@reedtribe.org fColor32Proc = SkBlitRow::ColorProcFactory(); 4883eafe9b22141b348d9ebdba21215f02181a27d48mike@reedtribe.org } 4891447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com 4908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 4911447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com 49229e5054dd07c97c2195c5f64bf67aaa6b5afa204senorblanco@chromium.org SkBlitRow::ColorProc fColor32Proc; 49343c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com 49443c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com typedef SkModeColorFilter INHERITED; 4958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 4968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 49743c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com/////////////////////////////////////////////////////////////////////////////// 4988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 499845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.comSkColorFilter* SkColorFilter::CreateModeFilter(SkColor color, 500845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com SkXfermode::Mode mode) { 5018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned alpha = SkColorGetA(color); 5028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // first collaps some modes if possible 5048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 505845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com if (SkXfermode::kClear_Mode == mode) { 5068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com color = 0; 507845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com mode = SkXfermode::kSrc_Mode; 508845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com } else if (SkXfermode::kSrcOver_Mode == mode) { 509845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com if (0 == alpha) { 510845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com mode = SkXfermode::kDst_Mode; 511845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com } else if (255 == alpha) { 512845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com mode = SkXfermode::kSrc_Mode; 5138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 5148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // else just stay srcover 5158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 5168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // weed out combinations that are noops, and just return null 518845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com if (SkXfermode::kDst_Mode == mode || 519845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com (0 == alpha && (SkXfermode::kSrcOver_Mode == mode || 520845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com SkXfermode::kDstOver_Mode == mode || 521845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com SkXfermode::kDstOut_Mode == mode || 522845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com SkXfermode::kSrcATop_Mode == mode || 523845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com SkXfermode::kXor_Mode == mode || 524845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com SkXfermode::kDarken_Mode == mode)) || 525845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com (0xFF == alpha && SkXfermode::kDstIn_Mode == mode)) { 5268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return NULL; 5278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 5281447c6f7f4579942b32af6ffff1eadede40b42bctomhudson@google.com 5298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com switch (mode) { 53043c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com case SkXfermode::kSrc_Mode: 53143c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com return SkNEW_ARGS(Src_SkModeColorFilter, (color)); 53243c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com case SkXfermode::kSrcOver_Mode: 53343c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com return SkNEW_ARGS(SrcOver_SkModeColorFilter, (color)); 53443c50c8c77df82c5cffb55cae2d386e59802b88freed@google.com default: 5358b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com return SkNEW_ARGS(SkModeColorFilter, (color, mode)); 5368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 5378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 539845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.com/////////////////////////////////////////////////////////////////////////////// 5408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 54131b3044af4e97c662076147d119ba233a163b769reed@google.comstatic SkScalar byte_to_scale(U8CPU byte) { 54231b3044af4e97c662076147d119ba233a163b769reed@google.com if (0xFF == byte) { 54331b3044af4e97c662076147d119ba233a163b769reed@google.com // want to get this exact 54431b3044af4e97c662076147d119ba233a163b769reed@google.com return 1; 54531b3044af4e97c662076147d119ba233a163b769reed@google.com } else { 54631b3044af4e97c662076147d119ba233a163b769reed@google.com return byte * 0.00392156862745f; 54731b3044af4e97c662076147d119ba233a163b769reed@google.com } 54831b3044af4e97c662076147d119ba233a163b769reed@google.com} 54931b3044af4e97c662076147d119ba233a163b769reed@google.com 550845fdaca174f4675e9acc164b510e3a5ffa9053creed@android.comSkColorFilter* SkColorFilter::CreateLightingFilter(SkColor mul, SkColor add) { 55131b3044af4e97c662076147d119ba233a163b769reed@google.com SkColorMatrix matrix; 55231b3044af4e97c662076147d119ba233a163b769reed@google.com matrix.setScale(byte_to_scale(SkColorGetR(mul)), 55331b3044af4e97c662076147d119ba233a163b769reed@google.com byte_to_scale(SkColorGetG(mul)), 55431b3044af4e97c662076147d119ba233a163b769reed@google.com byte_to_scale(SkColorGetB(mul)), 55531b3044af4e97c662076147d119ba233a163b769reed@google.com 1); 55631b3044af4e97c662076147d119ba233a163b769reed@google.com matrix.postTranslate(SkIntToScalar(SkColorGetR(add)), 55731b3044af4e97c662076147d119ba233a163b769reed@google.com SkIntToScalar(SkColorGetG(add)), 55831b3044af4e97c662076147d119ba233a163b769reed@google.com SkIntToScalar(SkColorGetB(add)), 55931b3044af4e97c662076147d119ba233a163b769reed@google.com 0); 560727a352f7412753d2a3e4d30eab6500a1a4de135commit-bot@chromium.org return SkColorMatrixFilter::Create(matrix); 5618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 563d26147adbbdca85f07dff432025afee0c8614387caryclark@google.comSK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkColorFilter) 5648b0d0f6a9c01f45cd5bacf7aea2a32306fb16684reed@google.com SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkModeColorFilter) 565d26147adbbdca85f07dff432025afee0c8614387caryclark@google.com SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(Src_SkModeColorFilter) 566d26147adbbdca85f07dff432025afee0c8614387caryclark@google.com SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SrcOver_SkModeColorFilter) 567d26147adbbdca85f07dff432025afee0c8614387caryclark@google.comSK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END 568