1 /**************************************************************************
5 * Copyright 2015 Samsung Electronics co., Ltd. All Rights Reserved.
7 * Contact: Eunchul Kim <chulspro.kim@samsung.com>,
8 * JinYoung Jeon <jy0.jeon@samsung.com>,
9 * Taeheon Kim <th908.kim@samsung.com>,
10 * YoungJun Cho <yj44.cho@samsung.com>,
11 * SooChan Lim <sc1.lim@samsung.com>,
12 * Boram Park <boram1288.park@samsung.com>
14 * Permission is hereby granted, free of charge, to any person obtaining a
15 * copy of this software and associated documentation files (the
16 * "Software"), to deal in the Software without restriction, including
17 * without limitation the rights to use, copy, modify, merge, publish,
18 * distribute, sub license, and/or sell copies of the Software, and to
19 * permit persons to whom the Software is furnished to do so, subject to
20 * the following conditions:
22 * The above copyright notice and this permission notice (including the
23 * next paragraph) shall be included in all copies or substantial portions
26 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
27 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
29 * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
30 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
31 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
32 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34 **************************************************************************/
45 #include <tbm_surface.h>
46 #include <tbm_surface_internal.h>
51 #include "tdm_helper.h"
52 #include "tdm_backend.h"
54 #include "tdm_macro.h"
55 #include "tdm_private.h"
58 ////////////////////////////////////////////////////////////////////////////////
79 static struct typestrings typestrs[] = {
80 {OPT_QRY, "Query", NULL},
81 {OPT_TST, "Test", NULL},
82 {OPT_GEN, "General", NULL},
85 static struct optstrings optstrs[] = {
87 OPT_QRY, "q", "show tdm output, layer information",
91 OPT_TST, "a", "set all layer objects for all connected outputs",
95 OPT_TST, "o", "set a mode for a output object",
96 "<output_idx>@<mode>[&<refresh>]", "0@1920x1080"
99 OPT_TST, "l", "set a layer object",
100 "<layer_idx>[:<w>x<h>[+<x>+<y>][,<h>x<v>][@<format>]]~<w>x<h>[+<x>+<y>][*<transform>]", NULL
103 OPT_TST, "p", "set a PP object.\n\t\t'-l' is used to show the result on screen.",
104 "<w>x<h>[+<x>+<y>][,<h>x<v>][@<format>]~<w>x<h>[+<x>+<y>][,<h>x<v>][@<format>][*<transform>][&<fps>]", NULL
107 OPT_TST, "c", "catpure a output object or a layer object.\n\t\t'-l' is used to show the result on screen.",
108 "<output_idx>[,<layer_idx>]~<w>x<h>[+<x>+<y>][,<h>x<v>][@<format>][*<transform>][^stream]", NULL
111 OPT_TST, "V", "virtual output test.\n\t\t'-l' is used to show the result on screen.",
115 OPT_GEN, "w", "set the property of a object",
116 "<prop_name>:<value>", NULL
119 OPT_GEN, "b", "set the fill(smtpe,tiles,plain) and framebuffer type(scanout,noncachable,wc)",
120 "<fill>[:<buf_flag>[,<buf_flag2>[,...]]]", NULL
123 OPT_GEN, "v", "update layers every vblank",
133 static struct usagestring usages[] = {
140 "test all outputs, layers with plain buffers"
144 "Set the \"1920x1080\" mode to the output 0. And show a buffer via a primary layer of the output 0"
147 "-o 0@1920x1080 -l 1~640x480+50+100",
148 "Create the 640x480 buffer and show it in the (50,100) pos of screen via the layer 1"
151 "-p 320x240@NV12~480x360+80+40,640x480@AR24 -l 1~640x480+50+100",
152 "Convert the 320x240@NV12 buffer to the 640x480@AR24 buffer(480x360+80+40) and show the result via the layer 1"
157 usage(char *app_name)
159 int type_size = sizeof(typestrs) / sizeof(struct typestrings);
160 int opt_size = sizeof(optstrs) / sizeof(struct optstrings);
161 int usages_size = sizeof(usages) / sizeof(struct usagestring);
164 printf("usage: %s \n\n", app_name);
166 for (t = 0; t < type_size; t++) {
169 for (o = 0; o < opt_size; o++)
170 if (optstrs[o].type == typestrs[t].type) {
172 printf(" %s options: %s\n\n", typestrs[t].string, (typestrs[t].desc) ? : "");
173 printf("\t-%s\t%s\n", optstrs[o].opt, optstrs[o].desc);
175 printf("\t\t %s\n", optstrs[o].arg);
177 printf("\t\t ex) %s\n", optstrs[o].ex);
183 printf(" For example)\n\n");
185 for (t = 0; t < usages_size; t++) {
186 printf(" $ %s %s\n", app_name, usages[t].string);
187 printf("\t%s\n", usages[t].desc);
192 ////////////////////////////////////////////////////////////////////////////////
194 static const char *tdm_buf_flag_names[] = {
199 TDM_BIT_NAME_FB(buf_flag)
201 #define DEFAULT_FORMAT TBM_FORMAT_ARGB8888
203 #define print_size(s) \
204 printf("%dx%d", (s)->h, (s)->v)
205 #define print_pos(p) \
206 printf("%dx%d+%d+%d", (p)->w, (p)->h, (p)->x, (p)->y)
207 #define print_format(f) \
208 if (f) printf("%c%c%c%c", FOURCC_STR(f)); \
210 #define print_config(c) \
212 print_size(&(c)->size); \
214 print_pos(&(c)->pos); \
216 print_format((c)->format); \
218 #define print_prop(w) \
219 printf("%s(%d)", (w)->name, ((w)->value).u32)
221 typedef struct _tdm_test_server tdm_test_server;
222 typedef struct _tdm_test_server_layer tdm_test_server_layer;
223 typedef struct _tdm_test_server_capture tdm_test_server_capture;
224 typedef struct _tdm_test_server_voutput tdm_test_server_voutput;
226 typedef struct _tdm_test_server_prop {
228 char name[TDM_NAME_LEN];
231 /* variables for test */
232 struct list_head link;
233 } tdm_test_server_prop;
235 typedef struct _tdm_test_server_buffer {
236 /* variables for test */
239 tdm_test_server_layer *l;
241 tdm_test_server_capture *c;
242 tdm_buffer_release_handler done;
243 } tdm_test_server_buffer;
245 typedef struct _tdm_test_server_output {
248 char mode[TDM_NAME_LEN];
251 /* variables for test */
252 struct list_head link;
253 struct list_head prop_list;
254 struct list_head layer_list;
255 tdm_test_server *data;
258 int fill_primary_layer;
259 } tdm_test_server_output;
261 typedef struct _tdm_test_server_pp {
266 /* variables for test */
267 struct list_head link;
268 tdm_test_server *data;
269 tdm_test_server_layer *l;
271 tbm_surface_h bufs[6];
274 tdm_event_loop_source *timer_source;
275 } tdm_test_server_pp;
277 struct _tdm_test_server_capture {
281 tdm_info_capture info;
283 /* variables for test */
284 struct list_head link;
285 tdm_test_server *data;
286 tdm_test_server_layer *l;
287 tdm_capture *capture;
290 struct _tdm_test_server_layer {
295 /* variables for test */
296 struct list_head link;
297 struct list_head prop_list;
298 tdm_test_server *data;
299 tdm_test_server_output *o;
302 tdm_test_server_pp *owner_p;
303 tdm_test_server_capture *owner_c;
304 tbm_surface_h bufs[3];
308 struct _tdm_test_server_voutput {
309 struct list_head link;
310 tdm_test_server *data;
313 tbm_surface_h bufs[3];
315 int need_mode_change;
317 tdm_event_loop_source *timer;
318 const tdm_output_mode *current_mode;
321 struct _tdm_test_server {
330 /* variables for test */
331 struct list_head output_list;
332 struct list_head pp_list;
333 struct list_head capture_list;
334 struct list_head voutput_list;
335 tdm_display *display;
338 static void destroy(tdm_test_server *data);
339 static void run_test(tdm_test_server *data);
340 static void output_setup(tdm_test_server_output *o);
341 static void layer_show_buffer(tdm_test_server_layer *l, tbm_surface_h b);
342 static void capture_attach(tdm_test_server_capture *c, tbm_surface_h b);
343 static void _vlayer_show_buffer(tdm_test_server_voutput *voutput);
344 static void _voutput_layer_init(tdm_test_server_voutput *voutput);
347 parse_size(tdm_size *size, char *arg)
350 size->h = strtol(arg, &end, 10);
351 TDM_EXIT_IF_FAIL(*end == 'x');
353 size->v = strtol(arg, &end, 10);
358 parse_pos(tdm_pos *pos, char *arg)
361 pos->w = strtol(arg, &end, 10);
362 TDM_EXIT_IF_FAIL(*end == 'x');
364 pos->h = strtol(arg, &end, 10);
367 pos->x = strtol(arg, &end, 10);
368 TDM_EXIT_IF_FAIL(*end == '+');
370 pos->y = strtol(arg, &end, 10);
376 parse_config(tdm_info_config *config, char *arg)
379 end = parse_pos(&config->pos, arg);
382 end = parse_size(&config->size, arg);
387 end = strtostr(temp, 32, arg, TDM_DELIM);
388 config->format = FOURCC_ID(temp);
394 parse_arg_o(tdm_test_server_output *o, char *arg)
397 TDM_EXIT_IF_FAIL(arg != NULL);
398 o->idx = strtol(arg, &end, 10);
399 TDM_EXIT_IF_FAIL(*end == '@');
401 end = strtostr(o->mode, TDM_NAME_LEN, arg, TDM_DELIM);
404 o->refresh = strtol(arg, &end, 10);
409 parse_arg_p(tdm_test_server_pp *p, char *arg)
411 tdm_info_pp *pp_info = &p->info;
413 TDM_EXIT_IF_FAIL(arg != NULL);
414 end = parse_config(&pp_info->src_config, arg);
415 TDM_EXIT_IF_FAIL(*end == '~');
417 end = parse_config(&pp_info->dst_config, arg);
420 pp_info->transform = strtol(arg, &end, 10);
424 p->fps = strtol(arg, &end, 10);
429 parse_arg_c(tdm_test_server_capture *c, char *arg)
431 tdm_info_capture *capture_info = &c->info;
433 TDM_EXIT_IF_FAIL(arg != NULL);
434 c->output_idx = strtol(arg, &end, 10);
437 c->layer_idx = strtol(arg, &end, 10);
439 TDM_EXIT_IF_FAIL(*end == '~');
441 end = parse_config(&capture_info->dst_config, arg);
444 capture_info->transform = strtol(arg, &end, 10);
448 if (strtol(arg, &end, 10) > 0)
449 capture_info->type = TDM_CAPTURE_TYPE_STREAM;
451 capture_info->type = TDM_CAPTURE_TYPE_ONESHOT;
456 parse_arg_l(tdm_test_server_layer *l, char *arg)
458 tdm_info_layer *layer_info = &l->info;
460 TDM_EXIT_IF_FAIL(arg != NULL);
461 l->idx = strtol(arg, &end, 10);
464 end = parse_config(&layer_info->src_config, arg);
466 TDM_EXIT_IF_FAIL(*end == '~');
468 end = parse_pos(&layer_info->dst_pos, arg);
471 layer_info->transform = strtol(arg, &end, 10);
476 parse_arg_w(tdm_test_server_prop *w, char *arg)
479 TDM_EXIT_IF_FAIL(arg != NULL);
480 end = strtostr(w->name, TDM_PATH_LEN, arg, TDM_DELIM);
481 TDM_EXIT_IF_FAIL(*end == ':');
483 w->value.u32 = strtol(arg, &end, 10);
487 parse_arg_b(tdm_test_server *data, char *arg)
490 char temp[TDM_NAME_LEN] = {0,};
491 TDM_EXIT_IF_FAIL(arg != NULL);
493 end = strtostr(temp, 32, arg, TDM_DELIM);
494 if (!strncmp(temp, "smpte", 5))
495 data->b_fill = PATTERN_SMPTE;
496 else if (!strncmp(temp, "tiles", 5))
497 data->b_fill = PATTERN_TILES;
498 else if (!strncmp(temp, "plain", 5))
499 data->b_fill = PATTERN_PLAIN;
501 printf("'%s': unknown flag\n", temp);
508 snprintf(temp, TDM_NAME_LEN, "%s", arg);
509 arg = strtok_r(temp, ",", &end);
511 if (!strncmp(arg, "default", 7))
512 printf("Ignore '%s' flag\n", arg);
513 else if (!strncmp(arg, "scanout", 7))
514 data->bflags |= TBM_BO_SCANOUT;
515 else if (!strncmp(arg, "noncachable", 11))
516 data->bflags |= TBM_BO_NONCACHABLE;
517 else if (!strncmp(arg, "wc", 2))
518 data->bflags |= TBM_BO_WC;
520 printf("'%s': unknown flag\n", arg);
523 arg = strtok_r(NULL, ",", &end);
529 parse_args(tdm_test_server *data, int argc, char *argv[])
531 tdm_test_server_output *o = NULL;
532 tdm_test_server_layer *l = NULL;
533 tdm_test_server_pp *p = NULL;
534 tdm_test_server_capture *c = NULL;
535 tdm_test_server_prop *w = NULL;
536 void *last_option = NULL;
537 void *last_object = NULL;
546 for (i = 1; i < argc; i++) {
547 if (!strncmp(argv[i] + 1, "q", 1)) {
550 } else if (!strncmp(argv[i] + 1, "a", 1)) {
552 } else if (!strncmp(argv[i] + 1, "o", 1)) {
553 TDM_GOTO_IF_FAIL(data->do_all == 0, all);
554 o = calloc(1, sizeof * o);
555 TDM_EXIT_IF_FAIL(o != NULL);
557 LIST_INITHEAD(&o->layer_list);
558 LIST_INITHEAD(&o->prop_list);
559 LIST_ADDTAIL(&o->link, &data->output_list);
560 parse_arg_o(o, argv[++i]);
562 } else if (!strncmp(argv[i] + 1, "p", 1)) {
563 TDM_GOTO_IF_FAIL(data->do_all == 0, all);
564 p = calloc(1, sizeof * p);
565 TDM_EXIT_IF_FAIL(p != NULL);
567 p->fps = 30; /* default 30 fps */
568 LIST_ADDTAIL(&p->link, &data->pp_list);
569 parse_arg_p(p, argv[++i]);
571 } else if (!strncmp(argv[i] + 1, "c", 1)) {
572 TDM_GOTO_IF_FAIL(data->do_all == 0, all);
573 c = calloc(1, sizeof * c);
574 TDM_EXIT_IF_FAIL(c != NULL);
578 LIST_ADDTAIL(&c->link, &data->capture_list);
579 parse_arg_c(c, argv[++i]);
581 } else if (!strncmp(argv[i] + 1, "l", 1)) {
582 TDM_GOTO_IF_FAIL(data->do_all == 0, all);
584 o = calloc(1, sizeof * o);
585 TDM_EXIT_IF_FAIL(o != NULL);
587 LIST_INITHEAD(&o->layer_list);
588 LIST_INITHEAD(&o->prop_list);
589 LIST_ADDTAIL(&o->link, &data->output_list);
591 l = calloc(1, sizeof * l);
592 TDM_EXIT_IF_FAIL(l != NULL);
593 LIST_INITHEAD(&l->prop_list);
594 LIST_ADDTAIL(&l->link, &o->layer_list);
597 parse_arg_l(l, argv[++i]);
598 if (p && last_option == p) {
601 } else if (c && last_option == c) {
606 } else if (!strncmp(argv[i] + 1, "w", 1)) {
607 TDM_GOTO_IF_FAIL(data->do_all == 0, all);
610 w = calloc(1, sizeof * w);
611 TDM_EXIT_IF_FAIL(w != NULL);
612 if (o && last_object == o)
613 LIST_ADDTAIL(&w->link, &o->prop_list);
614 else if (l && last_object == l)
615 LIST_ADDTAIL(&w->link, &l->prop_list);
616 parse_arg_w(w, argv[++i]);
617 } else if (!strncmp(argv[i] + 1, "b", 1)) {
618 parse_arg_b(data, argv[++i]);
619 } else if (!strncmp(argv[i] + 1, "v", 1)) {
621 } else if (!strncmp(argv[i] + 1, "V", 1)) {
622 data->do_voutput = 1;
630 LIST_FOR_EACH_ENTRY(p, &data->pp_list, link) {
634 LIST_FOR_EACH_ENTRY(c, &data->capture_list, link) {
641 printf("Use '-l' to set a layer for '-p' or '-c'.\n");
644 printf("Use '-o' or '-l' to set a object first.\n");
647 printf("Can't use '-%s' with '-a'.\n", argv[i] + 1);
652 interpret_args(tdm_test_server *data)
654 tdm_test_server_output *o = NULL;
655 tdm_test_server_layer *l = NULL;
658 /* create the objects of outputs */
662 ret = tdm_display_get_output_count(data->display, &output_count);
663 TDM_EXIT_IF_FAIL(ret == TDM_ERROR_NONE);
665 for (i = 0; i < output_count; i++) {
666 tdm_output *output = tdm_display_get_output(data->display, i, NULL);
667 tdm_output_conn_status status;
668 ret = tdm_output_get_conn_status(output, &status);
669 TDM_EXIT_IF_FAIL(ret == TDM_ERROR_NONE);
671 if (status == TDM_OUTPUT_CONN_STATUS_DISCONNECTED)
673 o = calloc(1, sizeof * o);
674 TDM_EXIT_IF_FAIL(o != NULL);
676 LIST_INITHEAD(&o->layer_list);
677 LIST_INITHEAD(&o->prop_list);
678 LIST_ADDTAIL(&o->link, &data->output_list);
680 o->fill_primary_layer = 1;
684 /* check if the primary layer object exists */
685 LIST_FOR_EACH_ENTRY(o, &data->output_list, link) {
687 const tdm_output_mode *mode;
688 int j, layer_count, primary_index = 0;
689 tdm_test_server_layer *primary_l = NULL;
693 output = tdm_display_get_output(data->display, o->idx, &ret);
694 TDM_EXIT_IF_FAIL(ret == TDM_ERROR_NONE);
695 ret = tdm_output_get_mode(output, &mode);
696 TDM_EXIT_IF_FAIL(ret == TDM_ERROR_NONE);
697 ret = tdm_output_get_layer_count(output, &layer_count);
698 TDM_EXIT_IF_FAIL(ret == TDM_ERROR_NONE);
699 ret = tdm_output_get_primary_index(output, &primary_index);
700 TDM_EXIT_IF_FAIL(ret == TDM_ERROR_NONE);
702 if (LIST_IS_EMPTY(&o->layer_list))
703 o->fill_primary_layer = 1;
705 LIST_FOR_EACH_ENTRY(l, &o->layer_list, link) {
706 if (l->idx == primary_index) {
708 o->fill_primary_layer = 1;
715 if (!primary_l || data->do_all) {
716 for (j = 0; j < layer_count; j++) {
717 if (j != primary_index && !data->do_all)
719 l = calloc(1, sizeof * l);
720 TDM_EXIT_IF_FAIL(l != NULL);
721 LIST_INITHEAD(&l->prop_list);
722 LIST_ADDTAIL(&l->link, &o->layer_list);
726 if (j == primary_index) {
728 l->info.dst_pos.w = mode->hdisplay;
729 l->info.dst_pos.h = mode->vdisplay;
732 l->info.dst_pos.w = TDM_ALIGN(mode->hdisplay / 3, 2);
733 l->info.dst_pos.h = TDM_ALIGN(mode->vdisplay / 3, 2);
734 l->info.dst_pos.x = TDM_ALIGN(((mode->hdisplay / 3) / layer_count) * j, 2);
735 l->info.dst_pos.y = TDM_ALIGN(((mode->vdisplay / 3) / layer_count) * j, 2);
740 TDM_EXIT_IF_FAIL(primary_l != NULL);
741 LIST_DEL(&primary_l->link);
742 LIST_ADD(&primary_l->link, &o->layer_list);
745 /* fill the empty information of layers */
746 LIST_FOR_EACH_ENTRY(o, &data->output_list, link) {
748 int minw, minh, maxw, maxh;
750 output = tdm_display_get_output(data->display, o->idx, &ret);
751 TDM_EXIT_IF_FAIL(ret == TDM_ERROR_NONE);
752 ret = tdm_output_get_available_size(output, &minw, &minh, &maxw, &maxh, NULL);
753 TDM_EXIT_IF_FAIL(ret == TDM_ERROR_NONE);
755 /* l->info.src_config.size will be decided when a buffer shows really */
756 LIST_FOR_EACH_ENTRY(l, &o->layer_list, link) {
757 if (minw > 0 && minh > 0) {
758 TDM_EXIT_IF_FAIL(l->info.dst_pos.w >= minw);
759 TDM_EXIT_IF_FAIL(l->info.dst_pos.h >= minh);
761 if (maxw > 0 && maxh > 0) {
762 TDM_EXIT_IF_FAIL(l->info.dst_pos.w <= maxw);
763 TDM_EXIT_IF_FAIL(l->info.dst_pos.h <= maxh);
767 l->info.src_config.format = l->owner_p->info.dst_config.format;
768 if (l->info.src_config.pos.w == 0) {
769 TDM_EXIT_IF_FAIL(l->owner_p->info.dst_config.size.h > 0);
770 l->info.src_config.pos.w = l->owner_p->info.dst_config.size.h;
771 l->info.src_config.pos.h = l->owner_p->info.dst_config.size.v;
773 } else if (l->owner_c) {
774 l->info.src_config.format = l->owner_c->info.dst_config.format;
775 if (l->info.src_config.pos.w == 0) {
776 TDM_EXIT_IF_FAIL(l->owner_c->info.dst_config.size.h > 0);
777 l->info.src_config.pos.w = l->owner_c->info.dst_config.size.h;
778 l->info.src_config.pos.h = l->owner_c->info.dst_config.size.v;
781 if (l->info.src_config.pos.w == 0) {
782 TDM_EXIT_IF_FAIL(l->info.dst_pos.w > 0);
783 l->info.src_config.pos.w = l->info.dst_pos.w;
784 l->info.src_config.pos.h = l->info.dst_pos.h;
791 static tdm_test_server tts_data;
792 static int tts_buffer_key;
793 #define TTS_BUFFER_KEY ((unsigned long)&tts_buffer_key)
796 buffer_allocate(int width, int height, int format, int flags)
798 tdm_test_server_buffer *tb = calloc(1, sizeof *tb);
799 TDM_EXIT_IF_FAIL(tb != NULL);
800 tb->b = tbm_surface_internal_create_with_flags(width, height, format, flags);
801 TDM_EXIT_IF_FAIL(tb->b != NULL);
802 tdm_helper_clear_buffer(tb->b);
803 tbm_surface_internal_add_user_data(tb->b, TTS_BUFFER_KEY, free);
804 tbm_surface_internal_set_user_data(tb->b, TTS_BUFFER_KEY, tb);
808 static tdm_test_server_buffer*
809 get_tts_buffer(tbm_surface_h b)
811 tdm_test_server_buffer *tb = NULL;
812 tbm_surface_internal_get_user_data(b, TTS_BUFFER_KEY, (void **)&tb);
817 _voutput_buff_deinit(tdm_test_server_voutput *voutput)
821 for (i = 0; i < 3; i++) {
822 if (!voutput->bufs[i]) continue;
824 tbm_surface_destroy(voutput->bufs[i]);
825 voutput->bufs[i] = NULL;
830 _voutput_buff_init(tdm_test_server_voutput *voutput)
832 tdm_output *output = voutput->output;
833 const tdm_output_mode *mode;
834 tdm_error ret = TDM_ERROR_NONE;
837 ret = tdm_output_get_mode(output, &mode);
838 TDM_EXIT_IF_FAIL(ret == TDM_ERROR_NONE);
840 for (i = 0; i < 3; i++) {
841 tbm_surface_h b = tbm_surface_internal_create_with_flags(mode->hdisplay, mode->vdisplay, DEFAULT_FORMAT, 0);
842 TDM_EXIT_IF_FAIL(b != NULL);
843 tdm_test_buffer_fill(b, i);
844 voutput->bufs[i] = b;
848 _vlayer_cb_commit(tdm_layer *layer, unsigned int sequence,
849 unsigned int tv_sec, unsigned int tv_usec, void *user_data)
851 tdm_test_server_voutput *voutput = (tdm_test_server_voutput *)user_data;
852 TDM_EXIT_IF_FAIL(voutput != NULL);
853 tdm_test_server *data;
854 tdm_output_conn_status status;
857 printf("voutput cb:\t %d: l(%p) b(%p)\n", voutput->buf_idx, voutput->layer, voutput->bufs[voutput->buf_idx]);
859 ret = tdm_output_get_conn_status(voutput->output, &status);
860 TDM_EXIT_IF_FAIL(ret == TDM_ERROR_NONE);
862 if (status == TDM_OUTPUT_CONN_STATUS_DISCONNECTED) return;
864 if (voutput->need_mode_change) {
865 const tdm_output_mode *modes;
868 tdm_output_get_available_modes(voutput->output, &modes, &count);
869 if (count > voutput->mode_index) {
870 const tdm_output_mode *mode;
872 mode = &modes[voutput->mode_index];
873 data = voutput->data;
875 printf("mode change to %d (%dx%d, %d)\n",
876 voutput->mode_index, mode->hdisplay, mode->vdisplay, mode->vrefresh);
877 _voutput_buff_deinit(voutput);
878 _voutput_buff_init(voutput);
880 ret = tdm_output_set_mode(voutput->output, mode);
881 TDM_EXIT_IF_FAIL(ret == TDM_ERROR_NONE);
883 voutput->current_mode = mode;
885 _voutput_layer_init(voutput);
886 voutput->buf_idx = 0;
888 tdm_display_lock(data->display);
889 ret = tdm_event_loop_source_timer_update(voutput->timer, 10);
890 tdm_display_unlock(data->display);
891 TDM_EXIT_IF_FAIL(ret == TDM_ERROR_NONE);
894 voutput->need_mode_change = 0;
899 _vlayer_show_buffer(voutput);
903 _vlayer_show_buffer(tdm_test_server_voutput *voutput)
907 if (voutput->buf_idx == 3)
908 voutput->buf_idx = 0;
910 index = voutput->buf_idx;
912 ret = tdm_layer_set_buffer(voutput->layer, voutput->bufs[index]);
913 TDM_EXIT_IF_FAIL(ret == TDM_ERROR_NONE);
915 ret = tdm_layer_commit(voutput->layer, _vlayer_cb_commit, voutput);
916 TDM_EXIT_IF_FAIL(ret == TDM_ERROR_NONE);
918 printf("voutput show:\t %d: l(%p) b(%p)\n", index, voutput->layer, voutput->bufs[index]);
922 _voutput_layer_init(tdm_test_server_voutput *voutput)
924 tdm_output *output = voutput->output;
925 const tdm_output_mode *mode;
926 tdm_info_layer layer_info;
927 tbm_surface_info_s info;
928 tdm_error ret = TDM_ERROR_NONE;
930 ret = tdm_output_get_mode(output, &mode);
931 TDM_EXIT_IF_FAIL(ret == TDM_ERROR_NONE);
933 TDM_ERR("modeinfo : %dx%d %d", mode->hdisplay, mode->vdisplay, mode->vrefresh);
935 voutput->current_mode = mode;
937 voutput->layer = tdm_output_get_layer(output, 0, &ret);
938 TDM_EXIT_IF_FAIL(ret == TDM_ERROR_NONE);
940 _voutput_buff_init(voutput);
942 tbm_surface_get_info(voutput->bufs[0], &info);
943 memset(&layer_info, 0x0, sizeof(tdm_info_layer));
944 if (IS_RGB(info.format)) {
945 layer_info.src_config.size.h = info.planes[0].stride >> 2;
946 layer_info.src_config.size.v = info.height;
948 layer_info.src_config.size.h = info.planes[0].stride;
949 layer_info.src_config.size.v = info.height;
951 layer_info.src_config.format = info.format;
953 layer_info.src_config.size.h = mode->hdisplay;
954 layer_info.src_config.size.v = mode->vdisplay;
955 layer_info.src_config.pos.x = 0;
956 layer_info.src_config.pos.y = 0;
957 layer_info.src_config.pos.w = mode->hdisplay;
958 layer_info.src_config.pos.h = mode->vdisplay;
959 layer_info.dst_pos.x = 0;
960 layer_info.dst_pos.y = 0;
961 layer_info.dst_pos.w = mode->hdisplay;
962 layer_info.dst_pos.h = mode->vdisplay;
963 layer_info.transform = TDM_TRANSFORM_NORMAL;
965 ret = tdm_layer_set_info(voutput->layer, &layer_info);
966 TDM_EXIT_IF_FAIL(ret == TDM_ERROR_NONE);
970 _voutput_connect(tdm_test_server_voutput *voutput)
973 const tdm_output_mode *modes, *found = NULL, *best = NULL, *prefer = NULL;
977 output = voutput->output;
979 ret = tdm_output_get_available_modes(output, &modes, &count);
980 TDM_EXIT_IF_FAIL(ret == TDM_ERROR_NONE);
982 for (i = 0; i < count; i++) {
985 if (modes[i].type & TDM_OUTPUT_MODE_TYPE_PREFERRED)
990 printf("found prefer mode: %dx%d %d\n", found->hdisplay, found->vdisplay, found->vrefresh);
992 if (!found && best) {
994 printf("found best mode: %dx%d %d\n", found->hdisplay, found->vdisplay, found->vrefresh);
997 printf("couldn't find any mode\n");
1001 ret = tdm_output_set_mode(output, found);
1002 TDM_EXIT_IF_FAIL(ret == TDM_ERROR_NONE);
1004 printf("output: %s %d\n", found->name, found->vrefresh);
1006 ret = tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_ON);
1007 TDM_EXIT_IF_FAIL(ret == TDM_ERROR_NONE);
1011 _voutput_disconnect(tdm_test_server_voutput *voutput)
1016 output = voutput->output;
1018 printf("output: %p disconnect\n", voutput);
1020 ret = tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_OFF);
1021 TDM_EXIT_IF_FAIL(ret == TDM_ERROR_NONE);
1025 _voutput_buffer_send(void *user_data)
1027 tdm_test_server_voutput *voutput = user_data;
1028 tdm_test_server *data = voutput->data;
1030 tdm_display_unlock(data->display);
1032 _vlayer_show_buffer(voutput);
1034 tdm_display_lock(data->display);
1036 return TDM_ERROR_NONE;
1040 _tdm_test_server_cb_output_change(tdm_output *output, tdm_output_change_type type, tdm_value value, void *user_data)
1042 tdm_test_server_voutput *voutput = NULL;
1043 tdm_test_server *data = NULL;
1044 const tdm_output_mode *mode;
1045 tdm_output_conn_status status;
1046 tdm_error ret = TDM_ERROR_NONE;
1048 voutput = (tdm_test_server_voutput *)user_data;
1049 TDM_EXIT_IF_FAIL(voutput != NULL);
1051 data = voutput->data;
1054 case TDM_OUTPUT_CHANGE_CONNECTION:
1055 status = (tdm_output_conn_status)value.u32;
1056 if (status == TDM_OUTPUT_CONN_STATUS_CONNECTED) {
1057 _voutput_connect(voutput);
1058 _voutput_layer_init(voutput);
1060 tdm_display_lock(data->display);
1061 ret = tdm_event_loop_source_timer_update(voutput->timer, 10);
1062 tdm_display_unlock(data->display);
1063 TDM_EXIT_IF_FAIL(ret == TDM_ERROR_NONE);
1064 } else if (status == TDM_OUTPUT_CONN_STATUS_DISCONNECTED) {
1065 _voutput_disconnect(voutput);
1066 } else if (status == TDM_OUTPUT_CONN_STATUS_MODE_SETTED) {
1067 ret = tdm_output_get_mode(output, &mode);
1068 TDM_EXIT_IF_FAIL(ret == TDM_ERROR_NONE);
1070 printf("mode setted (%dx%d, %d)\n", mode->hdisplay, mode->vdisplay, mode->vrefresh);
1080 _tdm_test_server_cb_output_mode_change(tdm_output *output, unsigned int index, void *user_data)
1082 tdm_test_server_voutput *voutput = NULL;
1083 const tdm_output_mode *modes, *mode;
1087 voutput = (tdm_test_server_voutput *)user_data;
1088 TDM_EXIT_IF_FAIL(voutput != NULL);
1090 ret = tdm_output_get_available_modes(output, &modes, &count);
1091 TDM_RETURN_IF_FAIL(ret == TDM_ERROR_NONE);
1092 TDM_RETURN_IF_FAIL(index < count);
1095 mode = &modes[index];
1097 if (mode == voutput->current_mode) return;
1099 voutput->need_mode_change = 1;
1100 voutput->mode_index = index;
1102 printf("request mode change to %d (%dx%d, %d) from (%dx%d, %d)\n",
1103 index, mode->hdisplay, mode->vdisplay, mode->vrefresh,
1104 voutput->current_mode->hdisplay, voutput->current_mode->vdisplay, voutput->current_mode->vrefresh);
1108 _tdm_output_cb_destroy_handler(tdm_output *output, void *user_data)
1110 tdm_test_server_voutput *voutput = NULL;
1112 voutput = (tdm_test_server_voutput *)user_data;
1113 TDM_EXIT_IF_FAIL(voutput != NULL);
1115 tdm_output_remove_mode_change_request_handler(output, _tdm_test_server_cb_output_mode_change, voutput);
1116 tdm_output_remove_change_handler(output, _tdm_test_server_cb_output_change, voutput);
1117 tdm_output_remove_destroy_handler(output, _tdm_output_cb_destroy_handler, voutput);
1119 LIST_DEL(&voutput->link);
1121 _voutput_buff_deinit(voutput);
1123 printf("voutput: %p destroy\n", voutput);
1129 _tdm_output_cb_create_handler(tdm_display *dpy, tdm_output *output, void *user_data)
1131 tdm_test_server *data;
1132 tdm_test_server_voutput *voutput = NULL;
1133 tdm_error ret = TDM_ERROR_NONE;
1135 printf("voutput create call\n");
1137 data = (tdm_test_server *)user_data;
1138 TDM_EXIT_IF_FAIL(data != NULL);
1140 voutput = calloc(1, sizeof *voutput);
1141 TDM_EXIT_IF_FAIL(voutput != NULL);
1143 ret = tdm_output_add_change_handler(output, _tdm_test_server_cb_output_change, voutput);
1144 TDM_EXIT_IF_FAIL(ret == TDM_ERROR_NONE);
1146 ret = tdm_output_add_mode_change_request_handler(output, _tdm_test_server_cb_output_mode_change, voutput);
1147 TDM_EXIT_IF_FAIL(ret == TDM_ERROR_NONE);
1149 ret = tdm_output_add_destroy_handler(output, _tdm_output_cb_destroy_handler, voutput);
1150 TDM_EXIT_IF_FAIL(ret == TDM_ERROR_NONE);
1152 voutput->output = output;
1153 voutput->data = data;
1155 tdm_display_lock(data->display);
1156 voutput->timer = tdm_event_loop_add_timer_handler(data->display, _voutput_buffer_send, voutput, &ret);
1157 tdm_display_unlock(data->display);
1158 TDM_EXIT_IF_FAIL(ret == TDM_ERROR_NONE);
1160 printf("voutput %p create done\n", voutput);
1162 LIST_ADDTAIL(&voutput->link, &data->voutput_list);
1166 destroy(tdm_test_server *data)
1168 tdm_test_server_output *o = NULL, *oo = NULL;
1169 tdm_test_server_layer *l = NULL, *ll = NULL;
1170 tdm_test_server_pp *p = NULL, *pp = NULL;
1171 tdm_test_server_capture *c = NULL, *cc = NULL;
1172 tdm_test_server_prop *w = NULL, *ww = NULL;
1173 tdm_test_server_voutput *v = NULL, *vv = NULL;
1177 LIST_FOR_EACH_ENTRY_SAFE(c, cc, &data->capture_list, link) {
1179 tdm_capture_destroy(c->capture);
1183 LIST_FOR_EACH_ENTRY_SAFE(p, pp, &data->pp_list, link) {
1184 tdm_display_lock(data->display);
1185 tdm_event_loop_source_remove(p->timer_source);
1186 tdm_display_unlock(data->display);
1188 tdm_pp_destroy(p->pp);
1191 LIST_FOR_EACH_ENTRY_SAFE(o, oo, &data->output_list, link) {
1192 LIST_FOR_EACH_ENTRY_SAFE(l, ll, &o->layer_list, link) {
1193 ret = tdm_layer_unset_buffer(l->layer);
1194 TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE);
1196 ret = tdm_layer_commit(l->layer, NULL, NULL);
1197 TDM_EXIT_IF_FAIL(ret == TDM_ERROR_NONE);
1200 LIST_FOR_EACH_ENTRY_SAFE(p, pp, &data->pp_list, link) {
1202 for (i = 0; i < TDM_ARRAY_SIZE(p->bufs); i++)
1203 tbm_surface_destroy(p->bufs[i]);
1207 LIST_FOR_EACH_ENTRY_SAFE(o, oo, &data->output_list, link) {
1209 LIST_FOR_EACH_ENTRY_SAFE(l, ll, &o->layer_list, link) {
1211 LIST_FOR_EACH_ENTRY_SAFE(w, ww, &l->prop_list, link) {
1215 for (i = 0; i < TDM_ARRAY_SIZE(l->bufs); i++)
1216 tbm_surface_destroy(l->bufs[i]);
1219 LIST_FOR_EACH_ENTRY_SAFE(w, ww, &o->prop_list, link) {
1227 LIST_FOR_EACH_ENTRY_SAFE(v, vv, &data->voutput_list, link) {
1228 _voutput_buff_deinit(v);
1233 if (data->do_voutput)
1234 tdm_display_remove_output_create_handler(data->display, _tdm_output_cb_create_handler, data);
1237 tdm_display_deinit(data->display);
1243 main(int argc, char *argv[])
1245 tdm_test_server *data = &tts_data;
1246 char temp[TDM_SERVER_REPLY_MSG_LEN];
1247 int len = sizeof temp;
1250 #if 1 /* for testing */
1251 const char *s = (const char*)getenv("XDG_RUNTIME_DIR");
1254 snprintf(buf, sizeof(buf), "/run");
1255 int ret = setenv("XDG_RUNTIME_DIR", (const char*)buf, 1);
1260 s = (const char*)getenv("TBM_DISPLAY_SERVER");
1263 snprintf(buf, sizeof(buf), "1");
1264 int ret = setenv("TBM_DISPLAY_SERVER", (const char*)buf, 1);
1270 memset(data, 0, sizeof * data);
1271 LIST_INITHEAD(&data->output_list);
1272 LIST_INITHEAD(&data->pp_list);
1273 LIST_INITHEAD(&data->capture_list);
1274 LIST_INITHEAD(&data->voutput_list);
1277 data->bflags = TBM_BO_SCANOUT;
1278 data->b_fill = PATTERN_SMPTE;
1280 data->display = tdm_display_init(&ret);
1281 TDM_EXIT_IF_FAIL(data->display != NULL);
1283 parse_args(data, argc, argv);
1284 interpret_args(data);
1286 if (data->do_query) {
1287 tdm_helper_get_display_information(data->display, temp, &len);
1292 if (data->do_voutput) {
1293 printf("support virtual output - server\n");
1294 ret = tdm_display_add_output_create_handler(data->display, _tdm_output_cb_create_handler, data);
1295 TDM_EXIT_IF_FAIL(ret == TDM_ERROR_NONE);
1301 tdm_display_deinit(data->display);
1307 output_setup(tdm_test_server_output *o)
1309 tdm_test_server *data = o->data;
1310 const tdm_output_mode *modes, *found = NULL, *best = NULL, *prefer = NULL;
1311 tdm_test_server_prop *w = NULL;
1312 const tdm_prop *props;
1316 o->output = tdm_display_get_output(data->display, o->idx, &ret);
1317 TDM_EXIT_IF_FAIL(ret == TDM_ERROR_NONE);
1319 ret = tdm_output_get_available_modes(o->output, &modes, &count);
1320 TDM_EXIT_IF_FAIL(ret == TDM_ERROR_NONE);
1322 for (i = 0; i < count; i++) {
1323 if (!strncmp(o->mode, modes[i].name, TDM_NAME_LEN) && o->refresh == modes[i].vrefresh) {
1325 printf("found mode: %dx%d %d\n", found->hdisplay, found->vdisplay, found->vrefresh);
1330 if (modes[i].type & TDM_OUTPUT_MODE_TYPE_PREFERRED)
1333 if (!found && prefer) {
1335 printf("found prefer mode: %dx%d %d\n", found->hdisplay, found->vdisplay, found->vrefresh);
1337 if (!found && best) {
1339 printf("found best mode: %dx%d %d\n", found->hdisplay, found->vdisplay, found->vrefresh);
1343 printf("couldn't find any mode\n");
1347 ret = tdm_output_set_mode(o->output, found);
1348 TDM_EXIT_IF_FAIL(ret == TDM_ERROR_NONE);
1350 printf("output %d: %s %d\n", o->idx, found->name, found->vrefresh);
1352 ret = tdm_output_get_available_properties(o->output, &props, &count);
1353 TDM_EXIT_IF_FAIL(ret == TDM_ERROR_NONE);
1355 LIST_FOR_EACH_ENTRY(w, &o->prop_list, link) {
1356 for (i = 0; i < count; i++) {
1357 if (strncmp(w->name, props[i].name, TDM_NAME_LEN))
1359 ret = tdm_output_set_property(o->output, props[i].id, w->value);
1360 TDM_EXIT_IF_FAIL(ret == TDM_ERROR_NONE);
1361 printf("\tprop '%s': %d\n", props[i].name, w->value.u32);
1366 /* DPMS on forcely at the first time. */
1367 ret = tdm_output_set_dpms(o->output, TDM_OUTPUT_DPMS_ON);
1368 TDM_EXIT_IF_FAIL(ret == TDM_ERROR_NONE);
1371 static tbm_surface_h
1372 layer_get_buffer(tdm_test_server_layer *l)
1374 int i, size = TDM_ARRAY_SIZE(l->bufs);
1376 for (i = 0; i < size; i++) {
1377 int width = (l->info.src_config.size.h) ? : l->info.src_config.pos.w;
1378 int height = (l->info.src_config.size.v) ? : l->info.src_config.pos.h;
1379 unsigned int format = (l->info.src_config.format) ? : DEFAULT_FORMAT;
1380 int flags = l->o->data->bflags;
1381 tbm_surface_h b = buffer_allocate(width, height, format, flags);
1382 TDM_EXIT_IF_FAIL(b != NULL);
1386 for (i = 0; i < size; i++) {
1387 tdm_test_server_buffer *tb = get_tts_buffer(l->bufs[i]);
1388 TDM_EXIT_IF_FAIL(tb != NULL);
1392 printf("no available layer buffer.\n");
1397 layer_cb_commit(tdm_layer *layer, unsigned int sequence,
1398 unsigned int tv_sec, unsigned int tv_usec,
1401 tdm_test_server_layer *l = user_data;
1402 tbm_surface_h b = layer_get_buffer(l);
1403 TDM_EXIT_IF_FAIL(b != NULL);
1405 if (!l->is_primary || l->o->fill_primary_layer)
1406 tdm_test_buffer_fill(b, l->data->b_fill);
1408 if (!l->is_primary || l->o->fill_primary_layer)
1409 layer_show_buffer(l, b);
1413 layer_cb_buffer_release(tbm_surface_h b, void *user_data)
1415 tdm_test_server_buffer *tb = get_tts_buffer(b);
1416 TDM_EXIT_IF_FAIL(tb != NULL);
1419 tdm_buffer_remove_release_handler(b, layer_cb_buffer_release, NULL);
1421 tb->done(b, user_data);
1425 layer_show_buffer(tdm_test_server_layer *l, tbm_surface_h b)
1427 tdm_test_server *data = l->o->data;
1428 tdm_test_server_buffer *tb;
1431 ret = tdm_layer_set_buffer(l->layer, b);
1432 TDM_EXIT_IF_FAIL(ret == TDM_ERROR_NONE);
1434 tb = get_tts_buffer(b);
1435 TDM_EXIT_IF_FAIL(tb != NULL);
1438 ret = tdm_buffer_add_release_handler(b, layer_cb_buffer_release, NULL);
1439 TDM_EXIT_IF_FAIL(ret == TDM_ERROR_NONE);
1441 if (data->do_vblank)
1442 ret = tdm_layer_commit(l->layer, layer_cb_commit, l);
1444 ret = tdm_layer_commit(l->layer, NULL, NULL);
1445 TDM_EXIT_IF_FAIL(ret == TDM_ERROR_NONE);
1447 printf("show:\tl(%p) b(%p)\n", l, b);
1451 layer_setup(tdm_test_server_layer *l, tbm_surface_h b)
1453 tdm_test_server_prop *w = NULL;
1454 const tdm_prop *props;
1457 tbm_surface_info_s info;
1459 l->layer = tdm_output_get_layer(l->o->output, l->idx, &ret);
1460 TDM_EXIT_IF_FAIL(ret == TDM_ERROR_NONE);
1462 /* The size and format information should be same with buffer's */
1463 tbm_surface_get_info(b, &info);
1464 if (IS_RGB(info.format)) {
1465 l->info.src_config.size.h = info.planes[0].stride >> 2;
1466 l->info.src_config.size.v = info.height;
1468 l->info.src_config.size.h = info.planes[0].stride;
1469 l->info.src_config.size.v = info.height;
1471 l->info.src_config.format = info.format;
1473 ret = tdm_layer_set_info(l->layer, &l->info);
1474 TDM_EXIT_IF_FAIL(ret == TDM_ERROR_NONE);
1476 printf("layer %d: output(%d) ", l->idx, l->o->idx);
1477 print_config(&l->info.src_config);
1479 print_pos(&l->info.dst_pos);
1480 printf(" transform(%s)\n", tdm_transform_str(l->info.transform));
1482 ret = tdm_layer_get_available_properties(l->layer, &props, &count);
1483 TDM_EXIT_IF_FAIL(ret == TDM_ERROR_NONE);
1485 LIST_FOR_EACH_ENTRY(w, &l->prop_list, link) {
1486 for (i = 0; i < count; i++) {
1487 if (strncmp(w->name, props[i].name, TDM_NAME_LEN))
1489 ret = tdm_layer_set_property(l->layer, props[i].id, w->value);
1490 TDM_EXIT_IF_FAIL(ret == TDM_ERROR_NONE);
1491 printf("\tprop '%s': %d\n", props[i].name, w->value.u32);
1497 static tbm_surface_h
1498 pp_get_buffer(tdm_test_server_pp *p)
1500 int i, size = TDM_ARRAY_SIZE(p->bufs);
1502 for (i = 0; i < size; i++) {
1503 int width = (p->info.src_config.size.h) ? : p->info.src_config.pos.w;
1504 int height = (p->info.src_config.size.v) ? : p->info.src_config.pos.h;
1505 unsigned int format = (p->info.src_config.format) ? : DEFAULT_FORMAT;
1506 tbm_surface_h b = buffer_allocate(width, height, format, 0);
1507 TDM_EXIT_IF_FAIL(b != NULL);
1511 for (i = 0; i < size; i++) {
1512 tdm_test_server_buffer *tb = get_tts_buffer(p->bufs[i]);
1518 tdm_test_buffer_fill(p->bufs[i], p->data->b_fill);
1522 printf("no available pp buffer.\n");
1527 pp_cb_done(tdm_pp *pp, tbm_surface_h sb, tbm_surface_h db, void *user_data)
1529 tdm_test_server_buffer *stb, *dtb;
1531 stb = get_tts_buffer(sb);
1532 TDM_EXIT_IF_FAIL(stb != NULL);
1534 dtb = get_tts_buffer(db);
1535 TDM_EXIT_IF_FAIL(dtb != NULL);
1537 stb->in_use = dtb->in_use = 0;
1539 layer_show_buffer(dtb->l, db);
1543 pp_convert_buffer(tdm_test_server_pp *p, tbm_surface_h sb, tbm_surface_h db)
1545 tdm_test_server_buffer *stb, *dtb;
1548 stb = get_tts_buffer(sb);
1549 TDM_EXIT_IF_FAIL(stb != NULL);
1551 dtb = get_tts_buffer(db);
1552 TDM_EXIT_IF_FAIL(dtb != NULL);
1554 stb->in_use = dtb->in_use = 1;
1557 ret = tdm_pp_attach(p->pp, sb, db);
1558 TDM_EXIT_IF_FAIL(ret == TDM_ERROR_NONE);
1560 ret = tdm_pp_commit(p->pp);
1561 TDM_EXIT_IF_FAIL(ret == TDM_ERROR_NONE);
1563 printf("convt:\tp(%p) sb(%p) db(%p)\n", p, sb, db);
1566 /* tdm_event_loop_xxx() function is not for the display server. It's for TDM
1567 * backend module. I use them only for simulating the video play. When we call
1568 * tdm_event_loop_xxx() outside of TDM backend module, we have to lock/unlock
1569 * the TDM display. And when the callback function of tdm_event_loop_xxx() is
1570 * called, the display has been already locked. So in this test application,
1571 * we have to unlock/lock the display for testing.
1574 pp_cb_timeout(void *user_data)
1576 tdm_test_server_pp *p = user_data;
1577 tdm_test_server *data = p->l->o->data;
1578 tbm_surface_h sb, db;
1581 tdm_display_unlock(data->display);
1583 sb = pp_get_buffer(p);
1584 TDM_EXIT_IF_FAIL(sb != NULL);
1585 db = layer_get_buffer(p->l);
1586 TDM_EXIT_IF_FAIL(db != NULL);
1588 pp_convert_buffer(p, sb, db);
1590 tdm_display_lock(data->display);
1591 ret = tdm_event_loop_source_timer_update(p->timer_source, 1000 / p->fps);
1592 tdm_display_unlock(data->display);
1593 TDM_EXIT_IF_FAIL(ret == TDM_ERROR_NONE);
1595 tdm_display_lock(data->display);
1597 return TDM_ERROR_NONE;
1601 pp_setup(tdm_test_server_pp *p, tbm_surface_h sb, tbm_surface_h db)
1603 tdm_test_server *data;
1604 tbm_surface_info_s info;
1607 if (!p || !p->l || !p->l->o || !p->l->o->data) {
1608 TDM_ERR("invalid parameter failed");
1611 data = p->l->o->data;
1613 p->pp = tdm_display_create_pp(data->display, &ret);
1614 TDM_EXIT_IF_FAIL(ret == TDM_ERROR_NONE);
1616 /* The size and format information should be same with buffer's */
1617 tbm_surface_get_info(sb, &info);
1618 if (IS_RGB(info.format)) {
1619 p->info.src_config.size.h = info.planes[0].stride >> 2;
1620 p->info.src_config.size.v = info.height;
1622 p->info.src_config.size.h = info.planes[0].stride;
1623 p->info.src_config.size.v = info.height;
1625 p->info.src_config.format = info.format;
1627 /* The size and format information should be same with buffer's */
1628 tbm_surface_get_info(db, &info);
1629 if (IS_RGB(info.format)) {
1630 p->info.dst_config.size.h = info.planes[0].stride >> 2;
1631 p->info.dst_config.size.v = info.height;
1633 p->info.dst_config.size.h = info.planes[0].stride;
1634 p->info.dst_config.size.v = info.height;
1636 p->info.dst_config.format = info.format;
1638 ret = tdm_pp_set_info(p->pp, &p->info);
1639 TDM_EXIT_IF_FAIL(ret == TDM_ERROR_NONE);
1641 ret = tdm_pp_set_done_handler(p->pp, pp_cb_done, NULL);
1642 TDM_EXIT_IF_FAIL(ret == TDM_ERROR_NONE);
1645 print_config(&p->info.src_config);
1647 print_config(&p->info.dst_config);
1648 printf(" fps(%d) transform(%s)\n", p->fps, tdm_transform_str(p->info.transform));
1649 printf("\toutput_idx(%d) layer_idx(%d)\n", p->l->o->idx, p->l->idx);
1651 layer_setup(p->l, db);
1653 /* tdm_event_loop_xxx() function is not for the display server. It's for TDM
1654 * backend module. I use them only for simulating the video play. When we call
1655 * tdm_event_loop_xxx() outside of TDM backend module, we have to lock/unlock
1656 * the TDM display. And when the callback function of tdm_event_loop_xxx() is
1657 * called, the display has been already locked. So in this test application,
1658 * we have to unlock/lock the display for testing.
1660 tdm_display_lock(data->display);
1661 p->timer_source = tdm_event_loop_add_timer_handler(data->display, pp_cb_timeout, p, &ret);
1662 tdm_display_unlock(data->display);
1663 TDM_EXIT_IF_FAIL(ret == TDM_ERROR_NONE);
1665 tdm_display_lock(data->display);
1666 ret = tdm_event_loop_source_timer_update(p->timer_source, 1000 / p->fps);
1667 tdm_display_unlock(data->display);
1668 TDM_EXIT_IF_FAIL(ret == TDM_ERROR_NONE);
1672 capture_cb_buffer_done(tbm_surface_h b, void *user_data)
1674 tdm_test_server_buffer *tb;
1676 tb = get_tts_buffer(b);
1677 TDM_EXIT_IF_FAIL(tb != NULL);
1679 capture_attach(tb->c, b);
1683 capture_cb_done(tdm_capture *capture, tbm_surface_h b, void *user_data)
1685 tdm_test_server_buffer *tb;
1687 tb = get_tts_buffer(b);
1688 TDM_EXIT_IF_FAIL(tb != NULL);
1692 tb->done = capture_cb_buffer_done;
1693 layer_show_buffer(tb->l, b);
1697 capture_attach(tdm_test_server_capture *c, tbm_surface_h b)
1700 tdm_test_server_buffer *tb;
1702 tb = get_tts_buffer(b);
1703 TDM_EXIT_IF_FAIL(tb != NULL);
1709 ret = tdm_capture_attach(c->capture, b);
1710 TDM_EXIT_IF_FAIL(ret == TDM_ERROR_NONE);
1712 printf("capture:\tc(%p) b(%p)\n", c, b);
1714 ret = tdm_capture_commit(c->capture);
1715 TDM_EXIT_IF_FAIL(ret == TDM_ERROR_NONE);
1719 capture_setup(tdm_test_server_capture *c, tbm_surface_h b)
1721 tdm_test_server *data;
1724 tbm_surface_info_s info;
1727 if (!c || !c->l || !c->l->o || !c->l->o->data) {
1728 TDM_ERR("invalid parameter failed");
1731 data = c->l->o->data;
1733 if (c->output_idx != -1 && c->layer_idx == -1) {
1734 output = tdm_display_get_output(data->display, c->output_idx, &ret);
1735 TDM_EXIT_IF_FAIL(ret == TDM_ERROR_NONE);
1736 c->capture = tdm_output_create_capture(output, &ret);
1737 TDM_EXIT_IF_FAIL(ret == TDM_ERROR_NONE);
1738 } else if (c->output_idx != -1 && c->layer_idx != -1) {
1739 output = tdm_display_get_output(data->display, c->output_idx, &ret);
1740 TDM_EXIT_IF_FAIL(ret == TDM_ERROR_NONE);
1741 layer = tdm_output_get_layer(output, c->layer_idx, &ret);
1742 TDM_EXIT_IF_FAIL(ret == TDM_ERROR_NONE);
1743 c->capture = tdm_layer_create_capture(layer, &ret);
1744 TDM_EXIT_IF_FAIL(ret == TDM_ERROR_NONE);
1747 TDM_EXIT_IF_FAIL(c->capture != NULL);
1749 /* The size and format information should be same with buffer's */
1750 tbm_surface_get_info(b, &info);
1751 if (IS_RGB(info.format)) {
1752 c->info.dst_config.size.h = info.planes[0].stride >> 2;
1753 c->info.dst_config.size.v = info.height;
1755 c->info.dst_config.size.h = info.planes[0].stride;
1756 c->info.dst_config.size.v = info.height;
1758 c->info.dst_config.format = info.format;
1759 c->info.type = TDM_CAPTURE_TYPE_ONESHOT;
1761 ret = tdm_capture_set_info(c->capture, &c->info);
1762 TDM_EXIT_IF_FAIL(ret == TDM_ERROR_NONE);
1764 ret = tdm_capture_set_done_handler(c->capture, capture_cb_done, NULL);
1765 TDM_EXIT_IF_FAIL(ret == TDM_ERROR_NONE);
1767 printf("capture: o(%d) l(%d) ", c->output_idx, c->layer_idx);
1768 print_config(&c->info.dst_config);
1769 printf(" transform(%s)\n", tdm_transform_str(c->info.transform));
1770 printf("\toutput_idx(%d) layer_idx(%d)\n", c->l->o->idx, c->l->idx);
1772 layer_setup(c->l, b);
1776 run_test(tdm_test_server *data)
1778 tdm_test_server_output *o = NULL;
1779 tdm_test_server_layer *l = NULL;
1780 tdm_test_server_pp *p = NULL;
1781 tdm_test_server_capture *c = NULL;
1782 tdm_display_capability caps;
1785 ret = tdm_display_get_capabilities(data->display, &caps);
1786 TDM_EXIT_IF_FAIL(ret == TDM_ERROR_NONE);
1788 LIST_FOR_EACH_ENTRY(o, &data->output_list, link) {
1789 LIST_FOR_EACH_ENTRY(l, &o->layer_list, link) {
1790 if (!l->owner_p && !l->owner_c) {
1792 b = layer_get_buffer(l);
1793 if (!l->is_primary || l->o->fill_primary_layer)
1794 tdm_test_buffer_fill(b, data->b_fill);
1796 layer_show_buffer(l, b);
1801 LIST_FOR_EACH_ENTRY(p, &data->pp_list, link) {
1802 tbm_surface_h sb, db;
1803 TDM_GOTO_IF_FAIL(caps & TDM_DISPLAY_CAPABILITY_PP, no_pp);
1804 sb = pp_get_buffer(p);
1805 TDM_EXIT_IF_FAIL(sb != NULL);
1806 db = layer_get_buffer(p->l);
1807 TDM_EXIT_IF_FAIL(db != NULL);
1808 pp_setup(p, sb, db);
1809 pp_convert_buffer(p, sb, db);
1812 LIST_FOR_EACH_ENTRY(c, &data->capture_list, link) {
1813 TDM_GOTO_IF_FAIL(caps & TDM_DISPLAY_CAPABILITY_CAPTURE, no_capture);
1815 b = layer_get_buffer(c->l);
1816 capture_setup(c, b);
1817 capture_attach(c, b);
1818 b = layer_get_buffer(c->l);
1819 capture_attach(c, b);
1820 b = layer_get_buffer(c->l);
1821 capture_attach(c, b);
1824 printf("enter test loop\n");
1827 ret = tdm_display_handle_events(data->display);
1828 TDM_EXIT_IF_FAIL(ret == TDM_ERROR_NONE);
1835 printf("no PP capability\n");
1838 printf("no Capture capability\n");