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 #include "pipeline/rs_single_frame_composer.h"
16 #include "platform/common/rs_system_properties.h"
17 #include "rs_trace.h"
18 
19 namespace OHOS {
20 namespace Rosen {
21 std::map<std::thread::id, uint64_t> RSSingleFrameComposer::ipcThreadIdMap_;
22 std::mutex RSSingleFrameComposer::ipcThreadIdMapMutex_;
23 std::map<pid_t, uint64_t> RSSingleFrameComposer::appPidMap_;
24 std::mutex RSSingleFrameComposer::appPidMapMutex_;
FindSingleFrameModifier(const std::list<std::shared_ptr<RSRenderModifier>> & modifierList)25 bool RSSingleFrameComposer::FindSingleFrameModifier(const std::list<std::shared_ptr<RSRenderModifier>>& modifierList)
26 {
27     for (auto iter = modifierList.begin(); iter != modifierList.end(); ++iter) {
28         if ((*iter)->GetSingleFrameModifier()) {
29             return true;
30         }
31     }
32     return false;
33 }
34 
EraseSingleFrameModifier(std::list<std::shared_ptr<RSRenderModifier>> & modifierList)35 void RSSingleFrameComposer::EraseSingleFrameModifier(std::list<std::shared_ptr<RSRenderModifier>>& modifierList)
36 {
37     for (auto iter = modifierList.begin(); iter != modifierList.end();) {
38         if ((*iter)->GetSingleFrameModifier()) {
39             iter = modifierList.erase(iter);
40         } else {
41             ++iter;
42         }
43     }
44 }
45 
SingleFrameModifierAdd(std::list<std::shared_ptr<RSRenderModifier>> & singleFrameModifierList,std::list<std::shared_ptr<RSRenderModifier>> & modifierList)46 void RSSingleFrameComposer::SingleFrameModifierAdd(
47     std::list<std::shared_ptr<RSRenderModifier>>& singleFrameModifierList,
48     std::list<std::shared_ptr<RSRenderModifier>>& modifierList)
49 {
50     for (auto iter = singleFrameModifierList.begin(); iter != singleFrameModifierList.end(); ++iter) {
51         RS_TRACE_NAME("Add SingleFrame DrawCmdModifier ID " + std::to_string((*iter)->GetDrawCmdListId()));
52         modifierList.emplace_back(*iter);
53     }
54 }
55 
SingleFrameModifierAddToList(RSModifierType type,std::list<std::shared_ptr<RSRenderModifier>> & modifierList)56 bool RSSingleFrameComposer::SingleFrameModifierAddToList(RSModifierType type,
57     std::list<std::shared_ptr<RSRenderModifier>>& modifierList)
58 {
59     bool needSkip = false;
60     EraseSingleFrameModifier(modifierList);
61     {
62         std::lock_guard<std::mutex> lock(singleFrameDrawMutex_);
63         auto iter = singleFrameDrawCmdModifiers_.find(type);
64         if (iter != singleFrameDrawCmdModifiers_.end() && !iter->second.empty()) {
65             SingleFrameModifierAdd(iter->second, modifierList);
66             singleFrameDrawCmdModifiers_.erase(type);
67         }
68     }
69     if (modifierList.size() > 1 && FindSingleFrameModifier(modifierList)) {
70         needSkip = true;
71     }
72 
73     return needSkip;
74 }
75 
SetSingleFrameFlag(const std::thread::id ipcThreadId)76 void RSSingleFrameComposer::SetSingleFrameFlag(const std::thread::id ipcThreadId)
77 {
78     std::lock_guard<std::mutex> lock(ipcThreadIdMapMutex_);
79     if (ipcThreadIdMap_.find(ipcThreadId) == ipcThreadIdMap_.end()) {
80         ipcThreadIdMap_[ipcThreadId] = 1;
81     } else {
82         ipcThreadIdMap_[ipcThreadId]++;
83     }
84 }
85 
IsShouldSingleFrameComposer()86 bool RSSingleFrameComposer::IsShouldSingleFrameComposer()
87 {
88     std::lock_guard<std::mutex> lock(ipcThreadIdMapMutex_);
89     std::thread::id ipcThreadId = std::this_thread::get_id();
90     if (ipcThreadIdMap_.find(ipcThreadId) == ipcThreadIdMap_.end()) {
91         return false;
92     } else {
93         ipcThreadIdMap_[ipcThreadId]--;
94         if (ipcThreadIdMap_[ipcThreadId] == 0) {
95             ipcThreadIdMap_.erase(ipcThreadId);
96         }
97         return true;
98     }
99 }
100 
SingleFrameIsNeedSkip(bool needSkip,const std::shared_ptr<RSRenderModifier> & modifier)101 bool RSSingleFrameComposer::SingleFrameIsNeedSkip(bool needSkip, const std::shared_ptr<RSRenderModifier>& modifier)
102 {
103     return needSkip && !modifier->GetSingleFrameModifier();
104 }
105 
SingleFrameAddModifier(const std::shared_ptr<RSRenderModifier> & modifier)106 void RSSingleFrameComposer::SingleFrameAddModifier(const std::shared_ptr<RSRenderModifier>& modifier)
107 {
108     if (modifier->GetType() >= RSModifierType::CUSTOM) {
109         modifier->SetSingleFrameModifier(true);
110         RS_TRACE_NAME("Add modifier DrawCmdListId " + std::to_string(modifier->GetDrawCmdListId()));
111         {
112             std::lock_guard<std::mutex> lock(singleFrameDrawMutex_);
113             singleFrameDrawCmdModifiers_.clear();
114             singleFrameDrawCmdModifiers_[modifier->GetType()].emplace_back(modifier);
115         }
116     }
117 }
118 
AddOrRemoveAppPidToMap(bool isNodeSingleFrameComposer,pid_t pid)119 void RSSingleFrameComposer::AddOrRemoveAppPidToMap(bool isNodeSingleFrameComposer, pid_t pid)
120 {
121     std::lock_guard<std::mutex> lock(appPidMapMutex_);
122     if (isNodeSingleFrameComposer) {
123         appPidMap_[pid] = 1;
124     } else {
125         appPidMap_.erase(pid);
126     }
127 }
128 
IsShouldProcessByIpcThread(pid_t pid)129 bool RSSingleFrameComposer::IsShouldProcessByIpcThread(pid_t pid)
130 {
131     std::lock_guard<std::mutex> lock(appPidMapMutex_);
132     if ((appPidMap_.find(pid) != appPidMap_.end() && appPidMap_[pid] != 0) ||
133         RSSystemProperties::GetSingleFrameComposerCanvasNodeEnabled()) {
134         return true;
135     }
136     return false;
137 }
138 }
139 }