summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Michael <cp.michael@samsung.com>2015-06-02 09:05:26 -0400
committerChris Michael <cp.michael@samsung.com>2015-06-05 10:00:44 -0400
commit58dbb63ba4bbc235477793b016ba31d2bf17d1fb (patch)
treea8ca151bf5871043ebe10d9cc66054865c84bfac
parent3f4c569341ab501b188f49c273bb961e0f1b75ee (diff)
evas-gl-drm: Remove old engine code
Signed-off-by: Chris Michael <cp.michael@samsung.com>
-rw-r--r--src/modules/evas/engines/gl_drm/Evas_Engine_GL_Drm.h44
-rw-r--r--src/modules/evas/engines/gl_drm/evas_drm.c347
-rw-r--r--src/modules/evas/engines/gl_drm/evas_drm_main.c636
-rw-r--r--src/modules/evas/engines/gl_drm/evas_engine.h191
4 files changed, 0 insertions, 1218 deletions
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
deleted file mode 100644
index 92069b61e0..0000000000
--- a/src/modules/evas/engines/gl_drm/Evas_Engine_GL_Drm.h
+++ /dev/null
@@ -1,44 +0,0 @@
1#ifndef _EVAS_ENGINE_GL_DRM_H
2# define _EVAS_ENGINE_GL_DRM_H
3
4# include <gbm.h>
5# include <Ecore_Drm.h>
6
7typedef struct _Evas_Engine_Info_GL_Drm Evas_Engine_Info_GL_Drm;
8
9struct _Evas_Engine_Info_GL_Drm
10{
11 /* PRIVATE - don't mess with this baby or evas will poke its tongue out
12 * at you and make nasty noises */
13 Evas_Engine_Info magic;
14
15 /* engine specific data & parameters it needs to set up */
16 struct
17 {
18 struct gbm_device *gbm;
19 struct gbm_surface *surface;
20 uint32_t format;
21 uint32_t flags;
22 int depth, screen, rotation;
23 unsigned char destination_alpha : 1;
24 int fd;
25 int output, plane;
26 Ecore_Drm_Device *dev;
27 } info;
28
29 struct
30 {
31 void (*pre_swap) (void *data, Evas *evas);
32 void (*post_swap) (void *data, Evas *evas);
33 void *data;
34 } callback;
35
36 /* non-blocking or blocking mode */
37 Evas_Engine_Render_Mode render_mode;
38
39 unsigned char vsync : 1;
40 unsigned char indirect : 1;
41 unsigned char swap_mode : 4;
42};
43
44#endif
diff --git a/src/modules/evas/engines/gl_drm/evas_drm.c b/src/modules/evas/engines/gl_drm/evas_drm.c
deleted file mode 100644
index c049fb9629..0000000000
--- a/src/modules/evas/engines/gl_drm/evas_drm.c
+++ /dev/null
@@ -1,347 +0,0 @@
1#include "evas_engine.h"
2#include <sys/mman.h>
3
4static void
5_evas_drm_fb_destroy_callback(struct gbm_bo *bo, void *data)
6{
7 Buffer *buffer = data;
8 struct gbm_device *gbm = gbm_bo_get_device(bo);
9
10 if (buffer->fb)
11 drmModeRmFB(gbm_device_get_fd(gbm), buffer->fb);
12}
13
14static unsigned int
15_evas_drm_crtc_buffer_get(int fd, int crtc_id)
16{
17 drmModeCrtc *crtc;
18 unsigned int id;
19
20 if (!(crtc = drmModeGetCrtc(fd, crtc_id))) return 0;
21 id = crtc->buffer_id;
22 drmModeFreeCrtc(crtc);
23 return id;
24}
25
26static void
27_evas_drm_outbuf_page_flip(int fd EINA_UNUSED, unsigned int seq EINA_UNUSED, unsigned int tv_sec EINA_UNUSED, unsigned int tv_usec EINA_UNUSED, void *data)
28{
29 Outbuf *ob;
30 Buffer *buff;
31
32 /* get the output buffer from data */
33 if (!(ob = data)) return;
34
35 buff = &(ob->priv.buffer[ob->priv.curr]);
36 gbm_surface_release_buffer(ob->surface, buff->bo);
37
38 ob->priv.pending_flip = EINA_FALSE;
39 ob->priv.curr = (ob->priv.curr + 1) % ob->priv.num;
40}
41
42static Eina_Bool
43_evas_drm_outbuf_planes_setup(Outbuf *ob, drmModePlaneResPtr pres)
44{
45 drmModePlanePtr dplane;
46 Plane *oplane;
47 unsigned int p = 0;
48 unsigned int f = 0;
49
50 for (p = 0; p < pres->count_planes; p++)
51 {
52 /* try to get this plane */
53 if (!(dplane = drmModeGetPlane(ob->priv.fd, pres->planes[p])))
54 continue;
55
56 /* try to allocate space for our plane */
57 if (!(oplane =
58 malloc(sizeof(Plane) +
59 ((sizeof(unsigned int)) * dplane->count_formats))))
60 {
61 drmModeFreePlane(dplane);
62 continue;
63 }
64
65 oplane->crtcs = dplane->possible_crtcs;
66 oplane->id = dplane->plane_id;
67 oplane->num_formats = dplane->count_formats;
68 memcpy(oplane->formats, dplane->formats,
69 dplane->count_formats * sizeof(dplane->formats[0]));
70
71 DBG("Plane %d, %d %d", p, dplane->x, dplane->y);
72 DBG("\tFB: %d", dplane->fb_id);
73 DBG("\tCrtc: %d, %d %d", dplane->crtc_id,
74 dplane->crtc_x, dplane->crtc_y);
75
76 DBG("\tSupported Formats");
77 for (f = 0; f < dplane->count_formats; f++)
78 {
79 DBG("\t\t%C%C%C%C", (dplane->formats[f] & 0xFF),
80 ((dplane->formats[f] >> 8) & 0xFF),
81 ((dplane->formats[f] >> 16) & 0xFF),
82 ((dplane->formats[f] >> 24) & 0xFF));
83 }
84
85 /* free this plane */
86 drmModeFreePlane(dplane);
87
88 /* append this plane */
89 ob->priv.planes = eina_list_append(ob->priv.planes, oplane);
90 }
91
92 if (eina_list_count(ob->priv.planes) < 1) return EINA_FALSE;
93 return EINA_TRUE;
94}
95
96Eina_Bool
97evas_drm_gbm_init(Evas_Engine_Info_GL_Drm *info, int w, int h)
98{
99 if (!info) return EINA_FALSE;
100 if (info->info.fd < 0) return EINA_FALSE;
101
102 if (!(info->info.gbm = gbm_create_device(info->info.fd)))
103 return EINA_FALSE;
104
105 if (!(info->info.surface =
106 gbm_surface_create(info->info.gbm, w, h,
107 info->info.format, info->info.flags)))
108 {
109 gbm_device_destroy(info->info.gbm);
110 info->info.gbm = NULL;
111 return EINA_FALSE;
112 }
113
114 return EINA_TRUE;
115}
116
117Eina_Bool
118evas_drm_gbm_shutdown(Evas_Engine_Info_GL_Drm *info)
119{
120 if (!info) return EINA_TRUE;
121
122 if (info->info.surface)
123 {
124 gbm_surface_destroy(info->info.surface);
125 info->info.surface = NULL;
126 }
127 if (info->info.gbm)
128 {
129 gbm_device_destroy(info->info.gbm);
130 info->info.gbm = NULL;
131 }
132
133 return EINA_TRUE;
134}
135
136Eina_Bool
137evas_drm_outbuf_setup(Outbuf *ob)
138{
139 drmModeRes *res;
140 drmModeConnector *conn;
141 drmModePlaneResPtr pres;
142 drmModeEncoder *enc;
143 drmModeModeInfo crtc_mode;
144 int i = 0;
145
146 /* check for valid Output buffer */
147 if ((!ob) || (ob->priv.fd < 0)) return EINA_FALSE;
148
149 /* setup drmHandleEvent context */
150 memset(&ob->priv.ctx, 0, sizeof(ob->priv.ctx));
151 ob->priv.ctx.version = DRM_EVENT_CONTEXT_VERSION;
152 ob->priv.ctx.page_flip_handler = _evas_drm_outbuf_page_flip;
153
154 /* try to get drm resources */
155 if (!(res = drmModeGetResources(ob->priv.fd)))
156 {
157 CRI("Could not get drm resources: %m");
158 return EINA_FALSE;
159 }
160
161 /* loop the connectors */
162 for (; i < res->count_connectors; ++i)
163 {
164 int crtc_id = -1;
165 int m = 0;
166
167 /* try to get this connector */
168 if (!(conn = drmModeGetConnector(ob->priv.fd, res->connectors[i])))
169 {
170 WRN("Could not get drm connector %d: %m", i);
171 continue;
172 }
173
174 /* make sure this connector is actually connected */
175 if (conn->connection != DRM_MODE_CONNECTED)
176 {
177 /* free connector resources */
178 drmModeFreeConnector(conn);
179 continue;
180 }
181
182 /* make sure it has modes */
183 if (conn->count_modes == 0)
184 {
185 /* free connector resources */
186 drmModeFreeConnector(conn);
187 continue;
188 }
189
190 /* record the connector id */
191 ob->priv.conn = conn->connector_id;
192
193 if ((enc = drmModeGetEncoder(ob->priv.fd, conn->encoder_id)))
194 {
195 drmModeCrtc *crtc;
196
197 if ((crtc = drmModeGetCrtc(ob->priv.fd, enc->crtc_id)))
198 {
199 crtc_id = enc->crtc_id;
200 if (crtc->mode_valid) crtc_mode = crtc->mode;
201 drmModeFreeCrtc(crtc);
202 }
203
204 drmModeFreeEncoder(enc);
205 }
206
207 /* record the crtc id */
208 ob->priv.crtc = crtc_id;
209
210 /* get the current framebuffer */
211 ob->priv.fb = _evas_drm_crtc_buffer_get(ob->priv.fd, crtc_id);
212
213 memset(&ob->priv.mode, 0, sizeof(ob->priv.mode));
214
215 for (m = 0; m < conn->count_modes; m++)
216 {
217 DBG("Output Available Mode: %d: %d %d %d", ob->priv.conn,
218 conn->modes[m].hdisplay, conn->modes[m].vdisplay,
219 conn->modes[m].vrefresh);
220 if (!memcmp(&crtc_mode, &conn->modes[m], sizeof(crtc_mode)))
221 {
222 /* record the current mode */
223 memcpy(&ob->priv.mode, &conn->modes[m], sizeof(ob->priv.mode));
224 break;
225 }
226
227 }
228
229 if ((!ob->priv.mode.hdisplay) && (crtc_mode.clock != 0))
230 memcpy(&ob->priv.mode, &crtc_mode, sizeof(ob->priv.mode));
231
232 DBG("Output Current Mode: %d: %d %d", ob->priv.conn,
233 ob->priv.mode.hdisplay, ob->priv.mode.vdisplay);
234
235 if ((ob->priv.mode.hdisplay != conn->modes[0].hdisplay) ||
236 (ob->priv.mode.vdisplay != conn->modes[0].vdisplay))
237 {
238 /* set new crtc mode */
239 drmModeSetCrtc(ob->priv.fd, ob->priv.crtc, ob->priv.fb, 0, 0,
240 &ob->priv.conn, 1, &ob->priv.mode);
241 }
242
243 /* free connector resources */
244 drmModeFreeConnector(conn);
245
246 break;
247 }
248
249 /* get any plane resource from the card */
250 pres = drmModeGetPlaneResources(ob->priv.fd);
251
252 /* if we have at least one plane, set it up */
253 if (pres->count_planes > 0)
254 {
255 if (!_evas_drm_outbuf_planes_setup(ob, pres))
256 WRN("Could not setup hardware planes");
257 }
258
259 /* free plane resources */
260 drmModeFreePlaneResources(pres);
261
262 /* free drm resources */
263 drmModeFreeResources(res);
264
265 return EINA_TRUE;
266}
267
268void
269evas_drm_outbuf_framebuffer_set(Outbuf *ob, Buffer *buffer)
270{
271 int ret;
272 uint32_t handles[4], pitches[4], offsets[4];
273 uint32_t width, height;
274 uint32_t format;
275
276 /* validate params */
277 if ((!ob) || (!buffer)) return;
278
279 if (buffer->valid) return;
280
281 width = gbm_bo_get_width(buffer->bo);
282 height = gbm_bo_get_height(buffer->bo);
283 buffer->stride = gbm_bo_get_stride(buffer->bo);
284 buffer->handle = gbm_bo_get_handle(buffer->bo).u32;
285 buffer->size = buffer->stride * height;
286 format = gbm_bo_get_format(buffer->bo);
287
288 handles[0] = buffer->handle;
289 pitches[0] = buffer->stride;
290 offsets[0] = 0;
291
292 ret = drmModeAddFB2(ob->priv.fd, width, height, format, handles,
293 pitches, offsets, &(buffer->fb), 0);
294 if (ret)
295 {
296 ret = drmModeAddFB(ob->priv.fd, width, height, 24, 32,
297 buffer->stride, buffer->handle, &(buffer->fb));
298 }
299 if (ret) ERR("Failed to AddFB: %m");
300
301 ret = drmModeSetCrtc(ob->priv.fd, ob->priv.crtc, buffer->fb, 0, 0,
302 &ob->priv.conn, 1, &ob->priv.mode);
303 if (ret) ERR("Failed to set crtc: %m");
304
305 gbm_bo_set_user_data(buffer->bo, buffer, _evas_drm_fb_destroy_callback);
306
307 buffer->valid = EINA_TRUE;
308}
309
310Eina_Bool
311evas_drm_framebuffer_send(Outbuf *ob, Buffer *buffer)
312{
313 /* check for valid Output buffer */
314 if ((!ob) || (ob->priv.fd < 0)) return EINA_FALSE;
315
316 /* check for valid buffer */
317 if (!buffer) return EINA_FALSE;
318
319 if (ob->vsync)
320 {
321 if (drmModePageFlip(ob->priv.fd, ob->priv.crtc,
322 buffer->fb, DRM_MODE_PAGE_FLIP_EVENT, ob) < 0)
323 {
324 ERR("Cannot flip crtc for connector %u: %m", ob->priv.conn);
325 return EINA_FALSE;
326 }
327
328 ob->priv.pending_flip = EINA_TRUE;
329
330 while (ob->priv.pending_flip)
331 drmHandleEvent(ob->priv.fd, &ob->priv.ctx);
332 }
333 else
334 {
335 /* NB: We don't actually need to do this if we are not vsync
336 * because we are drawing directly to the buffer anyway.
337 * If we enable the sending of buffer to crtc, it causes vsync */
338
339 /* send this buffer to the crtc */
340 /* evas_drm_outbuf_framebuffer_set(ob, buffer); */
341
342 /* increment buffer we are using */
343 ob->priv.curr = (ob->priv.curr + 1) % ob->priv.num;
344 }
345
346 return EINA_TRUE;
347}
diff --git a/src/modules/evas/engines/gl_drm/evas_drm_main.c b/src/modules/evas/engines/gl_drm/evas_drm_main.c
deleted file mode 100644
index 9918673974..0000000000
--- a/src/modules/evas/engines/gl_drm/evas_drm_main.c
+++ /dev/null
@@ -1,636 +0,0 @@
1#include "evas_engine.h"
2
3/* local variables */
4static Outbuf *_evas_gl_drm_window = NULL;
5static EGLContext context = EGL_NO_CONTEXT;
6static int win_count = 0;
7
8/* local function prototypes */
9static void _outbuf_buffer_swap(Outbuf *ob, Eina_Rectangle *rects, unsigned int count);
10static void _outbuf_flush_famebuffer(Outbuf *ob);
11
12/* local functions */
13static void
14_outbuf_buffer_swap(Outbuf *ob, Eina_Rectangle *rects EINA_UNUSED, unsigned int count EINA_UNUSED)
15{
16 Buffer *buff;
17
18 buff = &(ob->priv.buffer[ob->priv.curr]);
19
20 buff->bo = gbm_surface_lock_front_buffer(ob->surface);
21
22 /* if this buffer is not valid, we need to set it */
23 if (!buff->valid) evas_drm_outbuf_framebuffer_set(ob, buff);
24
25 /* send this buffer to the crtc */
26 evas_drm_framebuffer_send(ob, buff);
27}
28
29static void
30_outbuf_flush_famebuffer(Outbuf *ob)
31{
32 Eina_Rectangle *rects = NULL;
33 unsigned int n = 0;
34 //TODO: add region flush routine for SwapBuffersWithDamage
35
36 /* force a buffer swap */
37 _outbuf_buffer_swap(ob, rects, n);
38}
39
40Outbuf *
41eng_window_new(Evas_Engine_Info_GL_Drm *info, Evas *e, struct gbm_device *gbm, struct gbm_surface *surface, int screen, int depth, int w, int h, int indirect EINA_UNUSED, int alpha, int rot, Render_Engine_Swap_Mode swap_mode)
42{
43 Outbuf *gw;
44 int context_attrs[3];
45 int config_attrs[40];
46 int major_version, minor_version;
47 int num_config, n = 0;
48 const GLubyte *vendor, *renderer, *version, *glslversion;
49 Eina_Bool blacklist = EINA_FALSE;
50 char *num;
51
52 /* try to allocate space for outbuf */
53 gw = calloc(1, sizeof(Outbuf));
54 if (!gw) return NULL;
55
56 /* set properties of outbuf */
57 win_count++;
58 gw->gbm = gbm;
59 gw->surface = surface;
60 gw->screen = screen;
61 gw->depth = depth;
62 gw->w = w;
63 gw->h = h;
64 gw->alpha = alpha;
65 gw->rot = rot;
66 gw->swap_mode = swap_mode;
67 gw->info = info;
68 gw->evas = e;
69
70 /* setup drm outbuf */
71 /* set drm card fd */
72 gw->priv.fd = info->info.fd;
73 /* try to setup the drm card for this outbuf */
74 if (!evas_drm_outbuf_setup(gw))
75 {
76 ERR("Could not setup drm outbuf");
77 free(gw);
78 return NULL;
79 }
80
81 if (gw->w < gw->priv.mode.hdisplay) gw->w = gw->priv.mode.hdisplay;
82 if (gw->h < gw->priv.mode.vdisplay) gw->h = gw->priv.mode.vdisplay;
83
84 info->info.output = gw->priv.fb;
85 // TODO: change vsync for drm egl
86 //gw->vsync = info->vsync;
87
88 gw->priv.num = NUM_BUFFERS;
89 /* check for buffer override */
90 // TODO: change for gbm_bo related drm buffer number.
91 if ((num = getenv("EVAS_GL_DRM_BUFFERS")))
92 {
93 gw->priv.num = atoi(num);
94
95 /* cap maximum # of buffers */
96 if (gw->priv.num <= 0) gw->priv.num = 1;
97 else if (gw->priv.num > 3) gw->priv.num = 3;
98 }
99 /* end drm outbuf setup */
100
101 /* setup gbm egl surface */
102 context_attrs[0] = EGL_CONTEXT_CLIENT_VERSION;
103 context_attrs[1] = 2;
104 context_attrs[2] = EGL_NONE;
105
106 config_attrs[n++] = EGL_SURFACE_TYPE;
107 config_attrs[n++] = EGL_WINDOW_BIT;
108 config_attrs[n++] = EGL_RED_SIZE;
109 config_attrs[n++] = 1;
110 config_attrs[n++] = EGL_GREEN_SIZE;
111 config_attrs[n++] = 1;
112 config_attrs[n++] = EGL_BLUE_SIZE;
113 config_attrs[n++] = 1;
114 config_attrs[n++] = EGL_ALPHA_SIZE;
115 if (gw->alpha) config_attrs[n++] = 1;
116 else config_attrs[n++] = 0;
117 config_attrs[n++] = EGL_RENDERABLE_TYPE;
118 config_attrs[n++] = EGL_OPENGL_ES2_BIT;
119 config_attrs[n++] = EGL_NONE;
120
121#ifdef GL_DRM_DBG
122 DBG("GBM DEVICE: %x", (unsigned int)gbm);
123#endif
124
125 gw->egl_disp = eglGetDisplay((EGLNativeDisplayType)(gw->gbm));
126 if (gw->egl_disp == EGL_NO_DISPLAY)
127 {
128 ERR("eglGetDisplay() fail. code=%#x", eglGetError());
129 eng_window_free(gw);
130 return NULL;
131 }
132 if (!eglInitialize(gw->egl_disp, &major_version, &minor_version))
133 {
134 ERR("eglInitialize() fail. code=%#x", eglGetError());
135 eng_window_free(gw);
136 return NULL;
137 }
138 eglBindAPI(EGL_OPENGL_ES_API);
139 if (eglGetError() != EGL_SUCCESS)
140 {
141 ERR("eglBindAPI() fail. code=%#x", eglGetError());
142 eng_window_free(gw);
143 return NULL;
144 }
145
146 num_config = 0;
147 if (!eglChooseConfig(gw->egl_disp, config_attrs, &gw->egl_config,
148 1, &num_config) || (num_config != 1))
149 {
150 ERR("eglChooseConfig() fail. code=%#x", eglGetError());
151 eng_window_free(gw);
152 return NULL;
153 }
154
155 gw->egl_surface[0] =
156 eglCreateWindowSurface(gw->egl_disp, gw->egl_config,
157 (EGLNativeWindowType)gw->surface, NULL);
158 if (gw->egl_surface[0] == EGL_NO_SURFACE)
159 {
160 ERR("eglCreateWindowSurface() fail for %p. code=%#x",
161 gw->surface, eglGetError());
162 eng_window_free(gw);
163 return NULL;
164 }
165
166 gw->egl_context[0] =
167 eglCreateContext(gw->egl_disp, gw->egl_config, context, context_attrs);
168 if (gw->egl_context[0] == EGL_NO_CONTEXT)
169 {
170 ERR("eglCreateContext() fail. code=%#x", eglGetError());
171 eng_window_free(gw);
172 return NULL;
173 }
174
175 if (context == EGL_NO_CONTEXT) context = gw->egl_context[0];
176
177 if (eglMakeCurrent(gw->egl_disp, gw->egl_surface[0],
178 gw->egl_surface[0], gw->egl_context[0]) == EGL_FALSE)
179 {
180 ERR("eglMakeCurrent() fail. code=%#x", eglGetError());
181 eng_window_free(gw);
182 return NULL;
183 }
184
185 vendor = glGetString(GL_VENDOR);
186 renderer = glGetString(GL_RENDERER);
187 version = glGetString(GL_VERSION);
188 glslversion = glGetString(GL_SHADING_LANGUAGE_VERSION);
189 if (!vendor) vendor = (unsigned char *)"-UNKNOWN-";
190 if (!renderer) renderer = (unsigned char *)"-UNKNOWN-";
191 if (!version) version = (unsigned char *)"-UNKNOWN-";
192 if (!glslversion) glslversion = (unsigned char *)"-UNKNOWN-";
193 if (getenv("EVAS_GL_INFO"))
194 {
195 fprintf(stderr, "vendor : %s\n", vendor);
196 fprintf(stderr, "renderer: %s\n", renderer);
197 fprintf(stderr, "version : %s\n", version);
198 fprintf(stderr, "glsl ver: %s\n", glslversion);
199 }
200
201 if (strstr((const char *)vendor, "Mesa Project"))
202 {
203 if (strstr((const char *)renderer, "Software Rasterizer"))
204 blacklist = EINA_TRUE;
205 }
206 if (strstr((const char *)renderer, "softpipe"))
207 blacklist = EINA_TRUE;
208 if (strstr((const char *)renderer, "llvmpipe"))
209 blacklist = EINA_TRUE;
210 if ((blacklist) && (!getenv("EVAS_GL_NO_BLACKLIST")))
211 {
212 ERR("OpenGL Driver blacklisted:");
213 ERR("Vendor: %s", (const char *)vendor);
214 ERR("Renderer: %s", (const char *)renderer);
215 ERR("Version: %s", (const char *)version);
216 eng_window_free(gw);
217 return NULL;
218 }
219
220 gw->gl_context = glsym_evas_gl_common_context_new();
221 if (!gw->gl_context)
222 {
223 eng_window_free(gw);
224 return NULL;
225 }
226
227#ifdef GL_GLES
228 gw->gl_context->egldisp = gw->egl_disp;
229 gw->gl_context->eglctxt = gw->egl_context[0];
230#endif
231
232 eng_window_use(gw);
233 glsym_evas_gl_common_context_resize(gw->gl_context, w, h, rot);
234
235 gw->surf = EINA_TRUE;
236
237 return gw;
238}
239
240void
241eng_window_free(Outbuf *gw)
242{
243 int ref = 0;
244
245 win_count--;
246 eng_window_use(gw);
247
248 if (gw == _evas_gl_drm_window) _evas_gl_drm_window = NULL;
249
250 if (gw->gl_context)
251 {
252 ref = gw->gl_context->references - 1;
253 glsym_evas_gl_common_context_free(gw->gl_context);
254 }
255
256 eglMakeCurrent(gw->egl_disp, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
257
258 if (gw->egl_context[0] != context)
259 eglDestroyContext(gw->egl_disp, gw->egl_context[0]);
260
261 if (gw->egl_surface[0] != EGL_NO_SURFACE)
262 eglDestroySurface(gw->egl_disp, gw->egl_surface[0]);
263
264//TODO: consider gbm_surface destroy or not.
265#if 0
266 if (gw->surface)
267 {
268 gbm_surface_destroy(gw->surface);
269 gw->info->info.surface = NULL;
270 }
271#endif
272
273 if (ref == 0)
274 {
275 if (context) eglDestroyContext(gw->egl_disp, context);
276 eglTerminate(gw->egl_disp);
277 eglReleaseThread();
278 context = EGL_NO_CONTEXT;
279 }
280 free(gw);
281}
282
283Eina_Bool
284eng_window_make_current(void *data, void *doit)
285{
286 Outbuf *gw;
287
288 if (!(gw = data)) return EINA_FALSE;
289
290 if (doit)
291 {
292 if (!eglMakeCurrent(gw->egl_disp, gw->egl_surface[0],
293 gw->egl_surface[0], gw->egl_context[0]))
294 return EINA_FALSE;
295 }
296 else
297 {
298 if (!eglMakeCurrent(gw->egl_disp, EGL_NO_SURFACE,
299 EGL_NO_SURFACE, EGL_NO_CONTEXT))
300 return EINA_FALSE;
301 }
302
303 return EINA_TRUE;
304}
305
306void
307eng_window_use(Outbuf *gw)
308{
309 Eina_Bool force = EINA_FALSE;
310
311 glsym_evas_gl_preload_render_lock(eng_window_make_current, gw);
312
313 if (_evas_gl_drm_window)
314 {
315 if (eglGetCurrentContext() != _evas_gl_drm_window->egl_context[0])
316 force = EINA_TRUE;
317 }
318
319 if ((_evas_gl_drm_window != gw) || (force))
320 {
321 if (_evas_gl_drm_window)
322 {
323 glsym_evas_gl_common_context_use(_evas_gl_drm_window->gl_context);
324 glsym_evas_gl_common_context_flush(_evas_gl_drm_window->gl_context);
325 }
326
327 _evas_gl_drm_window = gw;
328
329 if (gw)
330 {
331 if (gw->egl_surface[0] != EGL_NO_SURFACE)
332 {
333 if (eglMakeCurrent(gw->egl_disp, gw->egl_surface[0],
334 gw->egl_surface[0],
335 gw->egl_context[0]) == EGL_FALSE)
336 ERR("eglMakeCurrent() failed!");
337 }
338 }
339 }
340
341 if (gw) glsym_evas_gl_common_context_use(gw->gl_context);
342}
343
344void
345eng_window_unsurf(Outbuf *gw)
346{
347 if (!gw->surf) return;
348 if (!getenv("EVAS_GL_WIN_RESURF")) return;
349 if (getenv("EVAS_GL_INFO")) printf("unsurf %p\n", gw);
350
351 if (_evas_gl_drm_window)
352 glsym_evas_gl_common_context_flush(_evas_gl_drm_window->gl_context);
353 if (_evas_gl_drm_window == gw)
354 {
355 eglMakeCurrent(gw->egl_disp, EGL_NO_SURFACE,
356 EGL_NO_SURFACE, EGL_NO_CONTEXT);
357 if (gw->egl_surface[0] != EGL_NO_SURFACE)
358 eglDestroySurface(gw->egl_disp, gw->egl_surface[0]);
359 gw->egl_surface[0] = EGL_NO_SURFACE;
360
361 _evas_gl_drm_window = NULL;
362 }
363
364 gw->surf = EINA_FALSE;
365}
366
367void
368eng_window_resurf(Outbuf *gw)
369{
370 if (gw->surf) return;
371 if (getenv("EVAS_GL_INFO")) printf("resurf %p\n", gw);
372
373 gw->egl_surface[0] =
374 eglCreateWindowSurface(gw->egl_disp, gw->egl_config,
375 (EGLNativeWindowType)gw->surface, NULL);
376
377 if (gw->egl_surface[0] == EGL_NO_SURFACE)
378 {
379 ERR("eglCreateWindowSurface() fail for %p. code=%#x",
380 gw->surface, eglGetError());
381 return;
382 }
383
384 if (eglMakeCurrent(gw->egl_disp, gw->egl_surface[0], gw->egl_surface[0],
385 gw->egl_context[0]) == EGL_FALSE)
386 ERR("eglMakeCurrent() failed!");
387
388 gw->surf = EINA_TRUE;
389}
390
391Context_3D *
392eng_gl_context_new(Outbuf *gw)
393{
394 Context_3D *ctx;
395 int context_attrs[3] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
396
397 if (!gw) return NULL;
398
399 ctx = calloc(1, sizeof(Context_3D));
400 if (!ctx) return NULL;
401
402 ctx->context = eglCreateContext(gw->egl_disp, gw->egl_config,
403 gw->egl_context[0], context_attrs);
404
405 if (!ctx->context)
406 {
407 ERR("EGL context creation failed.");
408 goto error;
409 }
410
411 ctx->display = gw->egl_disp;
412 ctx->surface = gw->egl_surface[0];
413
414 return ctx;
415
416error:
417 free(ctx);
418 return NULL;
419}
420
421void
422eng_gl_context_free(Context_3D *ctx)
423{
424 eglDestroyContext(ctx->display, ctx->context);
425 free(ctx);
426}
427
428void
429eng_gl_context_use(Context_3D *ctx)
430{
431 if (eglMakeCurrent(ctx->display, ctx->surface,
432 ctx->surface, ctx->context) == EGL_FALSE)
433 ERR("eglMakeCurrent() failed.");
434}
435
436void
437eng_outbuf_reconfigure(Outbuf *ob, int w, int h, int rot, Outbuf_Depth depth EINA_UNUSED)
438{
439 ob->w = w;
440 ob->h = h;
441 ob->rot = rot;
442 eng_window_use(ob);
443 glsym_evas_gl_common_context_resize(ob->gl_context, w, h, rot);
444
445 //TODO: need drm gbm surface destroy & re-create.?
446}
447
448int
449eng_outbuf_get_rot(Outbuf *ob)
450{
451 return ob->rot;
452}
453
454Render_Engine_Swap_Mode
455eng_outbuf_swap_mode(Outbuf *ob)
456{
457 if (ob->swap_mode == MODE_AUTO && extn_have_buffer_age)
458 {
459 Render_Engine_Swap_Mode swap_mode;
460
461 EGLint age = 0;
462
463 if (!eglQuerySurface(ob->egl_disp, ob->egl_surface[0],
464 EGL_BUFFER_AGE_EXT, &age))
465 age = 0;
466
467 if (age == 1) swap_mode = MODE_COPY;
468 else if (age == 2) swap_mode = MODE_DOUBLE;
469 else if (age == 3) swap_mode = MODE_TRIPLE;
470 else if (age == 4) swap_mode = MODE_QUADRUPLE;
471 else swap_mode = MODE_FULL;
472 if ((int)age != ob->prev_age) swap_mode = MODE_FULL;
473 ob->prev_age = age;
474
475 return swap_mode;
476 }
477
478 return ob->swap_mode;
479}
480
481Eina_Bool
482eng_outbuf_region_first_rect(Outbuf *ob)
483{
484 ob->gl_context->preserve_bit = GL_COLOR_BUFFER_BIT0_QCOM;
485
486 glsym_evas_gl_preload_render_lock(eng_preload_make_current, ob);
487 eng_window_use(ob);
488 if (!_re_wincheck(ob)) return EINA_TRUE;
489
490 glsym_evas_gl_common_context_resize(ob->gl_context, ob->w, ob->h, ob->rot);
491 glsym_evas_gl_common_context_flush(ob->gl_context);
492 glsym_evas_gl_common_context_newframe(ob->gl_context);
493
494 return EINA_FALSE;
495}
496
497void *
498eng_outbuf_new_region_for_update(Outbuf *ob, int x, int y, int w, int h, int *cx EINA_UNUSED, int *cy EINA_UNUSED, int *cw EINA_UNUSED, int *ch EINA_UNUSED)
499{
500 if ((w == ob->w) && (h == ob->h))
501 ob->gl_context->master_clip.enabled = EINA_FALSE;
502 else
503 {
504 ob->gl_context->master_clip.enabled = EINA_TRUE;
505 ob->gl_context->master_clip.x = x;
506 ob->gl_context->master_clip.y = y;
507 ob->gl_context->master_clip.w = w;
508 ob->gl_context->master_clip.h = h;
509 }
510 return ob->gl_context->def_surface;
511}
512
513void
514eng_outbuf_push_updated_region(Outbuf *ob, RGBA_Image *update EINA_UNUSED, int x EINA_UNUSED, int y EINA_UNUSED, int w EINA_UNUSED, int h EINA_UNUSED)
515{
516 /* Is it really necessary to flush per region ? Shouldn't we be able to
517 still do that for the full canvas when doing partial update */
518 if (!_re_wincheck(ob)) return;
519 ob->draw.drew = EINA_TRUE;
520 glsym_evas_gl_common_context_flush(ob->gl_context);
521}
522
523void
524eng_outbuf_push_free_region_for_update(Outbuf *ob EINA_UNUSED, RGBA_Image *update EINA_UNUSED)
525{
526 /* Nothing to do here as we don't really create an image per area */
527}
528
529void
530eng_outbuf_flush(Outbuf *ob, Tilebuf_Rect *rects EINA_UNUSED, Evas_Render_Mode render_mode)
531{
532 if (render_mode == EVAS_RENDER_MODE_ASYNC_INIT) goto end;
533
534 if (!_re_wincheck(ob)) goto end;
535 if (!ob->draw.drew) goto end;
536
537 ob->draw.drew = EINA_FALSE;
538 eng_window_use(ob);
539 glsym_evas_gl_common_context_done(ob->gl_context);
540
541 if (!ob->vsync)
542 {
543 if (ob->info->vsync) eglSwapInterval(ob->egl_disp, 1);
544 else eglSwapInterval(ob->egl_disp, 0);
545 ob->vsync = 1;
546 }
547
548 if (ob->info->callback.pre_swap)
549 ob->info->callback.pre_swap(ob->info->callback.data, ob->evas);
550
551// TODO: Check eglSwapBuffersWithDamage for gl_drm and apply
552#if 0
553 if ((glsym_eglSwapBuffersWithDamage) && (ob->swap_mode != MODE_FULL))
554
555 {
556 EGLint num = 0, *result = NULL, i = 0;
557 Tilebuf_Rect *r;
558
559 // if partial swaps can be done use re->rects
560 num = eina_inlist_count(EINA_INLIST_GET(rects));
561 if (num > 0)
562 {
563 result = alloca(sizeof(EGLint) * 4 * num);
564 EINA_INLIST_FOREACH(EINA_INLIST_GET(rects), r)
565 {
566 int gw, gh;
567
568 gw = ob->gl_context->w;
569 gh = ob->gl_context->h;
570 switch (ob->rot)
571 {
572 case 0:
573 result[i + 0] = r->x;
574 result[i + 1] = gh - (r->y + r->h);
575 result[i + 2] = r->w;
576 result[i + 3] = r->h;
577 break;
578 case 90:
579 result[i + 0] = r->y;
580 result[i + 1] = r->x;
581 result[i + 2] = r->h;
582 result[i + 3] = r->w;
583 break;
584 case 180:
585 result[i + 0] = gw - (r->x + r->w);
586 result[i + 1] = r->y;
587 result[i + 2] = r->w;
588 result[i + 3] = r->h;
589 break;
590 case 270:
591 result[i + 0] = gh - (r->y + r->h);
592 result[i + 1] = gw - (r->x + r->w);
593 result[i + 2] = r->h;
594 result[i + 3] = r->w;
595 break;
596 default:
597 result[i + 0] = r->x;
598 result[i + 1] = gh - (r->y + r->h);
599 result[i + 2] = r->w;
600 result[i + 3] = r->h;
601 break;
602 }
603 i += 4;
604 }
605 glsym_eglSwapBuffersWithDamage(ob->egl_disp, ob->egl_surface[0],
606 result, num);
607 }
608 }
609 else
610#endif
611 eglSwapBuffers(ob->egl_disp, ob->egl_surface[0]);
612
613 if (ob->info->callback.post_swap)
614 ob->info->callback.post_swap(ob->info->callback.data, ob->evas);
615
616 //Flush GL Surface data to Framebuffer
617 _outbuf_flush_famebuffer(ob);
618
619 ob->frame_cnt++;
620
621 end:
622 //TODO: Need render unlock after drm page flip?
623 glsym_evas_gl_preload_render_unlock(eng_preload_make_current, ob);
624}
625
626Evas_Engine_GL_Context *
627eng_outbuf_gl_context_get(Outbuf *ob)
628{
629 return ob->gl_context;
630}
631
632void *
633eng_outbuf_egl_display_get(Outbuf *ob)
634{
635 return ob->egl_disp;
636}
diff --git a/src/modules/evas/engines/gl_drm/evas_engine.h b/src/modules/evas/engines/gl_drm/evas_engine.h
deleted file mode 100644
index b97b0476fe..0000000000
--- a/src/modules/evas/engines/gl_drm/evas_engine.h
+++ /dev/null
@@ -1,191 +0,0 @@
1#ifndef EVAS_ENGINE_H
2# define EVAS_ENGINE_H
3
4#include "config.h"
5#include "evas_common_private.h"
6#include "evas_private.h"
7#include "Evas.h"
8#include "Evas_Engine_GL_Drm.h"
9#include "evas_macros.h"
10
11#define GL_GLEXT_PROTOTYPES
12#include <EGL/egl.h>
13#include <EGL/eglext.h>
14#include <EGL/eglmesaext.h>
15#include <GLES2/gl2.h>
16#include <GLES2/gl2ext.h>
17#include "../gl_generic/Evas_Engine_GL_Generic.h"
18
19#include <xf86drm.h>
20#include <xf86drmMode.h>
21#include <drm_fourcc.h>
22
23#include <signal.h>
24#include <sys/ioctl.h>
25#include <sys/types.h>
26#include <unistd.h>
27#include <fcntl.h>
28
29extern int extn_have_buffer_age;
30extern int _evas_engine_gl_drm_log_dom;
31
32extern Evas_GL_Common_Context_New glsym_evas_gl_common_context_new;
33extern Evas_GL_Common_Context_Call glsym_evas_gl_common_context_flush;
34extern Evas_GL_Common_Context_Call glsym_evas_gl_common_context_free;
35extern Evas_GL_Common_Context_Call glsym_evas_gl_common_context_use;
36extern Evas_GL_Common_Context_Call glsym_evas_gl_common_context_newframe;
37extern Evas_GL_Common_Context_Call glsym_evas_gl_common_context_done;
38extern Evas_GL_Common_Context_Resize_Call glsym_evas_gl_common_context_resize;
39extern Evas_GL_Common_Buffer_Dump_Call glsym_evas_gl_common_buffer_dump;
40extern Evas_GL_Preload_Render_Call glsym_evas_gl_preload_render_lock;
41extern Evas_GL_Preload_Render_Call glsym_evas_gl_preload_render_unlock;
42
43/* define this to enable debug for the gl_drm engine */
44/* #define GL_DRM_DBG 0 */
45
46# ifdef ERR
47# undef ERR
48# endif
49# define ERR(...) EINA_LOG_DOM_ERR(_evas_engine_gl_drm_log_dom, __VA_ARGS__)
50
51# ifdef DBG
52# undef DBG
53# endif
54# define DBG(...) EINA_LOG_DOM_DBG(_evas_engine_gl_drm_log_dom, __VA_ARGS__)
55
56# ifdef INF
57# undef INF
58# endif
59# define INF(...) EINA_LOG_DOM_INFO(_evas_engine_gl_drm_log_dom, __VA_ARGS__)
60
61# ifdef WRN
62# undef WRN
63# endif
64# define WRN(...) EINA_LOG_DOM_WARN(_evas_engine_gl_drm_log_dom, __VA_ARGS__)
65
66# ifdef CRI
67# undef CRI
68# endif
69# define CRI(...) EINA_LOG_DOM_CRIT(_evas_engine_gl_drm_log_dom, __VA_ARGS__)
70
71# define NUM_BUFFERS 2
72
73typedef struct _Buffer Buffer;
74typedef struct _Plane Plane;
75
76struct _Buffer
77{
78 int stride;
79 int size;
80 int handle;
81 unsigned int fb;
82 struct gbm_bo *bo; //used for hardware framebuffers
83 Eina_Bool valid : 1;
84};
85
86struct _Plane
87{
88 unsigned int id;
89 unsigned int crtcs;
90
91 struct
92 {
93 unsigned int x, y;
94 unsigned int w, h;
95 } src, dst;
96
97 unsigned int num_formats;
98 unsigned int formats[];
99};
100
101struct _Outbuf
102{
103 EGLContext egl_context[1];
104 EGLSurface egl_surface[1];
105 EGLConfig egl_config;
106 EGLDisplay egl_disp;
107 struct gbm_device *gbm;
108 struct gbm_surface *surface;
109 Evas *evas;
110 uint32_t format;
111 uint32_t flags;
112 Evas_Engine_GL_Context *gl_context;
113 Evas_Engine_Info_GL_Drm *info;
114 Render_Engine_Swap_Mode swap_mode;
115 int w, h;
116 int depth, rot, screen, alpha;
117 int prev_age;
118 int frame_cnt;
119 int vsync;
120 Eina_Bool lost_back : 1;
121 Eina_Bool surf : 1;
122
123 struct
124 {
125 Eina_Bool drew : 1;
126 } draw;
127
128 struct
129 {
130 int fd;
131 unsigned int conn, crtc, fb;
132 Buffer buffer[NUM_BUFFERS];
133 int curr, num;
134 drmModeModeInfo mode;
135 drmEventContext ctx;
136 Eina_List *pending_writes;
137 Eina_List *planes;
138 Eina_Bool pending_flip : 1;
139 } priv;
140};
141
142struct _Context_3D
143{
144 EGLDisplay display;
145 EGLContext context;
146 EGLSurface surface;
147};
148
149Outbuf *eng_window_new(Evas_Engine_Info_GL_Drm *info, Evas *e, struct gbm_device *gbm, struct gbm_surface *surface, int screen, int depth, int w, int h, int indirect, int alpha, int rot, Render_Engine_Swap_Mode swap_mode);
150void eng_window_free(Outbuf *gw);
151void eng_window_use(Outbuf *gw);
152void eng_window_unsurf(Outbuf *gw);
153void eng_window_resurf(Outbuf *gw);
154
155void eng_outbuf_reconfigure(Outbuf *ob, int w, int h, int rot, Outbuf_Depth depth);
156int eng_outbuf_get_rot(Outbuf *ob);
157Render_Engine_Swap_Mode eng_outbuf_swap_mode(Outbuf *ob);
158Eina_Bool eng_outbuf_region_first_rect(Outbuf *ob);
159void *eng_outbuf_new_region_for_update(Outbuf *ob, int x, int y, int w, int h, int *cx, int *cy, int *cw, int *ch);
160void eng_outbuf_push_free_region_for_update(Outbuf *ob, RGBA_Image *update);
161void eng_outbuf_push_updated_region(Outbuf *ob, RGBA_Image *update, int x, int y, int w, int h);
162void eng_outbuf_flush(Outbuf *ob, Tilebuf_Rect *rects, Evas_Render_Mode render_mode);
163Evas_Engine_GL_Context* eng_outbuf_gl_context_get(Outbuf *ob);
164void *eng_outbuf_egl_display_get(Outbuf *ob);
165
166void eng_gl_context_free(Context_3D *context);
167void eng_gl_context_use(Context_3D *context);
168
169Eina_Bool eng_preload_make_current(void *data, void *doit);
170
171Context_3D *eng_gl_context_new(Outbuf *win);
172
173static inline Eina_Bool
174_re_wincheck(Outbuf *ob)
175{
176 if (ob->surf) return EINA_TRUE;
177 eng_window_resurf(ob);
178 ob->lost_back = 1;
179 if (!ob->surf)
180 {
181 ERR("GL engine can't re-create window surface!");
182 }
183 return EINA_FALSE;
184}
185
186Eina_Bool evas_drm_gbm_init(Evas_Engine_Info_GL_Drm *info, int w, int h);
187Eina_Bool evas_drm_gbm_shutdown(Evas_Engine_Info_GL_Drm *info);
188Eina_Bool evas_drm_outbuf_setup(Outbuf *ob);
189void evas_drm_outbuf_framebuffer_set(Outbuf *ob, Buffer *buffer);
190Eina_Bool evas_drm_framebuffer_send(Outbuf *ob, Buffer *buffer);
191#endif