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