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