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 <unordered_set>
19 #include "rs_trace.h"
20 #include "hdi_output.h"
21 #include "vsync_generator.h"
22 #include "vsync_sampler.h"
23 #include "metadata_helper.h"
24 // DISPLAYENGINE
25 #include "syspara/parameters.h"
26 
27 using namespace OHOS::HDI::Display::Graphic::Common::V1_0;
28 
29 #define CHECK_DEVICE_NULL(device)                                   \
30     do {                                                            \
31         if ((device) == nullptr) {                                  \
32             HLOGD("[%{public}s]HdiDevice is nullptr.", __func__);   \
33             return ROSEN_ERROR_NOT_INIT;                            \
34         }                                                           \
35     } while (0)
36 
37 namespace OHOS {
38 namespace Rosen {
39 static constexpr uint32_t NUMBER_OF_HISTORICAL_FRAMES = 2;
40 static const std::string GENERIC_METADATA_KEY_ARSR_PRE_NEEDED = "ArsrDoEnhance";
41 static int32_t SOLID_SURFACE_COUNT = 0;
42 
CreateHdiOutput(uint32_t screenId)43 std::shared_ptr<HdiOutput> HdiOutput::CreateHdiOutput(uint32_t screenId)
44 {
45     return std::make_shared<HdiOutput>(screenId);
46 }
47 
HdiOutput(uint32_t screenId)48 HdiOutput::HdiOutput(uint32_t screenId) : screenId_(screenId)
49 {
50     // DISPLAYENGINE ARSR_PRE FLAG
51     arsrPreEnabled_ = system::GetBoolParameter("const.display.enable_arsr_pre", true);
52 }
53 
~HdiOutput()54 HdiOutput::~HdiOutput()
55 {
56     ClearBufferCache();
57 }
58 
ClearFrameBuffer()59 GSError HdiOutput::ClearFrameBuffer()
60 {
61     GSError ret = GSERROR_OK;
62     if (!CheckFbSurface()) {
63         return ret;
64     }
65     currFrameBuffer_ = nullptr;
66     lastFrameBuffer_ = nullptr;
67     ClearBufferCache();
68     fbSurface_->ClearFrameBuffer();
69     sptr<Surface> pFrameSurface = GetFrameBufferSurface();
70     if (pFrameSurface != nullptr) {
71         ret = pFrameSurface->CleanCache();
72     }
73     return ret;
74 }
75 
Init()76 RosenError HdiOutput::Init()
77 {
78     if (fbSurface_ != nullptr) {
79         return ROSEN_ERROR_OK;
80     }
81 
82     fbSurface_ = HdiFramebufferSurface::CreateFramebufferSurface();
83     if (fbSurface_ == nullptr) {
84         HLOGE("Create framebuffer surface failed");
85         return ROSEN_ERROR_NOT_INIT;
86     }
87 
88     if (device_ != nullptr) {
89         return ROSEN_ERROR_OK;
90     }
91 
92     device_ = HdiDevice::GetInstance();
93     CHECK_DEVICE_NULL(device_);
94 
95     bufferCacheCountMax_ = fbSurface_->GetBufferQueueSize();
96     int32_t ret = device_->SetScreenClientBufferCacheCount(screenId_, bufferCacheCountMax_);
97     if (ret != GRAPHIC_DISPLAY_SUCCESS) {
98         HLOGE("Set screen client buffer cache count failed, ret is %{public}d", ret);
99         return ROSEN_ERROR_INVALID_OPERATING;
100     }
101     ClearBufferCache();
102     bufferCache_.reserve(bufferCacheCountMax_);
103     historicalPresentfences_.clear();
104 
105     return ROSEN_ERROR_OK;
106 }
107 
SetHdiOutputDevice(HdiDevice * device)108 RosenError HdiOutput::SetHdiOutputDevice(HdiDevice* device)
109 {
110     if (device == nullptr) {
111         HLOGE("Input HdiDevice is null");
112         return ROSEN_ERROR_INVALID_ARGUMENTS;
113     }
114 
115     if (device_ != nullptr) {
116         HLOGW("HdiDevice has been changed");
117         return ROSEN_ERROR_OK;
118     }
119     device_ = device;
120     return ROSEN_ERROR_OK;
121 }
122 
SetLayerInfo(const std::vector<LayerInfoPtr> & layerInfos)123 void HdiOutput::SetLayerInfo(const std::vector<LayerInfoPtr> &layerInfos)
124 {
125     std::unique_lock<std::mutex> lock(mutex_);
126     for (auto &layerInfo : layerInfos) {
127         if (layerInfo == nullptr) {
128             HLOGE("current layerInfo is null");
129             continue;
130         }
131         if (layerInfo->GetSurface() == nullptr) {
132             if (layerInfo->GetCompositionType() ==
133                 GraphicCompositionType::GRAPHIC_COMPOSITION_SOLID_COLOR) {
134                 CreateLayerLocked(SOLID_SURFACE_COUNT++, layerInfo);
135             }
136             continue;
137         }
138 
139         uint64_t surfaceId = layerInfo->GetSurface()->GetUniqueId();
140         auto iter = surfaceIdMap_.find(surfaceId);
141         if (iter != surfaceIdMap_.end()) {
142             const LayerPtr &layer = iter->second;
143             layer->UpdateLayerInfo(layerInfo);
144             continue;
145         }
146 
147         int32_t ret = CreateLayerLocked(surfaceId, layerInfo);
148         if (ret != GRAPHIC_DISPLAY_SUCCESS) {
149             return;
150         }
151     }
152 
153     DeletePrevLayersLocked();
154     ResetLayerStatusLocked();
155 }
156 
DeletePrevLayersLocked()157 void HdiOutput::DeletePrevLayersLocked()
158 {
159     auto surfaceIter = surfaceIdMap_.begin();
160     while (surfaceIter != surfaceIdMap_.end()) {
161         const LayerPtr &layer = surfaceIter->second;
162         if (!layer->GetLayerStatus()) {
163             surfaceIdMap_.erase(surfaceIter++);
164         } else {
165             ++surfaceIter;
166         }
167     }
168 
169     auto layerIter = layerIdMap_.begin();
170     while (layerIter != layerIdMap_.end()) {
171         const LayerPtr &layer = layerIter->second;
172         if (!layer->GetLayerStatus()) {
173             layerIdMap_.erase(layerIter++);
174         } else {
175             ++layerIter;
176         }
177     }
178 }
179 
ResetLayerStatusLocked()180 void HdiOutput::ResetLayerStatusLocked()
181 {
182     for (auto iter = layerIdMap_.begin(); iter != layerIdMap_.end(); ++iter) {
183         iter->second->SetLayerStatus(false);
184     }
185 }
186 
CreateLayerLocked(uint64_t surfaceId,const LayerInfoPtr & layerInfo)187 int32_t HdiOutput::CreateLayerLocked(uint64_t surfaceId, const LayerInfoPtr &layerInfo)
188 {
189     LayerPtr layer = HdiLayer::CreateHdiLayer(screenId_);
190     if (layer == nullptr || !layer->Init(layerInfo)) {
191         HLOGE("Init hdiLayer failed");
192         return GRAPHIC_DISPLAY_FAILURE;
193     }
194 
195     layer->UpdateLayerInfo(layerInfo);
196     uint32_t layerId = layer->GetLayerId();
197 
198     layerIdMap_[layerId] = layer;
199     surfaceIdMap_[surfaceId] = layer;
200 
201     if (device_ == nullptr) {
202         HLOGE("[%{public}s]HdiDevice is nullptr.", __func__);
203         return GRAPHIC_DISPLAY_SUCCESS;
204     }
205     // DISPLAY ENGINE
206     if (!arsrPreEnabled_) {
207         return GRAPHIC_DISPLAY_SUCCESS;
208     }
209 
210     const auto& validKeys = device_->GetSupportedLayerPerFrameParameterKey();
211     if (std::find(validKeys.begin(), validKeys.end(), GENERIC_METADATA_KEY_ARSR_PRE_NEEDED) != validKeys.end()) {
212         if (CheckIfDoArsrPre(layerInfo)) {
213             const std::vector<int8_t> valueBlob{static_cast<int8_t>(1)};
214             if (device_->SetLayerPerFrameParameter(screenId_,
215                 layerId, GENERIC_METADATA_KEY_ARSR_PRE_NEEDED, valueBlob) != 0) {
216                 HLOGE("SetLayerPerFrameParameter Fail!");
217             }
218         }
219     }
220 
221     return GRAPHIC_DISPLAY_SUCCESS;
222 }
223 
SetOutputDamages(const std::vector<GraphicIRect> & outputDamages)224 void HdiOutput::SetOutputDamages(const std::vector<GraphicIRect> &outputDamages)
225 {
226     outputDamages_ = outputDamages;
227 }
228 
GetOutputDamages()229 const std::vector<GraphicIRect>& HdiOutput::GetOutputDamages()
230 {
231     return outputDamages_;
232 }
233 
GetComposeClientLayers(std::vector<LayerPtr> & clientLayers)234 void HdiOutput::GetComposeClientLayers(std::vector<LayerPtr>& clientLayers)
235 {
236     std::unique_lock<std::mutex> lock(mutex_);
237     for (const auto &[first, layer] : layerIdMap_) {
238         if (layer == nullptr) {
239             continue;
240         }
241         if (layer->GetLayerInfo()->GetCompositionType() == GraphicCompositionType::GRAPHIC_COMPOSITION_CLIENT ||
242             layer->GetLayerInfo()->GetCompositionType() == GraphicCompositionType::GRAPHIC_COMPOSITION_CLIENT_CLEAR ||
243             layer->GetLayerInfo()->GetCompositionType() == GraphicCompositionType::GRAPHIC_COMPOSITION_TUNNEL) {
244             clientLayers.emplace_back(layer);
245         }
246     }
247 }
248 
GetLayerInfos(std::vector<LayerInfoPtr> & layerInfos)249 void HdiOutput::GetLayerInfos(std::vector<LayerInfoPtr>& layerInfos)
250 {
251     std::unique_lock<std::mutex> lock(mutex_);
252     for (const auto &it : layerIdMap_) {
253         if (it.second != nullptr) {
254             layerInfos.emplace_back(it.second->GetLayerInfo());
255         }
256     }
257 }
258 
UpdatePrevLayerInfoLocked()259 void HdiOutput::UpdatePrevLayerInfoLocked()
260 {
261     for (auto iter = layerIdMap_.begin(); iter != layerIdMap_.end(); iter++) {
262         LayerPtr layer = iter->second;
263         layer->SavePrevLayerInfo();
264     }
265 }
266 
GetScreenId() const267 uint32_t HdiOutput::GetScreenId() const
268 {
269     return screenId_;
270 }
271 
GetFrameBufferSurface()272 sptr<Surface> HdiOutput::GetFrameBufferSurface()
273 {
274     if (!CheckFbSurface()) {
275         return nullptr;
276     }
277 
278     return fbSurface_->GetSurface();
279 }
280 
GetFramebuffer()281 std::unique_ptr<FrameBufferEntry> HdiOutput::GetFramebuffer()
282 {
283     if (!CheckFbSurface()) {
284         return nullptr;
285     }
286 
287     return fbSurface_->GetFramebuffer();
288 }
289 
CheckFbSurface()290 bool HdiOutput::CheckFbSurface()
291 {
292     if (fbSurface_ == nullptr) {
293         HLOGE("fbSurface is nullptr");
294         return false;
295     }
296 
297     return true;
298 }
299 
RecordCompositionTime(int64_t timeStamp)300 void HdiOutput::RecordCompositionTime(int64_t timeStamp)
301 {
302     compositionTimeRecords_[compTimeRcdIndex_] = timeStamp;
303     compTimeRcdIndex_ = (compTimeRcdIndex_ + 1) % COMPOSITION_RECORDS_NUM;
304 }
305 
PreProcessLayersComp()306 int32_t HdiOutput::PreProcessLayersComp()
307 {
308     int32_t ret = GRAPHIC_DISPLAY_SUCCESS;
309     std::unique_lock<std::mutex> lock(mutex_);
310     if (layerIdMap_.empty()) {
311         HLOGI("layer map is empty, drop this frame");
312         return GRAPHIC_DISPLAY_PARAM_ERR;
313     }
314 
315     for (const auto &[layerId, layer] : layerIdMap_) {
316         ret = layer->SetHdiLayerInfo();
317         if (ret != GRAPHIC_DISPLAY_SUCCESS) {
318             HLOGE("Set hdi layer[id:%{public}d] info failed, ret %{public}d.", layer->GetLayerId(), ret);
319             return GRAPHIC_DISPLAY_FAILURE;
320         }
321     }
322 
323     return ret;
324 }
325 
UpdateLayerCompType()326 int32_t HdiOutput::UpdateLayerCompType()
327 {
328     CHECK_DEVICE_NULL(device_);
329     std::vector<uint32_t> layersId;
330     std::vector<int32_t> types;
331     int32_t ret = device_->GetScreenCompChange(screenId_, layersId, types);
332     if (ret != GRAPHIC_DISPLAY_SUCCESS) {
333         HLOGE("GetScreenCompChange failed, ret is %{public}d", ret);
334         return ret;
335     }
336     if (layersId.size() != types.size()) {
337         HLOGE("HdiOutput::UpdateLayerCompType layersId size is not types size");
338         return GRAPHIC_DISPLAY_FAILURE;
339     }
340 
341     std::unique_lock<std::mutex> lock(mutex_);
342     size_t layerNum = layersId.size();
343     for (size_t i = 0; i < layerNum; i++) {
344         auto iter = layerIdMap_.find(layersId[i]);
345         if (iter == layerIdMap_.end()) {
346             HLOGE("Invalid hdi layer id[%{public}u]", layersId[i]);
347             continue;
348         }
349 
350         const LayerPtr &layer = iter->second;
351         layer->UpdateCompositionType(static_cast<GraphicCompositionType>(types[i]));
352     }
353 
354     return ret;
355 }
356 
CheckAndUpdateClientBufferCahce(sptr<SurfaceBuffer> buffer,uint32_t & index)357 bool HdiOutput::CheckAndUpdateClientBufferCahce(sptr<SurfaceBuffer> buffer, uint32_t& index)
358 {
359     uint32_t bufferCahceSize = (uint32_t)bufferCache_.size();
360     for (uint32_t i = 0; i < bufferCahceSize; i++) {
361         if (bufferCache_[i] == buffer) {
362             index = i;
363             return true;
364         }
365     }
366 
367     if (bufferCahceSize >= bufferCacheCountMax_) {
368         HLOGI("the length of buffer cache exceeds the limit, and not find the aim buffer!");
369         ClearBufferCache();
370     }
371 
372     index = (uint32_t)bufferCache_.size();
373     bufferCache_.push_back(buffer);
374     return false;
375 }
376 
377 // DISPLAY ENGINE
CheckIfDoArsrPre(const LayerInfoPtr & layerInfo)378 bool HdiOutput::CheckIfDoArsrPre(const LayerInfoPtr &layerInfo)
379 {
380     static const std::unordered_set<GraphicPixelFormat> yuvFormats {
381         GRAPHIC_PIXEL_FMT_YUV_422_I,
382         GRAPHIC_PIXEL_FMT_YCBCR_422_SP,
383         GRAPHIC_PIXEL_FMT_YCRCB_422_SP,
384         GRAPHIC_PIXEL_FMT_YCBCR_420_SP,
385         GRAPHIC_PIXEL_FMT_YCRCB_420_SP,
386         GRAPHIC_PIXEL_FMT_YCBCR_422_P,
387         GRAPHIC_PIXEL_FMT_YCRCB_422_P,
388         GRAPHIC_PIXEL_FMT_YCBCR_420_P,
389         GRAPHIC_PIXEL_FMT_YCRCB_420_P,
390         GRAPHIC_PIXEL_FMT_YUYV_422_PKG,
391         GRAPHIC_PIXEL_FMT_UYVY_422_PKG,
392         GRAPHIC_PIXEL_FMT_YVYU_422_PKG,
393         GRAPHIC_PIXEL_FMT_VYUY_422_PKG,
394         GRAPHIC_PIXEL_FMT_YCBCR_P010,
395         GRAPHIC_PIXEL_FMT_YCRCB_P010,
396     };
397 
398     static const std::unordered_set<std::string> videoLayers {
399         "xcomponentIdSurface",
400         "componentIdSurface",
401         "SceneViewer Model totemweather0",
402     };
403 
404     if (layerInfo->GetBuffer() == nullptr) {
405         return false;
406     }
407 
408     if (((yuvFormats.count(static_cast<GraphicPixelFormat>(layerInfo->GetBuffer()->GetFormat())) > 0) ||
409         (videoLayers.count(layerInfo->GetSurface()->GetName()) > 0)) && layerInfo->GetLayerArsr()) {
410         return true;
411     }
412 
413     return false;
414 }
415 
FlushScreen(std::vector<LayerPtr> & compClientLayers)416 int32_t HdiOutput::FlushScreen(std::vector<LayerPtr> &compClientLayers)
417 {
418     auto fbEntry = GetFramebuffer();
419     if (fbEntry == nullptr) {
420         HLOGE("HdiBackend flush screen failed : GetFramebuffer failed!");
421         return -1;
422     }
423 
424     const auto& fbAcquireFence = fbEntry->acquireFence;
425     for (auto &layer : compClientLayers) {
426         layer->MergeWithFramebufferFence(fbAcquireFence);
427     }
428 
429     currFrameBuffer_ = fbEntry->buffer;
430     if (currFrameBuffer_ == nullptr) {
431         HLOGE("HdiBackend flush screen failed : frame buffer is null");
432         return -1;
433     }
434 
435     uint32_t index = INVALID_BUFFER_CACHE_INDEX;
436     bool bufferCached = false;
437     if (bufferCacheCountMax_ == 0) {
438         ClearBufferCache();
439         HLOGE("The count of this client buffer cache is 0.");
440     } else {
441         bufferCached = CheckAndUpdateClientBufferCahce(currFrameBuffer_, index);
442     }
443 
444     CHECK_DEVICE_NULL(device_);
445     int32_t ret = device_->SetScreenClientDamage(screenId_, outputDamages_);
446     if (ret != GRAPHIC_DISPLAY_SUCCESS) {
447         HLOGE("Set screen client damage failed, ret is %{public}d", ret);
448         return ret;
449     }
450 
451     if (bufferCached && index < bufferCacheCountMax_) {
452         ret = device_->SetScreenClientBuffer(screenId_, nullptr, index, fbAcquireFence);
453     } else {
454         ret = device_->SetScreenClientBuffer(screenId_, currFrameBuffer_->GetBufferHandle(), index, fbAcquireFence);
455     }
456     if (ret != GRAPHIC_DISPLAY_SUCCESS) {
457         HLOGE("Set screen client buffer failed, ret is %{public}d", ret);
458         return ret;
459     }
460 
461     return GRAPHIC_DISPLAY_SUCCESS;
462 }
463 
Commit(sptr<SyncFence> & fbFence)464 int32_t HdiOutput::Commit(sptr<SyncFence> &fbFence)
465 {
466     CHECK_DEVICE_NULL(device_);
467     return device_->Commit(screenId_, fbFence);
468 }
469 
CommitAndGetReleaseFence(sptr<SyncFence> & fbFence,int32_t & skipState,bool & needFlush,bool isValidated)470 int32_t HdiOutput::CommitAndGetReleaseFence(
471     sptr<SyncFence> &fbFence, int32_t &skipState, bool &needFlush, bool isValidated)
472 {
473     CHECK_DEVICE_NULL(device_);
474     layersId_.clear();
475     fences_.clear();
476     return device_->CommitAndGetReleaseFence(
477         screenId_, fbFence, skipState, needFlush, layersId_, fences_, isValidated);
478 }
479 
UpdateInfosAfterCommit(sptr<SyncFence> fbFence)480 int32_t HdiOutput::UpdateInfosAfterCommit(sptr<SyncFence> fbFence)
481 {
482     std::unique_lock<std::mutex> lock(mutex_);
483     UpdatePrevLayerInfoLocked();
484 
485     if (sampler_ == nullptr) {
486         sampler_ = CreateVSyncSampler();
487     }
488     if (thirdFrameAheadPresentFence_ == nullptr) {
489         return GRAPHIC_DISPLAY_NULL_PTR;
490     }
491     int64_t timestamp = thirdFrameAheadPresentFence_->SyncFileReadTimestamp();
492     bool startSample = false;
493     if (timestamp != SyncFence::FENCE_PENDING_TIMESTAMP) {
494         startSample = sampler_->AddPresentFenceTime(timestamp);
495         RecordCompositionTime(timestamp);
496         bool presentTimeUpdated = false;
497         LayerPtr uniRenderLayer = nullptr;
498         for (auto iter = layerIdMap_.begin(); iter != layerIdMap_.end(); ++iter) {
499             const LayerPtr &layer = iter->second;
500             if (layer->RecordPresentTime(timestamp)) {
501                 presentTimeUpdated = true;
502             }
503             if (layer->GetLayerInfo() && layer->GetLayerInfo()->GetUniRenderFlag()) {
504                 uniRenderLayer = layer;
505             }
506         }
507         if (presentTimeUpdated && uniRenderLayer) {
508             uniRenderLayer->RecordMergedPresentTime(timestamp);
509         }
510     }
511 
512     int32_t ret = GRAPHIC_DISPLAY_SUCCESS;
513     if (startSample) {
514         ret = StartVSyncSampler();
515     }
516     if (historicalPresentfences_.size() == NUMBER_OF_HISTORICAL_FRAMES) {
517         thirdFrameAheadPresentFence_ = historicalPresentfences_[presentFenceIndex_];
518         historicalPresentfences_[presentFenceIndex_] = fbFence;
519         presentFenceIndex_ = (presentFenceIndex_ + 1) % NUMBER_OF_HISTORICAL_FRAMES;
520     } else {
521         historicalPresentfences_.push_back(fbFence);
522     }
523     return ret;
524 }
525 
ReleaseFramebuffer(const sptr<SyncFence> & releaseFence)526 int32_t HdiOutput::ReleaseFramebuffer(const sptr<SyncFence>& releaseFence)
527 {
528     if (currFrameBuffer_ == nullptr) {
529         return GRAPHIC_DISPLAY_NULL_PTR;
530     }
531 
532     int32_t ret = GRAPHIC_DISPLAY_SUCCESS;
533     if (lastFrameBuffer_ != nullptr) {
534         if (!CheckFbSurface()) { // wrong check
535             ret = GRAPHIC_DISPLAY_NULL_PTR;
536         } else {
537             ret = fbSurface_->ReleaseFramebuffer(lastFrameBuffer_, releaseFence);
538         }
539     }
540 
541     lastFrameBuffer_ = currFrameBuffer_;
542     currFrameBuffer_ = nullptr;
543     return ret;
544 }
545 
ReleaseSurfaceBuffer(sptr<SyncFence> & releaseFence)546 void HdiOutput::ReleaseSurfaceBuffer(sptr<SyncFence>& releaseFence)
547 {
548     auto releaseBuffer = [](sptr<SurfaceBuffer> buffer, sptr<SyncFence> releaseFence,
549         sptr<IConsumerSurface> cSurface) -> void {
550         if (cSurface == nullptr) {
551             HLOGE("HdiOutput:: ReleaseBuffer failed, no consumer!");
552             return;
553         }
554         if (buffer == nullptr) {
555             return;
556         }
557         RS_TRACE_NAME("HdiOutput::ReleaseBuffer");
558         auto ret = cSurface->ReleaseBuffer(buffer, releaseFence);
559         if (ret == OHOS::SURFACE_ERROR_OK) {
560             // reset prevBuffer if we release it successfully,
561             // to avoid releasing the same buffer next frame in some situations.
562             buffer = nullptr;
563             releaseFence = SyncFence::InvalidFence();
564         }
565     };
566     const auto layersReleaseFence = GetLayersReleaseFenceLocked();
567     if (layersReleaseFence.size() == 0) {
568         // When release fence's size is 0, the output may invalid, release all buffer
569         // This situation may happen when killing composer_host
570         for (const auto& [id, layer] : layerIdMap_) {
571             if (layer == nullptr || layer->GetLayerInfo()->GetSurface() == nullptr) {
572                 HLOGW("HdiOutput::ReleaseLayers: layer or layer's cSurface is nullptr");
573                 continue;
574             }
575             auto preBuffer = layer->GetLayerInfo()->GetPreBuffer();
576             auto consumer = layer->GetLayerInfo()->GetSurface();
577             releaseBuffer(preBuffer, SyncFence::InvalidFence(), consumer);
578         }
579         HLOGD("HdiOutput::ReleaseLayers: no layer needs to release");
580     }
581     for (const auto& [layer, fence] : layersReleaseFence) {
582         if (layer != nullptr) {
583             auto preBuffer = layer->GetPreBuffer();
584             auto consumer = layer->GetSurface();
585             releaseBuffer(preBuffer, fence, consumer);
586             if (layer->GetUniRenderFlag()) {
587                 releaseFence = fence;
588             }
589         }
590     }
591 }
592 
ReleaseLayers(sptr<SyncFence> & releaseFence)593 void HdiOutput::ReleaseLayers(sptr<SyncFence>& releaseFence)
594 {
595     auto layerPresentTimestamp = [](const LayerInfoPtr& layer, const sptr<IConsumerSurface>& cSurface) -> void {
596         if (!layer->IsSupportedPresentTimestamp()) {
597             return;
598         }
599         const auto& buffer = layer->GetBuffer();
600         if (buffer == nullptr) {
601             return;
602         }
603         if (cSurface->SetPresentTimestamp(buffer->GetSeqNum(), layer->GetPresentTimestamp()) != GSERROR_OK) {
604             HLOGD("LayerPresentTimestamp: SetPresentTimestamp failed");
605         }
606     };
607 
608     // get present timestamp from and set present timestamp to cSurface
609     std::unique_lock<std::mutex> lock(mutex_);
610     for (const auto& [id, layer] : layerIdMap_) {
611         if (layer == nullptr || layer->GetLayerInfo()->GetSurface() == nullptr) {
612             HLOGW("HdiOutput::ReleaseLayers: layer or layer's cSurface is nullptr");
613             continue;
614         }
615         layerPresentTimestamp(layer->GetLayerInfo(), layer->GetLayerInfo()->GetSurface());
616     }
617     ReleaseSurfaceBuffer(releaseFence);
618 }
619 
GetLayersReleaseFence()620 std::map<LayerInfoPtr, sptr<SyncFence>> HdiOutput::GetLayersReleaseFence()
621 {
622     std::unique_lock<std::mutex> lock(mutex_);
623     return GetLayersReleaseFenceLocked();
624 }
625 
GetLayersReleaseFenceLocked()626 std::map<LayerInfoPtr, sptr<SyncFence>> HdiOutput::GetLayersReleaseFenceLocked()
627 {
628     std::map<LayerInfoPtr, sptr<SyncFence>> res;
629     size_t layerNum = layersId_.size();
630     for (size_t i = 0; i < layerNum; i++) {
631         auto iter = layerIdMap_.find(layersId_[i]);
632         if (iter == layerIdMap_.end()) {
633             HLOGE("Invalid hdi layer id [%{public}u]", layersId_[i]);
634             continue;
635         }
636 
637         const LayerPtr &layer = iter->second;
638         layer->MergeWithLayerFence(fences_[i]);
639         res[layer->GetLayerInfo()] = layer->GetReleaseFence();
640     }
641     return res;
642 }
643 
StartVSyncSampler(bool forceReSample)644 int32_t HdiOutput::StartVSyncSampler(bool forceReSample)
645 {
646     if (sampler_ == nullptr) {
647         sampler_ = CreateVSyncSampler();
648     }
649     if (sampler_->StartSample(forceReSample) == VSYNC_ERROR_OK) {
650         return GRAPHIC_DISPLAY_SUCCESS;
651     } else {
652         return GRAPHIC_DISPLAY_FAILURE;
653     }
654 }
655 
SetPendingMode(int64_t period,int64_t timestamp)656 void HdiOutput::SetPendingMode(int64_t period, int64_t timestamp)
657 {
658     ScopedBytrace func("VSyncSampler::SetPendingMode period:" + std::to_string(period) +
659                         ", timestamp:" + std::to_string(timestamp));
660     if (sampler_ == nullptr) {
661         sampler_ = CreateVSyncSampler();
662     }
663     sampler_->SetPendingPeriod(period);
664     CreateVSyncGenerator()->SetPendingMode(period, timestamp);
665 }
666 
Dump(std::string & result) const667 void HdiOutput::Dump(std::string &result) const
668 {
669     std::vector<LayerDumpInfo> dumpLayerInfos;
670     std::unique_lock<std::mutex> lock(mutex_);
671     ReorderLayerInfoLocked(dumpLayerInfos);
672 
673     result.append("\n");
674     result.append("-- LayerInfo\n");
675 
676     for (const LayerDumpInfo &layerInfo : dumpLayerInfos) {
677         const LayerPtr &layer = layerInfo.layer;
678         if (layer == nullptr || layer->GetLayerInfo() == nullptr) {
679             continue;
680         }
681         auto surface = layer->GetLayerInfo()->GetSurface();
682         const std::string& name = surface ? surface->GetName() :
683             "Layer Without Surface" + std::to_string(SOLID_SURFACE_COUNT);
684         auto info = layer->GetLayerInfo();
685         result += "\n surface [" + name + "] NodeId[" + std::to_string(layerInfo.nodeId) + "]";
686         result +=  " LayerId[" + std::to_string(layer->GetLayerId()) + "]:\n";
687         info->Dump(result);
688     }
689 
690     if (fbSurface_ != nullptr) {
691         result += "\n";
692         result += "FrameBufferSurface\n";
693         fbSurface_->Dump(result);
694     }
695     CreateVSyncGenerator()->Dump(result);
696     CreateVSyncSampler()->Dump(result);
697 }
698 
DumpFps(std::string & result,const std::string & arg) const699 void HdiOutput::DumpFps(std::string &result, const std::string &arg) const
700 {
701     std::vector<LayerDumpInfo> dumpLayerInfos;
702     std::unique_lock<std::mutex> lock(mutex_);
703     ReorderLayerInfoLocked(dumpLayerInfos);
704     result.append("\n");
705     if (arg == "composer") {
706         result += "The fps of screen [Id:" + std::to_string(screenId_) + "] is:\n";
707         const int32_t offset = compTimeRcdIndex_;
708         for (uint32_t i = 0; i < COMPOSITION_RECORDS_NUM; i++) {
709             uint32_t order = (offset + i) % COMPOSITION_RECORDS_NUM;
710             result += std::to_string(compositionTimeRecords_[order]) + "\n";
711         }
712         return;
713     }
714 
715     for (const LayerDumpInfo &layerInfo : dumpLayerInfos) {
716         const LayerPtr &layer = layerInfo.layer;
717         if (arg == "UniRender") {
718             if (layer->GetLayerInfo()->GetUniRenderFlag()) {
719                 result += "\n surface [" + arg + "] Id[" + std::to_string(layerInfo.surfaceId) + "]:\n";
720                 layer->DumpMergedResult(result);
721                 break;
722             }
723             continue;
724         }
725         if (layer->GetLayerInfo()->GetSurface() == nullptr) {
726             continue;
727         }
728         const std::string& name = layer->GetLayerInfo()->GetSurface()->GetName();
729         if (name == arg) {
730             result += "\n surface [" + name + "] Id[" + std::to_string(layerInfo.surfaceId) + "]:\n";
731             layer->Dump(result);
732         }
733         if (layer->GetLayerInfo()->GetUniRenderFlag()) {
734             auto windowsName = layer->GetLayerInfo()->GetWindowsName();
735             auto iter = std::find(windowsName.begin(), windowsName.end(), arg);
736             if (iter != windowsName.end()) {
737                 result += "\n window [" + arg + "] Id[" + std::to_string(layerInfo.surfaceId) + "]:\n";
738                 layer->DumpByName(arg, result);
739             }
740         }
741     }
742 }
743 
DumpHitchs(std::string & result,const std::string & arg) const744 void HdiOutput::DumpHitchs(std::string &result, const std::string &arg) const
745 {
746     std::vector<LayerDumpInfo> dumpLayerInfos;
747     std::unique_lock<std::mutex> lock(mutex_);
748     ReorderLayerInfoLocked(dumpLayerInfos);
749     result.append("\n");
750     for (const LayerDumpInfo &layerInfo : dumpLayerInfos) {
751         const LayerPtr &layer = layerInfo.layer;
752         if (layer->GetLayerInfo()->GetUniRenderFlag()) {
753             result += "\n window [" + arg + "] Id[" + std::to_string(layerInfo.surfaceId) + "]:\n";
754             layer->SelectHitchsInfo(arg, result);
755         }
756     }
757 }
758 
ClearFpsDump(std::string & result,const std::string & arg)759 void HdiOutput::ClearFpsDump(std::string &result, const std::string &arg)
760 {
761     std::vector<LayerDumpInfo> dumpLayerInfos;
762     std::unique_lock<std::mutex> lock(mutex_);
763     ReorderLayerInfoLocked(dumpLayerInfos);
764 
765     result.append("\n");
766     if (arg == "composer") {
767         result += "The fps info of screen [Id:" + std::to_string(screenId_) + "] is cleared.\n";
768         compositionTimeRecords_.fill(0);
769         return;
770     }
771 
772     for (const LayerDumpInfo &layerInfo : dumpLayerInfos) {
773         const LayerPtr &layer = layerInfo.layer;
774         const std::string& name = layer->GetLayerInfo()->GetSurface()->GetName();
775         if (name == arg) {
776             result += "\n The fps info of surface [" + name + "] Id["
777                 + std::to_string(layerInfo.surfaceId) + "] is cleared.\n";
778             layer->ClearDump();
779         }
780     }
781 }
782 
Cmp(const LayerDumpInfo & layer1,const LayerDumpInfo & layer2)783 static inline bool Cmp(const LayerDumpInfo &layer1, const LayerDumpInfo &layer2)
784 {
785     return layer1.layer->GetLayerInfo()->GetZorder() < layer2.layer->GetLayerInfo()->GetZorder();
786 }
787 
ReorderLayerInfoLocked(std::vector<LayerDumpInfo> & dumpLayerInfos) const788 void HdiOutput::ReorderLayerInfoLocked(std::vector<LayerDumpInfo> &dumpLayerInfos) const
789 {
790     for (auto iter = surfaceIdMap_.begin(); iter != surfaceIdMap_.end(); ++iter) {
791         if (iter->second == nullptr || iter->second->GetLayerInfo() == nullptr) {
792             continue;
793         }
794         struct LayerDumpInfo layerInfo = {
795             .nodeId = iter->second->GetLayerInfo()->GetNodeId(),
796             .surfaceId = iter->first,
797             .layer = iter->second,
798         };
799 
800         dumpLayerInfos.emplace_back(layerInfo);
801     }
802 
803     std::sort(dumpLayerInfos.begin(), dumpLayerInfos.end(), Cmp);
804 }
805 
GetBufferCacheSize()806 int HdiOutput::GetBufferCacheSize()
807 {
808     return bufferCache_.size();
809 }
810 
ClearBufferCache()811 void HdiOutput::ClearBufferCache()
812 {
813     if (bufferCache_.empty()) {
814         return;
815     }
816     int32_t ret = device_->ClearClientBuffer(screenId_);
817     if (ret != GRAPHIC_DISPLAY_SUCCESS) {
818         HLOGD("Call hdi ClearClientBuffer failed, ret is %{public}d", ret);
819     }
820     bufferCache_.clear();
821 }
822 } // namespace Rosen
823 } // namespace OHOS
824