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_session.h>
17 #include <cerrno>
18 #include <mutex>
19 #include "display_common.h"
20 #include "display_device.h"
21 #include "display_layer.h"
22 
23 namespace OHOS {
24 namespace HDI {
25 namespace DISPLAY {
GetInstance()26 HdiSession &HdiSession::GetInstance()
27 {
28     static HdiSession instance;
29     static std::once_flag once;
30     std::call_once(once, [&]() { instance.Init(); });
31     return instance;
32 }
33 
Init()34 void HdiSession::Init()
35 {
36     DISPLAY_LOGD();
37     mHdiDevices = HdiDeviceInterface::DiscoveryDevice();
38     DISPLAY_LOGD("devices size %{public}zd", mHdiDevices.size());
39     mHdiDisplays.clear();
40     for (auto device : mHdiDevices) {
41         auto displays = device->DiscoveryDisplay();
42         mHdiDisplays.insert(displays.begin(), displays.end());
43     }
44 }
45 
RegHotPlugCallback(HotPlugCallback callback,void * data)46 int32_t HdiSession::RegHotPlugCallback(HotPlugCallback callback, void *data)
47 {
48     DISPLAY_CHK_RETURN((callback == nullptr), DISPLAY_NULL_PTR, DISPLAY_LOGE("the callback is nullptr"));
49     mHotPlugCallBacks[callback] = data;
50     for (auto displayMap : mHdiDisplays) {
51         auto display = displayMap.second;
52         if (display->IsConnected()) {
53             DoHotPlugCallback(display->GetId(), true);
54         }
55     }
56     return DISPLAY_SUCCESS;
57 }
58 
DoHotPlugCallback(uint32_t devId,bool connect)59 void HdiSession::DoHotPlugCallback(uint32_t devId, bool connect)
60 {
61     DISPLAY_LOGD();
62     for (const auto &callback : mHotPlugCallBacks) {
63         callback.first(devId, connect, callback.second);
64     }
65 }
66 } // OHOS
67 } // HDI
68 } // DISPLAY
69 
70 using namespace OHOS::HDI::DISPLAY;
RegHotPlugCallback(HotPlugCallback callback,void * data)71 static int32_t RegHotPlugCallback(HotPlugCallback callback, void *data)
72 {
73     DISPLAY_LOGD();
74     HdiSession::GetInstance().RegHotPlugCallback(callback, data);
75     return DISPLAY_SUCCESS;
76 }
77 
GetDisplayCapability(uint32_t devId,DisplayCapability * info)78 static int32_t GetDisplayCapability(uint32_t devId, DisplayCapability *info)
79 {
80     DISPLAY_LOGD();
81     DISPLAY_CHK_RETURN(info == nullptr, DISPLAY_NULL_PTR, DISPLAY_LOGE("info is nullptr"));
82     return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::GetDisplayCapability, info);
83 }
84 
GetDisplaySupportedModes(uint32_t devId,uint32_t * num,DisplayModeInfo * modes)85 static int32_t GetDisplaySupportedModes(uint32_t devId, uint32_t *num, DisplayModeInfo *modes)
86 {
87     DISPLAY_LOGD();
88     DISPLAY_CHK_RETURN(num == nullptr, DISPLAY_NULL_PTR, DISPLAY_LOGE("num is nullptr"));
89     return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::GetDisplaySupportedModes, num, modes);
90 }
91 
GetDisplayMode(uint32_t devId,uint32_t * mode)92 static int32_t GetDisplayMode(uint32_t devId, uint32_t *mode)
93 {
94     DISPLAY_LOGD();
95     DISPLAY_CHK_RETURN((mode == nullptr), DISPLAY_NULL_PTR, DISPLAY_LOGE("mode is nullptr"));
96     return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::GetDisplayMode, mode);
97 }
98 
SetDisplayMode(uint32_t devId,uint32_t mode)99 static int32_t SetDisplayMode(uint32_t devId, uint32_t mode)
100 {
101     DISPLAY_LOGD();
102     return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::SetDisplayMode, mode);
103 }
104 
GetDisplayPowerStatus(uint32_t devId,DispPowerStatus * status)105 static int32_t GetDisplayPowerStatus(uint32_t devId, DispPowerStatus *status)
106 {
107     DISPLAY_LOGD();
108     DISPLAY_CHK_RETURN((status == nullptr), DISPLAY_NULL_PTR, DISPLAY_LOGE("status is nullptr"));
109     return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::GetDisplayPowerStatus, status);
110 }
111 
SetDisplayPowerStatus(uint32_t devId,DispPowerStatus status)112 static int32_t SetDisplayPowerStatus(uint32_t devId, DispPowerStatus status)
113 {
114     DISPLAY_LOGD();
115     return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::SetDisplayPowerStatus, status);
116 }
117 
GetDisplayBacklight(uint32_t devId,uint32_t * value)118 static int32_t GetDisplayBacklight(uint32_t devId, uint32_t *value)
119 {
120     DISPLAY_LOGD();
121     DISPLAY_CHK_RETURN((value == nullptr), DISPLAY_NULL_PTR, DISPLAY_LOGE("value is nullptr"));
122     return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::GetDisplayBacklight, value);
123 }
124 
SetDisplayBacklight(uint32_t devId,uint32_t value)125 static int32_t SetDisplayBacklight(uint32_t devId, uint32_t value)
126 {
127     DISPLAY_LOGD();
128     return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::SetDisplayBacklight, value);
129 }
130 
GetDisplayProperty(uint32_t devId,uint32_t id,uint64_t * value)131 static int32_t GetDisplayProperty(uint32_t devId, uint32_t id, uint64_t *value)
132 {
133     DISPLAY_LOGD();
134     (void)id;
135     DISPLAY_CHK_RETURN((value == nullptr), DISPLAY_NULL_PTR, DISPLAY_LOGE("value is nullptr"));
136     return DISPLAY_NOT_SUPPORT;
137 }
138 
SetDisplayProperty(uint32_t devId,uint32_t id,uint64_t value)139 static int32_t SetDisplayProperty(uint32_t devId, uint32_t id, uint64_t value)
140 {
141     DISPLAY_LOGD();
142     (void)id;
143     return DISPLAY_NOT_SUPPORT;
144 }
145 
PrepareDisplayLayers(uint32_t devId,bool * needFlushFb)146 static int32_t PrepareDisplayLayers(uint32_t devId, bool *needFlushFb)
147 {
148     DISPLAY_LOGD();
149     DISPLAY_CHK_RETURN((needFlushFb == nullptr), DISPLAY_NULL_PTR, DISPLAY_LOGE("needFlushFb is nullptr"));
150     return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::PrepareDisplayLayers, needFlushFb);
151 }
152 
GetDisplayCompChange(uint32_t devId,uint32_t * num,uint32_t * layers,int32_t * type)153 static int32_t GetDisplayCompChange(uint32_t devId, uint32_t *num, uint32_t *layers, int32_t *type)
154 {
155     DISPLAY_LOGD();
156     DISPLAY_CHK_RETURN((num == nullptr), DISPLAY_NULL_PTR, DISPLAY_LOGE("num is nullptr"));
157     return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::GetDisplayCompChange, num, layers, type);
158 }
159 
SetDisplayClientCrop(uint32_t devId,IRect * rect)160 static int32_t SetDisplayClientCrop(uint32_t devId, IRect *rect)
161 {
162     DISPLAY_LOGD();
163     DISPLAY_CHK_RETURN((rect == NULL), DISPLAY_NULL_PTR, DISPLAY_LOGE("rect is nullptr"));
164     return DISPLAY_NOT_SUPPORT;
165 }
166 
SetDisplayClientDestRect(uint32_t devId,IRect * rect)167 static int32_t SetDisplayClientDestRect(uint32_t devId, IRect *rect)
168 {
169     DISPLAY_LOGD();
170     DISPLAY_CHK_RETURN((rect == NULL), DISPLAY_NULL_PTR, DISPLAY_LOGE("rect is nullptr"));
171     return DISPLAY_NOT_SUPPORT;
172 }
173 
SetDisplayClientBuffer(uint32_t devId,const BufferHandle * buffer,int32_t fence)174 static int32_t SetDisplayClientBuffer(uint32_t devId, const BufferHandle *buffer, int32_t fence)
175 {
176     DISPLAY_LOGD();
177     return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::SetDisplayClientBuffer, buffer, fence);
178 }
179 
SetDisplayClientDamage(uint32_t devId,uint32_t num,IRect * rect)180 static int32_t SetDisplayClientDamage(uint32_t devId, uint32_t num, IRect *rect)
181 {
182     DISPLAY_LOGD();
183     (void)num;
184     DISPLAY_CHK_RETURN((rect == NULL), DISPLAY_NULL_PTR, DISPLAY_LOGE("rect is nullptr"));
185     return DISPLAY_NOT_SUPPORT;
186 }
187 
SetDisplayVsyncEnabled(uint32_t devId,bool enabled)188 static int32_t SetDisplayVsyncEnabled(uint32_t devId, bool enabled)
189 {
190     DISPLAY_LOGD();
191     return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::SetDisplayVsyncEnabled, enabled);
192 }
193 
RegDisplayVBlankCallback(uint32_t devId,VBlankCallback callback,void * data)194 static int32_t RegDisplayVBlankCallback(uint32_t devId, VBlankCallback callback, void *data)
195 {
196     DISPLAY_LOGD();
197     return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::RegDisplayVBlankCallback, callback, data);
198 }
199 
GetDisplayReleaseFence(uint32_t devId,uint32_t * num,uint32_t * layers,int32_t * fences)200 static int32_t GetDisplayReleaseFence(uint32_t devId, uint32_t *num, uint32_t *layers, int32_t *fences)
201 {
202     DISPLAY_LOGD();
203     return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::GetDisplayReleaseFence, num, layers,
204         fences);
205 }
206 
Commit(uint32_t devId,int32_t * fence)207 static int32_t Commit(uint32_t devId, int32_t *fence)
208 {
209     DISPLAY_LOGD();
210     DISPLAY_CHK_RETURN((fence == NULL), DISPLAY_NULL_PTR, DISPLAY_LOGE("fence is nullptr"));
211     return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::Commit, fence);
212 }
213 
CreateVirtualDisplay(uint32_t width,uint32_t height,int32_t * format,uint32_t * devId)214 static int32_t CreateVirtualDisplay(uint32_t width, uint32_t height, int32_t *format, uint32_t *devId)
215 {
216     DISPLAY_LOGD();
217     return DISPLAY_NOT_SUPPORT;
218 }
DestroyVirtualDisplay(uint32_t devId)219 static int32_t DestroyVirtualDisplay(uint32_t devId)
220 {
221     DISPLAY_LOGD();
222     return DISPLAY_NOT_SUPPORT;
223 }
SetVirtualDisplayBuffer(uint32_t devId,BufferHandle * buffer,int32_t releaseFence)224 static int32_t SetVirtualDisplayBuffer(uint32_t devId, BufferHandle *buffer, int32_t releaseFence)
225 {
226     DISPLAY_LOGD();
227     return DISPLAY_NOT_SUPPORT;
228 }
229 
230 
231 // Layer function
CreateLayer(uint32_t devId,const LayerInfo * layerInfo,uint32_t * layerId)232 static int32_t CreateLayer(uint32_t devId, const LayerInfo *layerInfo, uint32_t *layerId)
233 {
234     DISPLAY_LOGD();
235     DISPLAY_CHK_RETURN((layerId == NULL), DISPLAY_NULL_PTR, DISPLAY_LOGE("layerId is nullptr"));
236     return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::CreateLayer, layerInfo, layerId);
237 }
238 
CloseLayer(uint32_t devId,uint32_t layerId)239 static int32_t CloseLayer(uint32_t devId, uint32_t layerId)
240 {
241     DISPLAY_LOGD();
242     return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::CloseLayer, layerId);
243 }
244 
SetLayerSize(uint32_t devId,uint32_t layerId,IRect * rect)245 static int32_t SetLayerSize(uint32_t devId, uint32_t layerId, IRect *rect)
246 {
247     DISPLAY_CHK_RETURN((rect == NULL), DISPLAY_NULL_PTR, DISPLAY_LOGE("rect is nullptr"));
248     DISPLAY_LOGD();
249     return HdiSession::GetInstance().CallLayerFunction(devId, layerId, &HdiLayer::SetLayerSize, rect);
250 }
251 
SetLayerCrop(uint32_t devId,uint32_t layerId,IRect * rect)252 static int32_t SetLayerCrop(uint32_t devId, uint32_t layerId, IRect *rect)
253 {
254     DISPLAY_LOGD();
255     DISPLAY_CHK_RETURN((rect == NULL), DISPLAY_NULL_PTR, DISPLAY_LOGE("rect is nullptr"));
256     return HdiSession::GetInstance().CallLayerFunction(devId, layerId, &HdiLayer::SetLayerCrop, rect);
257 }
258 
SetLayerZorder(uint32_t devId,uint32_t layerId,uint32_t zorder)259 static int32_t SetLayerZorder(uint32_t devId, uint32_t layerId, uint32_t zorder)
260 {
261     DISPLAY_LOGD();
262     return HdiSession::GetInstance().CallDisplayFunction(devId, &HdiDisplay::SetLayerZorder, layerId, zorder);
263 }
264 
SetLayerPreMulti(uint32_t devId,uint32_t layerId,bool preMul)265 static int32_t SetLayerPreMulti(uint32_t devId, uint32_t layerId, bool preMul)
266 {
267     DISPLAY_LOGD();
268     return HdiSession::GetInstance().CallLayerFunction(devId, layerId, &HdiLayer::SetLayerPreMulti, preMul);
269 }
270 
SetLayerAlpha(uint32_t devId,uint32_t layerId,LayerAlpha * alpha)271 static int32_t SetLayerAlpha(uint32_t devId, uint32_t layerId, LayerAlpha *alpha)
272 {
273     DISPLAY_LOGD();
274     DISPLAY_CHK_RETURN((alpha == NULL), DISPLAY_NULL_PTR, DISPLAY_LOGE("alpha is nullptr"));
275     return HdiSession::GetInstance().CallLayerFunction(devId, layerId, &HdiLayer::SetLayerAlpha, alpha);
276 }
277 
SetTransformMode(uint32_t devId,uint32_t layerId,TransformType type)278 static int32_t SetTransformMode(uint32_t devId, uint32_t layerId, TransformType type)
279 {
280     DISPLAY_LOGD();
281     return HdiSession::GetInstance().CallLayerFunction(devId, layerId, &HdiLayer::SetTransformMode, type);
282 }
283 
SetLayerDirtyRegion(uint32_t devId,uint32_t layerId,IRect * region)284 static int32_t SetLayerDirtyRegion(uint32_t devId, uint32_t layerId, IRect *region)
285 {
286     DISPLAY_LOGD();
287     DISPLAY_CHK_RETURN((region == NULL), DISPLAY_NULL_PTR, DISPLAY_LOGE("region is nullptr"));
288     return HdiSession::GetInstance().CallLayerFunction(devId, layerId, &HdiLayer::SetLayerDirtyRegion, region);
289 }
290 
SetLayerVisibleRegion(uint32_t devId,uint32_t layerId,uint32_t num,IRect * rect)291 static int32_t SetLayerVisibleRegion(uint32_t devId, uint32_t layerId, uint32_t num, IRect *rect)
292 {
293     DISPLAY_LOGD();
294     DISPLAY_CHK_RETURN((rect == NULL), DISPLAY_NULL_PTR, DISPLAY_LOGE("rect is nullptr"));
295     return HdiSession::GetInstance().CallLayerFunction(devId, layerId, &HdiLayer::SetLayerVisibleRegion, num, rect);
296 }
297 
SetLayerBuffer(uint32_t devId,uint32_t layerId,const BufferHandle * buffer,int32_t fence)298 static int32_t SetLayerBuffer(uint32_t devId, uint32_t layerId, const BufferHandle *buffer, int32_t fence)
299 {
300     DISPLAY_LOGD();
301     return HdiSession::GetInstance().CallLayerFunction(devId, layerId, &HdiLayer::SetLayerBuffer, buffer, fence);
302 }
303 
SetLayerCompositionType(uint32_t devId,uint32_t layerId,CompositionType type)304 static int32_t SetLayerCompositionType(uint32_t devId, uint32_t layerId, CompositionType type)
305 {
306     DISPLAY_LOGD();
307     return HdiSession::GetInstance().CallLayerFunction(devId, layerId, &HdiLayer::SetLayerCompositionType, type);
308 }
309 
SetLayerBlendType(uint32_t devId,uint32_t layerId,BlendType type)310 static int32_t SetLayerBlendType(uint32_t devId, uint32_t layerId, BlendType type)
311 {
312     DISPLAY_LOGD();
313     return HdiSession::GetInstance().CallLayerFunction(devId, layerId, &HdiLayer::SetLayerBlendType, type);
314 }
315 
SetLayerVisible(uint32_t devId,uint32_t layerId,bool visible)316 static int32_t SetLayerVisible(uint32_t devId, uint32_t layerId, bool visible)
317 {
318     DISPLAY_LOGD();
319     return HdiSession::GetInstance().CallLayerFunction(devId, layerId, &HdiLayer::SetLayerVisible, visible);
320 }
321 
322 extern "C" {
DeviceInitialize(DeviceFuncs ** funcs)323 int32_t DeviceInitialize(DeviceFuncs **funcs)
324 {
325     DISPLAY_CHK_RETURN((funcs == nullptr), DISPLAY_NULL_PTR, DISPLAY_LOGE("in funcs is null"));
326     DeviceFuncs *dFuncs = reinterpret_cast<DeviceFuncs *>(calloc(1, sizeof(DeviceFuncs)));
327     DISPLAY_CHK_RETURN((dFuncs == nullptr), DISPLAY_FAILURE, DISPLAY_LOGE("can not calloc"));
328 
329     dFuncs->RegHotPlugCallback = RegHotPlugCallback;
330     dFuncs->GetDisplayCapability = GetDisplayCapability;
331     dFuncs->GetDisplaySupportedModes = GetDisplaySupportedModes;
332     dFuncs->GetDisplayMode = GetDisplayMode;
333     dFuncs->SetDisplayMode = SetDisplayMode;
334     dFuncs->GetDisplayPowerStatus = GetDisplayPowerStatus;
335     dFuncs->SetDisplayPowerStatus = SetDisplayPowerStatus;
336     dFuncs->PrepareDisplayLayers = PrepareDisplayLayers;
337     dFuncs->GetDisplayBacklight = GetDisplayBacklight;
338     dFuncs->SetDisplayBacklight = SetDisplayBacklight;
339     dFuncs->GetDisplayProperty = GetDisplayProperty;
340     dFuncs->GetDisplayCompChange = GetDisplayCompChange;
341     dFuncs->SetDisplayClientCrop = SetDisplayClientCrop;
342     dFuncs->SetDisplayClientDestRect = SetDisplayClientDestRect;
343     dFuncs->SetDisplayClientBuffer = SetDisplayClientBuffer;
344     dFuncs->SetDisplayClientDamage = SetDisplayClientDamage;
345     dFuncs->SetDisplayVsyncEnabled = SetDisplayVsyncEnabled;
346     dFuncs->RegDisplayVBlankCallback = RegDisplayVBlankCallback;
347     dFuncs->GetDisplayReleaseFence = GetDisplayReleaseFence;
348     dFuncs->CreateVirtualDisplay = CreateVirtualDisplay;
349     dFuncs->DestroyVirtualDisplay = DestroyVirtualDisplay;
350     dFuncs->SetVirtualDisplayBuffer = SetVirtualDisplayBuffer;
351     dFuncs->SetDisplayProperty = SetDisplayProperty;
352     dFuncs->Commit = Commit;
353     *funcs = dFuncs;
354     DISPLAY_LOGD("%{public}s: device initialize success", __func__);
355     HdiSession::GetInstance();
356     return DISPLAY_SUCCESS;
357 }
358 
DeviceUninitialize(DeviceFuncs * funcs)359 int32_t DeviceUninitialize(DeviceFuncs *funcs)
360 {
361     DISPLAY_CHK_RETURN((funcs == nullptr), DISPLAY_NULL_PTR, DISPLAY_LOGE("in funcs is null"));
362     free(funcs);
363     return DISPLAY_SUCCESS;
364 }
365 
366 
LayerInitialize(LayerFuncs ** funcs)367 int32_t LayerInitialize(LayerFuncs **funcs)
368 {
369     DISPLAY_CHK_RETURN((funcs == nullptr), DISPLAY_NULL_PTR, DISPLAY_LOGE("the in funcs is nullptr"));
370     LayerFuncs *lFuncs = reinterpret_cast<LayerFuncs *>(calloc(1, sizeof(LayerFuncs)));
371     DISPLAY_CHK_RETURN((lFuncs == nullptr), DISPLAY_FAILURE, DISPLAY_LOGE("can not calloc errno: %{public}d", errno));
372     lFuncs->SetLayerAlpha = SetLayerAlpha;
373     lFuncs->CreateLayer = CreateLayer;
374     lFuncs->CloseLayer = CloseLayer;
375     lFuncs->SetLayerSize = SetLayerSize;
376     lFuncs->SetLayerCrop = SetLayerCrop;
377     lFuncs->SetLayerZorder = SetLayerZorder;
378     lFuncs->SetLayerPreMulti = SetLayerPreMulti;
379     lFuncs->SetTransformMode = SetTransformMode;
380     lFuncs->SetLayerDirtyRegion = SetLayerDirtyRegion;
381     lFuncs->SetLayerVisibleRegion = SetLayerVisibleRegion;
382     lFuncs->SetLayerBuffer = SetLayerBuffer;
383     lFuncs->SetLayerCompositionType = SetLayerCompositionType;
384     lFuncs->SetLayerBlendType = SetLayerBlendType;
385     lFuncs->SetLayerVisible = SetLayerVisible;
386 
387     *funcs = lFuncs;
388     DISPLAY_LOGD("%{public}s: layer initialize success", __func__);
389     return DISPLAY_SUCCESS;
390 }
391 
LayerUninitialize(LayerFuncs * funcs)392 int32_t LayerUninitialize(LayerFuncs *funcs)
393 {
394     DISPLAY_CHK_RETURN((funcs == nullptr), DISPLAY_FAILURE, DISPLAY_LOGE("the funcs is nullptr"));
395     free(funcs);
396     DISPLAY_LOGD("%{public}s: layer uninitialize success", __func__);
397     return DISPLAY_SUCCESS;
398 }
399 }
400