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_gfx_composition.h"
20 #include <cinttypes>
21 #include <dlfcn.h>
22 #include <cerrno>
23 #include "display_gfx.h"
24
25 namespace OHOS {
26 namespace HDI {
27 namespace DISPLAY {
Init(void)28 int32_t HdiGfxComposition::Init(void)
29 {
30 DISPLAY_LOGD();
31 int32_t ret = GfxModuleInit();
32 if ((ret != DISPLAY_SUCCESS) || (mGfxFuncs == nullptr)) {
33 DISPLAY_LOGE("GfxModuleInit failed will use client composition always");
34 return DISPLAY_SUCCESS;
35 }
36 ret = mGfxFuncs->InitGfx();
37 DISPLAY_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE, DISPLAY_LOGE("gfx init failed"));
38 if (ret != DISPLAY_SUCCESS) {
39 DISPLAY_LOGE("Failed to init gfx will use client composition always");
40 return DISPLAY_SUCCESS;
41 }
42 valid_ = true;
43 return DISPLAY_SUCCESS;
44 }
45
GfxModuleInit(void)46 int32_t HdiGfxComposition::GfxModuleInit(void)
47 {
48 DISPLAY_LOGD();
49 mGfxModule = dlopen(LIB_HDI_GFX_NAME, RTLD_NOW | RTLD_NOLOAD);
50 if (mGfxModule != nullptr) {
51 DISPLAY_LOGI("Module '%{public}s' already loaded", LIB_HDI_GFX_NAME);
52 } else {
53 DISPLAY_LOGI("Loading module '%{public}s'", LIB_HDI_GFX_NAME);
54 mGfxModule = dlopen(LIB_HDI_GFX_NAME, RTLD_NOW);
55 if (mGfxModule == nullptr) {
56 DISPLAY_LOGE("Failed to load module: %{public}s", dlerror());
57 return DISPLAY_FAILURE;
58 }
59 }
60
61 using InitFunc = int32_t (*)(GfxFuncs **funcs);
62 InitFunc func = reinterpret_cast<InitFunc>(dlsym(mGfxModule, LIB_GFX_FUNC_INIT));
63 if (func == nullptr) {
64 DISPLAY_LOGE("Failed to lookup %{public}s function: %s", LIB_GFX_FUNC_INIT, dlerror());
65 dlclose(mGfxModule);
66 return DISPLAY_FAILURE;
67 }
68 return func(&mGfxFuncs);
69 }
70
GfxModuleDeinit(void)71 int32_t HdiGfxComposition::GfxModuleDeinit(void)
72 {
73 DISPLAY_LOGD();
74 int32_t ret = DISPLAY_SUCCESS;
75 if (mGfxModule == nullptr) {
76 using DeinitFunc = int32_t (*)(GfxFuncs *funcs);
77 DeinitFunc func = reinterpret_cast<DeinitFunc>(dlsym(mGfxModule, LIB_GFX_FUNC_DEINIT));
78 if (func == nullptr) {
79 DISPLAY_LOGE("Failed to lookup %{public}s function: %s", LIB_GFX_FUNC_DEINIT, dlerror());
80 } else {
81 ret = func(mGfxFuncs);
82 }
83 dlclose(mGfxModule);
84 }
85 return ret;
86 }
87
CanHandle(HdiLayer & hdiLayer)88 bool HdiGfxComposition::CanHandle(HdiLayer &hdiLayer)
89 {
90 DISPLAY_LOGD();
91 (void)hdiLayer;
92 return valid_;
93 }
94
SetLayers(std::vector<HdiLayer * > & layers,HdiLayer & clientLayer)95 int32_t HdiGfxComposition::SetLayers(std::vector<HdiLayer *> &layers, HdiLayer &clientLayer)
96 {
97 DISPLAY_LOGD("layers size %{public}zd", layers.size());
98 mClientLayer = &clientLayer;
99 mCompLayers.clear();
100 for (auto &layer : layers) {
101 if (CanHandle(*layer)) {
102 if ((layer->GetCompositionType() != COMPOSITION_VIDEO) &&
103 (layer->GetCompositionType() != COMPOSITION_CURSOR)) {
104 layer->SetDeviceSelect(COMPOSITION_DEVICE);
105 } else {
106 layer->SetDeviceSelect(layer->GetCompositionType());
107 }
108 mCompLayers.push_back(layer);
109 } else {
110 layer->SetDeviceSelect(COMPOSITION_CLIENT);
111 }
112 }
113 DISPLAY_LOGD("composer layers size %{public}zd", mCompLayers.size());
114 return DISPLAY_SUCCESS;
115 }
116
InitGfxSurface(ISurface & surface,HdiLayerBuffer & buffer)117 void HdiGfxComposition::InitGfxSurface(ISurface &surface, HdiLayerBuffer &buffer)
118 {
119 surface.width = buffer.GetWidth();
120 surface.height = buffer.GetHeight();
121 surface.phyAddr = buffer.GetMemHandle();
122 surface.enColorFmt = (PixelFormat)buffer.GetFormat();
123 surface.stride = buffer.GetStride();
124 surface.bAlphaExt1555 = true;
125 surface.bAlphaMax255 = true;
126 surface.alpha0 = 0XFF;
127 surface.alpha1 = 0XFF;
128 DISPLAY_LOGD("surface w:%{public}d h:%{public}d addr:0x%{public}" PRIx64 " fmt:%{public}d stride:%{public}d",
129 surface.width, surface.height, surface.phyAddr, surface.enColorFmt, surface.stride);
130 }
131
132 // now not handle the alpha of layer
BlitLayer(HdiLayer & src,HdiLayer & dst)133 int32_t HdiGfxComposition::BlitLayer(HdiLayer &src, HdiLayer &dst)
134 {
135 ISurface srcSurface = { 0 };
136 ISurface dstSurface = { 0 };
137 GfxOpt opt = { 0 };
138 DISPLAY_LOGD();
139 HdiLayerBuffer *srcBuffer = src.GetCurrentBuffer();
140 DISPLAY_CHK_RETURN((srcBuffer == nullptr), DISPLAY_NULL_PTR, DISPLAY_LOGE("the srcbuffer is null"));
141 DISPLAY_LOGD("init the src surface");
142 InitGfxSurface(srcSurface, *srcBuffer);
143
144 HdiLayerBuffer *dstBuffer = dst.GetCurrentBuffer();
145 DISPLAY_CHK_RETURN((dstBuffer == nullptr), DISPLAY_FAILURE, DISPLAY_LOGE("can not get client layer buffer"));
146 DISPLAY_LOGD("init the dst surface");
147 InitGfxSurface(dstSurface, *dstBuffer);
148
149 opt.blendType = src.GetLayerBlenType();
150 DISPLAY_LOGD("blendType %{public}d", opt.blendType);
151 opt.enPixelAlpha = true;
152 opt.enableScale = true;
153
154 if (src.GetAlpha().enGlobalAlpha) { // is alpha is 0xff we not set it
155 opt.enGlobalAlpha = true;
156 srcSurface.alpha0 = src.GetAlpha().gAlpha;
157 DISPLAY_LOGD("src alpha %{public}x", src.GetAlpha().gAlpha);
158 }
159 opt.rotateType = src.GetTransFormType();
160 DISPLAY_LOGD(" the roate type is %{public}d", opt.rotateType);
161 IRect crop = src.GetLayerCrop();
162 IRect displayRect = src.GetLayerDisplayRect();
163 DISPLAY_LOGD("crop x: %{public}d y : %{public}d w : %{public}d h: %{public}d", crop.x, crop.y, crop.w, crop.h);
164 DISPLAY_LOGD("displayRect x: %{public}d y : %{public}d w : %{public}d h : %{public}d", displayRect.x, displayRect.y,
165 displayRect.w, displayRect.h);
166 DISPLAY_CHK_RETURN(mGfxFuncs == nullptr, DISPLAY_FAILURE, DISPLAY_LOGE("Blit: mGfxFuncs is null"));
167 return mGfxFuncs->Blit(&srcSurface, &crop, &dstSurface, &displayRect, &opt);
168 }
169
ClearRect(HdiLayer & src,HdiLayer & dst)170 int32_t HdiGfxComposition::ClearRect(HdiLayer &src, HdiLayer &dst)
171 {
172 ISurface dstSurface = { 0 };
173 GfxOpt opt = { 0 };
174 DISPLAY_LOGD();
175 HdiLayerBuffer *dstBuffer = dst.GetCurrentBuffer();
176 DISPLAY_CHK_RETURN((dstBuffer == nullptr), DISPLAY_FAILURE, DISPLAY_LOGE("can not get client layer buffer"));
177 InitGfxSurface(dstSurface, *dstBuffer);
178 IRect rect = src.GetLayerDisplayRect();
179 DISPLAY_CHK_RETURN(mGfxFuncs == nullptr, DISPLAY_FAILURE, DISPLAY_LOGE("Rect: mGfxFuncs is null"));
180 return mGfxFuncs->FillRect(&dstSurface, &rect, 0, &opt);
181 }
182
Apply(bool modeSet)183 int32_t HdiGfxComposition::Apply(bool modeSet)
184 {
185 int32_t ret;
186 DISPLAY_LOGD("composer layers size %{public}zd", mCompLayers.size());
187 for (uint32_t i = 0; i < mCompLayers.size(); i++) {
188 HdiLayer *layer = mCompLayers[i];
189 CompositionType compType = layer->GetDeviceSelect();
190 switch (compType) {
191 case COMPOSITION_VIDEO:
192 ret = ClearRect(*layer, *mClientLayer);
193 DISPLAY_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE,
194 DISPLAY_LOGE("clear layer %{public}d failed", i));
195 break;
196 case COMPOSITION_DEVICE:
197 ret = BlitLayer(*layer, *mClientLayer);
198 DISPLAY_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE,
199 DISPLAY_LOGE("blit layer %{public}d failed ", i));
200 break;
201 default:
202 DISPLAY_LOGE("the gfx composition can not surpport the type %{public}d", compType);
203 break;
204 }
205 }
206 return DISPLAY_SUCCESS;
207 }
208 } // namespace OHOS
209 } // namespace HDI
210 } // namespace DISPLAY
211