• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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