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_colorful_shadow_filter.h"
16
17 #include "common/rs_common_def.h"
18 #include "common/rs_optional_trace.h"
19 #include "draw/surface.h"
20 #include "platform/common/rs_log.h"
21 #ifdef USE_M133_SKIA
22 #include "src/core/SkChecksum.h"
23 #else
24 #include "src/core/SkOpts.h"
25 #endif
26
27 namespace OHOS {
28 namespace Rosen {
RSColorfulShadowFilter(float blurRadius,float offsetX,float offsetY)29 RSColorfulShadowFilter::RSColorfulShadowFilter(float blurRadius, float offsetX, float offsetY)
30 : RSForegroundEffectFilter(blurRadius), blurRadius_(blurRadius), offsetX_(offsetX), offsetY_(offsetY)
31 {
32 type_ = FilterType::COLORFUL_SHADOW;
33 #ifdef USE_M133_SKIA
34 const auto hashFunc = SkChecksum::Hash32;
35 #else
36 const auto hashFunc = SkOpts::hash;
37 #endif
38 hash_ = hashFunc(&type_, sizeof(type_), 0);
39 }
40
GetDescription()41 std::string RSColorfulShadowFilter::GetDescription()
42 {
43 return "RSColorfulShadowFilter " + std::to_string(blurRadius_);
44 }
45
IsValid() const46 bool RSColorfulShadowFilter::IsValid() const
47 {
48 constexpr float epsilon = 0.999f; // if blur radius less than 1, do not need to draw
49 return blurRadius_ > epsilon;
50 }
51
SetShadowColorMask(Color color)52 void RSColorfulShadowFilter::SetShadowColorMask(Color color)
53 {
54 isColorMask_ = true;
55 color_ = color;
56 }
57
DrawImageRectWithColor(Drawing::Canvas & canvas,const std::shared_ptr<Drawing::Image> & image) const58 std::shared_ptr<Drawing::Image> RSColorfulShadowFilter::DrawImageRectWithColor(Drawing::Canvas &canvas,
59 const std::shared_ptr<Drawing::Image> &image) const
60 {
61 bool isInvalid = !image || image->GetWidth() == 0 || image->GetHeight() == 0;
62 if (isInvalid) {
63 ROSEN_LOGE("RSColorfulShadowFilter::DrawImageRect error");
64 return nullptr;
65 }
66
67 RS_OPTIONAL_TRACE_NAME("ApplyShadowColorFilter");
68 std::shared_ptr<Drawing::Surface> surface = Drawing::Surface::MakeRenderTarget(canvas.GetGPUContext().get(),
69 false, image->GetImageInfo());
70 if (!surface) {
71 ROSEN_LOGE("Null surface");
72 return nullptr;
73 }
74
75 Drawing::Brush brush;
76 Drawing::Filter filter;
77 filter.SetColorFilter(Drawing::ColorFilter::CreateBlendModeColorFilter(color_.AsArgbInt(),
78 Drawing::BlendMode::SRC_IN));
79 brush.SetFilter(filter);
80 auto canvas1 = surface->GetCanvas();
81 if (canvas1 == nullptr) {
82 return nullptr;
83 }
84 auto samplingOptions = Drawing::SamplingOptions(Drawing::FilterMode::LINEAR, Drawing::MipmapMode::LINEAR);
85 canvas1->AttachBrush(brush);
86 canvas1->DrawImage(*image, 0.f, 0.f, samplingOptions);
87 canvas1->DetachBrush();
88 return surface->GetImageSnapshot();
89 }
90
DrawImageRect(Drawing::Canvas & canvas,const std::shared_ptr<Drawing::Image> & image,const Drawing::Rect & src,const Drawing::Rect & dst) const91 void RSColorfulShadowFilter::DrawImageRect(Drawing::Canvas &canvas, const std::shared_ptr<Drawing::Image> &image,
92 const Drawing::Rect &src, const Drawing::Rect &dst) const
93 {
94 if (image == nullptr) {
95 ROSEN_LOGE("RSColorfulShadowFilter::DrawImageRect error");
96 return;
97 }
98
99 if (IsValid()) {
100 // draw blur image
101 canvas.Translate(offsetX_, offsetY_);
102 std::shared_ptr<Drawing::Image> imageTemp = image;
103 if (isColorMask_) {
104 imageTemp = DrawImageRectWithColor(canvas, image);
105 imageTemp = imageTemp == nullptr ? image : imageTemp;
106 }
107 RSForegroundEffectFilter::DrawImageRect(canvas, imageTemp, src, dst);
108 canvas.Translate(-offsetX_, -offsetY_);
109 }
110
111 // draw clear image
112 auto samplingOptions = Drawing::SamplingOptions(Drawing::FilterMode::LINEAR, Drawing::MipmapMode::LINEAR);
113 canvas.DrawImage(*image, 0.f, 0.f, samplingOptions);
114 }
115 } // namespace Rosen
116 } // namespace OHOS
117