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