• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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