2 * Copyright © 2019 Samsung Electronics co., Ltd. All Rights Reserved.
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
29 #include <tbm_bufmgr.h>
30 #include <wayland-tbm-server.h>
31 #include <pepper-output-backend.h>
32 #include "HL_UI_LED.h"
33 #include "output_internal.h"
35 static const int KEY_OUTPUT;
36 static void led_output_add_frame_done(led_output_t *output);
37 static void led_output_update(led_output_t *output);
40 led_output_destroy(void *data)
42 led_output_t *output = (led_output_t *)data;
43 PEPPER_TRACE("Output Destroy %p base %p\n", output, output->output);
46 HL_UI_LED_Close(output->ui_led);
47 output->ui_led = NULL;
50 if (output->tbm_server) {
51 wayland_tbm_server_deinit(output->tbm_server);
52 output->tbm_server = NULL;
57 led_output_get_subpixel_order(void *o)
63 led_output_get_maker_name(void *o)
69 led_output_get_model_name(void *o)
75 led_output_get_mode_count(void *o)
81 led_output_get_mode(void *o, int index, pepper_output_mode_t *mode)
83 led_output_t *output = (led_output_t *)o;
85 PEPPER_TRACE("[OUTPUT]\n");
90 mode->flags = WL_OUTPUT_MODE_CURRENT | WL_OUTPUT_MODE_PREFERRED;
91 mode->w = output->num_led;
92 mode->h = output->num_led;
93 mode->refresh = 60000;
97 led_output_set_mode(void *o, const pepper_output_mode_t *mode)
103 led_output_assign_planes(void *o, const pepper_list_t *view_list)
105 led_output_t *output = (led_output_t *)o;
107 pepper_view_t *view, *top_view = NULL;
109 PEPPER_TRACE("[OUTPUT] Assign plane\n");
110 pepper_list_for_each_list(l, view_list) {
111 view = (pepper_view_t*)l->item;
113 if (pepper_view_is_mapped(view) && pepper_view_is_visible(view)) {
119 if (output->top_view != top_view)
120 PEPPER_TRACE("\tTop-View is changed(%p -> %p)\n", output->top_view, top_view);
122 output->top_view = top_view;
126 led_output_start_repaint_loop(void *o)
128 led_output_t *output = (led_output_t *)o;
131 PEPPER_TRACE("[OUTPUT] Start reapint loop\n");
132 pepper_compositor_get_time(output->compositor, &ts);
133 pepper_output_finish_frame(output->output, &ts);
137 led_output_repaint(void *o, const pepper_list_t *plane_list)
140 pepper_plane_t *plane;
141 led_output_t *output = (led_output_t *)o;
143 PEPPER_TRACE("[OUTPUT] Repaint\n");
145 pepper_list_for_each_list(l, plane_list) {
146 plane = (pepper_plane_t *)l->item;
147 pepper_plane_clear_damage_region(plane);
150 led_output_update(output);
151 led_output_add_frame_done(output);
155 led_output_attach_surface(void *o, pepper_surface_t *surface, int *w, int *h)
159 PEPPER_TRACE("[OUTPUT] attach surface:%p\n", surface);
163 led_output_flush_surface_damage(void *o, pepper_surface_t *surface, pepper_bool_t *keep_buffer)
165 *keep_buffer = PEPPER_TRUE;
166 PEPPER_TRACE("[OUTPUT] flush_surface_damage surface:%p\n", surface);
169 struct pepper_output_backend led_output_backend = {
172 led_output_get_subpixel_order,
173 led_output_get_maker_name,
174 led_output_get_model_name,
176 led_output_get_mode_count,
180 led_output_assign_planes,
181 led_output_start_repaint_loop,
183 led_output_attach_surface,
184 led_output_flush_surface_damage,
188 led_output_update_led(led_output_t *output, unsigned char *data)
191 uint8_t *ptr = (uint8_t *)data;
194 PEPPER_TRACE("[OUTPUT] update LED to empty\n");
195 HL_UI_LED_Clear_All(output->ui_led);
199 for(i=0; i<output->num_led; i++) {
200 HL_UI_LED_Set_Pixel_RGB(output->ui_led, i, ptr[R_OFF_SET], ptr[G_OFF_SET], ptr[B_OFF_SET]);
204 HL_UI_LED_Refresh(output->ui_led);
208 led_output_update(led_output_t *output)
210 pepper_buffer_t *buf;
211 pepper_surface_t *surface;
212 struct wl_resource *buf_res;
213 tbm_surface_h tbm_surface;
214 tbm_surface_info_s info;
217 if (!output->top_view) {
219 PEPPER_TRACE("[UPDATE LED] Empty Display\n");
221 led_output_update_led(output, NULL);
226 surface = pepper_view_get_surface(output->top_view);
227 PEPPER_CHECK(surface, return, "fail to get a surafce from a view(%p)\n", output->top_view);
229 buf = pepper_surface_get_buffer(surface);
230 PEPPER_CHECK(buf, return, "fail to get a pepper_buffer from a surface(%p)\n", surface);
232 buf_res = pepper_buffer_get_resource(buf);
233 tbm_surface = wayland_tbm_server_get_surface(NULL, buf_res);
234 PEPPER_CHECK(tbm_surface, return, "fail to get a tbm_surface from a pepper_buffer(%p)\n", buf);
236 ret = tbm_surface_map(tbm_surface, TBM_SURF_OPTION_READ, &info);
237 PEPPER_CHECK(ret == TBM_SURFACE_ERROR_NONE, return, "fail to map the tbm_surface\n");
240 PEPPER_TRACE("[UPDATE LED] %s\n", (char*)info.planes[0].ptr);
242 led_output_update_led(output, info.planes[0].ptr);
244 tbm_surface_unmap(tbm_surface);
248 led_output_cb_frame_done(void *data)
250 led_output_t *output = (led_output_t *)data;
252 PEPPER_TRACE("[OUTPUT] frame_done %p\n", output);
253 output->frame_done = NULL;
255 pepper_output_finish_frame(output->output, NULL);
259 led_output_add_frame_done(led_output_t *output)
261 struct wl_event_loop *loop;
263 PEPPER_TRACE("[OUTPUT] Add idle for frame(output:%p, frame_done:%p)\n", output, output->frame_done);
265 if (!output || output->frame_done) {
266 PEPPER_TRACE("[OUTPUT] skip add frame_done\n");
270 loop = wl_display_get_event_loop(pepper_compositor_get_display(output->compositor));
271 PEPPER_CHECK(loop, return, "[OUTPUT] fail to get event loop\n");
273 output->frame_done = wl_event_loop_add_idle(loop, led_output_cb_frame_done, output);
274 PEPPER_CHECK(output->frame_done, return, "[OUTPUT] fail to add idle\n");
278 pepper_output_bind_display(led_output_t *output)
280 tbm_bufmgr bufmgr = NULL;
282 PEPPER_CHECK(getenv("TBM_DISPLAY_SERVER"), return, "[TBM] run the subcompoitor mode\n");
284 bufmgr = wayland_tbm_server_get_bufmgr(output->tbm_server);
285 PEPPER_CHECK(bufmgr, return, "fail to get tbm_bufmgr\n");
287 if (!tbm_bufmgr_bind_native_display(bufmgr, (void *)pepper_compositor_get_display(output->compositor)))
289 PEPPER_CHECK(0, return, "fail to tbm_bufmgr_bind_native_display\n");
296 headless_output_init(pepper_compositor_t *compositor)
298 led_output_t *output = (led_output_t*)calloc(sizeof(led_output_t), 1);
300 PEPPER_TRACE("Output Init\n");
303 PEPPER_ERROR("Failed to allocate memory in %s\n", __FUNCTION__);
307 output->compositor = compositor;
308 output->tbm_server = wayland_tbm_server_init(pepper_compositor_get_display(compositor), NULL, -1, 0);
309 PEPPER_CHECK(output->tbm_server, goto error, "failed to wayland_tbm_server_init.\n");
311 pepper_output_bind_display(output);
313 output->num_led = NUM_LED;
314 output->ui_led = HL_UI_LED_Init(output->num_led);
315 if (output->ui_led) HL_UI_LED_Change_Brightness(output->ui_led, 0x1);
318 PEPPER_ERROR("HL_UI_LED_Init() failed.\n");
320 boot_ani_start(output);
322 output->output = pepper_compositor_add_output(compositor,
323 &led_output_backend, "led_output",
324 output, WL_OUTPUT_TRANSFORM_NORMAL, 1);
325 PEPPER_CHECK(output->output, goto error, "pepper_compositor_add_output() failed.\n");
327 output->plane = pepper_output_add_plane(output->output, NULL);
328 PEPPER_CHECK(output->plane, goto error, "pepper_output_add_plane() failed.\n");
330 pepper_object_set_user_data((pepper_object_t *)compositor,
331 &KEY_OUTPUT, output, NULL);
332 PEPPER_TRACE("\t Add Output %p, base %p\n", output, output->output);
333 PEPPER_TRACE("\t Add Output %p, plane %p\n", output, output->plane);
334 PEPPER_TRACE("\t Userdata %p\n", pepper_object_get_user_data((pepper_object_t *)compositor,&KEY_OUTPUT));
339 HL_UI_LED_Close(output->ui_led);
341 if (output->tbm_server)
342 wayland_tbm_server_deinit(output->tbm_server);
345 pepper_output_destroy(output->output);
353 headless_output_deinit(pepper_compositor_t *compositor)
355 led_output_t *output;
358 output = pepper_object_get_user_data((pepper_object_t *)compositor, &KEY_OUTPUT);
361 pepper_object_set_user_data((pepper_object_t *)compositor, &KEY_OUTPUT, NULL, NULL);
363 if (output->boot_ani) {
364 boot_ani_stop(output);
367 pepper_output_destroy(output->output);
368 led_output_destroy(output);
373 PEPPER_TRACE("Output Deinit ... DONE\n");