diff options
author | Derek Foreman <derekf@osg.samsung.com> | 2017-11-30 12:48:08 -0600 |
---|---|---|
committer | Derek Foreman <derekf@osg.samsung.com> | 2017-12-01 10:58:44 -0600 |
commit | 8a3b983c53cf41be5d8a8cb24aa18a83d8038bd8 (patch) | |
tree | 9d762a67a115a4db2c58bf6eb8fa69444db94dde /src/lib/ecore_wl2/ecore_wl2_surface.c | |
parent | dd5edfae03f23d45126404d3b459e0abbd94a54c (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.c | 228 |
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 | |||
14 | static 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 | |||
38 | static 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 | |||
63 | static 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 | |||
95 | static 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 | |||
120 | static 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 | |||
140 | static 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 | |||
153 | EAPI void | ||
154 | ecore_wl2_surface_destroy(Ecore_Wl2_Surface *surface) | ||
155 | { | ||
156 | EINA_SAFETY_ON_NULL_RETURN(surface); | ||
157 | |||
158 | surface->funcs.destroy(surface); | ||
159 | } | ||
160 | |||
161 | EAPI void | ||
162 | ecore_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 | |||
169 | EAPI void * | ||
170 | ecore_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 | |||
177 | EAPI int | ||
178 | ecore_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 | |||
185 | EAPI void | ||
186 | ecore_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 | |||
193 | EAPI Ecore_Wl2_Surface * | ||
194 | ecore_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 | |||
225 | err: | ||
226 | free(out); | ||
227 | return NULL; | ||
228 | } | ||