1 /*
2 * Copyright (C) 2021–2022 Beijing OSWare Technology Co., Ltd
3 * This file contains confidential and proprietary information of
4 * OSWare Technology Co., Ltd
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19 #include "hdi_video_composition.h"
20 #include <set>
21 #include <cinttypes>
22 #include <dlfcn.h>
23
24 namespace OHOS {
25 namespace HDI {
26 namespace DISPLAY {
VideoModuleInit(void)27 int32_t HdiVideoComposition::VideoModuleInit(void)
28 {
29 DISPLAY_LOGD();
30 videoModule_ = dlopen(VO_LAYER_LIB_NAME, RTLD_NOW | RTLD_NOLOAD);
31 if (videoModule_ != nullptr) {
32 DISPLAY_LOGI("Module '%{public}s' already loaded", VO_LAYER_LIB_NAME);
33 } else {
34 DISPLAY_LOGI("Loading module '%{public}s'", VO_LAYER_LIB_NAME);
35 videoModule_ = dlopen(VO_LAYER_LIB_NAME, RTLD_NOW);
36 if (videoModule_ == nullptr) {
37 DISPLAY_LOGE("Failed to load module: %{public}s", dlerror());
38 return DISPLAY_FAILURE;
39 }
40 }
41
42 using InitFunc = int32_t (*)(LayerFuncs **funcs);
43 InitFunc func = reinterpret_cast<InitFunc>(dlsym(videoModule_, VO_LAYER_FUNC_INIT));
44 if (func == nullptr) {
45 DISPLAY_LOGE("Failed to lookup %{public}s function: %s", VO_LAYER_FUNC_INIT, dlerror());
46 dlclose(videoModule_);
47 videoModule_ = nullptr;
48 return DISPLAY_FAILURE;
49 }
50 return func(&layerFuncs_);
51 }
52
CreateVideoLayerForHdiLayer(HdiLayer & hdiLayer)53 uint32_t HdiVideoComposition::CreateVideoLayerForHdiLayer(HdiLayer &hdiLayer)
54 {
55 uint32_t voLayerId;
56 DISPLAY_LOGD("layerId %{public}d", hdiLayer.GetId());
57 IRect rect = hdiLayer.GetLayerDisplayRect();
58 LayerInfo layerInfo = { rect.w, rect.h, LAYER_TYPE_OVERLAY, 8, PIXEL_FMT_YCRCB_420_P }; // the bpp of yuv is 8
59 int ret = layerFuncs_->CreateLayer(0, &layerInfo, &voLayerId);
60 DISPLAY_CHK_RETURN(((ret != DISPLAY_SUCCESS) || (voLayerId == INVALIDE_LAYER_ID)), INVALIDE_LAYER_ID,
61 DISPLAY_LOGE("can not create video layer"));
62 layerMaps_[hdiLayer.GetId()] = voLayerId;
63 DISPLAY_LOGD("map the voLayerId %{public}d to layerId %{public}d", voLayerId, hdiLayer.GetId());
64 return voLayerId;
65 }
66
GetVoLayerId(HdiLayer & hdiLayer)67 uint32_t HdiVideoComposition::GetVoLayerId(HdiLayer &hdiLayer)
68 {
69 DISPLAY_LOGD("layerId %{public}d", hdiLayer.GetId());
70 uint32_t voLayerId = INVALIDE_LAYER_ID;
71 if (layerMaps_.find(hdiLayer.GetId()) != layerMaps_.end()) {
72 voLayerId = layerMaps_[hdiLayer.GetId()];
73 }
74 return voLayerId;
75 }
76
Init(void)77 int32_t HdiVideoComposition::Init(void)
78 {
79 DISPLAY_LOGD();
80 int ret = VideoModuleInit();
81 DISPLAY_CHK_RETURN(((ret != DISPLAY_SUCCESS) || (layerFuncs_ == nullptr)), DISPLAY_FAILURE,
82 DISPLAY_LOGE("can not init the video module"));
83 return DISPLAY_SUCCESS;
84 }
85
SetLayers(std::vector<HdiLayer * > & layers,HdiLayer & clientLayer)86 int32_t HdiVideoComposition::SetLayers(std::vector<HdiLayer*> &layers, HdiLayer &clientLayer)
87 {
88 DISPLAY_LOGD();
89 mCompLayers.clear();
90 std::vector<HdiLayer*> matchedLayers;
91 for (auto layer : layers) {
92 if ((layer != nullptr) && CanHandle(*layer)) {
93 matchedLayers.push_back(layer);
94 }
95 }
96 CLoseUnUsedLayer(matchedLayers);
97 // make sure has the videoLayer for the matched layer
98 for (auto layer : matchedLayers) {
99 if ((GetVoLayerId(*layer) != INVALIDE_LAYER_ID) ||
100 (CreateVideoLayerForHdiLayer(*layer) != INVALIDE_LAYER_ID)) {
101 layer->SetLayerCompositionType(COMPOSITION_VIDEO);
102 mCompLayers.push_back(layer);
103 }
104 }
105 return DISPLAY_SUCCESS;
106 }
107
Apply(bool modeSet)108 int32_t HdiVideoComposition::Apply(bool modeSet)
109 {
110 DISPLAY_LOGD();
111 for (auto hdiLayer : mCompLayers) {
112 if (hdiLayer == nullptr) {
113 DISPLAY_LOGE("the composer layer is nullptr");
114 continue;
115 }
116 uint32_t voLayerId = GetVoLayerId(*hdiLayer);
117 layerFuncs_->SetLayerSize(0, voLayerId, const_cast<IRect *>(&(hdiLayer->GetLayerDisplayRect())));
118 layerFuncs_->SetLayerCrop(0, voLayerId, const_cast<IRect *>(&(hdiLayer->GetLayerCrop())));
119 layerFuncs_->SetLayerZorder(0, voLayerId, hdiLayer->GetZorder());
120 layerFuncs_->SetTransformMode(0, voLayerId, hdiLayer->GetTransFormType());
121 // now the display_layer has no fence
122 layerFuncs_->SetLayerBuffer(0, voLayerId, &(hdiLayer->GetCurrentBuffer()->mHandle),
123 hdiLayer->GetAcquireFenceFd());
124 hdiLayer->SetReleaseFence(-1); // todo check the fence wether use the last fence.
125 }
126 return DISPLAY_SUCCESS;
127 }
128
CLoseUnUsedLayer(std::vector<HdiLayer * > & layers)129 void HdiVideoComposition::CLoseUnUsedLayer(std::vector<HdiLayer*> &layers)
130 {
131 DISPLAY_LOGD();
132 std::vector<uint32_t> neededRemove;
133 for (auto iter = layerMaps_.begin(); iter != layerMaps_.end(); iter++) {
134 bool found = false;
135 for (auto layer : layers) {
136 if (iter->first == layer->GetId()) {
137 found = true;
138 }
139 }
140 if (!found) {
141 DISPLAY_LOGD("close the layer Id %{public}d", iter->second);
142 layerFuncs_->CloseLayer(0, iter->second);
143 neededRemove.push_back(iter->first);
144 break;
145 }
146 }
147 for (auto id : neededRemove) {
148 DISPLAY_LOGD("erase the layer Id %{public}d", id);
149 layerMaps_.erase(id);
150 }
151 }
152
CanHandle(HdiLayer & hdiLayer)153 bool HdiVideoComposition::CanHandle(HdiLayer &hdiLayer)
154 {
155 static std::set<PixelFormat> formats = {
156 PIXEL_FMT_YUV_422_I, /* *< YUV422 interleaved format */
157 PIXEL_FMT_YCBCR_422_SP, /* *< YCBCR422 semi-planar format */
158 PIXEL_FMT_YCRCB_422_SP, /* *< YCRCB422 semi-planar format */
159 PIXEL_FMT_YCBCR_420_SP, /* *< YCBCR420 semi-planar format */
160 PIXEL_FMT_YCRCB_420_SP, /* *< YCRCB420 semi-planar format */
161 PIXEL_FMT_YCBCR_422_P, /* *< YCBCR422 planar format */
162 PIXEL_FMT_YCRCB_422_P, /* *< YCRCB422 planar format */
163 PIXEL_FMT_YCBCR_420_P, /* *< YCBCR420 planar format */
164 PIXEL_FMT_YCRCB_420_P, /* *< YCRCB420 planar format */
165 PIXEL_FMT_YUYV_422_PKG, /* *< YUYV422 packed format */
166 PIXEL_FMT_UYVY_422_PKG, /* *< UYVY422 packed format */
167 PIXEL_FMT_YVYU_422_PKG, /* *< YVYU422 packed format */
168 PIXEL_FMT_VYUY_422_PKG, /* *< VYUY422 packed format */
169 };
170
171 if (hdiLayer.GetType() == LAYER_TYPE_SIDEBAND) {
172 DISPLAY_LOGD("is sideband");
173 return false;
174 }
175
176 if (hdiLayer.GetCurrentBuffer() == nullptr) {
177 DISPLAY_LOGD("has no buffer");
178 return false;
179 }
180
181 if (formats.find(static_cast<PixelFormat>(hdiLayer.GetCurrentBuffer()->GetFormat())) == formats.end()) {
182 return false;
183 }
184 return true;
185 }
186 }
187 }
188 }
189