1 /*
2  * Copyright (c) 2023-2023 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_COMMON_RS_OCCLUSION_REGION_HELPER_H
16 #define RENDER_SERVICE_BASE_CORE_COMMON_RS_OCCLUSION_REGION_HELPER_H
17 
18 #include <limits.h>
19 #include "common/rs_occlusion_region.h"
20 namespace OHOS {
21 namespace Rosen {
22 namespace Occlusion {
23 
24 enum RectType {
25     LHS_ONLY = 1,       // 001
26     LHS_RHS_BOTH = 2,   // 010
27     RHS_ONLY = 4        // 100
28 };
29 
30 class RectsPtr {
31 public:
32     std::vector<Rect>::const_iterator rects_;
33     size_t count_ = 0;
RectsPtr(const RectsPtr & rhs)34     inline RectsPtr(const RectsPtr &rhs) : rects_(rhs.rects_), count_(rhs.count_) {}
RectsPtr(const std::vector<Rect>::const_iterator & r,size_t c)35     inline RectsPtr(const std::vector<Rect>::const_iterator &r, size_t c) : rects_(r), count_(c) {}
~RectsPtr()36     ~RectsPtr() {}
37 };
38 class Assembler {
39 public:
Assembler(Region & r)40     explicit Assembler(Region &r)
41         : storage_(r.GetRegionRectsRef()), bound_(r.GetBoundRef()), lastRectRowBegin_(), end_(), cur_()
42     {
43         storage_.clear();
44         bound_ = Rect{INT_MAX, INT_MAX, INT_MIN, INT_MIN, false};
45     }
46     void Insert(const Rect &r); // insert a Rect into span
47     void FlushVerticalSpan();
48     bool CurrentSpanCanMerge() const;
49     void MergeSpanVertically();
50     ~Assembler();
51 private:
52     std::vector<Rect> &storage_;            // current all rects storage
53     Rect &bound_;                           // current bound
54     std::vector<Rect> rectsRow_;            // current span rects; will be dumped into storage every otter loop
55     std::vector<Rect>::iterator lastRectRowBegin_;
56     std::vector<Rect>::iterator end_;
57     std::vector<Rect>::iterator cur_;
58 };
59 class Looper {
60 public:
61     int lhsStart_ = INT_MAX;
62     int lhsEnd_ = INT_MAX;
63     int rhsStart_ = INT_MAX;
64     int rhsEnd_ = INT_MAX;
65 
Looper()66     Looper() : lhsStart_(INT_MAX), lhsEnd_(INT_MAX), rhsStart_(INT_MAX), rhsEnd_(INT_MAX) {}
~Looper()67     virtual ~Looper() {}
68     inline RectType GetEdgeRelation(int &head, int &tail, bool &more_lhs, bool &more_rhs);
69 };
70 class OuterLooper : protected Looper {
71 public:
72     RectsPtr lhs_;
73     RectsPtr rhs_;
OuterLooper(const RectsPtr & lhs,const RectsPtr & rhs)74     inline OuterLooper(const RectsPtr &lhs, const RectsPtr &rhs) : lhs_(lhs), rhs_(rhs)
75     {
76         if (lhs_.count_) {
77             Looper::lhsStart_ = lhs_.rects_->top_;
78             Looper::lhsEnd_ = lhs_.rects_->bottom_;
79         }
80         if (rhs_.count_) {
81             Looper::rhsStart_ = rhs_.rects_->top_;
82             Looper::rhsEnd_ = rhs_.rects_->bottom_;
83         }
84     }
~OuterLooper()85     ~OuterLooper() {}
86     RectType NextScanline(int &curTop, int &curBottom);
87     inline void MoveScanline(bool moreLhs, bool moreRhs);
88     void MoveScanline(RectsPtr &r, int &top, int &bottom);
isDone()89     inline bool isDone() const
90     {
91         return lhs_.count_ == 0 && rhs_.count_ == 0;
92     }
93 };
94 class InnerLooper : protected Looper {
95 public:
96     RectsPtr lhs_;
97     RectsPtr rhs_;
InnerLooper(const RectsPtr & lhs,const RectsPtr & rhs)98     inline InnerLooper(const RectsPtr &lhs, const RectsPtr &rhs)
99         : lhs_(lhs), rhs_(rhs) {}
InnerLooper(const OuterLooper & outer)100     InnerLooper(const OuterLooper &outer) : lhs_(outer.lhs_), rhs_(outer.rhs_) {}
~InnerLooper()101     ~InnerLooper() {}
102     void Init(RectType relationship);
103     RectType NextRect(int &curLeft, int &curRight);
104     inline void MoveRect(bool moreLhs, bool moreRhs);
105     void MoveRect(RectsPtr &r, int &left, int &right);
IsDone()106     inline bool IsDone() const
107     {
108         return lhsStart_ == INT_MAX && rhsStart_ == INT_MAX;
109     }
110 };
111 }
112 }
113 }
114 #endif //RENDER_SERVICE_BASE_CORE_COMMON_RS_OCCLUSION_REGION_HELPER_H