1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "include/core/SkM44.h"
17 
18 #include "skia_image.h"
19 #include "skia_image_info.h"
20 #include "skia_matrix.h"
21 #include "skia_matrix44.h"
22 #include "skia_shader_effect.h"
23 #include "skia_runtime_effect.h"
24 #include "skia_runtime_shader_builder.h"
25 
26 #include "effect/runtime_effect.h"
27 #include "image/image.h"
28 #include "utils/matrix.h"
29 
30 namespace OHOS {
31 namespace Rosen {
32 namespace Drawing {
SkiaRuntimeShaderBuilder(std::shared_ptr<RuntimeEffect> effect)33 SkiaRuntimeShaderBuilder::SkiaRuntimeShaderBuilder(std::shared_ptr<RuntimeEffect> effect) noexcept
34 {
35     auto effectImpl = effect ? effect->GetImpl<SkiaRuntimeEffect>() : nullptr;
36     if (effectImpl != nullptr) {
37         skRuntimeShaderBuilder_ = std::make_shared<SkRuntimeShaderBuilder>(effectImpl->GetRuntimeEffect());
38     }
39 }
40 
MakeShader(const Matrix * localMatrix,bool isOpaque)41 std::shared_ptr<ShaderEffect> SkiaRuntimeShaderBuilder::MakeShader(const Matrix* localMatrix, bool isOpaque)
42 {
43     if (!skRuntimeShaderBuilder_) {
44         return nullptr;
45     }
46     sk_sp<SkShader> skShader = skRuntimeShaderBuilder_->makeShader(
47         localMatrix ? &localMatrix->GetImpl<SkiaMatrix>()->ExportSkiaMatrix() : nullptr, isOpaque);
48     auto shader = std::make_shared<ShaderEffect>();
49     shader->GetImpl<SkiaShaderEffect>()->SetSkShader(skShader);
50 
51     return shader;
52 }
53 
MakeImage(GPUContext * grContext,const Matrix * localMatrix,ImageInfo resultInfo,bool mipmapped)54 std::shared_ptr<Image> SkiaRuntimeShaderBuilder::MakeImage(GPUContext* grContext, const Matrix* localMatrix,
55     ImageInfo resultInfo, bool mipmapped)
56 {
57     if (!skRuntimeShaderBuilder_ || !grContext) {
58         return nullptr;
59     }
60     sk_sp<SkImage> skImage = skRuntimeShaderBuilder_->makeImage(
61         grContext->GetImpl<SkiaGPUContext>()->GetGrContext().get(),
62         localMatrix ? &localMatrix->GetImpl<SkiaMatrix>()->ExportSkiaMatrix() : nullptr,
63         SkiaImageInfo::ConvertToSkImageInfo(resultInfo), mipmapped);
64     auto image = std::make_shared<Image>();
65     image->GetImpl<SkiaImage>()->SetSkImage(skImage);
66 
67     return image;
68 }
69 
SetChild(const std::string & name,std::shared_ptr<ShaderEffect> shader)70 void SkiaRuntimeShaderBuilder::SetChild(const std::string& name, std::shared_ptr<ShaderEffect> shader)
71 {
72     if (!skRuntimeShaderBuilder_) {
73         return;
74     }
75     skRuntimeShaderBuilder_->child(name.c_str()) = shader->GetImpl<SkiaShaderEffect>()->GetShader();
76 }
77 
SetUniform(const std::string & name,float val)78 void SkiaRuntimeShaderBuilder::SetUniform(const std::string& name, float val)
79 {
80     if (!skRuntimeShaderBuilder_) {
81         return;
82     }
83     skRuntimeShaderBuilder_->uniform(name.c_str()) = val;
84 }
85 
SetUniform(const std::string & name,float x,float y)86 void SkiaRuntimeShaderBuilder::SetUniform(const std::string& name, float x, float y)
87 {
88     if (!skRuntimeShaderBuilder_) {
89         return;
90     }
91     skRuntimeShaderBuilder_->uniform(name.c_str()) = SkV2{x, y};
92 }
93 
SetUniform(const std::string & name,float x,float y,float z)94 void SkiaRuntimeShaderBuilder::SetUniform(const std::string& name, float x, float y, float z)
95 {
96     if (!skRuntimeShaderBuilder_) {
97         return;
98     }
99     skRuntimeShaderBuilder_->uniform(name.c_str()) = SkV3{x, y, z};
100 }
101 
SetUniform(const std::string & name,const float values[],size_t size)102 void SkiaRuntimeShaderBuilder::SetUniform(const std::string& name, const float values[], size_t size)
103 {
104     if (!skRuntimeShaderBuilder_) {
105         return;
106     }
107     skRuntimeShaderBuilder_->uniform(name.c_str()).set(values, size);
108 }
109 
SetUniform(const std::string & name,const Matrix & uniformMatrix33)110 void SkiaRuntimeShaderBuilder::SetUniform(const std::string& name, const Matrix& uniformMatrix33)
111 {
112     if (!skRuntimeShaderBuilder_) {
113         return;
114     }
115 
116     skRuntimeShaderBuilder_->uniform(name.c_str()) = uniformMatrix33.GetImpl<SkiaMatrix>()->ExportSkiaMatrix();
117 }
118 
SetUniform(const std::string & name,const Matrix44 & uniformMatrix44)119 void SkiaRuntimeShaderBuilder::SetUniform(const std::string& name, const Matrix44& uniformMatrix44)
120 {
121     if (!skRuntimeShaderBuilder_) {
122         return;
123     }
124 
125     skRuntimeShaderBuilder_->uniform(name.c_str()) = uniformMatrix44.GetImpl<SkiaMatrix44>()->GetSkMatrix44();
126 }
127 
SetUniformVec4(const std::string & name,float x,float y,float z,float w)128 void SkiaRuntimeShaderBuilder::SetUniformVec4(const std::string& name, float x, float y, float z, float w)
129 {
130     if (!skRuntimeShaderBuilder_) {
131         return;
132     }
133     SkV4 uniformSk4 { x, y, z, w };
134     skRuntimeShaderBuilder_->uniform(name.c_str()) = uniformSk4;
135 }
136 
SetUniform(const std::string & name,float x,float y,float width,float height)137 void SkiaRuntimeShaderBuilder::SetUniform(const std::string& name, float x, float y, float width, float height)
138 {
139     if (!skRuntimeShaderBuilder_ || width == 0 || height == 0) {
140         return;
141     }
142     SkV2 offsets[5] = {
143         SkV2{0.0f, 0.0f},
144         SkV2{x / width, y / height},
145         SkV2{-x / width, y / height},
146         SkV2{x / width, -y / height},
147         SkV2{-x / width, -y / height},
148     };
149 
150     skRuntimeShaderBuilder_->uniform(name.c_str()) = offsets;
151 }
152 } // namespace Drawing
153 } // namespace Rosen
154 } // namespace OHOS