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