• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "ipc_callbacks/rs_surface_buffer_callback.h"
17 #include "pipeline/rs_surface_buffer_callback_manager.h"
18 #include "platform/common/rs_log.h"
19 
20 namespace OHOS {
21 namespace Rosen {
Instance()22 RSSurfaceBufferCallbackManager& RSSurfaceBufferCallbackManager::Instance()
23 {
24     static RSSurfaceBufferCallbackManager surfaceBufferCallbackMgr;
25     return surfaceBufferCallbackMgr;
26 }
27 
SetRunPolicy(std::function<void (std::function<void ()>)> runPolicy)28 void RSSurfaceBufferCallbackManager::SetRunPolicy(std::function<void(std::function<void()>)> runPolicy)
29 {
30     runPolicy_ = runPolicy;
31 }
32 
RegisterSurfaceBufferCallback(pid_t pid,uint64_t uid,sptr<RSISurfaceBufferCallback> callback)33 void RSSurfaceBufferCallbackManager::RegisterSurfaceBufferCallback(pid_t pid, uint64_t uid,
34     sptr<RSISurfaceBufferCallback> callback)
35 {
36     std::unique_lock<std::shared_mutex> lock { registerSurfaceBufferCallbackMutex_ };
37     auto iter = surfaceBufferCallbacks_.find({pid, uid});
38     if (iter == std::end(surfaceBufferCallbacks_)) {
39         surfaceBufferCallbacks_.insert({{pid, uid}, callback});
40     } else {
41         RS_LOGE("RSSurfaceBufferCallbackManager::RegisterSurfaceBufferCallback Pair:"
42             "[Pid: %{public}s, Uid: %{public}s] exists.",
43             std::to_string(pid).c_str(), std::to_string(uid).c_str());
44     }
45 }
46 
UnregisterSurfaceBufferCallback(pid_t pid)47 void RSSurfaceBufferCallbackManager::UnregisterSurfaceBufferCallback(pid_t pid)
48 {
49     std::unique_lock<std::shared_mutex> lock { registerSurfaceBufferCallbackMutex_ };
50     EraseIf(surfaceBufferCallbacks_, [pid](auto& pair) {
51         return pair.first.first == pid;
52     });
53 }
54 
UnregisterSurfaceBufferCallback(pid_t pid,uint64_t uid)55 void RSSurfaceBufferCallbackManager::UnregisterSurfaceBufferCallback(pid_t pid, uint64_t uid)
56 {
57     std::unique_lock<std::shared_mutex> lock { registerSurfaceBufferCallbackMutex_ };
58     auto iter = surfaceBufferCallbacks_.find({pid, uid});
59     if (iter == std::end(surfaceBufferCallbacks_)) {
60         RS_LOGE("RSSurfaceBufferCallbackManager::UnregisterSurfaceBufferCallback Pair:"
61             "[Pid: %{public}s, Uid: %{public}s] not exists.",
62             std::to_string(pid).c_str(), std::to_string(uid).c_str());
63     } else {
64         surfaceBufferCallbacks_.erase(iter);
65     }
66 }
67 
GetSurfaceBufferOpItemCallback() const68 std::function<void(pid_t, uint64_t, uint32_t)> RSSurfaceBufferCallbackManager::GetSurfaceBufferOpItemCallback() const
69 {
70     auto mutablePtr = const_cast<RSSurfaceBufferCallbackManager*>(this);
71     return [mutablePtr](pid_t pid, uint64_t uid, uint32_t surfaceBufferId) {
72         mutablePtr->OnSurfaceBufferOpItemDestruct(pid, uid, surfaceBufferId);
73     };
74 }
75 
GetSurfaceBufferCallback(pid_t pid,uint64_t uid) const76 sptr<RSISurfaceBufferCallback> RSSurfaceBufferCallbackManager::GetSurfaceBufferCallback(
77     pid_t pid, uint64_t uid) const
78 {
79     std::shared_lock<std::shared_mutex> lock { registerSurfaceBufferCallbackMutex_ };
80     auto iter = surfaceBufferCallbacks_.find({pid, uid});
81     if (iter == std::cend(surfaceBufferCallbacks_)) {
82         RS_LOGE("RSSurfaceBufferCallbackManager::GetSurfaceBufferCallback Pair:"
83             "[Pid: %{public}s, Uid: %{public}s] not exists.",
84             std::to_string(pid).c_str(), std::to_string(uid).c_str());
85         return nullptr;
86     }
87     return iter->second;
88 }
89 
GetSurfaceBufferCallbackSize() const90 size_t RSSurfaceBufferCallbackManager::GetSurfaceBufferCallbackSize() const
91 {
92     std::shared_lock<std::shared_mutex> lock { registerSurfaceBufferCallbackMutex_ };
93     return surfaceBufferCallbacks_.size();
94 }
95 
EnqueueSurfaceBufferId(pid_t pid,uint64_t uid,uint32_t surfaceBufferId)96 void RSSurfaceBufferCallbackManager::EnqueueSurfaceBufferId(pid_t pid, uint64_t uid, uint32_t surfaceBufferId)
97 {
98     auto iter = stagingSurfaceBufferIds_.find({pid, uid});
99     if (iter == std::end(stagingSurfaceBufferIds_)) {
100         std::tie(iter, std::ignore) = stagingSurfaceBufferIds_.insert({{pid, uid}, {}});
101     }
102     iter->second.push_back(surfaceBufferId);
103 }
104 
OnSurfaceBufferOpItemDestruct(pid_t pid,uint64_t uid,uint32_t surfaceBufferId)105 void RSSurfaceBufferCallbackManager::OnSurfaceBufferOpItemDestruct(
106     pid_t pid, uint64_t uid, uint32_t surfaceBufferId)
107 {
108     std::lock_guard<std::mutex> lock { surfaceBufferOpItemMutex_ };
109     if (surfaceBufferCallbacks_.find({pid, uid}) == std::end(surfaceBufferCallbacks_)) {
110         RS_LOGE("RSSurfaceBufferCallbackManager::OnSurfaceBufferOpItemDestruct Pair:"
111             "[Pid: %{public}s, Uid: %{public}s] Callback not exists.",
112             std::to_string(pid).c_str(), std::to_string(uid).c_str());
113         return;
114     }
115     EnqueueSurfaceBufferId(pid, uid, surfaceBufferId);
116 }
117 
RunSurfaceBufferCallback()118 void RSSurfaceBufferCallbackManager::RunSurfaceBufferCallback()
119 {
120     runPolicy_([this]() {
121         if (GetSurfaceBufferCallbackSize() == 0) {
122             return;
123         }
124         std::map<std::pair<pid_t, uint64_t>, std::vector<uint32_t>> surfaceBufferIds;
125         {
126             std::lock_guard<std::mutex> lock { surfaceBufferOpItemMutex_ };
127             surfaceBufferIds.swap(stagingSurfaceBufferIds_);
128         }
129         for (auto& [code, bufferIds] : surfaceBufferIds) {
130             auto [pid, uid] = code;
131             auto callback = GetSurfaceBufferCallback(pid, uid);
132             if (callback) {
133                 callback->OnFinish(uid, bufferIds);
134             }
135         }
136     });
137 }
138 } // namespace Rosen
139 } // namespace OHOS
140