Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(157)

Side by Side Diff: src/core/SkXfermode.cpp

Issue 16125008: Implement SkXfermode image filter (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Add new case to xfermodeimagefilter GM; revert changes to arithmode GM Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « include/effects/SkXfermodeImageFilter.h ('k') | src/effects/SkArithmeticMode.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 1
2 /* 2 /*
3 * Copyright 2006 The Android Open Source Project 3 * Copyright 2006 The Android Open Source Project
4 * 4 *
5 * Use of this source code is governed by a BSD-style license that can be 5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file. 6 * found in the LICENSE file.
7 */ 7 */
8 8
9 9
10 #include "SkXfermode.h" 10 #include "SkXfermode.h"
(...skipping 662 matching lines...) Expand 10 before | Expand all | Expand 10 after
673 /////////////////////////////////////////////////////////////////////////////// 673 ///////////////////////////////////////////////////////////////////////////////
674 674
675 bool SkXfermode::asCoeff(Coeff* src, Coeff* dst) const { 675 bool SkXfermode::asCoeff(Coeff* src, Coeff* dst) const {
676 return false; 676 return false;
677 } 677 }
678 678
679 bool SkXfermode::asMode(Mode* mode) const { 679 bool SkXfermode::asMode(Mode* mode) const {
680 return false; 680 return false;
681 } 681 }
682 682
683 bool SkXfermode::asNewEffectOrCoeff(GrContext*, GrEffectRef**, Coeff* src, Coeff * dst) const { 683 bool SkXfermode::asNewEffectOrCoeff(GrContext*, GrEffectRef**, Coeff* src, Coeff * dst, GrTexture*) const {
684 return this->asCoeff(src, dst); 684 return this->asCoeff(src, dst);
685 } 685 }
686 686
687 bool SkXfermode::AsNewEffectOrCoeff(SkXfermode* xfermode, 687 bool SkXfermode::AsNewEffectOrCoeff(SkXfermode* xfermode,
688 GrContext* context, 688 GrContext* context,
689 GrEffectRef** effect, 689 GrEffectRef** effect,
690 Coeff* src, 690 Coeff* src,
691 Coeff* dst) { 691 Coeff* dst,
692 GrTexture* background) {
692 if (NULL == xfermode) { 693 if (NULL == xfermode) {
693 return ModeAsCoeff(kSrcOver_Mode, src, dst); 694 return ModeAsCoeff(kSrcOver_Mode, src, dst);
694 } else { 695 } else {
695 return xfermode->asNewEffectOrCoeff(context, effect, src, dst); 696 return xfermode->asNewEffectOrCoeff(context, effect, src, dst, backgroun d);
696 } 697 }
697 } 698 }
698 699
699 SkPMColor SkXfermode::xferColor(SkPMColor src, SkPMColor dst) const{ 700 SkPMColor SkXfermode::xferColor(SkPMColor src, SkPMColor dst) const{
700 // no-op. subclasses should override this 701 // no-op. subclasses should override this
701 return dst; 702 return dst;
702 } 703 }
703 704
704 void SkXfermode::xfer32(SkPMColor* SK_RESTRICT dst, 705 void SkXfermode::xfer32(SkPMColor* SK_RESTRICT dst,
705 const SkPMColor* SK_RESTRICT src, int count, 706 const SkPMColor* SK_RESTRICT src, int count,
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after
941 #endif 942 #endif
942 943
943 ////////////////////////////////////////////////////////////////////////////// 944 //////////////////////////////////////////////////////////////////////////////
944 945
945 #if SK_SUPPORT_GPU 946 #if SK_SUPPORT_GPU
946 947
947 #include "GrEffect.h" 948 #include "GrEffect.h"
948 #include "GrEffectUnitTest.h" 949 #include "GrEffectUnitTest.h"
949 #include "GrTBackendEffectFactory.h" 950 #include "GrTBackendEffectFactory.h"
950 #include "gl/GrGLEffect.h" 951 #include "gl/GrGLEffect.h"
952 #include "gl/GrGLEffectMatrix.h"
951 953
952 /** 954 /**
953 * GrEffect that implements the all the separable xfer modes that cannot be expr essed as Coeffs. 955 * GrEffect that implements the all the separable xfer modes that cannot be expr essed as Coeffs.
954 */ 956 */
955 class XferEffect : public GrEffect { 957 class XferEffect : public GrEffect {
956 public: 958 public:
957 static bool IsSupportedMode(SkXfermode::Mode mode) { 959 static bool IsSupportedMode(SkXfermode::Mode mode) {
958 return mode > SkXfermode::kLastCoeffMode && mode <= SkXfermode::kLastMod e; 960 return mode > SkXfermode::kLastCoeffMode && mode <= SkXfermode::kLastMod e;
959 } 961 }
960 962
961 static GrEffectRef* Create(SkXfermode::Mode mode) { 963 static GrEffectRef* Create(SkXfermode::Mode mode, GrTexture* background) {
962 if (!IsSupportedMode(mode)) { 964 if (!IsSupportedMode(mode)) {
963 return NULL; 965 return NULL;
964 } else { 966 } else {
965 AutoEffectUnref effect(SkNEW_ARGS(XferEffect, (mode))); 967 AutoEffectUnref effect(SkNEW_ARGS(XferEffect, (mode, background)));
966 return CreateEffectRef(effect); 968 return CreateEffectRef(effect);
967 } 969 }
968 } 970 }
969 971
970 virtual void getConstantColorComponents(GrColor* color, 972 virtual void getConstantColorComponents(GrColor* color,
971 uint32_t* validFlags) const SK_OVERR IDE { 973 uint32_t* validFlags) const SK_OVERR IDE {
972 *validFlags = 0; 974 *validFlags = 0;
973 } 975 }
974 976
975 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE { 977 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE {
976 return GrTBackendEffectFactory<XferEffect>::getInstance(); 978 return GrTBackendEffectFactory<XferEffect>::getInstance();
977 } 979 }
978 980
979 static const char* Name() { return "XferEffect"; } 981 static const char* Name() { return "XferEffect"; }
980 982
981 SkXfermode::Mode mode() const { return fMode; } 983 SkXfermode::Mode mode() const { return fMode; }
984 const GrTextureAccess& backgroundAccess() const { return fBackgroundAccess; }
982 985
983 class GLEffect : public GrGLEffect { 986 class GLEffect : public GrGLEffect {
984 public: 987 public:
985 GLEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&) 988 GLEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&)
986 : GrGLEffect(factory ) { 989 : GrGLEffect(factory )
990 , fBackgroundEffectMatrix(kCoordsType) {
987 } 991 }
988 virtual void emitCode(GrGLShaderBuilder* builder, 992 virtual void emitCode(GrGLShaderBuilder* builder,
989 const GrDrawEffect& drawEffect, 993 const GrDrawEffect& drawEffect,
990 EffectKey key, 994 EffectKey key,
991 const char* outputColor, 995 const char* outputColor,
992 const char* inputColor, 996 const char* inputColor,
993 const TextureSamplerArray& samplers) SK_OVERRIDE { 997 const TextureSamplerArray& samplers) SK_OVERRIDE {
994 const char* dstColor = builder->dstColor(); 998 SkXfermode::Mode mode = drawEffect.castEffect<XferEffect>().mode();
999 const GrTexture* backgroundTex = drawEffect.castEffect<XferEffect>() .backgroundAccess().getTexture();
1000 const char* dstColor;
1001 if (backgroundTex) {
1002 const char* bgCoords;
1003 GrSLType bgCoordsType = fBackgroundEffectMatrix.emitCode(builder , key, &bgCoords, NULL, "BG");
1004 dstColor = "bgColor";
1005 builder->fsCodeAppendf("\t\tvec4 %s = ", dstColor);
1006 builder->appendTextureLookup(GrGLShaderBuilder::kFragment_Shader Type,
1007 samplers[0],
1008 bgCoords,
1009 bgCoordsType);
1010 builder->fsCodeAppendf(";\n");
1011 } else {
1012 dstColor = builder->dstColor();
1013 }
995 GrAssert(NULL != dstColor); 1014 GrAssert(NULL != dstColor);
996 1015
997 // We don't try to optimize for this case at all 1016 // We don't try to optimize for this case at all
998 if (NULL == inputColor) { 1017 if (NULL == inputColor) {
999 builder->fsCodeAppendf("\t\tconst vec4 ones = %s;\n", GrGLSLOnes Vecf(4)); 1018 builder->fsCodeAppendf("\t\tconst vec4 ones = %s;\n", GrGLSLOnes Vecf(4));
1000 inputColor = "ones"; 1019 inputColor = "ones";
1001 } 1020 }
1002
1003 SkXfermode::Mode mode = drawEffect.castEffect<XferEffect>().mode();
1004 builder->fsCodeAppendf("\t\t// SkXfermode::Mode: %s\n", SkXfermode:: ModeName(mode)); 1021 builder->fsCodeAppendf("\t\t// SkXfermode::Mode: %s\n", SkXfermode:: ModeName(mode));
1005 1022
1006 // These all perform src-over on the alpha channel. 1023 // These all perform src-over on the alpha channel.
1007 builder->fsCodeAppendf("\t\t%s.a = %s.a + (1.0 - %s.a) * %s.a;\n", 1024 builder->fsCodeAppendf("\t\t%s.a = %s.a + (1.0 - %s.a) * %s.a;\n",
1008 outputColor, inputColor, inputColor, dstColo r); 1025 outputColor, inputColor, inputColor, dstColo r);
1009 1026
1010 switch (mode) { 1027 switch (mode) {
1011 case SkXfermode::kOverlay_Mode: 1028 case SkXfermode::kOverlay_Mode:
1012 // Overlay is Hard-Light with the src and dst reversed 1029 // Overlay is Hard-Light with the src and dst reversed
1013 HardLight(builder, outputColor, dstColor, inputColor); 1030 HardLight(builder, outputColor, dstColor, inputColor);
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
1118 outputColor, inputColor, dstColor, ds tColor, inputColor); 1135 outputColor, inputColor, dstColor, ds tColor, inputColor);
1119 break; 1136 break;
1120 } 1137 }
1121 default: 1138 default:
1122 GrCrash("Unknown XferEffect mode."); 1139 GrCrash("Unknown XferEffect mode.");
1123 break; 1140 break;
1124 } 1141 }
1125 } 1142 }
1126 1143
1127 static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrG LCaps&) { 1144 static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrG LCaps&) {
1128 return drawEffect.castEffect<XferEffect>().mode(); 1145 const XferEffect& xfer = drawEffect.castEffect<XferEffect>();
1146 GrTexture* bgTex = xfer.backgroundAccess().getTexture();
1147 EffectKey bgKey = 0;
1148 if (bgTex) {
1149 bgKey = GrGLEffectMatrix::GenKey(GrEffect::MakeDivByTextureWHMat rix(bgTex),
1150 drawEffect,
1151 GLEffect::kCoordsType,
1152 bgTex);
1153 }
1154 EffectKey modeKey = xfer.mode() << GrGLEffectMatrix::kKeyBits;
1155 return modeKey | bgKey;
1129 } 1156 }
1130 1157
1131 virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_ OVERRIDE {} 1158 virtual void setData(const GrGLUniformManager& uman, const GrDrawEffect& drawEffect) SK_OVERRIDE {
1159 const XferEffect& xfer = drawEffect.castEffect<XferEffect>();
1160 GrTexture* bgTex = xfer.backgroundAccess().getTexture();
1161 if (bgTex) {
1162 fBackgroundEffectMatrix.setData(uman,
1163 GrEffect::MakeDivByTextureWHMatr ix(bgTex),
1164 drawEffect,
1165 bgTex);
1166 }
1167 }
1132 1168
1133 private: 1169 private:
1134 static void HardLight(GrGLShaderBuilder* builder, 1170 static void HardLight(GrGLShaderBuilder* builder,
1135 const char* final, 1171 const char* final,
1136 const char* src, 1172 const char* src,
1137 const char* dst) { 1173 const char* dst) {
1138 static const char kComponents[] = {'r', 'g', 'b'}; 1174 static const char kComponents[] = {'r', 'g', 'b'};
1139 for (size_t i = 0; i < SK_ARRAY_COUNT(kComponents); ++i) { 1175 for (size_t i = 0; i < SK_ARRAY_COUNT(kComponents); ++i) {
1140 char component = kComponents[i]; 1176 char component = kComponents[i];
1141 builder->fsCodeAppendf("\t\tif (2.0 * %s.%c <= %s.a) {\n", src, component, src); 1177 builder->fsCodeAppendf("\t\tif (2.0 * %s.%c <= %s.a) {\n", src, component, src);
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
1345 helpFunc, helpFunc); 1381 helpFunc, helpFunc);
1346 builder->emitFunction(GrGLShaderBuilder::kFragment_ShaderType, 1382 builder->emitFunction(GrGLShaderBuilder::kFragment_ShaderType,
1347 kVec3f_GrSLType, 1383 kVec3f_GrSLType,
1348 "set_saturation", 1384 "set_saturation",
1349 SK_ARRAY_COUNT(setSatArgs), setSatArgs, 1385 SK_ARRAY_COUNT(setSatArgs), setSatArgs,
1350 setSatBody.c_str(), 1386 setSatBody.c_str(),
1351 setSatFunction); 1387 setSatFunction);
1352 1388
1353 } 1389 }
1354 1390
1391 static const GrEffect::CoordsType kCoordsType = GrEffect::kLocal_CoordsT ype;
1392 GrGLEffectMatrix fBackgroundEffectMatrix;
1355 typedef GrGLEffect INHERITED; 1393 typedef GrGLEffect INHERITED;
1356 }; 1394 };
1357 1395
1358 GR_DECLARE_EFFECT_TEST; 1396 GR_DECLARE_EFFECT_TEST;
1359 1397
1360 private: 1398 private:
1361 XferEffect(SkXfermode::Mode mode) : fMode(mode) { this->setWillReadDstColor( ); } 1399 XferEffect(SkXfermode::Mode mode, GrTexture* background)
1362 virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE { return tru e; } 1400 : fMode(mode) {
1401 if (background) {
1402 fBackgroundAccess.reset(background);
1403 this->addTextureAccess(&fBackgroundAccess);
1404 } else {
1405 this->setWillReadDstColor();
1406 }
1407 }
1408 virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE {
1409 const XferEffect& s = CastEffect<XferEffect>(other);
1410 return fMode == s.fMode &&
1411 fBackgroundAccess.getTexture() == s.fBackgroundAccess.getTexture( );
1412 }
1363 1413
1364 SkXfermode::Mode fMode; 1414 SkXfermode::Mode fMode;
1415 GrTextureAccess fBackgroundAccess;
1365 1416
1366 typedef GrEffect INHERITED; 1417 typedef GrEffect INHERITED;
1367 }; 1418 };
1368 1419
1369 GR_DEFINE_EFFECT_TEST(XferEffect); 1420 GR_DEFINE_EFFECT_TEST(XferEffect);
1370 GrEffectRef* XferEffect::TestCreate(SkMWCRandom* rand, 1421 GrEffectRef* XferEffect::TestCreate(SkMWCRandom* rand,
1371 GrContext*, 1422 GrContext*,
1372 const GrDrawTargetCaps&, 1423 const GrDrawTargetCaps&,
1373 GrTexture*[]) { 1424 GrTexture*[]) {
1374 int mode = rand->nextRangeU(SkXfermode::kLastCoeffMode + 1, SkXfermode::kLas tSeparableMode); 1425 int mode = rand->nextRangeU(SkXfermode::kLastCoeffMode + 1, SkXfermode::kLas tSeparableMode);
1375 1426
1376 static AutoEffectUnref gEffect(SkNEW_ARGS(XferEffect, (static_cast<SkXfermod e::Mode>(mode)))); 1427 static AutoEffectUnref gEffect(SkNEW_ARGS(XferEffect, (static_cast<SkXfermod e::Mode>(mode), NULL)));
1377 return CreateEffectRef(gEffect); 1428 return CreateEffectRef(gEffect);
1378 } 1429 }
1379 1430
1380 #endif 1431 #endif
1381 1432
1382 /////////////////////////////////////////////////////////////////////////////// 1433 ///////////////////////////////////////////////////////////////////////////////
1383 /////////////////////////////////////////////////////////////////////////////// 1434 ///////////////////////////////////////////////////////////////////////////////
1384 1435
1385 class SkProcCoeffXfermode : public SkProcXfermode { 1436 class SkProcCoeffXfermode : public SkProcXfermode {
1386 public: 1437 public:
(...skipping 23 matching lines...) Expand all
1410 if (dc) { 1461 if (dc) {
1411 *dc = fDstCoeff; 1462 *dc = fDstCoeff;
1412 } 1463 }
1413 return true; 1464 return true;
1414 } 1465 }
1415 1466
1416 #if SK_SUPPORT_GPU 1467 #if SK_SUPPORT_GPU
1417 virtual bool asNewEffectOrCoeff(GrContext*, 1468 virtual bool asNewEffectOrCoeff(GrContext*,
1418 GrEffectRef** effect, 1469 GrEffectRef** effect,
1419 Coeff* src, 1470 Coeff* src,
1420 Coeff* dst) const SK_OVERRIDE { 1471 Coeff* dst,
1472 GrTexture* background) const SK_OVERRIDE {
1421 if (this->asCoeff(src, dst)) { 1473 if (this->asCoeff(src, dst)) {
1422 return true; 1474 return true;
1423 } 1475 }
1424 if (XferEffect::IsSupportedMode(fMode)) { 1476 if (XferEffect::IsSupportedMode(fMode)) {
1425 if (NULL != effect) { 1477 if (NULL != effect) {
1426 *effect = XferEffect::Create(fMode); 1478 *effect = XferEffect::Create(fMode, background);
1427 SkASSERT(NULL != *effect); 1479 SkASSERT(NULL != *effect);
1428 } 1480 }
1429 return true; 1481 return true;
1430 } 1482 }
1431 return false; 1483 return false;
1432 } 1484 }
1433 #endif 1485 #endif
1434 1486
1435 SK_DEVELOPER_TO_STRING() 1487 SK_DEVELOPER_TO_STRING()
1436 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkProcCoeffXfermode) 1488 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkProcCoeffXfermode)
(...skipping 533 matching lines...) Expand 10 before | Expand all | Expand 10 after
1970 return proc16; 2022 return proc16;
1971 } 2023 }
1972 2024
1973 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkXfermode) 2025 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkXfermode)
1974 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkProcCoeffXfermode) 2026 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkProcCoeffXfermode)
1975 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkClearXfermode) 2027 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkClearXfermode)
1976 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSrcXfermode) 2028 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSrcXfermode)
1977 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDstInXfermode) 2029 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDstInXfermode)
1978 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDstOutXfermode) 2030 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDstOutXfermode)
1979 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END 2031 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
OLDNEW
« no previous file with comments | « include/effects/SkXfermodeImageFilter.h ('k') | src/effects/SkArithmeticMode.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698