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