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 "hdi_layer.h"
17
18 namespace OHOS {
19 namespace Rosen {
20
21 /* rs create layer and set layer info begin */
CreateHdiLayer(uint32_t screenId)22 std::shared_ptr<HdiLayer> HdiLayer::CreateHdiLayer(uint32_t screenId)
23 {
24 return std::make_shared<HdiLayer>(screenId);
25 }
26
HdiLayer(uint32_t screenId)27 HdiLayer::HdiLayer(uint32_t screenId) : screenId_(screenId)
28 {
29 prevSbuffer_ = new LayerBufferInfo();
30 currSbuffer_ = new LayerBufferInfo();
31 }
32
~HdiLayer()33 HdiLayer::~HdiLayer()
34 {
35 CloseLayer();
36 }
37
Init(const LayerInfoPtr & layerInfo)38 bool HdiLayer::Init(const LayerInfoPtr &layerInfo)
39 {
40 if (layerInfo == nullptr) {
41 return false;
42 }
43
44 if (CreateLayer(layerInfo) != DISPLAY_SUCCESS) {
45 return false;
46 }
47
48 return true;
49 }
50
InitDevice()51 int32_t HdiLayer::InitDevice()
52 {
53 if (device_ != nullptr) {
54 return DISPLAY_SUCCESS;
55 }
56
57 device_ = HdiDevice::GetInstance();
58 if (device_ == nullptr) {
59 HLOGE("device_ init failed.");
60 return DISPLAY_NULL_PTR;
61 }
62 return DISPLAY_SUCCESS;
63 }
64
SetHdiDeviceMock(Base::HdiDevice * hdiDeviceMock)65 int32_t HdiLayer::SetHdiDeviceMock(Base::HdiDevice* hdiDeviceMock)
66 {
67 if (hdiDeviceMock == nullptr) {
68 HLOGE("Input HdiDevice is nullptr");
69 return DISPLAY_NULL_PTR;
70 }
71
72 if (device_ != nullptr) {
73 HLOGD("device_ has been initialized");
74 return DISPLAY_SUCCESS;
75 }
76
77 device_ = hdiDeviceMock;
78 return DISPLAY_SUCCESS;
79 }
80
CreateLayer(const LayerInfoPtr & layerInfo)81 int32_t HdiLayer::CreateLayer(const LayerInfoPtr &layerInfo)
82 {
83 GraphicLayerInfo hdiLayerInfo = {
84 .width = layerInfo->GetLayerSize().w,
85 .height = layerInfo->GetLayerSize().h,
86 .type = GRAPHIC_LAYER_TYPE_GRAPHIC,
87 .pixFormat = GRAPHIC_PIXEL_FMT_RGBA_8888,
88 };
89
90 int32_t retCode = InitDevice();
91 if (retCode != DISPLAY_SUCCESS) {
92 return DISPLAY_NULL_PTR;
93 }
94
95 uint32_t layerId = INT_MAX;
96 int32_t ret = device_->CreateLayer(screenId_, hdiLayerInfo, layerId);
97 if (ret != DISPLAY_SUCCESS) {
98 HLOGE("Create hwc layer failed, ret is %{public}d", ret);
99 return ret;
100 }
101
102 layerId_ = layerId;
103
104 HLOGD("Create hwc layer succeed, layerId is %{public}u", layerId_);
105
106 CheckRet(device_->GetSupportedPresentTimestampType(screenId_, layerId_, supportedPresentTimestamptype_),
107 "GetSupportedPresentTimestamp");
108 return ret;
109 }
110
CloseLayer()111 void HdiLayer::CloseLayer()
112 {
113 if (layerId_ == INT_MAX) {
114 HLOGI("this layer has not been created");
115 return;
116 }
117
118 int32_t retCode = InitDevice();
119 if (retCode != DISPLAY_SUCCESS) {
120 return;
121 }
122
123 retCode = device_->CloseLayer(screenId_, layerId_);
124 if (retCode != DISPLAY_SUCCESS) {
125 HLOGE("Close hwc layer[%{public}u] failed, ret is %{public}d", layerId_, retCode);
126 }
127
128 HLOGD("Close hwc layer succeed, layerId is %{public}u", layerId_);
129 }
130
SetLayerAlpha()131 int32_t HdiLayer::SetLayerAlpha()
132 {
133 if (doLayerInfoCompare_) {
134 const GraphicLayerAlpha& layerAlpha1 = layerInfo_->GetAlpha();
135 const GraphicLayerAlpha& layerAlpha2 = prevLayerInfo_->GetAlpha();
136 bool isSame = layerAlpha1.enGlobalAlpha == layerAlpha2.enGlobalAlpha &&
137 layerAlpha1.enPixelAlpha == layerAlpha2.enPixelAlpha &&
138 layerAlpha1.alpha0 == layerAlpha2.alpha0 && layerAlpha1.alpha1 == layerAlpha2.alpha1 &&
139 layerAlpha1.gAlpha == layerAlpha2.gAlpha;
140 if (isSame) {
141 return DISPLAY_SUCCESS;
142 }
143 }
144
145 int32_t ret = device_->SetLayerAlpha(screenId_, layerId_, layerInfo_->GetAlpha());
146 return ret;
147 }
148
IsSameRect(const IRect & rect1,const IRect & rect2)149 bool HdiLayer::IsSameRect(const IRect& rect1, const IRect& rect2)
150 {
151 return rect1.x == rect2.x && rect1.y == rect2.y && rect1.w == rect2.w && rect1.h == rect2.h;
152 }
153
SetLayerSize()154 int32_t HdiLayer::SetLayerSize()
155 {
156 if (doLayerInfoCompare_ && IsSameRect(layerInfo_->GetLayerSize(), prevLayerInfo_->GetLayerSize())) {
157 return DISPLAY_SUCCESS;
158 }
159
160 int32_t ret = device_->SetLayerSize(screenId_, layerId_, layerInfo_->GetLayerSize());
161 return ret;
162 }
163
SetTransformMode()164 int32_t HdiLayer::SetTransformMode()
165 {
166 if (layerInfo_->GetTransformType() == GraphicTransformType::GRAPHIC_ROTATE_BUTT || (doLayerInfoCompare_ &&
167 layerInfo_->GetTransformType() == prevLayerInfo_->GetTransformType())) {
168 return DISPLAY_SUCCESS;
169 }
170
171 int32_t ret = device_->SetTransformMode(screenId_, layerId_, layerInfo_->GetTransformType());
172 return ret;
173 }
174
SetLayerVisibleRegion()175 int32_t HdiLayer::SetLayerVisibleRegion()
176 {
177 if (doLayerInfoCompare_ && IsSameRect(layerInfo_->GetVisibleRegion(), prevLayerInfo_->GetVisibleRegion()) &&
178 layerInfo_->GetVisibleNum() == prevLayerInfo_->GetVisibleNum()) {
179 return DISPLAY_SUCCESS;
180 }
181
182 int32_t ret = device_->SetLayerVisibleRegion(screenId_, layerId_, layerInfo_->GetVisibleNum(),
183 layerInfo_->GetVisibleRegion());
184 return ret;
185 }
186
SetLayerDirtyRegion()187 int32_t HdiLayer::SetLayerDirtyRegion()
188 {
189 if (doLayerInfoCompare_ && IsSameRect(layerInfo_->GetDirtyRegion(), prevLayerInfo_->GetDirtyRegion())) {
190 return DISPLAY_SUCCESS;
191 }
192
193 int32_t ret = device_->SetLayerDirtyRegion(screenId_, layerId_, layerInfo_->GetDirtyRegion());
194 return ret;
195 }
196
SetLayerBuffer()197 int32_t HdiLayer::SetLayerBuffer()
198 {
199 if (layerInfo_->GetBuffer() == nullptr || (doLayerInfoCompare_ &&
200 layerInfo_->GetBuffer() == prevLayerInfo_->GetBuffer() &&
201 layerInfo_->GetAcquireFence() == prevLayerInfo_->GetAcquireFence())) {
202 return DISPLAY_SUCCESS;
203 }
204
205 int32_t ret = device_->SetLayerBuffer(screenId_, layerId_, layerInfo_->GetBuffer()->GetBufferHandle(),
206 layerInfo_->GetAcquireFence());
207 return ret;
208 }
209
SetLayerCompositionType()210 int32_t HdiLayer::SetLayerCompositionType()
211 {
212 if (doLayerInfoCompare_ && layerInfo_->GetCompositionType() == prevLayerInfo_->GetCompositionType()) {
213 return DISPLAY_SUCCESS;
214 }
215
216 int32_t ret = device_->SetLayerCompositionType(screenId_, layerId_, layerInfo_->GetCompositionType());
217 return ret;
218 }
219
SetLayerBlendType()220 int32_t HdiLayer::SetLayerBlendType()
221 {
222 if (doLayerInfoCompare_ && layerInfo_->GetBlendType() == prevLayerInfo_->GetBlendType()) {
223 return DISPLAY_SUCCESS;
224 }
225
226 int32_t ret = device_->SetLayerBlendType(screenId_, layerId_, layerInfo_->GetBlendType());
227 return ret;
228 }
229
SetLayerCrop()230 int32_t HdiLayer::SetLayerCrop()
231 {
232 if (doLayerInfoCompare_ && IsSameRect(layerInfo_->GetCropRect(), prevLayerInfo_->GetCropRect())) {
233 return DISPLAY_SUCCESS;
234 }
235
236 int32_t ret = device_->SetLayerCrop(screenId_, layerId_, layerInfo_->GetCropRect());
237 return ret;
238 }
239
SetLayerZorder()240 int32_t HdiLayer::SetLayerZorder()
241 {
242 if (doLayerInfoCompare_ && layerInfo_->GetZorder() == prevLayerInfo_->GetZorder()) {
243 return DISPLAY_SUCCESS;
244 }
245
246 int32_t ret = device_->SetLayerZorder(screenId_, layerId_, layerInfo_->GetZorder());
247 return ret;
248 }
249
SetLayerPreMulti()250 int32_t HdiLayer::SetLayerPreMulti()
251 {
252 if (doLayerInfoCompare_ && layerInfo_->IsPreMulti() == prevLayerInfo_->IsPreMulti()) {
253 return DISPLAY_SUCCESS;
254 }
255
256 int32_t ret = device_->SetLayerPreMulti(screenId_, layerId_, layerInfo_->IsPreMulti());
257 return ret;
258 }
259
SetLayerColorTransform()260 int32_t HdiLayer::SetLayerColorTransform()
261 {
262 if (doLayerInfoCompare_ && layerInfo_->GetColorTransform() == prevLayerInfo_->GetColorTransform()) {
263 return DISPLAY_SUCCESS;
264 }
265
266 // because hdi interface func is not implemented, delete CheckRet to avoid excessive print of log
267 device_->SetLayerColorTransform(screenId_, layerId_, layerInfo_->GetColorTransform());
268 return DISPLAY_SUCCESS;
269 }
270
SetLayerColorDataSpace()271 int32_t HdiLayer::SetLayerColorDataSpace()
272 {
273 if (doLayerInfoCompare_ && layerInfo_->GetColorDataSpace() == prevLayerInfo_->GetColorDataSpace()) {
274 return DISPLAY_SUCCESS;
275 }
276
277 // because hdi interface func is not implemented, delete CheckRet to avoid excessive print of log
278 device_->SetLayerColorDataSpace(screenId_, layerId_, layerInfo_->GetColorDataSpace());
279 return DISPLAY_SUCCESS;
280 }
281
IsSameLayerMetaData()282 bool HdiLayer::IsSameLayerMetaData()
283 {
284 bool isSame = false;
285 std::vector<GraphicHDRMetaData>& metaData = layerInfo_->GetMetaData();
286 std::vector<GraphicHDRMetaData>& prevMetaData = prevLayerInfo_->GetMetaData();
287 if (metaData.size() == prevMetaData.size()) {
288 isSame = true;
289 size_t metaDeataSize = metaData.size();
290 for (size_t i = 0; i < metaDeataSize; i++) {
291 if (metaData[i].key != prevMetaData[i].key || metaData[i].value != prevMetaData[i].value) {
292 isSame = false;
293 break;
294 }
295 }
296 }
297 return isSame;
298 }
299
SetLayerMetaData()300 int32_t HdiLayer::SetLayerMetaData()
301 {
302 if (doLayerInfoCompare_) {
303 bool isSame = IsSameLayerMetaData();
304 if (isSame) {
305 return DISPLAY_SUCCESS;
306 }
307 }
308
309 // because hdi interface func is not implemented, delete CheckRet to avoid excessive print of log
310 device_->SetLayerMetaData(screenId_, layerId_, layerInfo_->GetMetaData());
311 return DISPLAY_SUCCESS;
312 }
313
314
IsSameLayerMetaDataSet()315 bool HdiLayer::IsSameLayerMetaDataSet()
316 {
317 bool isSame = false;
318 GraphicHDRMetaDataSet &metaDataSet = layerInfo_->GetMetaDataSet();
319 GraphicHDRMetaDataSet &prevMetaDataSet = prevLayerInfo_->GetMetaDataSet();
320 if (metaDataSet.key == prevMetaDataSet.key &&
321 metaDataSet.metaData.size() == prevMetaDataSet.metaData.size()) {
322 isSame = true;
323 size_t metaDeataSetSize = metaDataSet.metaData.size();
324 for (size_t i = 0; i < metaDeataSetSize; i++) {
325 if (metaDataSet.metaData[i] != prevMetaDataSet.metaData[i]) {
326 isSame = false;
327 break;
328 }
329 }
330 }
331 return isSame;
332 }
333
SetLayerMetaDataSet()334 int32_t HdiLayer::SetLayerMetaDataSet()
335 {
336 if (doLayerInfoCompare_) {
337 bool isSame = IsSameLayerMetaDataSet();
338 if (isSame) {
339 return DISPLAY_SUCCESS;
340 }
341 }
342
343 // because hdi interface func is not implemented, delete CheckRet to avoid excessive print of log
344 device_->SetLayerMetaDataSet(screenId_, layerId_, layerInfo_->GetMetaDataSet().key,
345 layerInfo_->GetMetaDataSet().metaData);
346 return DISPLAY_SUCCESS;
347 }
348
SetLayerTunnelHandle()349 int32_t HdiLayer::SetLayerTunnelHandle()
350 {
351 if (!layerInfo_->GetTunnelHandleChange()) {
352 return DISPLAY_SUCCESS;
353 }
354 int32_t ret = DISPLAY_SUCCESS;
355 if (layerInfo_->GetTunnelHandle() == nullptr) {
356 ret = device_->SetLayerTunnelHandle(screenId_, layerId_, nullptr);
357 } else {
358 ret = device_->SetLayerTunnelHandle(screenId_, layerId_, layerInfo_->GetTunnelHandle()->GetHandle());
359 }
360 return ret;
361 }
362
SetLayerPresentTimestamp()363 int32_t HdiLayer::SetLayerPresentTimestamp()
364 {
365 if (supportedPresentTimestamptype_ == GraphicPresentTimestampType::GRAPHIC_DISPLAY_PTS_UNSUPPORTED) {
366 return DISPLAY_SUCCESS;
367 }
368 layerInfo_->SetIsSupportedPresentTimestamp(true);
369 GraphicPresentTimestamp timestamp = {GRAPHIC_DISPLAY_PTS_UNSUPPORTED, 0};
370 int32_t ret = device_->GetPresentTimestamp(screenId_, layerId_, timestamp);
371 CheckRet(ret, "GetPresentTimestamp");
372 if (ret == DISPLAY_SUCCESS) {
373 layerInfo_->SetPresentTimestamp(timestamp);
374 }
375 return ret;
376 }
377
SetHdiLayerInfo()378 int32_t HdiLayer::SetHdiLayerInfo()
379 {
380 /*
381 Some hardware platforms may not support all layer settings.
382 If the current function is not supported, continue other layer settings.
383 */
384 int32_t ret = InitDevice();
385 if (ret != DISPLAY_SUCCESS || layerInfo_ == nullptr) {
386 return DISPLAY_FAILURE;
387 }
388
389 // All layer properities need to set to hwc when the layer is created firstly or the previous layer's composition
390 // type is COMPOSITION_DEVICE for COMPOSITION_DEVICE can not reuse COMPOSITION_CLIENT layers info.
391 doLayerInfoCompare_ = prevLayerInfo_ != nullptr &&
392 prevLayerInfo_->GetCompositionType() == GraphicCompositionType::GRAPHIC_COMPOSITION_DEVICE;
393
394 ret = SetLayerAlpha();
395 CheckRet(ret, "SetLayerAlpha");
396 ret = SetLayerSize();
397 CheckRet(ret, "SetLayerSize");
398 ret = SetTransformMode();
399 CheckRet(ret, "SetTransformMode");
400 ret = SetLayerVisibleRegion();
401 CheckRet(ret, "SetLayerVisibleRegion");
402 ret = SetLayerDirtyRegion();
403 CheckRet(ret, "SetLayerDirtyRegion");
404 ret = SetLayerBuffer();
405 CheckRet(ret, "SetLayerBuffer");
406 ret = SetLayerCompositionType();
407 CheckRet(ret, "SetLayerCompositionType");
408 ret = SetLayerBlendType();
409 CheckRet(ret, "SetLayerBlendType");
410 ret = SetLayerCrop();
411 CheckRet(ret, "SetLayerCrop");
412 ret = SetLayerZorder();
413 CheckRet(ret, "SetLayerZorder");
414 ret = SetLayerPreMulti();
415 CheckRet(ret, "SetLayerPreMulti");
416 ret = SetLayerColorTransform();
417 CheckRet(ret, "SetLayerColorTransform");
418 ret = SetLayerColorDataSpace();
419 CheckRet(ret, "SetLayerColorDataSpace");
420 ret = SetLayerMetaData();
421 CheckRet(ret, "SetLayerMetaData");
422 ret = SetLayerMetaDataSet();
423 CheckRet(ret, "SetLayerMetaDataSet");
424 ret = SetLayerTunnelHandle();
425 CheckRet(ret, "SetLayerTunnelHandle");
426 ret = SetLayerPresentTimestamp();
427 CheckRet(ret, "SetLayerPresentTimestamp");
428 return DISPLAY_SUCCESS;
429 }
430
GetLayerId() const431 uint32_t HdiLayer::GetLayerId() const
432 {
433 return layerId_;
434 }
435
GetLayerInfo()436 const LayerInfoPtr& HdiLayer::GetLayerInfo()
437 {
438 return layerInfo_;
439 }
440
SetLayerStatus(bool inUsing)441 void HdiLayer::SetLayerStatus(bool inUsing)
442 {
443 isInUsing_ = inUsing;
444 }
445
GetLayerStatus() const446 bool HdiLayer::GetLayerStatus() const
447 {
448 return isInUsing_;
449 }
450
UpdateLayerInfo(const LayerInfoPtr & layerInfo)451 void HdiLayer::UpdateLayerInfo(const LayerInfoPtr &layerInfo)
452 {
453 if (layerInfo == nullptr) {
454 return;
455 }
456
457 /* If the layer is updated, it indicates that the layer will be used
458 * in the frame. Mark it.
459 */
460
461 isInUsing_ = true;
462 layerInfo_ = layerInfo;
463
464 prevSbuffer_->sbuffer_ = currSbuffer_->sbuffer_;
465 prevSbuffer_->acquireFence_ = currSbuffer_->acquireFence_;
466
467 currSbuffer_->sbuffer_ = layerInfo_->GetBuffer();
468 currSbuffer_->acquireFence_ = layerInfo_->GetAcquireFence();
469 }
470
GetReleaseFence() const471 sptr<SyncFence> HdiLayer::GetReleaseFence() const
472 {
473 if (currSbuffer_ == nullptr) {
474 return SyncFence::INVALID_FENCE;
475 }
476 return currSbuffer_->releaseFence_;
477 }
478
RecordPresentTime(int64_t timestamp)479 void HdiLayer::RecordPresentTime(int64_t timestamp)
480 {
481 if (currSbuffer_->sbuffer_ != prevSbuffer_->sbuffer_) {
482 presentTimeRecords[count] = timestamp;
483 count = (count + 1) % FRAME_RECORDS_NUM;
484 }
485 }
486
MergeWithFramebufferFence(const sptr<SyncFence> & fbAcquireFence)487 void HdiLayer::MergeWithFramebufferFence(const sptr<SyncFence> &fbAcquireFence)
488 {
489 if (fbAcquireFence != nullptr) {
490 currSbuffer_->releaseFence_ = Merge(currSbuffer_->releaseFence_, fbAcquireFence);
491 }
492 }
493
MergeWithLayerFence(const sptr<SyncFence> & layerReleaseFence)494 void HdiLayer::MergeWithLayerFence(const sptr<SyncFence> &layerReleaseFence)
495 {
496 if (layerReleaseFence != nullptr) {
497 currSbuffer_->releaseFence_ = layerReleaseFence;
498 }
499 }
500
UpdateCompositionType(GraphicCompositionType type)501 void HdiLayer::UpdateCompositionType(GraphicCompositionType type)
502 {
503 if (layerInfo_ == nullptr) {
504 return;
505 }
506
507 layerInfo_->SetCompositionType(type);
508 }
509 /* backend get layer info end */
510
Merge(const sptr<SyncFence> & fence1,const sptr<SyncFence> & fence2)511 sptr<SyncFence> HdiLayer::Merge(const sptr<SyncFence> &fence1, const sptr<SyncFence> &fence2)
512 {
513 return SyncFence::MergeFence("ReleaseFence", fence1, fence2);
514 }
515
CheckRet(int32_t ret,const char * func)516 void HdiLayer::CheckRet(int32_t ret, const char* func)
517 {
518 if (ret != DISPLAY_SUCCESS) {
519 HLOGD("call hdi %{public}s failed, ret is %{public}d", func, ret);
520 }
521 }
522
SavePrevLayerInfo()523 void HdiLayer::SavePrevLayerInfo()
524 {
525 if (prevLayerInfo_ == nullptr) {
526 prevLayerInfo_ = HdiLayerInfo::CreateHdiLayerInfo();
527 }
528 prevLayerInfo_->CopyLayerInfo(layerInfo_);
529 }
530
Dump(std::string & result)531 void HdiLayer::Dump(std::string &result)
532 {
533 const uint32_t offset = count;
534 for (uint32_t i = 0; i < FRAME_RECORDS_NUM; i++) {
535 uint32_t order = (offset + i) % FRAME_RECORDS_NUM;
536 result += std::to_string(presentTimeRecords[order]) + "\n";
537 }
538 }
539
ClearDump()540 void HdiLayer::ClearDump()
541 {
542 presentTimeRecords.fill(0);
543 }
544 } // namespace Rosen
545 } // namespace OHOS
546