xref: /aosp_15_r20/external/skia/src/gpu/ganesh/glsl/GrGLSLBlend.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1 /*
2  * Copyright 2015 Google Inc.
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 "src/gpu/ganesh/glsl/GrGLSLBlend.h"
8 
9 #include "include/core/SkBlendMode.h"
10 #include "include/core/SkSpan.h"
11 #include "include/private/base/SkAssert.h"
12 #include "include/private/gpu/ganesh/GrTypesPriv.h"
13 #include "src/core/SkSLTypeShared.h"
14 #include "src/gpu/Blend.h"
15 #include "src/gpu/ganesh/glsl/GrGLSLUniformHandler.h"
16 #include "src/sksl/SkSLString.h"
17 
18 namespace GrGLSLBlend {
19 
BlendExpression(const GrProcessor * processor,GrGLSLUniformHandler * uniformHandler,GrGLSLProgramDataManager::UniformHandle * blendUniform,const char * srcColor,const char * dstColor,SkBlendMode mode)20 std::string BlendExpression(const GrProcessor* processor,
21                             GrGLSLUniformHandler* uniformHandler,
22                             GrGLSLProgramDataManager::UniformHandle* blendUniform,
23                             const char* srcColor,
24                             const char* dstColor,
25                             SkBlendMode mode) {
26     auto info = skgpu::GetReducedBlendModeInfo(mode);
27     if (info.fUniformData.empty()) {
28         return SkSL::String::printf("%s(%s, %s)", info.fFunction, srcColor, dstColor);
29     }
30 
31     SkSLType skslType = (SkSLType)((int)SkSLType::kHalf + info.fUniformData.size() - 1);
32     SkASSERT(skslType >= SkSLType::kHalf && skslType <= SkSLType::kHalf4);
33 
34     const char* blendUniName;
35     *blendUniform = uniformHandler->addUniform(processor, kFragment_GrShaderFlag,
36                                                skslType, "blend", &blendUniName);
37     return SkSL::String::printf("%s(%s, %s, %s)", info.fFunction, blendUniName, srcColor, dstColor);
38 }
39 
BlendKey(SkBlendMode mode)40 int BlendKey(SkBlendMode mode) {
41     // This switch must be kept in sync with GetReducedBlendModeInfo() in src/gpu/Blend.cpp.
42     switch (mode) {
43         case SkBlendMode::kSrcOver:
44         case SkBlendMode::kDstOver:
45         case SkBlendMode::kSrcIn:
46         case SkBlendMode::kDstIn:
47         case SkBlendMode::kSrcOut:
48         case SkBlendMode::kDstOut:
49         case SkBlendMode::kSrcATop:
50         case SkBlendMode::kDstATop:
51         case SkBlendMode::kXor:
52             return -1;  // blend_porter_duff
53 
54         case SkBlendMode::kHue:
55         case SkBlendMode::kSaturation:
56         case SkBlendMode::kLuminosity:
57         case SkBlendMode::kColor:
58             return -2;  // blend_hslc
59 
60         case SkBlendMode::kOverlay:
61         case SkBlendMode::kHardLight:
62             return -3;  // blend_overlay
63 
64         case SkBlendMode::kDarken:
65         case SkBlendMode::kLighten:
66             return -4;  // blend_darken
67 
68         default:
69             return (int)mode;  // uses a dedicated SkSL blend function
70     }
71 }
72 
SetBlendModeUniformData(const GrGLSLProgramDataManager & pdman,GrGLSLProgramDataManager::UniformHandle blendUniform,SkBlendMode mode)73 void SetBlendModeUniformData(const GrGLSLProgramDataManager& pdman,
74                              GrGLSLProgramDataManager::UniformHandle blendUniform,
75                              SkBlendMode mode) {
76     auto info = skgpu::GetReducedBlendModeInfo(mode);
77     switch (info.fUniformData.size()) {
78         case 0:
79             /* no uniform data necessary */
80             break;
81         case 1:
82             pdman.set1f(blendUniform, info.fUniformData[0]);
83             break;
84         case 2:
85             pdman.set2f(blendUniform, info.fUniformData[0], info.fUniformData[1]);
86             break;
87         case 3:
88             pdman.set3f(blendUniform, info.fUniformData[0], info.fUniformData[1],
89                                       info.fUniformData[2]);
90             break;
91         case 4:
92             pdman.set4f(blendUniform, info.fUniformData[0], info.fUniformData[1],
93                                       info.fUniformData[2], info.fUniformData[3]);
94             break;
95     }
96 }
97 
98 }  // namespace GrGLSLBlend
99