7 typedef struct _tdm_dummy_output_data tdm_dummy_output_data;
8 typedef struct _tdm_dummy_layer_data tdm_dummy_layer_data;
9 typedef struct _tdm_dummy_event_data tdm_dummy_event_data;
12 TDM_DUMMY_EVENT_TYPE_WAIT,
13 TDM_DUMMY_EVENT_TYPE_COMMIT,
14 } tdm_dummy_event_type;
16 struct _tdm_dummy_event_data {
17 struct list_head link;
19 tdm_dummy_event_type type;
20 tdm_dummy_output_data *output_data;
24 struct _tdm_dummy_output_data {
25 struct list_head link;
27 /* data which are fixed at initializing */
28 tdm_dummy_data *dummy_data;
31 tdm_output_mode *output_mode;
32 tdm_output_type connector_type;
33 struct list_head layer_list;
34 tdm_dummy_layer_data *primary_layer;
36 /* not fixed data below */
37 tdm_output_vblank_handler vblank_func;
38 tdm_output_commit_handler commit_func;
40 tdm_output_conn_status status;
43 const tdm_output_mode *current_mode;
45 tdm_event_loop_source *timer;
46 unsigned int timer_waiting;
47 struct list_head timer_event_list;
50 struct _tdm_dummy_layer_data {
51 struct list_head link;
53 /* data which are fixed at initializing */
54 tdm_dummy_data *dummy_data;
55 tdm_dummy_output_data *output_data;
56 tdm_layer_capability capabilities;
59 /* not fixed data below */
63 tbm_surface_h display_buffer;
64 int display_buffer_changed;
68 _tdm_dummy_display_cb_event(tdm_dummy_output_data *output_data, tdm_dummy_event_data *event_data,
69 unsigned int sequence, unsigned int tv_sec, unsigned int tv_usec)
71 switch (event_data->type) {
72 case TDM_DUMMY_EVENT_TYPE_WAIT:
73 if (output_data->vblank_func)
74 output_data->vblank_func(output_data, sequence, tv_sec, tv_usec, event_data->user_data);
76 case TDM_DUMMY_EVENT_TYPE_COMMIT:
77 if (output_data->commit_func)
78 output_data->commit_func(output_data, sequence, tv_sec, tv_usec, event_data->user_data);
86 _tdm_dummy_display_cb_timeout(void *user_data)
88 tdm_dummy_output_data *output_data = user_data;
89 tdm_dummy_event_data *e = NULL, *ee = NULL;
90 unsigned int tv_sec, tv_usec;
91 static unsigned int sequence = 0;
96 if (clock_gettime(CLOCK_MONOTONIC, &tp) == 0) {
98 tv_usec = tp.tv_nsec / 1000;
100 tv_sec = tv_usec = 0;
103 LIST_FOR_EACH_ENTRY_SAFE(e, ee, &output_data->timer_event_list, link) {
105 _tdm_dummy_display_cb_event(output_data, e, sequence, tv_sec, tv_usec);
109 return TDM_ERROR_NONE;
113 _tdm_dummy_display_wait_vblank(tdm_dummy_output_data *output_data, tdm_dummy_event_data *event_data)
118 RETURN_VAL_IF_FAIL(output_data->timer != NULL, TDM_ERROR_OPERATION_FAILED);
119 RETURN_VAL_IF_FAIL(output_data->output_mode->vrefresh > 0, TDM_ERROR_OPERATION_FAILED);
121 if (output_data->timer_waiting) {
122 LIST_ADDTAIL(&event_data->link, &output_data->timer_event_list);
123 return TDM_ERROR_NONE;
126 ms = 1000 / output_data->output_mode->vrefresh;
128 ret = tdm_event_loop_source_timer_update(output_data->timer, ms);
129 if (ret != TDM_ERROR_NONE)
132 LIST_ADDTAIL(&event_data->link, &output_data->timer_event_list);
134 return TDM_ERROR_NONE;
138 _tdm_dummy_display_destroy_layer_list(tdm_dummy_data *dummy_data)
140 tdm_dummy_output_data *o = NULL;
142 LIST_FOR_EACH_ENTRY(o, &dummy_data->output_list, link) {
143 tdm_dummy_layer_data *l = NULL, *ll = NULL;
144 LIST_FOR_EACH_ENTRY_SAFE(l, ll, &o->layer_list, link) {
152 tdm_dummy_display_create_layer_list(tdm_dummy_data *dummy_data)
154 tdm_dummy_output_data *output_data = NULL;
155 tdm_error ret = TDM_ERROR_NONE;
157 if (LIST_IS_EMPTY(&dummy_data->output_list)) {
158 TDM_ERR("no output");
159 return TDM_ERROR_OPERATION_FAILED;
162 /* The TDM dummy backend only support one output. */
163 LIST_FOR_EACH_ENTRY(output_data, &dummy_data->output_list, link) {
164 tdm_dummy_layer_data *layer_data = calloc(1, sizeof(tdm_dummy_layer_data));
166 TDM_ERR("alloc failed");
167 ret = TDM_ERROR_OUT_OF_MEMORY;
171 layer_data->dummy_data = dummy_data;
172 layer_data->output_data = output_data;
173 layer_data->zpos = 0;
175 layer_data->capabilities = TDM_LAYER_CAPABILITY_PRIMARY | TDM_LAYER_CAPABILITY_GRAPHIC;
176 output_data->primary_layer = layer_data;
178 LIST_ADDTAIL(&layer_data->link, &output_data->layer_list);
181 return TDM_ERROR_NONE;
183 _tdm_dummy_display_destroy_layer_list(dummy_data);
188 tdm_dummy_display_destroy_output_list(tdm_dummy_data *dummy_data)
190 tdm_dummy_output_data *o = NULL, *oo = NULL;
192 if (LIST_IS_EMPTY(&dummy_data->output_list))
195 _tdm_dummy_display_destroy_layer_list(dummy_data);
197 LIST_FOR_EACH_ENTRY_SAFE(o, oo, &dummy_data->output_list, link) {
200 if (!LIST_IS_EMPTY(&o->timer_event_list)) {
201 tdm_dummy_event_data *e = NULL, *ee = NULL;
202 LIST_FOR_EACH_ENTRY_SAFE(e, ee, &o->timer_event_list, link) {
209 tdm_event_loop_source_remove(o->timer);
211 free(o->output_mode);
217 tdm_dummy_display_create_output_list(tdm_dummy_data *dummy_data)
219 tdm_dummy_output_data *output_data;
222 RETURN_VAL_IF_FAIL(LIST_IS_EMPTY(&dummy_data->output_list), TDM_ERROR_OPERATION_FAILED);
224 output_data = calloc(1, sizeof(tdm_dummy_output_data));
226 TDM_ERR("alloc failed");
227 ret = TDM_ERROR_OUT_OF_MEMORY;
231 LIST_INITHEAD(&output_data->layer_list);
233 output_data->dummy_data = dummy_data;
234 output_data->pipe = 0;
235 output_data->connector_type = TDM_OUTPUT_TYPE_Unknown;
236 output_data->status = TDM_OUTPUT_CONN_STATUS_CONNECTED;
238 output_data->output_mode = calloc(1, sizeof(tdm_output_mode));
239 if (!output_data->output_mode) {
240 TDM_ERR("alloc failed");
242 ret = TDM_ERROR_OUT_OF_MEMORY;
246 snprintf(output_data->output_mode->name, TDM_NAME_LEN, "640x480");
247 output_data->output_mode->vrefresh = 30;
248 output_data->output_mode->clock = 25200;
249 output_data->output_mode->hdisplay = 640;
250 output_data->output_mode->hsync_start = 656;
251 output_data->output_mode->hsync_end = 752;
252 output_data->output_mode->htotal = 800;
253 output_data->output_mode->hskew = 0;
254 output_data->output_mode->vdisplay = 480;
255 output_data->output_mode->vsync_start = 490;
256 output_data->output_mode->vsync_end = 492;
257 output_data->output_mode->vtotal = 525;
258 output_data->output_mode->vscan = 0;
259 output_data->output_mode->flags = 0;
260 output_data->output_mode->type = 0;
262 output_data->timer = tdm_event_loop_add_timer_handler(dummy_data->dpy,
263 _tdm_dummy_display_cb_timeout,
266 if (!output_data->timer) {
271 LIST_INITHEAD(&output_data->timer_event_list);
273 LIST_ADDTAIL(&output_data->link, &dummy_data->output_list);
275 return TDM_ERROR_NONE;
277 tdm_dummy_display_destroy_output_list(dummy_data);
282 dummy_display_get_capability(tdm_backend_data *bdata, tdm_caps_display *caps)
284 RETURN_VAL_IF_FAIL(caps, TDM_ERROR_INVALID_PARAMETER);
286 caps->max_layer_count = -1; /* not defined */
288 return TDM_ERROR_NONE;
292 dummy_display_get_outputs(tdm_backend_data *bdata, int *count, tdm_error *error)
294 tdm_dummy_data *dummy_data = bdata;
295 tdm_dummy_output_data *output_data = NULL;
296 tdm_output **outputs;
300 RETURN_VAL_IF_FAIL(dummy_data, NULL);
301 RETURN_VAL_IF_FAIL(count, NULL);
304 LIST_FOR_EACH_ENTRY(output_data, &dummy_data->output_list, link)
308 ret = TDM_ERROR_NONE;
312 /* will be freed in frontend */
313 outputs = calloc(*count, sizeof(tdm_dummy_output_data *));
315 TDM_ERR("failed: alloc memory");
317 ret = TDM_ERROR_OUT_OF_MEMORY;
322 LIST_FOR_EACH_ENTRY(output_data, &dummy_data->output_list, link)
323 outputs[i++] = output_data;
326 *error = TDM_ERROR_NONE;
336 dummy_display_get_fd(tdm_backend_data *bdata, int *fd)
338 tdm_dummy_data *dummy_data = bdata;
340 RETURN_VAL_IF_FAIL(dummy_data, TDM_ERROR_INVALID_PARAMETER);
341 RETURN_VAL_IF_FAIL(fd, TDM_ERROR_INVALID_PARAMETER);
343 *fd = dummy_data->pipe[0];
345 return TDM_ERROR_NONE;
349 dummy_display_handle_events(tdm_backend_data *bdata)
351 return TDM_ERROR_NONE;
355 dummy_output_get_capability(tdm_output *output, tdm_caps_output *caps)
357 tdm_dummy_output_data *output_data = output;
360 RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER);
361 RETURN_VAL_IF_FAIL(caps, TDM_ERROR_INVALID_PARAMETER);
363 memset(caps, 0, sizeof(tdm_caps_output));
365 snprintf(caps->maker, TDM_NAME_LEN, "dummy");
366 snprintf(caps->model, TDM_NAME_LEN, "dummy");
367 snprintf(caps->name, TDM_NAME_LEN, "dummy");
369 caps->status = output_data->status;
370 caps->type = output_data->connector_type;
373 caps->mode_count = 1;
374 caps->modes = calloc(1, sizeof(tdm_output_mode));
376 ret = TDM_ERROR_OUT_OF_MEMORY;
377 TDM_ERR("alloc failed\n");
381 *caps->modes = *output_data->output_mode;
384 caps->mmHeight = 480;
391 caps->preferred_align = -1;
393 caps->prop_count = 0;
395 return TDM_ERROR_NONE;
397 memset(caps, 0, sizeof(tdm_caps_output));
402 dummy_output_get_layers(tdm_output *output, int *count, tdm_error *error)
404 tdm_dummy_output_data *output_data = output;
405 tdm_dummy_layer_data *layer_data = NULL;
410 RETURN_VAL_IF_FAIL(output_data, NULL);
411 RETURN_VAL_IF_FAIL(count, NULL);
414 LIST_FOR_EACH_ENTRY(layer_data, &output_data->layer_list, link)
418 ret = TDM_ERROR_NONE;
422 /* will be freed in frontend */
423 layers = calloc(*count, sizeof(tdm_dummy_layer_data *));
425 TDM_ERR("failed: alloc memory");
427 ret = TDM_ERROR_OUT_OF_MEMORY;
432 LIST_FOR_EACH_ENTRY(layer_data, &output_data->layer_list, link)
433 layers[i++] = layer_data;
436 *error = TDM_ERROR_NONE;
446 dummy_output_wait_vblank(tdm_output *output, int interval, int sync, void *user_data)
448 tdm_dummy_output_data *output_data = output;
449 tdm_dummy_event_data *event_data;
452 RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER);
454 event_data = calloc(1, sizeof(tdm_dummy_event_data));
456 TDM_ERR("alloc failed");
457 return TDM_ERROR_OUT_OF_MEMORY;
460 event_data->type = TDM_DUMMY_EVENT_TYPE_WAIT;
461 event_data->output_data = output_data;
462 event_data->user_data = user_data;
464 ret = _tdm_dummy_display_wait_vblank(output_data, event_data);
465 if (ret != TDM_ERROR_NONE) {
470 return TDM_ERROR_NONE;
474 dummy_output_set_vblank_handler(tdm_output *output, tdm_output_vblank_handler func)
476 tdm_dummy_output_data *output_data = output;
478 RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER);
479 RETURN_VAL_IF_FAIL(func, TDM_ERROR_INVALID_PARAMETER);
481 output_data->vblank_func = func;
483 return TDM_ERROR_NONE;
487 dummy_output_commit(tdm_output *output, int sync, void *user_data)
489 tdm_dummy_output_data *output_data = output;
490 tdm_dummy_event_data *event_data;
493 RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER);
495 event_data = calloc(1, sizeof(tdm_dummy_event_data));
497 TDM_ERR("alloc failed");
498 return TDM_ERROR_OUT_OF_MEMORY;
501 event_data->type = TDM_DUMMY_EVENT_TYPE_COMMIT;
502 event_data->output_data = output_data;
503 event_data->user_data = user_data;
505 ret = _tdm_dummy_display_wait_vblank(output_data, event_data);
506 if (ret != TDM_ERROR_NONE) {
511 return TDM_ERROR_NONE;
515 dummy_output_set_commit_handler(tdm_output *output, tdm_output_commit_handler func)
517 tdm_dummy_output_data *output_data = output;
519 RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER);
520 RETURN_VAL_IF_FAIL(func, TDM_ERROR_INVALID_PARAMETER);
522 output_data->commit_func = func;
524 return TDM_ERROR_NONE;
528 dummy_output_set_mode(tdm_output *output, const tdm_output_mode *mode)
530 tdm_dummy_output_data *output_data = output;
532 RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER);
533 RETURN_VAL_IF_FAIL(mode, TDM_ERROR_INVALID_PARAMETER);
535 output_data->current_mode = mode;
536 output_data->mode_changed = 1;
538 return TDM_ERROR_NONE;
542 dummy_output_get_mode(tdm_output *output, const tdm_output_mode **mode)
544 tdm_dummy_output_data *output_data = output;
546 RETURN_VAL_IF_FAIL(output_data, TDM_ERROR_INVALID_PARAMETER);
547 RETURN_VAL_IF_FAIL(mode, TDM_ERROR_INVALID_PARAMETER);
549 *mode = output_data->current_mode;
551 return TDM_ERROR_NONE;
555 dummy_layer_get_capability(tdm_layer *layer, tdm_caps_layer *caps)
557 tdm_dummy_layer_data *layer_data = layer;
559 RETURN_VAL_IF_FAIL(layer_data, TDM_ERROR_INVALID_PARAMETER);
560 RETURN_VAL_IF_FAIL(caps, TDM_ERROR_INVALID_PARAMETER);
562 memset(caps, 0, sizeof(tdm_caps_layer));
564 caps->capabilities = layer_data->capabilities;
565 caps->zpos = layer_data->zpos;
567 caps->format_count = 2;
568 caps->formats = calloc(caps->format_count, sizeof(tbm_format));
569 if (!caps->formats) {
570 TDM_ERR("alloc failed\n");
572 memset(caps, 0, sizeof(tdm_caps_layer));
573 return TDM_ERROR_OUT_OF_MEMORY;
576 caps->formats[0] = TBM_FORMAT_ARGB8888;
577 caps->formats[1] = TBM_FORMAT_XRGB8888;
579 caps->prop_count = 0;
581 return TDM_ERROR_NONE;
585 dummy_layer_set_info(tdm_layer *layer, tdm_info_layer *info)
587 tdm_dummy_layer_data *layer_data = layer;
589 RETURN_VAL_IF_FAIL(layer_data, TDM_ERROR_INVALID_PARAMETER);
590 RETURN_VAL_IF_FAIL(info, TDM_ERROR_INVALID_PARAMETER);
592 layer_data->info = *info;
593 layer_data->info_changed = 1;
595 return TDM_ERROR_NONE;
599 dummy_layer_get_info(tdm_layer *layer, tdm_info_layer *info)
601 tdm_dummy_layer_data *layer_data = layer;
603 RETURN_VAL_IF_FAIL(layer_data, TDM_ERROR_INVALID_PARAMETER);
604 RETURN_VAL_IF_FAIL(info, TDM_ERROR_INVALID_PARAMETER);
606 *info = layer_data->info;
608 return TDM_ERROR_NONE;
612 dummy_layer_set_buffer(tdm_layer *layer, tbm_surface_h buffer)
614 tdm_dummy_layer_data *layer_data = layer;
616 RETURN_VAL_IF_FAIL(layer_data, TDM_ERROR_INVALID_PARAMETER);
617 RETURN_VAL_IF_FAIL(buffer, TDM_ERROR_INVALID_PARAMETER);
619 layer_data->display_buffer = buffer;
620 layer_data->display_buffer_changed = 1;
622 return TDM_ERROR_NONE;
626 dummy_layer_unset_buffer(tdm_layer *layer)
628 tdm_dummy_layer_data *layer_data = layer;
630 RETURN_VAL_IF_FAIL(layer_data, TDM_ERROR_INVALID_PARAMETER);
632 layer_data->display_buffer = NULL;
633 layer_data->display_buffer_changed = 1;
635 return TDM_ERROR_NONE;