summaryrefslogtreecommitdiff
path: root/src/lib/ecore_wl2/ecore_wl2_surface.c
diff options
context:
space:
mode:
authorDerek Foreman <derekf@osg.samsung.com>2017-11-30 12:48:08 -0600
committerDerek Foreman <derekf@osg.samsung.com>2017-12-01 10:58:44 -0600
commit8a3b983c53cf41be5d8a8cb24aa18a83d8038bd8 (patch)
tree9d762a67a115a4db2c58bf6eb8fa69444db94dde /src/lib/ecore_wl2/ecore_wl2_surface.c
parentdd5edfae03f23d45126404d3b459e0abbd94a54c (diff)
ecore_wl2 wayland_shm: Move surface functions into ecore_wl2
Finish pushing these all into ecore_wl2
Diffstat (limited to 'src/lib/ecore_wl2/ecore_wl2_surface.c')
-rw-r--r--src/lib/ecore_wl2/ecore_wl2_surface.c228
1 files changed, 228 insertions, 0 deletions
diff --git a/src/lib/ecore_wl2/ecore_wl2_surface.c b/src/lib/ecore_wl2/ecore_wl2_surface.c
new file mode 100644
index 0000000000..9a1c8ea1c6
--- /dev/null
+++ b/src/lib/ecore_wl2/ecore_wl2_surface.c
@@ -0,0 +1,228 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include "ecore_wl2_private.h"
6
7#include <sys/types.h>
8#include <sys/stat.h>
9
10#include "linux-dmabuf-unstable-v1-client-protocol.h"
11
12#define MAX_BUFFERS 4
13
14static void
15_evas_dmabuf_surface_reconfigure(Ecore_Wl2_Surface *s, int w, int h, uint32_t flags EINA_UNUSED, Eina_Bool force)
16{
17 Ecore_Wl2_Buffer *b;
18 Eina_List *l, *tmp;
19
20 if ((!w) || (!h)) return;
21 EINA_LIST_FOREACH_SAFE(s->buffers, l, tmp, b)
22 {
23 int stride = b->stride;
24
25 /* If stride is a little bigger than width we still fit */
26 if (!force && (w >= b->w) && (w <= stride / 4) && (h == b->h))
27 {
28 b->w = w;
29 continue;
30 }
31 ecore_wl2_buffer_destroy(b);
32 s->buffers = eina_list_remove_list(s->buffers, l);
33 }
34 s->w = w;
35 s->h = h;
36}
37
38static void *
39_evas_dmabuf_surface_data_get(Ecore_Wl2_Surface *s, int *w, int *h)
40{
41 Ecore_Wl2_Buffer *b;
42 void *ptr;
43
44 b = s->current;
45 if (!b) return NULL;
46
47 /* We return stride/bpp because it may not match the allocated
48 * width. evas will figure out the clipping
49 */
50 if (w) *w = b->stride / 4;
51 if (h) *h = b->h;
52 if (b->locked) return b->mapping;
53
54 ptr = ecore_wl2_buffer_map(b);
55 if (!ptr)
56 return NULL;
57
58 b->mapping = ptr;
59 b->locked = EINA_TRUE;
60 return b->mapping;
61}
62
63static Ecore_Wl2_Buffer *
64_evas_dmabuf_surface_wait(Ecore_Wl2_Surface *s)
65{
66 Ecore_Wl2_Buffer *b, *best = NULL;
67 Eina_List *l;
68 int best_age = -1;
69
70 EINA_LIST_FOREACH(s->buffers, l, b)
71 {
72 if (b->locked || b->busy) continue;
73 if (b->age > best_age)
74 {
75 best = b;
76 best_age = b->age;
77 }
78 }
79
80 if (!best && (eina_list_count(s->buffers) < MAX_BUFFERS))
81 {
82 Ecore_Wl2_Display *ewd;
83
84 ewd = ecore_wl2_window_display_get(s->wl2_win);
85 EINA_SAFETY_ON_NULL_RETURN_VAL(ewd, NULL);
86
87 best = ecore_wl2_buffer_create(ewd, s->w, s->h, s->alpha);
88 /* Start at -1 so it's age is incremented to 0 for first draw */
89 best->age = -1;
90 s->buffers = eina_list_append(s->buffers, best);
91 }
92 return best;
93}
94
95static int
96_evas_dmabuf_surface_assign(Ecore_Wl2_Surface *s)
97{
98 Ecore_Wl2_Buffer *b;
99 Eina_List *l;
100
101 s->current = _evas_dmabuf_surface_wait(s);
102 if (!s->current)
103 {
104 /* Should be unreachable and will result in graphical
105 * anomalies - we should probably blow away all the
106 * existing buffers and start over if we actually
107 * see this happen...
108 */
109 WRN("No free DMAbuf buffers, dropping a frame");
110 EINA_LIST_FOREACH(s->buffers, l, b)
111 b->age = 0;
112 return 0;
113 }
114 EINA_LIST_FOREACH(s->buffers, l, b)
115 b->age++;
116
117 return s->current->age;
118}
119
120static void
121_evas_dmabuf_surface_post(Ecore_Wl2_Surface *s, Eina_Rectangle *rects, unsigned int count)
122{
123 Ecore_Wl2_Buffer *b;
124
125 b = s->current;
126 if (!b) return;
127
128 ecore_wl2_buffer_unlock(b);
129
130 s->current = NULL;
131 b->busy = EINA_TRUE;
132 b->age = 0;
133
134 ecore_wl2_window_buffer_attach(s->wl2_win, b->wl_buffer, 0, 0, EINA_FALSE);
135 ecore_wl2_window_damage(s->wl2_win, rects, count);
136
137 ecore_wl2_window_commit(s->wl2_win, EINA_TRUE);
138}
139
140static void
141_evas_dmabuf_surface_destroy(Ecore_Wl2_Surface *s)
142{
143 Ecore_Wl2_Buffer *b;
144
145 if (!s) return;
146
147 EINA_LIST_FREE(s->buffers, b)
148 ecore_wl2_buffer_destroy(b);
149
150 free(s);
151}
152
153EAPI void
154ecore_wl2_surface_destroy(Ecore_Wl2_Surface *surface)
155{
156 EINA_SAFETY_ON_NULL_RETURN(surface);
157
158 surface->funcs.destroy(surface);
159}
160
161EAPI void
162ecore_wl2_surface_reconfigure(Ecore_Wl2_Surface *surface, int w, int h, uint32_t flags, Eina_Bool force)
163{
164 EINA_SAFETY_ON_NULL_RETURN(surface);
165
166 surface->funcs.reconfigure(surface, w, h, flags, force);
167}
168
169EAPI void *
170ecore_wl2_surface_data_get(Ecore_Wl2_Surface *surface, int *w, int *h)
171{
172 EINA_SAFETY_ON_NULL_RETURN_VAL(surface, NULL);
173
174 return surface->funcs.data_get(surface, w, h);
175}
176
177EAPI int
178ecore_wl2_surface_assign(Ecore_Wl2_Surface *surface)
179{
180 EINA_SAFETY_ON_NULL_RETURN_VAL(surface, 0);
181
182 return surface->funcs.assign(surface);
183}
184
185EAPI void
186ecore_wl2_surface_post(Ecore_Wl2_Surface *surface, Eina_Rectangle *rects, unsigned int count)
187{
188 EINA_SAFETY_ON_NULL_RETURN(surface);
189
190 surface->funcs.post(surface, rects, count);
191}
192
193EAPI Ecore_Wl2_Surface *
194ecore_wl2_surface_create(Ecore_Wl2_Window *win, Eina_Bool alpha)
195{
196 Ecore_Wl2_Surface *out;
197 Ecore_Wl2_Display *ewd;
198 Ecore_Wl2_Buffer_Type types = 0;
199
200 out = calloc(1, sizeof(*out));
201 if (!out) return NULL;
202 out->wl2_win = win;
203
204 ewd = ecore_wl2_window_display_get(win);
205 if (ecore_wl2_display_shm_get(ewd))
206 types |= ECORE_WL2_BUFFER_SHM;
207 if (ecore_wl2_display_dmabuf_get(ewd))
208 types |= ECORE_WL2_BUFFER_DMABUF;
209
210 out->alpha = alpha;
211 out->w = 0;
212 out->h = 0;
213
214 /* create surface buffers */
215 if (!ecore_wl2_buffer_init(ewd, types)) goto err;
216
217 out->funcs.destroy = _evas_dmabuf_surface_destroy;
218 out->funcs.reconfigure = _evas_dmabuf_surface_reconfigure;
219 out->funcs.data_get = _evas_dmabuf_surface_data_get;
220 out->funcs.assign = _evas_dmabuf_surface_assign;
221 out->funcs.post = _evas_dmabuf_surface_post;
222
223 return out;
224
225err:
226 free(out);
227 return NULL;
228}