• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) Huawei Technologies Co., Ltd. 2023. All rights reserved.
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 "frame_filter.h"
16 #include <memory>
17 #include <cinttypes>
18 #include "process_filter.h"
19 
20 namespace SysTuning {
21 namespace TraceStreamer {
FrameFilter(TraceDataCache * dataCache,const TraceStreamerFilters * filter)22 FrameFilter::FrameFilter(TraceDataCache *dataCache, const TraceStreamerFilters *filter) : FilterBase(dataCache, filter)
23 {
24 }
25 FrameFilter::~FrameFilter() = default;
26 
BeginVsyncEvent(const BytraceLine & line,uint64_t expectStart,uint64_t expectEnd,uint32_t vsyncId,uint32_t callStackSliceId)27 void FrameFilter::BeginVsyncEvent(const BytraceLine &line,
28                                   uint64_t expectStart,
29                                   uint64_t expectEnd,
30                                   uint32_t vsyncId,
31                                   uint32_t callStackSliceId)
32 {
33     auto frame = std::make_shared<FrameSlice>();
34     frame->startTs_ = line.ts;
35     frame->callStackSliceId_ = callStackSliceId;
36     frame->expectedStartTs_ = expectStart;
37     frame->expectedEndTs_ = expectEnd;
38     frame->expectedDur_ = expectEnd - expectStart;
39     frame->vsyncId_ = vsyncId;
40     auto itid = streamFilters_->processFilter_->GetInternalTid(line.pid);
41     auto ipid = streamFilters_->processFilter_->GetInternalPid(line.tgid);
42     frame->frameSliceRow_ =
43         traceDataCache_->GetFrameSliceData()->AppendFrame(line.ts, ipid, itid, vsyncId, callStackSliceId);
44     FrameSliceRow frameSliceRow = {
45         expectStart, ipid, itid, vsyncId, callStackSliceId, expectEnd, (uint8_t)TraceStdtype::FrameSlice::EXPECT_SLICE};
46     frame->frameExpectedSliceRow_ = traceDataCache_->GetFrameSliceData()->AppendFrame(frameSliceRow);
47     if (vsyncRenderSlice_.count(itid)) {
48         vsyncRenderSlice_[itid].push_back(frame);
49     } else {
50         std::vector<std::shared_ptr<FrameSlice>> frameVec;
51         frameVec.push_back(frame);
52         vsyncRenderSlice_[itid] = frameVec;
53     }
54 }
55 
MarkRSOnDoCompositionEvent(uint64_t ts,uint32_t itid)56 bool FrameFilter::MarkRSOnDoCompositionEvent(uint64_t ts, uint32_t itid)
57 {
58     auto frame = vsyncRenderSlice_.find(itid);
59     if (frame == vsyncRenderSlice_.end()) {
60         TS_LOGD("BeginOnDoCompositionEvent find for itid:%u failed, ts:%" PRIu64 "", itid, ts);
61         return false;
62     }
63     if (!frame->second.size()) {
64         TS_LOGD("BeginOnDoCompositionEvent find for itid:%u failed", itid);
65         return false;
66     }
67     auto lastFrameSlice = frame->second.back();
68     lastFrameSlice->isRsMainThread_ = true;
69     return true;
70 }
71 // for app
BeginRSTransactionData(uint64_t ts,uint32_t itid,uint32_t franeNum)72 bool FrameFilter::BeginRSTransactionData(uint64_t ts, uint32_t itid, uint32_t franeNum)
73 {
74     auto frame = vsyncRenderSlice_.find(itid);
75     if (frame == vsyncRenderSlice_.end()) {
76         TS_LOGD("BeginRSTransactionData find for itid:%u failed", itid);
77         return false;
78     }
79     if (!frame->second.size()) {
80         TS_LOGD("BeginRSTransactionData find for itid:%u failed", itid);
81         return false;
82     }
83     frame->second.begin()->get()->frameNum_ = franeNum;
84     if (!dstRenderSlice_.count(itid)) {
85         std::unordered_map<uint32_t /* frameNum */, std::shared_ptr<FrameSlice>> frameMap;
86         dstRenderSlice_.emplace(std::make_pair(itid, std::move(frameMap)));
87     }
88     dstRenderSlice_[itid][franeNum] = frame->second[0];
89     return true;
90 }
91 // for RS
BeginProcessCommandUni(uint64_t ts,uint32_t itid,const std::vector<FrameMap> & frames,uint32_t sliceIndex)92 bool FrameFilter::BeginProcessCommandUni(uint64_t ts,
93                                          uint32_t itid,
94                                          const std::vector<FrameMap> &frames,
95                                          uint32_t sliceIndex)
96 {
97     auto frame = vsyncRenderSlice_.find(itid);
98     TS_CHECK_TRUE_RET(frame != vsyncRenderSlice_.end(), false);
99     TS_CHECK_TRUE_RET(!frame->second.empty(), false);
100     auto lastFrameSlice = frame->second.back();
101     TS_CHECK_TRUE_RET(!lastFrameSlice->vsyncEnd_, false);
102     std::vector<uint64_t> fromSlices = {};
103     std::vector<uint64_t> fromExpectedSlices = {};
104     for (auto &it : frames) {
105         auto sourceFrameMap = dstRenderSlice_.find(it.sourceItid);
106         if (sourceFrameMap == dstRenderSlice_.end()) {
107             continue;
108         }
109         auto srcFrame = sourceFrameMap->second.find(it.frameNum);
110         if (srcFrame == sourceFrameMap->second.end()) {
111             continue;
112         }
113         fromSlices.push_back(srcFrame->second->frameSliceRow_);
114         fromExpectedSlices.push_back(srcFrame->second->frameExpectedSliceRow_);
115         srcFrame->second->dstFrameSliceId_ = lastFrameSlice->frameSliceRow_;
116         srcFrame->second->dstExpectedFrameSliceId_ = lastFrameSlice->frameExpectedSliceRow_;
117         TraceStdtype::FrameSlice *frameSlice = traceDataCache_->GetFrameSliceData();
118         (void)traceDataCache_->GetFrameMapsData()->AppendNew(frameSlice, srcFrame->second->frameSliceRow_,
119                                                              srcFrame->second->dstFrameSliceId_);
120         (void)traceDataCache_->GetFrameMapsData()->AppendNew(frameSlice, srcFrame->second->frameExpectedSliceRow_,
121                                                              srcFrame->second->dstExpectedFrameSliceId_);
122         frameSlice->SetDst(srcFrame->second->frameSliceRow_, srcFrame->second->dstFrameSliceId_);
123         frameSlice->SetDst(srcFrame->second->frameExpectedSliceRow_, srcFrame->second->dstExpectedFrameSliceId_);
124         if (srcFrame->second->endTs_ != INVALID_UINT64) {
125             // erase Source
126             sourceFrameMap->second.erase(it.frameNum);
127         }
128     }
129     TS_CHECK_TRUE_RET(!fromSlices.empty(), false);
130     lastFrameSlice->sourceSlice_ = fromSlices;
131     lastFrameSlice->sourceExpectedSlice_ = fromExpectedSlices;
132     traceDataCache_->GetFrameSliceData()->SetSrcs(lastFrameSlice->frameSliceRow_, fromSlices);
133     traceDataCache_->GetFrameSliceData()->SetSrcs(lastFrameSlice->frameExpectedSliceRow_, fromExpectedSlices);
134     return true;
135 }
EndVsyncEvent(uint64_t ts,uint32_t itid)136 bool FrameFilter::EndVsyncEvent(uint64_t ts, uint32_t itid)
137 {
138     auto frame = vsyncRenderSlice_.find(itid);
139     if (frame == vsyncRenderSlice_.end()) {
140         TS_LOGW("EndVsyncEvent find for itid:%u ts:%" PRIu64 " failed", itid, ts);
141         return false;
142     }
143     if (!frame->second.size()) {
144         TS_LOGW("EndVsyncEvent find for itid:%u ts:%" PRIu64 " failed", itid, ts);
145         return false;
146     }
147     auto lastFrameSlice = frame->second.back();
148     lastFrameSlice->vsyncEnd_ = true;
149     if (lastFrameSlice->isRsMainThread_) {
150         if (lastFrameSlice->gpuEnd_) {
151             traceDataCache_->GetFrameSliceData()->SetEndTimeAndFlag(
152                 lastFrameSlice->frameSliceRow_, ts, lastFrameSlice->expectedDur_, lastFrameSlice->expectedEndTs_);
153             lastFrameSlice->endTs_ = ts;
154             // for Render serivce
155             frame->second.pop_back();
156         }
157     } else { // for app
158         traceDataCache_->GetFrameSliceData()->SetEndTimeAndFlag(
159             lastFrameSlice->frameSliceRow_, ts, lastFrameSlice->expectedDur_, lastFrameSlice->expectedEndTs_);
160         if (lastFrameSlice->frameNum_ == INVALID_UINT32) {
161             // if app's frame num not received
162             traceDataCache_->GetFrameSliceData()->Erase(lastFrameSlice->frameSliceRow_);
163             traceDataCache_->GetFrameSliceData()->Erase(lastFrameSlice->frameExpectedSliceRow_);
164             frame->second.pop_back();
165             return false;
166         }
167         lastFrameSlice->endTs_ = ts;
168         frame->second.pop_back();
169     }
170     return true;
171 }
172 // only for renderservice
StartFrameQueue(uint64_t ts,uint32_t itid)173 bool FrameFilter::StartFrameQueue(uint64_t ts, uint32_t itid)
174 {
175     auto frame = vsyncRenderSlice_.find(itid);
176     if (frame == vsyncRenderSlice_.end()) {
177         TS_LOGD("StartFrameQueue find for itid:%u failed", itid);
178         return false;
179     }
180     if (!frame->second.size()) {
181         TS_LOGD("StartFrameQueue find for itid:%u failed", itid);
182         return false;
183     }
184     auto firstFrameSlice = frame->second.front();
185     firstFrameSlice->gpuEnd_ = false;
186     firstFrameSlice->frameQueueStartTs_ = ts;
187     return true;
188 }
EndFrameQueue(uint64_t ts,uint32_t itid)189 bool FrameFilter::EndFrameQueue(uint64_t ts, uint32_t itid)
190 {
191     auto frame = vsyncRenderSlice_.find(itid);
192     if (frame == vsyncRenderSlice_.end()) {
193         TS_LOGW("EndFrameQueue find for itid:%u ts:%" PRIu64 " failed", itid, ts);
194         return false;
195     }
196     if (!frame->second.size()) {
197         TS_LOGW("EndFrameQueue find for itid:%u ts:%" PRIu64 "  failed", itid, ts);
198         return false;
199     }
200     auto firstFrameSlicePos = frame->second.begin();
201     TraceStdtype::FrameSlice *frameSlice = traceDataCache_->GetFrameSliceData();
202     (void)traceDataCache_->GetGPUSliceData()->AppendNew(frameSlice->diskTableSize_ +
203                                                             (*firstFrameSlicePos)->frameSliceRow_,
204                                                         ts - firstFrameSlicePos->get()->frameQueueStartTs_);
205     firstFrameSlicePos->get()->gpuEnd_ = true;
206     if (firstFrameSlicePos->get()->vsyncEnd_) {
207         firstFrameSlicePos->get()->endTs_ = ts;
208         traceDataCache_->GetFrameSliceData()->SetEndTimeAndFlag(firstFrameSlicePos->get()->frameSliceRow_, ts,
209                                                                 firstFrameSlicePos->get()->expectedDur_,
210                                                                 firstFrameSlicePos->get()->expectedEndTs_);
211         // if vsync ended
212         frame->second.erase(firstFrameSlicePos);
213     }
214     return true;
215 }
SetMinFrameSliceRow(uint64_t & minFrameSliceRowToBeUpdated)216 void FrameFilter::SetMinFrameSliceRow(uint64_t &minFrameSliceRowToBeUpdated)
217 {
218     for (const auto &[_, frameSlices] : vsyncRenderSlice_) {
219         for (size_t idx = 0; idx < frameSlices.size(); idx++) {
220             if (minFrameSliceRowToBeUpdated > frameSlices[idx]->frameSliceRow_) {
221                 minFrameSliceRowToBeUpdated = frameSlices[idx]->frameSliceRow_;
222             }
223             if (minFrameSliceRowToBeUpdated > frameSlices[idx]->frameExpectedSliceRow_) {
224                 minFrameSliceRowToBeUpdated = frameSlices[idx]->frameExpectedSliceRow_;
225             }
226         }
227     }
228     for (const auto &pair : dstRenderSlice_) {
229         for (const auto &[_, frameSlice] : pair.second) {
230             if (minFrameSliceRowToBeUpdated > frameSlice->frameSliceRow_) {
231                 minFrameSliceRowToBeUpdated = frameSlice->frameSliceRow_;
232             }
233             if (minFrameSliceRowToBeUpdated > frameSlice->frameExpectedSliceRow_) {
234                 minFrameSliceRowToBeUpdated = frameSlice->frameExpectedSliceRow_;
235             }
236         }
237     }
238 }
UpdateFrameSliceReadySize()239 bool FrameFilter::UpdateFrameSliceReadySize()
240 {
241     traceDataCache_->GetFrameSliceData()->UpdateDepth();
242     auto frameSlice = traceDataCache_->GetFrameSliceData();
243     frameSlice->UpdateReadySize(frameSlice->Size());
244     uint64_t minFrameSliceRowToBeUpdated = INVALID_UINT64;
245     SetMinFrameSliceRow(minFrameSliceRowToBeUpdated);
246     // the ready size isn't all
247     TS_CHECK_TRUE_RET(minFrameSliceRowToBeUpdated != INVALID_UINT64, true);
248     frameSlice->UpdateReadySize(minFrameSliceRowToBeUpdated);
249     TS_LOGI("minFrameSliceRowToBeUpdated=%" PRIu64 ", size=%zu, ready.size=%zu\n", minFrameSliceRowToBeUpdated,
250             frameSlice->Size(), frameSlice->readySize_);
251     for (auto &[_, frameSlices] : vsyncRenderSlice_) {
252         for (size_t idx = 0; idx < frameSlices.size(); idx++) {
253             frameSlices[idx]->frameSliceRow_ -= minFrameSliceRowToBeUpdated;
254             frameSlices[idx]->frameExpectedSliceRow_ -= minFrameSliceRowToBeUpdated;
255         }
256     }
257     for (const auto &pair : dstRenderSlice_) {
258         for (const auto &[_, frameSlice] : pair.second) {
259             frameSlice->frameSliceRow_ -= minFrameSliceRowToBeUpdated;
260             frameSlice->frameExpectedSliceRow_ -= minFrameSliceRowToBeUpdated;
261         }
262     }
263     return true;
264 }
Clear()265 void FrameFilter::Clear()
266 {
267     traceDataCache_->GetFrameSliceData()->UpdateDepth();
268     vsyncRenderSlice_.clear();
269     dstRenderSlice_.clear();
270 }
271 } // namespace TraceStreamer
272 } // namespace SysTuning
273