1 /*
2 * Copyright (c) 2021-2023 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_gfx_composition.h"
17 #include <cinttypes>
18 #include <dlfcn.h>
19 #include <cerrno>
20 #include "display_log.h"
21 #include "display_gfx.h"
22 #include "hitrace_meter.h"
23 #include "v1_0/display_composer_type.h"
24
25 using namespace OHOS::HDI::Display::Composer::V1_0;
26
27 namespace OHOS {
28 namespace HDI {
29 namespace DISPLAY {
Init(void)30 int32_t HdiGfxComposition::Init(void)
31 {
32 DISPLAY_LOGD();
33 int32_t ret = GfxModuleInit();
34 DISPLAY_CHK_RETURN((ret != DISPLAY_SUCCESS) || (mGfxFuncs == nullptr), DISPLAY_FAILURE,
35 DISPLAY_LOGE("GfxModuleInit failed"));
36 ret = mGfxFuncs->InitGfx();
37 DISPLAY_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_LOGE("gfx init failed"));
38 return DISPLAY_SUCCESS;
39 }
40
GfxModuleInit(void)41 int32_t HdiGfxComposition::GfxModuleInit(void)
42 {
43 DISPLAY_LOGD();
44 mGfxModule = dlopen("libdisplay_gfx.z.so", RTLD_NOW | RTLD_NOLOAD);
45 if (mGfxModule != nullptr) {
46 DISPLAY_LOGI("Module '%{public}s' already loaded", "libdisplay_gfx.z.so");
47 } else {
48 DISPLAY_LOGI("Loading module '%{public}s'", "libdisplay_gfx.z.so");
49 mGfxModule = dlopen("libdisplay_gfx.z.so", RTLD_NOW);
50 if (mGfxModule == nullptr) {
51 DISPLAY_LOGE("Failed to load module: %{public}s", dlerror());
52 return DISPLAY_FAILURE;
53 }
54 }
55
56 using InitFunc = int32_t (*)(GfxFuncs **funcs);
57 InitFunc func = reinterpret_cast<InitFunc>(dlsym(mGfxModule, "GfxInitialize"));
58 if (func == nullptr) {
59 DISPLAY_LOGE("Failed to lookup %{public}s function: %s", "GfxInitialize", dlerror());
60 dlclose(mGfxModule);
61 return DISPLAY_FAILURE;
62 }
63 return func(&mGfxFuncs);
64 }
65
GfxModuleDeinit(void)66 int32_t HdiGfxComposition::GfxModuleDeinit(void)
67 {
68 DISPLAY_LOGD();
69 int32_t ret = DISPLAY_SUCCESS;
70 if (mGfxModule == nullptr) {
71 using DeinitFunc = int32_t (*)(GfxFuncs *funcs);
72 DeinitFunc func = reinterpret_cast<DeinitFunc>(dlsym(mGfxModule, "GfxUninitialize"));
73 if (func == nullptr) {
74 DISPLAY_LOGE("Failed to lookup %{public}s function: %s", "GfxUninitialize", dlerror());
75 } else {
76 ret = func(mGfxFuncs);
77 }
78 dlclose(mGfxModule);
79 }
80 return ret;
81 }
82
CanHandle(HdiLayer & hdiLayer)83 bool HdiGfxComposition::CanHandle(HdiLayer &hdiLayer)
84 {
85 DISPLAY_LOGD();
86 (void)hdiLayer;
87 return true;
88 }
89
UseCompositionClient(std::vector<HdiLayer * > & layers)90 bool HdiGfxComposition::UseCompositionClient(std::vector<HdiLayer *> &layers)
91 {
92 int32_t layerCount = 0;
93 bool hasCompositionClient = false;
94
95 for (auto &layer : layers) {
96 if (!CanHandle(*layer)) {
97 continue;
98 }
99 CompositionType type = layer->GetCompositionType();
100 layerCount += (type != COMPOSITION_VIDEO) && (type != COMPOSITION_CURSOR);
101 hasCompositionClient = hasCompositionClient || (type == COMPOSITION_CLIENT);
102 }
103 return hasCompositionClient || (layerCount > 4);
104 }
105
SetLayers(std::vector<HdiLayer * > & layers,HdiLayer & clientLayer)106 int32_t HdiGfxComposition::SetLayers(std::vector<HdiLayer *> &layers, HdiLayer &clientLayer)
107 {
108 std::lock_guard<std::mutex> lock(mCompLayersMutex);
109 DISPLAY_LOGD("layers size %{public}zd", layers.size());
110 CompositionType defaultCompType = UseCompositionClient(layers) ? COMPOSITION_CLIENT : COMPOSITION_DEVICE;
111 mClientLayer = &clientLayer;
112 mCompLayers.clear();
113 for (auto &layer : layers) {
114 if (!CanHandle(*layer)) {
115 continue;
116 }
117
118 if ((layer->GetCompositionType() == COMPOSITION_VIDEO) ||
119 (layer->GetCompositionType() == COMPOSITION_CURSOR)) {
120 layer->SetDeviceSelect(layer->GetCompositionType());
121 } else {
122 layer->SetDeviceSelect(defaultCompType);
123 }
124
125 mCompLayers.push_back(layer);
126 }
127 DISPLAY_LOGD("composer layers size %{public}zd", mCompLayers.size());
128 return DISPLAY_SUCCESS;
129 }
130
InitGfxSurface(ISurface & iSurface,HdiLayerBuffer & buffer)131 void HdiGfxComposition::InitGfxSurface(ISurface &iSurface, HdiLayerBuffer &buffer)
132 {
133 iSurface.width = buffer.GetWight();
134 iSurface.height = buffer.GetHeight();
135 iSurface.phyAddr = buffer.GetFb(); // buffer.GetPhysicalAddr();
136 iSurface.enColorFmt = (PixelFormat)buffer.GetFormat();
137 iSurface.stride = buffer.GetStride();
138 iSurface.bAlphaExt1555 = true;
139 iSurface.bAlphaMax255 = true;
140 iSurface.alpha0 = 0XFF;
141 iSurface.alpha1 = 0XFF;
142 DISPLAY_LOGD("iSurface fd %{public}d w:%{public}d h:%{public}d addr:0x%{public}" \
143 PRIx64 " fmt:%{public}d stride:%{public}d",
144 buffer.GetFb(), iSurface.width, iSurface.height,
145 buffer.GetPhysicalAddr(), iSurface.enColorFmt, iSurface.stride);
146 }
147
148 // now not handle the alpha of layer
BlitLayer(HdiLayer & src,HdiLayer & dst)149 int32_t HdiGfxComposition::BlitLayer(HdiLayer &src, HdiLayer &dst)
150 {
151 ISurface srcSurface = { 0 };
152 ISurface dstSurface = { 0 };
153 GfxOpt opt = { 0 };
154 StartTrace(HITRACE_TAG_HDF, "HDI:DISP:WaitAcquireFence");
155 src.WaitAcquireFence();
156 FinishTrace(HITRACE_TAG_HDF);
157 DISPLAY_LOGD();
158 HdiLayerBuffer *srcBuffer = src.GetCurrentBuffer();
159 DISPLAY_CHK_RETURN((srcBuffer == nullptr), DISPLAY_NULL_PTR, DISPLAY_LOGE("the srcbuffer is null"));
160 DISPLAY_LOGD("init the src iSurface");
161 InitGfxSurface(srcSurface, *srcBuffer);
162
163 HdiLayerBuffer *dstBuffer = dst.GetCurrentBuffer();
164 DISPLAY_CHK_RETURN((dstBuffer == nullptr), DISPLAY_FAILURE, DISPLAY_LOGE("can not get client layer buffer"));
165 DISPLAY_LOGD("init the dst iSurface");
166 InitGfxSurface(dstSurface, *dstBuffer);
167
168 opt.blendType = src.GetLayerBlenType();
169 DISPLAY_LOGD("blendType %{public}d", opt.blendType);
170 opt.enPixelAlpha = true;
171 opt.enableScale = true;
172
173 if (src.GetAlpha().enGlobalAlpha) { // is alpha is 0xff we not set it
174 opt.enGlobalAlpha = true;
175 srcSurface.alpha0 = src.GetAlpha().gAlpha;
176 DISPLAY_LOGD("src alpha %{public}x", src.GetAlpha().gAlpha);
177 }
178 opt.rotateType = src.GetTransFormType();
179 DISPLAY_LOGD(" the roate type is %{public}d", opt.rotateType);
180 IRect crop = src.GetLayerCrop();
181 IRect displayRect = src.GetLayerDisplayRect();
182 DISPLAY_LOGD("crop x: %{public}d y : %{public}d w : %{public}d h: %{public}d", crop.x, crop.y, crop.w, crop.h);
183 DISPLAY_LOGD("displayRect x: %{public}d y : %{public}d w : %{public}d h : %{public}d",
184 displayRect.x, displayRect.y, displayRect.w, displayRect.h);
185 DISPLAY_CHK_RETURN(mGfxFuncs == nullptr, DISPLAY_FAILURE, DISPLAY_LOGE("Blit: mGfxFuncs is null"));
186 return mGfxFuncs->Blit(&srcSurface, &crop, &dstSurface, &displayRect, &opt);
187 }
188
ClearRect(HdiLayer & src,HdiLayer & dst)189 int32_t HdiGfxComposition::ClearRect(HdiLayer &src, HdiLayer &dst)
190 {
191 ISurface dstSurface = { 0 };
192 GfxOpt opt = { 0 };
193 DISPLAY_LOGD();
194 HdiLayerBuffer *dstBuffer = dst.GetCurrentBuffer();
195 DISPLAY_CHK_RETURN((dstBuffer == nullptr), DISPLAY_FAILURE, DISPLAY_LOGE("can not get client layer buffer"));
196 InitGfxSurface(dstSurface, *dstBuffer);
197 IRect rect = src.GetLayerDisplayRect();
198 DISPLAY_CHK_RETURN(mGfxFuncs == nullptr, DISPLAY_FAILURE, DISPLAY_LOGE("Rect: mGfxFuncs is null"));
199 return mGfxFuncs->FillRect(&dstSurface, &rect, 0, &opt);
200 }
201
Apply(bool modeSet)202 int32_t HdiGfxComposition::Apply(bool modeSet)
203 {
204 StartTrace(HITRACE_TAG_HDF, "HDI:DISP:Apply");
205 std::lock_guard<std::mutex> lock(mCompLayersMutex);
206 int32_t ret;
207 DISPLAY_LOGD("composer layers size %{public}zd", mCompLayers.size());
208
209 bool needClear = false;
210 for (uint32_t i = 0; i < mCompLayers.size(); i++) {
211 HdiLayer *layer = mCompLayers[i];
212 if (layer == nullptr) {
213 DISPLAY_LOGD("HdiGfxComposition::Apply layer1 is null");
214 return DISPLAY_FAILURE;
215 }
216 CompositionType compType = layer->GetCompositionType();
217 if (compType == COMPOSITION_DEVICE) {
218 needClear = true;
219 break;
220 }
221 }
222
223 if (needClear) {
224 ClearRect(*mClientLayer, *mClientLayer);
225 }
226
227 for (uint32_t i = 0; i < mCompLayers.size(); i++) {
228 HdiLayer *layer = mCompLayers[i];
229 if (layer == nullptr) {
230 DISPLAY_LOGD("HdiGfxComposition::Apply layer2 is null");
231 return DISPLAY_FAILURE;
232 }
233 CompositionType compType = layer->GetCompositionType();
234 switch (compType) {
235 case COMPOSITION_VIDEO:
236 ret = ClearRect(*layer, *mClientLayer);
237 DISPLAY_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE,
238 DISPLAY_LOGE("clear layer %{public}d failed", i));
239 break;
240 case COMPOSITION_DEVICE:
241 ret = BlitLayer(*layer, *mClientLayer);
242 DISPLAY_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE,
243 DISPLAY_LOGE("blit layer %{public}d failed ", i));
244 break;
245 default:
246 DISPLAY_LOGE("the gfx composition can not surpport the type %{public}d", compType);
247 break;
248 }
249 }
250 FinishTrace(HITRACE_TAG_HDF);
251 return DISPLAY_SUCCESS;
252 }
253 } // namespace OHOS
254 } // namespace HDI
255 } // namespace DISPLAY
256