summaryrefslogtreecommitdiff
path: root/src/modules/ecore_evas/engines/drm
diff options
context:
space:
mode:
authorChris Michael <cpmichael@osg.samsung.com>2016-05-03 12:03:00 -0400
committerChris Michael <cpmichael@osg.samsung.com>2016-05-27 11:57:53 -0400
commit93178199a6c302e899438a32e8c296dc5bd2d248 (patch)
tree458f63b38e1ebc1aeb9bc0144226fe729a9db9fa /src/modules/ecore_evas/engines/drm
parentccb573ec7b460326e5d45ce2a3f9ac7a7470e335 (diff)
ecore-evas: Port ecore_evas drm engine to use Ecore_Drm2 library
Signed-off-by: Chris Michael <cpmichael@osg.samsung.com>
Diffstat (limited to 'src/modules/ecore_evas/engines/drm')
-rw-r--r--src/modules/ecore_evas/engines/drm/ecore_evas_drm.c1247
1 files changed, 508 insertions, 739 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 8b5e4047cc..3cdc7011f3 100644
--- a/src/modules/ecore_evas/engines/drm/ecore_evas_drm.c
+++ b/src/modules/ecore_evas/engines/drm/ecore_evas_drm.c
@@ -2,8 +2,6 @@
2# include <config.h> 2# include <config.h>
3#endif 3#endif
4 4
5#include <stdlib.h>
6#include <string.h>
7#include <Eina.h> 5#include <Eina.h>
8#include <Ecore.h> 6#include <Ecore.h>
9#include "ecore_private.h" 7#include "ecore_private.h"
@@ -12,12 +10,12 @@
12#include <Ecore_Evas.h> 10#include <Ecore_Evas.h>
13#include "ecore_evas_private.h" 11#include "ecore_evas_private.h"
14#include "ecore_evas_drm.h" 12#include "ecore_evas_drm.h"
15#include <Ecore_Drm.h> 13#include <Ecore_Drm2.h>
16#include <Evas_Engine_Drm.h> 14#include <Evas_Engine_Drm.h>
15#include <drm_fourcc.h>
17 16
18#ifdef BUILD_ECORE_EVAS_GL_DRM 17#ifdef BUILD_ECORE_EVAS_GL_DRM
19# include <Evas_Engine_GL_Drm.h> 18# include <Evas_Engine_GL_Drm.h>
20# include <gbm.h>
21# include <dlfcn.h> 19# include <dlfcn.h>
22#endif 20#endif
23 21
@@ -43,662 +41,257 @@
43# endif 41# endif
44#endif /* ! _WIN32 */ 42#endif /* ! _WIN32 */
45 43
46typedef struct _Ecore_Evas_Engine_Drm_Data Ecore_Evas_Engine_Drm_Data; 44typedef struct _Ecore_Evas_Engine_Drm_Data
47
48struct _Ecore_Evas_Engine_Drm_Data
49{
50 int w, h;
51};
52
53/* local function prototypes */
54static int _ecore_evas_drm_init(const char *device);
55static int _ecore_evas_drm_shutdown(void);
56static Ecore_Evas_Interface_Drm *_ecore_evas_drm_interface_new(void);
57static void _ecore_evas_drm_free(Ecore_Evas *ee);
58static void _ecore_evas_drm_callback_resize_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func);
59static void _ecore_evas_drm_callback_move_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func);
60static void _ecore_evas_drm_callback_focus_in_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func);
61static void _ecore_evas_drm_callback_focus_out_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func);
62static void _ecore_evas_drm_callback_mouse_in_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func);
63static void _ecore_evas_drm_callback_mouse_out_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func);
64static void _ecore_evas_drm_delete_request_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func);
65static void _ecore_evas_drm_move(Ecore_Evas *ee, int x, int y);
66static void _ecore_evas_drm_resize(Ecore_Evas *ee, int w, int h);
67static void _ecore_evas_drm_move_resize(Ecore_Evas *ee, int x, int y, int w, int h);
68static void _ecore_evas_drm_rotation_set(Ecore_Evas *ee, int rotation, int resize);
69static void _ecore_evas_drm_show(Ecore_Evas *ee);
70static void _ecore_evas_drm_hide(Ecore_Evas *ee);
71static void _ecore_evas_drm_title_set(Ecore_Evas *ee, const char *title);
72static void _ecore_evas_drm_name_class_set(Ecore_Evas *ee, const char *n, const char *c);
73static void _ecore_evas_drm_size_min_set(Ecore_Evas *ee, int w, int h);
74static void _ecore_evas_drm_size_max_set(Ecore_Evas *ee, int w, int h);
75static void _ecore_evas_drm_size_base_set(Ecore_Evas *ee, int w, int h);
76static void _ecore_evas_drm_size_step_set(Ecore_Evas *ee, int w, int h);
77static void _ecore_evas_drm_object_cursor_set(Ecore_Evas *ee, Evas_Object *obj, int layer, int hot_x, int hot_y);
78static void _ecore_evas_drm_object_cursor_unset(Ecore_Evas *ee);
79static void _ecore_evas_drm_layer_set(Ecore_Evas *ee, int layer);
80static void _ecore_evas_drm_iconified_set(Ecore_Evas *ee, Eina_Bool on);
81static void _ecore_evas_drm_borderless_set(Ecore_Evas *ee, Eina_Bool on);
82static void _ecore_evas_drm_maximized_set(Ecore_Evas *ee, Eina_Bool on);
83static void _ecore_evas_drm_fullscreen_set(Ecore_Evas *ee, Eina_Bool on);
84static void _ecore_evas_drm_withdrawn_set(Ecore_Evas *ee, Eina_Bool on);
85static void _ecore_evas_drm_ignore_events_set(Ecore_Evas *ee, int ignore);
86static void _ecore_evas_drm_alpha_set(Ecore_Evas *ee, int alpha);
87static void _ecore_evas_drm_transparent_set(Ecore_Evas *ee, int transparent);
88static void _ecore_evas_drm_aspect_set(Ecore_Evas *ee, double aspect);
89
90static int _ecore_evas_drm_render(Ecore_Evas *ee);
91static void _ecore_evas_drm_render_updates(void *data, Evas *evas EINA_UNUSED, void *event);
92static int _ecore_evas_drm_render_updates_process(Ecore_Evas *ee, Eina_List *updates);
93
94static void _ecore_evas_drm_screen_geometry_get(const Ecore_Evas *ee EINA_UNUSED, int *x, int *y, int *w, int *h);
95static void _ecore_evas_drm_pointer_xy_get(const Ecore_Evas *ee, Evas_Coord *x, Evas_Coord *y);
96Eina_Bool _ecore_evas_drm_pointer_warp(const Ecore_Evas *ee EINA_UNUSED, Evas_Coord x, Evas_Coord y);
97
98/* local variables */
99static int _ecore_evas_init_count = 0;
100static Ecore_Drm_Device *dev = NULL;
101
102static Ecore_Evas_Engine_Func _ecore_evas_drm_engine_func =
103{ 45{
104 _ecore_evas_drm_free, 46 int fd;
105 _ecore_evas_drm_callback_resize_set, 47 int cw, ch;
106 _ecore_evas_drm_callback_move_set, 48 int clockid;
107 NULL, //void (*fn_callback_show_set) (Ecore_Evas *ee, Ecore_Evas_Event_Cb func); 49 int x, y, w, h;
108 NULL, //void (*fn_callback_hide_set) (Ecore_Evas *ee, Ecore_Evas_Event_Cb func); 50 int depth, bpp;
109 _ecore_evas_drm_delete_request_set, 51 unsigned int format;
110 NULL, //void (*fn_callback_destroy_set) (Ecore_Evas *ee, Ecore_Evas_Event_Cb func); 52 Ecore_Drm2_Device *dev;
111 _ecore_evas_drm_callback_focus_in_set, 53 Ecore_Drm2_Output *output;
112 _ecore_evas_drm_callback_focus_out_set, 54} Ecore_Evas_Engine_Drm_Data;
113 _ecore_evas_drm_callback_mouse_in_set,
114 _ecore_evas_drm_callback_mouse_out_set,
115 NULL, //void (*fn_callback_sticky_set) (Ecore_Evas *ee, Ecore_Evas_Event_Cb func);
116 NULL, //void (*fn_callback_unsticky_set) (Ecore_Evas *ee, Ecore_Evas_Event_Cb func);
117 NULL, //void (*fn_callback_pre_render_set) (Ecore_Evas *ee, Ecore_Evas_Event_Cb func);
118 NULL, //void (*fn_callback_post_render_set) (Ecore_Evas *ee, Ecore_Evas_Event_Cb func);
119 _ecore_evas_drm_move,
120 NULL, //void (*fn_managed_move) (Ecore_Evas *ee, int x, int y);
121 _ecore_evas_drm_resize,
122 _ecore_evas_drm_move_resize,
123 _ecore_evas_drm_rotation_set,
124 NULL, //void (*fn_shaped_set) (Ecore_Evas *ee, int shaped);
125 _ecore_evas_drm_show,
126 _ecore_evas_drm_hide,
127 NULL, //void (*fn_raise) (Ecore_Evas *ee);
128 NULL, //void (*fn_lower) (Ecore_Evas *ee);
129 NULL, //void (*fn_activate) (Ecore_Evas *ee);
130 _ecore_evas_drm_title_set,
131 _ecore_evas_drm_name_class_set,
132 _ecore_evas_drm_size_min_set,
133 _ecore_evas_drm_size_max_set,
134 _ecore_evas_drm_size_base_set,
135 _ecore_evas_drm_size_step_set,
136 _ecore_evas_drm_object_cursor_set,
137 _ecore_evas_drm_object_cursor_unset,
138 _ecore_evas_drm_layer_set,
139 NULL, //void (*fn_focus_set) (Ecore_Evas *ee, Eina_Bool on);
140 _ecore_evas_drm_iconified_set,
141 _ecore_evas_drm_borderless_set,
142 NULL, //void (*fn_override_set) (Ecore_Evas *ee, Eina_Bool on);
143 _ecore_evas_drm_maximized_set,
144 _ecore_evas_drm_fullscreen_set,
145 NULL, //void (*fn_avoid_damage_set) (Ecore_Evas *ee, int on);
146 _ecore_evas_drm_withdrawn_set,
147 NULL, //void (*fn_sticky_set) (Ecore_Evas *ee, Eina_Bool on);
148 _ecore_evas_drm_ignore_events_set,
149 _ecore_evas_drm_alpha_set,
150 _ecore_evas_drm_transparent_set,
151 NULL, //void (*fn_profiles_set) (Ecore_Evas *ee, const char **profiles, int count);
152 NULL, //void (*fn_profile_set) (Ecore_Evas *ee, const char *profile);
153
154 NULL, //void (*fn_window_group_set) (Ecore_Evas *ee, const Ecore_Evas *ee_group);
155 _ecore_evas_drm_aspect_set,
156 NULL, //void (*fn_urgent_set) (Ecore_Evas *ee, Eina_Bool on);
157 NULL, //void (*fn_modal_set) (Ecore_Evas *ee, Eina_Bool on);
158 NULL, //void (*fn_demands_attention_set) (Ecore_Evas *ee, Eina_Bool on);
159 NULL, //void (*fn_focus_skip_set) (Ecore_Evas *ee, Eina_Bool on);
160
161 _ecore_evas_drm_render,
162
163 _ecore_evas_drm_screen_geometry_get,
164 NULL, //void (*fn_screen_dpi_get) (const Ecore_Evas *ee, int *xdpi, int *ydpi);
165 NULL, //void (*fn_msg_parent_send) (Ecore_Evas *ee, int maj, int min, void *data, int size);
166 NULL, //void (*fn_msg_send) (Ecore_Evas *ee, int maj, int min, void *data, int size);
167
168 _ecore_evas_drm_pointer_xy_get,
169 _ecore_evas_drm_pointer_warp,
170
171 NULL, // wm_rot_preferred_rotation_set
172 NULL, // wm_rot_available_rotations_set
173 NULL, // wm_rot_manual_rotation_done_set
174 NULL, // wm_rot_manual_rotation_done
175 55
176 NULL, // aux_hints_set 56static int _drm_init_count = 0;
177
178 NULL, // fn_animator_register
179 NULL // fn_animator_unregister
180};
181 57
182EAPI Ecore_Evas * 58static int
183ecore_evas_drm_new_internal(const char *device, unsigned int parent EINA_UNUSED, int x, int y, int w, int h) 59_ecore_evas_drm_init(Ecore_Evas_Engine_Drm_Data *edata, const char *device)
184{ 60{
185 Ecore_Evas *ee; 61 int mw, mh;
186 Evas_Engine_Info_Drm *einfo;
187 Ecore_Evas_Interface_Drm *iface;
188 Ecore_Evas_Engine_Drm_Data *edata;
189 int method;
190 62
191 /* try to find the evas drm engine */ 63 if (++_drm_init_count != 1) return _drm_init_count;
192 if (!(method = evas_render_method_lookup("drm")))
193 {
194 ERR("Render method lookup failed for Drm");
195 return NULL;
196 }
197 64
198 /* try to init drm */ 65 if (!ecore_drm2_init())
199 if (_ecore_evas_drm_init(device) < 1) return NULL;
200
201 if (!ecore_drm_device_software_setup(dev))
202 { 66 {
203 ERR("Could not setup device for software"); 67 ERR("Failed to init Ecore_Drm2 library");
204 goto soft_err; 68 goto init_err;
205 } 69 }
206 70
207 /* try to allocate space for new ecore_evas */ 71 if (!device) device = "seat0";
208 if (!(ee = calloc(1, sizeof(Ecore_Evas))))
209 {
210 ERR("Failed to allocate space for new Ecore_Evas");
211 goto ee_err;
212 }
213 72
214 if (!(edata = calloc(1, sizeof(Ecore_Evas_Engine_Drm_Data)))) 73 edata->dev = ecore_drm2_device_find(device, 0, EINA_TRUE);
74 if (!edata->dev)
215 { 75 {
216 ERR("Failed to allocate space for new Ecore_Evas_Engine_Data"); 76 ERR("Failed to create device");
217 free(ee); 77 goto dev_err;
218 goto ee_err;
219 } 78 }
220 79
221 ee->engine.data = edata; 80 edata->fd = ecore_drm2_device_open(edata->dev);
222 81 if (edata->fd < 0)
223 ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS);
224
225 ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_evas_drm_engine_func;
226
227 iface = _ecore_evas_drm_interface_new();
228 ee->engine.ifaces = eina_list_append(ee->engine.ifaces, iface);
229
230 /* set some engine properties */
231 ee->driver = "drm";
232 if (device) ee->name = strdup(device);
233 else
234 ee->name = strdup(ecore_drm_device_name_get(dev));
235
236 if (w < 1) w = 1;
237 if (h < 1) h = 1;
238
239 ee->x = ee->req.x = x;
240 ee->y = ee->req.y = y;
241 ee->w = ee->req.w = w;
242 ee->h = ee->req.h = h;
243
244 ee->prop.max.w = 32767;
245 ee->prop.max.h = 32767;
246 ee->prop.layer = 4;
247 ee->prop.request_pos = 0;
248 ee->prop.sticky = 0;
249 ee->prop.withdrawn = EINA_TRUE;
250 ee->alpha = EINA_FALSE;
251
252 ee->can_async_render = 1;
253 if (getenv("ECORE_EVAS_FORCE_SYNC_RENDER"))
254 ee->can_async_render = 0;
255
256 /* try to initialize evas */
257 ee->evas = evas_new();
258 evas_data_attach_set(ee->evas, ee);
259 evas_output_method_set(ee->evas, method);
260
261 if ((ee->rotation == 90) || (ee->rotation == 270))
262 { 82 {
263 evas_output_size_set(ee->evas, h, w); 83 ERR("Failed to open device");
264 evas_output_viewport_set(ee->evas, 0, 0, h, w); 84 goto open_err;
265 }
266 else
267 {
268 evas_output_size_set(ee->evas, w, h);
269 evas_output_viewport_set(ee->evas, 0, 0, w, h);
270 } 85 }
271 86
272 if (ee->can_async_render) 87 edata->clockid = ecore_drm2_device_clock_id_get(edata->dev);
273 evas_event_callback_add(ee->evas, EVAS_CALLBACK_RENDER_POST, 88 ecore_drm2_device_cursor_size_get(edata->dev, &edata->cw, &edata->ch);
274 _ecore_evas_drm_render_updates, ee);
275 89
276 if ((einfo = (Evas_Engine_Info_Drm *)evas_engine_info_get(ee->evas))) 90 if (!ecore_drm2_outputs_create(edata->dev))
277 { 91 {
278 Ecore_Drm_Output *output; 92 ERR("Could not create outputs");
279 char *num; 93 goto output_err;
280
281 einfo->info.depth = 32; // FIXME
282 einfo->info.destination_alpha = ee->alpha;
283 einfo->info.rotation = ee->rotation;
284
285 if ((num = getenv("EVAS_DRM_VSYNC")))
286 {
287 if (!atoi(num))
288 einfo->info.vsync = EINA_FALSE;
289 else
290 einfo->info.vsync = EINA_TRUE;
291 }
292 else
293 einfo->info.vsync = EINA_TRUE;
294
295 einfo->info.use_hw_accel = EINA_FALSE;
296 einfo->info.dev = dev;
297
298 if ((output = ecore_drm_device_output_find(dev, x, y)))
299 {
300 einfo->info.conn_id = ecore_drm_output_connector_id_get(output);
301 einfo->info.crtc_id = ecore_drm_output_crtc_id_get(output);
302 einfo->info.buffer_id = ecore_drm_output_crtc_buffer_get(output);
303 }
304
305 if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
306 {
307 ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
308 goto eng_err;
309 }
310 }
311 else
312 {
313 ERR("Failed to get Evas Engine Info for '%s'", ee->driver);
314 goto eng_err;
315 } 94 }
316 95
317 ee->prop.window = einfo->info.buffer_id; 96 edata->output = ecore_drm2_output_find(edata->dev, edata->x, edata->y);
318 97 if (!edata->output)
319 _ecore_evas_register(ee); 98 WRN("Could not find output at %d %d", edata->x, edata->y);
320 ecore_evas_input_event_register(ee);
321
322 ecore_drm_device_window_set(dev, ee->prop.window);
323 ecore_event_window_register(ee->prop.window, ee, ee->evas,
324 (Ecore_Event_Mouse_Move_Cb)_ecore_evas_mouse_move_process,
325 (Ecore_Event_Multi_Move_Cb)_ecore_evas_mouse_multi_move_process,
326 (Ecore_Event_Multi_Down_Cb)_ecore_evas_mouse_multi_down_process,
327 (Ecore_Event_Multi_Up_Cb)_ecore_evas_mouse_multi_up_process);
328 99
329 /* NB: Send a fake mouse move event so that E-Wl gets an updated 100 ecore_drm2_output_crtc_size_get(edata->output, &mw, &mh);
330 * pointer position, else we end up with buggers (ref: T2854) */ 101 ecore_drm2_device_pointer_max_set(edata->dev, mw, mh);
331 {
332 Ecore_Event_Mouse_Move *ev;
333 102
334 ev = calloc(1, sizeof(Ecore_Event_Mouse_Move)); 103 ecore_event_evas_init();
335 ev->window = ee->prop.window;
336 ev->event_window = ee->prop.window;
337 ev->root_window = ee->prop.window;
338 ev->same_screen = 1;
339 104
340 ecore_drm_device_pointer_xy_get(dev, &ev->x, &ev->y); 105 return _drm_init_count;
341 106
342 ev->root.x = ev->x; 107output_err:
343 ev->root.y = ev->y; 108 ecore_drm2_device_close(edata->dev);
109open_err:
110 ecore_drm2_device_free(edata->dev);
111dev_err:
112 ecore_drm2_shutdown();
113init_err:
114 return --_drm_init_count;
115}
344 116
345 ecore_event_evas_mouse_move(NULL, ECORE_EVENT_MOUSE_MOVE, ev); 117static int
346 } 118_ecore_evas_drm_shutdown(Ecore_Evas_Engine_Drm_Data *edata)
119{
120 if (--_drm_init_count != 0) return _drm_init_count;
347 121
348 return ee; 122 ecore_drm2_outputs_destroy(edata->dev);
123 ecore_drm2_device_close(edata->dev);
124 ecore_drm2_device_free(edata->dev);
125 ecore_drm2_shutdown();
126 ecore_event_evas_shutdown();
349 127
350eng_err: 128 return _drm_init_count;
351 ecore_evas_free(ee);
352soft_err:
353ee_err:
354 _ecore_evas_drm_shutdown();
355 return NULL;
356} 129}
357 130
358#ifdef BUILD_ECORE_EVAS_GL_DRM 131static void
359EAPI Ecore_Evas * 132_drm_free(Ecore_Evas *ee)
360ecore_evas_gl_drm_new_internal(const char *device, unsigned int parent EINA_UNUSED, int x, int y, int w, int h)
361{ 133{
362 Ecore_Evas *ee;
363 Evas_Engine_Info_GL_Drm *einfo;
364 Ecore_Evas_Interface_Drm *iface;
365 Ecore_Evas_Engine_Drm_Data *edata; 134 Ecore_Evas_Engine_Drm_Data *edata;
366 int method;
367 uint32_t format = GBM_FORMAT_XRGB8888;
368 uint32_t flags = GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING;
369 char *num;
370
371 /* try to find the evas drm engine */
372 if (!(method = evas_render_method_lookup("gl_drm")))
373 {
374 ERR("Render method lookup failed for GL Drm");
375 return NULL;
376 }
377
378 /* try to init drm */
379 if (_ecore_evas_drm_init(device) < 1) return NULL;
380
381 /* try to load gl libary, gbm libary */
382 /* Typically, gbm loads the dri driver However some versions of Mesa
383 * do not have libglapi symbols linked in the driver. Because of this,
384 * using hardware accel for our drm code Could fail with a
385 * message that the driver could not load. Let's be proactive and
386 * work around this for the user by preloading the glapi library */
387 dlopen("libglapi.so.0", (RTLD_LAZY | RTLD_GLOBAL));
388 if (dlerror())
389 {
390 _ecore_evas_drm_shutdown();
391 return NULL;
392 }
393
394 /* try to allocate space for new ecore_evas */
395 if (!(ee = calloc(1, sizeof(Ecore_Evas))))
396 {
397 ERR("Failed to allocate space for new Ecore_Evas");
398 goto ee_err;
399 }
400
401 if (!(edata = calloc(1, sizeof(Ecore_Evas_Engine_Drm_Data))))
402 {
403 ERR("Failed to allocate space for new Ecore_Evas_Engine_Data");
404 free(ee);
405 goto ee_err;
406 }
407
408 ee->engine.data = edata;
409 135
410 ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS); 136 ecore_evas_input_event_unregister(ee);
411
412 ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_evas_drm_engine_func;
413
414 iface = _ecore_evas_drm_interface_new();
415 ee->engine.ifaces = eina_list_append(ee->engine.ifaces, iface);
416
417 /* set some engine properties */
418 ee->driver = "gl_drm";
419 if (device) ee->name = strdup(device);
420 else
421 ee->name = strdup(ecore_drm_device_name_get(dev));
422
423 if (w < 1) w = 1;
424 if (h < 1) h = 1;
425
426 ee->x = ee->req.x = x;
427 ee->y = ee->req.y = y;
428 ee->w = ee->req.w = w;
429 ee->h = ee->req.h = h;
430
431 ee->prop.max.w = 32767;
432 ee->prop.max.h = 32767;
433 ee->prop.layer = 4;
434 ee->prop.request_pos = 0;
435 ee->prop.sticky = 0;
436 ee->prop.withdrawn = EINA_TRUE;
437 ee->alpha = EINA_FALSE;
438 137
439 /* NB: Disable async rendering for egl. Not Applicable as EGL is sync only */ 138 edata = ee->engine.data;
440 ee->can_async_render = 0; 139 _ecore_evas_drm_shutdown(edata);
441 /* if (getenv("ECORE_EVAS_FORCE_SYNC_RENDER")) */ 140 free(edata);
442 /* ee->can_async_render = 0; */ 141}
443 142
444 /* try to initialize evas */ 143static int
445 ee->evas = evas_new(); 144_drm_render_updates_process(Ecore_Evas *ee, Eina_List *updates)
446 evas_data_attach_set(ee->evas, ee); 145{
447 evas_output_method_set(ee->evas, method); 146 int rend = 0;
448 147
449 if ((ee->rotation == 90) || (ee->rotation == 270)) 148 if ((ee->visible) && (updates))
450 { 149 {
451 evas_output_size_set(ee->evas, h, w); 150 _ecore_evas_idle_timeout_update(ee);
452 evas_output_viewport_set(ee->evas, 0, 0, h, w); 151 rend = 1;
453 } 152 }
454 else 153 else
455 { 154 evas_norender(ee->evas);
456 evas_output_size_set(ee->evas, w, h);
457 evas_output_viewport_set(ee->evas, 0, 0, w, h);
458 }
459
460 if (ee->can_async_render)
461 evas_event_callback_add(ee->evas, EVAS_CALLBACK_RENDER_POST,
462 _ecore_evas_drm_render_updates, ee);
463
464 if ((einfo = (Evas_Engine_Info_GL_Drm *)evas_engine_info_get(ee->evas)))
465 {
466 Ecore_Drm_Output *output;
467
468 einfo->info.depth = 32;
469 einfo->info.destination_alpha = ee->alpha;
470 einfo->info.rotation = ee->rotation;
471
472 if ((num = getenv("EVAS_DRM_VSYNC")))
473 {
474 if (!atoi(num))
475 einfo->info.vsync = EINA_FALSE;
476 else
477 einfo->info.vsync = EINA_TRUE;
478 }
479 else
480 einfo->info.vsync = EINA_TRUE;
481
482 einfo->info.dev = dev;
483 einfo->info.format = format;
484 einfo->info.flags = flags;
485
486 if ((output = ecore_drm_device_output_find(dev, x, y)))
487 {
488 einfo->info.conn_id = ecore_drm_output_connector_id_get(output);
489 einfo->info.crtc_id = ecore_drm_output_crtc_id_get(output);
490 einfo->info.buffer_id = ecore_drm_output_crtc_buffer_get(output);
491 }
492 155
493 if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) 156 if (ee->func.fn_post_render) ee->func.fn_post_render(ee);
494 {
495 ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
496 goto eng_err;
497 }
498 }
499 else
500 {
501 ERR("Failed to get Evas Engine Info for '%s'", ee->driver);
502 goto eng_err;
503 }
504 157
505 ee->prop.window = einfo->info.buffer_id; 158 return rend;
159}
506 160
507 _ecore_evas_register(ee); 161static void
508 ecore_evas_input_event_register(ee); 162_drm_render_updates(void *data, Evas *evas EINA_UNUSED, void *event)
163{
164 Evas_Event_Render_Post *ev;
165 Ecore_Evas *ee;
509 166
510 ecore_drm_device_window_set(dev, ee->prop.window); 167 ev = event;
511 ecore_event_window_register(ee->prop.window, ee, ee->evas, 168 if (!ev) return;
512 (Ecore_Event_Mouse_Move_Cb)_ecore_evas_mouse_move_process,
513 (Ecore_Event_Multi_Move_Cb)_ecore_evas_mouse_multi_move_process,
514 (Ecore_Event_Multi_Down_Cb)_ecore_evas_mouse_multi_down_process,
515 (Ecore_Event_Multi_Up_Cb)_ecore_evas_mouse_multi_up_process);
516 169
517 return ee; 170 ee = data;
171 if (!ee) return;
518 172
519eng_err: 173 ee->in_async_render = EINA_FALSE;
520 ecore_evas_free(ee); 174 _drm_render_updates_process(ee, ev->updated_area);
521ee_err:
522 _ecore_evas_drm_shutdown();
523 return NULL;
524} 175}
525#endif
526 176
527/* local functions */
528static int 177static int
529_ecore_evas_drm_init(const char *device) 178_drm_render(Ecore_Evas *ee)
530{ 179{
531 if (++_ecore_evas_init_count != 1) return _ecore_evas_init_count; 180 int rend = 0;
181 Eina_List *l;
182 Ecore_Evas *ee2;
532 183
533 /* try to init ecore_drm */ 184 if (ee->in_async_render) return 0;
534 if (!ecore_drm_init())
535 {
536 ERR("Could not initialize Ecore_Drm");
537 return --_ecore_evas_init_count;
538 }
539 185
540 /* try to find the device */ 186 if (!ee->visible)
541 if (!(dev = ecore_drm_device_find(device, NULL)))
542 { 187 {
543 ERR("Could not find drm device with name: %s. Falling back to default device.", device); 188 evas_norender(ee->evas);
544 189 return 0;
545 /* if we already passed in NULL as device name, then no point in
546 * calling the find function below with no name either */
547 if (!device) goto dev_err;
548
549 /* try getting the default drm device */
550 if (!(dev = ecore_drm_device_find(NULL, NULL)))
551 goto dev_err;
552 } 190 }
553 191
554 if (!ecore_drm_launcher_connect(dev)) 192 EINA_LIST_FOREACH(ee->sub_ecore_evas, l, ee2)
555 { 193 {
556 ERR("Could not connect DRM launcher"); 194 if (ee2->func.fn_pre_render) ee2->func.fn_pre_render(ee2);
557 goto launcher_err; 195 if (ee2->engine.func->fn_render)
196 rend |= ee2->engine.func->fn_render(ee2);
197 if (ee2->func.fn_post_render) ee2->func.fn_post_render(ee2);
558 } 198 }
559 199
560 /* try to open the graphics card */ 200 if (ee->func.fn_pre_render) ee->func.fn_pre_render(ee);
561 if (!ecore_drm_device_open(dev))
562 {
563 ERR("Could not open drm device");
564 goto dev_open_err;
565 }
566 201
567 /* try to create sprites */ 202 if (!ee->can_async_render)
568 if (!ecore_drm_sprites_create(dev))
569 { 203 {
570 ERR("Could not create sprites"); 204 Eina_List *updates;
571 goto sprite_err;
572 }
573 205
574 /* try to create outputs */ 206 updates = evas_render_updates(ee->evas);
575 if (!ecore_drm_outputs_create(dev)) 207 rend = _drm_render_updates_process(ee, updates);
576 { 208 evas_render_updates_free(updates);
577 ERR("Could not create outputs");
578 goto output_err;
579 } 209 }
580 210 else if (evas_render_async(ee->evas))
581 /* try to create inputs */
582 if (!ecore_drm_inputs_create(dev))
583 { 211 {
584 ERR("Could not create inputs"); 212 ee->in_async_render = EINA_TRUE;
585 goto input_err; 213 rend = 1;
586 } 214 }
587 215
588 ecore_event_evas_init(); 216 return rend;
589
590 return _ecore_evas_init_count;
591
592output_err:
593 ecore_drm_inputs_destroy(dev);
594input_err:
595 ecore_drm_sprites_destroy(dev);
596sprite_err:
597 ecore_drm_device_close(dev);
598dev_open_err:
599 ecore_drm_launcher_disconnect(dev);
600 ecore_drm_device_free(dev);
601 dev = NULL;
602launcher_err:
603dev_err:
604 ecore_drm_shutdown();
605 return --_ecore_evas_init_count;
606} 217}
607 218
608static int 219static void
609_ecore_evas_drm_shutdown(void) 220_drm_screen_geometry_get(const Ecore_Evas *ee, int *x, int *y, int *w, int *h)
610{ 221{
611 Ecore_Drm_Output *output; 222 Ecore_Evas_Engine_Drm_Data *edata;
612
613 if (--_ecore_evas_init_count != 0) return _ecore_evas_init_count;
614
615 ecore_drm_inputs_destroy(dev);
616
617 EINA_LIST_FREE(dev->outputs, output)
618 ecore_drm_output_free(output);
619
620 ecore_drm_sprites_destroy(dev);
621 ecore_drm_device_close(dev);
622 ecore_drm_launcher_disconnect(dev);
623 ecore_drm_device_free(dev);
624 ecore_drm_shutdown();
625 dev = NULL;
626
627 ecore_event_evas_shutdown();
628 223
629 return _ecore_evas_init_count; 224 edata = ee->engine.data;
225 ecore_drm2_output_geometry_get(edata->output, x, y, w, h);
630} 226}
631 227
632static Ecore_Evas_Interface_Drm * 228static void
633_ecore_evas_drm_interface_new(void) 229_drm_pointer_xy_get(const Ecore_Evas *ee, Evas_Coord *x, Evas_Coord *y)
634{ 230{
635 Ecore_Evas_Interface_Drm *iface; 231 Ecore_Evas_Engine_Drm_Data *edata;
636
637 if (!(iface = calloc(1, sizeof(Ecore_Evas_Interface_Drm))))
638 return NULL;
639
640 iface->base.name = "drm";
641 iface->base.version = 1;
642 232
643 return iface; 233 edata = ee->engine.data;
234 ecore_drm2_device_pointer_xy_get(edata->dev, x, y);
644} 235}
645 236
646/* local ecore_evas functions */ 237static Eina_Bool
647static void 238_drm_pointer_warp(const Ecore_Evas *ee, Evas_Coord x, Evas_Coord y)
648_ecore_evas_drm_free(Ecore_Evas *ee)
649{ 239{
650 Ecore_Evas_Engine_Drm_Data *data; 240 Ecore_Evas_Engine_Drm_Data *edata;
651 241
652 data = ee->engine.data; 242 edata = ee->engine.data;
653 ecore_evas_input_event_unregister(ee); 243 ecore_drm2_device_pointer_warp(edata->dev, x, y);
654 free(data); 244 return EINA_TRUE;
655 _ecore_evas_drm_shutdown();
656} 245}
657 246
658static void 247static void
659_ecore_evas_drm_callback_resize_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func) 248_drm_show(Ecore_Evas *ee)
660{ 249{
661 ee->func.fn_resize = func; 250 if ((!ee) || (ee->visible)) return;
662}
663 251
664static void 252 ee->should_be_visible = 1;
665_ecore_evas_drm_callback_move_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func)
666{
667 ee->func.fn_move = func;
668}
669 253
670static void 254 if (ee->prop.avoid_damage)
671_ecore_evas_drm_callback_focus_in_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func) 255 _drm_render(ee);
672{
673 ee->func.fn_focus_in = func;
674}
675 256
676static void 257 if (ee->prop.override)
677_ecore_evas_drm_callback_focus_out_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func) 258 {
678{ 259 ee->prop.withdrawn = EINA_FALSE;
679 ee->func.fn_focus_out = func; 260 if (ee->func.fn_state_change) ee->func.fn_state_change(ee);
680} 261 }
681 262
682static void 263 if (ee->visible) return;
683_ecore_evas_drm_callback_mouse_in_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func)
684{
685 ee->func.fn_mouse_in = func;
686}
687 264
688static void 265 ee->visible = 1;
689_ecore_evas_drm_callback_mouse_out_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func) 266 if (ee->prop.fullscreen)
690{ 267 {
691 ee->func.fn_mouse_out = func; 268 evas_focus_in(ee->evas);
269 if (ee->func.fn_focus_in) ee->func.fn_focus_in(ee);
270 }
271 if (ee->func.fn_show) ee->func.fn_show(ee);
692} 272}
693 273
694static void 274static void
695_ecore_evas_drm_delete_request_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func) 275_drm_hide(Ecore_Evas *ee)
696{ 276{
697 ee->func.fn_delete_request = func; 277 if ((!ee) || (!ee->visible)) return;
278
279 if (ee->prop.override)
280 {
281 ee->prop.withdrawn = EINA_TRUE;
282 if (ee->func.fn_state_change) ee->func.fn_state_change(ee);
283 }
284
285 if (!ee->visible) return;
286
287 ee->visible = 0;
288 ee->should_be_visible = 0;
289 evas_sync(ee->evas);
290 if (ee->func.fn_hide) ee->func.fn_hide(ee);
698} 291}
699 292
700static void 293static void
701_ecore_evas_drm_move(Ecore_Evas *ee, int x, int y) 294_drm_move(Ecore_Evas *ee, int x, int y)
702{ 295{
703 ee->req.x = x; 296 ee->req.x = x;
704 ee->req.y = y; 297 ee->req.y = y;
@@ -709,7 +302,7 @@ _ecore_evas_drm_move(Ecore_Evas *ee, int x, int y)
709} 302}
710 303
711static void 304static void
712_ecore_evas_drm_resize(Ecore_Evas *ee, int w, int h) 305_drm_resize(Ecore_Evas *ee, int w, int h)
713{ 306{
714 ee->req.w = w; 307 ee->req.w = w;
715 ee->req.h = h; 308 ee->req.h = h;
@@ -722,16 +315,16 @@ _ecore_evas_drm_resize(Ecore_Evas *ee, int w, int h)
722} 315}
723 316
724static void 317static void
725_ecore_evas_drm_move_resize(Ecore_Evas *ee, int x, int y, int w, int h) 318_drm_move_resize(Ecore_Evas *ee, int x, int y, int w, int h)
726{ 319{
727 if ((ee->x != x) || (ee->y != y)) 320 if ((ee->x != x) || (ee->y != y))
728 _ecore_evas_drm_move(ee, x, y); 321 _drm_move(ee, x, y);
729 if ((ee->w != w) || (ee->h != h)) 322 if ((ee->w != w) || (ee->h != h))
730 _ecore_evas_drm_resize(ee, w, h); 323 _drm_resize(ee, w, h);
731} 324}
732 325
733static void 326static void
734_ecore_evas_drm_rotation_set(Ecore_Evas *ee, int rotation, int resize EINA_UNUSED) 327_drm_rotation_set(Ecore_Evas *ee, int rotation, int resize EINA_UNUSED)
735{ 328{
736 Evas_Engine_Info_Drm *einfo; 329 Evas_Engine_Info_Drm *einfo;
737 330
@@ -740,57 +333,11 @@ _ecore_evas_drm_rotation_set(Ecore_Evas *ee, int rotation, int resize EINA_UNUSE
740 if (!einfo) return; 333 if (!einfo) return;
741 einfo->info.rotation = rotation; 334 einfo->info.rotation = rotation;
742 if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) 335 if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
743 ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver); 336 ERR("evas_engine_info_set() for engine '%s' failed", ee->driver);
744}
745
746static void
747_ecore_evas_drm_show(Ecore_Evas *ee)
748{
749 if ((!ee) || (ee->visible)) return;
750
751 ee->should_be_visible = 1;
752
753 if (ee->prop.avoid_damage)
754 _ecore_evas_drm_render(ee);
755
756 if (ee->prop.override)
757 {
758 ee->prop.withdrawn = EINA_FALSE;
759 if (ee->func.fn_state_change) ee->func.fn_state_change(ee);
760 }
761
762 if (ee->visible) return;
763
764 ee->visible = 1;
765 if (ee->prop.fullscreen)
766 {
767 evas_focus_in(ee->evas);
768 if (ee->func.fn_focus_in) ee->func.fn_focus_in(ee);
769 }
770 if (ee->func.fn_show) ee->func.fn_show(ee);
771} 337}
772 338
773static void 339static void
774_ecore_evas_drm_hide(Ecore_Evas *ee) 340_drm_title_set(Ecore_Evas *ee, const char *title)
775{
776 if ((!ee) || (!ee->visible)) return;
777
778 if (ee->prop.override)
779 {
780 ee->prop.withdrawn = EINA_TRUE;
781 if (ee->func.fn_state_change) ee->func.fn_state_change(ee);
782 }
783
784 if (!ee->visible) return;
785
786 ee->visible = 0;
787 ee->should_be_visible = 0;
788 evas_sync(ee->evas);
789 if (ee->func.fn_hide) ee->func.fn_hide(ee);
790}
791
792static void
793_ecore_evas_drm_title_set(Ecore_Evas *ee, const char *title)
794{ 341{
795 if (eina_streq(ee->prop.title, title)) return; 342 if (eina_streq(ee->prop.title, title)) return;
796 if (ee->prop.title) free(ee->prop.title); 343 if (ee->prop.title) free(ee->prop.title);
@@ -799,7 +346,7 @@ _ecore_evas_drm_title_set(Ecore_Evas *ee, const char *title)
799} 346}
800 347
801static void 348static void
802_ecore_evas_drm_name_class_set(Ecore_Evas *ee, const char *n, const char *c) 349_drm_name_class_set(Ecore_Evas *ee, const char *n, const char *c)
803{ 350{
804 if (!eina_streq(ee->prop.name, n)) 351 if (!eina_streq(ee->prop.name, n))
805 { 352 {
@@ -807,6 +354,7 @@ _ecore_evas_drm_name_class_set(Ecore_Evas *ee, const char *n, const char *c)
807 ee->prop.name = NULL; 354 ee->prop.name = NULL;
808 if (n) ee->prop.name = strdup(n); 355 if (n) ee->prop.name = strdup(n);
809 } 356 }
357
810 if (!eina_streq(ee->prop.clas, c)) 358 if (!eina_streq(ee->prop.clas, c))
811 { 359 {
812 if (ee->prop.clas) free(ee->prop.clas); 360 if (ee->prop.clas) free(ee->prop.clas);
@@ -816,67 +364,54 @@ _ecore_evas_drm_name_class_set(Ecore_Evas *ee, const char *n, const char *c)
816} 364}
817 365
818static void 366static void
819_ecore_evas_drm_size_min_set(Ecore_Evas *ee, int w, int h) 367_drm_size_min_set(Ecore_Evas *ee, int w, int h)
820{ 368{
821 if (w < 0) w = 0;
822 if (h < 0) h = 0;
823 if ((ee->prop.min.w == w) && (ee->prop.min.h == h)) return; 369 if ((ee->prop.min.w == w) && (ee->prop.min.h == h)) return;
824 ee->prop.min.w = w; 370 ee->prop.min.w = w;
825 ee->prop.min.h = h; 371 ee->prop.min.h = h;
826} 372}
827 373
828static void 374static void
829_ecore_evas_drm_size_max_set(Ecore_Evas *ee, int w, int h) 375_drm_size_max_set(Ecore_Evas *ee, int w, int h)
830{ 376{
831 if (w < 0) w = 0;
832 if (h < 0) h = 0;
833 if ((ee->prop.max.w == w) && (ee->prop.max.h == h)) return; 377 if ((ee->prop.max.w == w) && (ee->prop.max.h == h)) return;
834 ee->prop.max.w = w; 378 ee->prop.max.w = w;
835 ee->prop.max.h = h; 379 ee->prop.max.h = h;
836} 380}
837 381
838static void 382static void
839_ecore_evas_drm_size_base_set(Ecore_Evas *ee, int w, int h) 383_drm_size_base_set(Ecore_Evas *ee, int w, int h)
840{ 384{
841 if (w < 0) w = 0;
842 if (h < 0) h = 0;
843 if ((ee->prop.base.w == w) && (ee->prop.base.h == h)) return; 385 if ((ee->prop.base.w == w) && (ee->prop.base.h == h)) return;
844 ee->prop.base.w = w; 386 ee->prop.base.w = w;
845 ee->prop.base.h = h; 387 ee->prop.base.h = h;
846} 388}
847 389
848static void 390static void
849_ecore_evas_drm_size_step_set(Ecore_Evas *ee, int w, int h) 391_drm_size_step_set(Ecore_Evas *ee, int w, int h)
850{ 392{
851 if (w < 0) w = 0;
852 if (h < 0) h = 0;
853 if ((ee->prop.step.w == w) && (ee->prop.step.h == h)) return; 393 if ((ee->prop.step.w == w) && (ee->prop.step.h == h)) return;
854 ee->prop.step.w = w; 394 ee->prop.step.w = w;
855 ee->prop.step.h = h; 395 ee->prop.step.h = h;
856} 396}
857 397
858static void 398static void
859_ecore_evas_drm_object_cursor_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) 399_drm_object_cursor_del(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
860{ 400{
861 Ecore_Evas *ee; 401 Ecore_Evas *ee;
862 402
863 if ((ee = data)) ee->prop.cursor.object = NULL; 403 ee = data;
864} 404 if (ee) ee->prop.cursor.object = NULL;
865
866static void
867_ecore_evas_drm_object_cursor_unset(Ecore_Evas *ee)
868{
869 evas_object_event_callback_del_full(ee->prop.cursor.object, EVAS_CALLBACK_DEL, _ecore_evas_drm_object_cursor_del, ee);
870} 405}
871 406
872static void 407static void
873_ecore_evas_drm_object_cursor_set(Ecore_Evas *ee, Evas_Object *obj, int layer, int hot_x, int hot_y) 408_drm_object_cursor_set(Ecore_Evas *ee, Evas_Object *obj, int layer, int hot_x, int hot_y)
874{ 409{
875 int x, y;
876 Evas_Object *old; 410 Evas_Object *old;
411 int x, y;
877 412
878 old = ee->prop.cursor.object; 413 old = ee->prop.cursor.object;
879 if (obj == NULL) 414 if (!obj)
880 { 415 {
881 ee->prop.cursor.object = NULL; 416 ee->prop.cursor.object = NULL;
882 ee->prop.cursor.layer = 0; 417 ee->prop.cursor.layer = 0;
@@ -899,7 +434,7 @@ _ecore_evas_drm_object_cursor_set(Ecore_Evas *ee, Evas_Object *obj, int layer, i
899 if (evas_pointer_inside_get(ee->evas)) 434 if (evas_pointer_inside_get(ee->evas))
900 evas_object_show(ee->prop.cursor.object); 435 evas_object_show(ee->prop.cursor.object);
901 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, 436 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL,
902 _ecore_evas_drm_object_cursor_del, ee); 437 _drm_object_cursor_del, ee);
903 } 438 }
904 439
905 evas_object_move(ee->prop.cursor.object, x - ee->prop.cursor.hot.x, 440 evas_object_move(ee->prop.cursor.object, x - ee->prop.cursor.hot.x,
@@ -909,13 +444,21 @@ end:
909 if ((old) && (obj != old)) 444 if ((old) && (obj != old))
910 { 445 {
911 evas_object_event_callback_del_full 446 evas_object_event_callback_del_full
912 (old, EVAS_CALLBACK_DEL, _ecore_evas_drm_object_cursor_del, ee); 447 (old, EVAS_CALLBACK_DEL, _drm_object_cursor_del, ee);
913 evas_object_del(old); 448 evas_object_del(old);
914 } 449 }
915} 450}
916 451
917static void 452static void
918_ecore_evas_drm_layer_set(Ecore_Evas *ee, int layer) 453_drm_object_cursor_unset(Ecore_Evas *ee)
454{
455 evas_object_event_callback_del_full(ee->prop.cursor.object,
456 EVAS_CALLBACK_DEL,
457 _drm_object_cursor_del, ee);
458}
459
460static void
461_drm_layer_set(Ecore_Evas *ee, int layer)
919{ 462{
920 if (layer < 1) layer = 1; 463 if (layer < 1) layer = 1;
921 else if (layer > 255) layer = 255; 464 else if (layer > 255) layer = 255;
@@ -924,44 +467,44 @@ _ecore_evas_drm_layer_set(Ecore_Evas *ee, int layer)
924} 467}
925 468
926static void 469static void
927_ecore_evas_drm_iconified_set(Ecore_Evas *ee, Eina_Bool on) 470_drm_iconified_set(Ecore_Evas *ee, Eina_Bool on)
928{ 471{
929 if (ee->prop.iconified == on) return; 472 if (ee->prop.iconified == on) return;
930 ee->prop.iconified = on; 473 ee->prop.iconified = on;
931} 474}
932 475
933static void 476static void
934_ecore_evas_drm_borderless_set(Ecore_Evas *ee, Eina_Bool on) 477_drm_borderless_set(Ecore_Evas *ee, Eina_Bool on)
935{ 478{
936 if (ee->prop.borderless == on) return; 479 if (ee->prop.borderless == on) return;
937 ee->prop.borderless = on; 480 ee->prop.borderless = on;
938} 481}
939 482
940static void 483static void
941_ecore_evas_drm_maximized_set(Ecore_Evas *ee, Eina_Bool on) 484_drm_maximized_set(Ecore_Evas *ee, Eina_Bool on)
942{ 485{
943 if (ee->prop.maximized == on) return; 486 if (ee->prop.maximized == on) return;
944 ee->prop.maximized = on; 487 ee->prop.maximized = on;
945} 488}
946 489
947static void 490static void
948_ecore_evas_drm_fullscreen_set(Ecore_Evas *ee, Eina_Bool on) 491_drm_fullscreen_set(Ecore_Evas *ee, Eina_Bool on)
949{ 492{
950 Eina_Bool resized = EINA_FALSE; 493 Eina_Bool resized = EINA_FALSE;
951 Ecore_Evas_Engine_Drm_Data *edata; 494 Ecore_Evas_Engine_Drm_Data *edata;
952 495
953 edata = ee->engine.data; 496 edata = ee->engine.data;
954 if (ee->prop.fullscreen == on) return; 497 if (ee->prop.fullscreen == on) return;
498 ee->prop.fullscreen = on;
499
955 if (on) 500 if (on)
956 { 501 {
957 Evas_Engine_Info_Drm *einfo;
958 int ow = 0, oh = 0; 502 int ow = 0, oh = 0;
959 503
960 edata->w = ee->w; 504 edata->w = ee->w;
961 edata->h = ee->h; 505 edata->h = ee->h;
962 if ((einfo = (Evas_Engine_Info_Drm *)evas_engine_info_get(ee->evas)))
963 ecore_drm_output_size_get(dev, einfo->info.buffer_id, &ow, &oh);
964 506
507 ecore_drm2_output_geometry_get(edata->output, NULL, NULL, &ow, &oh);
965 if ((ow == 0) || (oh == 0)) 508 if ((ow == 0) || (oh == 0))
966 { 509 {
967 ow = ee->w; 510 ow = ee->w;
@@ -992,7 +535,7 @@ _ecore_evas_drm_fullscreen_set(Ecore_Evas *ee, Eina_Bool on)
992} 535}
993 536
994static void 537static void
995_ecore_evas_drm_withdrawn_set(Ecore_Evas *ee, Eina_Bool on) 538_drm_withdrawn_set(Ecore_Evas *ee, Eina_Bool on)
996{ 539{
997 if (ee->prop.withdrawn == on) return; 540 if (ee->prop.withdrawn == on) return;
998 ee->prop.withdrawn = on; 541 ee->prop.withdrawn = on;
@@ -1001,145 +544,371 @@ _ecore_evas_drm_withdrawn_set(Ecore_Evas *ee, Eina_Bool on)
1001} 544}
1002 545
1003static void 546static void
1004_ecore_evas_drm_ignore_events_set(Ecore_Evas *ee, int ignore) 547_drm_ignore_events_set(Ecore_Evas *ee, int on)
1005{ 548{
1006 if (ee->ignore_events == ignore) return; 549 if (ee->ignore_events == on) return;
1007 ee->ignore_events = ignore; 550 ee->ignore_events = on;
1008} 551}
1009 552
1010static void 553static void
1011_ecore_evas_drm_alpha_set(Ecore_Evas *ee, int alpha) 554_drm_alpha_set(Ecore_Evas *ee, int alpha)
1012{ 555{
1013 if (ee->in_async_render) 556 if (ee->in_async_render)
1014 { 557 {
1015 ee->delayed.alpha = alpha; 558 ee->delayed.alpha = alpha;
1016 ee->delayed.alpha_changed = EINA_TRUE; 559 ee->delayed.alpha_changed = EINA_TRUE;
1017 return;
1018 } 560 }
1019
1020 /* FIXME: TODO: Finish */
1021} 561}
1022 562
1023static void 563static void
1024_ecore_evas_drm_transparent_set(Ecore_Evas *ee, int transparent) 564_drm_transparent_set(Ecore_Evas *ee, int transparent)
1025{ 565{
1026 if (ee->in_async_render) 566 if (ee->in_async_render)
1027 { 567 {
1028 ee->delayed.transparent = transparent; 568 ee->delayed.transparent = transparent;
1029 ee->delayed.transparent_changed = EINA_TRUE; 569 ee->delayed.transparent_changed = EINA_TRUE;
1030 return;
1031 } 570 }
1032
1033 /* FIXME: TODO: Finish */
1034} 571}
1035 572
1036static void 573static void
1037_ecore_evas_drm_aspect_set(Ecore_Evas *ee, double aspect) 574_drm_aspect_set(Ecore_Evas *ee, double aspect)
1038{ 575{
1039 if (ee->prop.aspect == aspect) return; 576 if (ee->prop.aspect == aspect) return;
1040 ee->prop.aspect = aspect; 577 ee->prop.aspect = aspect;
1041} 578}
1042 579
1043static int 580static Ecore_Evas_Interface_Drm *
1044_ecore_evas_drm_render(Ecore_Evas *ee) 581_ecore_evas_drm_interface_new(void)
1045{ 582{
1046 int rend = 0; 583 Ecore_Evas_Interface_Drm *iface;
1047 Eina_List *l;
1048 Ecore_Evas *ee2;
1049 584
1050 if (ee->in_async_render) return 0; 585 iface = calloc(1, sizeof(Ecore_Evas_Interface_Drm));
586 if (!iface) return NULL;
1051 587
1052 if (!ee->visible) 588 iface->base.name = "drm";
589 iface->base.version = 1;
590
591 return iface;
592}
593
594static Ecore_Evas_Engine_Func _ecore_evas_drm_engine_func =
595{
596 _drm_free,
597 NULL, //void (*fn_callback_resize_set) (Ecore_Evas *ee, Ecore_Evas_Event_Cb func);
598 NULL, //void (*fn_callback_move_set) (Ecore_Evas *ee, Ecore_Evas_Event_Cb func);
599 NULL, //void (*fn_callback_show_set) (Ecore_Evas *ee, Ecore_Evas_Event_Cb func);
600 NULL, //void (*fn_callback_hide_set) (Ecore_Evas *ee, Ecore_Evas_Event_Cb func);
601 NULL, //_ecore_evas_drm_delete_request_set,
602 NULL, //void (*fn_callback_destroy_set) (Ecore_Evas *ee, Ecore_Evas_Event_Cb func);
603 NULL, //_ecore_evas_drm_callback_focus_in_set,
604 NULL, //_ecore_evas_drm_callback_focus_out_set,
605 NULL, //_ecore_evas_drm_callback_mouse_in_set,
606 NULL, //_ecore_evas_drm_callback_mouse_out_set,
607 NULL, //void (*fn_callback_sticky_set) (Ecore_Evas *ee, Ecore_Evas_Event_Cb func);
608 NULL, //void (*fn_callback_unsticky_set) (Ecore_Evas *ee, Ecore_Evas_Event_Cb func);
609 NULL, //void (*fn_callback_pre_render_set) (Ecore_Evas *ee, Ecore_Evas_Event_Cb func);
610 NULL, //void (*fn_callback_post_render_set) (Ecore_Evas *ee, Ecore_Evas_Event_Cb func);
611 _drm_move,
612 NULL, //void (*fn_managed_move) (Ecore_Evas *ee, int x, int y);
613 _drm_resize,
614 _drm_move_resize,
615 _drm_rotation_set,
616 NULL, //void (*fn_shaped_set) (Ecore_Evas *ee, int shaped);
617 _drm_show,
618 _drm_hide,
619 NULL, //void (*fn_raise) (Ecore_Evas *ee);
620 NULL, //void (*fn_lower) (Ecore_Evas *ee);
621 NULL, //void (*fn_activate) (Ecore_Evas *ee);
622 _drm_title_set,
623 _drm_name_class_set,
624 _drm_size_min_set,
625 _drm_size_max_set,
626 _drm_size_base_set,
627 _drm_size_step_set,
628 _drm_object_cursor_set,
629 _drm_object_cursor_unset,
630 _drm_layer_set,
631 NULL, //void (*fn_focus_set) (Ecore_Evas *ee, Eina_Bool on);
632 _drm_iconified_set,
633 _drm_borderless_set,
634 NULL, //void (*fn_override_set) (Ecore_Evas *ee, Eina_Bool on);
635 _drm_maximized_set,
636 _drm_fullscreen_set,
637 NULL, //void (*fn_avoid_damage_set) (Ecore_Evas *ee, int on);
638 _drm_withdrawn_set,
639 NULL, //void (*fn_sticky_set) (Ecore_Evas *ee, Eina_Bool on);
640 _drm_ignore_events_set,
641 _drm_alpha_set,
642 _drm_transparent_set,
643 NULL, //void (*fn_profiles_set) (Ecore_Evas *ee, const char **profiles, int count);
644 NULL, //void (*fn_profile_set) (Ecore_Evas *ee, const char *profile);
645
646 NULL, //void (*fn_window_group_set) (Ecore_Evas *ee, const Ecore_Evas *ee_group);
647 _drm_aspect_set,
648 NULL, //void (*fn_urgent_set) (Ecore_Evas *ee, Eina_Bool on);
649 NULL, //void (*fn_modal_set) (Ecore_Evas *ee, Eina_Bool on);
650 NULL, //void (*fn_demands_attention_set) (Ecore_Evas *ee, Eina_Bool on);
651 NULL, //void (*fn_focus_skip_set) (Ecore_Evas *ee, Eina_Bool on);
652
653 _drm_render,
654
655 _drm_screen_geometry_get,
656 NULL, //void (*fn_screen_dpi_get) (const Ecore_Evas *ee, int *xdpi, int *ydpi);
657 NULL, //void (*fn_msg_parent_send) (Ecore_Evas *ee, int maj, int min, void *data, int size);
658 NULL, //void (*fn_msg_send) (Ecore_Evas *ee, int maj, int min, void *data, int size);
659
660 _drm_pointer_xy_get,
661 _drm_pointer_warp,
662
663 NULL, // wm_rot_preferred_rotation_set
664 NULL, // wm_rot_available_rotations_set
665 NULL, // wm_rot_manual_rotation_done_set
666 NULL, // wm_rot_manual_rotation_done
667
668 NULL, // aux_hints_set
669
670 NULL, // animator_register
671 NULL // animator_unregister
672};
673
674EAPI Ecore_Evas *
675ecore_evas_drm_new_internal(const char *device, unsigned int parent EINA_UNUSED, int x, int y, int w, int h)
676{
677 Ecore_Evas *ee;
678 Evas_Engine_Info_Drm *einfo;
679 Ecore_Evas_Interface_Drm *iface;
680 Ecore_Evas_Engine_Drm_Data *edata;
681 int method;
682
683 method = evas_render_method_lookup("drm");
684 if (!method) return NULL;
685
686 ee = calloc(1, sizeof(Ecore_Evas));
687 if (!ee) return NULL;
688
689 edata = calloc(1, sizeof(Ecore_Evas_Engine_Drm_Data));
690 if (!edata)
1053 { 691 {
1054 evas_norender(ee->evas); 692 free(ee);
1055 return 0; 693 return NULL;
1056 } 694 }
1057 695
1058 EINA_LIST_FOREACH(ee->sub_ecore_evas, l, ee2) 696 edata->x = x;
697 edata->y = y;
698 edata->w = w;
699 edata->h = h;
700 edata->depth = 24; // FIXME: Remove hardcode
701 edata->bpp = 32; // FIXME: Remove hardcode
702 edata->format = DRM_FORMAT_XRGB8888;
703
704 if (_ecore_evas_drm_init(edata, device) < 1)
1059 { 705 {
1060 if (ee2->func.fn_pre_render) ee2->func.fn_pre_render(ee2); 706 free(edata);
1061 if (ee2->engine.func->fn_render) 707 free(ee);
1062 rend |= ee2->engine.func->fn_render(ee2); 708 return NULL;
1063 if (ee2->func.fn_post_render) ee2->func.fn_post_render(ee2);
1064 } 709 }
1065 710
1066 if (ee->func.fn_pre_render) ee->func.fn_pre_render(ee); 711 ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS);
1067 712
1068 if (!ee->can_async_render) 713 ee->driver = "drm";
1069 { 714 ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_evas_drm_engine_func;
1070 Eina_List *updates; 715 ee->engine.data = edata;
1071 716
1072 updates = evas_render_updates(ee->evas); 717 /* FIXME */
1073 rend = _ecore_evas_drm_render_updates_process(ee, updates); 718 /* if (edata->device) ee->name = strdup(edata->device); */
1074 evas_render_updates_free(updates); 719
1075 } 720 iface = _ecore_evas_drm_interface_new();
1076 else if (evas_render_async(ee->evas)) 721 ee->engine.ifaces = eina_list_append(ee->engine.ifaces, iface);
722
723 ee->x = ee->req.x = x;
724 ee->y = ee->req.y = y;
725 ee->w = ee->req.w = w;
726 ee->h = ee->req.h = h;
727
728 ee->prop.max.w = 32767;
729 ee->prop.max.h = 32767;
730 ee->prop.layer = 4;
731 ee->prop.request_pos = 0;
732 ee->prop.sticky = 0;
733 ee->prop.withdrawn = EINA_TRUE;
734 ee->alpha = EINA_FALSE;
735
736 ee->can_async_render = 1;
737 if (getenv("ECORE_EVAS_FORCE_SYNC_RENDER"))
738 ee->can_async_render = 0;
739
740 ee->evas = evas_new();
741 evas_data_attach_set(ee->evas, ee);
742 evas_output_method_set(ee->evas, method);
743 evas_output_size_set(ee->evas, w, h);
744 evas_output_viewport_set(ee->evas, 0, 0, w, h);
745
746 if (ee->can_async_render)
747 evas_event_callback_add(ee->evas, EVAS_CALLBACK_RENDER_POST,
748 _drm_render_updates, ee);
749
750 einfo = (Evas_Engine_Info_Drm *)evas_engine_info_get(ee->evas);
751 if (einfo)
1077 { 752 {
1078 ee->in_async_render = EINA_TRUE; 753 einfo->info.fd = edata->fd;
1079 rend = 1; 754 einfo->info.bpp = edata->bpp;
755 einfo->info.depth = edata->depth;
756 einfo->info.format = edata->format;
757 einfo->info.rotation = ee->rotation;
758 einfo->info.output = edata->output;
759 if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
760 {
761 ERR("evas_engine_info_set() for engine '%s' failed", ee->driver);
762 goto eng_err;
763 }
1080 } 764 }
1081 765
1082 return rend; 766 ee->prop.window = ecore_drm2_output_crtc_get(edata->output);
767 ecore_drm2_device_window_set(edata->dev, ee->prop.window);
768
769 ecore_evas_data_set(ee, "device", edata->dev);
770
771 _ecore_evas_register(ee);
772 ecore_evas_input_event_register(ee);
773 ecore_event_window_register(ee->prop.window, ee, ee->evas,
774 (Ecore_Event_Mouse_Move_Cb)_ecore_evas_mouse_move_process,
775 (Ecore_Event_Multi_Move_Cb)_ecore_evas_mouse_multi_move_process,
776 (Ecore_Event_Multi_Down_Cb)_ecore_evas_mouse_multi_down_process,
777 (Ecore_Event_Multi_Up_Cb)_ecore_evas_mouse_multi_up_process);
778
779 return ee;
780
781eng_err:
782 ecore_evas_free(ee);
783 return NULL;
1083} 784}
1084 785
1085static void 786#ifdef BUILD_ECORE_EVAS_GL_DRM
1086_ecore_evas_drm_render_updates(void *data, Evas *evas EINA_UNUSED, void *event) 787EAPI Ecore_Evas *
788ecore_evas_gl_drm_new_internal(const char *device, unsigned int parent EINA_UNUSED, int x, int y, int w, int h)
1087{ 789{
1088 Evas_Event_Render_Post *ev;
1089 Ecore_Evas *ee; 790 Ecore_Evas *ee;
791 Evas_Engine_Info_GL_Drm *einfo;
792 Ecore_Evas_Interface_Drm *iface;
793 Ecore_Evas_Engine_Drm_Data *edata;
794 int method;
1090 795
1091 if (!(ev = event)) return; 796 method = evas_render_method_lookup("gl_drm");
1092 if (!(ee = data)) return; 797 if (!method) return NULL;
1093 798
1094 ee->in_async_render = EINA_FALSE; 799 ee = calloc(1, sizeof(Ecore_Evas));
800 if (!ee) return NULL;
1095 801
1096 _ecore_evas_drm_render_updates_process(ee, ev->updated_area); 802 edata = calloc(1, sizeof(Ecore_Evas_Engine_Drm_Data));
803 if (!edata)
804 {
805 free(ee);
806 return NULL;
807 }
1097 808
1098 /* TODO: handle delayed changes */ 809 edata->x = x;
1099} 810 edata->y = y;
811 edata->w = w;
812 edata->h = h;
813 edata->depth = 24; // FIXME: Remove hardcode
814 edata->bpp = 32; // FIXME: Remove hardcode
815 edata->format = DRM_FORMAT_XRGB8888;
1100 816
1101static int 817 dlopen("libglapi.so.0", RTLD_LAZY | RTLD_GLOBAL);
1102_ecore_evas_drm_render_updates_process(Ecore_Evas *ee, Eina_List *updates) 818 if (dlerror())
1103{ 819 {
1104 int rend = 0; 820 free(edata);
821 free(ee);
822 return NULL;
823 }
1105 824
1106 if ((ee->visible) && (updates)) 825 if (_ecore_evas_drm_init(edata, device) < 1)
1107 { 826 {
1108// Eina_List *l = NULL; 827 free(edata);
1109// Eina_Rectangle *r; 828 free(ee);
1110// 829 return NULL;
1111// EINA_LIST_FOREACH(updates, l, r) 830 }
1112// {
1113// /* TODO */
1114// }
1115 831
1116 _ecore_evas_idle_timeout_update(ee); 832 ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS);
1117 rend = 1; 833
834 ee->driver = "gl_drm";
835 ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_evas_drm_engine_func;
836 ee->engine.data = edata;
837
838 /* FIXME */
839 /* if (edata->device) ee->name = strdup(edata->device); */
840
841 iface = _ecore_evas_drm_interface_new();
842 ee->engine.ifaces = eina_list_append(ee->engine.ifaces, iface);
843
844 ee->x = ee->req.x = x;
845 ee->y = ee->req.y = y;
846 ee->w = ee->req.w = w;
847 ee->h = ee->req.h = h;
848
849 ee->prop.max.w = 32767;
850 ee->prop.max.h = 32767;
851 ee->prop.layer = 4;
852 ee->prop.request_pos = 0;
853 ee->prop.sticky = 0;
854 ee->prop.withdrawn = EINA_TRUE;
855 ee->alpha = EINA_FALSE;
856
857 ee->can_async_render = 0; // FIXME ??
858 if (getenv("ECORE_EVAS_FORCE_SYNC_RENDER"))
859 ee->can_async_render = 0;
860
861 ee->evas = evas_new();
862 evas_data_attach_set(ee->evas, ee);
863 evas_output_method_set(ee->evas, method);
864 evas_output_size_set(ee->evas, w, h);
865 evas_output_viewport_set(ee->evas, 0, 0, w, h);
866
867 if (ee->can_async_render)
868 evas_event_callback_add(ee->evas, EVAS_CALLBACK_RENDER_POST,
869 _drm_render_updates, ee);
870
871 einfo = (Evas_Engine_Info_GL_Drm *)evas_engine_info_get(ee->evas);
872 if (einfo)
873 {
874 char *num;
875
876 einfo->info.vsync = EINA_TRUE;
877
878 num = getenv("EVAS_DRM_VSYNC");
879 if ((num) && (!atoi(num)))
880 einfo->info.vsync = EINA_FALSE;
881
882 einfo->info.fd = edata->fd;
883 einfo->info.bpp = edata->bpp;
884 einfo->info.depth = edata->depth;
885 einfo->info.format = edata->format;
886 einfo->info.rotation = ee->rotation;
887 einfo->info.output = edata->output;
888 if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
889 {
890 ERR("evas_engine_info_set() for engine '%s' failed", ee->driver);
891 goto eng_err;
892 }
1118 } 893 }
1119 else
1120 evas_norender(ee->evas);
1121 894
1122 if (ee->func.fn_post_render) ee->func.fn_post_render(ee); 895 ee->prop.window = ecore_drm2_output_crtc_get(edata->output);
896 ecore_drm2_device_window_set(edata->dev, ee->prop.window);
1123 897
1124 return rend; 898 ecore_evas_data_set(ee, "device", edata->dev);
1125}
1126 899
1127static void 900 _ecore_evas_register(ee);
1128_ecore_evas_drm_screen_geometry_get(const Ecore_Evas *ee EINA_UNUSED, int *x, int *y, int *w, int *h) 901 ecore_evas_input_event_register(ee);
1129{ 902 ecore_event_window_register(ee->prop.window, ee, ee->evas,
1130 ecore_drm_outputs_geometry_get(dev, x, y, w, h); 903 (Ecore_Event_Mouse_Move_Cb)_ecore_evas_mouse_move_process,
1131} 904 (Ecore_Event_Multi_Move_Cb)_ecore_evas_mouse_multi_move_process,
905 (Ecore_Event_Multi_Down_Cb)_ecore_evas_mouse_multi_down_process,
906 (Ecore_Event_Multi_Up_Cb)_ecore_evas_mouse_multi_up_process);
1132 907
1133static void 908 return ee;
1134_ecore_evas_drm_pointer_xy_get(const Ecore_Evas *ee EINA_UNUSED, Evas_Coord *x, Evas_Coord *y)
1135{
1136 /* get pointer position from input */
1137 ecore_drm_device_pointer_xy_get(dev, x, y);
1138}
1139 909
1140Eina_Bool 910eng_err:
1141_ecore_evas_drm_pointer_warp(const Ecore_Evas *ee EINA_UNUSED, Evas_Coord x, Evas_Coord y) 911 ecore_evas_free(ee);
1142{ 912 return NULL;
1143 ecore_drm_device_pointer_warp(dev, x, y);
1144 return EINA_TRUE;
1145} 913}
914#endif