1 /*
2  * Copyright (c) 2024 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 #include "render/rs_mesa_blur_shader_filter.h"
16 
17 #include "effect/color_matrix.h"
18 #include "effect/runtime_shader_builder.h"
19 #include "include/gpu/GrDirectContext.h"
20 #include "platform/common/rs_system_properties.h"
21 #include "src/core/SkOpts.h"
22 
23 namespace OHOS {
24 namespace Rosen {
RSMESABlurShaderFilter(int radius)25 RSMESABlurShaderFilter::RSMESABlurShaderFilter(int radius)
26     : radius_(radius)
27 {
28     type_ = ShaderFilterType::MESA;
29     CalculateHash();
30 }
31 
RSMESABlurShaderFilter(int radius,float greyCoefLow,float greyCoefHigh)32 RSMESABlurShaderFilter::RSMESABlurShaderFilter(int radius, float greyCoefLow, float greyCoefHigh)
33     : radius_(radius), greyCoefLow_(greyCoefLow), greyCoefHigh_(greyCoefHigh)
34 {
35     type_ = ShaderFilterType::MESA;
36     CalculateHash();
37 }
38 
39 RSMESABlurShaderFilter::~RSMESABlurShaderFilter() = default;
40 
GetRadius() const41 int RSMESABlurShaderFilter::GetRadius() const
42 {
43     return radius_;
44 }
45 
SetRadius(int radius)46 void RSMESABlurShaderFilter::SetRadius(int radius)
47 {
48     radius_ = radius;
49     CalculateHash();
50 }
51 
SetPixelStretchParams(std::shared_ptr<RSPixelStretchParams> & param)52 void RSMESABlurShaderFilter::SetPixelStretchParams(std::shared_ptr<RSPixelStretchParams>& param)
53 {
54     {
55         std::lock_guard<std::mutex> lock(pixelStretchParamsMutex_);
56         pixelStretchParam_ = std::move(param);
57     }
58     CalculateHash();
59 }
60 
CalculateHash()61 void RSMESABlurShaderFilter::CalculateHash()
62 {
63     hash_ = SkOpts::hash(&radius_, sizeof(radius_), 0);
64     hash_ = SkOpts::hash(&greyCoefLow_, sizeof(greyCoefLow_), hash_);
65     hash_ = SkOpts::hash(&greyCoefHigh_, sizeof(greyCoefHigh_), hash_);
66     if (auto localParams = GetPixelStretchParams()) {
67         hash_ = SkOpts::hash(&localParams->offsetX_, sizeof(localParams->offsetX_), hash_);
68         hash_ = SkOpts::hash(&localParams->offsetY_, sizeof(localParams->offsetY_), hash_);
69         hash_ = SkOpts::hash(&localParams->offsetZ_, sizeof(localParams->offsetZ_), hash_);
70         hash_ = SkOpts::hash(&localParams->offsetW_, sizeof(localParams->offsetW_), hash_);
71         hash_ = SkOpts::hash(&localParams->tileMode_, sizeof(localParams->tileMode_), hash_);
72         hash_ = SkOpts::hash(&localParams->width_, sizeof(localParams->width_), hash_);
73         hash_ = SkOpts::hash(&localParams->height_, sizeof(localParams->height_), hash_);
74     }
75 }
76 
GetDetailedDescription() const77 std::string RSMESABlurShaderFilter::GetDetailedDescription() const
78 {
79     std::string filterString = ", radius: " + std::to_string(radius_) + " sigma";
80     filterString = filterString + ", greyCoef1: " + std::to_string(greyCoefLow_);
81     filterString = filterString + ", greyCoef2: " + std::to_string(greyCoefHigh_);
82     if (auto localParams = GetPixelStretchParams()) {
83         filterString = filterString + ", pixel stretch offsetX: " + std::to_string(localParams->offsetX_);
84         filterString = filterString + ", offsetY: " + std::to_string(localParams->offsetY_);
85         filterString = filterString + ", offsetZ: " + std::to_string(localParams->offsetZ_);
86         filterString = filterString + ", offsetW: " + std::to_string(localParams->offsetW_);
87         filterString = filterString + ", tileMode: " + std::to_string(localParams->tileMode_);
88         filterString = filterString + ", width: " + std::to_string(localParams->width_);
89         filterString = filterString + ", height: " + std::to_string(localParams->height_);
90     }
91     return filterString;
92 }
93 
GenerateGEVisualEffect(std::shared_ptr<Drawing::GEVisualEffectContainer> visualEffectContainer)94 void RSMESABlurShaderFilter::GenerateGEVisualEffect(
95     std::shared_ptr<Drawing::GEVisualEffectContainer> visualEffectContainer)
96 {
97     auto mesaFilter = std::make_shared<Drawing::GEVisualEffect>("MESA_BLUR", Drawing::DrawingPaintType::BRUSH);
98     mesaFilter->SetParam("MESA_BLUR_RADIUS", (int)radius_); // blur radius
99     mesaFilter->SetParam("MESA_BLUR_GREY_COEF_1", greyCoefLow_);
100     mesaFilter->SetParam("MESA_BLUR_GREY_COEF_2", greyCoefHigh_);
101     if (auto localParams = GetPixelStretchParams()) {
102         mesaFilter->SetParam("OFFSET_X", localParams->offsetX_);
103         mesaFilter->SetParam("OFFSET_Y", localParams->offsetY_);
104         mesaFilter->SetParam("OFFSET_Z", localParams->offsetZ_);
105         mesaFilter->SetParam("OFFSET_W", localParams->offsetW_);
106         mesaFilter->SetParam("TILE_MODE", localParams->tileMode_);
107         mesaFilter->SetParam("WIDTH", localParams->width_);
108         mesaFilter->SetParam("HEIGHT", localParams->height_);
109     } else {
110         mesaFilter->SetParam("OFFSET_X", 0.f);
111         mesaFilter->SetParam("OFFSET_Y", 0.f);
112         mesaFilter->SetParam("OFFSET_Z", 0.f);
113         mesaFilter->SetParam("OFFSET_W", 0.f);
114         mesaFilter->SetParam("TILE_MODE", 0);
115         mesaFilter->SetParam("WIDTH", 0.f);
116         mesaFilter->SetParam("HEIGHT", 0.f);
117     }
118     visualEffectContainer->AddToChainedFilter(mesaFilter);
119 }
120 } // namespace Rosen
121 } // namespace OHOS
122