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 #ifndef RENDER_SERVICE_BASE_PIPELINE_RS_SURFACE_BUFFER_CALLBACK_MANAGER_H
17 #define RENDER_SERVICE_BASE_PIPELINE_RS_SURFACE_BUFFER_CALLBACK_MANAGER_H
18 
19 #include <functional>
20 #include <map>
21 #include <mutex>
22 #include <shared_mutex>
23 #include <utility>
24 #include <vector>
25 
26 #include "common/rs_common_def.h"
27 #include "refbase.h"
28 
29 namespace OHOS {
30 namespace Rosen {
31 
32 class RSISurfaceBufferCallback;
33 namespace Drawing {
34 struct DrawSurfaceBufferFinishCbData;
35 struct DrawSurfaceBufferAfterAcquireCbData;
36 } // namespace Drawing
37 class RSB_EXPORT RSSurfaceBufferCallbackManager {
38 public:
39     struct VSyncFuncs {
40         std::function<void()> requestNextVSync;
41         std::function<bool()> isRequestedNextVSync;
42     };
43 
44 #ifdef ROSEN_OHOS
45     using OnFinishCb = std::function<void(const Drawing::DrawSurfaceBufferFinishCbData&)>;
46     using OnAfterAcquireBufferCb = std::function<void(const Drawing::DrawSurfaceBufferAfterAcquireCbData&)>;
47 #endif
48 
49     void RegisterSurfaceBufferCallback(pid_t pid, uint64_t uid,
50         sptr<RSISurfaceBufferCallback> callback);
51     void UnregisterSurfaceBufferCallback(pid_t pid);
52     void UnregisterSurfaceBufferCallback(pid_t pid, uint64_t uid);
53 
54 #ifdef ROSEN_OHOS
55     OnFinishCb GetOnFinishCb() const;
56     OnAfterAcquireBufferCb GetOnAfterAcquireBufferCb() const;
57 #endif
58 
59     std::function<void(pid_t, uint64_t, uint32_t)> GetSurfaceBufferOpItemCallback() const;
60     void SetRunPolicy(std::function<void(std::function<void()>)> runPolicy);
61     void SetVSyncFuncs(VSyncFuncs vSyncFuncs);
62     void SetIsUniRender(bool isUniRender);
63 #ifdef RS_ENABLE_VK
64     void SetReleaseFenceForVulkan(int releaseFenceFd, NodeId rootNodeId);
65 #endif
66 
67     void RunSurfaceBufferCallback();
68 #ifdef RS_ENABLE_VK
69     void RunSurfaceBufferSubCallbackForVulkan(NodeId rootNodeId);
70 #endif
71 
72     static RSSurfaceBufferCallbackManager& Instance();
73 private:
74     static constexpr size_t ROOTNODEIDS_POS = 3;
75     struct BufferQueueData {
76         std::vector<uint32_t> bufferIds;
77         std::vector<uint8_t> isRenderedFlags;
78 #ifdef ROSEN_OHOS
79         std::vector<sptr<SyncFence>> releaseFences;
80 #endif
81         std::vector<NodeId> rootNodeIds;
82     };
83     RSSurfaceBufferCallbackManager() = default;
84     ~RSSurfaceBufferCallbackManager() noexcept = default;
85 
86     RSSurfaceBufferCallbackManager(const RSSurfaceBufferCallbackManager&) = delete;
87     RSSurfaceBufferCallbackManager(RSSurfaceBufferCallbackManager&&) = delete;
88     RSSurfaceBufferCallbackManager& operator=(const RSSurfaceBufferCallbackManager&) = delete;
89     RSSurfaceBufferCallbackManager& operator=(RSSurfaceBufferCallbackManager&&) = delete;
90 
91     sptr<RSISurfaceBufferCallback> GetSurfaceBufferCallback(pid_t pid, uint64_t uid) const;
92     size_t GetSurfaceBufferCallbackSize() const;
93 
94 #ifdef ROSEN_OHOS
95     void OnAfterAcquireBuffer(const Drawing::DrawSurfaceBufferAfterAcquireCbData& data);
96     void OnFinish(const Drawing::DrawSurfaceBufferFinishCbData& data);
97 #endif
98 
99 #ifdef ROSEN_OHOS
100     void EnqueueSurfaceBufferId(const Drawing::DrawSurfaceBufferFinishCbData& data);
101 #endif
102     void RequestNextVSync();
103 
104     static std::string SerializeBufferIdVec(const std::vector<uint32_t>& bufferIdVec);
105 
106     std::map<std::pair<pid_t, uint64_t>, sptr<RSISurfaceBufferCallback>>
107         surfaceBufferCallbacks_;
108     std::map<std::pair<pid_t, uint64_t>, BufferQueueData> stagingSurfaceBufferIds_;
109     mutable std::shared_mutex registerSurfaceBufferCallbackMutex_;
110     std::mutex surfaceBufferOpItemMutex_;
111     std::function<void(std::function<void()>)> runPolicy_ = [](auto task) {
112         std::invoke(task);
113     };
114     VSyncFuncs vSyncFuncs_;
115     bool isUniRender_ = {};
116 };
117 
118 namespace RSSurfaceBufferCallbackMgrUtil {
119 namespace Detail {
120 template<class... Iters, class UnaryPred, size_t... Is>
FindIf(std::tuple<Iters...> begin,std::tuple<Iters...> end,UnaryPred unaryPred,std::index_sequence<Is...>)121 std::tuple<Iters...> FindIf(std::tuple<Iters...> begin, std::tuple<Iters...> end,
122     UnaryPred unaryPred, std::index_sequence<Is...>)
123 {
124     for (; begin != end; (++std::get<Is>(begin), ...)) {
125         if (unaryPred(begin)) {
126             return begin;
127         }
128     }
129     return end;
130 }
131 
132 template<class... Iters, class UnaryPred, size_t... Is>
RemoveIf(std::tuple<Iters...> begin,std::tuple<Iters...> end,UnaryPred unaryPred,std::index_sequence<Is...>)133 std::tuple<Iters...> RemoveIf(std::tuple<Iters...> begin, std::tuple<Iters...> end,
134     UnaryPred unaryPred, std::index_sequence<Is...>)
135 {
136     begin = Detail::FindIf(begin, end, unaryPred, std::make_index_sequence<sizeof...(Iters)>());
137     if (begin != end) {
138         for (auto i = begin; i != end; (++std::get<Is>(i), ...)) {
139             if (!unaryPred(i)) {
140                 ((*(std::get<Is>(begin)++) = std::move(*std::get<Is>(i))), ...);
141             }
142         }
143     }
144     return begin;
145 }
146 
147 template <class... InputIters, class... OutPutIters, class UnaryPred, size_t... Is>
CopyIf(std::tuple<InputIters...> inputBegin,std::tuple<InputIters...> inputEnd,std::tuple<OutPutIters...> outputBegin,UnaryPred unaryPred,std::index_sequence<Is...>)148 std::tuple<OutPutIters...> CopyIf(std::tuple<InputIters...> inputBegin,
149     std::tuple<InputIters...> inputEnd, std::tuple<OutPutIters...> outputBegin, UnaryPred unaryPred,
150     std::index_sequence<Is...>)
151 {
152     for (; inputBegin != inputEnd; (++std::get<Is>(inputBegin), ...)) {
153         if (unaryPred(inputBegin))
154         {
155             ((*std::get<Is>(outputBegin) = *std::get<Is>(inputBegin)), ...);
156             (++std::get<Is>(outputBegin), ...);
157         }
158     }
159     return outputBegin;
160 }
161 } // namespace Detail
162 
163 template<class... Iters, class UnaryPred>
FindIf(std::tuple<Iters...> begin,std::tuple<Iters...> end,UnaryPred unaryPred)164 std::tuple<Iters...> FindIf(std::tuple<Iters...> begin,
165     std::tuple<Iters...> end, UnaryPred unaryPred)
166 {
167     return Detail::FindIf(begin, end, unaryPred, std::make_index_sequence<sizeof...(Iters)>());
168 }
169 
170 template<class... Iters, class UnaryPred>
RemoveIf(std::tuple<Iters...> begin,std::tuple<Iters...> end,UnaryPred unaryPred)171 std::tuple<Iters...> RemoveIf(std::tuple<Iters...> begin,
172     std::tuple<Iters...> end, UnaryPred unaryPred)
173 {
174     return Detail::RemoveIf(begin, end, unaryPred, std::make_index_sequence<sizeof...(Iters)>());
175 }
176 
177 template<class... InputIters, class... OutPutIters, class UnaryPred>
CopyIf(std::tuple<InputIters...> inputBegin,std::tuple<InputIters...> inputEnd,std::tuple<OutPutIters...> outputBegin,UnaryPred unaryPred)178 std::tuple<OutPutIters...> CopyIf(std::tuple<InputIters...> inputBegin,
179     std::tuple<InputIters...> inputEnd, std::tuple<OutPutIters...> outputBegin, UnaryPred unaryPred)
180 {
181     static_assert(sizeof...(InputIters) == sizeof...(OutPutIters));
182     return Detail::CopyIf(inputBegin, inputEnd, outputBegin, unaryPred,
183         std::make_index_sequence<sizeof...(InputIters)>());
184 }
185 } // namespace RSSurfaceBufferCallbackMgrUtil
186 } // namespace Rosen
187 } // namespace OHOS
188 
189 #endif // RENDER_SERVICE_BASE_PIPELINE_RS_SURFACE_BUFFER_CALLBACK_MANAGER_H
190