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