1 /*
2  * Copyright (c) 2023-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 #ifndef RENDER_SERVICE_CLIENT_CORE_RENDER_RS_KAWASE_BLUR_H
16 #define RENDER_SERVICE_CLIENT_CORE_RENDER_RS_KAWASE_BLUR_H
17 
18 #include "draw/canvas.h"
19 #include "effect/color_filter.h"
20 #include "effect/runtime_effect.h"
21 #include "image/image.h"
22 #include "utils/matrix.h"
23 #include "utils/rect.h"
24 
25 namespace OHOS {
26 namespace Rosen {
27 struct KawaseParameter {
28     Drawing::Rect src;
29     Drawing::Rect dst;
30     int radius = 0;
31     std::shared_ptr<Drawing::ColorFilter> colorFilter;
32     float alpha = 0.f;
33 
34     KawaseParameter(const Drawing::Rect& s, const Drawing::Rect& d, int r,
35         std::shared_ptr<Drawing::ColorFilter> color = nullptr, float a = 0.f)
36         : src(s), dst(d), radius(r), colorFilter(color), alpha(a) {}
37 };
38 class KawaseBlurFilter {
39 public:
40     bool ApplyKawaseBlur(Drawing::Canvas& canvas, const std::shared_ptr<Drawing::Image>& image,
41         const KawaseParameter& param);
GetKawaseBlurFilter()42     static KawaseBlurFilter* GetKawaseBlurFilter()
43     {
44         static thread_local KawaseBlurFilter* filter;
45         if (filter == nullptr) {
46             filter = new KawaseBlurFilter();
47         }
48         return filter;
49     }
50 
51 private:
52     struct BlurParams {
53         int numberOfPasses = 1;
54         int width = 0;
55         int height = 0;
56         float radiusByPass = 0.f;
57     };
58 
59     KawaseBlurFilter();
60     ~KawaseBlurFilter();
61     KawaseBlurFilter(const KawaseBlurFilter& filter);
62     const KawaseBlurFilter &operator=(const KawaseBlurFilter& filter);
63     static Drawing::Matrix GetShaderTransform(const Drawing::Canvas* canvas, const Drawing::Rect& blurRect,
64         float scaleW = 1.0f, float scaleH = 1.0f);
65     void CheckInputImage(Drawing::Canvas& canvas, const std::shared_ptr<Drawing::Image>& image,
66         const KawaseParameter& param, std::shared_ptr<Drawing::Image>& checkedImage);
67     void OutputOriginalImage(Drawing::Canvas& canvas, const std::shared_ptr<Drawing::Image>& image,
68         const KawaseParameter& param);
69     std::shared_ptr<Drawing::ShaderEffect> ApplySimpleFilter(Drawing::Canvas& canvas,
70         const std::shared_ptr<Drawing::Image>& input, const Drawing::Matrix& blurMatrix,
71         const Drawing::ImageInfo& scaledInfo, const Drawing::SamplingOptions& linear) const;
72     std::shared_ptr<Drawing::Image> ExecutePingPongBlur(Drawing::Canvas& canvas,
73         const std::shared_ptr<Drawing::Image>& input, const KawaseParameter& kParam, const BlurParams& bParam) const;
74     bool ApplyBlur(Drawing::Canvas& canvas, const std::shared_ptr<Drawing::Image>& image,
75         const std::shared_ptr<Drawing::Image>& blurImage, const KawaseParameter& param) const;
76     void ComputeRadiusAndScale(int radius);
77     void AdjustRadiusAndScale();
78     std::string GetDescription() const;
79     void SetupSimpleFilter();
80 
81     static constexpr float baseBlurScale = 0.5f; // base downSample radio
82     static constexpr uint32_t kMaxPasses = 4; // Maximum number of render passes
83     static constexpr uint32_t kMaxPassesLargeRadius = 7;
84     static constexpr float kDilatedConvolution = 2.0f;
85     static constexpr float kDilatedConvolutionLargeRadius = 4.6f;
86     // To avoid downscaling artifacts, interpolate the blurred fbo with the full composited image, up to this radius
87     static constexpr float kMaxCrossFadeRadius = 10.0f;
88     static constexpr bool supportLargeRadius = true;
89 
90     std::shared_ptr<Drawing::RuntimeEffect> blurEffect_;
91     std::shared_ptr<Drawing::RuntimeEffect> mixEffect_;
92     std::shared_ptr<Drawing::RuntimeEffect> simpleFilter_;
93     float blurRadius_ = 0.f;
94     float blurScale_ = 0.25f;
95 
96     // Advanced Filter
97     void setupBlurEffectAdvancedFilter();
98     std::shared_ptr<Drawing::RuntimeEffect> blurEffectAF_;
99 };
100 } // namespace Rosen
101 } // namespace OHOS
102 #endif // RENDER_SERVICE_CLIENT_CORE_RENDER_RS_KAWASE_BLUR_H