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 
16 #include <chrono>
17 
18 #include "ge_log.h"
19 #include "ge_water_ripple_filter.h"
20 
21 namespace OHOS {
22 namespace Rosen {
23 // Advanced Filter
24 #define PROPERTY_HIGPU_VERSION "const.gpu.vendor"
25 #define PROPERTY_DEBUG_SUPPORT_AF "persist.sys.graphic.supports_af"
26 namespace {
27 
28 const int SMALL2MEDIUM_RECV = 0;
29 const int SMALL2MEDIUM_SEND = 1;
30 const int SMALL2SMALL = 2;
31 
32 } // namespace
33 
34 
GEWaterRippleFilter(const Drawing::GEWaterRippleFilterParams & params)35 GEWaterRippleFilter::GEWaterRippleFilter(const Drawing::GEWaterRippleFilterParams& params)
36     : progress_(params.progress), waveCount_(params.waveCount), rippleCenterX_(params.rippleCenterX),
37     rippleCenterY_(params.rippleCenterY), rippleMode_(params.rippleMode)
38 {}
39 
ProcessImage(Drawing::Canvas & canvas,const std::shared_ptr<Drawing::Image> image,const Drawing::Rect & src,const Drawing::Rect & dst)40 std::shared_ptr<Drawing::Image> GEWaterRippleFilter::ProcessImage(Drawing::Canvas& canvas,
41     const std::shared_ptr<Drawing::Image> image, const Drawing::Rect& src, const Drawing::Rect& dst)
42 {
43     if (image == nullptr) {
44         LOGE("GEWaterRippleFilter::ProcessImage input is invalid");
45         return nullptr;
46     }
47 
48     Drawing::Matrix matrix;
49     auto shader = Drawing::ShaderEffect::CreateImageShader(*image, Drawing::TileMode::CLAMP,
50         Drawing::TileMode::CLAMP, Drawing::SamplingOptions(Drawing::FilterMode::LINEAR), matrix);
51     auto imageInfo = image->GetImageInfo();
52     float height = imageInfo.GetHeight();
53     float width = imageInfo.GetWidth();
54     std::shared_ptr<Drawing::RuntimeEffect> waterRipple;
55     switch (rippleMode_) {
56         case SMALL2MEDIUM_RECV: {
57             waterRipple = GetWaterRippleEffectSM(SMALL2MEDIUM_RECV);
58             break;
59         }
60         case SMALL2MEDIUM_SEND: {
61             waterRipple = GetWaterRippleEffectSM(SMALL2MEDIUM_SEND);
62             break;
63         }
64         case SMALL2SMALL: {
65             waterRipple = GetWaterRippleEffectSS();
66             break;
67         }
68         default: {
69             LOGE("GEWaterRippleFilter::ProcessImage: Not support current ripple mode");
70             return nullptr;
71         }
72     }
73     if (waterRipple == nullptr) {
74         LOGE("GEWaterRippleFilter::ProcessImage g_waterRippleEffect init failed");
75         return nullptr;
76     }
77     Drawing::RuntimeShaderBuilder builder(waterRipple);
78     builder.SetChild("image", shader);
79     builder.SetUniform("iResolution", width, height);
80     builder.SetUniform("progress", progress_);
81     builder.SetUniform("waveCount", static_cast<float>(waveCount_));
82     builder.SetUniform("rippleCenter", rippleCenterX_, rippleCenterY_);
83 
84     auto invertedImage = builder.MakeImage(canvas.GetGPUContext().get(), nullptr, imageInfo, false);
85     if (invertedImage == nullptr) {
86         LOGE("GEWaterRippleFilter::ProcessImage make image failed");
87         return nullptr;
88     }
89     return invertedImage;
90 }
91 
GetWaterRippleEffectSM(const int rippleMode)92 std::shared_ptr<Drawing::RuntimeEffect> GEWaterRippleFilter::GetWaterRippleEffectSM(const int rippleMode)
93 {
94     static std::shared_ptr<Drawing::RuntimeEffect> g_waterRippleEffectSM = nullptr;
95     if (g_waterRippleEffectSM == nullptr) {
96         g_waterRippleEffectSM = (rippleMode == SMALL2MEDIUM_SEND) ?
97             Drawing::RuntimeEffect::CreateForShader(shaderStringSMsend) :
98             Drawing::RuntimeEffect::CreateForShader(shaderStringSMrecv);
99     }
100     return g_waterRippleEffectSM;
101 }
102 
GetWaterRippleEffectSS()103 std::shared_ptr<Drawing::RuntimeEffect> GEWaterRippleFilter::GetWaterRippleEffectSS()
104 {
105     static std::shared_ptr<Drawing::RuntimeEffect> g_waterRippleEffectSS = nullptr;
106     if (g_waterRippleEffectSS == nullptr) {
107         g_waterRippleEffectSS = Drawing::RuntimeEffect::CreateForShader(shaderStringSSmutual);
108     }
109     return g_waterRippleEffectSS;
110 }
111 
112 } // namespace Rosen
113 } // namespace OHOS