SkModeColorFilter.cpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  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/SkColorFilter.h"
  8. #include "include/core/SkString.h"
  9. #include "include/private/SkColorData.h"
  10. #include "include/utils/SkRandom.h"
  11. #include "src/core/SkArenaAlloc.h"
  12. #include "src/core/SkBlendModePriv.h"
  13. #include "src/core/SkBlitRow.h"
  14. #include "src/core/SkColorSpacePriv.h"
  15. #include "src/core/SkColorSpaceXformSteps.h"
  16. #include "src/core/SkModeColorFilter.h"
  17. #include "src/core/SkRasterPipeline.h"
  18. #include "src/core/SkReadBuffer.h"
  19. #include "src/core/SkValidationUtils.h"
  20. #include "src/core/SkWriteBuffer.h"
  21. #include "src/utils/SkUTF.h"
  22. //////////////////////////////////////////////////////////////////////////////////////////////////
  23. SkModeColorFilter::SkModeColorFilter(SkColor color, SkBlendMode mode) {
  24. fColor = color;
  25. fMode = mode;
  26. }
  27. bool SkModeColorFilter::onAsAColorMode(SkColor* color, SkBlendMode* mode) const {
  28. if (color) {
  29. *color = fColor;
  30. }
  31. if (mode) {
  32. *mode = fMode;
  33. }
  34. return true;
  35. }
  36. uint32_t SkModeColorFilter::getFlags() const {
  37. uint32_t flags = 0;
  38. switch (fMode) {
  39. case SkBlendMode::kDst: //!< [Da, Dc]
  40. case SkBlendMode::kSrcATop: //!< [Da, Sc * Da + (1 - Sa) * Dc]
  41. flags |= kAlphaUnchanged_Flag;
  42. default:
  43. break;
  44. }
  45. return flags;
  46. }
  47. void SkModeColorFilter::flatten(SkWriteBuffer& buffer) const {
  48. buffer.writeColor(fColor);
  49. buffer.writeUInt((int)fMode);
  50. }
  51. sk_sp<SkFlattenable> SkModeColorFilter::CreateProc(SkReadBuffer& buffer) {
  52. SkColor color = buffer.readColor();
  53. SkBlendMode mode = (SkBlendMode)buffer.readUInt();
  54. return SkColorFilters::Blend(color, mode);
  55. }
  56. bool SkModeColorFilter::onAppendStages(const SkStageRec& rec, bool shaderIsOpaque) const {
  57. rec.fPipeline->append(SkRasterPipeline::move_src_dst);
  58. SkColor4f color = SkColor4f::FromColor(fColor);
  59. SkColorSpaceXformSteps(sk_srgb_singleton(), kUnpremul_SkAlphaType,
  60. rec.fDstCS, kUnpremul_SkAlphaType).apply(color.vec());
  61. rec.fPipeline->append_constant_color(rec.fAlloc, color.premul().vec());
  62. SkBlendMode_AppendStages(fMode, rec.fPipeline);
  63. return true;
  64. }
  65. ///////////////////////////////////////////////////////////////////////////////
  66. #if SK_SUPPORT_GPU
  67. #include "include/gpu/GrBlend.h"
  68. #include "src/gpu/SkGr.h"
  69. #include "src/gpu/effects/GrXfermodeFragmentProcessor.h"
  70. #include "src/gpu/effects/generated/GrConstColorProcessor.h"
  71. std::unique_ptr<GrFragmentProcessor> SkModeColorFilter::asFragmentProcessor(
  72. GrRecordingContext*, const GrColorSpaceInfo& dstColorSpaceInfo) const {
  73. if (SkBlendMode::kDst == fMode) {
  74. return nullptr;
  75. }
  76. auto constFP = GrConstColorProcessor::Make(SkColorToPMColor4f(fColor, dstColorSpaceInfo),
  77. GrConstColorProcessor::InputMode::kIgnore);
  78. auto fp = GrXfermodeFragmentProcessor::MakeFromSrcProcessor(std::move(constFP), fMode);
  79. if (!fp) {
  80. return nullptr;
  81. }
  82. #ifdef SK_DEBUG
  83. // With a solid color input this should always be able to compute the blended color
  84. // (at least for coeff modes)
  85. if ((unsigned)fMode <= (unsigned)SkBlendMode::kLastCoeffMode) {
  86. SkASSERT(fp->hasConstantOutputForConstantInput());
  87. }
  88. #endif
  89. return fp;
  90. }
  91. #endif
  92. ///////////////////////////////////////////////////////////////////////////////
  93. sk_sp<SkColorFilter> SkColorFilters::Blend(SkColor color, SkBlendMode mode) {
  94. if (!SkIsValidMode(mode)) {
  95. return nullptr;
  96. }
  97. unsigned alpha = SkColorGetA(color);
  98. // first collaps some modes if possible
  99. if (SkBlendMode::kClear == mode) {
  100. color = 0;
  101. mode = SkBlendMode::kSrc;
  102. } else if (SkBlendMode::kSrcOver == mode) {
  103. if (0 == alpha) {
  104. mode = SkBlendMode::kDst;
  105. } else if (255 == alpha) {
  106. mode = SkBlendMode::kSrc;
  107. }
  108. // else just stay srcover
  109. }
  110. // weed out combinations that are noops, and just return null
  111. if (SkBlendMode::kDst == mode ||
  112. (0 == alpha && (SkBlendMode::kSrcOver == mode ||
  113. SkBlendMode::kDstOver == mode ||
  114. SkBlendMode::kDstOut == mode ||
  115. SkBlendMode::kSrcATop == mode ||
  116. SkBlendMode::kXor == mode ||
  117. SkBlendMode::kDarken == mode)) ||
  118. (0xFF == alpha && SkBlendMode::kDstIn == mode)) {
  119. return nullptr;
  120. }
  121. return SkModeColorFilter::Make(color, mode);
  122. }