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