• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 "frame_filter.h"
16 #include <memory>
17 #include <cinttypes>
18 #include "log.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(uint64_t ts,uint32_t ipid,uint32_t itid,uint64_t expectStart,uint64_t expectEnd,uint32_t vsyncId,uint32_t callStackSliceId)27 void FrameFilter::BeginVsyncEvent(uint64_t ts,
28                                   uint32_t ipid,
29                                   uint32_t itid,
30                                   uint64_t expectStart,
31                                   uint64_t expectEnd,
32                                   uint32_t vsyncId,
33                                   uint32_t callStackSliceId)
34 {
35     auto frame = std::make_shared<FrameSlice>();
36     frame->startTs_ = ts;
37     frame->callStackSliceId_ = callStackSliceId;
38     frame->expectedStartTs_ = expectStart;
39     frame->expectedEndTs_ = expectEnd;
40     frame->expectedDur_ = expectEnd - expectStart;
41     frame->vsyncId_ = vsyncId;
42     frame->frameSliceRow_ =
43         traceDataCache_->GetFrameSliceData()->AppendFrame(ts, ipid, itid, vsyncId, callStackSliceId);
44     frame->frameExpectedSliceRow_ = traceDataCache_->GetFrameSliceData()->AppendFrame(
45         expectStart, ipid, itid, vsyncId, callStackSliceId, expectEnd, (uint8_t)TraceStdtype::FrameSlice::EXPECT_SLICE);
46     if (vsyncRenderSlice_.count(itid)) {
47         vsyncRenderSlice_[itid].push_back(frame);
48     } else {
49         std::vector<std::shared_ptr<FrameSlice>> frameVec;
50         frameVec.push_back(frame);
51         vsyncRenderSlice_[itid] = frameVec;
52     }
53 }
54 
MarkRSOnDoCompositionEvent(uint64_t ts,uint32_t itid)55 bool FrameFilter::MarkRSOnDoCompositionEvent(uint64_t ts, uint32_t itid)
56 {
57     auto frame = vsyncRenderSlice_.find(itid);
58     if (frame == vsyncRenderSlice_.end()) {
59         TS_LOGD("BeginOnDoCompositionEvent find for itid:%u failed, ts:%" PRIu64 "", itid, ts);
60         return false;
61     }
62     if (!frame->second.size()) {
63         TS_LOGD("BeginOnDoCompositionEvent find for itid:%u failed", itid);
64         return false;
65     }
66     auto lastFrameSlice = frame->second.back();
67     lastFrameSlice->isRsMainThread_ = true;
68     return true;
69 }
70 // for app
BeginRSTransactionData(uint64_t ts,uint32_t itid,uint32_t franeNum)71 bool FrameFilter::BeginRSTransactionData(uint64_t ts, uint32_t itid, uint32_t franeNum)
72 {
73     auto frame = vsyncRenderSlice_.find(itid);
74     if (frame == vsyncRenderSlice_.end()) {
75         TS_LOGD("BeginRSTransactionData find for itid:%u failed", itid);
76         return false;
77     }
78     if (!frame->second.size()) {
79         TS_LOGD("BeginRSTransactionData find for itid:%u failed", itid);
80         return false;
81     }
82     frame->second.begin()->get()->frameNum_ = franeNum;
83     if (!dstRenderSlice_.count(itid)) {
84         std::unordered_map<uint32_t /* frameNum */, std::shared_ptr<FrameSlice>> frameMap;
85         dstRenderSlice_.emplace(std::make_pair(itid, std::move(frameMap)));
86     }
87     dstRenderSlice_[itid][franeNum] = frame->second[0];
88     return true;
89 }
90 // for RS
BeginProcessCommandUni(uint64_t ts,uint32_t itid,const std::vector<FrameMap> & frames,uint32_t sliceIndex)91 bool FrameFilter::BeginProcessCommandUni(uint64_t ts,
92                                          uint32_t itid,
93                                          const std::vector<FrameMap>& frames,
94                                          uint32_t sliceIndex)
95 {
96     auto frame = vsyncRenderSlice_.find(itid);
97     if (frame == vsyncRenderSlice_.end()) {
98         return false;
99     }
100     if (!frame->second.size()) {
101         return false;
102     }
103     auto lastFrameSlice = frame->second.back();
104     if (lastFrameSlice->vsyncEnd_) {
105         return false;
106     }
107     std::vector<uint64_t> fromSlices = {};
108     std::vector<uint64_t> fromExpectedSlices = {};
109     for (auto& it : frames) {
110         auto sourceFrameMap = dstRenderSlice_.find(it.sourceItid);
111         if (sourceFrameMap == dstRenderSlice_.end()) {
112             continue;
113         }
114         auto srcFrame = sourceFrameMap->second.find(it.frameNum);
115         if (srcFrame == sourceFrameMap->second.end()) {
116             continue;
117         }
118         fromSlices.push_back(srcFrame->second.get()->frameSliceRow_);
119         fromExpectedSlices.push_back(srcFrame->second.get()->frameExpectedSliceRow_);
120         srcFrame->second.get()->dstFrameSliceId_ = lastFrameSlice->frameSliceRow_;
121         srcFrame->second.get()->dstExpectedFrameSliceId_ = lastFrameSlice->frameExpectedSliceRow_;
122         TraceStdtype::FrameSlice* frameSlice = traceDataCache_->GetFrameSliceData();
123         (void)traceDataCache_->GetFrameMapsData()->AppendNew(frameSlice, srcFrame->second.get()->frameSliceRow_,
124                                                              srcFrame->second.get()->dstFrameSliceId_);
125         (void)traceDataCache_->GetFrameMapsData()->AppendNew(frameSlice, srcFrame->second.get()->frameExpectedSliceRow_,
126                                                              srcFrame->second.get()->dstExpectedFrameSliceId_);
127         frameSlice->SetDst(srcFrame->second.get()->frameSliceRow_, srcFrame->second.get()->dstFrameSliceId_);
128         frameSlice->SetDst(srcFrame->second.get()->frameExpectedSliceRow_,
129                            srcFrame->second.get()->dstExpectedFrameSliceId_);
130         if (srcFrame->second.get()->endTs_ != INVALID_UINT64) {
131             // erase Source
132             sourceFrameMap->second.erase(it.frameNum);
133         }
134     }
135     if (!fromSlices.size()) {
136         return false;
137     }
138     lastFrameSlice->sourceSlice_ = fromSlices;
139     lastFrameSlice->sourceExpectedSlice_ = fromExpectedSlices;
140     traceDataCache_->GetFrameSliceData()->SetSrcs(lastFrameSlice->frameSliceRow_, fromSlices);
141     traceDataCache_->GetFrameSliceData()->SetSrcs(lastFrameSlice->frameExpectedSliceRow_, fromExpectedSlices);
142     return true;
143 }
EndVsyncEvent(uint64_t ts,uint32_t itid)144 bool FrameFilter::EndVsyncEvent(uint64_t ts, uint32_t itid)
145 {
146     auto frame = vsyncRenderSlice_.find(itid);
147     if (frame == vsyncRenderSlice_.end()) {
148         TS_LOGW("EndVsyncEvent find for itid:%u ts:%" PRIu64 " failed", itid, ts);
149         return false;
150     }
151     if (!frame->second.size()) {
152         TS_LOGW("EndVsyncEvent find for itid:%u ts:%" PRIu64 " failed", itid, ts);
153         return false;
154     }
155     auto lastFrameSlice = frame->second.back();
156     lastFrameSlice->vsyncEnd_ = true;
157     if (lastFrameSlice->isRsMainThread_) {
158         if (lastFrameSlice->gpuEnd_) {
159             traceDataCache_->GetFrameSliceData()->SetEndTimeAndFlag(
160                 lastFrameSlice->frameSliceRow_, ts, lastFrameSlice->expectedDur_, lastFrameSlice->expectedEndTs_);
161             lastFrameSlice->endTs_ = ts;
162             // for Render serivce
163             frame->second.pop_back();
164         }
165     } else { // for app
166         traceDataCache_->GetFrameSliceData()->SetEndTimeAndFlag(
167             lastFrameSlice->frameSliceRow_, ts, lastFrameSlice->expectedDur_, lastFrameSlice->expectedEndTs_);
168         if (lastFrameSlice->frameNum_ == INVALID_UINT32) {
169             // if app's frame num not received
170             traceDataCache_->GetFrameSliceData()->Erase(lastFrameSlice->frameSliceRow_);
171             traceDataCache_->GetFrameSliceData()->Erase(lastFrameSlice->frameExpectedSliceRow_);
172             frame->second.pop_back();
173             return false;
174         }
175         lastFrameSlice->endTs_ = ts;
176         frame->second.pop_back();
177     }
178     return true;
179 }
180 // only for renderservice
StartFrameQueue(uint64_t ts,uint32_t itid)181 bool FrameFilter::StartFrameQueue(uint64_t ts, uint32_t itid)
182 {
183     auto frame = vsyncRenderSlice_.find(itid);
184     if (frame == vsyncRenderSlice_.end()) {
185         TS_LOGD("StartFrameQueue find for itid:%u failed", itid);
186         return false;
187     }
188     if (!frame->second.size()) {
189         TS_LOGD("StartFrameQueue find for itid:%u failed", itid);
190         return false;
191     }
192     auto firstFrameSlice = frame->second.front();
193     firstFrameSlice->gpuEnd_ = false;
194     firstFrameSlice->frameQueueStartTs_ = ts;
195     return true;
196 }
EndFrameQueue(uint64_t ts,uint32_t itid)197 bool FrameFilter::EndFrameQueue(uint64_t ts, uint32_t itid)
198 {
199     auto frame = vsyncRenderSlice_.find(itid);
200     if (frame == vsyncRenderSlice_.end()) {
201         TS_LOGW("EndFrameQueue find for itid:%u ts:%" PRIu64 " failed", itid, ts);
202         return false;
203     }
204     if (!frame->second.size()) {
205         TS_LOGW("EndFrameQueue find for itid:%u ts:%" PRIu64 "  failed", itid, ts);
206         return false;
207     }
208     auto firstFrameSlicePos = frame->second.begin();
209     (void)traceDataCache_->GetGPUSliceData()->AppendNew(firstFrameSlicePos->get()->frameSliceRow_,
210                                                         ts - firstFrameSlicePos->get()->frameQueueStartTs_);
211     firstFrameSlicePos->get()->gpuEnd_ = true;
212     if (firstFrameSlicePos->get()->vsyncEnd_) {
213         firstFrameSlicePos->get()->endTs_ = ts;
214         traceDataCache_->GetFrameSliceData()->SetEndTimeAndFlag(firstFrameSlicePos->get()->frameSliceRow_, ts,
215                                                                 firstFrameSlicePos->get()->expectedDur_,
216                                                                 firstFrameSlicePos->get()->expectedEndTs_);
217         // if vsync ended
218         frame->second.erase(firstFrameSlicePos);
219     }
220     return true;
221 }
Clear()222 void FrameFilter::Clear()
223 {
224     traceDataCache_->GetFrameSliceData()->UpdateDepth();
225     vsyncRenderSlice_.clear();
226     dstRenderSlice_.clear();
227 }
228 } // namespace TraceStreamer
229 } // namespace SysTuning
230