• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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