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 "rs_profiler_file.h"
17
18 #include <algorithm>
19 #include <chrono>
20 #include <iostream>
21 #include <memory>
22 #include <string>
23 #include <thread>
24 #include <utility>
25 #include <vector>
26
27 #include "rs_profiler_cache.h"
28
29 namespace OHOS::Rosen {
30
31 RSFile::RSFile() = default;
32
GetDefaultPath()33 const std::string& RSFile::GetDefaultPath()
34 {
35 static const std::string PATH("RECORD_IN_MEMORY");
36 return PATH;
37 }
38
Create(const std::string& fname)39 void RSFile::Create(const std::string& fname)
40 {
41 if (file_ != nullptr) {
42 Close();
43 }
44 const std::lock_guard<std::mutex> lgMutex(writeMutex_);
45
46 #ifdef RENDER_PROFILER_APPLICATION
47 file_ = Utils::FileOpen(fname, "wb");
48 #else
49 file_ = Utils::FileOpen(fname, "wbe");
50 #endif
51 if (file_ == nullptr) {
52 return;
53 }
54
55 uint32_t headerId = 'ROHR';
56 Utils::FileWrite(&headerId, sizeof(headerId), 1, file_);
57 Utils::FileWrite(&versionId_, sizeof(versionId_), 1, file_);
58
59 headerOff_ = 0; // TEMP VALUE
60 Utils::FileWrite(&headerOff_, sizeof(headerOff_), 1, file_);
61
62 writeDataOff_ = RSFileLayer::MARKUP_SIZE;
63
64 wasChanged_ = true;
65 }
66
Open(const std::string& fname)67 bool RSFile::Open(const std::string& fname)
68 {
69 if (file_ != nullptr) {
70 Close();
71 }
72
73 #ifdef RENDER_PROFILER_APPLICATION
74 file_ = Utils::FileOpen(fname, "rb");
75 #else
76 file_ = Utils::FileOpen(fname, "rbe");
77 #endif
78 if (file_ == nullptr) {
79 return false;
80 }
81
82 uint32_t headerId;
83 Utils::FileRead(&headerId, sizeof(headerId), 1, file_);
84 if (headerId != 'ROHR') { // Prohibit too old file versions
85 Utils::FileClose(file_);
86 file_ = nullptr;
87 return false;
88 }
89
90 Utils::FileRead(&versionId_, sizeof(versionId_), 1, file_);
91 Utils::FileRead(&headerOff_, sizeof(headerOff_), 1, file_);
92 Utils::FileSeek(file_, 0, SEEK_END);
93 writeDataOff_ = Utils::FileTell(file_);
94 Utils::FileSeek(file_, headerOff_, SEEK_SET);
95 ReadHeaders();
96 wasChanged_ = false;
97
98 return true;
99 }
100
IsOpen() const101 bool RSFile::IsOpen() const
102 {
103 return file_ != nullptr;
104 }
105
SetWriteTime(double time)106 void RSFile::SetWriteTime(double time)
107 {
108 writeStartTime_ = time;
109 }
110
GetWriteTime() const111 double RSFile::GetWriteTime() const
112 {
113 return writeStartTime_;
114 }
115
116 // ***********************************
117 // *** GLOBAL HEADER
118
AddHeaderPid(pid_t pid)119 void RSFile::AddHeaderPid(pid_t pid)
120 {
121 if (std::find(std::begin(headerPidList_), std::end(headerPidList_), pid) != std::end(headerPidList_)) {
122 return;
123 }
124 headerPidList_.push_back(pid);
125
126 wasChanged_ = true;
127 }
128
GetHeaderPids() const129 const std::vector<pid_t>& RSFile::GetHeaderPids() const
130 {
131 return headerPidList_;
132 }
133
SetPreparedHeader(const std::vector<uint8_t>& headerData)134 void RSFile::SetPreparedHeader(const std::vector<uint8_t>& headerData)
135 {
136 preparedHeader_ = headerData;
137 }
138
GetPreparedHeader(std::vector<uint8_t>& headerData)139 void RSFile::GetPreparedHeader(std::vector<uint8_t>& headerData)
140 {
141 headerData = preparedHeader_;
142 }
143
SetPreparedHeaderMode(bool mode)144 void RSFile::SetPreparedHeaderMode(bool mode)
145 {
146 preparedHeaderMode_ = mode;
147 }
148
WriteHeader()149 void RSFile::WriteHeader()
150 {
151 // WARNING removed redundant mutex
152 if (!file_) {
153 return;
154 }
155
156 headerOff_ = writeDataOff_;
157 Utils::FileSeek(file_, writeDataOff_, SEEK_SET);
158
159 if (preparedHeaderMode_) {
160 // WRITE RAW
161 Utils::FileWrite(preparedHeader_.data(), 1, preparedHeader_.size(), file_);
162 preparedHeader_.clear();
163 } else {
164 // WRITE TIME START
165 Utils::FileWrite(&writeStartTime_, 1, sizeof(writeStartTime_), file_);
166
167 // SAVE PID LIST
168 const uint32_t recordSize = headerPidList_.size();
169 Utils::FileWrite(&recordSize, sizeof(recordSize), 1, file_);
170 Utils::FileWrite(headerPidList_.data(), headerPidList_.size(), sizeof(pid_t), file_);
171
172 // SAVE FIRST SCREEN
173 uint32_t firstScrSize = headerFirstFrame_.size();
174 Utils::FileWrite(&firstScrSize, sizeof(firstScrSize), 1, file_);
175 Utils::FileWrite(headerFirstFrame_.data(), headerFirstFrame_.size(), 1, file_);
176
177 if (versionId_ >= RSFILE_VERSION_RENDER_ANIMESTARTTIMES_ADDED) {
178 // ANIME START TIMES
179 uint32_t startTimesSize = headerAnimeStartTimes_.size();
180 Utils::FileWrite(&startTimesSize, sizeof(startTimesSize), 1, file_);
181 Utils::FileWrite(headerAnimeStartTimes_.data(),
182 headerAnimeStartTimes_.size() * sizeof(std::pair<uint64_t, int64_t>), 1, file_);
183 }
184
185 // ALL TEXTURES
186 ImageCache::Serialize(file_);
187 }
188
189 // SAVE LAYERS OFFSETS
190 const uint32_t recordSize = layerData_.size();
191 Utils::FileWrite(&recordSize, sizeof(recordSize), 1, file_);
192 for (auto& i : layerData_) {
193 Utils::FileWrite(&i.layerHeader, sizeof(i.layerHeader), 1, file_);
194 }
195
196 constexpr int preambleSize = 8;
197 Utils::FileSeek(file_, preambleSize, SEEK_SET);
198 Utils::FileWrite(&headerOff_, sizeof(headerOff_), 1, file_);
199 }
200
ReadHeader()201 void RSFile::ReadHeader()
202 {
203 if (!file_) {
204 return;
205 }
206
207 Utils::FileSeek(file_, headerOff_, SEEK_SET);
208
209 uint32_t recordSize;
210
211 const size_t subHeaderStartOff = Utils::FileTell(file_);
212
213 // READ what was write start time
214 Utils::FileRead(&writeStartTime_, 1, sizeof(writeStartTime_), file_);
215
216 // READ PID LIST
217 Utils::FileRead(&recordSize, sizeof(recordSize), 1, file_);
218 headerPidList_.resize(recordSize);
219 Utils::FileRead(headerPidList_.data(), headerPidList_.size(), sizeof(pid_t), file_);
220
221 // READ FIRST SCREEN
222 uint32_t firstScrSize;
223 Utils::FileRead(&firstScrSize, sizeof(firstScrSize), 1, file_);
224 headerFirstFrame_.resize(firstScrSize);
225 Utils::FileRead(headerFirstFrame_.data(), headerFirstFrame_.size(), 1, file_);
226
227 // READ ANIME START TIMES
228 if (versionId_ >= RSFILE_VERSION_RENDER_ANIMESTARTTIMES_ADDED) {
229 uint32_t startTimesSize;
230 Utils::FileRead(&startTimesSize, sizeof(startTimesSize), 1, file_);
231 headerAnimeStartTimes_.resize(startTimesSize);
232 Utils::FileRead(headerAnimeStartTimes_.data(),
233 headerAnimeStartTimes_.size() * sizeof(std::pair<uint64_t, int64_t>), 1, file_);
234 }
235
236 // ALL TEXTURES
237 ImageCache::Deserialize(file_);
238
239 if (preparedHeaderMode_) {
240 const size_t subHeaderEndOff = Utils::FileTell(file_);
241 Utils::FileSeek(file_, subHeaderStartOff, SEEK_SET);
242 const size_t subHeaderLen = subHeaderEndOff - subHeaderStartOff;
243 preparedHeader_.resize(subHeaderLen);
244 Utils::FileRead(preparedHeader_.data(), subHeaderLen, 1, file_);
245 }
246
247 // READ LAYERS OFFSETS
248 Utils::FileRead(&recordSize, sizeof(recordSize), 1, file_);
249 layerData_.resize(recordSize);
250 for (auto& i : layerData_) {
251 Utils::FileRead(&i.layerHeader, sizeof(i.layerHeader), 1, file_);
252 i.readindexRsData = 0;
253 }
254 }
255
256 // ***********************************
257 // *** LAYER HEADER
258
AddLayer()259 uint32_t RSFile::AddLayer()
260 {
261 const uint32_t newId = layerData_.size();
262 const RSFileLayer data;
263 layerData_.push_back(data);
264
265 wasChanged_ = true;
266
267 return newId;
268 }
269
LayerAddHeaderProperty(uint32_t layer, const std::string& name, const std::string& value)270 void RSFile::LayerAddHeaderProperty(uint32_t layer, const std::string& name, const std::string& value)
271 {
272 if (!HasLayer(layer)) {
273 return;
274 }
275
276 RSFileLayer& layerData = layerData_[layer];
277 layerData.property.SetProperty(name, value);
278
279 wasChanged_ = true;
280 }
281
LayerWriteHeader(uint32_t layer)282 void RSFile::LayerWriteHeader(uint32_t layer)
283 {
284 if (!file_ || !HasLayer(layer)) {
285 return;
286 }
287
288 RSFileLayer& layerData = layerData_[layer];
289
290 const uint32_t layerHeaderOff = writeDataOff_; // position of layer table
291 Utils::FileSeek(file_, writeDataOff_, SEEK_SET);
292
293 std::vector<char> propertyData;
294 layerData.property.Serialize(propertyData);
295
296 // SAVE LAYER PROPERTY
297 uint32_t recordSize = propertyData.size();
298 Utils::FileWrite(&recordSize, sizeof(recordSize), 1, file_);
299 Utils::FileWrite(propertyData.data(), propertyData.size(), 1, file_);
300
301 LayerWriteHeaderOfTrack(layerData.rsData);
302 LayerWriteHeaderOfTrack(layerData.oglData);
303 LayerWriteHeaderOfTrack(layerData.rsMetrics);
304 if (versionId_ >= RSFILE_VERSION_RENDER_METRICS_ADDED) {
305 LayerWriteHeaderOfTrack(layerData.renderMetrics);
306 }
307 LayerWriteHeaderOfTrack(layerData.oglMetrics);
308 LayerWriteHeaderOfTrack(layerData.gfxMetrics);
309 layerData.layerHeader = { layerHeaderOff, Utils::FileTell(file_) - layerHeaderOff }; // position of layer table
310
311 writeDataOff_ = Utils::FileTell(file_);
312 }
313
LayerReadHeader(uint32_t layer)314 void RSFile::LayerReadHeader(uint32_t layer)
315 {
316 if (!file_ || !HasLayer(layer)) {
317 return;
318 }
319
320 RSFileLayer& layerData = layerData_[layer];
321
322 Utils::FileSeek(file_, layerData.layerHeader.first, SEEK_SET);
323
324 // READ LAYER PROPERTY
325 uint32_t recordSize = 0u;
326 Utils::FileRead(&recordSize, sizeof(recordSize), 1, file_);
327 std::vector<char> propertyData;
328 propertyData.resize(recordSize);
329 Utils::FileRead(propertyData.data(), recordSize, 1, file_);
330
331 layerData.property.Deserialize(propertyData);
332 LayerReadHeaderOfTrack(layerData.rsData);
333 LayerReadHeaderOfTrack(layerData.oglData);
334 LayerReadHeaderOfTrack(layerData.rsMetrics);
335 if (versionId_ >= RSFILE_VERSION_RENDER_METRICS_ADDED) {
336 LayerReadHeaderOfTrack(layerData.renderMetrics);
337 }
338 LayerReadHeaderOfTrack(layerData.oglMetrics);
339 LayerReadHeaderOfTrack(layerData.gfxMetrics);
340 }
341
GetVersion() const342 uint32_t RSFile::GetVersion() const
343 {
344 return versionId_;
345 }
346
SetVersion(uint32_t version)347 void RSFile::SetVersion(uint32_t version)
348 {
349 versionId_ = version;
350 }
351
352 // ***********************************
353 // *** LAYER DATA - WRITE
354
WriteRSData(double time, const void* data, size_t size)355 void RSFile::WriteRSData(double time, const void* data, size_t size)
356 {
357 WriteTrackData(&RSFileLayer::rsData, 0, time, data, size);
358 }
359
WriteOGLData(uint32_t layer, double time, const void* data, size_t size)360 void RSFile::WriteOGLData(uint32_t layer, double time, const void* data, size_t size)
361 {
362 WriteTrackData(&RSFileLayer::oglData, layer, time, data, size);
363 }
364
WriteRSMetrics(uint32_t layer, double time, const void* data, size_t size)365 void RSFile::WriteRSMetrics(uint32_t layer, double time, const void* data, size_t size)
366 {
367 WriteTrackData(&RSFileLayer::rsMetrics, layer, time, data, size);
368 }
369
WriteRenderMetrics(uint32_t layer, double time, const void* data, size_t size)370 void RSFile::WriteRenderMetrics(uint32_t layer, double time, const void* data, size_t size)
371 {
372 WriteTrackData(&RSFileLayer::renderMetrics, layer, time, data, size);
373 }
374
WriteOGLMetrics(uint32_t layer, double time, uint32_t , const void* data, size_t size)375 void RSFile::WriteOGLMetrics(uint32_t layer, double time, uint32_t /*frame*/, const void* data, size_t size)
376 {
377 WriteTrackData(&RSFileLayer::oglMetrics, layer, time, data, size);
378 }
379
WriteGFXMetrics(uint32_t layer, double time, uint32_t , const void* data, size_t size)380 void RSFile::WriteGFXMetrics(uint32_t layer, double time, uint32_t /*frame*/, const void* data, size_t size)
381 {
382 WriteTrackData(&RSFileLayer::gfxMetrics, layer, time, data, size);
383 }
384
385 // ***********************************
386 // *** LAYER DATA - READ
387
ReadRSDataRestart()388 void RSFile::ReadRSDataRestart()
389 {
390 ReadTrackDataRestart(&RSFileLayer::readindexRsData, 0);
391 }
392
ReadOGLDataRestart(uint32_t layer)393 void RSFile::ReadOGLDataRestart(uint32_t layer)
394 {
395 ReadTrackDataRestart(&RSFileLayer::readindexOglData, layer);
396 }
397
ReadRSMetricsRestart(uint32_t layer)398 void RSFile::ReadRSMetricsRestart(uint32_t layer)
399 {
400 ReadTrackDataRestart(&RSFileLayer::readindexRsMetrics, layer);
401 }
402
ReadRenderMetricsRestart(uint32_t layer)403 void RSFile::ReadRenderMetricsRestart(uint32_t layer)
404 {
405 ReadTrackDataRestart(&RSFileLayer::readindexRenderMetrics, layer);
406 }
407
ReadOGLMetricsRestart(uint32_t layer)408 void RSFile::ReadOGLMetricsRestart(uint32_t layer)
409 {
410 ReadTrackDataRestart(&RSFileLayer::readindexOglMetrics, layer);
411 }
412
ReadGFXMetricsRestart(uint32_t layer)413 void RSFile::ReadGFXMetricsRestart(uint32_t layer)
414 {
415 ReadTrackDataRestart(&RSFileLayer::readindexGfxMetrics, layer);
416 }
417
RSDataEOF() const418 bool RSFile::RSDataEOF() const
419 {
420 return TrackEOF({ &RSFileLayer::readindexRsData, &RSFileLayer::rsData }, 0);
421 }
422
OGLDataEOF(uint32_t layer) const423 bool RSFile::OGLDataEOF(uint32_t layer) const
424 {
425 return TrackEOF({ &RSFileLayer::readindexOglData, &RSFileLayer::oglData }, layer);
426 }
427
RSMetricsEOF(uint32_t layer) const428 bool RSFile::RSMetricsEOF(uint32_t layer) const
429 {
430 return TrackEOF({ &RSFileLayer::readindexRsMetrics, &RSFileLayer::rsMetrics }, layer);
431 }
432
RenderMetricsEOF(uint32_t layer) const433 bool RSFile::RenderMetricsEOF(uint32_t layer) const
434 {
435 return TrackEOF({ &RSFileLayer::readindexRenderMetrics, &RSFileLayer::renderMetrics }, layer);
436 }
437
OGLMetricsEOF(uint32_t layer) const438 bool RSFile::OGLMetricsEOF(uint32_t layer) const
439 {
440 return TrackEOF({ &RSFileLayer::readindexOglMetrics, &RSFileLayer::oglMetrics }, layer);
441 }
442
GFXMetricsEOF(uint32_t layer) const443 bool RSFile::GFXMetricsEOF(uint32_t layer) const
444 {
445 return TrackEOF({ &RSFileLayer::readindexGfxMetrics, &RSFileLayer::gfxMetrics }, layer);
446 }
447
ReadRSData(double untilTime, std::vector<uint8_t>& data, double& readTime)448 bool RSFile::ReadRSData(double untilTime, std::vector<uint8_t>& data, double& readTime)
449 {
450 readTime = 0.0;
451 if (!file_ || layerData_.empty()) {
452 return false;
453 }
454
455 RSFileLayer& layerData = layerData_[0];
456
457 if (layerData.readindexRsData >= layerData.rsData.size()) {
458 return false;
459 }
460
461 Utils::FileSeek(file_, layerData.rsData[layerData.readindexRsData].first, SEEK_SET);
462
463 Utils::FileRead(&readTime, sizeof(readTime), 1, file_);
464 constexpr double epsilon = 1e-9;
465 if (readTime >= untilTime + epsilon) {
466 return false;
467 }
468
469 const uint32_t dataLen = layerData.rsData[layerData.readindexRsData].second - sizeof(readTime);
470 data.resize(dataLen);
471 Utils::FileRead(data.data(), dataLen, 1, file_);
472
473 layerData.readindexRsData++;
474 return true;
475 }
476
ReadOGLData(double untilTime, uint32_t layer, std::vector<uint8_t>& data, double& readTime)477 bool RSFile::ReadOGLData(double untilTime, uint32_t layer, std::vector<uint8_t>& data, double& readTime)
478 {
479 return ReadTrackData({ &RSFileLayer::readindexOglData, &RSFileLayer::oglData }, untilTime, layer, data, readTime);
480 }
481
ReadRSMetrics(double untilTime, uint32_t layer, std::vector<uint8_t>& data, double& readTime)482 bool RSFile::ReadRSMetrics(double untilTime, uint32_t layer, std::vector<uint8_t>& data, double& readTime)
483 {
484 return ReadTrackData(
485 { &RSFileLayer::readindexRsMetrics, &RSFileLayer::rsMetrics }, untilTime, layer, data, readTime);
486 }
487
ReadRenderMetrics(double untilTime, uint32_t layer, std::vector<uint8_t>& data, double& readTime)488 bool RSFile::ReadRenderMetrics(double untilTime, uint32_t layer, std::vector<uint8_t>& data, double& readTime)
489 {
490 return ReadTrackData(
491 { &RSFileLayer::readindexRenderMetrics, &RSFileLayer::renderMetrics }, untilTime, layer, data, readTime);
492 }
493
ReadOGLMetrics(double untilTime, uint32_t layer, std::vector<uint8_t>& data, double& readTime)494 bool RSFile::ReadOGLMetrics(double untilTime, uint32_t layer, std::vector<uint8_t>& data, double& readTime)
495 {
496 return ReadTrackData(
497 { &RSFileLayer::readindexOglMetrics, &RSFileLayer::oglMetrics }, untilTime, layer, data, readTime);
498 }
499
ReadGFXMetrics(double untilTime, uint32_t layer, std::vector<uint8_t>& data, double& readTime)500 bool RSFile::ReadGFXMetrics(double untilTime, uint32_t layer, std::vector<uint8_t>& data, double& readTime)
501 {
502 return ReadTrackData(
503 { &RSFileLayer::readindexGfxMetrics, &RSFileLayer::gfxMetrics }, untilTime, layer, data, readTime);
504 }
505
GetDataCopy(std::vector<uint8_t>& data)506 bool RSFile::GetDataCopy(std::vector<uint8_t>& data)
507 {
508 const std::lock_guard<std::mutex> lgMutex(writeMutex_);
509
510 WriteHeaders(); // Make sure the header is written
511
512 size_t fileSize = Utils::FileSize(file_);
513 if (fileSize == 0) {
514 return false;
515 }
516
517 // File size threshold is set to ensure that the file is valid
518 const size_t maxFileSize = 300000000;
519 if (fileSize > maxFileSize) {
520 return false;
521 }
522
523 data.clear();
524 data.resize(fileSize);
525
526 const int64_t position = static_cast<int64_t>(Utils::FileTell(file_));
527 Utils::FileSeek(file_, 0, SEEK_SET);
528 Utils::FileRead(file_, data.data(), fileSize);
529 Utils::FileSeek(file_, position, SEEK_SET); // set ptr back
530
531 return true;
532 }
533
HasLayer(uint32_t layer) const534 bool RSFile::HasLayer(uint32_t layer) const
535 {
536 // if this condition is true, then layerData_ is surely not empty
537 return layer < layerData_.size();
538 }
539
540 // ***********************************
541 // *** READ/SAVE HEADERS
542
WriteHeaders()543 void RSFile::WriteHeaders()
544 {
545 if (!(file_ && wasChanged_)) {
546 return;
547 }
548 for (size_t i = 0; i < layerData_.size(); i++) {
549 LayerWriteHeader(i);
550 }
551 WriteHeader();
552 }
553
ReadHeaders()554 void RSFile::ReadHeaders()
555 {
556 ReadHeader();
557 for (size_t i = 0; i < layerData_.size(); i++) {
558 LayerReadHeader(i);
559 }
560 }
561
Close()562 void RSFile::Close()
563 {
564 if (!file_) {
565 return;
566 }
567
568 const std::lock_guard<std::mutex> lgMutex(writeMutex_);
569
570 WriteHeaders();
571
572 Utils::FileClose(file_);
573 file_ = nullptr;
574
575 headerOff_ = 0;
576 headerPidList_.clear();
577 layerData_.clear();
578
579 writeDataOff_ = 0;
580 wasChanged_ = false;
581 }
582
WriteTrackData(LayerTrackMarkupPtr trackMarkup, uint32_t layer, double time, const void* data, size_t size)583 void RSFile::WriteTrackData(LayerTrackMarkupPtr trackMarkup, uint32_t layer, double time, const void* data, size_t size)
584 {
585 const std::lock_guard<std::mutex> lgMutex(writeMutex_);
586
587 if (!file_ || !HasLayer(layer)) {
588 return;
589 }
590
591 RSFileLayer& layerData = layerData_[layer];
592 (layerData.*trackMarkup).emplace_back(writeDataOff_, size + sizeof(time));
593
594 Utils::FileSeek(file_, writeDataOff_, SEEK_SET);
595 Utils::FileWrite(&time, sizeof(time), 1, file_);
596 Utils::FileWrite(data, size, 1, file_);
597 writeDataOff_ = Utils::FileTell(file_);
598 }
599
ReadTrackData( LayerTrackPtr track, double untilTime, uint32_t layer, std::vector<uint8_t>& data, double& readTime)600 bool RSFile::ReadTrackData(
601 LayerTrackPtr track, double untilTime, uint32_t layer, std::vector<uint8_t>& data, double& readTime)
602 {
603 if (!file_ || !HasLayer(layer)) {
604 return false;
605 }
606
607 RSFileLayer& layerData = layerData_[layer];
608 auto& trackIndex = layerData.*track.index;
609 auto& trackData = layerData.*track.markup;
610
611 if (trackIndex >= trackData.size()) {
612 return false;
613 }
614
615 Utils::FileSeek(file_, trackData[trackIndex].first, SEEK_SET);
616 Utils::FileRead(&readTime, sizeof(readTime), 1, file_);
617 if (readTime > untilTime) {
618 return false;
619 }
620
621 const uint32_t dataLen = trackData[trackIndex].second - RSFileLayer::MARKUP_SIZE;
622 data.resize(dataLen);
623 Utils::FileRead(data.data(), dataLen, 1, file_);
624
625 trackIndex++;
626 return true;
627 }
628
ReadTrackDataRestart(LayerTrackIndexPtr trackIndex, uint32_t layer)629 void RSFile::ReadTrackDataRestart(LayerTrackIndexPtr trackIndex, uint32_t layer)
630 {
631 if (!HasLayer(layer)) {
632 return;
633 }
634
635 RSFileLayer& layerData = layerData_[layer];
636 layerData.*trackIndex = 0;
637 }
638
TrackEOF(LayerTrackPtr track, uint32_t layer) const639 bool RSFile::TrackEOF(LayerTrackPtr track, uint32_t layer) const
640 {
641 if (!file_ || !HasLayer(layer)) {
642 return true;
643 }
644
645 const RSFileLayer& layerData = layerData_[layer];
646 return layerData.*track.index >= (layerData.*track.markup).size();
647 }
648
GetHeaderFirstFrame() const649 const std::string& RSFile::GetHeaderFirstFrame() const
650 {
651 return headerFirstFrame_;
652 }
653
AddHeaderFirstFrame(const std::string& dataFirstFrame)654 void RSFile::AddHeaderFirstFrame(const std::string& dataFirstFrame)
655 {
656 headerFirstFrame_ = dataFirstFrame;
657 wasChanged_ = true;
658 }
659
GetAnimeStartTimes() const660 const std::vector<std::pair<uint64_t, int64_t>>& RSFile::GetAnimeStartTimes() const
661 {
662 return headerAnimeStartTimes_;
663 }
664
AddAnimeStartTimes(const std::vector<std::pair<uint64_t, int64_t>>& startTimes)665 void RSFile::AddAnimeStartTimes(const std::vector<std::pair<uint64_t, int64_t>>& startTimes)
666 {
667 headerAnimeStartTimes_ = startTimes;
668 wasChanged_ = true;
669 }
670
ConvertVsyncId2Time(int64_t vsyncId)671 double RSFile::ConvertVsyncId2Time(int64_t vsyncId)
672 {
673 if (mapVsyncId2Time_.count(vsyncId)) {
674 return mapVsyncId2Time_[vsyncId];
675 }
676 constexpr int64_t MAX_INT64T = 0x7FFFFFFFFFFFFFFF;
677 int64_t minVSync = MAX_INT64T;
678 int64_t maxVSync = -1;
679 for (const auto& item : mapVsyncId2Time_) {
680 if (minVSync > item.first) {
681 minVSync = item.first;
682 }
683 if (maxVSync < item.first) {
684 maxVSync = item.first;
685 }
686 }
687 if (vsyncId < minVSync) {
688 if (mapVsyncId2Time_.count(minVSync)) {
689 return mapVsyncId2Time_[minVSync];
690 }
691 }
692 if (vsyncId > maxVSync) {
693 if (mapVsyncId2Time_.count(maxVSync)) {
694 return mapVsyncId2Time_[maxVSync];
695 }
696 }
697 return 0.0;
698 }
699
ConvertTime2VsyncId(double time)700 int64_t RSFile::ConvertTime2VsyncId(double time)
701 {
702 constexpr double numericError = 1e-5;
703 for (const auto& item : mapVsyncId2Time_) {
704 if (time <= item.second + numericError) {
705 return item.first;
706 }
707 }
708 return 0;
709 }
710
CacheVsyncId2Time(uint32_t layer)711 void RSFile::CacheVsyncId2Time(uint32_t layer)
712 {
713 mapVsyncId2Time_.clear();
714
715 if (!file_ || !HasLayer(layer)) {
716 return;
717 }
718
719 LayerTrackPtr track = { &RSFileLayer::readindexRsMetrics, &RSFileLayer::rsMetrics };
720
721 RSFileLayer& layerData = layerData_[layer];
722 auto& trackData = layerData.*track.markup;
723
724 double readTime;
725 std::vector<char> data;
726
727 for (const auto& trackItem : trackData) {
728 Utils::FileSeek(file_, trackItem.first, SEEK_SET);
729 Utils::FileRead(&readTime, sizeof(readTime), 1, file_);
730
731 constexpr char packetTypeRsMetrics = 2;
732 char packetType;
733
734 Utils::FileRead(&packetType, sizeof(packetType), 1, file_);
735 if (packetType != packetTypeRsMetrics) {
736 continue;
737 }
738
739 const int32_t dataLen = trackItem.second - RSFileLayer::MARKUP_SIZE - 1;
740 constexpr int32_t dataLenMax = 100'000;
741 if (dataLen < 0 || dataLen > dataLenMax) {
742 continue;
743 }
744 data.resize(dataLen);
745 Utils::FileRead(data.data(), dataLen, 1, file_);
746
747 RSCaptureData captureData;
748 captureData.Deserialize(data);
749 int64_t readVsyncId = captureData.GetPropertyInt64(RSCaptureData::KEY_RS_VSYNC_ID);
750 if (readVsyncId > 0 && !mapVsyncId2Time_.count(readVsyncId)) {
751 mapVsyncId2Time_.insert({readVsyncId, readTime});
752 }
753 }
754 }
755
756 } // namespace OHOS::Rosen