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 #ifndef RENDER_SERVICE_BASE_CORE_RENDER_RS_ATTRACTION_EFFECT_FILTER_H
16 #define RENDER_SERVICE_BASE_CORE_RENDER_RS_ATTRACTION_EFFECT_FILTER_H
17 
18 #include <memory>
19 
20 #include "common/rs_rect.h"
21 #include "effect/runtime_effect.h"
22 #include "effect/runtime_shader_builder.h"
23 #include "render/rs_skia_filter.h"
24 
25 namespace OHOS {
26 namespace Rosen {
27 // Number of deformation control points of the window
28 constexpr int32_t POINT_NUM = 12;
29 
30 // 0 to 11 indicate the index of the window control point, which is rotated clockwise.
31 constexpr int TOP_LEFT_INDEX        = 0;
32 constexpr int TOP_ONE_THIRD         = 1;
33 constexpr int TOP_TWO_THIRDS        = 2;
34 constexpr int TOP_RIGHT_INDEX       = 3;
35 constexpr int RIGHT_ONE_THIRD       = 4;
36 constexpr int RIGHT_TWO_THIRDS      = 5;
37 constexpr int BOTTOM_RIGHT_INDEX    = 6;
38 constexpr int BOTTOM_TWO_THIRDS     = 7;
39 constexpr int BOTTOM_ONE_THIRD      = 8;
40 constexpr int BOTTOM_LEFT_INDEX     = 9;
41 constexpr int LEFT_TWO_THIRDS       = 10;
42 constexpr int LEFT_ONE_THIRD        = 11;
43 
44 class RSB_EXPORT RSAttractionEffectFilter : public RSDrawingFilterOriginal {
45 public:
46     RSAttractionEffectFilter(float attractionFraction);
47     RSAttractionEffectFilter(const RSAttractionEffectFilter&) = delete;
48     RSAttractionEffectFilter operator=(const RSAttractionEffectFilter&) = delete;
49     ~RSAttractionEffectFilter() override;
50 
51     bool IsValid() const override;
52     std::string GetDescription() override;
53     Drawing::Brush GetBrush(const std::shared_ptr<Drawing::Image>& image) const;
54     void DrawImageRect(Drawing::Canvas& canvas, const std::shared_ptr<Drawing::Image>& image,
55         const Drawing::Rect& src, const Drawing::Rect& dst) const override;
PreProcess(std::shared_ptr<Drawing::Image> image)56     void PreProcess(std::shared_ptr<Drawing::Image> image) override {};
PostProcess(Drawing::Canvas & canvas)57     void PostProcess(Drawing::Canvas& canvas) override {};
58     float GetAttractionFraction() const;
59     void UpdateDirtyRegion(float leftPoint, float topPonit);
60     RectI GetAttractionDirtyRegion() const;
61 
Compose(const std::shared_ptr<RSDrawingFilterOriginal> & other)62     std::shared_ptr<RSDrawingFilterOriginal> Compose(
63         const std::shared_ptr<RSDrawingFilterOriginal>& other) const override
64     {
65         return nullptr;
66     }
67 
68     void CalculateWindowStatus(float canvasWidth, float canvasHeight, Vector2f& destinationPoint);
69     void InitWindowInitCtrlPoints();
70     void CalculateDeltaXAndDeltaY(const Drawing::Point &pointDst, float &deltaX, float &deltaY, int direction);
71     void CalculateBezierVelList(const std::vector<Drawing::Point> &velocityList,
72         std::vector<Drawing::Point> &velocityCtrl, int direction);
73     float CalculateCubic(float p1, float p2, float t);
74     bool IsWithinThreshold(const float left, const float right, const float threshold);
75     float BinarySearch(float targetX, const Drawing::Point &p1, const Drawing::Point &p2);
76 
77     std::vector<Drawing::Point> CalculateCubicsCtrlPointOffset(const std::vector<Drawing::Point> controlPointOfVertex);
78     std::vector<int> CreateIndexSequence(int direction);
79     std::vector<Drawing::Point> CalculateCubicsCtrlPoint(std::vector<Drawing::Point> controlPointOfVertex,
80         const Drawing::Point points[], int direction, bool isFirstCtrl);
81 
82     Drawing::Point LerpPoint(const Drawing::Point& firstPoint, const Drawing::Point& secondPoint,
83         float firstFactor, float secondFactor);
84     Drawing::Point CubicBezier(const Drawing::Point &p0, const Drawing::Point &p1, const Drawing::Point &p2,
85         const Drawing::Point &p3, float t);
86 
87     void CalculateVelocityCtrlPointUpper(std::vector<Drawing::Point>& velocityCtrlPointUpper);
88     void CalculateVelocityCtrlPointLower(std::vector<Drawing::Point>& velocityCtrlPointLower);
89     std::vector<Drawing::Point> CalculateUpperCtrlPointOfVertex(float deltaX, float deltaY, float width, float height,
90         int direction);
91     std::vector<Drawing::Point> CalculateLowerCtrlPointOfVertex(float deltaX, float deltaY, float width, float height,
92         int direction);
93 
94 private:
95     float attractionFraction_ = 0.0f;
96     float canvasWidth_ = 0.0f;
97     float canvasHeight_ = 0.0f;
98     Drawing::Point windowCtrlPoints_[12] = {
99         {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f},
100         {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}
101     };
102     Drawing::Point windowStatusPoints_[12] = {
103         {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f},
104         {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}
105     };
106     RectI attractionDirtyRegion_ = {0, 0, 0, 0};
107     bool isBelowTarget_ = false;
108 
109     friend class RSMarshallingHelper;
110 };
111 } // namespace Rosen
112 } // namespace OHOS
113 
114 #endif // RENDER_SERVICE_BASE_CORE_RENDER_RS_ATTRACTION_EFFECT_FILTER_H