1 /*
2 * Copyright (c) 2021 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 <cstdint>
17 #include <scoped_bytrace.h>
18 #include "hdi_output.h"
19 #include "metadata_helper.h"
20 #include "vsync_generator.h"
21 #include "vsync_sampler.h"
22
23 using namespace OHOS::HDI::Display::Graphic::Common::V1_0;
24
25 #define CHECK_DEVICE_NULL(device) \
26 do { \
27 if ((device) == nullptr) { \
28 HLOGD("[%{public}s]HdiDevice is nullptr.", __func__); \
29 return ROSEN_ERROR_NOT_INIT; \
30 } \
31 } while (0)
32
33 namespace OHOS {
34 namespace Rosen {
35
CreateHdiOutput(uint32_t screenId)36 std::shared_ptr<HdiOutput> HdiOutput::CreateHdiOutput(uint32_t screenId)
37 {
38 return std::make_shared<HdiOutput>(screenId);
39 }
40
HdiOutput(uint32_t screenId)41 HdiOutput::HdiOutput(uint32_t screenId) : screenId_(screenId)
42 {
43 }
44
~HdiOutput()45 HdiOutput::~HdiOutput()
46 {
47 }
48
ClearFrameBuffer()49 GSError HdiOutput::ClearFrameBuffer()
50 {
51 GSError ret = GSERROR_OK;
52 if (!CheckFbSurface()) {
53 return ret;
54 }
55 currFrameBuffer_ = nullptr;
56 lastFrameBuffer_ = nullptr;
57 bufferCache_.clear();
58 fbSurface_->ClearFrameBuffer();
59 sptr<Surface> pFrameSurface = GetFrameBufferSurface();
60 if (pFrameSurface != nullptr) {
61 ret = pFrameSurface->CleanCache();
62 }
63 return ret;
64 }
65
Init()66 RosenError HdiOutput::Init()
67 {
68 if (fbSurface_ != nullptr) {
69 return ROSEN_ERROR_OK;
70 }
71
72 fbSurface_ = HdiFramebufferSurface::CreateFramebufferSurface();
73 if (fbSurface_ == nullptr) {
74 HLOGE("Create framebuffer surface failed");
75 return ROSEN_ERROR_NOT_INIT;
76 }
77
78 if (device_ != nullptr) {
79 return ROSEN_ERROR_OK;
80 }
81
82 device_ = HdiDevice::GetInstance();
83 CHECK_DEVICE_NULL(device_);
84
85 bufferCacheCountMax_ = fbSurface_->GetBufferQueueSize();
86 int32_t ret = device_->SetScreenClientBufferCacheCount(screenId_, bufferCacheCountMax_);
87 if (ret != GRAPHIC_DISPLAY_SUCCESS) {
88 HLOGE("Set screen client buffer cache count failed, ret is %{public}d", ret);
89 return ROSEN_ERROR_INVALID_OPERATING;
90 }
91 bufferCache_.clear();
92 bufferCache_.reserve(bufferCacheCountMax_);
93
94 return ROSEN_ERROR_OK;
95 }
96
SetHdiOutputDevice(HdiDevice * device)97 RosenError HdiOutput::SetHdiOutputDevice(HdiDevice* device)
98 {
99 if (device == nullptr) {
100 HLOGE("Input HdiDevice is null");
101 return ROSEN_ERROR_INVALID_ARGUMENTS;
102 }
103
104 if (device_ != nullptr) {
105 HLOGW("HdiDevice has been changed");
106 return ROSEN_ERROR_OK;
107 }
108 device_ = device;
109 return ROSEN_ERROR_OK;
110 }
111
SetLayerInfo(const std::vector<LayerInfoPtr> & layerInfos)112 void HdiOutput::SetLayerInfo(const std::vector<LayerInfoPtr> &layerInfos)
113 {
114 for (auto &layerInfo : layerInfos) {
115 if (layerInfo == nullptr || layerInfo->GetSurface() == nullptr) {
116 HLOGE("current layerInfo or layerInfo's cSurface is null");
117 continue;
118 }
119
120 uint64_t surfaceId = layerInfo->GetSurface()->GetUniqueId();
121 auto iter = surfaceIdMap_.find(surfaceId);
122 if (iter != surfaceIdMap_.end()) {
123 const LayerPtr &layer = iter->second;
124 layer->UpdateLayerInfo(layerInfo);
125 continue;
126 }
127
128 int32_t ret = CreateLayer(surfaceId, layerInfo);
129 if (ret != GRAPHIC_DISPLAY_SUCCESS) {
130 return;
131 }
132 }
133
134 DeletePrevLayers();
135 ResetLayerStatus();
136 }
137
DeletePrevLayers()138 void HdiOutput::DeletePrevLayers()
139 {
140 auto surfaceIter = surfaceIdMap_.begin();
141 while (surfaceIter != surfaceIdMap_.end()) {
142 const LayerPtr &layer = surfaceIter->second;
143 if (!layer->GetLayerStatus()) {
144 surfaceIdMap_.erase(surfaceIter++);
145 } else {
146 ++surfaceIter;
147 }
148 }
149
150 auto layerIter = layerIdMap_.begin();
151 while (layerIter != layerIdMap_.end()) {
152 const LayerPtr &layer = layerIter->second;
153 if (!layer->GetLayerStatus()) {
154 layerIdMap_.erase(layerIter++);
155 } else {
156 ++layerIter;
157 }
158 }
159 }
160
ResetLayerStatus()161 void HdiOutput::ResetLayerStatus()
162 {
163 for (auto iter = layerIdMap_.begin(); iter != layerIdMap_.end(); ++iter) {
164 iter->second->SetLayerStatus(false);
165 }
166 }
167
CreateLayer(uint64_t surfaceId,const LayerInfoPtr & layerInfo)168 int32_t HdiOutput::CreateLayer(uint64_t surfaceId, const LayerInfoPtr &layerInfo)
169 {
170 LayerPtr layer = HdiLayer::CreateHdiLayer(screenId_);
171 if (!layer->Init(layerInfo)) {
172 HLOGE("Init hdiLayer failed");
173 return GRAPHIC_DISPLAY_FAILURE;
174 }
175
176 layer->UpdateLayerInfo(layerInfo);
177 uint32_t layerId = layer->GetLayerId();
178 layerIdMap_[layerId] = layer;
179 surfaceIdMap_[surfaceId] = layer;
180
181 return GRAPHIC_DISPLAY_SUCCESS;
182 }
183
SetOutputDamages(const std::vector<GraphicIRect> & outputDamages)184 void HdiOutput::SetOutputDamages(const std::vector<GraphicIRect> &outputDamages)
185 {
186 outputDamages_ = outputDamages;
187 }
188
GetOutputDamages()189 const std::vector<GraphicIRect>& HdiOutput::GetOutputDamages()
190 {
191 return outputDamages_;
192 }
193
GetLayers()194 const std::unordered_map<uint32_t, std::shared_ptr<HdiLayer>>& HdiOutput::GetLayers()
195 {
196 return layerIdMap_;
197 }
198
UpdatePrevLayerInfo()199 void HdiOutput::UpdatePrevLayerInfo()
200 {
201 for (auto iter = layerIdMap_.begin(); iter != layerIdMap_.end(); iter++) {
202 LayerPtr layer = iter->second;
203 layer->SavePrevLayerInfo();
204 }
205 }
206
GetScreenId() const207 uint32_t HdiOutput::GetScreenId() const
208 {
209 return screenId_;
210 }
211
SetLayerCompCapacity(uint32_t layerCompositionCapacity)212 void HdiOutput::SetLayerCompCapacity(uint32_t layerCompositionCapacity)
213 {
214 layerCompCapacity_ = layerCompositionCapacity;
215 }
216
GetLayerCompCapacity() const217 uint32_t HdiOutput::GetLayerCompCapacity() const
218 {
219 return layerCompCapacity_;
220 }
221
GetFrameBufferSurface()222 sptr<Surface> HdiOutput::GetFrameBufferSurface()
223 {
224 if (!CheckFbSurface()) {
225 return nullptr;
226 }
227
228 return fbSurface_->GetSurface();
229 }
230
GetFramebuffer()231 std::unique_ptr<FrameBufferEntry> HdiOutput::GetFramebuffer()
232 {
233 if (!CheckFbSurface()) {
234 return nullptr;
235 }
236
237 return fbSurface_->GetFramebuffer();
238 }
239
CheckFbSurface()240 bool HdiOutput::CheckFbSurface()
241 {
242 if (fbSurface_ == nullptr) {
243 HLOGE("fbSurface is nullptr");
244 return false;
245 }
246
247 return true;
248 }
249
RecordCompositionTime(int64_t timeStamp)250 void HdiOutput::RecordCompositionTime(int64_t timeStamp)
251 {
252 compositionTimeRecords_[compTimeRcdIndex_] = timeStamp;
253 compTimeRcdIndex_ = (compTimeRcdIndex_ + 1) % COMPOSITION_RECORDS_NUM;
254 }
255
SetDirectClientCompEnableStatus(bool enableStatus)256 void HdiOutput::SetDirectClientCompEnableStatus(bool enableStatus)
257 {
258 directClientCompositionEnabled_ = enableStatus;
259 }
260
GetDirectClientCompEnableStatus() const261 bool HdiOutput::GetDirectClientCompEnableStatus() const
262 {
263 return directClientCompositionEnabled_;
264 }
265
PreProcessLayersComp(bool & needFlush)266 int32_t HdiOutput::PreProcessLayersComp(bool &needFlush)
267 {
268 if (layerIdMap_.empty()) {
269 HLOGI("layer map is empty, drop this frame");
270 return GRAPHIC_DISPLAY_PARAM_ERR;
271 }
272
273 uint32_t layersNum = layerIdMap_.size();
274 // If doClientCompositionDirectly is true then layer->SetHdiLayerInfo and UpdateLayerCompType is no need to run.
275 bool doClientCompositionDirectly = ((layerCompCapacity_ != LAYER_COMPOSITION_CAPACITY_INVALID) &&
276 (layersNum > layerCompCapacity_));
277 if (!directClientCompositionEnabled_) {
278 doClientCompositionDirectly = false;
279 }
280
281 int32_t ret;
282 for (auto iter = layerIdMap_.begin(); iter != layerIdMap_.end(); ++iter) {
283 const LayerPtr &layer = iter->second;
284 if (doClientCompositionDirectly) {
285 layer->UpdateCompositionType(GraphicCompositionType::GRAPHIC_COMPOSITION_CLIENT);
286 continue;
287 }
288 ret = layer->SetHdiLayerInfo();
289 if (ret != GRAPHIC_DISPLAY_SUCCESS) {
290 HLOGE("Set hdi layer[id:%{public}d] info failed, ret %{public}d.", layer->GetLayerId(), ret);
291 return GRAPHIC_DISPLAY_FAILURE;
292 }
293 }
294
295 CHECK_DEVICE_NULL(device_);
296 ret = device_->PrepareScreenLayers(screenId_, needFlush);
297 if (ret != GRAPHIC_DISPLAY_SUCCESS) {
298 HLOGE("PrepareScreenLayers failed, ret is %{public}d", ret);
299 return GRAPHIC_DISPLAY_FAILURE;
300 }
301
302 if (doClientCompositionDirectly) {
303 ScopedBytrace doClientCompositionDirectlyTag("DoClientCompositionDirectly");
304 HLOGD("Direct client composition is enabled.");
305 return GRAPHIC_DISPLAY_SUCCESS;
306 }
307
308 return UpdateLayerCompType();
309 }
310
UpdateLayerCompType()311 int32_t HdiOutput::UpdateLayerCompType()
312 {
313 CHECK_DEVICE_NULL(device_);
314 std::vector<uint32_t> layersId;
315 std::vector<int32_t> types;
316 int32_t ret = device_->GetScreenCompChange(screenId_, layersId, types);
317 if (ret != GRAPHIC_DISPLAY_SUCCESS || layersId.size() != types.size()) {
318 HLOGE("GetScreenCompChange failed, ret is %{public}d", ret);
319 return ret;
320 }
321
322 size_t layerNum = layersId.size();
323 for (size_t i = 0; i < layerNum; i++) {
324 auto iter = layerIdMap_.find(layersId[i]);
325 if (iter == layerIdMap_.end()) {
326 HLOGE("Invalid hdi layer id[%{public}u]", layersId[i]);
327 continue;
328 }
329
330 const LayerPtr &layer = iter->second;
331 layer->UpdateCompositionType(static_cast<GraphicCompositionType>(types[i]));
332 }
333
334 return ret;
335 }
336
CheckAndUpdateClientBufferCahce(sptr<SurfaceBuffer> buffer,uint32_t & index)337 bool HdiOutput::CheckAndUpdateClientBufferCahce(sptr<SurfaceBuffer> buffer, uint32_t& index)
338 {
339 uint32_t bufferCahceSize = (uint32_t)bufferCache_.size();
340 for (uint32_t i = 0; i < bufferCahceSize; i++) {
341 if (bufferCache_[i] == buffer) {
342 index = i;
343 return true;
344 }
345 }
346
347 if (bufferCahceSize >= bufferCacheCountMax_) {
348 HLOGI("the length of buffer cache exceeds the limit, and not find the aim buffer!");
349 bufferCache_.clear();
350 }
351
352 index = (uint32_t)bufferCache_.size();
353 bufferCache_.push_back(buffer);
354 return false;
355 }
356
SetBufferColorSpace(sptr<SurfaceBuffer> & buffer,const std::vector<LayerPtr> & layers)357 void HdiOutput::SetBufferColorSpace(sptr<SurfaceBuffer>& buffer, const std::vector<LayerPtr>& layers)
358 {
359 if (buffer == nullptr) {
360 HLOGE("HdiOutput::SetBufferColorSpace null buffer");
361 return;
362 }
363
364 CM_ColorSpaceType targetColorSpace = CM_DISPLAY_SRGB;
365 for (auto& layer : layers) {
366 auto layerInfo = layer->GetLayerInfo();
367 if (layerInfo == nullptr) {
368 HLOGW("HdiOutput::SetBufferColorSpace The info of layer is nullptr");
369 continue;
370 }
371
372 auto layerBuffer = layerInfo->GetBuffer();
373 if (layerBuffer == nullptr) {
374 HLOGW("HdiOutput::SetBufferColorSpace The buffer of layer is nullptr");
375 continue;
376 }
377
378 CM_ColorSpaceInfo colorSpaceInfo;
379 if (MetadataHelper::GetColorSpaceInfo(layerBuffer, colorSpaceInfo) != GSERROR_OK) {
380 HLOGD("HdiOutput::SetBufferColorSpace Get color space failed");
381 continue;
382 }
383
384 if (colorSpaceInfo.primaries != COLORPRIMARIES_SRGB) {
385 targetColorSpace = CM_DISPLAY_P3_SRGB;
386 break;
387 }
388 }
389
390 if (MetadataHelper::SetColorSpaceType(buffer, targetColorSpace) != GSERROR_OK) {
391 HLOGE("HdiOutput::SetBufferColorSpace set metadata to buffer failed");
392 }
393 }
394
FlushScreen(std::vector<LayerPtr> & compClientLayers)395 int32_t HdiOutput::FlushScreen(std::vector<LayerPtr> &compClientLayers)
396 {
397 auto fbEntry = GetFramebuffer();
398 if (fbEntry == nullptr) {
399 HLOGE("HdiBackend flush screen failed : GetFramebuffer failed!");
400 return -1;
401 }
402
403 const auto& fbAcquireFence = fbEntry->acquireFence;
404 for (auto &layer : compClientLayers) {
405 layer->MergeWithFramebufferFence(fbAcquireFence);
406 }
407
408 currFrameBuffer_ = fbEntry->buffer;
409 if (currFrameBuffer_ == nullptr) {
410 HLOGE("HdiBackend flush screen failed : frame buffer is null");
411 return -1;
412 }
413
414 uint32_t index = INVALID_BUFFER_CACHE_INDEX;
415 bool bufferCached = false;
416 if (bufferCacheCountMax_ == 0) {
417 bufferCache_.clear();
418 HLOGE("The count of this client buffer cache is 0.");
419 } else {
420 bufferCached = CheckAndUpdateClientBufferCahce(currFrameBuffer_, index);
421 }
422
423 SetBufferColorSpace(currFrameBuffer_, compClientLayers);
424
425 CHECK_DEVICE_NULL(device_);
426 int32_t ret = device_->SetScreenClientDamage(screenId_, outputDamages_);
427 if (ret != GRAPHIC_DISPLAY_SUCCESS) {
428 HLOGE("Set screen client damage failed, ret is %{public}d", ret);
429 return ret;
430 }
431
432 CHECK_DEVICE_NULL(device_);
433 if (bufferCached && index < bufferCacheCountMax_) {
434 ret = device_->SetScreenClientBuffer(screenId_, nullptr, index, fbAcquireFence);
435 } else {
436 ret = device_->SetScreenClientBuffer(screenId_, currFrameBuffer_->GetBufferHandle(), index, fbAcquireFence);
437 }
438 if (ret != GRAPHIC_DISPLAY_SUCCESS) {
439 HLOGE("Set screen client buffer failed, ret is %{public}d", ret);
440 return ret;
441 }
442
443 return GRAPHIC_DISPLAY_SUCCESS;
444 }
445
Commit(sptr<SyncFence> & fbFence)446 int32_t HdiOutput::Commit(sptr<SyncFence> &fbFence)
447 {
448 CHECK_DEVICE_NULL(device_);
449 return device_->Commit(screenId_, fbFence);
450 }
451
UpdateInfosAfterCommit(sptr<SyncFence> fbFence)452 int32_t HdiOutput::UpdateInfosAfterCommit(sptr<SyncFence> fbFence)
453 {
454 UpdatePrevLayerInfo();
455
456 if (sampler_ == nullptr) {
457 sampler_ = CreateVSyncSampler();
458 }
459 int64_t timestamp = lastPresentFence_->SyncFileReadTimestamp();
460 bool startSample = false;
461 if (timestamp != SyncFence::FENCE_PENDING_TIMESTAMP) {
462 startSample = sampler_->AddPresentFenceTime(timestamp);
463 RecordCompositionTime(timestamp);
464 for (auto iter = layerIdMap_.begin(); iter != layerIdMap_.end(); ++iter) {
465 const LayerPtr &layer = iter->second;
466 layer->RecordPresentTime(timestamp);
467 }
468 }
469
470 int32_t ret = GRAPHIC_DISPLAY_SUCCESS;
471 if (startSample) {
472 ret = StartVSyncSampler();
473 }
474 lastPresentFence_ = fbFence;
475 return ret;
476 }
477
ReleaseFramebuffer(const sptr<SyncFence> & releaseFence)478 int32_t HdiOutput::ReleaseFramebuffer(const sptr<SyncFence>& releaseFence)
479 {
480 if (currFrameBuffer_ == nullptr) {
481 return GRAPHIC_DISPLAY_NULL_PTR;
482 }
483
484 int32_t ret = GRAPHIC_DISPLAY_SUCCESS;
485 if (lastFrameBuffer_ != nullptr) {
486 if (!CheckFbSurface()) { // wrong check
487 ret = GRAPHIC_DISPLAY_NULL_PTR;
488 } else {
489 ret = fbSurface_->ReleaseFramebuffer(lastFrameBuffer_, releaseFence);
490 }
491 }
492
493 lastFrameBuffer_ = currFrameBuffer_;
494 currFrameBuffer_ = nullptr;
495 return ret;
496 }
497
GetLayersReleaseFence()498 std::map<LayerInfoPtr, sptr<SyncFence>> HdiOutput::GetLayersReleaseFence()
499 {
500 if (device_ == nullptr) {
501 return {};
502 }
503 std::vector<uint32_t> layersId;
504 std::vector<sptr<SyncFence>> fences;
505 int32_t ret = device_->GetScreenReleaseFence(screenId_, layersId, fences);
506 if (ret != GRAPHIC_DISPLAY_SUCCESS || layersId.size() != fences.size()) {
507 HLOGE("GetScreenReleaseFence failed, ret is %{public}d, layerId size[%{public}d], fence size[%{public}d]",
508 ret, (int)layersId.size(), (int)fences.size());
509 return {};
510 }
511
512 std::map<LayerInfoPtr, sptr<SyncFence>> res;
513 size_t layerNum = layersId.size();
514 for (size_t i = 0; i < layerNum; i++) {
515 auto iter = layerIdMap_.find(layersId[i]);
516 if (iter == layerIdMap_.end()) {
517 HLOGE("Invalid hdi layer id [%{public}u]", layersId[i]);
518 continue;
519 }
520
521 const LayerPtr &layer = iter->second;
522 layer->MergeWithLayerFence(fences[i]);
523 res[layer->GetLayerInfo()] = layer->GetReleaseFence();
524 }
525 return res;
526 }
527
StartVSyncSampler(bool forceReSample)528 int32_t HdiOutput::StartVSyncSampler(bool forceReSample)
529 {
530 ScopedBytrace func("HdiOutput::StartVSyncSampler, forceReSample:" + std::to_string(forceReSample));
531 CHECK_DEVICE_NULL(device_);
532 if (sampler_ == nullptr) {
533 sampler_ = CreateVSyncSampler();
534 }
535 bool alreadyStartSample = sampler_->GetHardwareVSyncStatus();
536 if (!forceReSample && alreadyStartSample) {
537 HLOGD("Already Start Sample.");
538 return GRAPHIC_DISPLAY_SUCCESS;
539 }
540 HLOGD("Enable Screen Vsync");
541 sampler_->SetScreenVsyncEnabledInRSMainThread(true);
542 sampler_->BeginSample();
543 return GRAPHIC_DISPLAY_SUCCESS;
544 }
545
SetPendingMode(int64_t period,int64_t timestamp)546 void HdiOutput::SetPendingMode(int64_t period, int64_t timestamp)
547 {
548 ScopedBytrace func("VSyncSampler::SetPendingMode period:" + std::to_string(period) +
549 ", timestamp:" + std::to_string(timestamp));
550 if (sampler_ == nullptr) {
551 sampler_ = CreateVSyncSampler();
552 }
553 sampler_->SetPendingPeriod(period);
554 CreateVSyncGenerator()->SetPendingMode(period, timestamp);
555 }
556
Dump(std::string & result) const557 void HdiOutput::Dump(std::string &result) const
558 {
559 std::vector<LayerDumpInfo> dumpLayerInfos;
560 ReorderLayerInfo(dumpLayerInfos);
561
562 result.append("\n");
563 result.append("-- LayerInfo\n");
564
565 for (const LayerDumpInfo &layerInfo : dumpLayerInfos) {
566 const LayerPtr &layer = layerInfo.layer;
567 if (layer == nullptr || layer->GetLayerInfo() == nullptr ||
568 layer->GetLayerInfo()->GetSurface() == nullptr) {
569 continue;
570 }
571 const std::string& name = layer->GetLayerInfo()->GetSurface()->GetName();
572 auto info = layer->GetLayerInfo();
573 result += "\n surface [" + name + "] NodeId[" + std::to_string(layerInfo.surfaceId) + "]";
574 result += " LayerId[" + std::to_string(layer->GetLayerId()) + "]:\n";
575 info->Dump(result);
576 }
577
578 if (fbSurface_ != nullptr) {
579 result += "\n";
580 result += "FrameBufferSurface\n";
581 fbSurface_->Dump(result);
582 }
583 CreateVSyncGenerator()->Dump(result);
584 CreateVSyncSampler()->Dump(result);
585 }
586
DumpFps(std::string & result,const std::string & arg) const587 void HdiOutput::DumpFps(std::string &result, const std::string &arg) const
588 {
589 std::vector<LayerDumpInfo> dumpLayerInfos;
590 ReorderLayerInfo(dumpLayerInfos);
591
592 result.append("\n");
593 if (arg == "composer") {
594 result += "The fps of screen [Id:" + std::to_string(screenId_) + "] is:\n";
595 const int32_t offset = compTimeRcdIndex_;
596 for (uint32_t i = 0; i < COMPOSITION_RECORDS_NUM; i++) {
597 uint32_t order = (offset + i) % COMPOSITION_RECORDS_NUM;
598 result += std::to_string(compositionTimeRecords_[order]) + "\n";
599 }
600 return;
601 }
602
603 for (const LayerDumpInfo &layerInfo : dumpLayerInfos) {
604 const LayerPtr &layer = layerInfo.layer;
605 const std::string& name = layer->GetLayerInfo()->GetSurface()->GetName();
606 if (name == arg) {
607 result += "\n surface [" + name + "] Id[" + std::to_string(layerInfo.surfaceId) + "]:\n";
608 layer->Dump(result);
609 }
610 }
611 }
612
ClearFpsDump(std::string & result,const std::string & arg)613 void HdiOutput::ClearFpsDump(std::string &result, const std::string &arg)
614 {
615 std::vector<LayerDumpInfo> dumpLayerInfos;
616 ReorderLayerInfo(dumpLayerInfos);
617
618 result.append("\n");
619 if (arg == "composer") {
620 result += "The fps info of screen [Id:" + std::to_string(screenId_) + "] is cleared.\n";
621 compositionTimeRecords_.fill(0);
622 return;
623 }
624
625 for (const LayerDumpInfo &layerInfo : dumpLayerInfos) {
626 const LayerPtr &layer = layerInfo.layer;
627 const std::string& name = layer->GetLayerInfo()->GetSurface()->GetName();
628 if (name == arg) {
629 result += "\n The fps info of surface [" + name + "] Id["
630 + std::to_string(layerInfo.surfaceId) + "] is cleared.\n";
631 layer->ClearDump();
632 }
633 }
634 }
635
Cmp(const LayerDumpInfo & layer1,const LayerDumpInfo & layer2)636 static inline bool Cmp(const LayerDumpInfo &layer1, const LayerDumpInfo &layer2)
637 {
638 return layer1.layer->GetLayerInfo()->GetZorder() < layer2.layer->GetLayerInfo()->GetZorder();
639 }
640
ReorderLayerInfo(std::vector<LayerDumpInfo> & dumpLayerInfos) const641 void HdiOutput::ReorderLayerInfo(std::vector<LayerDumpInfo> &dumpLayerInfos) const
642 {
643 for (auto iter = surfaceIdMap_.begin(); iter != surfaceIdMap_.end(); ++iter) {
644 struct LayerDumpInfo layerInfo = {
645 .surfaceId = iter->first,
646 .layer = iter->second,
647 };
648 dumpLayerInfos.emplace_back(layerInfo);
649 }
650
651 std::sort(dumpLayerInfos.begin(), dumpLayerInfos.end(), Cmp);
652 }
653 } // namespace Rosen
654 } // namespace OHOS
655