• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 bool 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 false;
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_ = Utils::FileTell(file_);
63 
64     wasChanged_ = true;
65     return true;
66 }
67 
Open(const std::string & fname)68 bool RSFile::Open(const std::string& fname)
69 {
70     if (file_ != nullptr) {
71         Close();
72     }
73 
74 #ifdef RENDER_PROFILER_APPLICATION
75     file_ = Utils::FileOpen(fname, "rb");
76 #else
77     file_ = Utils::FileOpen(fname, "rbe");
78 #endif
79     if (file_ == nullptr) {
80         return false;
81     }
82 
83     uint32_t headerId;
84     Utils::FileRead(&headerId, sizeof(headerId), 1, file_);
85     if (headerId != 'ROHR') { // Prohibit too old file versions
86         Utils::FileClose(file_);
87         file_ = nullptr;
88         return false;
89     }
90 
91     Utils::FileRead(&versionId_, sizeof(versionId_), 1, file_);
92     Utils::FileRead(&headerOff_, sizeof(headerOff_), 1, file_);
93     Utils::FileSeek(file_, 0, SEEK_END);
94     writeDataOff_ = Utils::FileTell(file_);
95     Utils::FileSeek(file_, headerOff_, SEEK_SET);
96     std::string errReason = ReadHeaders();
97     if (errReason.size()) {
98         Utils::FileClose(file_);
99         file_ = nullptr;
100         return false;
101     }
102     wasChanged_ = false;
103 
104     return true;
105 }
106 
IsOpen() const107 bool RSFile::IsOpen() const
108 {
109     return file_ != nullptr;
110 }
111 
SetWriteTime(double time)112 void RSFile::SetWriteTime(double time)
113 {
114     writeStartTime_ = time;
115 }
116 
GetWriteTime() const117 double RSFile::GetWriteTime() const
118 {
119     return writeStartTime_;
120 }
121 
122 // ***********************************
123 // *** GLOBAL HEADER
124 
AddHeaderPid(pid_t pid)125 void RSFile::AddHeaderPid(pid_t pid)
126 {
127     if (std::find(std::begin(headerPidList_), std::end(headerPidList_), pid) != std::end(headerPidList_)) {
128         return;
129     }
130     headerPidList_.push_back(pid);
131 
132     wasChanged_ = true;
133 }
134 
GetHeaderPids() const135 const std::vector<pid_t>& RSFile::GetHeaderPids() const
136 {
137     return headerPidList_;
138 }
139 
SetPreparedHeader(const std::vector<uint8_t> & headerData)140 void RSFile::SetPreparedHeader(const std::vector<uint8_t>& headerData)
141 {
142     preparedHeader_ = headerData;
143 }
144 
GetPreparedHeader(std::vector<uint8_t> & headerData)145 void RSFile::GetPreparedHeader(std::vector<uint8_t>& headerData)
146 {
147     headerData = preparedHeader_;
148 }
149 
SetPreparedHeaderMode(bool mode)150 void RSFile::SetPreparedHeaderMode(bool mode)
151 {
152     preparedHeaderMode_ = mode;
153 }
154 
WriteHeader()155 void RSFile::WriteHeader()
156 {
157     // WARNING removed redundant mutex
158     if (!file_) {
159         return;
160     }
161 
162     headerOff_ = writeDataOff_;
163     Utils::FileSeek(file_, writeDataOff_, SEEK_SET);
164 
165     if (preparedHeaderMode_) {
166         // WRITE RAW
167         Utils::FileWrite(preparedHeader_.data(), 1, preparedHeader_.size(), file_);
168         preparedHeader_.clear();
169     } else {
170         // WRITE TIME START
171         Utils::FileWrite(&writeStartTime_, 1, sizeof(writeStartTime_), file_);
172 
173         // SAVE PID LIST
174         const uint32_t recordSize = headerPidList_.size();
175         Utils::FileWrite(&recordSize, sizeof(recordSize), 1, file_);
176         Utils::FileWrite(headerPidList_.data(), headerPidList_.size(), sizeof(pid_t), file_);
177 
178         // SAVE FIRST SCREEN
179         uint32_t firstScrSize = headerFirstFrame_.size();
180         Utils::FileWrite(&firstScrSize, sizeof(firstScrSize), 1, file_);
181         Utils::FileWrite(headerFirstFrame_.data(), headerFirstFrame_.size(), 1, file_);
182 
183         if (versionId_ >= RSFILE_VERSION_RENDER_ANIMESTARTTIMES_ADDED) {
184             // ANIME START TIMES
185             uint32_t startTimesSize = headerAnimeStartTimes_.size();
186             Utils::FileWrite(&startTimesSize, sizeof(startTimesSize), 1, file_);
187             Utils::FileWrite(headerAnimeStartTimes_.data(),
188                 headerAnimeStartTimes_.size() * sizeof(std::pair<uint64_t, int64_t>), 1, file_);
189         }
190 
191         // ALL TEXTURES
192         ImageCache::Serialize(file_);
193     }
194 
195     // SAVE LAYERS OFFSETS
196     const uint32_t recordSize = layerData_.size();
197     Utils::FileWrite(&recordSize, sizeof(recordSize), 1, file_);
198     for (auto& i : layerData_) {
199         Utils::FileWrite(&i.layerHeader, sizeof(i.layerHeader), 1, file_);
200     }
201 
202     constexpr int preambleSize = 8;
203     Utils::FileSeek(file_, preambleSize, SEEK_SET);
204     Utils::FileWrite(&headerOff_, sizeof(headerOff_), 1, file_);
205 }
206 
ReadHeaderPidList()207 bool RSFile::ReadHeaderPidList()
208 {
209     uint32_t recordSize;
210     Utils::FileRead(&recordSize, sizeof(recordSize), 1, file_);
211     if (recordSize > chunkSizeMax) {
212         return false;
213     }
214     headerPidList_.resize(recordSize);
215     Utils::FileRead(headerPidList_.data(), headerPidList_.size(), sizeof(pid_t), file_);
216     return true;
217 }
218 
ReadHeaderFirstScreen()219 bool RSFile::ReadHeaderFirstScreen()
220 {
221     // READ FIRST SCREEN
222     uint32_t firstScrSize;
223     Utils::FileRead(&firstScrSize, sizeof(firstScrSize), 1, file_);
224     if (firstScrSize > chunkSizeMax) {
225         return false;
226     }
227     headerFirstFrame_.resize(firstScrSize);
228     Utils::FileRead(headerFirstFrame_.data(), headerFirstFrame_.size(), 1, file_);
229     return true;
230 }
231 
ReadHeader()232 std::string RSFile::ReadHeader()
233 {
234     const std::string errCode = "can't read header";
235     if (!file_) {
236         return errCode;
237     }
238 
239     Utils::FileSeek(file_, headerOff_, SEEK_SET);
240     const size_t subHeaderStartOff = Utils::FileTell(file_);
241 
242     // READ what was write start time
243     Utils::FileRead(&writeStartTime_, 1, sizeof(writeStartTime_), file_);
244 
245     if (!ReadHeaderPidList()) {
246         return errCode;
247     }
248 
249     if (!ReadHeaderFirstScreen()) {
250         return errCode;
251     }
252 
253      // READ ANIME START TIMES
254     if (versionId_ >= RSFILE_VERSION_RENDER_ANIMESTARTTIMES_ADDED) {
255         uint32_t startTimesSize;
256         Utils::FileRead(&startTimesSize, sizeof(startTimesSize), 1, file_);
257         if (startTimesSize > chunkSizeMax) {
258             return errCode;
259         }
260         headerAnimeStartTimes_.resize(startTimesSize);
261         Utils::FileRead(headerAnimeStartTimes_.data(),
262             headerAnimeStartTimes_.size() * sizeof(std::pair<uint64_t, int64_t>), 1, file_);
263     }
264 
265     // ALL TEXTURES
266     ImageCache::Deserialize(file_);
267 
268     if (preparedHeaderMode_) {
269         const size_t subHeaderEndOff = Utils::FileTell(file_);
270         Utils::FileSeek(file_, subHeaderStartOff, SEEK_SET);
271         const size_t subHeaderLen = subHeaderEndOff - subHeaderStartOff;
272         if (subHeaderLen > headerSizeMax) {
273             return errCode;
274         }
275         preparedHeader_.resize(subHeaderLen);
276         Utils::FileRead(preparedHeader_.data(), subHeaderLen, 1, file_);
277     }
278 
279     // READ LAYERS OFFSETS
280     uint32_t recordSize;
281     Utils::FileRead(&recordSize, sizeof(recordSize), 1, file_);
282     if (recordSize > chunkSizeMax) {
283         return errCode;
284     }
285     layerData_.resize(recordSize);
286     for (auto& i : layerData_) {
287         Utils::FileRead(&i.layerHeader, sizeof(i.layerHeader), 1, file_);
288         i.readindexRsData = 0;
289     }
290     return "";
291 }
292 
293 // ***********************************
294 // *** LAYER HEADER
295 
AddLayer()296 uint32_t RSFile::AddLayer()
297 {
298     const uint32_t newId = layerData_.size();
299     const RSFileLayer data;
300     layerData_.push_back(data);
301 
302     wasChanged_ = true;
303 
304     return newId;
305 }
306 
LayerAddHeaderProperty(uint32_t layer,const std::string & name,const std::string & value)307 void RSFile::LayerAddHeaderProperty(uint32_t layer, const std::string& name, const std::string& value)
308 {
309     if (!HasLayer(layer)) {
310         return;
311     }
312 
313     RSFileLayer& layerData = layerData_[layer];
314     layerData.property.SetProperty(name, value);
315 
316     wasChanged_ = true;
317 }
318 
LayerWriteHeader(uint32_t layer)319 void RSFile::LayerWriteHeader(uint32_t layer)
320 {
321     if (!file_ || !HasLayer(layer)) {
322         return;
323     }
324 
325     RSFileLayer& layerData = layerData_[layer];
326 
327     const uint32_t layerHeaderOff = writeDataOff_; // position of layer table
328     Utils::FileSeek(file_, writeDataOff_, SEEK_SET);
329 
330     std::vector<char> propertyData;
331     layerData.property.Serialize(propertyData);
332 
333     // SAVE LAYER PROPERTY
334     uint32_t recordSize = propertyData.size();
335     Utils::FileWrite(&recordSize, sizeof(recordSize), 1, file_);
336     Utils::FileWrite(propertyData.data(), propertyData.size(), 1, file_);
337 
338     LayerWriteHeaderOfTrack(layerData.rsData);
339     LayerWriteHeaderOfTrack(layerData.oglData);
340     LayerWriteHeaderOfTrack(layerData.rsMetrics);
341     if (versionId_ >= RSFILE_VERSION_RENDER_METRICS_ADDED) {
342         LayerWriteHeaderOfTrack(layerData.renderMetrics);
343     }
344     if (versionId_ >= RSFILE_VERSION_LOG_EVENTS_ADDED) {
345         LayerWriteHeaderOfTrack(layerData.logEvents);
346     }
347     LayerWriteHeaderOfTrack(layerData.oglMetrics);
348     LayerWriteHeaderOfTrack(layerData.gfxMetrics);
349     layerData.layerHeader = { layerHeaderOff, Utils::FileTell(file_) - layerHeaderOff }; // position of layer table
350 
351     writeDataOff_ = Utils::FileTell(file_);
352 }
353 
LayerReadHeader(uint32_t layer)354 std::string RSFile::LayerReadHeader(uint32_t layer)
355 {
356     const std::string errCode = "can't read layer header";
357     if (!file_ || !HasLayer(layer)) {
358         return errCode;
359     }
360 
361     RSFileLayer& layerData = layerData_[layer];
362 
363     Utils::FileSeek(file_, layerData.layerHeader.first, SEEK_SET);
364 
365     // READ LAYER PROPERTY
366     uint32_t recordSize = 0u;
367     Utils::FileRead(&recordSize, sizeof(recordSize), 1, file_);
368     if (recordSize > chunkSizeMax) {
369         return errCode;
370     }
371     std::vector<char> propertyData;
372     propertyData.resize(recordSize);
373     Utils::FileRead(propertyData.data(), recordSize, 1, file_);
374 
375     layerData.property.Deserialize(propertyData);
376     LayerReadHeaderOfTrack(layerData.rsData);
377     LayerReadHeaderOfTrack(layerData.oglData);
378     LayerReadHeaderOfTrack(layerData.rsMetrics);
379     if (versionId_ >= RSFILE_VERSION_RENDER_METRICS_ADDED) {
380         LayerReadHeaderOfTrack(layerData.renderMetrics);
381     }
382     if (versionId_ >= RSFILE_VERSION_LOG_EVENTS_ADDED) {
383         LayerReadHeaderOfTrack(layerData.logEvents);
384     }
385     LayerReadHeaderOfTrack(layerData.oglMetrics);
386     LayerReadHeaderOfTrack(layerData.gfxMetrics);
387 
388     return "";
389 }
390 
GetVersion() const391 uint32_t RSFile::GetVersion() const
392 {
393     return versionId_;
394 }
395 
SetVersion(uint32_t version)396 void RSFile::SetVersion(uint32_t version)
397 {
398     versionId_ = version;
399 }
400 
401 // ***********************************
402 // *** LAYER DATA - UNWRITE
403 
UnwriteRSData()404 void RSFile::UnwriteRSData()
405 {
406     UnwriteTrackData(&RSFileLayer::rsData, 0);
407 }
408 
409 // ***********************************
410 // *** LAYER DATA - WRITE
411 
WriteRSData(double time,const void * data,size_t size)412 void RSFile::WriteRSData(double time, const void* data, size_t size)
413 {
414     WriteTrackData(&RSFileLayer::rsData, 0, time, data, size);
415 }
416 
WriteOGLData(uint32_t layer,double time,const void * data,size_t size)417 void RSFile::WriteOGLData(uint32_t layer, double time, const void* data, size_t size)
418 {
419     WriteTrackData(&RSFileLayer::oglData, layer, time, data, size);
420 }
421 
WriteRSMetrics(uint32_t layer,double time,const void * data,size_t size)422 void RSFile::WriteRSMetrics(uint32_t layer, double time, const void* data, size_t size)
423 {
424     WriteTrackData(&RSFileLayer::rsMetrics, layer, time, data, size);
425 }
426 
WriteRenderMetrics(uint32_t layer,double time,const void * data,size_t size)427 void RSFile::WriteRenderMetrics(uint32_t layer, double time, const void* data, size_t size)
428 {
429     WriteTrackData(&RSFileLayer::renderMetrics, layer, time, data, size);
430 }
431 
WriteOGLMetrics(uint32_t layer,double time,uint32_t,const void * data,size_t size)432 void RSFile::WriteOGLMetrics(uint32_t layer, double time, uint32_t /*frame*/, const void* data, size_t size)
433 {
434     WriteTrackData(&RSFileLayer::oglMetrics, layer, time, data, size);
435 }
436 
WriteGFXMetrics(uint32_t layer,double time,uint32_t,const void * data,size_t size)437 void RSFile::WriteGFXMetrics(uint32_t layer, double time, uint32_t /*frame*/, const void* data, size_t size)
438 {
439     WriteTrackData(&RSFileLayer::gfxMetrics, layer, time, data, size);
440 }
441 
WriteLogEvent(uint32_t layer,double time,const void * data,size_t size)442 void RSFile::WriteLogEvent(uint32_t layer, double time, const void* data, size_t size)
443 {
444     WriteTrackData(&RSFileLayer::logEvents, layer, time, data, size);
445 }
446 
447 // ***********************************
448 // *** LAYER DATA - READ
449 
ReadRSDataRestart()450 void RSFile::ReadRSDataRestart()
451 {
452     ReadTrackDataRestart(&RSFileLayer::readindexRsData, 0);
453 }
454 
ReadOGLDataRestart(uint32_t layer)455 void RSFile::ReadOGLDataRestart(uint32_t layer)
456 {
457     ReadTrackDataRestart(&RSFileLayer::readindexOglData, layer);
458 }
459 
ReadRSMetricsRestart(uint32_t layer)460 void RSFile::ReadRSMetricsRestart(uint32_t layer)
461 {
462     ReadTrackDataRestart(&RSFileLayer::readindexRsMetrics, layer);
463 }
464 
ReadRenderMetricsRestart(uint32_t layer)465 void RSFile::ReadRenderMetricsRestart(uint32_t layer)
466 {
467     ReadTrackDataRestart(&RSFileLayer::readindexRenderMetrics, layer);
468 }
469 
ReadOGLMetricsRestart(uint32_t layer)470 void RSFile::ReadOGLMetricsRestart(uint32_t layer)
471 {
472     ReadTrackDataRestart(&RSFileLayer::readindexOglMetrics, layer);
473 }
474 
ReadGFXMetricsRestart(uint32_t layer)475 void RSFile::ReadGFXMetricsRestart(uint32_t layer)
476 {
477     ReadTrackDataRestart(&RSFileLayer::readindexGfxMetrics, layer);
478 }
479 
ReadLogEventRestart(uint32_t layer)480 void RSFile::ReadLogEventRestart(uint32_t layer)
481 {
482     ReadTrackDataRestart(&RSFileLayer::readindexLogEvents, layer);
483 }
484 
RSDataEOF() const485 bool RSFile::RSDataEOF() const
486 {
487     return TrackEOF({ &RSFileLayer::readindexRsData, &RSFileLayer::rsData }, 0);
488 }
489 
OGLDataEOF(uint32_t layer) const490 bool RSFile::OGLDataEOF(uint32_t layer) const
491 {
492     return TrackEOF({ &RSFileLayer::readindexOglData, &RSFileLayer::oglData }, layer);
493 }
494 
RSMetricsEOF(uint32_t layer) const495 bool RSFile::RSMetricsEOF(uint32_t layer) const
496 {
497     return TrackEOF({ &RSFileLayer::readindexRsMetrics, &RSFileLayer::rsMetrics }, layer);
498 }
499 
RenderMetricsEOF(uint32_t layer) const500 bool RSFile::RenderMetricsEOF(uint32_t layer) const
501 {
502     return TrackEOF({ &RSFileLayer::readindexRenderMetrics, &RSFileLayer::renderMetrics }, layer);
503 }
504 
OGLMetricsEOF(uint32_t layer) const505 bool RSFile::OGLMetricsEOF(uint32_t layer) const
506 {
507     return TrackEOF({ &RSFileLayer::readindexOglMetrics, &RSFileLayer::oglMetrics }, layer);
508 }
509 
GFXMetricsEOF(uint32_t layer) const510 bool RSFile::GFXMetricsEOF(uint32_t layer) const
511 {
512     return TrackEOF({ &RSFileLayer::readindexGfxMetrics, &RSFileLayer::gfxMetrics }, layer);
513 }
514 
LogEventEOF(uint32_t layer) const515 bool RSFile::LogEventEOF(uint32_t layer) const
516 {
517     return TrackEOF({ &RSFileLayer::readindexLogEvents, &RSFileLayer::logEvents }, layer);
518 }
519 
ReadRSData(double untilTime,std::vector<uint8_t> & data,double & readTime)520 bool RSFile::ReadRSData(double untilTime, std::vector<uint8_t>& data, double& readTime)
521 {
522     readTime = 0.0;
523     if (!file_ || layerData_.empty()) {
524         return false;
525     }
526 
527     RSFileLayer& layerData = layerData_[0];
528 
529     if (layerData.readindexRsData >= layerData.rsData.size()) {
530         return false;
531     }
532 
533     Utils::FileSeek(file_, layerData.rsData[layerData.readindexRsData].first, SEEK_SET);
534 
535     Utils::FileRead(&readTime, sizeof(readTime), 1, file_);
536     constexpr double epsilon = 1e-9;
537     if (readTime >= untilTime + epsilon) {
538         return false;
539     }
540 
541     const uint32_t dataLen = layerData.rsData[layerData.readindexRsData].second - sizeof(readTime);
542     if (dataLen > chunkSizeMax) {
543         return false;
544     }
545     data.resize(dataLen);
546     Utils::FileRead(data.data(), dataLen, 1, file_);
547 
548     layerData.readindexRsData++;
549     return true;
550 }
551 
ReadOGLData(double untilTime,uint32_t layer,std::vector<uint8_t> & data,double & readTime)552 bool RSFile::ReadOGLData(double untilTime, uint32_t layer, std::vector<uint8_t>& data, double& readTime)
553 {
554     return ReadTrackData({ &RSFileLayer::readindexOglData, &RSFileLayer::oglData }, untilTime, layer, data, readTime);
555 }
556 
ReadRSMetrics(double untilTime,uint32_t layer,std::vector<uint8_t> & data,double & readTime)557 bool RSFile::ReadRSMetrics(double untilTime, uint32_t layer, std::vector<uint8_t>& data, double& readTime)
558 {
559     return ReadTrackData(
560         { &RSFileLayer::readindexRsMetrics, &RSFileLayer::rsMetrics }, untilTime, layer, data, readTime);
561 }
562 
ReadRenderMetrics(double untilTime,uint32_t layer,std::vector<uint8_t> & data,double & readTime)563 bool RSFile::ReadRenderMetrics(double untilTime, uint32_t layer, std::vector<uint8_t>& data, double& readTime)
564 {
565     return ReadTrackData(
566         { &RSFileLayer::readindexRenderMetrics, &RSFileLayer::renderMetrics }, untilTime, layer, data, readTime);
567 }
568 
ReadOGLMetrics(double untilTime,uint32_t layer,std::vector<uint8_t> & data,double & readTime)569 bool RSFile::ReadOGLMetrics(double untilTime, uint32_t layer, std::vector<uint8_t>& data, double& readTime)
570 {
571     return ReadTrackData(
572         { &RSFileLayer::readindexOglMetrics, &RSFileLayer::oglMetrics }, untilTime, layer, data, readTime);
573 }
574 
ReadGFXMetrics(double untilTime,uint32_t layer,std::vector<uint8_t> & data,double & readTime)575 bool RSFile::ReadGFXMetrics(double untilTime, uint32_t layer, std::vector<uint8_t>& data, double& readTime)
576 {
577     return ReadTrackData(
578         { &RSFileLayer::readindexGfxMetrics, &RSFileLayer::gfxMetrics }, untilTime, layer, data, readTime);
579 }
580 
ReadLogEvent(double untilTime,uint32_t layer,std::vector<uint8_t> & data,double & readTime)581 bool RSFile::ReadLogEvent(double untilTime, uint32_t layer, std::vector<uint8_t>& data, double& readTime)
582 {
583     return ReadTrackData(
584         { &RSFileLayer::readindexLogEvents, &RSFileLayer::logEvents }, untilTime, layer, data, readTime);
585 }
586 
GetDataCopy(std::vector<uint8_t> & data)587 bool RSFile::GetDataCopy(std::vector<uint8_t>& data)
588 {
589     const std::lock_guard<std::mutex> lgMutex(writeMutex_);
590 
591     WriteHeaders(); // Make sure the header is written
592 
593     size_t fileSize = Utils::FileSize(file_);
594     if (fileSize == 0) {
595         return false;
596     }
597 
598     // File size threshold is set to ensure that the file is valid
599     const size_t maxFileSize = 300000000;
600     if (fileSize > maxFileSize) {
601         return false;
602     }
603 
604     data.clear();
605     data.resize(fileSize);
606 
607     const int64_t position = static_cast<int64_t>(Utils::FileTell(file_));
608     Utils::FileSeek(file_, 0, SEEK_SET);
609     Utils::FileRead(file_, data.data(), fileSize);
610     Utils::FileSeek(file_, position, SEEK_SET); // set ptr back
611 
612     return true;
613 }
614 
HasLayer(uint32_t layer) const615 bool RSFile::HasLayer(uint32_t layer) const
616 {
617     // if this condition is true, then layerData_ is surely not empty
618     return layer < layerData_.size();
619 }
620 
621 // ***********************************
622 // *** READ/SAVE HEADERS
623 
WriteHeaders()624 void RSFile::WriteHeaders()
625 {
626     if (!(file_ && wasChanged_)) {
627         return;
628     }
629     for (size_t i = 0; i < layerData_.size(); i++) {
630         LayerWriteHeader(i);
631     }
632     WriteHeader();
633 }
634 
ReadHeaders()635 std::string RSFile::ReadHeaders()
636 {
637     std::string errReason = ReadHeader();
638     if (errReason.size()) {
639         return errReason;
640     }
641     for (size_t i = 0; i < layerData_.size(); i++) {
642         errReason = LayerReadHeader(i);
643         if (errReason.size()) {
644             return errReason;
645         }
646     }
647     return "";
648 }
649 
Close()650 void RSFile::Close()
651 {
652     if (!file_) {
653         return;
654     }
655 
656     const std::lock_guard<std::mutex> lgMutex(writeMutex_);
657 
658     WriteHeaders();
659 
660     Utils::FileClose(file_);
661     file_ = nullptr;
662 
663     headerOff_ = 0;
664     headerPidList_.clear();
665     layerData_.clear();
666 
667     writeDataOff_ = 0;
668     wasChanged_ = false;
669 
670     preparedHeaderMode_ = false;
671     headerFirstFrame_.clear();
672     headerAnimeStartTimes_.clear();
673     preparedHeader_.clear();
674     mapVsyncId2Time_.clear();
675 }
676 
UnwriteTrackData(LayerTrackMarkupPtr trackMarkup,uint32_t layer)677 void RSFile::UnwriteTrackData(LayerTrackMarkupPtr trackMarkup, uint32_t layer)
678 {
679     const std::lock_guard<std::mutex> lgMutex(writeMutex_);
680 
681     if (!file_ || !HasLayer(layer)) {
682         return;
683     }
684 
685     RSFileLayer& layerData = layerData_[layer];
686     if ((layerData.*trackMarkup).size()) {
687         (layerData.*trackMarkup).pop_back();
688     }
689 }
690 
WriteTrackData(LayerTrackMarkupPtr trackMarkup,uint32_t layer,double time,const void * data,size_t size)691 void RSFile::WriteTrackData(LayerTrackMarkupPtr trackMarkup, uint32_t layer, double time, const void* data, size_t size)
692 {
693     const std::lock_guard<std::mutex> lgMutex(writeMutex_);
694 
695     if (!file_ || !HasLayer(layer)) {
696         return;
697     }
698 
699     RSFileLayer& layerData = layerData_[layer];
700     (layerData.*trackMarkup).emplace_back(writeDataOff_, size + sizeof(time));
701 
702     Utils::FileSeek(file_, writeDataOff_, SEEK_SET);
703     Utils::FileWrite(&time, sizeof(time), 1, file_);
704     Utils::FileWrite(data, size, 1, file_);
705     writeDataOff_ = Utils::FileTell(file_);
706 }
707 
ReadTrackData(LayerTrackPtr track,double untilTime,uint32_t layer,std::vector<uint8_t> & data,double & readTime)708 bool RSFile::ReadTrackData(
709     LayerTrackPtr track, double untilTime, uint32_t layer, std::vector<uint8_t>& data, double& readTime)
710 {
711     if (!file_ || !HasLayer(layer)) {
712         return false;
713     }
714 
715     RSFileLayer& layerData = layerData_[layer];
716     auto& trackIndex = layerData.*track.index;
717     auto& trackData = layerData.*track.markup;
718 
719     if (trackIndex >= trackData.size()) {
720         return false;
721     }
722 
723     Utils::FileSeek(file_, trackData[trackIndex].first, SEEK_SET);
724     Utils::FileRead(&readTime, sizeof(readTime), 1, file_);
725     if (readTime > untilTime) {
726         return false;
727     }
728 
729     const uint32_t dataLen = trackData[trackIndex].second - RSFileLayer::MARKUP_SIZE;
730     if (dataLen > chunkSizeMax) {
731         return false;
732     }
733     data.resize(dataLen);
734     Utils::FileRead(data.data(), dataLen, 1, file_);
735 
736     trackIndex++;
737     return true;
738 }
739 
ReadTrackDataRestart(LayerTrackIndexPtr trackIndex,uint32_t layer)740 void RSFile::ReadTrackDataRestart(LayerTrackIndexPtr trackIndex, uint32_t layer)
741 {
742     if (!HasLayer(layer)) {
743         return;
744     }
745 
746     RSFileLayer& layerData = layerData_[layer];
747     layerData.*trackIndex = 0;
748 }
749 
TrackEOF(LayerTrackPtr track,uint32_t layer) const750 bool RSFile::TrackEOF(LayerTrackPtr track, uint32_t layer) const
751 {
752     if (!file_ || !HasLayer(layer)) {
753         return true;
754     }
755 
756     const RSFileLayer& layerData = layerData_[layer];
757     return layerData.*track.index >= (layerData.*track.markup).size();
758 }
759 
GetHeaderFirstFrame() const760 const std::string& RSFile::GetHeaderFirstFrame() const
761 {
762     return headerFirstFrame_;
763 }
764 
AddHeaderFirstFrame(const std::string & dataFirstFrame)765 void RSFile::AddHeaderFirstFrame(const std::string& dataFirstFrame)
766 {
767     headerFirstFrame_ = dataFirstFrame;
768     wasChanged_ = true;
769 }
770 
GetAnimeStartTimes() const771 const std::vector<std::pair<uint64_t, int64_t>>& RSFile::GetAnimeStartTimes() const
772 {
773     return headerAnimeStartTimes_;
774 }
775 
AddAnimeStartTimes(const std::vector<std::pair<uint64_t,int64_t>> & startTimes)776 void RSFile::AddAnimeStartTimes(const std::vector<std::pair<uint64_t, int64_t>>& startTimes)
777 {
778     headerAnimeStartTimes_ = startTimes;
779     wasChanged_ = true;
780 }
781 
GetClosestVsyncId(int64_t vsyncId)782 int64_t RSFile::GetClosestVsyncId(int64_t vsyncId)
783 {
784     if (mapVsyncId2Time_.count(vsyncId)) {
785         return vsyncId;
786     }
787     if (!mapVsyncId2Time_.size()) {
788         return 0;
789     }
790 
791     int64_t minVSync = mapVsyncId2Time_.begin()->first;
792     int64_t maxVSync = mapVsyncId2Time_.rbegin()->first;
793 
794     auto it = mapVsyncId2Time_.lower_bound(vsyncId);
795     if (it != mapVsyncId2Time_.end()) {
796         return it->first;
797     }
798     return minVSync;
799 }
800 
ConvertVsyncId2Time(int64_t vsyncId)801 double RSFile::ConvertVsyncId2Time(int64_t vsyncId)
802 {
803     if (mapVsyncId2Time_.count(vsyncId)) {
804         return mapVsyncId2Time_[vsyncId];
805     }
806     return 0.0;
807 }
808 
ConvertTime2VsyncId(double time) const809 int64_t RSFile::ConvertTime2VsyncId(double time) const
810 {
811     constexpr double numericError = 1e-5;
812     for (const auto& item : mapVsyncId2Time_) {
813         if (time <= item.second + numericError) {
814             return item.first;
815         }
816     }
817     return 0;
818 }
819 
CacheVsyncId2Time(uint32_t layer)820 void RSFile::CacheVsyncId2Time(uint32_t layer)
821 {
822     mapVsyncId2Time_.clear();
823 
824     if (!file_ || !HasLayer(layer)) {
825         return;
826     }
827 
828     LayerTrackPtr track = { &RSFileLayer::readindexRsMetrics, &RSFileLayer::rsMetrics };
829 
830     RSFileLayer& layerData = layerData_[layer];
831     const auto& trackData = layerData.*track.markup;
832 
833     double readTime;
834 
835     for (const auto& trackItem : trackData) {
836         Utils::FileSeek(file_, trackItem.first, SEEK_SET);
837         Utils::FileRead(&readTime, sizeof(readTime), 1, file_);
838 
839         constexpr char packetTypeRsMetrics = 2;
840         char packetType;
841 
842         Utils::FileRead(&packetType, sizeof(packetType), 1, file_);
843         if (packetType != packetTypeRsMetrics) {
844             continue;
845         }
846 
847         const int32_t dataLen = trackItem.second - RSFileLayer::MARKUP_SIZE - 1;
848         constexpr int32_t dataLenMax = 100'000;
849         if (dataLen < 0 || dataLen > dataLenMax) {
850             continue;
851         }
852         std::vector<char> data;
853         data.resize(dataLen);
854         Utils::FileRead(data.data(), dataLen, 1, file_);
855 
856         RSCaptureData captureData;
857         captureData.Deserialize(data);
858         int64_t readVsyncId = captureData.GetPropertyInt64(RSCaptureData::KEY_RS_VSYNC_ID);
859         if (readVsyncId > 0 && !mapVsyncId2Time_.count(readVsyncId)) {
860             mapVsyncId2Time_.insert({readVsyncId, readTime});
861         }
862     }
863 }
864 
865 } // namespace OHOS::Rosen