1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2021 Google LLC 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#include "src/core/SkBlendModeBlender.h" 9cb93a386Sopenharmony_ci#include "src/core/SkReadBuffer.h" 10cb93a386Sopenharmony_ci#include "src/core/SkWriteBuffer.h" 11cb93a386Sopenharmony_ci 12cb93a386Sopenharmony_ci#if SK_SUPPORT_GPU 13cb93a386Sopenharmony_ci#include "src/gpu/GrFragmentProcessor.h" 14cb93a386Sopenharmony_ci#include "src/gpu/effects/GrBlendFragmentProcessor.h" 15cb93a386Sopenharmony_ci#endif 16cb93a386Sopenharmony_ci 17cb93a386Sopenharmony_cisk_sp<SkBlender> SkBlender::Mode(SkBlendMode mode) { 18cb93a386Sopenharmony_ci#define RETURN_SINGLETON_BLENDER(m) \ 19cb93a386Sopenharmony_ci case m: { \ 20cb93a386Sopenharmony_ci static auto* sBlender = new SkBlendModeBlender{m}; \ 21cb93a386Sopenharmony_ci return sk_ref_sp(sBlender); \ 22cb93a386Sopenharmony_ci } 23cb93a386Sopenharmony_ci 24cb93a386Sopenharmony_ci switch (mode) { 25cb93a386Sopenharmony_ci RETURN_SINGLETON_BLENDER(SkBlendMode::kClear) 26cb93a386Sopenharmony_ci RETURN_SINGLETON_BLENDER(SkBlendMode::kSrc) 27cb93a386Sopenharmony_ci RETURN_SINGLETON_BLENDER(SkBlendMode::kDst) 28cb93a386Sopenharmony_ci RETURN_SINGLETON_BLENDER(SkBlendMode::kSrcOver) 29cb93a386Sopenharmony_ci RETURN_SINGLETON_BLENDER(SkBlendMode::kDstOver) 30cb93a386Sopenharmony_ci RETURN_SINGLETON_BLENDER(SkBlendMode::kSrcIn) 31cb93a386Sopenharmony_ci RETURN_SINGLETON_BLENDER(SkBlendMode::kDstIn) 32cb93a386Sopenharmony_ci RETURN_SINGLETON_BLENDER(SkBlendMode::kSrcOut) 33cb93a386Sopenharmony_ci RETURN_SINGLETON_BLENDER(SkBlendMode::kDstOut) 34cb93a386Sopenharmony_ci RETURN_SINGLETON_BLENDER(SkBlendMode::kSrcATop) 35cb93a386Sopenharmony_ci RETURN_SINGLETON_BLENDER(SkBlendMode::kDstATop) 36cb93a386Sopenharmony_ci RETURN_SINGLETON_BLENDER(SkBlendMode::kXor) 37cb93a386Sopenharmony_ci RETURN_SINGLETON_BLENDER(SkBlendMode::kPlus) 38cb93a386Sopenharmony_ci RETURN_SINGLETON_BLENDER(SkBlendMode::kModulate) 39cb93a386Sopenharmony_ci RETURN_SINGLETON_BLENDER(SkBlendMode::kScreen) 40cb93a386Sopenharmony_ci RETURN_SINGLETON_BLENDER(SkBlendMode::kOverlay) 41cb93a386Sopenharmony_ci RETURN_SINGLETON_BLENDER(SkBlendMode::kDarken) 42cb93a386Sopenharmony_ci RETURN_SINGLETON_BLENDER(SkBlendMode::kLighten) 43cb93a386Sopenharmony_ci RETURN_SINGLETON_BLENDER(SkBlendMode::kColorDodge) 44cb93a386Sopenharmony_ci RETURN_SINGLETON_BLENDER(SkBlendMode::kColorBurn) 45cb93a386Sopenharmony_ci RETURN_SINGLETON_BLENDER(SkBlendMode::kHardLight) 46cb93a386Sopenharmony_ci RETURN_SINGLETON_BLENDER(SkBlendMode::kSoftLight) 47cb93a386Sopenharmony_ci RETURN_SINGLETON_BLENDER(SkBlendMode::kDifference) 48cb93a386Sopenharmony_ci RETURN_SINGLETON_BLENDER(SkBlendMode::kExclusion) 49cb93a386Sopenharmony_ci RETURN_SINGLETON_BLENDER(SkBlendMode::kMultiply) 50cb93a386Sopenharmony_ci RETURN_SINGLETON_BLENDER(SkBlendMode::kHue) 51cb93a386Sopenharmony_ci RETURN_SINGLETON_BLENDER(SkBlendMode::kSaturation) 52cb93a386Sopenharmony_ci RETURN_SINGLETON_BLENDER(SkBlendMode::kColor) 53cb93a386Sopenharmony_ci RETURN_SINGLETON_BLENDER(SkBlendMode::kLuminosity) 54cb93a386Sopenharmony_ci } 55cb93a386Sopenharmony_ci 56cb93a386Sopenharmony_ci SkDEBUGFAILF("invalid blend mode %d", (int)mode); 57cb93a386Sopenharmony_ci return nullptr; 58cb93a386Sopenharmony_ci 59cb93a386Sopenharmony_ci#undef RETURN_SINGLETON_BLENDER 60cb93a386Sopenharmony_ci} 61cb93a386Sopenharmony_ci 62cb93a386Sopenharmony_cisk_sp<SkFlattenable> SkBlendModeBlender::CreateProc(SkReadBuffer& buffer) { 63cb93a386Sopenharmony_ci SkBlendMode mode = buffer.read32LE(SkBlendMode::kLastMode); 64cb93a386Sopenharmony_ci return SkBlender::Mode(mode); 65cb93a386Sopenharmony_ci} 66cb93a386Sopenharmony_ci 67cb93a386Sopenharmony_civoid SkBlendModeBlender::flatten(SkWriteBuffer& buffer) const { 68cb93a386Sopenharmony_ci buffer.writeInt((int)fMode); 69cb93a386Sopenharmony_ci} 70cb93a386Sopenharmony_ci 71cb93a386Sopenharmony_ci#if SK_SUPPORT_GPU 72cb93a386Sopenharmony_cistd::unique_ptr<GrFragmentProcessor> SkBlendModeBlender::asFragmentProcessor( 73cb93a386Sopenharmony_ci std::unique_ptr<GrFragmentProcessor> srcFP, 74cb93a386Sopenharmony_ci std::unique_ptr<GrFragmentProcessor> dstFP, 75cb93a386Sopenharmony_ci const GrFPArgs& fpArgs) const { 76cb93a386Sopenharmony_ci // Note that for the final blend onto the canvas, we should prefer to use the GrXferProcessor 77cb93a386Sopenharmony_ci // instead of a SkBlendModeBlender to perform the blend. The Xfer processor is able to perform 78cb93a386Sopenharmony_ci // coefficient-based blends directly, without readback. This will be much more efficient. 79cb93a386Sopenharmony_ci return GrBlendFragmentProcessor::Make( 80cb93a386Sopenharmony_ci std::move(srcFP), GrFragmentProcessor::UseDestColorAsInput(std::move(dstFP)), fMode); 81cb93a386Sopenharmony_ci} 82cb93a386Sopenharmony_ci#endif 83cb93a386Sopenharmony_ci 84cb93a386Sopenharmony_ciskvm::Color SkBlendModeBlender::onProgram(skvm::Builder* p, skvm::Color src, skvm::Color dst, 85cb93a386Sopenharmony_ci const SkColorInfo& colorInfo, skvm::Uniforms* uniforms, 86cb93a386Sopenharmony_ci SkArenaAlloc* alloc) const { 87cb93a386Sopenharmony_ci return p->blend(fMode, src, dst); 88cb93a386Sopenharmony_ci} 89