SkXfermode.cpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. /*
  2. * Copyright 2006 The Android Open Source Project
  3. *
  4. * Use of this source code is governed by a BSD-style license that can be
  5. * found in the LICENSE file.
  6. */
  7. #include "include/core/SkString.h"
  8. #include "include/private/SkColorData.h"
  9. #include "include/private/SkOnce.h"
  10. #include "src/core/SkBlendModePriv.h"
  11. #include "src/core/SkMathPriv.h"
  12. #include "src/core/SkOpts.h"
  13. #include "src/core/SkRasterPipeline.h"
  14. #include "src/core/SkReadBuffer.h"
  15. #include "src/core/SkWriteBuffer.h"
  16. #include "src/core/SkXfermodePriv.h"
  17. #if SK_SUPPORT_GPU
  18. #include "src/gpu/GrFragmentProcessor.h"
  19. #include "src/gpu/effects/GrCustomXfermode.h"
  20. #include "src/gpu/effects/GrPorterDuffXferProcessor.h"
  21. #include "src/gpu/effects/GrXfermodeFragmentProcessor.h"
  22. #endif
  23. ///////////////////////////////////////////////////////////////////////////////////////////////////
  24. class SkProcCoeffXfermode : public SkXfermode {
  25. public:
  26. SkProcCoeffXfermode(SkBlendMode mode) : fMode(mode) {}
  27. void xfer32(SkPMColor dst[], const SkPMColor src[], int count,
  28. const SkAlpha aa[]) const override {
  29. SkASSERT(dst && src && count >= 0);
  30. SkRasterPipeline_<256> p;
  31. SkRasterPipeline_MemoryCtx dst_ctx = { (void*)dst, 0 },
  32. src_ctx = { (void*)src, 0 },
  33. aa_ctx = { (void*)aa, 0 };
  34. p.append_load (kN32_SkColorType, &src_ctx);
  35. p.append_load_dst(kN32_SkColorType, &dst_ctx);
  36. if (SkBlendMode_ShouldPreScaleCoverage(fMode, /*rgb_coverage=*/false)) {
  37. if (aa) {
  38. p.append(SkRasterPipeline::scale_u8, &aa_ctx);
  39. }
  40. SkBlendMode_AppendStages(fMode, &p);
  41. } else {
  42. SkBlendMode_AppendStages(fMode, &p);
  43. if (aa) {
  44. p.append(SkRasterPipeline::lerp_u8, &aa_ctx);
  45. }
  46. }
  47. p.append_store(kN32_SkColorType, &dst_ctx);
  48. p.run(0, 0, count,1);
  49. }
  50. private:
  51. const SkBlendMode fMode;
  52. typedef SkXfermode INHERITED;
  53. };
  54. const char* SkBlendMode_Name(SkBlendMode mode) {
  55. SkASSERT((unsigned) mode <= (unsigned)SkBlendMode::kLastMode);
  56. const char* gModeStrings[] = {
  57. "Clear", "Src", "Dst", "SrcOver", "DstOver", "SrcIn", "DstIn",
  58. "SrcOut", "DstOut", "SrcATop", "DstATop", "Xor", "Plus",
  59. "Modulate", "Screen", "Overlay", "Darken", "Lighten", "ColorDodge",
  60. "ColorBurn", "HardLight", "SoftLight", "Difference", "Exclusion",
  61. "Multiply", "Hue", "Saturation", "Color", "Luminosity"
  62. };
  63. return gModeStrings[(int)mode];
  64. static_assert(SK_ARRAY_COUNT(gModeStrings) == (size_t)SkBlendMode::kLastMode + 1, "mode_count");
  65. }
  66. sk_sp<SkXfermode> SkXfermode::Make(SkBlendMode mode) {
  67. if ((unsigned)mode > (unsigned)SkBlendMode::kLastMode) {
  68. // report error
  69. return nullptr;
  70. }
  71. // Skia's "default" mode is srcover. nullptr in SkPaint is interpreted as srcover
  72. // so we can just return nullptr from the factory.
  73. if (SkBlendMode::kSrcOver == mode) {
  74. return nullptr;
  75. }
  76. const int COUNT_BLENDMODES = (int)SkBlendMode::kLastMode + 1;
  77. static SkOnce once[COUNT_BLENDMODES];
  78. static SkXfermode* cached[COUNT_BLENDMODES];
  79. once[(int)mode]([mode] {
  80. if (auto xfermode = SkOpts::create_xfermode(mode)) {
  81. cached[(int)mode] = xfermode;
  82. } else {
  83. cached[(int)mode] = new SkProcCoeffXfermode(mode);
  84. }
  85. });
  86. return sk_ref_sp(cached[(int)mode]);
  87. }
  88. ///////////////////////////////////////////////////////////////////////////////////////////////////
  89. bool SkXfermode::IsOpaque(SkBlendMode mode, SrcColorOpacity opacityType) {
  90. SkBlendModeCoeff src, dst;
  91. if (!SkBlendMode_AsCoeff(mode, &src, &dst)) {
  92. return false;
  93. }
  94. switch (src) {
  95. case SkBlendModeCoeff::kDA:
  96. case SkBlendModeCoeff::kDC:
  97. case SkBlendModeCoeff::kIDA:
  98. case SkBlendModeCoeff::kIDC:
  99. return false;
  100. default:
  101. break;
  102. }
  103. switch (dst) {
  104. case SkBlendModeCoeff::kZero:
  105. return true;
  106. case SkBlendModeCoeff::kISA:
  107. return kOpaque_SrcColorOpacity == opacityType;
  108. case SkBlendModeCoeff::kSA:
  109. return kTransparentBlack_SrcColorOpacity == opacityType ||
  110. kTransparentAlpha_SrcColorOpacity == opacityType;
  111. case SkBlendModeCoeff::kSC:
  112. return kTransparentBlack_SrcColorOpacity == opacityType;
  113. default:
  114. return false;
  115. }
  116. return false;
  117. }
  118. #if SK_SUPPORT_GPU
  119. const GrXPFactory* SkBlendMode_AsXPFactory(SkBlendMode mode) {
  120. if (SkBlendMode_AsCoeff(mode, nullptr, nullptr)) {
  121. const GrXPFactory* result = GrPorterDuffXPFactory::Get(mode);
  122. SkASSERT(result);
  123. return result;
  124. }
  125. SkASSERT(GrCustomXfermode::IsSupportedMode(mode));
  126. return GrCustomXfermode::Get(mode);
  127. }
  128. #endif