1 /*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sublicense, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial
14 * portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
20 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
21 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 * SOFTWARE.
24 */
25
26 #include <assert.h>
27
28 #include <vsync_module_c.h>
29
30 #include "libweston/soft_vsync.h" // OHOS vsync module
31
32 #include "hdi_backend.h"
33 #include "hdi_head.h"
34
35 // C header adapter
36 extern "C" {
37 #include "libweston/libweston.h"
38 #include "libweston/libweston-internal.h"
39 #include "shared/helpers.h"
40 }
41
42 #include "libweston/trace.h"
43 DEFINE_LOG_LABEL("HdiHead");
44
45 struct hdi_head {
46 struct weston_head base;
47 uint32_t device_id;
48 DisplayCapability displayCapability;
49 };
50
51 struct hdi_head *
to_hdi_head(struct weston_head * base)52 to_hdi_head(struct weston_head *base)
53 {
54 return container_of(base, struct hdi_head, base);
55 }
56
57 uint32_t
hdi_head_get_device_id(struct weston_head * base)58 hdi_head_get_device_id(struct weston_head *base)
59 {
60 return to_hdi_head(base)->device_id;
61 }
62
63 static void
hdi_vblank_callback(uint32_t seq,uint64_t ns,void * data)64 hdi_vblank_callback(uint32_t seq, uint64_t ns, void *data)
65 {
66 // OHOS vsync module
67 VsyncModuleTrigger();
68 SoftVsync::GetInstance().SoftVsyncStop();
69 }
70
71 int
hdi_head_create(struct weston_compositor * compositor,uint32_t device_id)72 hdi_head_create(struct weston_compositor *compositor, uint32_t device_id)
73 {
74 LOG_SCOPE();
75 struct hdi_backend *b = to_hdi_backend(compositor);
76 assert(b->device_funcs);
77
78 struct hdi_head *head = reinterpret_cast<struct hdi_head *>(zalloc(sizeof *head));
79 if (head == NULL) {
80 return -1;
81 }
82
83 head->device_id = device_id;
84
85 // now just support display 0 to give vsync signal
86 if (device_id == 0) {
87 b->device_funcs->RegDisplayVBlankCallback(device_id, hdi_vblank_callback, NULL);
88 b->device_funcs->SetDisplayVsyncEnabled(device_id, true);
89 }
90
91 if (b->device_funcs->GetDisplayCapability != NULL) {
92 int ret = b->device_funcs->GetDisplayCapability(head->device_id, &head->displayCapability);
93 LOG_CORE("DeviceFuncs.GetDisplayCapability return %d", ret);
94 } else {
95 LOG_ERROR("GetDisplayCapability is NULL");
96 }
97
98 LOG_INFO("screen: %s, %ux%u", head->displayCapability.name,
99 head->displayCapability.phyWidth, head->displayCapability.phyHeight);
100
101 weston_head_init(&head->base, head->displayCapability.name);
102 weston_head_set_connection_status(&head->base, true);
103 weston_compositor_add_head(compositor, &head->base);
104 return 0;
105 }
106
107 void
hdi_head_destroy(struct weston_head * base)108 hdi_head_destroy(struct weston_head *base)
109 {
110 LOG_SCOPE();
111 if (hdi_head_get_device_id(base) == 0) {
112 struct hdi_backend *b = to_hdi_backend(base->compositor);
113 if (b != NULL) {
114 b->device_funcs->SetDisplayVsyncEnabled(0, false);
115 }
116 }
117 weston_head_release(base);
118 free(to_hdi_head(base));
119 }
120