diff options
Diffstat (limited to '')
-rw-r--r-- | m4/evas_check_engine.m4 | 13 | ||||
-rw-r--r-- | src/Makefile_Evas.am | 14 | ||||
-rw-r--r-- | src/modules/evas/engines/drm/Evas_Engine_Drm.h | 21 | ||||
-rw-r--r-- | src/modules/evas/engines/drm/evas_engine.c | 102 | ||||
-rw-r--r-- | src/modules/evas/engines/drm/evas_engine.h | 56 | ||||
-rw-r--r-- | src/modules/evas/engines/drm/evas_outbuf.c | 506 | ||||
-rw-r--r-- | src/modules/evas/engines/gl_drm/Evas_Engine_GL_Drm.h | 6 | ||||
-rw-r--r-- | src/modules/evas/engines/gl_drm/evas_engine.c | 70 | ||||
-rw-r--r-- | src/modules/evas/engines/gl_drm/evas_engine.h | 24 | ||||
-rw-r--r-- | src/modules/evas/engines/gl_drm/evas_outbuf.c | 197 |
10 files changed, 708 insertions, 301 deletions
diff --git a/m4/evas_check_engine.m4 b/m4/evas_check_engine.m4 index 448a210592..4789d4b9f0 100644 --- a/m4/evas_check_engine.m4 +++ b/m4/evas_check_engine.m4 | |||
@@ -597,16 +597,23 @@ AC_DEFUN([EVAS_CHECK_ENGINE_DEP_DRM], | |||
597 | [ | 597 | [ |
598 | 598 | ||
599 | requirement="" | 599 | requirement="" |
600 | have_dep="yes" | 600 | have_dep="no" |
601 | have_hw_dep="no" | 601 | have_hw_dep="no" |
602 | evas_engine_[]$1[]_cflags="" | 602 | evas_engine_[]$1[]_cflags="" |
603 | evas_engine_[]$1[]_libs="" | 603 | evas_engine_[]$1[]_libs="" |
604 | 604 | ||
605 | PKG_CHECK_EXISTS([libdrm], | ||
606 | [ | ||
607 | have_dep="yes" | ||
608 | requirement="libdrm" | ||
609 | ], [have_dep="no"]) | ||
610 | |||
605 | if test "x${have_dep}" = "xyes" ; then | 611 | if test "x${have_dep}" = "xyes" ; then |
606 | if test "x$3" = "xstatic" ; then | 612 | if test "x$3" = "xstatic" ; then |
607 | requirements_pc_evas="${requirement} ${requirements_pc_evas}" | 613 | requirements_pc_evas="${requirement} ${requirements_pc_evas}" |
608 | requirements_pc_deps_evas="${requirement} ${requirements_pc_deps_evas}" | 614 | requirements_pc_deps_evas="${requirement} ${requirements_pc_deps_evas}" |
609 | else | 615 | else |
616 | PKG_CHECK_MODULES([DRM], [${requirement}]) | ||
610 | evas_engine_[]$1[]_cflags="${DRM_CFLAGS}" | 617 | evas_engine_[]$1[]_cflags="${DRM_CFLAGS}" |
611 | evas_engine_[]$1[]_libs="${DRM_LIBS}" | 618 | evas_engine_[]$1[]_libs="${DRM_LIBS}" |
612 | fi | 619 | fi |
@@ -636,10 +643,10 @@ else | |||
636 | AC_MSG_ERROR([We currently do not support GL DRM without OpenGL ES. Please consider OpenGL ES if you want to use it.]) | 643 | AC_MSG_ERROR([We currently do not support GL DRM without OpenGL ES. Please consider OpenGL ES if you want to use it.]) |
637 | fi | 644 | fi |
638 | 645 | ||
639 | PKG_CHECK_EXISTS([egl ${gl_library} gbm wayland-client >= REQUIRED_WAYLAND_VERSION], | 646 | PKG_CHECK_EXISTS([egl ${gl_library} libdrm gbm wayland-client >= REQUIRED_WAYLAND_VERSION], |
640 | [ | 647 | [ |
641 | have_dep="yes" | 648 | have_dep="yes" |
642 | requirement="egl ${gl_library} gbm wayland-client >= REQUIRED_WAYLAND_VERSION" | 649 | requirement="egl ${gl_library} libdrm gbm wayland-client >= REQUIRED_WAYLAND_VERSION" |
643 | ], | 650 | ], |
644 | [have_dep="no"]) | 651 | [have_dep="no"]) |
645 | 652 | ||
diff --git a/src/Makefile_Evas.am b/src/Makefile_Evas.am index daa11b8a86..19fea04991 100644 --- a/src/Makefile_Evas.am +++ b/src/Makefile_Evas.am | |||
@@ -1276,7 +1276,6 @@ endif | |||
1276 | endif | 1276 | endif |
1277 | 1277 | ||
1278 | if BUILD_ENGINE_DRM | 1278 | if BUILD_ENGINE_DRM |
1279 | dist_installed_evasmainheaders_DATA += modules/evas/engines/drm/Evas_Engine_Drm.h | ||
1280 | DRM_SOURCES = \ | 1279 | DRM_SOURCES = \ |
1281 | modules/evas/engines/drm/evas_outbuf.c \ | 1280 | modules/evas/engines/drm/evas_outbuf.c \ |
1282 | modules/evas/engines/drm/evas_engine.c \ | 1281 | modules/evas/engines/drm/evas_engine.c \ |
@@ -1301,20 +1300,19 @@ modules_evas_engines_drm_module_la_CPPFLAGS = -I$(top_builddir)/src/lib/efl \ | |||
1301 | -I$(top_srcdir)/src/lib/evas/cserve2 \ | 1300 | -I$(top_srcdir)/src/lib/evas/cserve2 \ |
1302 | -I$(top_srcdir)/src/modules/evas/engines/drm \ | 1301 | -I$(top_srcdir)/src/modules/evas/engines/drm \ |
1303 | @EVAS_CFLAGS@ \ | 1302 | @EVAS_CFLAGS@ \ |
1304 | @ECORE_DRM_CFLAGS@ \ | 1303 | @ECORE_DRM2_CFLAGS@ \ |
1305 | @evas_engine_drm_cflags@ | 1304 | @evas_engine_drm_cflags@ |
1306 | modules_evas_engines_drm_module_la_LIBADD = \ | 1305 | modules_evas_engines_drm_module_la_LIBADD = \ |
1307 | @USE_EVAS_LIBS@ \ | 1306 | @USE_EVAS_LIBS@ \ |
1308 | @USE_ECORE_DRM_LIBS@ \ | 1307 | @USE_ECORE_DRM2_LIBS@ \ |
1309 | @evas_engine_drm_libs@ | 1308 | @evas_engine_drm_libs@ |
1310 | modules_evas_engines_drm_module_la_DEPENDENCIES = @USE_EVAS_INTERNAL_LIBS@ @USE_ECORE_DRM_INTERNAL_LIBS@ | 1309 | modules_evas_engines_drm_module_la_DEPENDENCIES = @USE_EVAS_INTERNAL_LIBS@ @USE_ECORE_DRM2_INTERNAL_LIBS@ |
1311 | modules_evas_engines_drm_module_la_LDFLAGS = -module @EFL_LTMODULE_FLAGS@ | 1310 | modules_evas_engines_drm_module_la_LDFLAGS = -module @EFL_LTMODULE_FLAGS@ |
1312 | modules_evas_engines_drm_module_la_LIBTOOLFLAGS = --tag=disable-static | 1311 | modules_evas_engines_drm_module_la_LIBTOOLFLAGS = --tag=disable-static |
1313 | endif | 1312 | endif |
1314 | endif | 1313 | endif |
1315 | 1314 | ||
1316 | if BUILD_ENGINE_GL_DRM | 1315 | if BUILD_ENGINE_GL_DRM |
1317 | dist_installed_evasmainheaders_DATA += modules/evas/engines/gl_drm/Evas_Engine_GL_Drm.h | ||
1318 | GL_DRM_SOURCES = \ | 1316 | GL_DRM_SOURCES = \ |
1319 | modules/evas/engines/gl_drm/evas_outbuf.c \ | 1317 | modules/evas/engines/gl_drm/evas_outbuf.c \ |
1320 | modules/evas/engines/gl_drm/evas_engine.c \ | 1318 | modules/evas/engines/gl_drm/evas_engine.c \ |
@@ -1339,13 +1337,13 @@ modules_evas_engines_gl_drm_module_la_CPPFLAGS = -I$(top_builddir)/src/lib/efl \ | |||
1339 | -I$(top_srcdir)/src/lib/evas/cserve2 \ | 1337 | -I$(top_srcdir)/src/lib/evas/cserve2 \ |
1340 | -I$(top_srcdir)/src/modules/evas/engines/gl_drm \ | 1338 | -I$(top_srcdir)/src/modules/evas/engines/gl_drm \ |
1341 | @EVAS_CFLAGS@ \ | 1339 | @EVAS_CFLAGS@ \ |
1342 | @ECORE_DRM_CFLAGS@ \ | 1340 | @ECORE_DRM2_CFLAGS@ \ |
1343 | @evas_engine_gl_drm_cflags@ | 1341 | @evas_engine_gl_drm_cflags@ |
1344 | modules_evas_engines_gl_drm_module_la_LIBADD = \ | 1342 | modules_evas_engines_gl_drm_module_la_LIBADD = \ |
1345 | @USE_EVAS_LIBS@ \ | 1343 | @USE_EVAS_LIBS@ \ |
1346 | @USE_ECORE_DRM_LIBS@ \ | 1344 | @USE_ECORE_DRM2_LIBS@ \ |
1347 | @evas_engine_gl_drm_libs@ | 1345 | @evas_engine_gl_drm_libs@ |
1348 | modules_evas_engines_gl_drm_module_la_DEPENDENCIES = @USE_EVAS_INTERNAL_LIBS@ @USE_ECORE_DRM_INTERNAL_LIBS@ | 1346 | modules_evas_engines_gl_drm_module_la_DEPENDENCIES = @USE_EVAS_INTERNAL_LIBS@ @USE_ECORE_DRM2_INTERNAL_LIBS@ |
1349 | modules_evas_engines_gl_drm_module_la_LDFLAGS = -module @EFL_LTMODULE_FLAGS@ | 1347 | modules_evas_engines_gl_drm_module_la_LDFLAGS = -module @EFL_LTMODULE_FLAGS@ |
1350 | modules_evas_engines_gl_drm_module_la_LIBTOOLFLAGS = --tag=disable-static | 1348 | modules_evas_engines_gl_drm_module_la_LIBTOOLFLAGS = --tag=disable-static |
1351 | endif | 1349 | endif |
diff --git a/src/modules/evas/engines/drm/Evas_Engine_Drm.h b/src/modules/evas/engines/drm/Evas_Engine_Drm.h index 136eb919db..457db625e7 100644 --- a/src/modules/evas/engines/drm/Evas_Engine_Drm.h +++ b/src/modules/evas/engines/drm/Evas_Engine_Drm.h | |||
@@ -1,11 +1,7 @@ | |||
1 | #ifndef _EVAS_ENGINE_DRM_H | 1 | #ifndef _EVAS_ENGINE_DRM_H |
2 | # define _EVAS_ENGINE_DRM_H | 2 | # define _EVAS_ENGINE_DRM_H |
3 | 3 | ||
4 | # include <Ecore_Drm.h> | 4 | typedef struct _Evas_Engine_Info_Drm |
5 | |||
6 | typedef struct _Evas_Engine_Info_Drm Evas_Engine_Info_Drm; | ||
7 | |||
8 | struct _Evas_Engine_Info_Drm | ||
9 | { | 5 | { |
10 | /* PRIVATE - don't mess with this baby or evas will poke its tongue out */ | 6 | /* PRIVATE - don't mess with this baby or evas will poke its tongue out */ |
11 | /* at you and make nasty noises */ | 7 | /* at you and make nasty noises */ |
@@ -13,18 +9,17 @@ struct _Evas_Engine_Info_Drm | |||
13 | 9 | ||
14 | struct | 10 | struct |
15 | { | 11 | { |
16 | unsigned int rotation, depth; | 12 | int fd; |
17 | Eina_Bool destination_alpha : 1; | 13 | int depth, bpp; |
18 | Eina_Bool vsync : 1; | 14 | unsigned int format, rotation; |
19 | 15 | ||
20 | unsigned int crtc_id, conn_id, buffer_id; | 16 | void *output; |
21 | 17 | Eina_Bool alpha : 1; | |
22 | Eina_Bool use_hw_accel : 1; | 18 | Eina_Bool vsync : 1; |
23 | Ecore_Drm_Device *dev; | ||
24 | } info; | 19 | } info; |
25 | 20 | ||
26 | /* non-blocking or blocking mode */ | 21 | /* non-blocking or blocking mode */ |
27 | Evas_Engine_Render_Mode render_mode; | 22 | Evas_Engine_Render_Mode render_mode; |
28 | }; | 23 | } Evas_Engine_Info_Drm; |
29 | 24 | ||
30 | #endif | 25 | #endif |
diff --git a/src/modules/evas/engines/drm/evas_engine.c b/src/modules/evas/engines/drm/evas_engine.c index 40365a99f1..e3cd01e576 100644 --- a/src/modules/evas/engines/drm/evas_engine.c +++ b/src/modules/evas/engines/drm/evas_engine.c | |||
@@ -1,65 +1,57 @@ | |||
1 | #include "evas_engine.h" | 1 | #include "evas_engine.h" |
2 | 2 | ||
3 | /* local structures */ | 3 | typedef struct _Render_Engine |
4 | typedef struct _Render_Engine Render_Engine; | ||
5 | |||
6 | struct _Render_Engine | ||
7 | { | 4 | { |
8 | Render_Engine_Software_Generic generic; | 5 | Render_Engine_Software_Generic generic; |
9 | }; | 6 | } Render_Engine; |
10 | 7 | ||
11 | /* function tables - filled in later (func and parent func) */ | ||
12 | static Evas_Func func, pfunc; | 8 | static Evas_Func func, pfunc; |
13 | 9 | ||
14 | /* external variables */ | ||
15 | int _evas_engine_drm_log_dom; | 10 | int _evas_engine_drm_log_dom; |
16 | 11 | ||
17 | /* local functions */ | 12 | static Render_Engine * |
18 | static void * | 13 | _render_engine_setup(Evas_Engine_Info_Drm *info, int w, int h) |
19 | _output_setup(Evas_Engine_Info_Drm *info, int w, int h) | ||
20 | { | 14 | { |
21 | Render_Engine *re = NULL; | 15 | Render_Engine *re; |
22 | Outbuf *ob; | 16 | Outbuf *ob; |
23 | 17 | ||
24 | /* try to allocate space for our render engine structure */ | 18 | re = calloc(1, sizeof(Render_Engine)); |
25 | if (!(re = calloc(1, sizeof(Render_Engine)))) | 19 | if (!re) return NULL; |
26 | goto on_error; | ||
27 | 20 | ||
28 | /* try to create new outbuf */ | 21 | ob = _outbuf_setup(info, w, h); |
29 | if (!(ob = evas_outbuf_setup(info, w, h))) | 22 | if (!ob) goto err; |
30 | goto on_error; | ||
31 | 23 | ||
32 | if (!evas_render_engine_software_generic_init(&re->generic, ob, | 24 | if (!evas_render_engine_software_generic_init(&re->generic, ob, |
33 | evas_outbuf_buffer_state_get, | 25 | _outbuf_state_get, |
34 | evas_outbuf_rot_get, | 26 | _outbuf_rotation_get, |
35 | evas_outbuf_reconfigure, NULL, | 27 | _outbuf_reconfigure, |
36 | evas_outbuf_update_region_new, | 28 | NULL, |
37 | evas_outbuf_update_region_push, | 29 | _outbuf_update_region_new, |
38 | evas_outbuf_update_region_free, | 30 | _outbuf_update_region_push, |
39 | NULL, evas_outbuf_flush, | 31 | _outbuf_update_region_free, |
40 | evas_outbuf_free, | 32 | NULL, |
33 | _outbuf_flush, | ||
34 | _outbuf_free, | ||
41 | ob->w, ob->h)) | 35 | ob->w, ob->h)) |
42 | goto on_error; | 36 | goto init_err; |
43 | 37 | ||
44 | /* return the allocated render_engine structure */ | ||
45 | return re; | 38 | return re; |
46 | 39 | ||
47 | on_error: | 40 | init_err: |
48 | if (re) evas_render_engine_software_generic_clean(&re->generic); | 41 | evas_render_engine_software_generic_clean(&re->generic); |
49 | 42 | err: | |
50 | free(re); | 43 | free(re); |
51 | return NULL; | 44 | return NULL; |
52 | } | 45 | } |
53 | 46 | ||
54 | /* engine api functions */ | ||
55 | static void * | 47 | static void * |
56 | eng_info(Evas *evas EINA_UNUSED) | 48 | eng_info(Evas *evas EINA_UNUSED) |
57 | { | 49 | { |
58 | Evas_Engine_Info_Drm *info; | 50 | Evas_Engine_Info_Drm *info; |
59 | 51 | ||
60 | /* try to allocate space for our engine info structure */ | 52 | /* try to allocate space for our engine info structure */ |
61 | if (!(info = calloc(1, sizeof(Evas_Engine_Info_Drm)))) | 53 | info = calloc(1, sizeof(Evas_Engine_Info_Drm)); |
62 | return NULL; | 54 | if (!info) return NULL; |
63 | 55 | ||
64 | /* set some engine default properties */ | 56 | /* set some engine default properties */ |
65 | info->magic.magic = rand(); | 57 | info->magic.magic = rand(); |
@@ -74,55 +66,47 @@ eng_info_free(Evas *evas EINA_UNUSED, void *einfo) | |||
74 | Evas_Engine_Info_Drm *info; | 66 | Evas_Engine_Info_Drm *info; |
75 | 67 | ||
76 | /* free the engine info */ | 68 | /* free the engine info */ |
77 | if ((info = (Evas_Engine_Info_Drm *)einfo)) | 69 | info = (Evas_Engine_Info_Drm *)einfo; |
78 | free(info); | 70 | free(info); |
79 | } | 71 | } |
80 | 72 | ||
81 | static int | 73 | static int |
82 | eng_setup(Evas *evas, void *einfo) | 74 | eng_setup(Evas *evas, void *einfo) |
83 | { | 75 | { |
84 | Evas_Engine_Info_Drm *info; | ||
85 | Evas_Public_Data *epd; | ||
86 | Render_Engine *re; | 76 | Render_Engine *re; |
77 | Evas_Public_Data *epd; | ||
78 | Evas_Engine_Info_Drm *info; | ||
87 | 79 | ||
88 | /* try to cast to our engine info structure */ | 80 | info = (Evas_Engine_Info_Drm *)einfo; |
89 | if (!(info = (Evas_Engine_Info_Drm *)einfo)) return 0; | 81 | if (!info) return 0; |
90 | 82 | ||
91 | /* try to get the evas public data */ | 83 | epd = eo_data_scope_get(evas, EVAS_CANVAS_CLASS); |
92 | if (!(epd = eo_data_scope_get(evas, EVAS_CANVAS_CLASS))) return 0; | 84 | if (!epd) return 0; |
93 | 85 | ||
94 | /* check for valid engine output */ | 86 | re = epd->engine.data.output; |
95 | if (!(re = epd->engine.data.output)) | 87 | if (!re) |
96 | { | 88 | { |
97 | /* NB: If we have no valid output then assume we have not been | ||
98 | * initialized yet and call any needed common init routines */ | ||
99 | evas_common_init(); | 89 | evas_common_init(); |
100 | 90 | ||
101 | /* try to create a new render_engine */ | 91 | re = _render_engine_setup(info, epd->output.w, epd->output.h); |
102 | if (!(re = _output_setup(info, epd->output.w, epd->output.h))) | 92 | if (!re) return 0; |
103 | return 0; | ||
104 | } | 93 | } |
105 | else | 94 | else |
106 | { | 95 | { |
107 | Outbuf *ob; | 96 | Outbuf *ob; |
108 | 97 | ||
109 | /* try to create a new outbuf */ | 98 | ob = _outbuf_setup(info, epd->output.w, epd->output.h); |
110 | ob = evas_outbuf_setup(info, epd->output.w, epd->output.h); | ||
111 | if (!ob) return 0; | 99 | if (!ob) return 0; |
112 | 100 | ||
113 | /* if we have an existing outbuf, free it */ | 101 | evas_render_engine_software_generic_update(&re->generic, ob, |
114 | evas_render_engine_software_generic_update(&re->generic, ob, | ||
115 | ob->w, ob->h); | 102 | ob->w, ob->h); |
116 | } | 103 | } |
117 | 104 | ||
118 | /* reassign engine output */ | ||
119 | epd->engine.data.output = re; | 105 | epd->engine.data.output = re; |
120 | if (!epd->engine.data.output) return 0; | 106 | if (!epd->engine.data.output) return 0; |
121 | 107 | ||
122 | /* check for valid engine context */ | ||
123 | if (!epd->engine.data.context) | 108 | if (!epd->engine.data.context) |
124 | { | 109 | { |
125 | /* create a context if needed */ | ||
126 | epd->engine.data.context = | 110 | epd->engine.data.context = |
127 | epd->engine.func->context_new(epd->engine.data.output); | 111 | epd->engine.func->context_new(epd->engine.data.output); |
128 | } | 112 | } |
@@ -135,7 +119,8 @@ eng_output_free(void *data) | |||
135 | { | 119 | { |
136 | Render_Engine *re; | 120 | Render_Engine *re; |
137 | 121 | ||
138 | if ((re = data)) | 122 | re = data; |
123 | if (re) | ||
139 | { | 124 | { |
140 | evas_render_engine_software_generic_clean(&re->generic); | 125 | evas_render_engine_software_generic_clean(&re->generic); |
141 | free(re); | 126 | free(re); |
@@ -144,7 +129,6 @@ eng_output_free(void *data) | |||
144 | evas_common_shutdown(); | 129 | evas_common_shutdown(); |
145 | } | 130 | } |
146 | 131 | ||
147 | /* module api functions */ | ||
148 | static int | 132 | static int |
149 | module_open(Evas_Module *em) | 133 | module_open(Evas_Module *em) |
150 | { | 134 | { |
@@ -165,6 +149,8 @@ module_open(Evas_Module *em) | |||
165 | return 0; | 149 | return 0; |
166 | } | 150 | } |
167 | 151 | ||
152 | ecore_init(); | ||
153 | |||
168 | /* store parent functions */ | 154 | /* store parent functions */ |
169 | func = pfunc; | 155 | func = pfunc; |
170 | 156 | ||
@@ -185,6 +171,8 @@ module_close(Evas_Module *em EINA_UNUSED) | |||
185 | { | 171 | { |
186 | /* unregister the eina log domain for this engine */ | 172 | /* unregister the eina log domain for this engine */ |
187 | eina_log_domain_unregister(_evas_engine_drm_log_dom); | 173 | eina_log_domain_unregister(_evas_engine_drm_log_dom); |
174 | |||
175 | ecore_shutdown(); | ||
188 | } | 176 | } |
189 | 177 | ||
190 | static Evas_Module_Api evas_modapi = | 178 | static Evas_Module_Api evas_modapi = |
diff --git a/src/modules/evas/engines/drm/evas_engine.h b/src/modules/evas/engines/drm/evas_engine.h index d5139117ee..a1925b939e 100644 --- a/src/modules/evas/engines/drm/evas_engine.h +++ b/src/modules/evas/engines/drm/evas_engine.h | |||
@@ -6,8 +6,13 @@ | |||
6 | # include "evas_private.h" | 6 | # include "evas_private.h" |
7 | # include "Evas.h" | 7 | # include "Evas.h" |
8 | # include "Evas_Engine_Drm.h" | 8 | # include "Evas_Engine_Drm.h" |
9 | # include <Ecore.h> | ||
10 | # include <Ecore_Drm2.h> | ||
11 | # include <drm_fourcc.h> | ||
12 | # include <xf86drm.h> | ||
13 | # include <xf86drmMode.h> | ||
9 | 14 | ||
10 | #include "../software_generic/Evas_Engine_Software_Generic.h" | 15 | # include "../software_generic/Evas_Engine_Software_Generic.h" |
11 | 16 | ||
12 | extern int _evas_engine_drm_log_dom; | 17 | extern int _evas_engine_drm_log_dom; |
13 | 18 | ||
@@ -36,35 +41,44 @@ extern int _evas_engine_drm_log_dom; | |||
36 | # endif | 41 | # endif |
37 | # define CRI(...) EINA_LOG_DOM_CRIT(_evas_engine_drm_log_dom, __VA_ARGS__) | 42 | # define CRI(...) EINA_LOG_DOM_CRIT(_evas_engine_drm_log_dom, __VA_ARGS__) |
38 | 43 | ||
39 | struct _Outbuf | 44 | typedef struct _Outbuf_Fb |
40 | { | 45 | { |
41 | Evas_Engine_Info_Drm *info; | 46 | int age; |
47 | Ecore_Drm2_Fb *fb; | ||
48 | |||
49 | Eina_Bool valid : 1; | ||
50 | Eina_Bool drawn : 1; | ||
51 | Eina_Bool busy : 1; | ||
52 | } Outbuf_Fb; | ||
42 | 53 | ||
43 | int w, h; | 54 | struct _Outbuf |
44 | int rotation; | 55 | { |
45 | unsigned int depth; | 56 | int fd, w, h, bpp, rotation; |
57 | unsigned int depth, format; | ||
46 | 58 | ||
47 | struct | 59 | struct |
48 | { | 60 | { |
49 | Ecore_Drm_Fb *buffer[4]; | 61 | int num; |
50 | 62 | Outbuf_Fb ofb[4], *current; | |
51 | Eina_List *pending_writes; | 63 | Ecore_Drm2_Output *output; |
52 | 64 | Eina_List *pending; | |
53 | int curr, last, num; | ||
54 | } priv; | 65 | } priv; |
55 | 66 | ||
56 | Eina_Bool destination_alpha : 1; | 67 | drmEventContext ctx; |
68 | Ecore_Fd_Handler *hdlr; | ||
69 | |||
70 | Eina_Bool alpha : 1; | ||
57 | Eina_Bool vsync : 1; | 71 | Eina_Bool vsync : 1; |
58 | }; | 72 | }; |
59 | 73 | ||
60 | Outbuf *evas_outbuf_setup(Evas_Engine_Info_Drm *info, int w, int h); | 74 | Outbuf *_outbuf_setup(Evas_Engine_Info_Drm *info, int w, int h); |
61 | void evas_outbuf_free(Outbuf *ob); | 75 | void _outbuf_free(Outbuf *ob); |
62 | void evas_outbuf_reconfigure(Outbuf *ob, int w, int h, int rot, Outbuf_Depth depth); | 76 | int _outbuf_rotation_get(Outbuf *ob); |
63 | Render_Engine_Swap_Mode evas_outbuf_buffer_state_get(Outbuf *ob); | 77 | void _outbuf_reconfigure(Outbuf *ob, int w, int h, int rotation, Outbuf_Depth depth); |
64 | int evas_outbuf_rot_get(Outbuf *ob); | 78 | Render_Engine_Swap_Mode _outbuf_state_get(Outbuf *ob); |
65 | void *evas_outbuf_update_region_new(Outbuf *ob, int x, int y, int w, int h, int *cx, int *cy, int *cw, int *ch); | 79 | void *_outbuf_update_region_new(Outbuf *ob, int x, int y, int w, int h, int *cx, int *cy, int *cw, int *ch); |
66 | void evas_outbuf_update_region_push(Outbuf *ob, RGBA_Image *update, int x, int y, int w, int h); | 80 | void _outbuf_update_region_push(Outbuf *ob, RGBA_Image *update, int x, int y, int w, int h); |
67 | void evas_outbuf_update_region_free(Outbuf *ob, RGBA_Image *update); | 81 | void _outbuf_update_region_free(Outbuf *ob, RGBA_Image *update); |
68 | void evas_outbuf_flush(Outbuf *ob, Tilebuf_Rect *rects, Evas_Render_Mode render_mode); | 82 | void _outbuf_flush(Outbuf *ob, Tilebuf_Rect *rects, Evas_Render_Mode render_mode); |
69 | 83 | ||
70 | #endif | 84 | #endif |
diff --git a/src/modules/evas/engines/drm/evas_outbuf.c b/src/modules/evas/engines/drm/evas_outbuf.c index 64b3ba9a52..4c87f2df2f 100644 --- a/src/modules/evas/engines/drm/evas_outbuf.c +++ b/src/modules/evas/engines/drm/evas_outbuf.c | |||
@@ -8,183 +8,430 @@ | |||
8 | #define GREEN_MASK 0x00ff00 | 8 | #define GREEN_MASK 0x00ff00 |
9 | #define BLUE_MASK 0x0000ff | 9 | #define BLUE_MASK 0x0000ff |
10 | 10 | ||
11 | static void | 11 | static void _outbuf_tick_schedule(int fd, void *data); |
12 | _evas_outbuf_buffer_swap(Outbuf *ob, Eina_Rectangle *rects, unsigned int count) | 12 | |
13 | static Eina_Bool ticking = EINA_FALSE; | ||
14 | |||
15 | static void | ||
16 | _outbuf_tick_begin(void *data) | ||
17 | { | ||
18 | Outbuf *ob; | ||
19 | |||
20 | ob = data; | ||
21 | ticking = EINA_TRUE; | ||
22 | if (ob) _outbuf_tick_schedule(ob->fd, ob); | ||
23 | } | ||
24 | |||
25 | static void | ||
26 | _outbuf_tick_end(void *data EINA_UNUSED) | ||
27 | { | ||
28 | ticking = EINA_FALSE; | ||
29 | } | ||
30 | |||
31 | static void | ||
32 | _outbuf_tick_source_set(Outbuf *ob) | ||
33 | { | ||
34 | if (ob) | ||
35 | { | ||
36 | ecore_animator_custom_source_tick_begin_callback_set | ||
37 | (_outbuf_tick_begin, ob); | ||
38 | ecore_animator_custom_source_tick_end_callback_set | ||
39 | (_outbuf_tick_end, ob); | ||
40 | ecore_animator_source_set(ECORE_ANIMATOR_SOURCE_CUSTOM); | ||
41 | } | ||
42 | else | ||
43 | { | ||
44 | ecore_animator_custom_source_tick_begin_callback_set(NULL, NULL); | ||
45 | ecore_animator_custom_source_tick_end_callback_set(NULL, NULL); | ||
46 | ecore_animator_source_set(ECORE_ANIMATOR_SOURCE_TIMER); | ||
47 | } | ||
48 | } | ||
49 | |||
50 | static void | ||
51 | _outbuf_tick_schedule(int fd EINA_UNUSED, void *data) | ||
52 | { | ||
53 | Outbuf *ob; | ||
54 | Outbuf_Fb *ofb; | ||
55 | |||
56 | ob = data; | ||
57 | if (!ticking) return; | ||
58 | |||
59 | ofb = ob->priv.current; | ||
60 | if (!ofb) return; | ||
61 | |||
62 | drmVBlank vbl = | ||
63 | { | ||
64 | .request.type = DRM_VBLANK_RELATIVE | DRM_VBLANK_EVENT, | ||
65 | .request.sequence = 1, | ||
66 | .request.signal = (unsigned long)data, | ||
67 | }; | ||
68 | |||
69 | if (drmWaitVBlank(fd, &vbl) < 0) | ||
70 | _outbuf_tick_source_set(NULL); | ||
71 | } | ||
72 | |||
73 | static void | ||
74 | _cb_vblank(int fd, unsigned int frame EINA_UNUSED, unsigned int sec EINA_UNUSED, unsigned int usec EINA_UNUSED, void *data) | ||
75 | { | ||
76 | ecore_animator_custom_tick(); | ||
77 | if (ticking) _outbuf_tick_schedule(fd, data); | ||
78 | } | ||
79 | |||
80 | static void | ||
81 | _cb_pageflip(int fd EINA_UNUSED, unsigned int frame EINA_UNUSED, unsigned int sec EINA_UNUSED, unsigned int usec EINA_UNUSED, void *data) | ||
13 | { | 82 | { |
14 | Ecore_Drm_Fb *buff; | 83 | Outbuf *ob; |
84 | Outbuf_Fb *ofb; | ||
85 | Ecore_Drm2_Fb *next; | ||
86 | |||
87 | ob = data; | ||
88 | |||
89 | ofb = ob->priv.current; | ||
90 | if (ofb) ofb->busy = EINA_FALSE; | ||
91 | |||
92 | next = ecore_drm2_output_next_fb_get(ob->priv.output); | ||
93 | if (next) | ||
94 | { | ||
95 | ecore_drm2_output_next_fb_set(ob->priv.output, NULL); | ||
96 | if (ecore_drm2_fb_flip(next, ob->priv.output, ob) < 0) | ||
97 | _outbuf_tick_source_set(NULL); | ||
98 | } | ||
99 | } | ||
100 | |||
101 | static Eina_Bool | ||
102 | _cb_drm_event(void *data, Ecore_Fd_Handler *hdlr EINA_UNUSED) | ||
103 | { | ||
104 | Outbuf *ob; | ||
105 | int ret; | ||
106 | |||
107 | ob = data; | ||
108 | ret = drmHandleEvent(ob->fd, &ob->ctx); | ||
109 | if (ret) | ||
110 | { | ||
111 | WRN("drmHandleEvent failed to read an event"); | ||
112 | return EINA_FALSE; | ||
113 | } | ||
114 | |||
115 | return EINA_TRUE; | ||
116 | } | ||
15 | 117 | ||
16 | buff = ob->priv.buffer[ob->priv.curr]; | 118 | static void |
119 | _outbuf_buffer_swap(Outbuf *ob, Eina_Rectangle *rects, unsigned int count) | ||
120 | { | ||
121 | /* Ecore_Drm2_Plane *plane; */ | ||
122 | Outbuf_Fb *ofb; | ||
123 | |||
124 | ofb = ob->priv.current; | ||
125 | if (!ofb) return; | ||
126 | |||
127 | ecore_drm2_fb_dirty(ofb->fb, rects, count); | ||
128 | if (ecore_drm2_fb_flip(ofb->fb, ob->priv.output, ob) < 0) | ||
129 | { | ||
130 | _outbuf_tick_source_set(NULL); | ||
131 | return; | ||
132 | } | ||
133 | |||
134 | ofb->busy = EINA_TRUE; | ||
135 | ofb->drawn = EINA_TRUE; | ||
136 | ofb->age = 0; | ||
137 | |||
138 | /* plane = ecore_drm2_plane_find(ob->priv.output, ofb->fb, ob->format); */ | ||
139 | /* if (plane) */ | ||
140 | /* { */ | ||
141 | /* drmVBlank vbl = */ | ||
142 | /* { */ | ||
143 | /* .request.type = DRM_VBLANK_RELATIVE | DRM_VBLANK_EVENT, */ | ||
144 | /* .request.sequence = 1, */ | ||
145 | /* }; */ | ||
146 | |||
147 | /* vbl.request.type |= ecore_drm2_output_vblank_get(ob->priv.output); */ | ||
148 | /* vbl.request.signal = (unsigned long)ofb; */ | ||
149 | |||
150 | /* ecore_drm2_fb_dirty(ofb->fb, rects, count); */ | ||
151 | |||
152 | /* if (!ecore_drm2_plane_fb_set(plane, ofb->fb)) */ | ||
153 | /* { */ | ||
154 | /* ERR("Failed to set FB on Plane"); */ | ||
155 | /* return; */ | ||
156 | /* } */ | ||
157 | |||
158 | /* if (drmWaitVBlank(ob->fd, &vbl) < 0) */ | ||
159 | /* { */ | ||
160 | /* _outbuf_tick_source_set(NULL); */ | ||
161 | /* return; */ | ||
162 | /* } */ | ||
163 | |||
164 | /* ofb->busy = EINA_TRUE; */ | ||
165 | /* ofb->drawn = EINA_TRUE; */ | ||
166 | /* ofb->age = 0; */ | ||
167 | |||
168 | /* ob->priv.current = NULL; */ | ||
169 | /* } */ | ||
170 | /* else */ | ||
171 | /* WRN("Could not find a plane for this framebuffer"); */ | ||
172 | } | ||
17 | 173 | ||
18 | /* mark the fb as dirty */ | 174 | static Eina_Bool |
19 | ecore_drm_fb_dirty(buff, rects, count); | 175 | _outbuf_fb_create(Outbuf *ob, Outbuf_Fb *ofb) |
176 | { | ||
177 | ofb->fb = | ||
178 | ecore_drm2_fb_create(ob->fd, ob->w, ob->h, | ||
179 | ob->depth, ob->bpp, ob->format); | ||
180 | if (!ofb->fb) return EINA_FALSE; | ||
20 | 181 | ||
21 | /* send this buffer to the crtc */ | 182 | ofb->age = 0; |
22 | ecore_drm_fb_send(ob->info->info.dev, buff, NULL, NULL); | 183 | ofb->busy = EINA_FALSE; |
184 | ofb->drawn = EINA_FALSE; | ||
185 | ofb->valid = EINA_TRUE; | ||
23 | 186 | ||
24 | ob->priv.last = ob->priv.curr; | 187 | return EINA_TRUE; |
25 | ob->priv.curr = (ob->priv.curr + 1) % ob->priv.num; | 188 | } |
189 | |||
190 | static void | ||
191 | _outbuf_fb_destroy(Outbuf_Fb *ofb) | ||
192 | { | ||
193 | ecore_drm2_fb_destroy(ofb->fb); | ||
194 | |||
195 | memset(ofb, 0, sizeof(*ofb)); | ||
196 | ofb->valid = EINA_FALSE; | ||
197 | ofb->busy = EINA_FALSE; | ||
198 | ofb->drawn = EINA_FALSE; | ||
199 | ofb->age = 0; | ||
26 | } | 200 | } |
27 | 201 | ||
28 | Outbuf * | 202 | Outbuf * |
29 | evas_outbuf_setup(Evas_Engine_Info_Drm *info, int w, int h) | 203 | _outbuf_setup(Evas_Engine_Info_Drm *info, int w, int h) |
30 | { | 204 | { |
31 | Outbuf *ob; | 205 | Outbuf *ob; |
32 | char *num; | 206 | char *num; |
33 | int i = 0; | 207 | int i = 0; |
34 | 208 | ||
35 | /* try to allocate space for outbuf */ | 209 | ob = calloc(1, sizeof(Outbuf)); |
36 | if (!(ob = calloc(1, sizeof(Outbuf)))) return NULL; | 210 | if (!ob) return NULL; |
37 | 211 | ||
38 | /* set properties of outbuf */ | ||
39 | ob->w = w; | 212 | ob->w = w; |
40 | ob->h = h; | 213 | ob->h = h; |
214 | ob->fd = info->info.fd; | ||
215 | ob->alpha = info->info.alpha; | ||
216 | ob->rotation = info->info.rotation; | ||
41 | 217 | ||
42 | ob->info = info; | 218 | ob->bpp = info->info.bpp; |
43 | ob->depth = info->info.depth; | 219 | ob->depth = info->info.depth; |
44 | ob->rotation = info->info.rotation; | 220 | ob->format = info->info.format; |
45 | ob->destination_alpha = info->info.destination_alpha; | 221 | |
46 | ob->vsync = info->info.vsync; | 222 | ob->priv.output = info->info.output; |
47 | 223 | ||
48 | /* we must triple-buffer to prevent problems with the page flip handler */ | ||
49 | ob->priv.num = 3; | 224 | ob->priv.num = 3; |
50 | 225 | ||
51 | /* check for buffer override */ | 226 | num = getenv("EVAS_DRM_BUFFERS"); |
52 | if ((num = getenv("EVAS_DRM_BUFFERS"))) | 227 | if (num) |
53 | { | 228 | { |
54 | ob->priv.num = atoi(num); | 229 | ob->priv.num = atoi(num); |
55 | if (ob->priv.num <= 0) ob->priv.num = 1; | 230 | if (ob->priv.num <= 0) ob->priv.num = 3; |
56 | else if (ob->priv.num > 4) ob->priv.num = 4; | 231 | else if (ob->priv.num > 4) ob->priv.num = 4; |
57 | } | 232 | } |
58 | 233 | ||
59 | /* check for vsync override */ | 234 | for (i = 0; i < ob->priv.num; i++) |
60 | if ((num = getenv("EVAS_DRM_VSYNC"))) | ||
61 | ob->vsync = atoi(num); | ||
62 | |||
63 | /* try to create buffers */ | ||
64 | for (; i < ob->priv.num; i++) | ||
65 | { | 235 | { |
66 | ob->priv.buffer[i] = | 236 | if (!_outbuf_fb_create(ob, &(ob->priv.ofb[i]))) |
67 | ecore_drm_fb_create(ob->info->info.dev, ob->w, ob->h); | ||
68 | if (!ob->priv.buffer[i]) | ||
69 | { | 237 | { |
70 | ERR("Failed to create buffer %d", i); | 238 | WRN("Failed to create framebuffer %d", i); |
71 | break; | 239 | continue; |
72 | } | 240 | } |
73 | |||
74 | DBG("Evas Engine Created Dumb Buffer"); | ||
75 | DBG("\tFb: %d", ob->priv.buffer[i]->id); | ||
76 | DBG("\tHandle: %d", ob->priv.buffer[i]->hdl); | ||
77 | DBG("\tStride: %d", ob->priv.buffer[i]->stride); | ||
78 | DBG("\tSize: %d", ob->priv.buffer[i]->size); | ||
79 | DBG("\tW: %d\tH: %d", | ||
80 | ob->priv.buffer[i]->w, ob->priv.buffer[i]->h); | ||
81 | } | 241 | } |
82 | 242 | ||
83 | /* set the front buffer to be the one on the crtc */ | 243 | /* setup vblank handler */ |
84 | ecore_drm_fb_send(info->info.dev, ob->priv.buffer[0], NULL, NULL); | 244 | memset(&ob->ctx, 0, sizeof(ob->ctx)); |
245 | ob->ctx.version = DRM_EVENT_CONTEXT_VERSION; | ||
246 | ob->ctx.vblank_handler = _cb_vblank; | ||
247 | ob->ctx.page_flip_handler = _cb_pageflip; | ||
248 | |||
249 | ob->hdlr = | ||
250 | ecore_main_fd_handler_add(ob->fd, ECORE_FD_READ, _cb_drm_event, ob, | ||
251 | NULL, NULL); | ||
252 | |||
253 | _outbuf_tick_source_set(ob); | ||
85 | 254 | ||
86 | return ob; | 255 | return ob; |
87 | } | 256 | } |
88 | 257 | ||
89 | void | 258 | void |
90 | evas_outbuf_free(Outbuf *ob) | 259 | _outbuf_free(Outbuf *ob) |
91 | { | 260 | { |
92 | int i = 0; | 261 | int i = 0; |
93 | 262 | ||
94 | /* destroy the old buffers */ | 263 | for (i = 0; i < ob->priv.num; i++) |
95 | for (; i < ob->priv.num; i++) | 264 | _outbuf_fb_destroy(&ob->priv.ofb[i]); |
96 | ecore_drm_fb_destroy(ob->priv.buffer[i]); | 265 | |
266 | ecore_main_fd_handler_del(ob->hdlr); | ||
97 | 267 | ||
98 | /* free allocate space for outbuf */ | ||
99 | free(ob); | 268 | free(ob); |
100 | } | 269 | } |
101 | 270 | ||
271 | int | ||
272 | _outbuf_rotation_get(Outbuf *ob) | ||
273 | { | ||
274 | return ob->rotation; | ||
275 | } | ||
276 | |||
102 | void | 277 | void |
103 | evas_outbuf_reconfigure(Outbuf *ob, int w, int h, int rot, Outbuf_Depth depth) | 278 | _outbuf_reconfigure(Outbuf *ob, int w, int h, int rotation, Outbuf_Depth depth) |
104 | { | 279 | { |
105 | int i = 0; | 280 | int i = 0; |
281 | unsigned int format = DRM_FORMAT_ARGB8888; | ||
106 | 282 | ||
107 | /* check if we are inheriting the old buffer depth */ | 283 | switch (depth) |
108 | if (depth == OUTBUF_DEPTH_INHERIT) depth = ob->depth; | 284 | { |
285 | case OUTBUF_DEPTH_RGB_16BPP_565_565_DITHERED: | ||
286 | format = DRM_FORMAT_RGB565; | ||
287 | break; | ||
288 | case OUTBUF_DEPTH_RGB_16BPP_555_555_DITHERED: | ||
289 | format = DRM_FORMAT_RGBX5551; | ||
290 | break; | ||
291 | case OUTBUF_DEPTH_RGB_16BPP_444_444_DITHERED: | ||
292 | format = DRM_FORMAT_RGBX4444; | ||
293 | break; | ||
294 | case OUTBUF_DEPTH_RGB_16BPP_565_444_DITHERED: | ||
295 | format = DRM_FORMAT_RGB565; | ||
296 | break; | ||
297 | case OUTBUF_DEPTH_RGB_32BPP_888_8888: | ||
298 | format = DRM_FORMAT_RGBX8888; | ||
299 | break; | ||
300 | case OUTBUF_DEPTH_ARGB_32BPP_8888_8888: | ||
301 | format = DRM_FORMAT_ARGB8888; | ||
302 | break; | ||
303 | case OUTBUF_DEPTH_BGRA_32BPP_8888_8888: | ||
304 | format = DRM_FORMAT_BGRA8888; | ||
305 | break; | ||
306 | case OUTBUF_DEPTH_BGR_32BPP_888_8888: | ||
307 | format = DRM_FORMAT_BGRX8888; | ||
308 | break; | ||
309 | case OUTBUF_DEPTH_RGB_24BPP_888_888: | ||
310 | format = DRM_FORMAT_RGB888; | ||
311 | break; | ||
312 | case OUTBUF_DEPTH_BGR_24BPP_888_888: | ||
313 | format = DRM_FORMAT_BGR888; | ||
314 | break; | ||
315 | case OUTBUF_DEPTH_INHERIT: | ||
316 | default: | ||
317 | depth = ob->depth; | ||
318 | format = ob->format; | ||
319 | break; | ||
320 | } | ||
109 | 321 | ||
110 | /* check for changes */ | 322 | if ((ob->w == w) && (ob->h == h) && (ob->rotation == rotation) && |
111 | if ((ob->w == w) && (ob->h == h) && | 323 | (ob->depth == depth) && (ob->format == format)) |
112 | (ob->destination_alpha == ob->info->info.destination_alpha) && | ||
113 | (ob->rotation == rot) && | ||
114 | (ob->depth == depth)) | ||
115 | return; | 324 | return; |
116 | 325 | ||
117 | /* set new outbuf properties */ | ||
118 | ob->rotation = rot; | ||
119 | ob->depth = depth; | 326 | ob->depth = depth; |
120 | ob->destination_alpha = ob->info->info.destination_alpha; | 327 | ob->format = format; |
328 | ob->rotation = rotation; | ||
121 | 329 | ||
122 | /* handle rotation */ | 330 | ob->w = w; |
123 | if ((ob->rotation == 0) || (ob->rotation == 180)) | 331 | ob->h = h; |
124 | { | 332 | if ((ob->rotation == 90) || (ob->rotation == 270)) |
125 | ob->w = w; | ||
126 | ob->h = h; | ||
127 | } | ||
128 | else | ||
129 | { | 333 | { |
130 | ob->w = h; | 334 | ob->w = h; |
131 | ob->h = w; | 335 | ob->h = w; |
132 | } | 336 | } |
133 | 337 | ||
134 | /* destroy the old buffers */ | 338 | for (i = 0; i < ob->priv.num; i++) |
135 | for (; i < ob->priv.num; i++) | 339 | _outbuf_fb_destroy(&ob->priv.ofb[i]); |
136 | ecore_drm_fb_destroy(ob->priv.buffer[i]); | ||
137 | 340 | ||
138 | for (i = 0; i < ob->priv.num; i++) | 341 | for (i = 0; i < ob->priv.num; i++) |
139 | { | 342 | { |
140 | ob->priv.buffer[i] = | 343 | if (!_outbuf_fb_create(ob, &(ob->priv.ofb[i]))) |
141 | ecore_drm_fb_create(ob->info->info.dev, ob->w, ob->h); | ||
142 | if (!ob->priv.buffer[i]) | ||
143 | { | 344 | { |
144 | ERR("Failed to create buffer %d", i); | 345 | WRN("Failed to create framebuffer %d", i); |
145 | break; | 346 | continue; |
146 | } | 347 | } |
147 | } | 348 | } |
148 | } | 349 | } |
149 | 350 | ||
150 | Render_Engine_Swap_Mode | 351 | static Outbuf_Fb * |
151 | evas_outbuf_buffer_state_get(Outbuf *ob) | 352 | _outbuf_fb_wait(Outbuf *ob) |
152 | { | 353 | { |
153 | int delta; | 354 | int iter = 0, i = 0; |
154 | 355 | ||
155 | /* check for valid output buffer */ | 356 | while (iter++ < 10) |
156 | if (!ob) return MODE_FULL; | 357 | { |
358 | for (i = 0; i < ob->priv.num; i++) | ||
359 | { | ||
360 | if (ob->priv.ofb[i].busy) continue; | ||
361 | if (ob->priv.ofb[i].valid) return &(ob->priv.ofb[i]); | ||
362 | } | ||
363 | |||
364 | drmHandleEvent(ob->fd, &ob->ctx); | ||
365 | } | ||
366 | |||
367 | return NULL; | ||
368 | } | ||
369 | |||
370 | static Eina_Bool | ||
371 | _outbuf_fb_assign(Outbuf *ob) | ||
372 | { | ||
373 | int i; | ||
157 | 374 | ||
158 | delta = (ob->priv.last - ob->priv.curr + ob->priv.num) % ob->priv.num; | 375 | ob->priv.current = _outbuf_fb_wait(ob); |
159 | 376 | ||
160 | /* This is the number of frame since last frame */ | 377 | if (!ob->priv.current) |
161 | switch (delta) | ||
162 | { | 378 | { |
163 | case 0: | 379 | WRN("No Free Buffers. Dropping a frame"); |
164 | return MODE_COPY; | 380 | for (i = 0; i < ob->priv.num; i++) |
165 | case 1: | 381 | { |
166 | return MODE_DOUBLE; | 382 | if (ob->priv.ofb[i].valid) |
167 | case 2: | 383 | { |
168 | return MODE_TRIPLE; | 384 | ob->priv.ofb[i].age = 0; |
169 | case 3: | 385 | ob->priv.ofb[i].drawn = EINA_FALSE; |
170 | return MODE_QUADRUPLE; | 386 | } |
171 | default: | 387 | } |
172 | return MODE_FULL; | 388 | |
389 | return EINA_FALSE; | ||
173 | } | 390 | } |
391 | |||
392 | for (i = 0; i < ob->priv.num; i++) | ||
393 | { | ||
394 | if ((ob->priv.ofb[i].valid) && (ob->priv.ofb[i].drawn)) | ||
395 | { | ||
396 | ob->priv.ofb[i].age++; | ||
397 | if (ob->priv.ofb[i].age > ob->priv.num) | ||
398 | { | ||
399 | ob->priv.ofb[i].age = 0; | ||
400 | ob->priv.ofb[i].drawn = EINA_FALSE; | ||
401 | } | ||
402 | } | ||
403 | } | ||
404 | |||
405 | return EINA_TRUE; | ||
406 | } | ||
407 | |||
408 | Render_Engine_Swap_Mode | ||
409 | _outbuf_state_get(Outbuf *ob) | ||
410 | { | ||
411 | int age; | ||
412 | |||
413 | if (!_outbuf_fb_assign(ob)) return MODE_FULL; | ||
414 | |||
415 | age = ob->priv.current->age; | ||
416 | if (age > ob->priv.num) return MODE_FULL; | ||
417 | else if (age == 1) return MODE_COPY; | ||
418 | else if (age == 2) return MODE_DOUBLE; | ||
419 | else if (age == 3) return MODE_TRIPLE; | ||
420 | else if (age == 4) return MODE_QUADRUPLE; | ||
421 | |||
422 | return MODE_FULL; | ||
174 | } | 423 | } |
175 | 424 | ||
176 | void * | 425 | void * |
177 | evas_outbuf_update_region_new(Outbuf *ob, int x, int y, int w, int h, int *cx, int *cy, int *cw, int *ch) | 426 | _outbuf_update_region_new(Outbuf *ob, int x, int y, int w, int h, int *cx, int *cy, int *cw, int *ch) |
178 | { | 427 | { |
179 | RGBA_Image *img = NULL; | 428 | RGBA_Image *img = NULL; |
180 | 429 | ||
181 | if ((w <= 0) || (h <= 0)) return NULL; | 430 | if ((w <= 0) || (h <= 0)) return NULL; |
182 | 431 | ||
183 | /* DBG("Outbuf Region New: %d %d %d %d", x, y, w, h); */ | ||
184 | |||
185 | RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, ob->w, ob->h); | 432 | RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, ob->w, ob->h); |
186 | 433 | ||
187 | if ((ob->rotation == 0) && (ob->depth == 32)) | 434 | if ((ob->rotation == 0))// && (ob->depth == 32)) |
188 | { | 435 | { |
189 | Eina_Rectangle *rect; | 436 | Eina_Rectangle *rect; |
190 | 437 | ||
@@ -204,7 +451,7 @@ evas_outbuf_update_region_new(Outbuf *ob, int x, int y, int w, int h, int *cx, i | |||
204 | return NULL; | 451 | return NULL; |
205 | } | 452 | } |
206 | 453 | ||
207 | img->cache_entry.flags.alpha = ob->destination_alpha; | 454 | img->cache_entry.flags.alpha = ob->alpha; |
208 | 455 | ||
209 | #ifdef EVAS_CSERVE2 | 456 | #ifdef EVAS_CSERVE2 |
210 | if (evas_cserve2_use_get()) | 457 | if (evas_cserve2_use_get()) |
@@ -221,48 +468,52 @@ evas_outbuf_update_region_new(Outbuf *ob, int x, int y, int w, int h, int *cx, i | |||
221 | if (ch) *ch = h; | 468 | if (ch) *ch = h; |
222 | 469 | ||
223 | /* add this cached image data to pending writes */ | 470 | /* add this cached image data to pending writes */ |
224 | ob->priv.pending_writes = | 471 | ob->priv.pending = |
225 | eina_list_append(ob->priv.pending_writes, img); | 472 | eina_list_append(ob->priv.pending, img); |
226 | } | 473 | } |
227 | 474 | ||
228 | return img; | 475 | return img; |
229 | } | 476 | } |
230 | 477 | ||
231 | void | 478 | void |
232 | evas_outbuf_update_region_push(Outbuf *ob, RGBA_Image *update, int x, int y, int w, int h) | 479 | _outbuf_update_region_push(Outbuf *ob, RGBA_Image *update, int x, int y, int w, int h) |
233 | { | 480 | { |
234 | Gfx_Func_Convert func = NULL; | 481 | Gfx_Func_Convert func = NULL; |
235 | Eina_Rectangle rect = {0, 0, 0, 0}, pr; | 482 | Eina_Rectangle rect = {0, 0, 0, 0}, pr; |
236 | DATA32 *src; | 483 | DATA32 *src; |
237 | DATA8 *dst; | 484 | DATA8 *dst; |
238 | Ecore_Drm_Fb *buff; | 485 | Ecore_Drm2_Fb *buff; |
239 | int bpp = 0, bpl = 0; | 486 | int bpp = 0, bpl = 0; |
240 | int rx = 0, ry = 0; | 487 | int rx = 0, ry = 0; |
488 | int bw = 0, bh = 0; | ||
241 | 489 | ||
242 | /* check for valid output buffer */ | 490 | /* check for valid output buffer */ |
243 | if (!ob) return; | 491 | if (!ob) return; |
244 | 492 | ||
245 | /* check for pending writes */ | 493 | /* check for pending writes */ |
246 | if (!ob->priv.pending_writes) return; | 494 | if (!ob->priv.pending) return; |
247 | 495 | ||
248 | /* check for valid source data */ | 496 | /* check for valid source data */ |
249 | if (!(src = update->image.data)) return; | 497 | if (!(src = update->image.data)) return; |
250 | 498 | ||
251 | /* check for valid desination data */ | 499 | /* check for valid desination data */ |
252 | buff = ob->priv.buffer[ob->priv.curr]; | 500 | if (!ob->priv.current) return; |
253 | if (!(dst = buff->mmap)) return; | 501 | buff = ob->priv.current->fb; |
502 | |||
503 | dst = ecore_drm2_fb_data_get(buff); | ||
504 | if (!dst) return; | ||
254 | 505 | ||
255 | if ((ob->rotation == 0) || (ob->rotation == 180)) | 506 | if ((ob->rotation == 0) || (ob->rotation == 180)) |
256 | { | 507 | { |
257 | func = | 508 | func = |
258 | evas_common_convert_func_get(0, w, h, ob->depth, | 509 | evas_common_convert_func_get(0, w, h, ob->bpp, |
259 | RED_MASK, GREEN_MASK, BLUE_MASK, | 510 | RED_MASK, GREEN_MASK, BLUE_MASK, |
260 | PAL_MODE_NONE, ob->rotation); | 511 | PAL_MODE_NONE, ob->rotation); |
261 | } | 512 | } |
262 | else if ((ob->rotation == 90) || (ob->rotation == 270)) | 513 | else if ((ob->rotation == 90) || (ob->rotation == 270)) |
263 | { | 514 | { |
264 | func = | 515 | func = |
265 | evas_common_convert_func_get(0, h, w, ob->depth, | 516 | evas_common_convert_func_get(0, h, w, ob->bpp, |
266 | RED_MASK, GREEN_MASK, BLUE_MASK, | 517 | RED_MASK, GREEN_MASK, BLUE_MASK, |
267 | PAL_MODE_NONE, ob->rotation); | 518 | PAL_MODE_NONE, ob->rotation); |
268 | } | 519 | } |
@@ -304,15 +555,18 @@ evas_outbuf_update_region_push(Outbuf *ob, RGBA_Image *update, int x, int y, int | |||
304 | rect.h = w; | 555 | rect.h = w; |
305 | } | 556 | } |
306 | 557 | ||
307 | bpp = (ob->depth / 8); | 558 | bpp = ob->bpp / 8; |
308 | if (bpp <= 0) return; | 559 | bw = ob->w; |
560 | bh = ob->h; | ||
561 | /* bpp = (ob->depth / 8); */ | ||
562 | /* if (bpp <= 0) return; */ | ||
309 | 563 | ||
310 | bpl = buff->stride; | 564 | bpl = ecore_drm2_fb_stride_get(buff); |
311 | 565 | ||
312 | if (ob->rotation == 0) | 566 | if (ob->rotation == 0) |
313 | { | 567 | { |
314 | RECTS_CLIP_TO_RECT(rect.x, rect.y, rect.w, rect.h, | 568 | RECTS_CLIP_TO_RECT(rect.x, rect.y, rect.w, rect.h, |
315 | 0, 0, buff->w, buff->h); | 569 | 0, 0, bw, bh); |
316 | dst += (bpl * rect.y) + (rect.x * bpp); | 570 | dst += (bpl * rect.y) + (rect.x * bpp); |
317 | w -= rx; | 571 | w -= rx; |
318 | } | 572 | } |
@@ -320,7 +574,7 @@ evas_outbuf_update_region_push(Outbuf *ob, RGBA_Image *update, int x, int y, int | |||
320 | { | 574 | { |
321 | pr = rect; | 575 | pr = rect; |
322 | RECTS_CLIP_TO_RECT(rect.x, rect.y, rect.w, rect.h, | 576 | RECTS_CLIP_TO_RECT(rect.x, rect.y, rect.w, rect.h, |
323 | 0, 0, buff->w, buff->h); | 577 | 0, 0, bw, bh); |
324 | rx = pr.w - rect.w; | 578 | rx = pr.w - rect.w; |
325 | ry = pr.h - rect.h; | 579 | ry = pr.h - rect.h; |
326 | src += (update->cache_entry.w * ry) + rx; | 580 | src += (update->cache_entry.w * ry) + rx; |
@@ -330,7 +584,7 @@ evas_outbuf_update_region_push(Outbuf *ob, RGBA_Image *update, int x, int y, int | |||
330 | { | 584 | { |
331 | pr = rect; | 585 | pr = rect; |
332 | RECTS_CLIP_TO_RECT(rect.x, rect.y, rect.w, rect.h, | 586 | RECTS_CLIP_TO_RECT(rect.x, rect.y, rect.w, rect.h, |
333 | 0, 0, buff->w, buff->h); | 587 | 0, 0, bw, bh); |
334 | rx = pr.w - rect.w; ry = pr.h - rect.h; | 588 | rx = pr.w - rect.w; ry = pr.h - rect.h; |
335 | src += ry; | 589 | src += ry; |
336 | w -= ry; | 590 | w -= ry; |
@@ -339,7 +593,7 @@ evas_outbuf_update_region_push(Outbuf *ob, RGBA_Image *update, int x, int y, int | |||
339 | { | 593 | { |
340 | pr = rect; | 594 | pr = rect; |
341 | RECTS_CLIP_TO_RECT(rect.x, rect.y, rect.w, rect.h, | 595 | RECTS_CLIP_TO_RECT(rect.x, rect.y, rect.w, rect.h, |
342 | 0, 0, buff->w, buff->h); | 596 | 0, 0, bw, bh); |
343 | rx = pr.w - rect.w; ry = pr.h - rect.h; | 597 | rx = pr.w - rect.w; ry = pr.h - rect.h; |
344 | src += (update->cache_entry.w * rx); | 598 | src += (update->cache_entry.w * rx); |
345 | w -= ry; | 599 | w -= ry; |
@@ -352,13 +606,13 @@ evas_outbuf_update_region_push(Outbuf *ob, RGBA_Image *update, int x, int y, int | |||
352 | } | 606 | } |
353 | 607 | ||
354 | void | 608 | void |
355 | evas_outbuf_update_region_free(Outbuf *ob EINA_UNUSED, RGBA_Image *update EINA_UNUSED) | 609 | _outbuf_update_region_free(Outbuf *ob EINA_UNUSED, RGBA_Image *update EINA_UNUSED) |
356 | { | 610 | { |
357 | /* evas_cache_image_drop(&update->cache_entry); */ | 611 | |
358 | } | 612 | } |
359 | 613 | ||
360 | void | 614 | void |
361 | evas_outbuf_flush(Outbuf *ob, Tilebuf_Rect *rects EINA_UNUSED, Evas_Render_Mode render_mode) | 615 | _outbuf_flush(Outbuf *ob, Tilebuf_Rect *rects EINA_UNUSED, Evas_Render_Mode render_mode) |
362 | { | 616 | { |
363 | Eina_Rectangle *r; | 617 | Eina_Rectangle *r; |
364 | RGBA_Image *img; | 618 | RGBA_Image *img; |
@@ -367,19 +621,21 @@ evas_outbuf_flush(Outbuf *ob, Tilebuf_Rect *rects EINA_UNUSED, Evas_Render_Mode | |||
367 | if (render_mode == EVAS_RENDER_MODE_ASYNC_INIT) return; | 621 | if (render_mode == EVAS_RENDER_MODE_ASYNC_INIT) return; |
368 | 622 | ||
369 | /* get number of pending writes */ | 623 | /* get number of pending writes */ |
370 | n = eina_list_count(ob->priv.pending_writes); | 624 | n = eina_list_count(ob->priv.pending); |
371 | if (n == 0) return; | 625 | if (n == 0) return; |
372 | 626 | ||
373 | /* allocate rectangles */ | 627 | /* allocate rectangles */ |
374 | if (!(r = alloca(n * sizeof(Eina_Rectangle)))) return; | 628 | r = alloca(n * sizeof(Eina_Rectangle)); |
629 | if (!r) return; | ||
375 | 630 | ||
376 | /* loop the pending writes */ | 631 | /* loop the pending writes */ |
377 | EINA_LIST_FREE(ob->priv.pending_writes, img) | 632 | EINA_LIST_FREE(ob->priv.pending, img) |
378 | { | 633 | { |
379 | Eina_Rectangle *rect; | 634 | Eina_Rectangle *rect; |
380 | int x = 0, y = 0, w = 0, h = 0; | 635 | int x = 0, y = 0, w = 0, h = 0; |
381 | 636 | ||
382 | if (!(rect = img->extended_info)) continue; | 637 | rect = img->extended_info; |
638 | if (!rect) continue; | ||
383 | 639 | ||
384 | x = rect->x; y = rect->y; w = rect->w; h = rect->h; | 640 | x = rect->x; y = rect->y; w = rect->w; h = rect->h; |
385 | 641 | ||
@@ -430,11 +686,5 @@ evas_outbuf_flush(Outbuf *ob, Tilebuf_Rect *rects EINA_UNUSED, Evas_Render_Mode | |||
430 | } | 686 | } |
431 | 687 | ||
432 | /* force a buffer swap */ | 688 | /* force a buffer swap */ |
433 | _evas_outbuf_buffer_swap(ob, r, n); | 689 | _outbuf_buffer_swap(ob, r, n); |
434 | } | ||
435 | |||
436 | int | ||
437 | evas_outbuf_rot_get(Outbuf *ob) | ||
438 | { | ||
439 | return ob->rotation; | ||
440 | } | 690 | } |
diff --git a/src/modules/evas/engines/gl_drm/Evas_Engine_GL_Drm.h b/src/modules/evas/engines/gl_drm/Evas_Engine_GL_Drm.h index 71ab60cefc..514aa80c09 100644 --- a/src/modules/evas/engines/gl_drm/Evas_Engine_GL_Drm.h +++ b/src/modules/evas/engines/gl_drm/Evas_Engine_GL_Drm.h | |||
@@ -1,7 +1,7 @@ | |||
1 | #ifndef _EVAS_ENGINE_GL_DRM_H | 1 | #ifndef _EVAS_ENGINE_GL_DRM_H |
2 | # define _EVAS_ENGINE_GL_DRM_H | 2 | # define _EVAS_ENGINE_GL_DRM_H |
3 | 3 | ||
4 | # include <Ecore_Drm.h> | 4 | # include <Ecore_Drm2.h> |
5 | # include <gbm.h> | 5 | # include <gbm.h> |
6 | 6 | ||
7 | typedef enum _Evas_Engine_Info_GL_Drm_Swap_Mode | 7 | typedef enum _Evas_Engine_Info_GL_Drm_Swap_Mode |
@@ -26,11 +26,11 @@ struct _Evas_Engine_Info_GL_Drm | |||
26 | { | 26 | { |
27 | struct gbm_device *gbm; | 27 | struct gbm_device *gbm; |
28 | 28 | ||
29 | int fd, bpp; | ||
29 | unsigned int rotation, depth; | 30 | unsigned int rotation, depth; |
30 | unsigned int crtc_id, conn_id, buffer_id; | ||
31 | unsigned int format, flags; | 31 | unsigned int format, flags; |
32 | 32 | ||
33 | Ecore_Drm_Device *dev; | 33 | void *output; |
34 | 34 | ||
35 | Eina_Bool destination_alpha : 1; | 35 | Eina_Bool destination_alpha : 1; |
36 | Eina_Bool vsync : 1; | 36 | Eina_Bool vsync : 1; |
diff --git a/src/modules/evas/engines/gl_drm/evas_engine.c b/src/modules/evas/engines/gl_drm/evas_engine.c index d8d4312aee..29f2e0c533 100644 --- a/src/modules/evas/engines/gl_drm/evas_engine.c +++ b/src/modules/evas/engines/gl_drm/evas_engine.c | |||
@@ -118,12 +118,9 @@ static const EVGL_Interface evgl_funcs = | |||
118 | Eina_Bool | 118 | Eina_Bool |
119 | eng_gbm_init(Evas_Engine_Info_GL_Drm *info) | 119 | eng_gbm_init(Evas_Engine_Info_GL_Drm *info) |
120 | { | 120 | { |
121 | Ecore_Drm_Device *dev; | ||
122 | |||
123 | if (!info) return EINA_FALSE; | 121 | if (!info) return EINA_FALSE; |
124 | if (!(dev = info->info.dev)) return EINA_FALSE; | ||
125 | 122 | ||
126 | if (!(info->info.gbm = gbm_create_device(dev->drm.fd))) | 123 | if (!(info->info.gbm = gbm_create_device(info->info.fd))) |
127 | { | 124 | { |
128 | ERR("Coult not create gbm device"); | 125 | ERR("Coult not create gbm device"); |
129 | return EINA_FALSE; | 126 | return EINA_FALSE; |
@@ -146,13 +143,6 @@ eng_gbm_shutdown(Evas_Engine_Info_GL_Drm *info) | |||
146 | return EINA_TRUE; | 143 | return EINA_TRUE; |
147 | } | 144 | } |
148 | 145 | ||
149 | /* local inline functions */ | ||
150 | static inline Outbuf * | ||
151 | eng_get_ob(Render_Engine *re) | ||
152 | { | ||
153 | return re->generic.software.ob; | ||
154 | } | ||
155 | |||
156 | /* local functions */ | 146 | /* local functions */ |
157 | static void | 147 | static void |
158 | gl_symbols(void) | 148 | gl_symbols(void) |
@@ -362,6 +352,8 @@ evgl_eng_native_window_create(void *data) | |||
362 | Render_Engine *re; | 352 | Render_Engine *re; |
363 | struct gbm_surface *surface; | 353 | struct gbm_surface *surface; |
364 | Evas_Engine_Info_GL_Drm *info; | 354 | Evas_Engine_Info_GL_Drm *info; |
355 | unsigned int format = GBM_FORMAT_XRGB8888; | ||
356 | unsigned int flags = GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING; | ||
365 | 357 | ||
366 | re = (Render_Engine *)data; | 358 | re = (Render_Engine *)data; |
367 | if (!re) | 359 | if (!re) |
@@ -377,9 +369,9 @@ evgl_eng_native_window_create(void *data) | |||
377 | return NULL; | 369 | return NULL; |
378 | } | 370 | } |
379 | 371 | ||
380 | surface = gbm_surface_create(info->info.gbm, | 372 | surface = |
381 | eng_get_ob(re)->w, eng_get_ob(re)->h, | 373 | gbm_surface_create(info->info.gbm, |
382 | info->info.format, info->info.flags); | 374 | eng_get_ob(re)->w, eng_get_ob(re)->h, format, flags); |
383 | if (!surface) | 375 | if (!surface) |
384 | { | 376 | { |
385 | ERR("Could not create gl drm window"); | 377 | ERR("Could not create gl drm window"); |
@@ -786,6 +778,37 @@ _native_cb_free(void *image) | |||
786 | free(n); | 778 | free(n); |
787 | } | 779 | } |
788 | 780 | ||
781 | static void | ||
782 | _cb_vblank(int fd, unsigned int frame EINA_UNUSED, unsigned int sec EINA_UNUSED, unsigned int usec EINA_UNUSED, void *data) | ||
783 | { | ||
784 | evas_outbuf_vblank(data, fd); | ||
785 | } | ||
786 | |||
787 | static void | ||
788 | _cb_page_flip(int fd, unsigned int frame EINA_UNUSED, unsigned int sec EINA_UNUSED, unsigned int usec EINA_UNUSED, void *data) | ||
789 | { | ||
790 | evas_outbuf_page_flip(data, fd); | ||
791 | } | ||
792 | |||
793 | static Eina_Bool | ||
794 | _cb_drm_event(void *data, Ecore_Fd_Handler *hdlr EINA_UNUSED) | ||
795 | { | ||
796 | Render_Engine *re; | ||
797 | int ret; | ||
798 | |||
799 | re = data; | ||
800 | if (!re) return EINA_TRUE; | ||
801 | |||
802 | ret = drmHandleEvent(re->fd, &re->ctx); | ||
803 | if (ret) | ||
804 | { | ||
805 | ERR("drmHandleEvent failed to read an event: %m"); | ||
806 | return EINA_FALSE; | ||
807 | } | ||
808 | |||
809 | return EINA_TRUE; | ||
810 | } | ||
811 | |||
789 | /* engine specific override functions */ | 812 | /* engine specific override functions */ |
790 | static void * | 813 | static void * |
791 | eng_info(Evas *eo_e EINA_UNUSED) | 814 | eng_info(Evas *eo_e EINA_UNUSED) |
@@ -899,6 +922,17 @@ eng_setup(Evas *evas, void *in) | |||
899 | return 0; | 922 | return 0; |
900 | } | 923 | } |
901 | 924 | ||
925 | re->fd = info->info.fd; | ||
926 | |||
927 | memset(&re->ctx, 0, sizeof(re->ctx)); | ||
928 | re->ctx.version = DRM_EVENT_CONTEXT_VERSION; | ||
929 | re->ctx.vblank_handler = _cb_vblank; | ||
930 | re->ctx.page_flip_handler = _cb_page_flip; | ||
931 | |||
932 | re->hdlr = | ||
933 | ecore_main_fd_handler_add(info->info.fd, ECORE_FD_READ, | ||
934 | _cb_drm_event, re, NULL, NULL); | ||
935 | |||
902 | /* try to create new outbuf */ | 936 | /* try to create new outbuf */ |
903 | ob = evas_outbuf_new(info, epd->output.w, epd->output.h, swap_mode); | 937 | ob = evas_outbuf_new(info, epd->output.w, epd->output.h, swap_mode); |
904 | if (!ob) | 938 | if (!ob) |
@@ -970,16 +1004,16 @@ eng_setup(Evas *evas, void *in) | |||
970 | re->generic.software.ob = NULL; | 1004 | re->generic.software.ob = NULL; |
971 | gl_wins--; | 1005 | gl_wins--; |
972 | 1006 | ||
1007 | if (ob_old) evas_outbuf_free(ob_old); | ||
1008 | |||
973 | ob = evas_outbuf_new(info, epd->output.w, epd->output.h, swap_mode); | 1009 | ob = evas_outbuf_new(info, epd->output.w, epd->output.h, swap_mode); |
974 | if (!ob) | 1010 | if (!ob) |
975 | { | 1011 | { |
976 | if (ob_old) evas_outbuf_free(ob_old); | ||
977 | free(re); | 1012 | free(re); |
978 | return 0; | 1013 | return 0; |
979 | } | 1014 | } |
980 | 1015 | ||
981 | evas_outbuf_use(ob); | 1016 | evas_outbuf_use(ob); |
982 | if (ob_old) evas_outbuf_free(ob_old); | ||
983 | 1017 | ||
984 | ob->evas = evas; | 1018 | ob->evas = evas; |
985 | 1019 | ||
@@ -1439,6 +1473,8 @@ module_open(Evas_Module *em) | |||
1439 | return 0; | 1473 | return 0; |
1440 | } | 1474 | } |
1441 | 1475 | ||
1476 | ecore_init(); | ||
1477 | |||
1442 | /* store it for later use */ | 1478 | /* store it for later use */ |
1443 | func = pfunc; | 1479 | func = pfunc; |
1444 | 1480 | ||
@@ -1471,6 +1507,8 @@ module_close(Evas_Module *em EINA_UNUSED) | |||
1471 | /* unregister the eina log domain for this engine */ | 1507 | /* unregister the eina log domain for this engine */ |
1472 | eina_log_domain_unregister(_evas_engine_gl_drm_log_dom); | 1508 | eina_log_domain_unregister(_evas_engine_gl_drm_log_dom); |
1473 | _evas_engine_gl_drm_log_dom = -1; | 1509 | _evas_engine_gl_drm_log_dom = -1; |
1510 | |||
1511 | ecore_shutdown(); | ||
1474 | } | 1512 | } |
1475 | 1513 | ||
1476 | static Evas_Module_Api evas_modapi = | 1514 | static Evas_Module_Api evas_modapi = |
diff --git a/src/modules/evas/engines/gl_drm/evas_engine.h b/src/modules/evas/engines/gl_drm/evas_engine.h index f45a1995e6..8a51d59c93 100644 --- a/src/modules/evas/engines/gl_drm/evas_engine.h +++ b/src/modules/evas/engines/gl_drm/evas_engine.h | |||
@@ -7,6 +7,11 @@ | |||
7 | # include "Evas.h" | 7 | # include "Evas.h" |
8 | # include "Evas_Engine_GL_Drm.h" | 8 | # include "Evas_Engine_GL_Drm.h" |
9 | 9 | ||
10 | # include <Ecore.h> | ||
11 | # include <drm_fourcc.h> | ||
12 | # include <xf86drm.h> | ||
13 | # include <xf86drmMode.h> | ||
14 | |||
10 | # define EGL_EGLEXT_PROTOTYPES | 15 | # define EGL_EGLEXT_PROTOTYPES |
11 | # define GL_GLEXT_PROTOTYPES | 16 | # define GL_GLEXT_PROTOTYPES |
12 | 17 | ||
@@ -64,6 +69,10 @@ typedef struct _Render_Engine Render_Engine; | |||
64 | struct _Render_Engine | 69 | struct _Render_Engine |
65 | { | 70 | { |
66 | Render_Engine_GL_Generic generic; | 71 | Render_Engine_GL_Generic generic; |
72 | |||
73 | int fd; | ||
74 | drmEventContext ctx; | ||
75 | Ecore_Fd_Handler *hdlr; | ||
67 | }; | 76 | }; |
68 | 77 | ||
69 | struct _Context_3D | 78 | struct _Context_3D |
@@ -80,11 +89,10 @@ struct _Outbuf | |||
80 | 89 | ||
81 | Evas *evas; // used for pre_swap, post_swap | 90 | Evas *evas; // used for pre_swap, post_swap |
82 | 91 | ||
83 | int w, h; | 92 | int fd, w, h, bpp; |
84 | unsigned int rotation, depth; | 93 | unsigned int rotation, depth, format; |
85 | Render_Engine_Swap_Mode swap_mode; | 94 | Render_Engine_Swap_Mode swap_mode; |
86 | 95 | ||
87 | /* struct gbm_device *gbm; */ | ||
88 | struct gbm_surface *surface; | 96 | struct gbm_surface *surface; |
89 | 97 | ||
90 | struct | 98 | struct |
@@ -98,6 +106,7 @@ struct _Outbuf | |||
98 | struct | 106 | struct |
99 | { | 107 | { |
100 | struct gbm_bo *bo[2]; | 108 | struct gbm_bo *bo[2]; |
109 | Ecore_Drm2_Output *output; | ||
101 | } priv; | 110 | } priv; |
102 | 111 | ||
103 | Eina_Bool destination_alpha : 1; | 112 | Eina_Bool destination_alpha : 1; |
@@ -123,6 +132,9 @@ void *evas_outbuf_update_region_new(Outbuf *ob, int x, int y, int w, int h, int | |||
123 | void evas_outbuf_update_region_push(Outbuf *ob, RGBA_Image *update, int x, int y, int w, int h); | 132 | void evas_outbuf_update_region_push(Outbuf *ob, RGBA_Image *update, int x, int y, int w, int h); |
124 | void evas_outbuf_update_region_free(Outbuf *ob, RGBA_Image *update); | 133 | void evas_outbuf_update_region_free(Outbuf *ob, RGBA_Image *update); |
125 | void evas_outbuf_flush(Outbuf *ob, Tilebuf_Rect *rects, Evas_Render_Mode render_mode); | 134 | void evas_outbuf_flush(Outbuf *ob, Tilebuf_Rect *rects, Evas_Render_Mode render_mode); |
135 | void evas_outbuf_vblank(void *data, int fd); | ||
136 | void evas_outbuf_page_flip(void *data, int fd); | ||
137 | |||
126 | Evas_Engine_GL_Context* evas_outbuf_gl_context_get(Outbuf *ob); | 138 | Evas_Engine_GL_Context* evas_outbuf_gl_context_get(Outbuf *ob); |
127 | void *evas_outbuf_egl_display_get(Outbuf *ob); | 139 | void *evas_outbuf_egl_display_get(Outbuf *ob); |
128 | Context_3D *evas_outbuf_gl_context_new(Outbuf *ob); | 140 | Context_3D *evas_outbuf_gl_context_new(Outbuf *ob); |
@@ -138,6 +150,12 @@ _re_wincheck(Outbuf *ob) | |||
138 | return EINA_FALSE; | 150 | return EINA_FALSE; |
139 | } | 151 | } |
140 | 152 | ||
153 | static inline Outbuf * | ||
154 | eng_get_ob(Render_Engine *re) | ||
155 | { | ||
156 | return re->generic.software.ob; | ||
157 | } | ||
158 | |||
141 | extern unsigned int (*glsym_eglSwapBuffersWithDamage)(EGLDisplay a, void *b, const EGLint *d, EGLint c); | 159 | extern unsigned int (*glsym_eglSwapBuffersWithDamage)(EGLDisplay a, void *b, const EGLint *d, EGLint c); |
142 | extern unsigned int (*glsym_eglSetDamageRegionKHR)(EGLDisplay a, EGLSurface b, EGLint *c, EGLint d); | 160 | extern unsigned int (*glsym_eglSetDamageRegionKHR)(EGLDisplay a, EGLSurface b, EGLint *c, EGLint d); |
143 | 161 | ||
diff --git a/src/modules/evas/engines/gl_drm/evas_outbuf.c b/src/modules/evas/engines/gl_drm/evas_outbuf.c index b120216608..ad3f2a0414 100644 --- a/src/modules/evas/engines/gl_drm/evas_outbuf.c +++ b/src/modules/evas/engines/gl_drm/evas_outbuf.c | |||
@@ -5,6 +5,7 @@ | |||
5 | static Outbuf *_evas_gl_drm_window = NULL; | 5 | static Outbuf *_evas_gl_drm_window = NULL; |
6 | static EGLContext context = EGL_NO_CONTEXT; | 6 | static EGLContext context = EGL_NO_CONTEXT; |
7 | static int win_count = 0; | 7 | static int win_count = 0; |
8 | static Eina_Bool ticking = EINA_FALSE; | ||
8 | 9 | ||
9 | #ifdef EGL_MESA_platform_gbm | 10 | #ifdef EGL_MESA_platform_gbm |
10 | static PFNEGLGETPLATFORMDISPLAYEXTPROC dlsym_eglGetPlatformDisplayEXT = NULL; | 11 | static PFNEGLGETPLATFORMDISPLAYEXTPROC dlsym_eglGetPlatformDisplayEXT = NULL; |
@@ -12,6 +13,79 @@ static PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC dlsym_eglCreatePlatformWindowSur | |||
12 | #endif | 13 | #endif |
13 | 14 | ||
14 | static void | 15 | static void |
16 | _outbuf_tick_schedule(int fd, void *data) | ||
17 | { | ||
18 | if (!ticking) return; | ||
19 | |||
20 | drmVBlank vbl = | ||
21 | { | ||
22 | .request.type = DRM_VBLANK_RELATIVE | DRM_VBLANK_EVENT, | ||
23 | .request.sequence = 1, | ||
24 | .request.signal = (unsigned long)data, | ||
25 | }; | ||
26 | |||
27 | drmWaitVBlank(fd, &vbl); | ||
28 | } | ||
29 | |||
30 | static void | ||
31 | _outbuf_tick_begin(void *data) | ||
32 | { | ||
33 | Outbuf *ob; | ||
34 | |||
35 | ob = data; | ||
36 | ticking = EINA_TRUE; | ||
37 | if (ob) _outbuf_tick_schedule(ob->fd, ob); | ||
38 | } | ||
39 | |||
40 | static void | ||
41 | _outbuf_tick_end(void *data EINA_UNUSED) | ||
42 | { | ||
43 | ticking = EINA_FALSE; | ||
44 | } | ||
45 | |||
46 | static void | ||
47 | _outbuf_tick_source_set(Outbuf *ob) | ||
48 | { | ||
49 | if (ob) | ||
50 | { | ||
51 | ecore_animator_custom_source_tick_begin_callback_set | ||
52 | (_outbuf_tick_begin, ob); | ||
53 | ecore_animator_custom_source_tick_end_callback_set | ||
54 | (_outbuf_tick_end, ob); | ||
55 | ecore_animator_source_set(ECORE_ANIMATOR_SOURCE_CUSTOM); | ||
56 | } | ||
57 | else | ||
58 | { | ||
59 | ecore_animator_custom_source_tick_begin_callback_set(NULL, NULL); | ||
60 | ecore_animator_custom_source_tick_end_callback_set(NULL, NULL); | ||
61 | ecore_animator_source_set(ECORE_ANIMATOR_SOURCE_TIMER); | ||
62 | } | ||
63 | } | ||
64 | |||
65 | void | ||
66 | evas_outbuf_vblank(void *data, int fd) | ||
67 | { | ||
68 | ecore_animator_custom_tick(); | ||
69 | if (ticking) _outbuf_tick_schedule(fd, data); | ||
70 | } | ||
71 | |||
72 | void | ||
73 | evas_outbuf_page_flip(void *data, int fd EINA_UNUSED) | ||
74 | { | ||
75 | Outbuf *ob; | ||
76 | Ecore_Drm2_Fb *next; | ||
77 | |||
78 | ob = data; | ||
79 | next = ecore_drm2_output_next_fb_get(ob->priv.output); | ||
80 | if (next) | ||
81 | { | ||
82 | ecore_drm2_output_next_fb_set(ob->priv.output, NULL); | ||
83 | if (ecore_drm2_fb_flip(next, ob->priv.output, ob) < 0) | ||
84 | _outbuf_tick_source_set(NULL); | ||
85 | } | ||
86 | } | ||
87 | |||
88 | static void | ||
15 | _evas_outbuf_gbm_surface_destroy(Outbuf *ob) | 89 | _evas_outbuf_gbm_surface_destroy(Outbuf *ob) |
16 | { | 90 | { |
17 | if (!ob) return; | 91 | if (!ob) return; |
@@ -25,63 +99,51 @@ _evas_outbuf_gbm_surface_destroy(Outbuf *ob) | |||
25 | static void | 99 | static void |
26 | _evas_outbuf_gbm_surface_create(Outbuf *ob, int w, int h) | 100 | _evas_outbuf_gbm_surface_create(Outbuf *ob, int w, int h) |
27 | { | 101 | { |
102 | unsigned int format = GBM_FORMAT_XRGB8888; | ||
103 | unsigned int flags = GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING; | ||
104 | |||
28 | if (!ob) return; | 105 | if (!ob) return; |
29 | 106 | ||
30 | ob->surface = | 107 | ob->surface = |
31 | gbm_surface_create(ob->info->info.gbm, w, h, | 108 | gbm_surface_create(ob->info->info.gbm, w, h, format, flags); |
32 | ob->info->info.format, ob->info->info.flags); | ||
33 | 109 | ||
34 | if (!ob->surface) ERR("Failed to create gbm surface"); | 110 | if (!ob->surface) ERR("Failed to create gbm surface"); |
35 | } | 111 | } |
36 | 112 | ||
37 | static void | 113 | static void |
38 | _evas_outbuf_fb_cb_destroy(struct gbm_bo *bo, void *data) | 114 | _evas_outbuf_fb_cb_destroy(struct gbm_bo *bo EINA_UNUSED, void *data) |
39 | { | 115 | { |
40 | Ecore_Drm_Fb *fb; | 116 | Ecore_Drm2_Fb *fb; |
41 | 117 | ||
42 | fb = data; | 118 | fb = data; |
43 | if (fb) | 119 | if (fb) ecore_drm2_fb_destroy(fb); |
44 | { | ||
45 | struct gbm_device *gbm; | ||
46 | |||
47 | gbm = gbm_bo_get_device(bo); | ||
48 | drmModeRmFB(gbm_device_get_fd(gbm), fb->id); | ||
49 | free(fb); | ||
50 | } | ||
51 | } | 120 | } |
52 | 121 | ||
53 | static Ecore_Drm_Fb * | 122 | static Ecore_Drm2_Fb * |
54 | _evas_outbuf_fb_get(Ecore_Drm_Device *dev, struct gbm_bo *bo) | 123 | _evas_outbuf_fb_get(Outbuf *ob, struct gbm_bo *bo) |
55 | { | 124 | { |
56 | int ret; | 125 | Ecore_Drm2_Fb *fb; |
57 | Ecore_Drm_Fb *fb; | 126 | uint32_t format, hdl, stride; |
58 | uint32_t format; | 127 | int w, h; |
59 | uint32_t handles[4], pitches[4], offsets[4]; | ||
60 | 128 | ||
61 | fb = gbm_bo_get_user_data(bo); | 129 | fb = gbm_bo_get_user_data(bo); |
62 | if (fb) return fb; | 130 | if (fb) return fb; |
63 | 131 | ||
64 | if (!(fb = calloc(1, sizeof(Ecore_Drm_Fb)))) return NULL; | ||
65 | |||
66 | format = gbm_bo_get_format(bo); | 132 | format = gbm_bo_get_format(bo); |
67 | 133 | w = gbm_bo_get_width(bo); | |
68 | fb->w = gbm_bo_get_width(bo); | 134 | h = gbm_bo_get_height(bo); |
69 | fb->h = gbm_bo_get_height(bo); | 135 | hdl = gbm_bo_get_handle(bo).u32; |
70 | fb->hdl = gbm_bo_get_handle(bo).u32; | 136 | stride = gbm_bo_get_stride(bo); |
71 | fb->stride = gbm_bo_get_stride(bo); | 137 | /* fb->size = fb->stride * fb->h; */ |
72 | fb->size = fb->stride * fb->h; | 138 | |
73 | 139 | fb = | |
74 | handles[0] = fb->hdl; | 140 | ecore_drm2_fb_gbm_create(ob->fd, w, h, ob->depth, ob->bpp, |
75 | pitches[0] = fb->stride; | 141 | format, hdl, stride); |
76 | offsets[0] = 0; | 142 | if (!fb) |
77 | 143 | { | |
78 | ret = drmModeAddFB2(dev->drm.fd, fb->w, fb->h, format, | 144 | ERR("Failed to create FBO"); |
79 | handles, pitches, offsets, &(fb->id), 0); | 145 | return NULL; |
80 | if (ret) | 146 | } |
81 | ret = drmModeAddFB(dev->drm.fd, fb->w, fb->h, 24, 32, | ||
82 | fb->stride, fb->hdl, &(fb->id)); | ||
83 | |||
84 | if (ret) ERR("FAILED TO ADD FB: %m"); | ||
85 | 147 | ||
86 | gbm_bo_set_user_data(bo, fb, _evas_outbuf_fb_cb_destroy); | 148 | gbm_bo_set_user_data(bo, fb, _evas_outbuf_fb_cb_destroy); |
87 | 149 | ||
@@ -91,7 +153,9 @@ _evas_outbuf_fb_get(Ecore_Drm_Device *dev, struct gbm_bo *bo) | |||
91 | static void | 153 | static void |
92 | _evas_outbuf_buffer_swap(Outbuf *ob, Eina_Rectangle *rects, unsigned int count) | 154 | _evas_outbuf_buffer_swap(Outbuf *ob, Eina_Rectangle *rects, unsigned int count) |
93 | { | 155 | { |
94 | Ecore_Drm_Fb *fb; | 156 | Ecore_Drm2_Fb *fb; |
157 | |||
158 | if (ob->priv.bo[1]) gbm_surface_release_buffer(ob->surface, ob->priv.bo[1]); | ||
95 | 159 | ||
96 | /* Repulsive hack: Right now we don't actually have a proper way to retire | 160 | /* Repulsive hack: Right now we don't actually have a proper way to retire |
97 | * buffers because the ticker and the flip handler are out of sync, the | 161 | * buffers because the ticker and the flip handler are out of sync, the |
@@ -106,15 +170,48 @@ _evas_outbuf_buffer_swap(Outbuf *ob, Eina_Rectangle *rects, unsigned int count) | |||
106 | ob->priv.bo[0] = gbm_surface_lock_front_buffer(ob->surface); | 170 | ob->priv.bo[0] = gbm_surface_lock_front_buffer(ob->surface); |
107 | if (!ob->priv.bo[0]) | 171 | if (!ob->priv.bo[0]) |
108 | { | 172 | { |
109 | WRN("Could not lock front buffer"); | 173 | WRN("Could not lock front buffer: %m"); |
110 | return; | 174 | return; |
111 | } | 175 | } |
112 | fb = _evas_outbuf_fb_get(ob->info->info.dev, ob->priv.bo[0]); | 176 | |
177 | fb = _evas_outbuf_fb_get(ob, ob->priv.bo[0]); | ||
113 | if (fb) | 178 | if (fb) |
114 | { | 179 | { |
115 | ecore_drm_fb_dirty(fb, rects, count); | 180 | ecore_drm2_fb_dirty(fb, rects, count); |
116 | ecore_drm_fb_send(ob->info->info.dev, fb, NULL, NULL); | 181 | if (ecore_drm2_fb_flip(fb, ob->priv.output, ob) < 0) |
182 | _outbuf_tick_source_set(NULL); | ||
183 | |||
184 | /* Ecore_Drm2_Plane *plane; */ | ||
185 | |||
186 | /* plane = ecore_drm2_plane_find(ob->priv.output, fb, ob->format); */ | ||
187 | /* if (plane) */ | ||
188 | /* { */ | ||
189 | /* int ret; */ | ||
190 | /* drmVBlank vbl = */ | ||
191 | /* { */ | ||
192 | /* .request.type = DRM_VBLANK_RELATIVE | DRM_VBLANK_EVENT, */ | ||
193 | /* .request.sequence = 1, */ | ||
194 | /* }; */ | ||
195 | |||
196 | /* vbl.request.type |= ecore_drm2_output_vblank_get(ob->priv.output); */ | ||
197 | /* vbl.request.signal = (unsigned long)ob; */ | ||
198 | |||
199 | /* ecore_drm2_fb_dirty(fb, rects, count); */ | ||
200 | |||
201 | /* if (!ecore_drm2_plane_fb_set(plane, fb)) */ | ||
202 | /* { */ | ||
203 | /* ERR("Failed to set FB on Plane"); */ | ||
204 | /* return; */ | ||
205 | /* } */ | ||
206 | |||
207 | /* ret = drmWaitVBlank(ob->fd, &vbl); */ | ||
208 | /* if (ret) return; */ | ||
209 | /* } */ | ||
210 | /* else */ | ||
211 | /* WRN("NO PLANE FOUND"); */ | ||
117 | } | 212 | } |
213 | else | ||
214 | WRN("Could not get FBO from Bo"); | ||
118 | } | 215 | } |
119 | 216 | ||
120 | static Eina_Bool | 217 | static Eina_Bool |
@@ -253,9 +350,6 @@ _evas_outbuf_egl_setup(Outbuf *ob) | |||
253 | return EINA_FALSE; | 350 | return EINA_FALSE; |
254 | } | 351 | } |
255 | 352 | ||
256 | DBG("Config Format: %d", format); | ||
257 | DBG("OB Format: %d", ob->info->info.format); | ||
258 | |||
259 | if (format == (int)ob->info->info.format) | 353 | if (format == (int)ob->info->info.format) |
260 | { | 354 | { |
261 | ob->egl.config = cfgs[i]; | 355 | ob->egl.config = cfgs[i]; |
@@ -369,6 +463,11 @@ evas_outbuf_new(Evas_Engine_Info_GL_Drm *info, int w, int h, Render_Engine_Swap_ | |||
369 | /* ob->vsync = info->info.vsync; */ | 463 | /* ob->vsync = info->info.vsync; */ |
370 | ob->swap_mode = swap_mode; | 464 | ob->swap_mode = swap_mode; |
371 | 465 | ||
466 | ob->fd = info->info.fd; | ||
467 | ob->bpp = info->info.bpp; | ||
468 | ob->format = info->info.format; | ||
469 | ob->priv.output = info->info.output; | ||
470 | |||
372 | /* if ((num = getenv("EVAS_GL_DRM_VSYNC"))) */ | 471 | /* if ((num = getenv("EVAS_GL_DRM_VSYNC"))) */ |
373 | /* ob->vsync = atoi(num); */ | 472 | /* ob->vsync = atoi(num); */ |
374 | 473 | ||
@@ -383,6 +482,8 @@ evas_outbuf_new(Evas_Engine_Info_GL_Drm *info, int w, int h, Render_Engine_Swap_ | |||
383 | return NULL; | 482 | return NULL; |
384 | } | 483 | } |
385 | 484 | ||
485 | _outbuf_tick_source_set(ob); | ||
486 | |||
386 | return ob; | 487 | return ob; |
387 | } | 488 | } |
388 | 489 | ||
@@ -577,9 +678,7 @@ evas_outbuf_buffer_state_get(Outbuf *ob) | |||
577 | return swap_mode; | 678 | return swap_mode; |
578 | } | 679 | } |
579 | else | 680 | else |
580 | { | 681 | return MODE_FULL; |
581 | return MODE_FULL; | ||
582 | } | ||
583 | 682 | ||
584 | return ob->swap_mode; | 683 | return ob->swap_mode; |
585 | } | 684 | } |