diff options
author | Chris Michael <cpmichael@osg.samsung.com> | 2016-05-03 12:03:00 -0400 |
---|---|---|
committer | Chris Michael <cpmichael@osg.samsung.com> | 2016-05-27 11:57:53 -0400 |
commit | 93178199a6c302e899438a32e8c296dc5bd2d248 (patch) | |
tree | 458f63b38e1ebc1aeb9bc0144226fe729a9db9fa /src/modules/ecore_evas/engines/drm/ecore_evas_drm.c | |
parent | ccb573ec7b460326e5d45ce2a3f9ac7a7470e335 (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/ecore_evas_drm.c')
-rw-r--r-- | src/modules/ecore_evas/engines/drm/ecore_evas_drm.c | 1247 |
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 | ||
46 | typedef struct _Ecore_Evas_Engine_Drm_Data Ecore_Evas_Engine_Drm_Data; | 44 | typedef struct _Ecore_Evas_Engine_Drm_Data |
47 | |||
48 | struct _Ecore_Evas_Engine_Drm_Data | ||
49 | { | ||
50 | int w, h; | ||
51 | }; | ||
52 | |||
53 | /* local function prototypes */ | ||
54 | static int _ecore_evas_drm_init(const char *device); | ||
55 | static int _ecore_evas_drm_shutdown(void); | ||
56 | static Ecore_Evas_Interface_Drm *_ecore_evas_drm_interface_new(void); | ||
57 | static void _ecore_evas_drm_free(Ecore_Evas *ee); | ||
58 | static void _ecore_evas_drm_callback_resize_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func); | ||
59 | static void _ecore_evas_drm_callback_move_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func); | ||
60 | static void _ecore_evas_drm_callback_focus_in_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func); | ||
61 | static void _ecore_evas_drm_callback_focus_out_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func); | ||
62 | static void _ecore_evas_drm_callback_mouse_in_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func); | ||
63 | static void _ecore_evas_drm_callback_mouse_out_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func); | ||
64 | static void _ecore_evas_drm_delete_request_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func); | ||
65 | static void _ecore_evas_drm_move(Ecore_Evas *ee, int x, int y); | ||
66 | static void _ecore_evas_drm_resize(Ecore_Evas *ee, int w, int h); | ||
67 | static void _ecore_evas_drm_move_resize(Ecore_Evas *ee, int x, int y, int w, int h); | ||
68 | static void _ecore_evas_drm_rotation_set(Ecore_Evas *ee, int rotation, int resize); | ||
69 | static void _ecore_evas_drm_show(Ecore_Evas *ee); | ||
70 | static void _ecore_evas_drm_hide(Ecore_Evas *ee); | ||
71 | static void _ecore_evas_drm_title_set(Ecore_Evas *ee, const char *title); | ||
72 | static void _ecore_evas_drm_name_class_set(Ecore_Evas *ee, const char *n, const char *c); | ||
73 | static void _ecore_evas_drm_size_min_set(Ecore_Evas *ee, int w, int h); | ||
74 | static void _ecore_evas_drm_size_max_set(Ecore_Evas *ee, int w, int h); | ||
75 | static void _ecore_evas_drm_size_base_set(Ecore_Evas *ee, int w, int h); | ||
76 | static void _ecore_evas_drm_size_step_set(Ecore_Evas *ee, int w, int h); | ||
77 | static void _ecore_evas_drm_object_cursor_set(Ecore_Evas *ee, Evas_Object *obj, int layer, int hot_x, int hot_y); | ||
78 | static void _ecore_evas_drm_object_cursor_unset(Ecore_Evas *ee); | ||
79 | static void _ecore_evas_drm_layer_set(Ecore_Evas *ee, int layer); | ||
80 | static void _ecore_evas_drm_iconified_set(Ecore_Evas *ee, Eina_Bool on); | ||
81 | static void _ecore_evas_drm_borderless_set(Ecore_Evas *ee, Eina_Bool on); | ||
82 | static void _ecore_evas_drm_maximized_set(Ecore_Evas *ee, Eina_Bool on); | ||
83 | static void _ecore_evas_drm_fullscreen_set(Ecore_Evas *ee, Eina_Bool on); | ||
84 | static void _ecore_evas_drm_withdrawn_set(Ecore_Evas *ee, Eina_Bool on); | ||
85 | static void _ecore_evas_drm_ignore_events_set(Ecore_Evas *ee, int ignore); | ||
86 | static void _ecore_evas_drm_alpha_set(Ecore_Evas *ee, int alpha); | ||
87 | static void _ecore_evas_drm_transparent_set(Ecore_Evas *ee, int transparent); | ||
88 | static void _ecore_evas_drm_aspect_set(Ecore_Evas *ee, double aspect); | ||
89 | |||
90 | static int _ecore_evas_drm_render(Ecore_Evas *ee); | ||
91 | static void _ecore_evas_drm_render_updates(void *data, Evas *evas EINA_UNUSED, void *event); | ||
92 | static int _ecore_evas_drm_render_updates_process(Ecore_Evas *ee, Eina_List *updates); | ||
93 | |||
94 | static void _ecore_evas_drm_screen_geometry_get(const Ecore_Evas *ee EINA_UNUSED, int *x, int *y, int *w, int *h); | ||
95 | static void _ecore_evas_drm_pointer_xy_get(const Ecore_Evas *ee, Evas_Coord *x, Evas_Coord *y); | ||
96 | Eina_Bool _ecore_evas_drm_pointer_warp(const Ecore_Evas *ee EINA_UNUSED, Evas_Coord x, Evas_Coord y); | ||
97 | |||
98 | /* local variables */ | ||
99 | static int _ecore_evas_init_count = 0; | ||
100 | static Ecore_Drm_Device *dev = NULL; | ||
101 | |||
102 | static 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 | 56 | static int _drm_init_count = 0; |
177 | |||
178 | NULL, // fn_animator_register | ||
179 | NULL // fn_animator_unregister | ||
180 | }; | ||
181 | 57 | ||
182 | EAPI Ecore_Evas * | 58 | static int |
183 | ecore_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; | 107 | output_err: |
343 | ev->root.y = ev->y; | 108 | ecore_drm2_device_close(edata->dev); |
109 | open_err: | ||
110 | ecore_drm2_device_free(edata->dev); | ||
111 | dev_err: | ||
112 | ecore_drm2_shutdown(); | ||
113 | init_err: | ||
114 | return --_drm_init_count; | ||
115 | } | ||
344 | 116 | ||
345 | ecore_event_evas_mouse_move(NULL, ECORE_EVENT_MOUSE_MOVE, ev); | 117 | static 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 | ||
350 | eng_err: | 128 | return _drm_init_count; |
351 | ecore_evas_free(ee); | ||
352 | soft_err: | ||
353 | ee_err: | ||
354 | _ecore_evas_drm_shutdown(); | ||
355 | return NULL; | ||
356 | } | 129 | } |
357 | 130 | ||
358 | #ifdef BUILD_ECORE_EVAS_GL_DRM | 131 | static void |
359 | EAPI Ecore_Evas * | 132 | _drm_free(Ecore_Evas *ee) |
360 | ecore_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 */ | 143 | static 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); | 161 | static 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 | ||
519 | eng_err: | 173 | ee->in_async_render = EINA_FALSE; |
520 | ecore_evas_free(ee); | 174 | _drm_render_updates_process(ee, ev->updated_area); |
521 | ee_err: | ||
522 | _ecore_evas_drm_shutdown(); | ||
523 | return NULL; | ||
524 | } | 175 | } |
525 | #endif | ||
526 | 176 | ||
527 | /* local functions */ | ||
528 | static int | 177 | static 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 | |||
592 | output_err: | ||
593 | ecore_drm_inputs_destroy(dev); | ||
594 | input_err: | ||
595 | ecore_drm_sprites_destroy(dev); | ||
596 | sprite_err: | ||
597 | ecore_drm_device_close(dev); | ||
598 | dev_open_err: | ||
599 | ecore_drm_launcher_disconnect(dev); | ||
600 | ecore_drm_device_free(dev); | ||
601 | dev = NULL; | ||
602 | launcher_err: | ||
603 | dev_err: | ||
604 | ecore_drm_shutdown(); | ||
605 | return --_ecore_evas_init_count; | ||
606 | } | 217 | } |
607 | 218 | ||
608 | static int | 219 | static 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 | ||
632 | static Ecore_Evas_Interface_Drm * | 228 | static 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 */ | 237 | static Eina_Bool |
647 | static 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 | ||
658 | static void | 247 | static 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 | ||
664 | static 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 | ||
670 | static 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 | ||
676 | static 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 | ||
682 | static 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 | ||
688 | static 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 | ||
694 | static void | 274 | static 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 | ||
700 | static void | 293 | static 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 | ||
711 | static void | 304 | static 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 | ||
724 | static void | 317 | static 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 | ||
733 | static void | 326 | static 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 | |||
746 | static 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 | ||
773 | static void | 339 | static 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 | |||
792 | static 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 | ||
801 | static void | 348 | static 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 | ||
818 | static void | 366 | static 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 | ||
828 | static void | 374 | static 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 | ||
838 | static void | 382 | static 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 | ||
848 | static void | 390 | static 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 | ||
858 | static void | 398 | static 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 | |||
866 | static 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 | ||
872 | static void | 407 | static 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 | ||
917 | static void | 452 | static 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 | |||
460 | static 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 | ||
926 | static void | 469 | static 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 | ||
933 | static void | 476 | static 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 | ||
940 | static void | 483 | static 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 | ||
947 | static void | 490 | static 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 | ||
994 | static void | 537 | static 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 | ||
1003 | static void | 546 | static 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 | ||
1010 | static void | 553 | static 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 | ||
1023 | static void | 563 | static 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 | ||
1036 | static void | 573 | static 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 | ||
1043 | static int | 580 | static 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 | |||
594 | static 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 | |||
674 | EAPI Ecore_Evas * | ||
675 | ecore_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 | |||
781 | eng_err: | ||
782 | ecore_evas_free(ee); | ||
783 | return NULL; | ||
1083 | } | 784 | } |
1084 | 785 | ||
1085 | static void | 786 | #ifdef BUILD_ECORE_EVAS_GL_DRM |
1086 | _ecore_evas_drm_render_updates(void *data, Evas *evas EINA_UNUSED, void *event) | 787 | EAPI Ecore_Evas * |
788 | ecore_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 | ||
1101 | static 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 | ||
1127 | static 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 | ||
1133 | static 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 | ||
1140 | Eina_Bool | 910 | eng_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 | ||