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 "info_collection/rs_gpu_dirty_region_collection.h"
17 
18 namespace OHOS {
19 namespace Rosen {
20 const std::string SELF_DRAWING_NODE_SUFFIX = "-selfDrawing";
GetInstance()21 GpuDirtyRegionCollection& GpuDirtyRegionCollection::GetInstance()
22 {
23     static GpuDirtyRegionCollection instance;
24     return instance;
25 }
26 
GpuDirtyRegionCollection()27 GpuDirtyRegionCollection::GpuDirtyRegionCollection()
28 {
29 }
30 
~GpuDirtyRegionCollection()31 GpuDirtyRegionCollection::~GpuDirtyRegionCollection() noexcept
32 {
33 }
34 
UpdateActiveDirtyInfoForDFX(NodeId id,const std::string & windowName,std::vector<RectI> rectIs)35 void GpuDirtyRegionCollection::UpdateActiveDirtyInfoForDFX(NodeId id, const std::string& windowName,
36     std::vector<RectI> rectIs)
37 {
38     std::lock_guard<std::mutex> lock(activeMtx_);
39     for (const auto& rectI : rectIs) {
40         ++activeDirtyRegionInfoMap_[id].activeFramesNumber;
41         activeDirtyRegionInfoMap_[id].activeDirtyRegionArea += rectI.width_ * rectI.height_;
42         activeDirtyRegionInfoMap_[id].pidOfBelongsApp = ExtractPid(id);
43         activeDirtyRegionInfoMap_[id].windowName = windowName;
44     }
45 }
46 
UpdateActiveDirtyInfoForDFX(NodeId id,const std::string & windowName,Rect damage)47 void GpuDirtyRegionCollection::UpdateActiveDirtyInfoForDFX(NodeId id, const std::string& windowName, Rect damage)
48 {
49     std::lock_guard<std::mutex> lock(activeMtx_);
50     ++activeDirtyRegionInfoMap_[id].activeFramesNumber;
51     activeDirtyRegionInfoMap_[id].activeDirtyRegionArea += damage.w * damage.h;
52     activeDirtyRegionInfoMap_[id].pidOfBelongsApp = ExtractPid(id);
53     activeDirtyRegionInfoMap_[id].windowName = windowName + SELF_DRAWING_NODE_SUFFIX;
54 }
55 
UpdateGlobalDirtyInfoForDFX(RectI rect)56 void GpuDirtyRegionCollection::UpdateGlobalDirtyInfoForDFX(RectI rect)
57 {
58     std::lock_guard<std::mutex> lock(globalMtx_);
59     ++globalDirtyRegionInfo_.globalFramesNumber;
60     globalDirtyRegionInfo_.globalDirtyRegionAreas += rect.width_ * rect.height_;
61 }
62 
AddSkipProcessFramesNumberForDFX(pid_t sendingPid)63 void GpuDirtyRegionCollection::AddSkipProcessFramesNumberForDFX(pid_t sendingPid)
64 {
65     std::lock_guard<std::mutex> lock(globalMtx_);
66     ++globalDirtyRegionInfo_.skipProcessFramesNumber;
67     ++sendingPidWhenDisplayNodeSkipMap_[sendingPid];
68 }
69 
GetActiveDirtyRegionInfo() const70 std::vector<ActiveDirtyRegionInfo> GpuDirtyRegionCollection::GetActiveDirtyRegionInfo() const
71 {
72     std::lock_guard<std::mutex> lock(activeMtx_);
73     std::vector<ActiveDirtyRegionInfo> activeDirtyRegionInfos;
74     for (auto activeDirtyRegionInfo : activeDirtyRegionInfoMap_) {
75         if (activeDirtyRegionInfo.second.pidOfBelongsApp && activeDirtyRegionInfo.second.activeFramesNumber > 0) {
76             activeDirtyRegionInfo.second.activeDirtyRegionArea /= activeDirtyRegionInfo.second.activeFramesNumber;
77             activeDirtyRegionInfos.emplace_back(activeDirtyRegionInfo.second);
78         }
79     }
80     return activeDirtyRegionInfos;
81 }
82 
GetGlobalDirtyRegionInfo() const83 GlobalDirtyRegionInfo GpuDirtyRegionCollection::GetGlobalDirtyRegionInfo() const
84 {
85     std::lock_guard<std::mutex> lock(globalMtx_);
86     GlobalDirtyRegionInfo globalDirtyRegionInfo;
87     if (globalDirtyRegionInfo_.globalFramesNumber > 0) {
88         globalDirtyRegionInfo.globalDirtyRegionAreas = globalDirtyRegionInfo_.globalDirtyRegionAreas /
89             globalDirtyRegionInfo_.globalFramesNumber;
90         globalDirtyRegionInfo.globalFramesNumber = globalDirtyRegionInfo_.globalFramesNumber;
91         globalDirtyRegionInfo.skipProcessFramesNumber = globalDirtyRegionInfo_.skipProcessFramesNumber;
92         globalDirtyRegionInfo.mostSendingPidWhenDisplayNodeSkip = GetMostSendingPidWhenDisplayNodeSkip();
93     }
94     return globalDirtyRegionInfo;
95 }
96 
ResetActiveDirtyRegionInfo()97 void GpuDirtyRegionCollection::ResetActiveDirtyRegionInfo()
98 {
99     std::lock_guard<std::mutex> lock(activeMtx_);
100     activeDirtyRegionInfoMap_.clear();
101 }
102 
ResetGlobalDirtyRegionInfo()103 void GpuDirtyRegionCollection::ResetGlobalDirtyRegionInfo()
104 {
105     std::lock_guard<std::mutex> lock(globalMtx_);
106     globalDirtyRegionInfo_ = GlobalDirtyRegionInfo {};
107     sendingPidWhenDisplayNodeSkipMap_.clear();
108 }
109 
GetMostSendingPidWhenDisplayNodeSkip() const110 pid_t GpuDirtyRegionCollection::GetMostSendingPidWhenDisplayNodeSkip() const
111 {
112     pid_t mostSendingPidWhenDisplayNodeSkip = 0;
113     int32_t maxCountOfSendingPid = 0;
114     for (const auto& pair : sendingPidWhenDisplayNodeSkipMap_) {
115         if (pair.second > maxCountOfSendingPid) {
116             mostSendingPidWhenDisplayNodeSkip = pair.first;
117             maxCountOfSendingPid = pair.second;
118         }
119     }
120     return mostSendingPidWhenDisplayNodeSkip;
121 }
122 } // namespace Rosen
123 } // namespace OHOS