summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--m4/evas_check_engine.m413
-rw-r--r--src/Makefile_Evas.am14
-rw-r--r--src/modules/evas/engines/drm/Evas_Engine_Drm.h21
-rw-r--r--src/modules/evas/engines/drm/evas_engine.c102
-rw-r--r--src/modules/evas/engines/drm/evas_engine.h56
-rw-r--r--src/modules/evas/engines/drm/evas_outbuf.c506
-rw-r--r--src/modules/evas/engines/gl_drm/Evas_Engine_GL_Drm.h6
-rw-r--r--src/modules/evas/engines/gl_drm/evas_engine.c70
-rw-r--r--src/modules/evas/engines/gl_drm/evas_engine.h24
-rw-r--r--src/modules/evas/engines/gl_drm/evas_outbuf.c197
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
599requirement="" 599requirement=""
600have_dep="yes" 600have_dep="no"
601have_hw_dep="no" 601have_hw_dep="no"
602evas_engine_[]$1[]_cflags="" 602evas_engine_[]$1[]_cflags=""
603evas_engine_[]$1[]_libs="" 603evas_engine_[]$1[]_libs=""
604 604
605PKG_CHECK_EXISTS([libdrm],
606 [
607 have_dep="yes"
608 requirement="libdrm"
609 ], [have_dep="no"])
610
605if test "x${have_dep}" = "xyes" ; then 611if 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.])
637fi 644fi
638 645
639PKG_CHECK_EXISTS([egl ${gl_library} gbm wayland-client >= REQUIRED_WAYLAND_VERSION], 646PKG_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
1276endif 1276endif
1277 1277
1278if BUILD_ENGINE_DRM 1278if BUILD_ENGINE_DRM
1279dist_installed_evasmainheaders_DATA += modules/evas/engines/drm/Evas_Engine_Drm.h
1280DRM_SOURCES = \ 1279DRM_SOURCES = \
1281modules/evas/engines/drm/evas_outbuf.c \ 1280modules/evas/engines/drm/evas_outbuf.c \
1282modules/evas/engines/drm/evas_engine.c \ 1281modules/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@
1306modules_evas_engines_drm_module_la_LIBADD = \ 1305modules_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@
1310modules_evas_engines_drm_module_la_DEPENDENCIES = @USE_EVAS_INTERNAL_LIBS@ @USE_ECORE_DRM_INTERNAL_LIBS@ 1309modules_evas_engines_drm_module_la_DEPENDENCIES = @USE_EVAS_INTERNAL_LIBS@ @USE_ECORE_DRM2_INTERNAL_LIBS@
1311modules_evas_engines_drm_module_la_LDFLAGS = -module @EFL_LTMODULE_FLAGS@ 1310modules_evas_engines_drm_module_la_LDFLAGS = -module @EFL_LTMODULE_FLAGS@
1312modules_evas_engines_drm_module_la_LIBTOOLFLAGS = --tag=disable-static 1311modules_evas_engines_drm_module_la_LIBTOOLFLAGS = --tag=disable-static
1313endif 1312endif
1314endif 1313endif
1315 1314
1316if BUILD_ENGINE_GL_DRM 1315if BUILD_ENGINE_GL_DRM
1317dist_installed_evasmainheaders_DATA += modules/evas/engines/gl_drm/Evas_Engine_GL_Drm.h
1318GL_DRM_SOURCES = \ 1316GL_DRM_SOURCES = \
1319modules/evas/engines/gl_drm/evas_outbuf.c \ 1317modules/evas/engines/gl_drm/evas_outbuf.c \
1320modules/evas/engines/gl_drm/evas_engine.c \ 1318modules/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@
1344modules_evas_engines_gl_drm_module_la_LIBADD = \ 1342modules_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@
1348modules_evas_engines_gl_drm_module_la_DEPENDENCIES = @USE_EVAS_INTERNAL_LIBS@ @USE_ECORE_DRM_INTERNAL_LIBS@ 1346modules_evas_engines_gl_drm_module_la_DEPENDENCIES = @USE_EVAS_INTERNAL_LIBS@ @USE_ECORE_DRM2_INTERNAL_LIBS@
1349modules_evas_engines_gl_drm_module_la_LDFLAGS = -module @EFL_LTMODULE_FLAGS@ 1347modules_evas_engines_gl_drm_module_la_LDFLAGS = -module @EFL_LTMODULE_FLAGS@
1350modules_evas_engines_gl_drm_module_la_LIBTOOLFLAGS = --tag=disable-static 1348modules_evas_engines_gl_drm_module_la_LIBTOOLFLAGS = --tag=disable-static
1351endif 1349endif
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> 4typedef struct _Evas_Engine_Info_Drm
5
6typedef struct _Evas_Engine_Info_Drm Evas_Engine_Info_Drm;
7
8struct _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 */ 3typedef struct _Render_Engine
4typedef struct _Render_Engine Render_Engine;
5
6struct _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) */
12static Evas_Func func, pfunc; 8static Evas_Func func, pfunc;
13 9
14/* external variables */
15int _evas_engine_drm_log_dom; 10int _evas_engine_drm_log_dom;
16 11
17/* local functions */ 12static Render_Engine *
18static 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: 40init_err:
48 if (re) evas_render_engine_software_generic_clean(&re->generic); 41 evas_render_engine_software_generic_clean(&re->generic);
49 42err:
50 free(re); 43 free(re);
51 return NULL; 44 return NULL;
52} 45}
53 46
54/* engine api functions */
55static void * 47static void *
56eng_info(Evas *evas EINA_UNUSED) 48eng_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
81static int 73static int
82eng_setup(Evas *evas, void *einfo) 74eng_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 */
148static int 132static int
149module_open(Evas_Module *em) 133module_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
190static Evas_Module_Api evas_modapi = 178static 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
12extern int _evas_engine_drm_log_dom; 17extern 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
39struct _Outbuf 44typedef 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; 54struct _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
60Outbuf *evas_outbuf_setup(Evas_Engine_Info_Drm *info, int w, int h); 74Outbuf *_outbuf_setup(Evas_Engine_Info_Drm *info, int w, int h);
61void evas_outbuf_free(Outbuf *ob); 75void _outbuf_free(Outbuf *ob);
62void evas_outbuf_reconfigure(Outbuf *ob, int w, int h, int rot, Outbuf_Depth depth); 76int _outbuf_rotation_get(Outbuf *ob);
63Render_Engine_Swap_Mode evas_outbuf_buffer_state_get(Outbuf *ob); 77void _outbuf_reconfigure(Outbuf *ob, int w, int h, int rotation, Outbuf_Depth depth);
64int evas_outbuf_rot_get(Outbuf *ob); 78Render_Engine_Swap_Mode _outbuf_state_get(Outbuf *ob);
65void *evas_outbuf_update_region_new(Outbuf *ob, int x, int y, int w, int h, int *cx, int *cy, int *cw, int *ch); 79void *_outbuf_update_region_new(Outbuf *ob, int x, int y, int w, int h, int *cx, int *cy, int *cw, int *ch);
66void evas_outbuf_update_region_push(Outbuf *ob, RGBA_Image *update, int x, int y, int w, int h); 80void _outbuf_update_region_push(Outbuf *ob, RGBA_Image *update, int x, int y, int w, int h);
67void evas_outbuf_update_region_free(Outbuf *ob, RGBA_Image *update); 81void _outbuf_update_region_free(Outbuf *ob, RGBA_Image *update);
68void evas_outbuf_flush(Outbuf *ob, Tilebuf_Rect *rects, Evas_Render_Mode render_mode); 82void _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
11static void 11static void _outbuf_tick_schedule(int fd, void *data);
12_evas_outbuf_buffer_swap(Outbuf *ob, Eina_Rectangle *rects, unsigned int count) 12
13static Eina_Bool ticking = EINA_FALSE;
14
15static 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
25static void
26_outbuf_tick_end(void *data EINA_UNUSED)
27{
28 ticking = EINA_FALSE;
29}
30
31static 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
50static 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
73static 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
80static 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
101static 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]; 118static 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 */ 174static 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
190static 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
28Outbuf * 202Outbuf *
29evas_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
89void 258void
90evas_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
271int
272_outbuf_rotation_get(Outbuf *ob)
273{
274 return ob->rotation;
275}
276
102void 277void
103evas_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
150Render_Engine_Swap_Mode 351static Outbuf_Fb *
151evas_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
370static 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
408Render_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
176void * 425void *
177evas_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
231void 478void
232evas_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
354void 608void
355evas_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
360void 614void
361evas_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
436int
437evas_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
7typedef enum _Evas_Engine_Info_GL_Drm_Swap_Mode 7typedef 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 =
118Eina_Bool 118Eina_Bool
119eng_gbm_init(Evas_Engine_Info_GL_Drm *info) 119eng_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 */
150static inline Outbuf *
151eng_get_ob(Render_Engine *re)
152{
153 return re->generic.software.ob;
154}
155
156/* local functions */ 146/* local functions */
157static void 147static void
158gl_symbols(void) 148gl_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
781static 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
787static 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
793static 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 */
790static void * 813static void *
791eng_info(Evas *eo_e EINA_UNUSED) 814eng_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
1476static Evas_Module_Api evas_modapi = 1514static 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;
64struct _Render_Engine 69struct _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
69struct _Context_3D 78struct _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
123void evas_outbuf_update_region_push(Outbuf *ob, RGBA_Image *update, int x, int y, int w, int h); 132void evas_outbuf_update_region_push(Outbuf *ob, RGBA_Image *update, int x, int y, int w, int h);
124void evas_outbuf_update_region_free(Outbuf *ob, RGBA_Image *update); 133void evas_outbuf_update_region_free(Outbuf *ob, RGBA_Image *update);
125void evas_outbuf_flush(Outbuf *ob, Tilebuf_Rect *rects, Evas_Render_Mode render_mode); 134void evas_outbuf_flush(Outbuf *ob, Tilebuf_Rect *rects, Evas_Render_Mode render_mode);
135void evas_outbuf_vblank(void *data, int fd);
136void evas_outbuf_page_flip(void *data, int fd);
137
126Evas_Engine_GL_Context* evas_outbuf_gl_context_get(Outbuf *ob); 138Evas_Engine_GL_Context* evas_outbuf_gl_context_get(Outbuf *ob);
127void *evas_outbuf_egl_display_get(Outbuf *ob); 139void *evas_outbuf_egl_display_get(Outbuf *ob);
128Context_3D *evas_outbuf_gl_context_new(Outbuf *ob); 140Context_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
153static inline Outbuf *
154eng_get_ob(Render_Engine *re)
155{
156 return re->generic.software.ob;
157}
158
141extern unsigned int (*glsym_eglSwapBuffersWithDamage)(EGLDisplay a, void *b, const EGLint *d, EGLint c); 159extern unsigned int (*glsym_eglSwapBuffersWithDamage)(EGLDisplay a, void *b, const EGLint *d, EGLint c);
142extern unsigned int (*glsym_eglSetDamageRegionKHR)(EGLDisplay a, EGLSurface b, EGLint *c, EGLint d); 160extern 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 @@
5static Outbuf *_evas_gl_drm_window = NULL; 5static Outbuf *_evas_gl_drm_window = NULL;
6static EGLContext context = EGL_NO_CONTEXT; 6static EGLContext context = EGL_NO_CONTEXT;
7static int win_count = 0; 7static int win_count = 0;
8static Eina_Bool ticking = EINA_FALSE;
8 9
9#ifdef EGL_MESA_platform_gbm 10#ifdef EGL_MESA_platform_gbm
10static PFNEGLGETPLATFORMDISPLAYEXTPROC dlsym_eglGetPlatformDisplayEXT = NULL; 11static PFNEGLGETPLATFORMDISPLAYEXTPROC dlsym_eglGetPlatformDisplayEXT = NULL;
@@ -12,6 +13,79 @@ static PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC dlsym_eglCreatePlatformWindowSur
12#endif 13#endif
13 14
14static void 15static 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
30static 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
40static void
41_outbuf_tick_end(void *data EINA_UNUSED)
42{
43 ticking = EINA_FALSE;
44}
45
46static 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
65void
66evas_outbuf_vblank(void *data, int fd)
67{
68 ecore_animator_custom_tick();
69 if (ticking) _outbuf_tick_schedule(fd, data);
70}
71
72void
73evas_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
88static 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)
25static void 99static 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
37static void 113static 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
53static Ecore_Drm_Fb * 122static 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)
91static void 153static 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
120static Eina_Bool 217static 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}