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