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