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