| 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 |