1 /*
2 * Copyright (c) 2021 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_material_filter.h"
16
17 #include <unordered_map>
18
19 #include "include/effects/SkBlurImageFilter.h"
20
21 #include "pipeline/rs_paint_filter_canvas.h"
22 #include "property/rs_properties_painter.h"
23
24 namespace OHOS {
25 namespace Rosen {
26 namespace {
27 constexpr float BLUR_SIGMA_SCALE = 0.57735f;
28 // material blur style params
29 struct MaterialParam {
30 float radius;
31 float saturation;
32 SkColor maskColor;
33 };
34 // style to MaterialParam map
35 std::unordered_map<MATERIAL_BLUR_STYLE, MaterialParam> materialParams_ {
36 // card blur params
37 { STYLE_CARD_THIN_LIGHT, { 75.0f, 1.22, 0x6BF0F0F0 } },
38 { STYLE_CARD_LIGHT, { 50.0f, 1.8, 0x99FAFAFA } },
39 { STYLE_CARD_THICK_LIGHT, { 75.0f, 2.4, 0xB8FAFAFA } },
40 { STYLE_CARD_THIN_DARK, { 75.0f, 1.35, 0x6B1A1A1A } },
41 { STYLE_CARD_DARK, { 50.0f, 2.15, 0xD11F1F1F } },
42 { STYLE_CARD_THICK_DARK, { 75.0f, 2.15, 0xD11F1F1F } },
43 // background blur params
44 { STYLE_BACKGROUND_SMALL_LIGHT, { 15.0f, 1.2, 0x4C666666 } },
45 { STYLE_BACKGROUND_MEDIUM_LIGHT, { 55.0f, 1.5, 0x4C262626 } },
46 { STYLE_BACKGROUND_LARGE_LIGHT, { 75.0f, 1.5, 0x4D262626 } },
47 { STYLE_BACKGROUND_XLARGE_LIGHT, { 120.0f, 1.3, 0x4C666666 } },
48 { STYLE_BACKGROUND_SMALL_DARK, { 15.0f, 1.1, 0x800D0D0D } },
49 { STYLE_BACKGROUND_MEDIUM_DARK, { 55.0f, 1.15, 0x800D0D0D } },
50 { STYLE_BACKGROUND_LARGE_DARK, { 75.0f, 1.5, 0x800D0D0D } },
51 { STYLE_BACKGROUND_XLARGE_DARK, { 130.0f, 1.3, 0x800D0D0D } },
52 };
53 } // namespace
54
RSMaterialFilter(int style,float dipScale,BLUR_COLOR_MODE mode)55 RSMaterialFilter::RSMaterialFilter(int style, float dipScale, BLUR_COLOR_MODE mode)
56 : RSSkiaFilter(RSMaterialFilter::CreateMaterialStyle(static_cast<MATERIAL_BLUR_STYLE>(style), dipScale)),
57 dipScale_(dipScale), style_(static_cast<MATERIAL_BLUR_STYLE>(style)), colorMode_(mode)
58 {
59 type_ = FilterType::MATERIAL;
60 }
61
62 RSMaterialFilter::~RSMaterialFilter() = default;
63
RadiusVp2Sigma(float radiusVp,float dipScale)64 float RSMaterialFilter::RadiusVp2Sigma(float radiusVp, float dipScale)
65 {
66 float radiusPx = radiusVp * dipScale;
67 return radiusPx > 0.0f ? BLUR_SIGMA_SCALE * radiusPx + SK_ScalarHalf : 0.0f;
68 }
69
CreateMaterialFilter(float radius,float sat,SkColor maskColor)70 sk_sp<SkImageFilter> RSMaterialFilter::CreateMaterialFilter(float radius, float sat, SkColor maskColor)
71 {
72 maskColor_ = maskColor;
73 sk_sp<SkImageFilter> blurFilter = SkBlurImageFilter::Make(radius, radius, nullptr, nullptr,
74 SkBlurImageFilter::kClamp_TileMode); // blur
75 SkColorMatrix cm;
76 cm.setSaturation(sat);
77 sk_sp<SkColorFilter> satFilter = SkColorFilters::Matrix(cm); // saturation
78
79 return SkImageFilters::ColorFilter(satFilter, blurFilter);
80 }
81
CreateMaterialStyle(MATERIAL_BLUR_STYLE style,float dipScale)82 sk_sp<SkImageFilter> RSMaterialFilter::CreateMaterialStyle(MATERIAL_BLUR_STYLE style, float dipScale)
83 {
84 if (materialParams_.find(style) != materialParams_.end()) {
85 MaterialParam materialParam = materialParams_[style];
86 return RSMaterialFilter::CreateMaterialFilter(RSMaterialFilter::RadiusVp2Sigma(materialParam.radius, dipScale),
87 materialParam.saturation, materialParam.maskColor);
88 }
89 // ??
90 return nullptr;
91 }
92
PreProcess(sk_sp<SkImage> imageSnapshot)93 void RSMaterialFilter::PreProcess(sk_sp<SkImage> imageSnapshot)
94 {
95 if (colorMode_ == AVERAGE && imageSnapshot != nullptr) {
96 // update maskColor while persevere alpha
97 maskColor_ = SkColorSetA(RSPropertiesPainter::CalcAverageColor(imageSnapshot), SkColorGetA(maskColor_));
98 }
99 }
100
PostProcess(RSPaintFilterCanvas & canvas)101 void RSMaterialFilter::PostProcess(RSPaintFilterCanvas& canvas)
102 {
103 SkPaint paint;
104 paint.setColor(maskColor_);
105 canvas.drawPaint(paint);
106 }
107
Add(const std::shared_ptr<RSFilter> & rhs)108 std::shared_ptr<RSFilter> RSMaterialFilter::Add(const std::shared_ptr<RSFilter>& rhs)
109 {
110 return shared_from_this();
111 }
112
Sub(const std::shared_ptr<RSFilter> & rhs)113 std::shared_ptr<RSFilter> RSMaterialFilter::Sub(const std::shared_ptr<RSFilter>& rhs)
114 {
115 return shared_from_this();
116 }
117
Multiply(float rhs)118 std::shared_ptr<RSFilter> RSMaterialFilter::Multiply(float rhs)
119 {
120 return shared_from_this();
121 }
122
Negate()123 std::shared_ptr<RSFilter> RSMaterialFilter::Negate()
124 {
125 return shared_from_this();
126 }
127 } // namespace Rosen
128 } // namespace OHOS
129