summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDerek Foreman <derekf@osg.samsung.com>2017-11-08 14:33:31 -0600
committerDerek Foreman <derekf@osg.samsung.com>2017-11-08 15:12:51 -0600
commitc2fe37a46dfacdf7f03477ecfe55722f93d93719 (patch)
tree84f7a9b748a50adcb9710ab89d12376bdce4a095
parenta5c7fbd006b5e4e578e2a938a609c2aa79315fc2 (diff)
wayland_shm: Remove old shm code
The new shm code should be equally capable - minus one surface resize optimization that probably didn't buy us much performance at the cost of memory.
-rw-r--r--src/Makefile_Evas.am1
-rw-r--r--src/modules/evas/engines/wayland_shm/evas_shm.c599
2 files changed, 0 insertions, 600 deletions
diff --git a/src/Makefile_Evas.am b/src/Makefile_Evas.am
index e5c3dba..f1d0148 100644
--- a/src/Makefile_Evas.am
+++ b/src/Makefile_Evas.am
@@ -1318,7 +1318,6 @@ WAYLAND_SHM_SOURCES = \
1318modules/evas/engines/wayland_common/Evas_Engine_Wayland.h \ 1318modules/evas/engines/wayland_common/Evas_Engine_Wayland.h \
1319modules/evas/engines/wayland_shm/evas_engine.c \ 1319modules/evas/engines/wayland_shm/evas_engine.c \
1320modules/evas/engines/wayland_shm/evas_engine.h \ 1320modules/evas/engines/wayland_shm/evas_engine.h \
1321modules/evas/engines/wayland_shm/evas_shm.c \
1322modules/evas/engines/wayland_shm/evas_dmabuf.c \ 1321modules/evas/engines/wayland_shm/evas_dmabuf.c \
1323modules/evas/engines/wayland_shm/evas_outbuf.c \ 1322modules/evas/engines/wayland_shm/evas_outbuf.c \
1324static_libs/libdrm/drm_fourcc.h \ 1323static_libs/libdrm/drm_fourcc.h \
diff --git a/src/modules/evas/engines/wayland_shm/evas_shm.c b/src/modules/evas/engines/wayland_shm/evas_shm.c
deleted file mode 100644
index a2ab42c..0000000
--- a/src/modules/evas/engines/wayland_shm/evas_shm.c
+++ /dev/null
@@ -1,599 +0,0 @@
1/* Portions of this code have been derived from Weston
2 *
3 * Copyright © 2008-2012 Kristian Høgsberg
4 * Copyright © 2010-2012 Intel Corporation
5 * Copyright © 2010-2011 Benjamin Franzke
6 * Copyright © 2011-2012 Collabora, Ltd.
7 * Copyright © 2010 Red Hat <mjg@redhat.com>
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice (including the next
17 * paragraph) shall be included in all copies or substantial portions of the
18 * Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26 * DEALINGS IN THE SOFTWARE.
27 */
28
29#include "evas_common_private.h"
30#include "evas_private.h"
31#include "evas_engine.h"
32#include <sys/mman.h>
33
34typedef struct _Shm_Pool Shm_Pool;
35struct _Shm_Pool
36{
37 struct wl_shm_pool *pool;
38 size_t size, used;
39 void *data;
40};
41
42typedef struct _Shm_Data Shm_Data;
43struct _Shm_Data
44{
45 struct wl_buffer *buffer;
46 Shm_Pool *pool;
47 void *map;
48};
49
50typedef struct _Shm_Leaf Shm_Leaf;
51struct _Shm_Leaf
52{
53 int w, h, busy, age;
54 Shm_Data *data;
55 Shm_Pool *resize_pool;
56 Eina_Bool valid : 1;
57 Eina_Bool reconfigure : 1;
58 Eina_Bool drawn : 1;
59};
60
61typedef struct _Shm_Surface Shm_Surface;
62struct _Shm_Surface
63{
64 int w, h;
65 int num_buff;
66 int compositor_version;
67
68 Shm_Leaf leaf[MAX_BUFFERS];
69 Shm_Leaf *current;
70
71 Eina_Bool alpha : 1;
72};
73
74static Eina_Bool _shm_leaf_create(Surface *s, Shm_Leaf *leaf, int w, int h);
75static void _shm_leaf_release(Shm_Leaf *leaf);
76static void _shm_leaf_destroy(Shm_Leaf *leaf);
77
78static struct wl_shm_pool *
79_shm_pool_make(struct wl_shm *shm, int size, void **data)
80{
81 struct wl_shm_pool *pool;
82 int fd = 0;
83 Eina_Tmpstr *fullname;
84 Efl_Vpath_File *file_obj;
85
86 LOGFN(__FILE__, __LINE__, __FUNCTION__);
87
88 /* check for valid wl_shm */
89 if (!shm) return NULL;
90
91 /* create tmp file name */
92 file_obj = efl_vpath_manager_fetch(EFL_VPATH_MANAGER_CLASS,
93 "(:run:)/evas-wayland_shm-XXXXXX");
94 fd = eina_file_mkstemp(efl_vpath_file_result_get(file_obj), &fullname);
95 efl_del(file_obj);
96
97 if (fd < 0)
98 /* try to create tmp file */
99 /* if ((fd = mkstemp(name)) < 0) */
100 {
101 ERR("Could not create temporary file: %m");
102 return NULL;
103 }
104
105 unlink(fullname);
106 eina_tmpstr_del(fullname);
107
108 /* try to truncate file to size */
109 if (ftruncate(fd, size) < 0)
110 {
111 ERR("Could not truncate temporary file: %m");
112 goto fd_err;
113 }
114
115 /* try to mmap the file */
116 *data = mmap(NULL, size, (PROT_READ | PROT_WRITE), MAP_SHARED, fd, 0);
117 if (*data == MAP_FAILED)
118 {
119 ERR("Could not mmap temporary file: %m");
120 goto fd_err;
121 }
122
123 /* NB: Commented out. Used for debugging rendering issues */
124 /* memset(*data, 127, size); */
125
126 /* create wl_shm_pool using fd */
127 pool = wl_shm_create_pool(shm, fd, size);
128
129 close(fd);
130
131 return pool;
132
133fd_err:
134 close(fd);
135 return NULL;
136}
137
138static Shm_Pool *
139_shm_pool_create(struct wl_shm *shm, size_t size)
140{
141 Shm_Pool *pool;
142
143 LOGFN(__FILE__, __LINE__, __FUNCTION__);
144
145 if (!(pool = malloc(sizeof(Shm_Pool)))) return NULL;
146
147 pool->pool = _shm_pool_make(shm, size, &pool->data);
148 if (!pool->pool) goto err;
149
150 pool->size = size;
151 pool->used = 0;
152
153 return pool;
154
155err:
156 free(pool);
157 return NULL;
158}
159
160static void
161_shm_pool_destroy(Shm_Pool *pool)
162{
163 LOGFN(__FILE__, __LINE__, __FUNCTION__);
164
165 munmap(pool->data, pool->size);
166 wl_shm_pool_destroy(pool->pool);
167 free(pool);
168}
169
170static void *
171_shm_pool_allocate(Shm_Pool *pool, size_t size, int *offset)
172{
173 LOGFN(__FILE__, __LINE__, __FUNCTION__);
174
175 if ((pool->used + size) > pool->size)
176 {
177 WRN("Shm Pool Too Small");
178 return NULL;
179 }
180
181 *offset = pool->used;
182 pool->used += size;
183
184 return (char *)pool->data + *offset;
185}
186
187static void
188_shm_pool_reset(Shm_Pool *pool)
189{
190 LOGFN(__FILE__, __LINE__, __FUNCTION__);
191
192 pool->used = 0;
193}
194
195static Shm_Data *
196_shm_data_create_from_pool(Shm_Pool *pool, int w, int h, Eina_Bool alpha)
197{
198 Shm_Data *data;
199 int len, offset;
200 uint32_t wl_format = WL_SHM_FORMAT_ARGB8888;
201
202 LOGFN(__FILE__, __LINE__, __FUNCTION__);
203
204 /* try to malloc space for data */
205 if (!(data = malloc(sizeof(Shm_Data))))
206 {
207 ERR("Could not allocate space for data");
208 return NULL;
209 }
210
211 len = (w * sizeof(int)) * h;
212 data->pool = NULL;
213
214 if (!(data->map = _shm_pool_allocate(pool, len, &offset)))
215 {
216 ERR("Could not map leaf data");
217 goto err;
218 }
219
220 if (alpha)
221 wl_format = WL_SHM_FORMAT_ARGB8888;
222
223 data->buffer =
224 wl_shm_pool_create_buffer(pool->pool, offset, w, h,
225 (w * sizeof(int)), wl_format);
226 if (!data->buffer)
227 {
228 ERR("Could not create buffer from pool");
229 goto err;
230 }
231
232 return data;
233
234err:
235 free(data);
236 return NULL;
237}
238
239static void
240_shm_data_create(Shm_Pool *alt_pool, Shm_Data **ret, Surface *s, int w, int h)
241{
242 Shm_Surface *surface;
243 Shm_Pool *pool;
244 Shm_Data *data;
245 struct wl_shm *shm;
246
247 LOGFN(__FILE__, __LINE__, __FUNCTION__);
248
249 surface = s->surf.shm;
250 if (ret) *ret = NULL;
251
252 if (alt_pool)
253 {
254 _shm_pool_reset(alt_pool);
255 if ((data = _shm_data_create_from_pool(alt_pool, w, h, surface->alpha)))
256 goto out;
257 }
258
259 shm = ecore_wl2_display_shm_get(s->ob->ewd);
260 if (!(pool = _shm_pool_create(shm, ((w * sizeof(int)) * h))))
261 {
262 ERR("Could not create shm pool");
263 return;
264 }
265
266 if (!(data = _shm_data_create_from_pool(pool, w, h, surface->alpha)))
267 {
268 ERR("Could not create data from pool");
269 _shm_pool_destroy(pool);
270 return;
271 }
272
273 data->pool = pool;
274
275out:
276 if (ret) *ret = data;
277}
278
279static void
280_shm_data_destroy(Shm_Data *data)
281{
282 LOGFN(__FILE__, __LINE__, __FUNCTION__);
283
284 if (data->buffer) wl_buffer_destroy(data->buffer);
285 if (data->pool) _shm_pool_destroy(data->pool);
286 free(data);
287}
288
289static void
290_shm_buffer_release(void *data, struct wl_buffer *buffer)
291{
292 Surface *s;
293 Shm_Surface *surf;
294 Shm_Leaf *leaf;
295 int i = 0;
296
297 LOGFN(__FILE__, __LINE__, __FUNCTION__);
298
299 s = data;
300 surf = s->surf.shm;
301 for (; i < surf->num_buff; i++)
302 {
303 leaf = &surf->leaf[i];
304 if ((leaf->data) && (leaf->data->buffer == buffer))
305 {
306// DBG("Buffer Released: %d", (int)(leaf - &surf->leaf[0]));
307 leaf->busy = 0;
308
309 if (leaf->reconfigure)
310 {
311 _shm_leaf_release(leaf);
312 _shm_leaf_create(s, leaf, surf->w, surf->h);
313 }
314
315 break;
316 }
317 }
318}
319
320static const struct wl_buffer_listener _shm_buffer_listener =
321{
322 _shm_buffer_release
323};
324
325static Eina_Bool
326_shm_leaf_create(Surface *s, Shm_Leaf *leaf, int w, int h)
327{
328 LOGFN(__FILE__, __LINE__, __FUNCTION__);
329
330 _shm_data_create(leaf->resize_pool, &leaf->data, s, w, h);
331 if (!leaf->data)
332 {
333 CRI("Failed to create leaf data");
334 abort();
335 }
336
337 leaf->w = w;
338 leaf->h = h;
339 leaf->valid = EINA_TRUE;
340 leaf->drawn = EINA_FALSE;
341 leaf->age = 0;
342 wl_buffer_add_listener(leaf->data->buffer, &_shm_buffer_listener, s);
343
344 return EINA_TRUE;
345}
346
347static void
348_shm_leaf_release(Shm_Leaf *leaf)
349{
350 LOGFN(__FILE__, __LINE__, __FUNCTION__);
351 Shm_Pool *resize_pool;
352
353 /* if we delete resize_pool here we blow away the clever optimization
354 * it provides (and end up doing two allocations per resize when we
355 * might have done none at all).
356 */
357 resize_pool = leaf->resize_pool;
358 if (leaf->data) _shm_data_destroy(leaf->data);
359 memset(leaf, 0, sizeof(*leaf));
360 leaf->valid = EINA_FALSE;
361 leaf->resize_pool = resize_pool;
362}
363
364static void
365_shm_leaf_destroy(Shm_Leaf *leaf)
366{
367 _shm_leaf_release(leaf);
368 if (leaf->resize_pool) _shm_pool_destroy(leaf->resize_pool);
369 leaf->resize_pool = NULL;
370}
371
372static void
373_evas_shm_surface_destroy(Surface *surface)
374{
375 int i = 0;
376
377 LOGFN(__FILE__, __LINE__, __FUNCTION__);
378
379 if (!surface) return;
380
381 for (; i < surface->surf.shm->num_buff; i++)
382 _shm_leaf_destroy(&surface->surf.shm->leaf[i]);
383
384 free(surface->surf.shm);
385 surface->surf.shm = NULL;
386}
387
388static void
389_evas_shm_surface_reconfigure(Surface *s, int w, int h, uint32_t flags, Eina_Bool force)
390{
391 Shm_Surface *surface;
392 int i = 0, resize = 0;
393
394 LOGFN(__FILE__, __LINE__, __FUNCTION__);
395
396 surface = s->surf.shm;
397 resize = !!flags;
398
399 if (force)
400 {
401 for (; i < surface->num_buff; i++)
402 surface->leaf[i].busy = EINA_FALSE;
403 }
404
405 for (; i < surface->num_buff; i++)
406 {
407 /* don't resize any busy leafs */
408 if (surface->leaf[i].busy)
409 {
410 surface->leaf[i].reconfigure = EINA_TRUE;
411 continue;
412 }
413
414 /* clear this leaf */
415 _shm_leaf_release(&surface->leaf[i]);
416 }
417
418 surface->w = w;
419 surface->h = h;
420
421 if ((!w) || (!h)) return;
422 for (i = 0; i < surface->num_buff; i++)
423 {
424 if (surface->leaf[i].busy) continue;
425
426 if ((resize) && (!surface->leaf[i].resize_pool))
427 {
428 struct wl_shm *shm;
429
430 shm = ecore_wl2_display_shm_get(s->ob->ewd);
431 surface->leaf[i].resize_pool =
432 _shm_pool_create(shm, 6 * 1024 * 1024);
433 }
434
435 if (!_shm_leaf_create(s, &surface->leaf[i], w, h))
436 {
437 CRI("Failed to create leaf data");
438 abort();
439 }
440 }
441}
442
443static Shm_Leaf *
444_evas_shm_surface_wait(Shm_Surface *surface)
445{
446 int i = 0, best = -1, best_age = -1;
447
448 for (i = 0; i < surface->num_buff; i++)
449 {
450 if (surface->leaf[i].busy) continue;
451 if ((surface->leaf[i].valid) && (surface->leaf[i].age > best_age))
452 {
453 best = i;
454 best_age = surface->leaf[i].age;
455 }
456 }
457
458 if (best >= 0) return &surface->leaf[best];
459 return NULL;
460}
461
462static int
463_evas_shm_surface_assign(Surface *s)
464{
465 int i;
466 Shm_Surface *surface;
467
468 surface = s->surf.shm;
469 surface->current = _evas_shm_surface_wait(surface);
470
471 /* If we ran out of buffers we're in trouble, reset all ages */
472 if (!surface->current)
473 {
474 WRN("No free SHM buffers, dropping a frame");
475 for (i = 0; i < surface->num_buff; i++)
476 {
477 if (surface->leaf[i].valid)
478 {
479 surface->leaf[i].drawn = EINA_FALSE;
480 surface->leaf[i].age = 0;
481 }
482 }
483 return 0;
484 }
485
486 /* Increment ages of all valid buffers */
487 for (i = 0; i < surface->num_buff; i++)
488 {
489 if (surface->leaf[i].valid && surface->leaf[i].drawn)
490 {
491 surface->leaf[i].age++;
492 if (surface->leaf[i].age > 4)
493 {
494 surface->leaf[i].age = 0;
495 surface->leaf[i].drawn = EINA_FALSE;
496 }
497 }
498 }
499
500 return surface->current->age;
501}
502
503static void *
504_evas_shm_surface_data_get(Surface *s, int *w, int *h)
505{
506 Shm_Surface *surface;
507 LOGFN(__FILE__, __LINE__, __FUNCTION__);
508
509 surface = s->surf.shm;
510 if (w) *w = 0;
511 if (h) *h = 0;
512
513 if (!surface->current)
514 {
515 /* WRN("All buffers held by server"); */
516 return NULL;
517 }
518
519 /* DBG("Leaf Data Get %d", (int)(leaf - &surface->leaf[0])); */
520
521 if (w) *w = surface->current->w;
522 if (h) *h = surface->current->h;
523
524 return surface->current->data->map;
525}
526
527static void
528_evas_shm_surface_post(Surface *s, Eina_Rectangle *rects, unsigned int count)
529{
530 Ecore_Wl2_Window *win;
531 struct wl_surface *wls;
532 Shm_Surface *surf;
533 Shm_Leaf *leaf;
534
535 LOGFN(__FILE__, __LINE__, __FUNCTION__);
536
537 surf = s->surf.shm;
538 leaf = surf->current;
539 if (!leaf) return;
540
541 win = s->info->info.wl2_win;
542 wls = ecore_wl2_window_surface_get(win);
543
544 ecore_wl2_window_buffer_attach(win, leaf->data->buffer, 0, 0, EINA_FALSE);
545
546 _evas_surface_damage(wls, surf->compositor_version,
547 leaf->w, leaf->h, rects, count);
548
549 ecore_wl2_window_commit(s->info->info.wl2_win, EINA_TRUE);
550
551 leaf->busy = EINA_TRUE;
552 leaf->drawn = EINA_TRUE;
553 leaf->age = 0;
554 surf->current = NULL;
555}
556
557Eina_Bool
558_evas_shm_surface_create(Surface *s, int w, int h, int num_buff)
559{
560 Shm_Surface *surf;
561 int i = 0;
562
563 LOGFN(__FILE__, __LINE__, __FUNCTION__);
564
565 if (!(s->surf.shm = calloc(1, sizeof(Shm_Surface)))) return EINA_FALSE;
566 surf = s->surf.shm;
567
568 surf->w = w;
569 surf->h = h;
570 surf->num_buff = num_buff;
571 surf->alpha = s->info->info.destination_alpha;
572 surf->compositor_version = s->info->info.compositor_version;
573
574 if (w && h)
575 {
576 /* create surface buffers */
577 for (; i < surf->num_buff; i++)
578 {
579 if (!_shm_leaf_create(s, &(surf->leaf[i]), w, h))
580 {
581 ERR("Could not create surface leaf");
582 goto err;
583 }
584 }
585 }
586
587 s->type = SURFACE_SHM;
588 s->funcs.destroy = _evas_shm_surface_destroy;
589 s->funcs.reconfigure = _evas_shm_surface_reconfigure;
590 s->funcs.data_get = _evas_shm_surface_data_get;
591 s->funcs.assign = _evas_shm_surface_assign;
592 s->funcs.post = _evas_shm_surface_post;
593
594 return EINA_TRUE;
595
596err:
597 _evas_shm_surface_destroy(s);
598 return EINA_FALSE;
599}