test: adapt the change of policy request
[platform/core/uifw/libds-tizen.git] / examples / tdm-backend.c
1 #include <assert.h>
2 #include <stdbool.h>
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <signal.h>
6
7 #include <wayland-server.h>
8 #include <libds/log.h>
9 #include <libds/backend.h>
10 #include <libds/output.h>
11 #include <libds/swapchain.h>
12 #include <libds/compositor.h>
13 #include <libds-tizen/allocator/tbm.h>
14 #include <libds-tizen/backend/tdm.h>
15
16 #define WIDTH   1280
17 #define HEIGHT  720
18
19 struct server
20 {
21     struct ds_backend *backend;
22     struct ds_output *output;
23     struct ds_allocator *allocator;
24     struct ds_swapchain *swapchain;
25     struct ds_buffer *front_buffer;
26
27     struct wl_display *display;
28     struct wl_event_source *stdin_source;
29
30     struct wl_listener new_output;
31     struct wl_listener output_destroy;
32     struct wl_listener output_frame;
33
34     int width, height;
35 };
36
37 struct server _server;
38
39 static void init_server(struct server *server, struct wl_display *display);
40 static void fini_server(struct server *server);
41 static void output_handle_destroy(struct wl_listener *listener, void *data);
42 static void output_handle_frame(struct wl_listener *listener, void *data);
43 static void draw_output(struct server *server);
44 static int stdin_dispatch(int fd, uint32_t mask, void *data);
45
46 int
47 main(void)
48 {
49     struct server *server = &_server;
50     struct wl_display *display;
51
52     ds_log_init(DS_DBG, NULL);
53
54     display = wl_display_create();
55     assert(display);
56
57     server->width = WIDTH;
58     server->height = HEIGHT;
59
60     init_server(server, display);
61
62     ds_backend_start(server->backend);
63
64     draw_output(server);
65
66     struct wl_event_loop *loop = wl_display_get_event_loop(display);
67     server->stdin_source = wl_event_loop_add_fd(loop, STDIN_FILENO,
68             WL_EVENT_READABLE, stdin_dispatch, server);
69
70     wl_display_run(display);
71
72     fini_server(server);
73     wl_display_destroy(display);
74     return 0;
75 }
76
77 static void
78 backend_handle_new_output(struct wl_listener *listener, void *data)
79 {
80     struct server *server;
81     struct ds_output *output;
82
83     server = wl_container_of(listener, server, new_output);
84     output = data;
85     ds_inf("New output(%p)", output);
86
87
88     if (server->output)
89         return;
90
91     server->output = output;
92
93     server->output_destroy.notify = output_handle_destroy;
94     ds_output_add_destroy_listener(server->output,
95             &server->output_destroy);
96
97     server->output_frame.notify = output_handle_frame;
98     ds_output_add_frame_listener(server->output,
99             &server->output_frame);
100 }
101
102 static void
103 init_server(struct server *server, struct wl_display *display)
104 {
105     server->display = display;
106     server->front_buffer = NULL;
107
108     server->backend = ds_tdm_backend_create(display);
109     assert(server->backend);
110
111     server->new_output.notify = backend_handle_new_output;
112     ds_backend_add_new_output_listener(server->backend,
113             &server->new_output);
114
115     server->allocator = ds_tbm_allocator_create();
116     assert(server->allocator);
117
118     server->swapchain = ds_swapchain_create(server->allocator,
119             server->width, server->height, WL_SHM_FORMAT_XRGB8888);
120     assert(server->swapchain);
121 }
122
123 static void
124 fini_server(struct server *server)
125 {
126     wl_list_remove(&server->new_output.link);
127     wl_list_remove(&server->output_destroy.link);
128     wl_list_remove(&server->output_frame.link);
129     if (server->front_buffer)
130         ds_buffer_unlock(server->front_buffer);
131     ds_swapchain_destroy(server->swapchain);
132     ds_allocator_destroy(server->allocator);
133 }
134
135 static void
136 output_handle_destroy(struct wl_listener *listener,
137         void *data __attribute__((unused)))
138 {
139     struct server *server =
140         wl_container_of(listener, server, output_destroy);
141     wl_display_terminate(server->display);
142 }
143
144 static void
145 paint_pixels(void *image, int padding, int width, int height, uint32_t time)
146 {
147         const int halfh = padding + (height - padding * 2) / 2;
148         const int halfw = padding + (width - padding * 2) / 2;
149         int ir, or;
150         uint32_t *pixel = image;
151         int y;
152
153         /* squared radii thresholds */
154         or = (halfw < halfh ? halfw : halfh) - 8;
155         ir = or - 32;
156         or *= or;
157         ir *= ir;
158
159         pixel += padding * width;
160         for (y = padding; y < height - padding; y++) {
161                 int x;
162                 int y2 = (y - halfh) * (y - halfh);
163
164                 pixel += padding;
165                 for (x = padding; x < width - padding; x++) {
166                         uint32_t v;
167
168                         /* squared distance from center */
169                         int r2 = (x - halfw) * (x - halfw) + y2;
170
171                         if (r2 < ir)
172                                 v = (r2 / 32 + time / 64) * 0x0080401;
173                         else if (r2 < or)
174                                 v = (y + time / 32) * 0x0080401;
175                         else
176                                 v = (x + time / 16) * 0x0080401;
177                         v &= 0x00ffffff;
178
179                         /* cross if compositor uses X from XRGB as alpha */
180                         if (abs(x - y) > 6 && abs(x + y - height) > 6)
181                                 v |= 0xff000000;
182
183                         *pixel++ = v;
184                 }
185
186                 pixel += padding;
187         }
188 }
189
190 static inline int64_t                                       
191 timespec_to_msec(const struct timespec *a)                  
192 {                                                           
193     return (int64_t)a->tv_sec * 1000 + a->tv_nsec / 1000000;
194 }                                                           
195
196 static void
197 output_handle_frame(struct wl_listener *listener,
198         void *data __attribute__((unused)))
199 {
200     struct server *server =
201         wl_container_of(listener, server, output_frame);
202     draw_output(server);
203 }
204
205 static void
206 draw_output(struct server *server)
207 {
208     struct ds_buffer *buffer;
209     void *data;
210     uint32_t format;
211     size_t stride;
212     struct timespec now;                 
213     uint32_t frame_time_msec;
214
215     ds_dbg("Redraw output");
216
217     clock_gettime(CLOCK_MONOTONIC, &now);
218     frame_time_msec = timespec_to_msec(&now);
219
220     buffer = ds_swapchain_acquire(server->swapchain, NULL);
221     assert(buffer);
222
223     assert(ds_buffer_begin_data_ptr_access(buffer,
224                 0, &data, &format, &stride) == true);
225
226     paint_pixels(data, 20, server->width, server->height, frame_time_msec);
227
228     ds_buffer_end_data_ptr_access(buffer);
229
230     ds_output_attach_buffer(server->output, buffer);
231     ds_output_commit(server->output);
232
233     if (server->front_buffer)
234         ds_buffer_unlock(server->front_buffer);
235
236     server->front_buffer = buffer;
237 }
238
239 static int
240 stdin_dispatch(int fd, uint32_t mask, void *data)
241 {
242     struct server *server = data;
243
244     wl_display_terminate(server->display);
245
246     return 1;
247 }