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