1 /*
2 * Copyright (c) 2021-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 "render/rs_blur_filter.h"
17
18 #ifdef USE_M133_SKIA
19 #include "src/core/SkChecksum.h"
20 #else
21 #include "src/core/SkOpts.h"
22 #endif
23
24 #include "common/rs_common_def.h"
25 #include "platform/common/rs_log.h"
26 #include "platform/common/rs_system_properties.h"
27
28
29 namespace OHOS {
30 namespace Rosen {
31 const bool KAWASE_BLUR_ENABLED = RSSystemProperties::GetKawaseEnabled();
32 const auto BLUR_TYPE = KAWASE_BLUR_ENABLED ? Drawing::ImageBlurType::KAWASE : Drawing::ImageBlurType::GAUSS;
RSBlurFilter(float blurRadiusX,float blurRadiusY,bool disableSystemAdaptation)33 RSBlurFilter::RSBlurFilter(float blurRadiusX, float blurRadiusY, bool disableSystemAdaptation)
34 : RSDrawingFilterOriginal(Drawing::ImageFilter::CreateBlurImageFilter(blurRadiusX, blurRadiusY,
35 Drawing::TileMode::CLAMP, nullptr, BLUR_TYPE)),
36 blurRadiusX_(blurRadiusX),
37 blurRadiusY_(blurRadiusY),
38 disableSystemAdaptation_(disableSystemAdaptation)
39 {
40 type_ = FilterType::BLUR;
41
42 float blurRadiusXForHash = DecreasePrecision(blurRadiusX);
43 float blurRadiusYForHash = DecreasePrecision(blurRadiusY);
44 #ifdef USE_M133_SKIA
45 const auto hashFunc = SkChecksum::Hash32;
46 #else
47 const auto hashFunc = SkOpts::hash;
48 #endif
49 hash_ = hashFunc(&type_, sizeof(type_), 0);
50 hash_ = hashFunc(&blurRadiusXForHash, sizeof(blurRadiusXForHash), hash_);
51 hash_ = hashFunc(&blurRadiusYForHash, sizeof(blurRadiusYForHash), hash_);
52 hash_ = hashFunc(&disableSystemAdaptation, sizeof(disableSystemAdaptation), hash_);
53 }
54
55 RSBlurFilter::~RSBlurFilter() = default;
56
GetBlurRadiusX()57 float RSBlurFilter::GetBlurRadiusX()
58 {
59 return blurRadiusX_;
60 }
61
GetBlurRadiusY()62 float RSBlurFilter::GetBlurRadiusY()
63 {
64 return blurRadiusY_;
65 }
66
GetDisableSystemAdaptation()67 bool RSBlurFilter::GetDisableSystemAdaptation()
68 {
69 return disableSystemAdaptation_;
70 }
71
GetDescription()72 std::string RSBlurFilter::GetDescription()
73 {
74 return "RSBlurFilter blur radius is " + std::to_string(blurRadiusX_) + " sigma";
75 }
76
GetDetailedDescription()77 std::string RSBlurFilter::GetDetailedDescription()
78 {
79 return "RSBlurFilterBlur, radius: " + std::to_string(blurRadiusX_) + " sigma" +
80 ", greyCoef1: " + std::to_string(greyCoef_ == std::nullopt ? 0.0f : greyCoef_->x_) +
81 ", greyCoef2: " + std::to_string(greyCoef_ == std::nullopt ? 0.0f : greyCoef_->y_);
82 }
83
IsValid() const84 bool RSBlurFilter::IsValid() const
85 {
86 constexpr float epsilon = 0.999f;
87 return blurRadiusX_ > epsilon || blurRadiusY_ > epsilon;
88 }
89
Compose(const std::shared_ptr<RSDrawingFilterOriginal> & other) const90 std::shared_ptr<RSDrawingFilterOriginal> RSBlurFilter::Compose(
91 const std::shared_ptr<RSDrawingFilterOriginal>& other) const
92 {
93 std::shared_ptr<RSBlurFilter> result = std::make_shared<RSBlurFilter>(blurRadiusX_, blurRadiusY_,
94 disableSystemAdaptation_);
95 result->imageFilter_ = Drawing::ImageFilter::CreateComposeImageFilter(imageFilter_, other->GetImageFilter());
96 auto otherHash = other->Hash();
97 #ifdef USE_M133_SKIA
98 const auto hashFunc = SkChecksum::Hash32;
99 #else
100 const auto hashFunc = SkOpts::hash;
101 #endif
102 result->hash_ = hashFunc(&otherHash, sizeof(otherHash), hash_);
103 return result;
104 }
105
DrawImageRect(Drawing::Canvas & canvas,const std::shared_ptr<Drawing::Image> & image,const Drawing::Rect & src,const Drawing::Rect & dst) const106 void RSBlurFilter::DrawImageRect(Drawing::Canvas& canvas, const std::shared_ptr<Drawing::Image>& image,
107 const Drawing::Rect& src, const Drawing::Rect& dst) const
108 {
109 auto brush = GetBrush();
110 std::shared_ptr<Drawing::Image> greyImage = image;
111 if (greyCoef_.has_value()) {
112 greyImage = RSPropertiesPainter::DrawGreyAdjustment(canvas, image, greyCoef_.value());
113 }
114 if (greyImage == nullptr) {
115 greyImage = image;
116 }
117 // if kawase blur failed, use gauss blur
118 static bool DDGR_ENABLED = RSSystemProperties::GetGpuApiType() == GpuApiType::DDGR;
119 KawaseParameter param = KawaseParameter(src, dst, blurRadiusX_, nullptr, brush.GetColor().GetAlphaF());
120 if (!DDGR_ENABLED && KAWASE_BLUR_ENABLED &&
121 KawaseBlurFilter::GetKawaseBlurFilter()->ApplyKawaseBlur(canvas, greyImage, param)) {
122 return;
123 }
124 canvas.AttachBrush(brush);
125 canvas.DrawImageRect(*greyImage, src, dst, Drawing::SamplingOptions());
126 canvas.DetachBrush();
127 }
128
SetGreyCoef(const std::optional<Vector2f> & greyCoef)129 void RSBlurFilter::SetGreyCoef(const std::optional<Vector2f>& greyCoef)
130 {
131 greyCoef_ = greyCoef;
132 }
133
CanSkipFrame() const134 bool RSBlurFilter::CanSkipFrame() const
135 {
136 constexpr float HEAVY_BLUR_THRESHOLD = 25.0f;
137 return blurRadiusX_ > HEAVY_BLUR_THRESHOLD && blurRadiusY_ > HEAVY_BLUR_THRESHOLD;
138 };
139 } // namespace Rosen
140 } // namespace OHOS
141