6 #include "pixman-helper.h"
7 #include "pixman-tbm-helper.h"
8 #include "tinyds-tdm-renderer.h"
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);
15 init_renderer(struct tinyds_renderer *renderer)
17 renderer->damaged = false;
19 wl_list_init(&renderer->textures);
21 renderer_setup_thread(renderer);
27 fini_renderer(struct tinyds_renderer *renderer)
29 pthread_mutex_lock(&renderer->mutex);
31 renderer->destroying = true;
32 pthread_cond_signal(&renderer->cond);
34 pthread_mutex_unlock(&renderer->mutex);
36 pthread_join(renderer->worker_thread, NULL);
38 pthread_mutex_destroy(&renderer->mutex);
39 pthread_cond_destroy(&renderer->cond);
43 renderer_set_surface_queue(struct tinyds_renderer *renderer,
46 pthread_mutex_lock(&renderer->mutex);
48 renderer->surface_queue = (tbm_surface_queue_h)surface_queue;
50 pthread_mutex_unlock(&renderer->mutex);
54 renderer_set_bg_color(struct tinyds_renderer *renderer,
55 uint8_t r, uint8_t g, uint8_t b)
59 pthread_mutex_lock(&renderer->mutex);
61 color_rgb888(&color, r, g, b);
63 renderer->bg_image = pixman_image_create_solid_fill(&color);
64 assert(renderer->bg_image);
66 renderer->damaged = true;
68 pthread_mutex_unlock(&renderer->mutex);
72 renderer_add_texture(struct tinyds_renderer *renderer,
73 tbm_surface_h tbm_surface, int x, int y)
75 struct tinyds_texture *texture;
77 pthread_mutex_lock(&renderer->mutex);
79 texture = calloc(1, sizeof *texture);
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);
88 wl_list_insert(renderer->textures.prev, &texture->link);
90 ds_dbg("Add texture(%p)", texture);
92 pthread_mutex_unlock(&renderer->mutex);
96 renderer_draw(struct tinyds_renderer *renderer)
98 pthread_mutex_lock(&renderer->mutex);
100 renderer->damaged = true;
101 pthread_cond_signal(&renderer->cond);
103 pthread_mutex_unlock(&renderer->mutex);
107 renderer_setup_thread(struct tinyds_renderer *renderer)
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);
116 renderer_thread_func(void *data)
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;
124 pthread_mutex_lock(&renderer->mutex);
126 while (!renderer->destroying) {
127 if (!renderer->damaged)
128 pthread_cond_wait(&renderer->cond, &renderer->mutex);
130 if (!renderer->damaged)
133 if (!tbm_surface_queue_can_dequeue(renderer->surface_queue, 0))
136 ds_dbg(">> BEGIN DRAW");
138 err = tbm_surface_queue_dequeue(renderer->surface_queue, &surface);
139 assert(err == TBM_SURFACE_QUEUE_ERROR_NONE);
141 dst_image = pixman_image_from_tbm_surface(surface,
142 DS_BUFFER_DATA_PTR_ACCESS_WRITE);
144 if (renderer->bg_image) {
145 pixman_image_composite32(PIXMAN_OP_SRC,
150 pixman_image_get_width(dst_image),
151 pixman_image_get_height(dst_image));
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,
161 texture->x, texture->y,
162 pixman_image_get_width(texture->image),
163 pixman_image_get_height(texture->image));
164 texture_destroy(texture);
166 pixman_image_unref(dst_image);
168 err = tbm_surface_queue_enqueue(renderer->surface_queue, surface);
169 assert(err == TBM_SURFACE_QUEUE_ERROR_NONE);
171 renderer->damaged = false;
173 ds_dbg("<< END DRAW");
176 pthread_mutex_unlock(&renderer->mutex);
182 texture_destroy(struct tinyds_texture *texture)
184 pixman_image_unref(texture->image);
185 wl_list_remove(&texture->link);