• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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     DISPLAY_LOGD("layers size %{public}zd", layers.size());
109     CompositionType defaultCompType = UseCompositionClient(layers) ? COMPOSITION_CLIENT : COMPOSITION_DEVICE;
110     mClientLayer = &clientLayer;
111     mCompLayers.clear();
112     for (auto &layer : layers) {
113         if (!CanHandle(*layer)) {
114             continue;
115         }
116 
117         if ((layer->GetCompositionType() == COMPOSITION_VIDEO) ||
118             (layer->GetCompositionType() == COMPOSITION_CURSOR)) {
119             layer->SetDeviceSelect(layer->GetCompositionType());
120         } else {
121             layer->SetDeviceSelect(defaultCompType);
122         }
123 
124         mCompLayers.push_back(layer);
125     }
126     DISPLAY_LOGD("composer layers size %{public}zd", mCompLayers.size());
127     return DISPLAY_SUCCESS;
128 }
129 
InitGfxSurface(ISurface & iSurface,HdiLayerBuffer & buffer)130 void HdiGfxComposition::InitGfxSurface(ISurface &iSurface, HdiLayerBuffer &buffer)
131 {
132     iSurface.width = buffer.GetWight();
133     iSurface.height = buffer.GetHeight();
134     iSurface.phyAddr = buffer.GetFb(); // buffer.GetPhysicalAddr();
135     iSurface.enColorFmt = (PixelFormat)buffer.GetFormat();
136     iSurface.stride = buffer.GetStride();
137     iSurface.bAlphaExt1555 = true;
138     iSurface.bAlphaMax255 = true;
139     iSurface.alpha0 = 0XFF;
140     iSurface.alpha1 = 0XFF;
141     DISPLAY_LOGD("iSurface fd %{public}d w:%{public}d h:%{public}d addr:0x%{public}" \
142         PRIx64 " fmt:%{public}d stride:%{public}d",
143         buffer.GetFb(), iSurface.width, iSurface.height,
144         buffer.GetPhysicalAddr(), iSurface.enColorFmt, iSurface.stride);
145 }
146 
147 // now not handle the alpha of layer
BlitLayer(HdiLayer & src,HdiLayer & dst)148 int32_t HdiGfxComposition::BlitLayer(HdiLayer &src, HdiLayer &dst)
149 {
150     ISurface srcSurface = { 0 };
151     ISurface dstSurface = { 0 };
152     GfxOpt opt = { 0 };
153     StartTrace(HITRACE_TAG_HDF, "HDI:DISP:WaitAcquireFence");
154     src.WaitAcquireFence();
155     FinishTrace(HITRACE_TAG_HDF);
156     DISPLAY_LOGD();
157     HdiLayerBuffer *srcBuffer = src.GetCurrentBuffer();
158     DISPLAY_CHK_RETURN((srcBuffer == nullptr), DISPLAY_NULL_PTR, DISPLAY_LOGE("the srcbuffer is null"));
159     DISPLAY_LOGD("init the src iSurface");
160     InitGfxSurface(srcSurface, *srcBuffer);
161 
162     HdiLayerBuffer *dstBuffer = dst.GetCurrentBuffer();
163     DISPLAY_CHK_RETURN((dstBuffer == nullptr), DISPLAY_FAILURE, DISPLAY_LOGE("can not get client layer buffer"));
164     DISPLAY_LOGD("init the dst iSurface");
165     InitGfxSurface(dstSurface, *dstBuffer);
166 
167     opt.blendType = src.GetLayerBlenType();
168     DISPLAY_LOGD("blendType %{public}d", opt.blendType);
169     opt.enPixelAlpha = true;
170     opt.enableScale = true;
171 
172     if (src.GetAlpha().enGlobalAlpha) { // is alpha is 0xff we not set it
173         opt.enGlobalAlpha = true;
174         srcSurface.alpha0 = src.GetAlpha().gAlpha;
175         DISPLAY_LOGD("src alpha %{public}x", src.GetAlpha().gAlpha);
176     }
177     opt.rotateType = src.GetTransFormType();
178     DISPLAY_LOGD(" the roate type is %{public}d", opt.rotateType);
179     IRect crop = src.GetLayerCrop();
180     IRect displayRect = src.GetLayerDisplayRect();
181     DISPLAY_LOGD("crop x: %{public}d y : %{public}d w : %{public}d h: %{public}d", crop.x, crop.y, crop.w, crop.h);
182     DISPLAY_LOGD("displayRect x: %{public}d y : %{public}d w : %{public}d h : %{public}d",
183         displayRect.x, displayRect.y, displayRect.w, displayRect.h);
184     DISPLAY_CHK_RETURN(mGfxFuncs == nullptr, DISPLAY_FAILURE, DISPLAY_LOGE("Blit: mGfxFuncs is null"));
185     return mGfxFuncs->Blit(&srcSurface, &crop, &dstSurface, &displayRect, &opt);
186 }
187 
ClearRect(HdiLayer & src,HdiLayer & dst)188 int32_t HdiGfxComposition::ClearRect(HdiLayer &src, HdiLayer &dst)
189 {
190     ISurface dstSurface = { 0 };
191     GfxOpt opt = { 0 };
192     DISPLAY_LOGD();
193     HdiLayerBuffer *dstBuffer = dst.GetCurrentBuffer();
194     DISPLAY_CHK_RETURN((dstBuffer == nullptr), DISPLAY_FAILURE, DISPLAY_LOGE("can not get client layer buffer"));
195     InitGfxSurface(dstSurface, *dstBuffer);
196     IRect rect = src.GetLayerDisplayRect();
197     DISPLAY_CHK_RETURN(mGfxFuncs == nullptr, DISPLAY_FAILURE, DISPLAY_LOGE("Rect: mGfxFuncs is null"));
198     return mGfxFuncs->FillRect(&dstSurface, &rect, 0, &opt);
199 }
200 
Apply(bool modeSet)201 int32_t HdiGfxComposition::Apply(bool modeSet)
202 {
203     StartTrace(HITRACE_TAG_HDF, "HDI:DISP:Apply");
204     int32_t ret;
205     DISPLAY_LOGD("composer layers size %{public}zd", mCompLayers.size());
206 
207     bool needClear = false;
208     for (uint32_t i = 0; i < mCompLayers.size(); i++) {
209         HdiLayer *layer = mCompLayers[i];
210 		if (layer == nullptr) {
211             DISPLAY_LOGD("HdiGfxComposition::Apply layer1 is null");
212 		    return DISPLAY_FAILURE;
213 		}
214         CompositionType compType = layer->GetCompositionType();
215         if (compType == COMPOSITION_DEVICE) {
216             needClear = true;
217             break;
218         }
219     }
220 
221     if (needClear) {
222         ClearRect(*mClientLayer, *mClientLayer);
223     }
224 
225     for (uint32_t i = 0; i < mCompLayers.size(); i++) {
226         HdiLayer *layer = mCompLayers[i];
227 		if (layer == nullptr) {
228             DISPLAY_LOGD("HdiGfxComposition::Apply layer2 is null");
229 		    return DISPLAY_FAILURE;
230 		}
231         CompositionType compType = layer->GetCompositionType();
232         switch (compType) {
233             case COMPOSITION_VIDEO:
234                 ret = ClearRect(*layer, *mClientLayer);
235                 DISPLAY_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE,
236                     DISPLAY_LOGE("clear layer %{public}d failed", i));
237                 break;
238             case COMPOSITION_DEVICE:
239                 ret = BlitLayer(*layer, *mClientLayer);
240                 DISPLAY_CHK_RETURN((ret != DISPLAY_SUCCESS), DISPLAY_FAILURE,
241                     DISPLAY_LOGE("blit layer %{public}d failed ", i));
242                 break;
243             default:
244                 DISPLAY_LOGE("the gfx composition can not surpport the type %{public}d", compType);
245                 break;
246         }
247     }
248     FinishTrace(HITRACE_TAG_HDF);
249     return DISPLAY_SUCCESS;
250 }
251 } // namespace OHOS
252 } // namespace HDI
253 } // namespace DISPLAY
254