• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "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