test: adapt the change of policy request
[platform/core/uifw/libds-tizen.git] / examples / tinyds-tdm-renderer.c
1 #include <assert.h>
2 #include <stdlib.h>
3
4 #include <libds/log.h>
5
6 #include "pixman-helper.h"
7 #include "pixman-tbm-helper.h"
8 #include "tinyds-tdm-renderer.h"
9
10 static void renderer_setup_thread(struct tinyds_renderer *renderer);
11 static void *renderer_thread_func(void *data);
12 static void texture_destroy(struct tinyds_texture *texture);
13
14 bool
15 init_renderer(struct tinyds_renderer *renderer)
16 {
17     renderer->damaged = false;
18
19     wl_list_init(&renderer->textures);
20
21     renderer_setup_thread(renderer);
22
23     return true;
24 }
25
26 void
27 fini_renderer(struct tinyds_renderer *renderer)
28 {
29     pthread_mutex_lock(&renderer->mutex);
30
31     renderer->destroying = true;
32     pthread_cond_signal(&renderer->cond);
33
34     pthread_mutex_unlock(&renderer->mutex);
35
36     pthread_join(renderer->worker_thread, NULL);
37
38     pthread_mutex_destroy(&renderer->mutex);
39     pthread_cond_destroy(&renderer->cond);
40 }
41
42 void
43 renderer_set_surface_queue(struct tinyds_renderer *renderer,
44         void *surface_queue)
45 {
46     pthread_mutex_lock(&renderer->mutex);
47
48     renderer->surface_queue = (tbm_surface_queue_h)surface_queue;
49
50     pthread_mutex_unlock(&renderer->mutex);
51 }
52
53 void
54 renderer_set_bg_color(struct tinyds_renderer *renderer,
55         uint8_t r, uint8_t g, uint8_t b)
56 {
57     pixman_color_t color;
58
59     pthread_mutex_lock(&renderer->mutex);
60
61     color_rgb888(&color, r, g, b);
62
63     renderer->bg_image = pixman_image_create_solid_fill(&color);
64     assert(renderer->bg_image);
65
66     renderer->damaged = true;
67
68     pthread_mutex_unlock(&renderer->mutex);
69 }
70
71 void
72 renderer_add_texture(struct tinyds_renderer *renderer,
73         tbm_surface_h tbm_surface, int x, int y)
74 {
75     struct tinyds_texture *texture;
76
77     pthread_mutex_lock(&renderer->mutex);
78
79     texture = calloc(1, sizeof *texture);
80
81     texture->x = x;
82     texture->y = y;
83     texture->renderer = renderer;
84     texture->surface = tbm_surface;
85     texture->image = pixman_image_from_tbm_surface(tbm_surface,
86             DS_BUFFER_DATA_PTR_ACCESS_READ);
87
88     wl_list_insert(renderer->textures.prev, &texture->link);
89
90     ds_dbg("Add texture(%p)", texture);
91
92     pthread_mutex_unlock(&renderer->mutex);
93 }
94
95 void
96 renderer_draw(struct tinyds_renderer *renderer)
97 {
98     pthread_mutex_lock(&renderer->mutex);
99
100     renderer->damaged = true;
101     pthread_cond_signal(&renderer->cond);
102
103     pthread_mutex_unlock(&renderer->mutex);
104 }
105
106 static void
107 renderer_setup_thread(struct tinyds_renderer *renderer)
108 {
109     pthread_mutex_init(&renderer->mutex, NULL);
110     pthread_cond_init(&renderer->cond, NULL);
111     pthread_create(&renderer->worker_thread, NULL,
112             renderer_thread_func, renderer);
113 }
114
115 static void *
116 renderer_thread_func(void *data)
117 {
118     struct tinyds_renderer *renderer = data;
119     struct tinyds_texture *texture, *texture_tmp;
120     pixman_image_t *dst_image;
121     tbm_surface_h surface;
122     tbm_surface_queue_error_e err;
123
124     pthread_mutex_lock(&renderer->mutex);
125
126     while (!renderer->destroying) {
127         if (!renderer->damaged)
128             pthread_cond_wait(&renderer->cond, &renderer->mutex);
129
130         if (!renderer->damaged)
131             continue;
132
133         if (!tbm_surface_queue_can_dequeue(renderer->surface_queue, 0))
134             continue;
135
136         ds_dbg(">> BEGIN DRAW");
137
138         err = tbm_surface_queue_dequeue(renderer->surface_queue, &surface);
139         assert(err == TBM_SURFACE_QUEUE_ERROR_NONE);
140
141         dst_image = pixman_image_from_tbm_surface(surface,
142                 DS_BUFFER_DATA_PTR_ACCESS_WRITE);
143
144         if (renderer->bg_image) {
145             pixman_image_composite32(PIXMAN_OP_SRC,
146                     renderer->bg_image,
147                     NULL,
148                     dst_image,
149                     0, 0, 0, 0, 0, 0,
150                     pixman_image_get_width(dst_image),
151                     pixman_image_get_height(dst_image));
152         }
153
154         wl_list_for_each_safe(texture, texture_tmp, &renderer->textures, link) {
155             ds_dbg("Draw texture(%p)", texture);
156             pixman_image_composite32(PIXMAN_OP_OVER,
157                     texture->image,
158                     NULL,
159                     dst_image,
160                     0, 0, 0, 0,
161                     texture->x, texture->y,
162                     pixman_image_get_width(texture->image),
163                     pixman_image_get_height(texture->image));
164             texture_destroy(texture);
165         }
166         pixman_image_unref(dst_image);
167
168         err = tbm_surface_queue_enqueue(renderer->surface_queue, surface);
169         assert(err == TBM_SURFACE_QUEUE_ERROR_NONE);
170
171         renderer->damaged = false;
172
173         ds_dbg("<< END DRAW");
174     }
175
176     pthread_mutex_unlock(&renderer->mutex);
177
178     return NULL;
179 }
180
181 static void
182 texture_destroy(struct tinyds_texture *texture)
183 {
184     pixman_image_unref(texture->image);
185     wl_list_remove(&texture->link);
186     free(texture);
187 }