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