summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Michael <cp.michael@samsung.com>2017-11-02 12:34:27 -0400
committerChristopher Michael <cp.michael@samsung.com>2019-02-25 13:19:16 -0500
commitb45b621330001e43a765ceb89f86cf9f0f4d280f (patch)
treed55c7caebaf687fb309ab7175b4bf22d1ea13359
parent46aae64b3404d2cb24ee2d7735804d5a2c145a22 (diff)
ecore-evas-drm: Refactor ecore-evas drm engine to work with multiple outputsdevs/devilhorns/multi-output
This patch refactors the Ecore_Evas drm engine code to support multiple outputs in software mode. This does NOT include support for gl-drm yet... @feature Signed-off-by: Chris Michael <cp.michael@samsung.com>
-rw-r--r--src/modules/ecore_evas/engines/drm/ecore_evas_drm.c1138
1 files changed, 516 insertions, 622 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 5668b416d1..19a89c8183 100644
--- a/src/modules/ecore_evas/engines/drm/ecore_evas_drm.c
+++ b/src/modules/ecore_evas/engines/drm/ecore_evas_drm.c
@@ -20,7 +20,7 @@
20#include "elput_private.h" 20#include "elput_private.h"
21 21
22#ifdef BUILD_ECORE_EVAS_GL_DRM 22#ifdef BUILD_ECORE_EVAS_GL_DRM
23# include <Evas_Engine_GL_Drm.h> 23/* # include <Evas_Engine_GL_Drm.h> */
24# include <dlfcn.h> 24# include <dlfcn.h>
25#endif 25#endif
26 26
@@ -46,346 +46,126 @@
46# endif 46# endif
47#endif /* ! _WIN32 */ 47#endif /* ! _WIN32 */
48 48
49typedef struct _Ecore_Evas_Engine_Drm_Tick
50{
51 Ecore_Drm2_Output *output;
52 Efl_Canvas_Output *canvas;
53 double offset, timestamp;
54} Ecore_Evas_Engine_Drm_Tick;
55
49typedef struct _Ecore_Evas_Engine_Drm_Data 56typedef struct _Ecore_Evas_Engine_Drm_Data
50{ 57{
51 int cw, ch; 58 Ecore_Drm2_Device *dev;
52 int clockid;
53 int x, y, w, h;
54 int depth, bpp;
55 unsigned int format;
56 double offset;
57 double tick_job_timestamp;
58 Ecore_Drm2_Context ctx; 59 Ecore_Drm2_Context ctx;
60
59 Ecore_Fd_Handler *hdlr; 61 Ecore_Fd_Handler *hdlr;
60 Ecore_Drm2_Device *dev; 62
61 Ecore_Drm2_Output *output;
62 Evas_Device *seat; 63 Evas_Device *seat;
64
65 Ecore_Job *tick_job;
66
67 Eina_List *ticks;
68
63 Eina_Bool ticking : 1; 69 Eina_Bool ticking : 1;
64 Eina_Bool once : 1; 70 Eina_Bool once : 1;
65 Ecore_Job *tick_job;
66 Ecore_Job *focus_job;
67} Ecore_Evas_Engine_Drm_Data; 71} Ecore_Evas_Engine_Drm_Data;
68 72
73static int _drm_shutdown(Ecore_Evas_Engine_Drm_Data *edata);
74
69static int _drm_init_count = 0; 75static int _drm_init_count = 0;
70static Eina_List *handlers; 76static Eina_List *canvases, *outputs;
71static Eina_List *canvases; 77static Ecore_Event_Handler *devhdlr;
72 78
73static Eina_Bool 79static void
74_drm_device_change(void *d EINA_UNUSED, int t EINA_UNUSED, void *event) 80_cb_tick(void *data)
75{ 81{
76 Elput_Event_Device_Change *ev = event;
77 const Eina_List *l;
78 Ecore_Evas *ee; 82 Ecore_Evas *ee;
79 Ecore_Evas_Engine_Drm_Data *edata; 83 Ecore_Evas_Engine_Drm_Data *edata;
80 Elput_Seat *seat; 84 Ecore_Evas_Engine_Drm_Tick *etick;
81 Elput_Manager *manager; 85 Eina_List *l;
82 Eina_Bool found = EINA_FALSE;
83 Elput_Device_Caps caps;
84 Evas_Device_Class devclass = EVAS_DEVICE_CLASS_NONE;
85 Eo *dev;
86
87 seat = elput_device_seat_get(ev->device);
88 manager = elput_seat_manager_get(seat);
89 caps = elput_device_caps_get(ev->device);
90
91 EINA_LIST_FOREACH(canvases, l, ee)
92 {
93 edata = ee->engine.data;
94 found = edata->dev->em == manager;
95 if (found) break;
96 }
97
98 if (!found) return ECORE_CALLBACK_RENEW;
99 if (caps & ELPUT_DEVICE_CAPS_TABLET_TOOL)
100 devclass = EVAS_DEVICE_CLASS_PEN; // idk how "pen" is a device class?
101 else if (caps & ELPUT_DEVICE_CAPS_POINTER)
102 devclass = EVAS_DEVICE_CLASS_MOUSE;
103 else if (caps & ELPUT_DEVICE_CAPS_TOUCH)
104 devclass = EVAS_DEVICE_CLASS_TOUCH;
105 else if (caps & ELPUT_DEVICE_CAPS_KEYBOARD)
106 devclass = EVAS_DEVICE_CLASS_KEYBOARD;
107 switch (ev->type)
108 {
109 case ELPUT_DEVICE_ADDED:
110 {
111 if (!edata->seat)
112 {
113 Eina_Stringshare *name = elput_seat_name_get(seat);
114 edata->seat = evas_device_add_full(ee->evas, name,
115 "drm seat", NULL, NULL, EVAS_DEVICE_CLASS_SEAT, EVAS_DEVICE_SUBCLASS_NONE);
116 evas_device_seat_id_set(edata->seat, strtol(name, NULL, 10));
117 }
118
119 dev = evas_device_add_full(ee->evas, elput_device_output_name_get(ev->device),
120 "drm device", edata->seat, NULL, devclass, EVAS_DEVICE_SUBCLASS_NONE);
121 ev->device->evas_device = dev;
122 break;
123 }
124 case ELPUT_DEVICE_REMOVED:
125 {
126 EINA_LIST_FOREACH(evas_device_list(ee->evas, edata->seat), l, dev)
127 {
128 if (dev != ev->device->evas_device) continue;
129 evas_device_del(dev);
130 ev->device->evas_device = NULL;
131 break;
132 }
133 break;
134 }
135 }
136
137 return ECORE_CALLBACK_RENEW;
138}
139
140static int
141_ecore_evas_drm_init(Ecore_Evas *ee, Ecore_Evas_Engine_Drm_Data *edata, const char *device)
142{
143 if (++_drm_init_count != 1) return _drm_init_count;
144 86
145 if (!ecore_drm2_init()) 87 ee = data;
146 { 88 edata = ee->engine.data;
147 ERR("Failed to init Ecore_Drm2 library"); 89 edata->tick_job = NULL;
148 goto init_err;
149 }
150
151 /* NB: No seat name passed in, try to get from env */
152 if (!device) device = getenv("XDG_SEAT");
153
154 /* NB: fallback to seat0 if env var is not set */
155 if (!device) device = "seat0";
156
157 edata->dev = ecore_drm2_device_open(device, 0);
158 if (!edata->dev)
159 {
160 ERR("Failed to open device");
161 goto open_err;
162 }
163
164 edata->clockid = ecore_drm2_device_clock_id_get(edata->dev);
165 ecore_drm2_device_cursor_size_get(edata->dev, &edata->cw, &edata->ch);
166 90
167 if (!ecore_drm2_outputs_create(edata->dev)) 91 EINA_LIST_FOREACH(edata->ticks, l, etick)
168 { 92 {
169 ERR("Could not create outputs"); 93 Eina_Rectangle rect;
170 goto output_err; 94 int ox, oy, ow, oh;
171 }
172
173 edata->output = ecore_drm2_output_find(edata->dev, edata->x, edata->y);
174 if (edata->output) ecore_drm2_output_user_data_set(edata->output, ee);
175 else WRN("Could not find output at %d %d", edata->x, edata->y);
176 95
177 ecore_event_evas_init(); 96 ecore_drm2_output_info_get(etick->output, &ox, &oy, &ow, &oh, NULL);
178 if (!handlers) 97 EINA_RECTANGLE_SET(&rect, ox, oy, ow, oh);
179 { 98 /* efl_canvas_output_unlock(etick->canvas); */
180 handlers = 99 ecore_evas_animator_tick(ee, &rect, etick->timestamp);
181 eina_list_append(handlers,
182 ecore_event_handler_add(ELPUT_EVENT_DEVICE_CHANGE,
183 _drm_device_change, NULL));
184 } 100 }
185
186 return _drm_init_count;
187
188output_err:
189 ecore_drm2_device_close(edata->dev);
190open_err:
191 ecore_drm2_shutdown();
192init_err:
193 return --_drm_init_count;
194} 101}
195 102
196static int 103static inline Ecore_Evas_Engine_Drm_Tick *
197_ecore_evas_drm_shutdown(Ecore_Evas_Engine_Drm_Data *edata) 104_drm_tick_get(Ecore_Evas_Engine_Drm_Data *edata, Ecore_Drm2_Output *output)
198{ 105{
199 Ecore_Event_Handler *h; 106 Ecore_Evas_Engine_Drm_Tick *etick;
200 if (--_drm_init_count != 0) return _drm_init_count; 107 Eina_List *l;
201 108
202 if (edata->focus_job) 109 EINA_LIST_FOREACH(edata->ticks, l, etick)
203 { 110 if (etick->output == output) return etick;
204 ecore_job_del(edata->focus_job);
205 edata->focus_job = NULL;
206 }
207 ecore_drm2_outputs_destroy(edata->dev);
208 ecore_drm2_device_close(edata->dev);
209 ecore_drm2_shutdown();
210 ecore_event_evas_shutdown();
211 EINA_LIST_FREE(handlers, h)
212 ecore_event_handler_del(h);
213 111
214 return _drm_init_count; 112 return NULL;
215} 113}
216 114
217static void 115static void
218_drm_free(Ecore_Evas *ee) 116_drm_free(Ecore_Evas *ee)
219{ 117{
220 Ecore_Evas_Engine_Drm_Data *edata; 118 Ecore_Evas_Engine_Drm_Data *edata;
221 119 Ecore_Evas_Engine_Drm_Tick *etick;
222 ecore_evas_input_event_unregister(ee);
223
224 edata = ee->engine.data;
225 canvases = eina_list_remove(canvases, ee);
226 _ecore_evas_drm_shutdown(edata);
227 free(edata);
228}
229
230static void
231_drm_rotation_do(Ecore_Evas *ee, int rotation, int resize)
232{
233 Evas_Engine_Info_Drm *einfo;
234 Ecore_Evas_Engine_Drm_Data *edata;
235 Eina_Bool use_hw = EINA_FALSE;
236 int diff, rotations = 0, orient = 0;
237
238 if (ee->rotation == rotation) return;
239
240 einfo = (Evas_Engine_Info_Drm *)evas_engine_info_get(ee->evas);
241 if (!einfo) return;
242 120
243 edata = ee->engine.data; 121 edata = ee->engine.data;
244 122
245 rotations = ecore_drm2_output_supported_rotations_get(edata->output); 123 EINA_LIST_FREE(edata->ticks, etick)
246 if (rotations >= 0) 124 free(etick);
247 {
248 if (rotations & ECORE_DRM2_ROTATION_NORMAL)
249 {
250 if (rotation == 0)
251 {
252 use_hw = EINA_TRUE;
253 orient = ECORE_DRM2_ROTATION_NORMAL;
254 }
255 }
256
257 if (rotations & ECORE_DRM2_ROTATION_90)
258 {
259 if (rotation == 90)
260 {
261 use_hw = EINA_TRUE;
262 orient = ECORE_DRM2_ROTATION_90;
263 }
264 }
265
266 if (rotations & ECORE_DRM2_ROTATION_180)
267 {
268 if (rotation == 180)
269 {
270 use_hw = EINA_TRUE;
271 orient = ECORE_DRM2_ROTATION_180;
272 }
273 }
274
275 if (rotations & ECORE_DRM2_ROTATION_270)
276 {
277 if (rotation == 270)
278 {
279 use_hw = EINA_TRUE;
280 orient = ECORE_DRM2_ROTATION_270;
281 }
282 }
283 }
284
285 if (use_hw)
286 {
287 ecore_drm2_output_rotation_set(edata->output, orient);
288 ee->rotation = rotation;
289 return;
290 }
291
292 einfo->info.rotation = rotation;
293 if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
294 ERR("evas_engine_info_set() for engine '%s' failed", ee->driver);
295
296 diff = ee->rotation - rotation;
297 if (diff < 0) diff = -diff;
298 125
299 if (diff != 180) 126 ecore_job_del(edata->tick_job);
300 { 127 ecore_evas_input_event_unregister(ee);
301 if (!resize)
302 {
303 int ww, hh;
304
305 if (ECORE_EVAS_PORTRAIT(ee))
306 evas_damage_rectangle_add(ee->evas, 0, 0, ee->req.w, ee->req.h);
307 else
308 evas_damage_rectangle_add(ee->evas, 0, 0, ee->req.h, ee->req.w);
309
310 ww = ee->h;
311 hh = ee->w;
312 ee->w = ww;
313 ee->h = hh;
314 ee->req.w = ww;
315 ee->req.h = hh;
316 }
317 else
318 {
319 if ((rotation == 0) || (rotation == 180))
320 {
321 evas_output_size_set(ee->evas, ee->w, ee->h);
322 evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
323 }
324 else
325 {
326 evas_output_size_set(ee->evas, ee->h, ee->w);
327 evas_output_viewport_set(ee->evas, 0, 0, ee->h, ee->w);
328 }
329 }
330 }
331
332 ee->rotation = rotation;
333
334 if (ee->func.fn_resize) ee->func.fn_resize(ee);
335 128
336 if (ECORE_EVAS_PORTRAIT(ee)) 129 ecore_main_fd_handler_del(edata->hdlr);
337 evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h); 130 edata->hdlr = NULL;
338 else
339 evas_damage_rectangle_add(ee->evas, 0, 0, ee->h, ee->w);
340}
341 131
342static void 132 canvases = eina_list_remove(canvases, ee);
343_drm_render_updates(void *data, Evas *evas EINA_UNUSED, void *event EINA_UNUSED)
344{
345 Ecore_Evas *ee = data;
346 133
347 if (ee->delayed.rotation_changed) 134 _drm_shutdown(edata);
348 { 135 free(edata);
349 _drm_rotation_do(ee, ee->delayed.rotation, ee->delayed.rotation_resize);
350 ee->delayed.rotation_changed = EINA_FALSE;
351 }
352} 136}
353 137
354static void 138static void
355_drm_screen_geometry_get(const Ecore_Evas *ee, int *x, int *y, int *w, int *h) 139_drm_move(Ecore_Evas *ee, int x, int y)
356{ 140{
357 Ecore_Evas_Engine_Drm_Data *edata; 141 ee->req.x = x;
358 142 ee->req.y = y;
359 edata = ee->engine.data; 143 if ((ee->x == x) && (ee->y == y)) return;
360 ecore_drm2_output_info_get(edata->output, x, y, w, h, NULL); 144 ee->x = x;
145 ee->y = y;
146 if (ee->func.fn_move) ee->func.fn_move(ee);
361} 147}
362 148
363static void 149static void
364_drm_screen_dpi_get(const Ecore_Evas *ee, int *xdpi, int *ydpi) 150_drm_resize(Ecore_Evas *ee, int w, int h)
365{ 151{
366 Ecore_Evas_Engine_Drm_Data *edata; 152 ee->req.w = w;
367 153 ee->req.h = h;
368 edata = ee->engine.data; 154 if ((ee->w == w) && (ee->h == h)) return;
369 ecore_drm2_output_dpi_get(edata->output, xdpi, ydpi); 155 ee->w = w;
156 ee->h = h;
157 evas_output_size_set(ee->evas, w, h);
158 evas_output_viewport_set(ee->evas, 0, 0, w, h);
159 if (ee->func.fn_resize) ee->func.fn_resize(ee);
370} 160}
371 161
372static void 162static void
373_drm_pointer_xy_get(const Ecore_Evas *ee, Evas_Coord *x, Evas_Coord *y) 163_drm_move_resize(Ecore_Evas *ee, int x, int y, int w, int h)
374{
375 Ecore_Evas_Engine_Drm_Data *edata;
376
377 edata = ee->engine.data;
378 ecore_drm2_device_pointer_xy_get(edata->dev, x, y);
379}
380
381static Eina_Bool
382_drm_pointer_warp(const Ecore_Evas *ee, Evas_Coord x, Evas_Coord y)
383{ 164{
384 Ecore_Evas_Engine_Drm_Data *edata; 165 if ((ee->x != x) || (ee->y != y))
385 166 _drm_move(ee, x, y);
386 edata = ee->engine.data; 167 if ((ee->w != w) || (ee->h != h))
387 ecore_drm2_device_pointer_warp(edata->dev, x, y); 168 _drm_resize(ee, w, h);
388 return EINA_TRUE;
389} 169}
390 170
391static void 171static void
@@ -402,10 +182,15 @@ _drm_show_focus_job(void *data)
402static void 182static void
403_drm_show(Ecore_Evas *ee) 183_drm_show(Ecore_Evas *ee)
404{ 184{
185 /* Ecore_Drm2_Output *output; */
186 Ecore_Evas_Engine_Drm_Tick *etick;
405 Ecore_Evas_Engine_Drm_Data *edata; 187 Ecore_Evas_Engine_Drm_Data *edata;
188 Eina_List *l;
406 189
407 if ((!ee) || (ee->visible)) return; 190 if ((!ee) || (ee->visible)) return;
408 191
192 edata = ee->engine.data;
193
409 ee->should_be_visible = 1; 194 ee->should_be_visible = 1;
410 195
411 if (ee->prop.avoid_damage) 196 if (ee->prop.avoid_damage)
@@ -420,19 +205,28 @@ _drm_show(Ecore_Evas *ee)
420 if (ee->func.fn_state_change) ee->func.fn_state_change(ee); 205 if (ee->func.fn_state_change) ee->func.fn_state_change(ee);
421 } 206 }
422 207
423 if (ee->visible) return;
424
425 ee->visible = 1; 208 ee->visible = 1;
209 if (ee->prop.fullscreen)
210 {
211 evas_focus_in(ee->evas);
212 if (ee->func.fn_focus_in) ee->func.fn_focus_in(ee);
213 }
214
426 if (ee->func.fn_show) ee->func.fn_show(ee); 215 if (ee->func.fn_show) ee->func.fn_show(ee);
427 216
428 edata = ee->engine.data;
429 edata->focus_job = ecore_job_add(_drm_show_focus_job, ee);
430 /* HACK: sometimes we still have an animator ticking when we vc switch 217 /* HACK: sometimes we still have an animator ticking when we vc switch
431 * so for now we just fire off a flip here to kick it when we come back. 218 * so for now we just fire off a flip here to kick it when we come back.
432 * This is just papering over a bug for now until I have time to track 219 * This is just papering over a bug for now until I have time to track
433 * it down properly. :( 220 * it down properly. :(
434 */ 221 */
435 ecore_drm2_fb_flip(NULL, edata->output); 222 /* EINA_LIST_FOREACH(outputs, l, output) */
223 /* ecore_drm2_fb_flip(NULL, output); */
224
225 EINA_LIST_FOREACH(edata->ticks, l, etick)
226 {
227 /* efl_canvas_output_lock(etick->canvas); */
228 ecore_drm2_fb_flip(NULL, etick->output);
229 }
436} 230}
437 231
438static void 232static void
@@ -455,54 +249,6 @@ _drm_hide(Ecore_Evas *ee)
455} 249}
456 250
457static void 251static void
458_drm_move(Ecore_Evas *ee, int x, int y)
459{
460 ee->req.x = x;
461 ee->req.y = y;
462 if ((ee->x == x) && (ee->y == y)) return;
463 ee->x = x;
464 ee->y = y;
465 if (ee->func.fn_move) ee->func.fn_move(ee);
466}
467
468static void
469_drm_resize(Ecore_Evas *ee, int w, int h)
470{
471 ee->req.w = w;
472 ee->req.h = h;
473 if ((ee->w == w) && (ee->h == h)) return;
474 ee->w = w;
475 ee->h = h;
476 evas_output_size_set(ee->evas, w, h);
477 evas_output_viewport_set(ee->evas, 0, 0, w, h);
478 if (ee->func.fn_resize) ee->func.fn_resize(ee);
479}
480
481static void
482_drm_move_resize(Ecore_Evas *ee, int x, int y, int w, int h)
483{
484 if ((ee->x != x) || (ee->y != y))
485 _drm_move(ee, x, y);
486 if ((ee->w != w) || (ee->h != h))
487 _drm_resize(ee, w, h);
488}
489
490static void
491_drm_rotation_set(Ecore_Evas *ee, int rotation, int resize)
492{
493 if (ee->rotation == rotation) return;
494
495 if (ee->in_async_render)
496 {
497 ee->delayed.rotation = rotation;
498 ee->delayed.rotation_resize = resize;
499 ee->delayed.rotation_changed = EINA_TRUE;
500 }
501 else
502 _drm_rotation_do(ee, rotation, resize);
503}
504
505static void
506_drm_title_set(Ecore_Evas *ee, const char *title) 252_drm_title_set(Ecore_Evas *ee, const char *title)
507{ 253{
508 if (eina_streq(ee->prop.title, title)) return; 254 if (eina_streq(ee->prop.title, title)) return;
@@ -592,53 +338,6 @@ _drm_maximized_set(Ecore_Evas *ee, Eina_Bool on)
592} 338}
593 339
594static void 340static void
595_drm_fullscreen_set(Ecore_Evas *ee, Eina_Bool on)
596{
597 Eina_Bool resized = EINA_FALSE;
598 Ecore_Evas_Engine_Drm_Data *edata;
599
600 edata = ee->engine.data;
601 if (ee->prop.fullscreen == on) return;
602 ee->prop.fullscreen = on;
603
604 if (on)
605 {
606 int ow = 0, oh = 0;
607
608 edata->w = ee->w;
609 edata->h = ee->h;
610
611 ecore_drm2_output_info_get(edata->output, NULL, NULL, &ow, &oh, NULL);
612 if ((ow == 0) || (oh == 0))
613 {
614 ow = ee->w;
615 oh = ee->h;
616 }
617 if ((ow != ee->w) || (oh != ee->h)) resized = EINA_TRUE;
618 ee->w = ow;
619 ee->h = oh;
620 }
621 else
622 {
623 if ((edata->w != ee->w) || (edata->h != ee->h)) resized = EINA_TRUE;
624 ee->w = edata->w;
625 ee->h = edata->h;
626 }
627
628 ee->req.w = ee->w;
629 ee->req.h = ee->h;
630 ee->prop.fullscreen = on;
631 evas_output_size_set(ee->evas, ee->w, ee->h);
632 evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
633 evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
634
635 if (resized)
636 {
637 if (ee->func.fn_resize) ee->func.fn_resize(ee);
638 }
639}
640
641static void
642_drm_withdrawn_set(Ecore_Evas *ee, Eina_Bool on) 341_drm_withdrawn_set(Ecore_Evas *ee, Eina_Bool on)
643{ 342{
644 if (ee->prop.withdrawn == on) return; 343 if (ee->prop.withdrawn == on) return;
@@ -681,161 +380,135 @@ _drm_aspect_set(Ecore_Evas *ee, double aspect)
681 ee->prop.aspect = aspect; 380 ee->prop.aspect = aspect;
682} 381}
683 382
684static Ecore_Evas_Interface_Drm * 383static void
685_ecore_evas_drm_interface_new(void) 384_drm_screen_geometry_get(const Ecore_Evas *ee EINA_UNUSED, int *x, int *y, int *w, int *h)
686{ 385{
687 Ecore_Evas_Interface_Drm *iface; 386 Ecore_Drm2_Output *output;
688 387 Eina_List *l;
689 iface = calloc(1, sizeof(Ecore_Evas_Interface_Drm)); 388 int ox, oy, ow, oh;
690 if (!iface) return NULL;
691
692 iface->base.name = "drm";
693 iface->base.version = 1;
694
695 return iface;
696}
697 389
698static Eina_Bool 390 if (x) *x = 0;
699_cb_drm_event(void *data, Ecore_Fd_Handler *hdlr EINA_UNUSED) 391 if (y) *y = 0;
700{
701 Ecore_Evas *ee;
702 Ecore_Evas_Engine_Drm_Data *edata;
703 int ret;
704 392
705 ee = data; 393 EINA_LIST_FOREACH(outputs, l, output)
706 edata = ee->engine.data;
707 ret = ecore_drm2_event_handle(edata->dev, &edata->ctx);
708 if (ret)
709 { 394 {
710 WRN("drmHandleEvent failed to read an event"); 395 ecore_drm2_output_info_get(output, &ox, &oy, &ow, &oh, NULL);
711 return EINA_FALSE; 396 if (w) *w += MAX(*w, ow);
397 if (h) *h = MAX(*h, oh);
712 } 398 }
713
714 return EINA_TRUE;
715} 399}
716 400
717static void 401static void
718_cb_pageflip(int fd EINA_UNUSED, unsigned int frame EINA_UNUSED, unsigned int sec, unsigned int usec, void *data) 402_drm_screen_dpi_get(const Ecore_Evas *ee EINA_UNUSED, int *xdpi, int *ydpi)
719{ 403{
720 Ecore_Evas *ee;
721 Ecore_Drm2_Output *output; 404 Ecore_Drm2_Output *output;
722 Ecore_Evas_Engine_Drm_Data *edata;
723 int ret;
724
725 output = data;
726
727 ee = ecore_drm2_output_user_data_get(output);
728 if (!ee) return;
729
730 edata = ee->engine.data;
731 405
732 ret = ecore_drm2_fb_flip_complete(output); 406 if (xdpi) *xdpi = 0;
407 if (ydpi) *ydpi = 0;
733 408
734 if (edata->ticking) 409 output = eina_list_data_get(outputs);
735 { 410 if (!output) return;
736 int x, y, w, h;
737 double t = (double)sec + ((double)usec / 1000000);
738 411
739 ecore_drm2_output_info_get(output, &x, &y, &w, &h, NULL); 412 ecore_drm2_output_dpi_get(output, xdpi, ydpi);
740
741 if (!edata->once) t = ecore_time_get();
742 ecore_evas_animator_tick(ee, &(Eina_Rectangle){x, y, w, h},
743 t - edata->offset);
744 }
745 else if (ret)
746 ecore_drm2_fb_flip(NULL, output);
747} 413}
748 414
749static void 415static void
750_drm_evas_changed(Ecore_Evas *ee, Eina_Bool changed) 416_drm_pointer_xy_get(const Ecore_Evas *ee, Evas_Coord *x, Evas_Coord *y)
751{ 417{
752 Ecore_Evas_Engine_Drm_Data *edata; 418 Ecore_Evas_Engine_Drm_Data *edata;
753 419
754 if (changed) return;
755
756 edata = ee->engine.data; 420 edata = ee->engine.data;
757 if (edata->ticking && !ecore_drm2_output_pending_get(edata->output)) 421 ecore_drm2_device_pointer_xy_get(edata->dev, x, y);
758 ecore_drm2_fb_flip(NULL, edata->output);
759} 422}
760 423
761static void 424static Eina_Bool
762_tick_job(void *data) 425_drm_pointer_warp(const Ecore_Evas *ee, Evas_Coord x, Evas_Coord y)
763{ 426{
764 Ecore_Evas_Engine_Drm_Data *edata; 427 Ecore_Evas_Engine_Drm_Data *edata;
765 Ecore_Evas *ee;
766 int x, y, w, h;
767 428
768 ee = data;
769 edata = ee->engine.data; 429 edata = ee->engine.data;
770 edata->tick_job = NULL; 430 ecore_drm2_device_pointer_warp(edata->dev, x, y);
771 431 return EINA_TRUE;
772 ecore_drm2_output_info_get(edata->output, &x, &y, &w, &h, NULL);
773
774 ecore_evas_animator_tick(ee, &(Eina_Rectangle){x, y, w, h},
775 edata->tick_job_timestamp - edata->offset);
776} 432}
777 433
778static void 434static void
779_drm_animator_register(Ecore_Evas *ee) 435_drm_animator_register(Ecore_Evas *ee)
780{ 436{
781 double t;
782 long sec, usec;
783 Ecore_Evas_Engine_Drm_Data *edata; 437 Ecore_Evas_Engine_Drm_Data *edata;
784 Eina_Bool r; 438 Ecore_Evas_Engine_Drm_Tick *etick;
439 Ecore_Drm2_Output *output;
440 Eina_List *l;
785 441
786 if (ee->manual_render) 442 if (ee->manual_render)
787 ERR("Attempt to schedule tick for manually rendered canvas"); 443 {
444 ERR("Attempt to schedule tick for manually rendered canvas");
445 /* return; */
446 }
788 447
789 edata = ee->engine.data; 448 edata = ee->engine.data;
790 449
791 /* Some graphics stacks appear to lie about their clock sources
792 * so attempt to measure the difference between our clock and the
793 * GPU's source of timestamps once at startup and apply that.
794 * If it's tiny, just assume they're the same clock and it's
795 * measurement error.
796 *
797 * <cedric> what happen when you suspend ?
798 * <cedric> what about drift ?
799 *
800 * If someone could relay the message to cedric that I'm not
801 * talking to him anymore, that would be helpful.
802 */
803 if (!edata->once) 450 if (!edata->once)
804 { 451 {
805 r = ecore_drm2_output_blanktime_get(edata->output, 1, &sec, &usec); 452 EINA_LIST_FOREACH(outputs, l, output)
806 if (r)
807 { 453 {
808 t = (double)sec + ((double)usec / 1000000.0); 454 Eina_Bool r = EINA_FALSE;
809 edata->offset = t - ecore_time_get(); 455 double t = 0.0;
810 if (fabs(edata->offset) < 0.010) 456 long sec, usec;
811 edata->offset = 0.0; 457
458 r = ecore_drm2_output_blanktime_get(output, 1, &sec, &usec);
459 if (!r) continue;
460
461 etick = _drm_tick_get(edata, output);
462 if (!etick) continue;
812 463
813 edata->once = EINA_TRUE; 464 t = (double)sec + ((double)usec / 1000000.0);
465 etick->offset = t - ecore_time_get();
466 if (fabs(etick->offset) < 0.010)
467 etick->offset = 0.0;
814 } 468 }
469 edata->once = EINA_TRUE;
815 } 470 }
816 471
817 if (ee->animator_ticked || ee->animator_ran) 472 if (edata->tick_job)
818 { 473 {
819 edata->ticking = EINA_TRUE; 474 ERR("Double animator register");
820 return; 475 return;
821 } 476 }
822 477
823 if (edata->tick_job) ERR("Double animator register"); 478 EINA_LIST_FOREACH(outputs, l, output)
824 else
825 if (!edata->ticking &&
826 !(ecore_drm2_output_pending_get(edata->output) || ee->in_async_render))
827 { 479 {
828 r = ecore_drm2_output_blanktime_get(edata->output, 0, &sec, &usec); 480 Eina_Bool r = EINA_FALSE;
829 if (r) 481 long sec, usec;
482
483 if (!edata->ticking &&
484 !(ecore_drm2_output_pending_get(output) || ee->in_async_render))
830 { 485 {
831 edata->tick_job_timestamp = (double)sec 486 r = ecore_drm2_output_blanktime_get(output, 0, &sec, &usec);
832 + ((double)usec / 1000000); 487 if (r)
833 edata->tick_job = ecore_job_add(_tick_job, ee); 488 {
489 etick = _drm_tick_get(edata, output);
490 if (!etick) continue;
491
492 etick->timestamp = (double)sec + ((double)usec / 1000000.0);
493 }
834 } 494 }
835 else 495 else
836 ecore_drm2_fb_flip(NULL, edata->output); 496 ecore_drm2_fb_flip(NULL, edata->output);
837 } 497 }
838 498
499 if (!edata->ticking)
500 edata->tick_job = ecore_job_add(_cb_tick, ee);
501
502 EINA_LIST_FOREACH(edata->ticks, l, etick)
503 {
504 if ((!ecore_drm2_output_pending_get(etick->output)) &&
505 !ee->in_async_render)
506 {
507 /* efl_canvas_output_lock(etick->canvas); */
508 ecore_drm2_fb_flip(NULL, etick->output);
509 }
510 }
511
839 edata->ticking = EINA_TRUE; 512 edata->ticking = EINA_TRUE;
840} 513}
841 514
@@ -846,28 +519,59 @@ _drm_animator_unregister(Ecore_Evas *ee)
846 519
847 edata = ee->engine.data; 520 edata = ee->engine.data;
848 edata->ticking = EINA_FALSE; 521 edata->ticking = EINA_FALSE;
522
849 if (edata->tick_job) 523 if (edata->tick_job)
850 { 524 {
851 ERR("Animator unregister before first tick");
852 ecore_job_del(edata->tick_job); 525 ecore_job_del(edata->tick_job);
853 edata->tick_job = NULL; 526 edata->tick_job = NULL;
854 } 527 }
855} 528}
856 529
857static double 530static void
858_drm_last_tick_get(Ecore_Evas *ee) 531_drm_evas_changed(Ecore_Evas *ee, Eina_Bool changed)
859{ 532{
860 Ecore_Evas_Engine_Drm_Data *edata; 533 Ecore_Evas_Engine_Drm_Data *edata;
861 long sec, usec; 534 Ecore_Evas_Engine_Drm_Tick *etick;
535 Eina_List *l;
536
537 if (changed) return;
862 538
863 edata = ee->engine.data; 539 edata = ee->engine.data;
864 if (!ecore_drm2_output_blanktime_get(edata->output, 0, &sec, &usec)) 540 if (!edata->ticking) return;
865 return -1.0;
866 541
867 return sec + usec / 1000000.0; 542 EINA_LIST_FOREACH(edata->ticks, l, etick)
543 {
544 if (!ecore_drm2_output_pending_get(etick->output))
545 {
546 /* efl_canvas_output_lock(etick->canvas); */
547 ecore_drm2_fb_flip(NULL, etick->output);
548 }
549 }
868} 550}
869 551
870static Ecore_Evas_Engine_Func _ecore_evas_drm_engine_func = 552static double
553_drm_last_tick_get(Ecore_Evas *ee EINA_UNUSED)
554{
555 Ecore_Drm2_Output *output;
556 Eina_List *l;
557 long sec, usec;
558 double tmp = 0.0;
559
560 EINA_LIST_FOREACH(outputs, l, output)
561 {
562 if (!ecore_drm2_output_blanktime_get(output, 0, &sec, &usec))
563 tmp = -1.0;
564 else
565 {
566 if ((sec + usec / 1000000.0) > tmp)
567 tmp = sec + usec / 1000000.0;
568 }
569 }
570
571 return tmp;
572}
573
574static Ecore_Evas_Engine_Func _drm_engine_func =
871{ 575{
872 _drm_free, 576 _drm_free,
873 NULL, //void (*fn_callback_resize_set) (Ecore_Evas *ee, Ecore_Evas_Event_Cb func); 577 NULL, //void (*fn_callback_resize_set) (Ecore_Evas *ee, Ecore_Evas_Event_Cb func);
@@ -888,7 +592,7 @@ static Ecore_Evas_Engine_Func _ecore_evas_drm_engine_func =
888 NULL, //void (*fn_managed_move) (Ecore_Evas *ee, int x, int y); 592 NULL, //void (*fn_managed_move) (Ecore_Evas *ee, int x, int y);
889 _drm_resize, 593 _drm_resize,
890 _drm_move_resize, 594 _drm_move_resize,
891 _drm_rotation_set, 595 NULL, //_drm_rotation_set,
892 NULL, //void (*fn_shaped_set) (Ecore_Evas *ee, int shaped); 596 NULL, //void (*fn_shaped_set) (Ecore_Evas *ee, int shaped);
893 _drm_show, 597 _drm_show,
894 _drm_hide, 598 _drm_hide,
@@ -909,7 +613,7 @@ static Ecore_Evas_Engine_Func _ecore_evas_drm_engine_func =
909 _drm_borderless_set, 613 _drm_borderless_set,
910 NULL, //void (*fn_override_set) (Ecore_Evas *ee, Eina_Bool on); 614 NULL, //void (*fn_override_set) (Ecore_Evas *ee, Eina_Bool on);
911 _drm_maximized_set, 615 _drm_maximized_set,
912 _drm_fullscreen_set, 616 NULL, //_drm_fullscreen_set,
913 NULL, //void (*fn_avoid_damage_set) (Ecore_Evas *ee, int on); 617 NULL, //void (*fn_avoid_damage_set) (Ecore_Evas *ee, int on);
914 _drm_withdrawn_set, 618 _drm_withdrawn_set,
915 NULL, //void (*fn_sticky_set) (Ecore_Evas *ee, Eina_Bool on); 619 NULL, //void (*fn_sticky_set) (Ecore_Evas *ee, Eina_Bool on);
@@ -918,35 +622,27 @@ static Ecore_Evas_Engine_Func _ecore_evas_drm_engine_func =
918 _drm_transparent_set, 622 _drm_transparent_set,
919 NULL, //void (*fn_profiles_set) (Ecore_Evas *ee, const char **profiles, int count); 623 NULL, //void (*fn_profiles_set) (Ecore_Evas *ee, const char **profiles, int count);
920 NULL, //void (*fn_profile_set) (Ecore_Evas *ee, const char *profile); 624 NULL, //void (*fn_profile_set) (Ecore_Evas *ee, const char *profile);
921
922 NULL, //void (*fn_window_group_set) (Ecore_Evas *ee, const Ecore_Evas *ee_group); 625 NULL, //void (*fn_window_group_set) (Ecore_Evas *ee, const Ecore_Evas *ee_group);
923 _drm_aspect_set, 626 _drm_aspect_set,
924 NULL, //void (*fn_urgent_set) (Ecore_Evas *ee, Eina_Bool on); 627 NULL, //void (*fn_urgent_set) (Ecore_Evas *ee, Eina_Bool on);
925 NULL, //void (*fn_modal_set) (Ecore_Evas *ee, Eina_Bool on); 628 NULL, //void (*fn_modal_set) (Ecore_Evas *ee, Eina_Bool on);
926 NULL, //void (*fn_demands_attention_set) (Ecore_Evas *ee, Eina_Bool on); 629 NULL, //void (*fn_demands_attention_set) (Ecore_Evas *ee, Eina_Bool on);
927 NULL, //void (*fn_focus_skip_set) (Ecore_Evas *ee, Eina_Bool on); 630 NULL, //void (*fn_focus_skip_set) (Ecore_Evas *ee, Eina_Bool on);
928
929 NULL, 631 NULL,
930
931 _drm_screen_geometry_get, 632 _drm_screen_geometry_get,
932 _drm_screen_dpi_get, 633 _drm_screen_dpi_get,
933 NULL, //void (*fn_msg_parent_send) (Ecore_Evas *ee, int maj, int min, void *data, int size); 634 NULL, //void (*fn_msg_parent_send) (Ecore_Evas *ee, int maj, int min, void *data, int size);
934 NULL, //void (*fn_msg_send) (Ecore_Evas *ee, int maj, int min, void *data, int size); 635 NULL, //void (*fn_msg_send) (Ecore_Evas *ee, int maj, int min, void *data, int size);
935
936 _drm_pointer_xy_get, 636 _drm_pointer_xy_get,
937 _drm_pointer_warp, 637 _drm_pointer_warp,
938
939 NULL, // wm_rot_preferred_rotation_set 638 NULL, // wm_rot_preferred_rotation_set
940 NULL, // wm_rot_available_rotations_set 639 NULL, // wm_rot_available_rotations_set
941 NULL, // wm_rot_manual_rotation_done_set 640 NULL, // wm_rot_manual_rotation_done_set
942 NULL, // wm_rot_manual_rotation_done 641 NULL, // wm_rot_manual_rotation_done
943
944 NULL, // aux_hints_set 642 NULL, // aux_hints_set
945 643 _drm_animator_register,
946 _drm_animator_register, // animator_register 644 _drm_animator_unregister,
947 _drm_animator_unregister, // animator_unregister 645 _drm_evas_changed,
948
949 _drm_evas_changed, // evas_changed
950 NULL, //fn_focus_device_set 646 NULL, //fn_focus_device_set
951 NULL, //fn_callback_focus_device_in_set 647 NULL, //fn_callback_focus_device_in_set
952 NULL, //fn_callback_focus_device_out_set 648 NULL, //fn_callback_focus_device_out_set
@@ -957,186 +653,384 @@ static Ecore_Evas_Engine_Func _ecore_evas_drm_engine_func =
957 _drm_last_tick_get, 653 _drm_last_tick_get,
958}; 654};
959 655
960#ifdef BUILD_ECORE_EVAS_GL_DRM 656static Eina_Bool
961static void * 657_cb_drm_event(void *data, Ecore_Fd_Handler *hdlr EINA_UNUSED)
962_drm_gl_canvas_setup(Ecore_Evas *ee, Ecore_Evas_Engine_Drm_Data *edata)
963{ 658{
964 Evas_Engine_Info_GL_Drm *einfo; 659 Ecore_Evas *ee;
965 char *num; 660 Ecore_Evas_Engine_Drm_Data *edata;
661 int ret = 0;
662
663 ee = data;
664 edata = ee->engine.data;
665
666 ret = ecore_drm2_event_handle(edata->dev, &edata->ctx);
667 if (ret)
668 {
669 WRN("drmHandleEvent failed to read an event");
670 return EINA_FALSE;
671 }
966 672
967 einfo = (Evas_Engine_Info_GL_Drm *)evas_engine_info_get(ee->evas); 673 return EINA_TRUE;
968 if (!einfo) return NULL; 674}
969 675
970 einfo->info.vsync = EINA_TRUE; 676static void
677_cb_pageflip(int fd EINA_UNUSED, unsigned int frame EINA_UNUSED, unsigned int sec, unsigned int usec, void *data)
678{
679 Ecore_Evas *ee;
680 Ecore_Evas_Engine_Drm_Data *edata;
681 Ecore_Drm2_Output *output;
682 int ret = 0;
971 683
972 num = getenv("EVAS_DRM_VSYNC"); 684 output = data;
973 if ((num) && (!atoi(num))) 685 ee = ecore_drm2_output_user_data_get(output);
974 einfo->info.vsync = EINA_FALSE; 686 edata = ee->engine.data;
975 687
976 einfo->info.dev = edata->dev; 688 fprintf(stderr, "Pageflip Complete For Output %s\n",
977 einfo->info.bpp = edata->bpp; 689 ecore_drm2_output_name_get(output));
978 einfo->info.depth = edata->depth;
979 einfo->info.format = edata->format;
980 einfo->info.rotation = ee->rotation;
981 einfo->info.output = edata->output;
982 690
983 return einfo; 691 ret = ecore_drm2_fb_flip_complete(output);
692 if (edata->ticking)
693 {
694 Ecore_Evas_Engine_Drm_Tick *etick;
695 double t;
696
697 t = (double)sec + ((double)usec / 1000000);
698 if (!edata->once) t = ecore_time_get();
699
700 etick = _drm_tick_get(edata, output);
701 if (etick)
702 {
703 Eina_Rectangle rect;
704 int ox, oy, ow, oh;
705
706 ecore_drm2_output_info_get(output, &ox, &oy, &ow, &oh, NULL);
707 EINA_RECTANGLE_SET(&rect, ox, oy, ow, oh);
708 /* efl_canvas_output_unlock(etick->canvas); */
709 ecore_evas_animator_tick(ee, &rect, t - etick->offset);
710 }
711 }
712 else if (ret)
713 {
714 Ecore_Evas_Engine_Drm_Tick *etick;
715
716 etick = _drm_tick_get(edata, output);
717 if (etick)
718 {
719 /* efl_canvas_output_lock(etick->canvas); */
720 ecore_drm2_fb_flip(NULL, etick->output);
721 }
722 }
723}
724
725static Eina_Bool
726_cb_device_change(void *d EINA_UNUSED, int t EINA_UNUSED, void *event)
727{
728 Elput_Event_Device_Change *ev = event;
729 const Eina_List *l;
730 Ecore_Evas *ee;
731 Ecore_Evas_Engine_Drm_Data *edata;
732 Elput_Seat *seat;
733 Elput_Manager *manager;
734 Eina_Bool found = EINA_FALSE;
735 Elput_Device_Caps caps;
736 Evas_Device_Class devclass = EVAS_DEVICE_CLASS_NONE;
737 Eo *dev;
738
739 seat = elput_device_seat_get(ev->device);
740 manager = elput_seat_manager_get(seat);
741 caps = elput_device_caps_get(ev->device);
742
743 EINA_LIST_FOREACH(canvases, l, ee)
744 {
745 edata = ee->engine.data;
746 found = edata->dev->em == manager;
747 if (found) break;
748 }
749
750 if (!found) return ECORE_CALLBACK_RENEW;
751 if (caps & ELPUT_DEVICE_CAPS_TABLET_TOOL)
752 devclass = EVAS_DEVICE_CLASS_PEN; // idk how "pen" is a device class?
753 else if (caps & ELPUT_DEVICE_CAPS_POINTER)
754 devclass = EVAS_DEVICE_CLASS_MOUSE;
755 else if (caps & ELPUT_DEVICE_CAPS_TOUCH)
756 devclass = EVAS_DEVICE_CLASS_TOUCH;
757 else if (caps & ELPUT_DEVICE_CAPS_KEYBOARD)
758 devclass = EVAS_DEVICE_CLASS_KEYBOARD;
759 switch (ev->type)
760 {
761 case ELPUT_DEVICE_ADDED:
762 {
763 if (!edata->seat)
764 {
765 Eina_Stringshare *name;
766
767 name = elput_seat_name_get(seat);
768 edata->seat =
769 evas_device_add_full(ee->evas, name, "drm seat", NULL, NULL,
770 EVAS_DEVICE_CLASS_SEAT,
771 EVAS_DEVICE_SUBCLASS_NONE);
772 evas_device_seat_id_set(edata->seat, strtol(name, NULL, 10));
773 }
774
775 dev =
776 evas_device_add_full(ee->evas,
777 elput_device_output_name_get(ev->device),
778 "drm device", edata->seat, NULL, devclass,
779 EVAS_DEVICE_SUBCLASS_NONE);
780 ev->device->evas_device = dev;
781 break;
782 }
783 case ELPUT_DEVICE_REMOVED:
784 {
785 EINA_LIST_FOREACH(evas_device_list(ee->evas, edata->seat), l, dev)
786 {
787 if (dev != ev->device->evas_device) continue;
788 evas_device_del(dev);
789 ev->device->evas_device = NULL;
790 break;
791 }
792 break;
793 }
794 }
795
796 return ECORE_CALLBACK_RENEW;
984} 797}
985#endif
986 798
987static void * 799static int
988_drm_canvas_setup(Ecore_Evas *ee, Ecore_Evas_Engine_Drm_Data *edata) 800_drm_init(Ecore_Evas_Engine_Drm_Data *edata, const char *device)
989{ 801{
990 Evas_Engine_Info_Drm *einfo; 802 if (++_drm_init_count != 1) return _drm_init_count;
803
804 if (!ecore_drm2_init())
805 {
806 ERR("Failed to init Ecore_Drm2 library");
807 goto init_err;
808 }
809
810 if (!device) device = "seat0";
811
812 edata->dev = ecore_drm2_device_open(device, 0);
813 if (!edata->dev)
814 {
815 ERR("Failed to open drm device");
816 goto open_err;
817 }
818
819 if (!ecore_drm2_outputs_create(edata->dev))
820 {
821 ERR("Failed to create drm outputs");
822 goto output_err;
823 }
824
825 ecore_event_evas_init();
991 826
992 einfo = (Evas_Engine_Info_Drm *)evas_engine_info_get(ee->evas); 827 if (!devhdlr)
993 if (!einfo) return NULL; 828 {
829 devhdlr =
830 ecore_event_handler_add(ELPUT_EVENT_DEVICE_CHANGE,
831 _cb_device_change, NULL);
832 }
994 833
995 einfo->info.dev = edata->dev; 834 return _drm_init_count;
996 einfo->info.bpp = edata->bpp;
997 einfo->info.depth = edata->depth;
998 einfo->info.format = edata->format;
999 einfo->info.rotation = ee->rotation;
1000 einfo->info.output = edata->output;
1001 835
1002 return einfo; 836output_err:
837 ecore_drm2_device_close(edata->dev);
838open_err:
839 ecore_drm2_shutdown();
840init_err:
841 return --_drm_init_count;
842}
843
844static int
845_drm_shutdown(Ecore_Evas_Engine_Drm_Data *edata)
846{
847 if (--_drm_init_count != 0) return _drm_init_count;
848
849 ecore_event_handler_del(devhdlr);
850
851 ecore_event_evas_shutdown();
852 ecore_drm2_outputs_destroy(edata->dev);
853 ecore_drm2_device_close(edata->dev);
854 ecore_drm2_shutdown();
855
856 return _drm_init_count;
857}
858
859static Ecore_Evas_Interface_Drm *
860_drm_interface_new(void)
861{
862 Ecore_Evas_Interface_Drm *iface;
863
864 iface = calloc(1, sizeof(Ecore_Evas_Interface_Drm));
865 if (!iface) return NULL;
866
867 iface->base.name = "drm";
868 iface->base.version = 1;
869
870 return iface;
871}
872
873static void
874_ecore_evas_drm_canvas_setup(Ecore_Evas *ee, Ecore_Evas_Engine_Drm_Data *edata)
875{
876 Ecore_Drm2_Output *output;
877 Eina_List *outs, *l;
878
879 outs = (Eina_List *)ecore_drm2_outputs_get(edata->dev);
880 EINA_LIST_FOREACH(outs, l, output)
881 {
882 Efl_Canvas_Output *eout;
883 Evas_Engine_Info_Drm *einfo;
884 Ecore_Evas_Engine_Drm_Tick *etick;
885 int ox, oy, ow, oh;
886
887 if (!ecore_drm2_output_connected_get(output)) continue;
888 if (!ecore_drm2_output_enabled_get(output)) continue;
889
890 eout = efl_canvas_output_add(ee->evas);
891 if (!eout) continue;
892
893 /* efl_canvas_output_lock(eout); */
894
895 einfo = (Evas_Engine_Info_Drm *)efl_canvas_output_engine_info_get(eout);
896 if (!einfo)
897 {
898 efl_canvas_output_del(eout);
899 continue;
900 }
901
902 einfo->info.dev = edata->dev;
903 einfo->info.bpp = 32;
904 einfo->info.depth = 24;
905 einfo->info.alpha = ee->alpha;
906 einfo->info.rotation = ee->rotation;
907 einfo->info.format = DRM_FORMAT_XRGB8888;
908 einfo->info.output = output;
909
910 ecore_drm2_output_info_get(output, &ox, &oy, &ow, &oh, NULL);
911
912 fprintf(stderr, "Ecore_Evas_Drm: Adding Canvas for Output %s At %d %d %d %d\n",
913 ecore_drm2_output_name_get(output), ox, oy, ow, oh);
914
915 efl_canvas_output_view_set(eout, ox, oy, ow, oh);
916 efl_canvas_output_engine_info_set(eout, (Evas_Engine_Info *)einfo);
917
918 ecore_drm2_output_user_data_set(output, ee);
919
920 if (ecore_drm2_output_primary_get(output))
921 {
922 ee->prop.window = ecore_drm2_output_crtc_get(output);
923 ecore_drm2_device_window_set(edata->dev, ee->prop.window);
924 }
925
926 outputs = eina_list_append(outputs, output);
927
928 etick = calloc(1, sizeof(Ecore_Evas_Engine_Drm_Tick));
929 if (!etick) continue;
930
931 etick->canvas = eout;
932 etick->output = output;
933 if (edata->once) etick->offset = 0.0;
934
935 edata->ticks = eina_list_append(edata->ticks, etick);
936 }
1003} 937}
1004 938
1005static Ecore_Evas * 939static Ecore_Evas *
1006_ecore_evas_new_internal(const char *device, int x, int y, int w, int h, Eina_Bool gl) 940_ecore_evas_new_internal(const char *device, int x, int y, int w, int h, Eina_Bool gl)
1007{ 941{
1008 Ecore_Evas *ee; 942 Ecore_Evas *ee;
1009 Ecore_Evas_Interface_Drm *iface;
1010 Ecore_Evas_Engine_Drm_Data *edata; 943 Ecore_Evas_Engine_Drm_Data *edata;
1011 int method, mw, mh; 944 int method = 0;
1012 void *tinfo;
1013 945
1014 if (gl) 946 if (gl)
1015 method = evas_render_method_lookup("gl_drm"); 947 method = evas_render_method_lookup("gl_drm");
1016 else 948 else
1017 method = evas_render_method_lookup("drm"); 949 method = evas_render_method_lookup("drm");
1018 950
1019 if (!method) return NULL; 951 if (!method)
952 {
953 ERR("Could not find evas render method");
954 return NULL;
955 }
1020 956
1021 ee = calloc(1, sizeof(Ecore_Evas)); 957 ee = calloc(1, sizeof(Ecore_Evas));
1022 if (!ee) return NULL; 958 if (!ee) return NULL;
1023 959
1024 edata = calloc(1, sizeof(Ecore_Evas_Engine_Drm_Data)); 960 edata = calloc(1, sizeof(Ecore_Evas_Engine_Drm_Data));
1025 if (!edata) 961 if (!edata) goto edata_err;
1026 { 962
1027 free(ee); 963 if (_drm_init(edata, device) < 1)
1028 return NULL; 964 goto init_err;
1029 }
1030 965
1031 if (!getenv("ECORE_EVAS_DRM_GPU_CLOCK_WRONG")) 966 if (!getenv("ECORE_EVAS_DRM_GPU_CLOCK_WRONG"))
1032 { 967 edata->once = EINA_TRUE;
1033 edata->once = EINA_TRUE;
1034 edata->offset = 0.0;
1035 }
1036 edata->x = x;
1037 edata->y = y;
1038 edata->w = w;
1039 edata->h = h;
1040 edata->depth = 24; // FIXME: Remove hardcode
1041 edata->bpp = 32; // FIXME: Remove hardcode
1042 edata->format = DRM_FORMAT_XRGB8888;
1043
1044 if (_ecore_evas_drm_init(ee, edata, device) < 1)
1045 {
1046 free(edata);
1047 free(ee);
1048 return NULL;
1049 }
1050 968
1051 ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS); 969 ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS);
1052 970
1053 if (gl) ee->driver = "gl_drm"; 971 if (gl)
1054 else ee->driver = "drm"; 972 ee->driver = "gl_drm";
973 else
974 ee->driver = "drm";
1055 975
1056 ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_evas_drm_engine_func; 976 ee->engine.func = (Ecore_Evas_Engine_Func *)&_drm_engine_func;
1057 ee->engine.data = edata; 977 ee->engine.data = edata;
1058 978 ee->engine.ifaces =
1059 /* FIXME */ 979 eina_list_append(ee->engine.ifaces, _drm_interface_new());
1060 /* if (edata->device) ee->name = strdup(edata->device); */
1061
1062 iface = _ecore_evas_drm_interface_new();
1063 ee->engine.ifaces = eina_list_append(ee->engine.ifaces, iface);
1064 980
1065 ee->x = ee->req.x = x; 981 ee->x = ee->req.x = x;
1066 ee->y = ee->req.y = y; 982 ee->y = ee->req.y = y;
1067 ee->w = ee->req.w = w; 983 ee->w = ee->req.w = w;
1068 ee->h = ee->req.h = h; 984 ee->h = ee->req.h = h;
985 ee->alpha = EINA_FALSE;
1069 986
1070 ee->prop.max.w = 32767;
1071 ee->prop.max.h = 32767;
1072 ee->prop.layer = 4; 987 ee->prop.layer = 4;
1073 ee->prop.request_pos = 0; 988 ee->prop.max.w = ee->prop.max.h = 32767;
1074 ee->prop.sticky = 0; 989 ee->prop.request_pos = EINA_FALSE;
990 ee->prop.sticky = EINA_FALSE;
1075 ee->prop.withdrawn = EINA_TRUE; 991 ee->prop.withdrawn = EINA_TRUE;
1076 ee->alpha = EINA_FALSE;
1077 992
1078 ee->can_async_render = !gl; 993 ee->can_async_render = !gl;
1079 if (getenv("ECORE_EVAS_FORCE_SYNC_RENDER")) 994 if (getenv("ECORE_EVAS_FORCE_SYNC_RENDER"))
1080 ee->can_async_render = 0; 995 ee->can_async_render = EINA_FALSE;
1081 996
1082 if (!ecore_evas_evas_new(ee, w, h)) 997 if (!ecore_evas_evas_new(ee, w, h))
1083 { 998 {
1084 ERR("Can not create a Canvas."); 999 ERR("Can not create a Canvas.");
1000>>>>>>> ecore-evas-drm: Refactor ecore-evas drm engine to work with multiple outputs
1085 goto eng_err; 1001 goto eng_err;
1086 } 1002 }
1087 1003
1088 evas_output_method_set(ee->evas, method); 1004 evas_output_method_set(ee->evas, method);
1089 1005
1090 if (ee->can_async_render) 1006 /* TODO */
1091 evas_event_callback_add(ee->evas, EVAS_CALLBACK_RENDER_POST, 1007 /* if (ee->can_async_render) */
1092 _drm_render_updates, ee); 1008 /* evas_event_callback_add(ee->evas, EVAS_CALLBACK_RENDER_POST, */
1093 1009 /* _cb_render_updates, ee); */
1094#ifdef BUILD_ECORE_EVAS_GL_DRM
1095 if (gl)
1096 tinfo = _drm_gl_canvas_setup(ee, edata);
1097 else
1098#endif
1099 tinfo = _drm_canvas_setup(ee, edata);
1100 1010
1101 if (!tinfo) 1011 /* TODO: setup efl_canvas outputs */
1102 { 1012 if (!gl)
1103 ERR("evas_engine_info_get() for engine '%s' failed", ee->driver); 1013 _ecore_evas_drm_canvas_setup(ee, edata);
1104 goto eng_err;
1105 }
1106
1107 if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)tinfo))
1108 {
1109 ERR("evas_engine_info_set() for engine '%s' failed", ee->driver);
1110 goto eng_err;
1111 }
1112
1113 ee->prop.window = ecore_drm2_output_crtc_get(edata->output);
1114 ecore_drm2_device_window_set(edata->dev, ee->prop.window);
1115 1014
1116 ecore_evas_data_set(ee, "device", edata->dev); 1015 ecore_evas_data_set(ee, "device", edata->dev);
1117 1016
1118 ecore_evas_done(ee, EINA_FALSE); 1017 ecore_evas_done(ee, EINA_FALSE);
1119 1018
1120 ecore_drm2_output_info_get(edata->output, NULL, NULL, &mw, &mh, NULL); 1019 memset(&edata->ctx, 0, sizeof(Ecore_Drm2_Context));
1121
1122 ecore_drm2_device_calibrate(edata->dev, mw, mh);
1123 ecore_drm2_device_pointer_max_set(edata->dev, mw, mh);
1124 ecore_drm2_device_pointer_warp(edata->dev, mw / 2, mh / 2);
1125
1126 /* setup vblank handler */
1127 memset(&edata->ctx, 0, sizeof(edata->ctx));
1128 edata->ctx.page_flip_handler = _cb_pageflip; 1020 edata->ctx.page_flip_handler = _cb_pageflip;
1129 1021
1130 edata->hdlr = 1022 edata->hdlr =
1131 ecore_main_fd_handler_add(ecore_drm2_device_fd_get(edata->dev), 1023 ecore_main_fd_handler_add(ecore_drm2_device_fd_get(edata->dev),
1132 ECORE_FD_READ, _cb_drm_event, ee, 1024 ECORE_FD_READ, _cb_drm_event, ee, NULL, NULL);
1133 NULL, NULL);
1134 1025
1135 canvases = eina_list_append(canvases, ee); 1026 canvases = eina_list_append(canvases, ee);
1027
1136 return ee; 1028 return ee;
1137 1029
1138eng_err: 1030init_err:
1139 ecore_evas_free(ee); 1031 free(edata);
1032edata_err:
1033 free(ee);
1140 return NULL; 1034 return NULL;
1141} 1035}
1142 1036