OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |