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