summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChris Michael <cp.michael@samsung.com>2014-03-10 10:02:31 +0000
committerChris Michael <cp.michael@samsung.com>2014-03-10 12:40:31 +0000
commitc403035e1d571b6b5a9137c92578723b810f44e5 (patch)
tree6a2de970d087da2ea04ea4311a4c21607484a73f /src
parent90551ff49ca66dfef84ff7e6b6ee78468c46304d (diff)
ecore-evas-drm: Add initial code to make ecore_evas render using drm
NB: This is still a work-in-progress and not complete yet Signed-off-by: Chris Michael <cp.michael@samsung.com>
Diffstat (limited to 'src')
-rw-r--r--src/modules/ecore_evas/engines/drm/ecore_evas_drm.c335
1 files changed, 318 insertions, 17 deletions
diff --git a/src/modules/ecore_evas/engines/drm/ecore_evas_drm.c b/src/modules/ecore_evas/engines/drm/ecore_evas_drm.c
index 4cf2370f40..78dc49547e 100644
--- a/src/modules/ecore_evas/engines/drm/ecore_evas_drm.c
+++ b/src/modules/ecore_evas/engines/drm/ecore_evas_drm.c
@@ -14,10 +14,10 @@
14#include "ecore_evas_private.h" 14#include "ecore_evas_private.h"
15#include "ecore_evas_drm.h" 15#include "ecore_evas_drm.h"
16 16
17#ifdef BUILD_ECORE_EVAS_DRM 17//#ifdef BUILD_ECORE_EVAS_DRM
18# include <Evas_Engine_Drm.h> 18# include <Evas_Engine_Drm.h>
19# include <Ecore_Drm.h> 19# include <Ecore_Drm.h>
20#endif 20//#endif
21 21
22/* local structures */ 22/* local structures */
23typedef struct _Ecore_Evas_Engine_Data_Drm Ecore_Evas_Engine_Data_Drm; 23typedef struct _Ecore_Evas_Engine_Data_Drm Ecore_Evas_Engine_Data_Drm;
@@ -32,17 +32,27 @@ static int _ecore_evas_drm_init(void);
32static int _ecore_evas_drm_shutdown(void); 32static int _ecore_evas_drm_shutdown(void);
33static Ecore_Evas_Interface_Drm *_ecore_evas_drm_interface_new(void); 33static Ecore_Evas_Interface_Drm *_ecore_evas_drm_interface_new(void);
34 34
35static void _ecore_evas_drm_free(Ecore_Evas *ee);
36static void _ecore_evas_drm_delete_request_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func);
37static void _ecore_evas_drm_resize(Ecore_Evas *ee, int w, int h);
38static void _ecore_evas_drm_show(Ecore_Evas *ee);
39static void _ecore_evas_drm_hide(Ecore_Evas *ee);
40static int _ecore_evas_drm_render(Ecore_Evas *ee);
41static void _ecore_evas_drm_render_updates(void *data, Evas *evas EINA_UNUSED, void *event);
42static int _ecore_evas_drm_render_updates_process(Ecore_Evas *ee, Eina_List *updates);
43
35/* local variables */ 44/* local variables */
36static int _ecore_evas_init_count = 0; 45static int _ecore_evas_init_count = 0;
46static Ecore_Drm_Device *dev = NULL;
37 47
38static Ecore_Evas_Engine_Func _ecore_evas_drm_engine_func = 48static Ecore_Evas_Engine_Func _ecore_evas_drm_engine_func =
39{ 49{
40 NULL, //void (*fn_free) (Ecore_Evas *ee); 50 _ecore_evas_drm_free,
41 NULL, //void (*fn_callback_resize_set) (Ecore_Evas *ee, Ecore_Evas_Event_Cb func); 51 NULL, //void (*fn_callback_resize_set) (Ecore_Evas *ee, Ecore_Evas_Event_Cb func);
42 NULL, //void (*fn_callback_move_set) (Ecore_Evas *ee, Ecore_Evas_Event_Cb func); 52 NULL, //void (*fn_callback_move_set) (Ecore_Evas *ee, Ecore_Evas_Event_Cb func);
43 NULL, //void (*fn_callback_show_set) (Ecore_Evas *ee, Ecore_Evas_Event_Cb func); 53 NULL, //void (*fn_callback_show_set) (Ecore_Evas *ee, Ecore_Evas_Event_Cb func);
44 NULL, //void (*fn_callback_hide_set) (Ecore_Evas *ee, Ecore_Evas_Event_Cb func); 54 NULL, //void (*fn_callback_hide_set) (Ecore_Evas *ee, Ecore_Evas_Event_Cb func);
45 NULL, //void (*fn_callback_delete_request_set) (Ecore_Evas *ee, Ecore_Evas_Event_Cb func); 55 _ecore_evas_drm_delete_request_set,
46 NULL, //void (*fn_callback_destroy_set) (Ecore_Evas *ee, Ecore_Evas_Event_Cb func); 56 NULL, //void (*fn_callback_destroy_set) (Ecore_Evas *ee, Ecore_Evas_Event_Cb func);
47 NULL, //void (*fn_callback_focus_in_set) (Ecore_Evas *ee, Ecore_Evas_Event_Cb func); 57 NULL, //void (*fn_callback_focus_in_set) (Ecore_Evas *ee, Ecore_Evas_Event_Cb func);
48 NULL, //void (*fn_callback_focus_out_set) (Ecore_Evas *ee, Ecore_Evas_Event_Cb func); 58 NULL, //void (*fn_callback_focus_out_set) (Ecore_Evas *ee, Ecore_Evas_Event_Cb func);
@@ -54,12 +64,12 @@ static Ecore_Evas_Engine_Func _ecore_evas_drm_engine_func =
54 NULL, //void (*fn_callback_post_render_set) (Ecore_Evas *ee, Ecore_Evas_Event_Cb func); 64 NULL, //void (*fn_callback_post_render_set) (Ecore_Evas *ee, Ecore_Evas_Event_Cb func);
55 NULL, //void (*fn_move) (Ecore_Evas *ee, int x, int y); 65 NULL, //void (*fn_move) (Ecore_Evas *ee, int x, int y);
56 NULL, //void (*fn_managed_move) (Ecore_Evas *ee, int x, int y); 66 NULL, //void (*fn_managed_move) (Ecore_Evas *ee, int x, int y);
57 NULL, //void (*fn_resize) (Ecore_Evas *ee, int w, int h); 67 _ecore_evas_drm_resize,
58 NULL, //void (*fn_move_resize) (Ecore_Evas *ee, int x, int y, int w, int h); 68 NULL, //void (*fn_move_resize) (Ecore_Evas *ee, int x, int y, int w, int h);
59 NULL, //void (*fn_rotation_set) (Ecore_Evas *ee, int rot, int resize); 69 NULL, //void (*fn_rotation_set) (Ecore_Evas *ee, int rot, int resize);
60 NULL, //void (*fn_shaped_set) (Ecore_Evas *ee, int shaped); 70 NULL, //void (*fn_shaped_set) (Ecore_Evas *ee, int shaped);
61 NULL, //void (*fn_show) (Ecore_Evas *ee); 71 _ecore_evas_drm_show,
62 NULL, //void (*fn_hide) (Ecore_Evas *ee); 72 _ecore_evas_drm_hide,
63 NULL, //void (*fn_raise) (Ecore_Evas *ee); 73 NULL, //void (*fn_raise) (Ecore_Evas *ee);
64 NULL, //void (*fn_lower) (Ecore_Evas *ee); 74 NULL, //void (*fn_lower) (Ecore_Evas *ee);
65 NULL, //void (*fn_activate) (Ecore_Evas *ee); 75 NULL, //void (*fn_activate) (Ecore_Evas *ee);
@@ -93,7 +103,8 @@ static Ecore_Evas_Engine_Func _ecore_evas_drm_engine_func =
93 NULL, //void (*fn_demands_attention_set) (Ecore_Evas *ee, Eina_Bool on); 103 NULL, //void (*fn_demands_attention_set) (Ecore_Evas *ee, Eina_Bool on);
94 NULL, //void (*fn_focus_skip_set) (Ecore_Evas *ee, Eina_Bool on); 104 NULL, //void (*fn_focus_skip_set) (Ecore_Evas *ee, Eina_Bool on);
95 105
96 NULL, //int (*fn_render) (Ecore_Evas *ee); 106 _ecore_evas_drm_render,
107
97 NULL, //void (*fn_screen_geometry_get) (const Ecore_Evas *ee, int *x, int *y, int *w, int *h); 108 NULL, //void (*fn_screen_geometry_get) (const Ecore_Evas *ee, int *x, int *y, int *w, int *h);
98 NULL, //void (*fn_screen_dpi_get) (const Ecore_Evas *ee, int *xdpi, int *ydpi); 109 NULL, //void (*fn_screen_dpi_get) (const Ecore_Evas *ee, int *xdpi, int *ydpi);
99 NULL, //void (*fn_msg_parent_send) (Ecore_Evas *ee, int maj, int min, void *data, int size); 110 NULL, //void (*fn_msg_parent_send) (Ecore_Evas *ee, int maj, int min, void *data, int size);
@@ -114,6 +125,8 @@ EAPI Ecore_Evas *
114ecore_evas_drm_new_internal(const char *device, unsigned int parent, int x, int y, int w, int h) 125ecore_evas_drm_new_internal(const char *device, unsigned int parent, int x, int y, int w, int h)
115{ 126{
116 Ecore_Evas *ee; 127 Ecore_Evas *ee;
128 Evas_Engine_Info_Drm *einfo;
129 Ecore_Evas_Interface_Drm *iface;
117 int method; 130 int method;
118 131
119 /* try to find the evas drm engine */ 132 /* try to find the evas drm engine */
@@ -123,41 +136,329 @@ ecore_evas_drm_new_internal(const char *device, unsigned int parent, int x, int
123 return NULL; 136 return NULL;
124 } 137 }
125 138
139 /* try to init drm */
140 if (_ecore_evas_drm_init() < 1) return NULL;
141
126 /* try to allocate space for new ecore_evas */ 142 /* try to allocate space for new ecore_evas */
127 if (!(ee = calloc(1, sizeof(Ecore_Evas)))) 143 if (!(ee = calloc(1, sizeof(Ecore_Evas))))
128 { 144 {
129 ERR("Failed to allocate space for new Ecore_Evas"); 145 ERR("Failed to allocate space for new Ecore_Evas");
130 return NULL; 146 goto ee_err;
131 } 147 }
132 148
133 ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS); 149 ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS);
134 150
135 /* try to init drm */ 151 ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_evas_drm_engine_func;
152
153 iface = _ecore_evas_drm_interface_new();
154 ee->engine.ifaces = eina_list_append(ee->engine.ifaces, iface);
155
156 /* set some engine properties */
157 ee->driver = "drm";
158 if (device) ee->name = strdup(device);
159
160 if (w < 1) w = 1;
161 if (h < 1) h = 1;
162
163 ee->x = ee->req.x = x;
164 ee->y = ee->req.y = y;
165 ee->w = ee->req.w = w;
166 ee->h = ee->req.h = h;
167
168 ee->prop.max.w = 32767;
169 ee->prop.max.h = 32767;
170 ee->prop.layer = 4;
171 ee->prop.request_pos = 0;
172 ee->prop.sticky = 0;
173 ee->alpha = EINA_FALSE;
174
175 ee->can_async_render = 1;
176 if (getenv("ECORE_EVAS_FORCE_SYNC_RENDER"))
177 ee->can_async_render = 0;
178
179 /* try to initialize evas */
180 ee->evas = evas_new();
181 evas_data_attach_set(ee->evas, ee);
182 evas_output_method_set(ee->evas, method);
183
184 /* FIXME: Support initial rotation ?? */
185 evas_output_size_set(ee->evas, w, h);
186 evas_output_viewport_set(ee->evas, 0, 0, w, h);
187
188 if (ee->can_async_render)
189 evas_event_callback_add(ee->evas, EVAS_CALLBACK_RENDER_POST,
190 _ecore_evas_drm_render_updates, ee);
191
192 if ((einfo = (Evas_Engine_Info_Drm *)evas_engine_info_get(ee->evas)))
193 {
194 einfo->info.depth = 32; // FIXME
195 einfo->info.destination_alpha = ee->alpha;
196 einfo->info.rotation = ee->rotation;
197 einfo->info.vsync = EINA_FALSE;
198 einfo->info.use_hw_accel = EINA_FALSE;
199 einfo->info.fd = ecore_drm_device_fd_get(dev);
200 einfo->info.tty = ecore_drm_tty_get(dev);
201
202 if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
203 {
204 ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
205 goto eng_err;
206 }
207 }
208 else
209 {
210 ERR("Failed to get Evas Engine Info for '%s'", ee->driver);
211 goto eng_err;
212 }
213
214 _ecore_evas_register(ee);
215 ecore_evas_input_event_register(ee);
136 216
137 return ee; 217 return ee;
218
219eng_err:
220 ecore_evas_free(ee);
221ee_err:
222 _ecore_evas_drm_shutdown();
223 return NULL;
138} 224}
139 225
140/* local functions */ 226/* local functions */
141static int 227static int
142_ecore_evas_drm_init(void) 228_ecore_evas_drm_init(void)
143{ 229{
144 _ecore_evas_init_count++; 230 if (++_ecore_evas_init_count != 1) return _ecore_evas_init_count;
145 if (_ecore_evas_init_count > 1) return _ecore_evas_init_count; 231
232 /* try to init ecore_drm */
233 if (!ecore_drm_init())
234 {
235 ERR("Could not initialize Ecore_Drm");
236 return --_ecore_evas_init_count;
237 }
238
239 /* try to find the device */
240 if (!(dev = ecore_drm_device_find(NULL, NULL)))
241 {
242 ERR("Could not find default drm device");
243 goto dev_err;
244 }
245
246 /* try to open the graphics card */
247 if (!ecore_drm_device_open(dev))
248 {
249 ERR("Could not open drm device");
250 goto dev_open_err;
251 }
252
253 /* try to open the tty */
254 if (!ecore_drm_tty_open(dev, NULL))
255 {
256 ERR("Could not open tty: %m");
257 goto tty_open_err;
258 }
259
260 /* FIXME: Init egl/software renderer here ?? */
261
262 /* try to create sprites */
263 if (!ecore_drm_sprites_create(dev))
264 {
265 ERR("Could not create sprites: %m");
266 goto sprite_err;
267 }
268
269 /* try to create outputs */
270 if (!ecore_drm_outputs_create(dev))
271 {
272 ERR("Could not create outputs: %m");
273 goto output_err;
274 }
275
276 /* try to create inputs */
277 if (!ecore_drm_inputs_create(dev))
278 {
279 ERR("Could not create inputs: %m");
280 goto output_err;
281 }
146 282
147 ecore_event_evas_init(); 283 ecore_event_evas_init();
148 284
149 return _ecore_evas_init_count; 285 return _ecore_evas_init_count;
286
287output_err:
288 ecore_drm_sprites_destroy(dev);
289sprite_err:
290 ecore_drm_tty_close(dev);
291tty_open_err:
292 ecore_drm_device_close(dev);
293dev_open_err:
294 ecore_drm_device_free(dev);
295dev_err:
296 ecore_drm_shutdown();
297 return --_ecore_evas_init_count;
150} 298}
151 299
152static int 300static int
153_ecore_evas_drm_shutdown(void) 301_ecore_evas_drm_shutdown(void)
154{ 302{
155 _ecore_evas_init_count--; 303 if (--_ecore_evas_init_count != 0) return _ecore_evas_init_count;
156 if (_ecore_evas_init_count == 0) 304
305 ecore_drm_sprites_destroy(dev);
306 /* NB: No need to free outputs here. Is done in device free */
307 ecore_drm_inputs_destroy(dev);
308 ecore_drm_tty_close(dev);
309 ecore_drm_device_close(dev);
310 ecore_drm_device_free(dev);
311 ecore_drm_shutdown();
312
313 ecore_event_evas_shutdown();
314
315 return _ecore_evas_init_count;
316}
317
318static Ecore_Evas_Interface_Drm *
319_ecore_evas_drm_interface_new(void)
320{
321 Ecore_Evas_Interface_Drm *iface;
322
323 if (!(iface = calloc(1, sizeof(Ecore_Evas_Interface_Drm))))
324 return NULL;
325
326 iface->base.name = "drm";
327 iface->base.version = 1;
328
329 /* iface->pixmap_visual_get; */
330 /* iface->pixmap_colormap_get; */
331 /* iface->pixmap_depth_get; */
332
333 return iface;
334}
335
336/* local ecore_evas functions */
337static void
338_ecore_evas_drm_free(Ecore_Evas *ee)
339{
340 ecore_evas_input_event_unregister(ee);
341 _ecore_evas_drm_shutdown();
342}
343
344static void
345_ecore_evas_drm_delete_request_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func)
346{
347 ee->func.fn_delete_request = func;
348}
349
350static void
351_ecore_evas_drm_resize(Ecore_Evas *ee, int w, int h)
352{
353 ee->req.w = w;
354 ee->req.h = h;
355 if ((ee->w == w) && (ee->h == h)) return;
356 ee->w = w;
357 ee->h = h;
358 evas_output_size_set(ee->evas, w, h);
359 evas_output_viewport_set(ee->evas, 0, 0, w, h);
360 if (ee->func.fn_resize) ee->func.fn_resize(ee);
361}
362
363static void
364_ecore_evas_drm_show(Ecore_Evas *ee)
365{
366 if ((!ee) || (ee->visible)) return;
367 evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
368 ee->visible = 1;
369 if (ee->func.fn_show) ee->func.fn_show(ee);
370}
371
372static void
373_ecore_evas_drm_hide(Ecore_Evas *ee)
374{
375 if ((!ee) || (!ee->visible)) return;
376 evas_sync(ee->evas);
377 ee->visible = 0;
378 ee->should_be_visible = 0;
379 if (ee->func.fn_hide) ee->func.fn_hide(ee);
380}
381
382static int
383_ecore_evas_drm_render(Ecore_Evas *ee)
384{
385 int rend = 0;
386 Eina_List *l;
387 Ecore_Evas *ee2;
388
389 if (ee->in_async_render) return 0;
390
391 if (!ee->visible)
157 { 392 {
158 ecore_event_evas_shutdown(); 393 evas_norender(ee->evas);
394 return 0;
159 } 395 }
160 396
161 if (_ecore_evas_init_count < 0) _ecore_evas_init_count = 0; 397 EINA_LIST_FOREACH(ee->sub_ecore_evas, l, ee2)
162 return _ecore_evas_init_count; 398 {
399 if (ee2->func.fn_pre_render) ee2->func.fn_pre_render(ee2);
400 if (ee2->engine.func->fn_render)
401 rend |= ee2->engine.func->fn_render(ee2);
402 if (ee2->func.fn_post_render) ee2->func.fn_post_render(ee2);
403 }
404
405 if (ee->func.fn_pre_render) ee->func.fn_pre_render(ee);
406
407 if (!ee->can_async_render)
408 {
409 Eina_List *updates;
410
411 updates = evas_render_updates(ee->evas);
412 rend = _ecore_evas_drm_render_updates_process(ee, updates);
413 evas_render_updates_free(updates);
414 }
415 else if (evas_render_async(ee->evas))
416 {
417 ee->in_async_render = EINA_TRUE;
418 rend = 1;
419 }
420
421 return rend;
422}
423
424static void
425_ecore_evas_drm_render_updates(void *data, Evas *evas EINA_UNUSED, void *event)
426{
427 Evas_Event_Render_Post *ev;
428 Ecore_Evas *ee;
429
430 if (!(ev = event)) return;
431 if (!(ee = data)) return;
432
433 ee->in_async_render = EINA_FALSE;
434
435 _ecore_evas_drm_render_updates_process(ee, ev->updated_area);
436
437 /* TODO: handle delayed changes */
438}
439
440static int
441_ecore_evas_drm_render_updates_process(Ecore_Evas *ee, Eina_List *updates)
442{
443 int rend = 0;
444
445 if ((ee->visible) && (updates))
446 {
447 Eina_List *l = NULL;
448 Eina_Rectangle *r;
449
450 EINA_LIST_FOREACH(updates, l, r)
451 {
452 /* TODO */
453 }
454
455 _ecore_evas_idle_timeout_update(ee);
456 rend = 1;
457 }
458 else
459 evas_norender(ee->evas);
460
461 if (ee->func.fn_post_render) ee->func.fn_post_render(ee);
462
463 return rend;
163} 464}