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_render_maskcolor_filter.h"
16 #ifdef USE_M133_SKIA
17 #include "include/core/SkColor.h"
18 #include "src/core/SkChecksum.h"
19 #else
20 #include "src/core/SkOpts.h"
21 #endif
22
23 namespace OHOS {
24 namespace Rosen {
25
26 constexpr float MAX_ALPHA = 255.0f;
27
RSMaskColorShaderFilter(int colorMode,RSColor maskColor)28 RSMaskColorShaderFilter::RSMaskColorShaderFilter(int colorMode, RSColor maskColor)
29 : RSRenderFilterParaBase(RSUIFilterType::MASK_COLOR), colorMode_(colorMode), maskColor_(maskColor)
30 {
31 #ifdef USE_M133_SKIA
32 const auto hashFunc = SkChecksum::Hash32;
33 #else
34 const auto hashFunc = SkOpts::hash;
35 #endif
36 hash_ = hashFunc(&type_, sizeof(type_), 0);
37 hash_ = hashFunc(&colorMode_, sizeof(colorMode_), hash_);
38 hash_ = hashFunc(&maskColor_, sizeof(maskColor_), hash_);
39 }
40
41 RSMaskColorShaderFilter::~RSMaskColorShaderFilter() = default;
42
GetColorMode() const43 int RSMaskColorShaderFilter::GetColorMode() const
44 {
45 return colorMode_;
46 }
47
GetMaskColor() const48 RSColor RSMaskColorShaderFilter::GetMaskColor() const
49 {
50 return maskColor_;
51 }
52
NeedForceSubmit() const53 bool RSMaskColorShaderFilter::NeedForceSubmit() const
54 {
55 return colorMode_ == AVERAGE;
56 }
57
CalcAverageColor(std::shared_ptr<Drawing::Image> image)58 Drawing::ColorQuad RSMaskColorShaderFilter::CalcAverageColor(std::shared_ptr<Drawing::Image> image)
59 {
60 // create a 1x1 SkPixmap
61 uint32_t pixel[1] = { 0 };
62 Drawing::ImageInfo single_pixel_info(1, 1, Drawing::ColorType::COLORTYPE_RGBA_8888,
63 Drawing::AlphaType::ALPHATYPE_PREMUL);
64 Drawing::Bitmap single_pixel;
65 single_pixel.Build(single_pixel_info, single_pixel_info.GetBytesPerPixel());
66 single_pixel.SetPixels(pixel);
67
68 // resize snapshot to 1x1 to calculate average color
69 // kMedium_SkFilterQuality will do bilerp + mipmaps for down-scaling, we can easily get average color
70 image->ScalePixels(single_pixel,
71 Drawing::SamplingOptions(Drawing::FilterMode::LINEAR, Drawing::MipmapMode::LINEAR));
72 // convert color format and return average color
73 return SkColor4f::FromBytes_RGBA(pixel[0]).toSkColor();
74 }
75
CaclMaskColor(std::shared_ptr<Drawing::Image> & image)76 void RSMaskColorShaderFilter::CaclMaskColor(std::shared_ptr<Drawing::Image>& image)
77 {
78 if (colorMode_ == AVERAGE && image != nullptr) {
79 // update maskColor while persevere alpha
80 auto colorPicker = CalcAverageColor(image);
81 maskColor_ = RSColor(Drawing::Color::ColorQuadGetR(colorPicker), Drawing::Color::ColorQuadGetG(colorPicker),
82 Drawing::Color::ColorQuadGetB(colorPicker), maskColor_.GetAlpha());
83 }
84 }
85
PreProcess(std::shared_ptr<Drawing::Image> & image)86 void RSMaskColorShaderFilter::PreProcess(std::shared_ptr<Drawing::Image>& image)
87 {
88 CaclMaskColor(image);
89 }
90
PostProcess(Drawing::Canvas & canvas)91 void RSMaskColorShaderFilter::PostProcess(Drawing::Canvas& canvas)
92 {
93 Drawing::Brush brush;
94 brush.SetColor(maskColor_.AsArgbInt());
95
96 canvas.DrawBackground(brush);
97 }
98
GetPostProcessAlpha() const99 float RSMaskColorShaderFilter::GetPostProcessAlpha() const
100 {
101 float rawAlpha = static_cast<float>(maskColor_.GetAlpha());
102 return (rawAlpha / MAX_ALPHA);
103 }
104 } // namespace Rosen
105 } // namespace OHOS
106