6 #include "pixman-helper.h"
7 #include "pixman-tbm-helper.h"
8 #include "tinyds-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);
73 renderer_cursor_create(struct tinyds_renderer *renderer,
74 uint8_t r, uint8_t g, uint8_t b, uint32_t width, uint32_t height)
78 pthread_mutex_lock(&renderer->mutex);
80 color_rgb888(&color, r, g, b);
82 renderer->cursor_image = pixman_image_create_solid_fill(&color);
83 assert(renderer->cursor_image);
85 renderer->damaged = true;
87 renderer->cursor.w = width;
88 renderer->cursor.h = height;
90 pthread_mutex_unlock(&renderer->mutex);
94 renderer_cursor_destroy(struct tinyds_renderer *renderer)
96 pthread_mutex_lock(&renderer->mutex);
98 if (renderer->cursor_image)
100 pixman_image_unref(renderer->cursor_image);
101 renderer->cursor_image = NULL;
104 renderer->damaged = true;
106 pthread_mutex_unlock(&renderer->mutex);
110 renderer_cursor_update(struct tinyds_renderer *renderer,
111 uint32_t x, uint32_t y)
113 pthread_mutex_lock(&renderer->mutex);
115 renderer->cursor.x = x;
116 renderer->cursor.y = y;
118 pthread_mutex_unlock(&renderer->mutex);
123 renderer_add_texture(struct tinyds_renderer *renderer,
124 tbm_surface_h tbm_surface, int x, int y)
126 struct tinyds_texture *texture;
128 pthread_mutex_lock(&renderer->mutex);
130 texture = calloc(1, sizeof *texture);
134 texture->renderer = renderer;
135 texture->surface = tbm_surface;
136 texture->image = pixman_image_from_tbm_surface(tbm_surface,
137 DS_BUFFER_DATA_PTR_ACCESS_READ);
139 wl_list_insert(renderer->textures.prev, &texture->link);
141 ds_dbg("Add texture(%p)", texture);
143 pthread_mutex_unlock(&renderer->mutex);
147 renderer_draw(struct tinyds_renderer *renderer)
149 pthread_mutex_lock(&renderer->mutex);
151 renderer->damaged = true;
152 pthread_cond_signal(&renderer->cond);
154 pthread_mutex_unlock(&renderer->mutex);
158 renderer_setup_thread(struct tinyds_renderer *renderer)
160 pthread_mutex_init(&renderer->mutex, NULL);
161 pthread_cond_init(&renderer->cond, NULL);
162 pthread_create(&renderer->worker_thread, NULL,
163 renderer_thread_func, renderer);
167 renderer_thread_func(void *data)
169 struct tinyds_renderer *renderer = data;
170 struct tinyds_texture *texture, *texture_tmp;
171 pixman_image_t *dst_image;
172 tbm_surface_h surface;
173 tbm_surface_queue_error_e err;
175 pthread_mutex_lock(&renderer->mutex);
177 while (!renderer->destroying) {
178 if (!renderer->damaged)
179 pthread_cond_wait(&renderer->cond, &renderer->mutex);
181 if (!renderer->damaged)
184 if (!tbm_surface_queue_can_dequeue(renderer->surface_queue, 0))
187 ds_dbg(">> BEGIN DRAW");
189 err = tbm_surface_queue_dequeue(renderer->surface_queue, &surface);
190 assert(err == TBM_SURFACE_QUEUE_ERROR_NONE);
192 dst_image = pixman_image_from_tbm_surface(surface,
193 DS_BUFFER_DATA_PTR_ACCESS_WRITE);
195 if (renderer->bg_image) {
196 pixman_image_composite32(PIXMAN_OP_SRC,
201 pixman_image_get_width(dst_image),
202 pixman_image_get_height(dst_image));
206 if (renderer->cursor_image) {
207 pixman_image_composite32(PIXMAN_OP_OVER,
208 renderer->cursor_image,
212 renderer->cursor.x, renderer->cursor.y,
213 renderer->cursor.w, renderer->cursor.h);
217 wl_list_for_each_safe(texture, texture_tmp, &renderer->textures, link) {
218 ds_dbg("Draw texture(%p)", texture);
219 pixman_image_composite32(PIXMAN_OP_OVER,
224 texture->x, texture->y,
225 pixman_image_get_width(texture->image),
226 pixman_image_get_height(texture->image));
227 texture_destroy(texture);
229 pixman_image_unref(dst_image);
231 err = tbm_surface_queue_enqueue(renderer->surface_queue, surface);
232 assert(err == TBM_SURFACE_QUEUE_ERROR_NONE);
234 renderer->damaged = false;
236 ds_dbg("<< END DRAW");
239 pthread_mutex_unlock(&renderer->mutex);
245 texture_destroy(struct tinyds_texture *texture)
247 pixman_image_unref(texture->image);
248 wl_list_remove(&texture->link);