summaryrefslogtreecommitdiff
path: root/src/modules/evas/engines/gl_drm/evas_outbuf.c
diff options
context:
space:
mode:
authorChris Michael <cp.michael@samsung.com>2015-06-04 11:52:22 -0400
committerChris Michael <cp.michael@samsung.com>2015-06-05 10:00:45 -0400
commita83bb5e45d9b58788f7a98c2d3f74513495aff68 (patch)
treea3f0c9adccf481203f95e2e45051d46f3f6b099a /src/modules/evas/engines/gl_drm/evas_outbuf.c
parent35e7d364892a0d30993c600f29c83f9f1e9220c8 (diff)
evas-gl-drm: Refactor gl_drm engine to not use dumb buffers
@fix Signed-off-by: Chris Michael <cp.michael@samsung.com>
Diffstat (limited to '')
-rw-r--r--src/modules/evas/engines/gl_drm/evas_outbuf.c162
1 files changed, 91 insertions, 71 deletions
diff --git a/src/modules/evas/engines/gl_drm/evas_outbuf.c b/src/modules/evas/engines/gl_drm/evas_outbuf.c
index 9df628f47f..09f2981b7d 100644
--- a/src/modules/evas/engines/gl_drm/evas_outbuf.c
+++ b/src/modules/evas/engines/gl_drm/evas_outbuf.c
@@ -6,18 +6,74 @@ static EGLContext context = EGL_NO_CONTEXT;
6static int win_count = 0; 6static int win_count = 0;
7 7
8static void 8static void
9_evas_outbuf_fb_cb_destroy(struct gbm_bo *bo, void *data)
10{
11 Ecore_Drm_Fb *fb;
12
13 fb = data;
14 if (fb)
15 {
16 struct gbm_device *gbm;
17
18 gbm = gbm_bo_get_device(bo);
19 drmModeRmFB(gbm_device_get_fd(gbm), fb->id);
20 free(fb);
21 }
22}
23
24static Ecore_Drm_Fb *
25_evas_outbuf_fb_get(Ecore_Drm_Device *dev, struct gbm_bo *bo)
26{
27 int ret;
28 Ecore_Drm_Fb *fb;
29 uint32_t format;
30 uint32_t handles[4], pitches[4], offsets[4];
31
32 fb = gbm_bo_get_user_data(bo);
33 if (fb) return fb;
34
35 if (!(fb = calloc(1, sizeof(Ecore_Drm_Fb)))) return NULL;
36
37 format = gbm_bo_get_format(bo);
38
39 fb->w = gbm_bo_get_width(bo);
40 fb->h = gbm_bo_get_height(bo);
41 fb->hdl = gbm_bo_get_handle(bo).u32;
42 fb->stride = gbm_bo_get_stride(bo);
43 fb->size = fb->stride * fb->h;
44
45 handles[0] = fb->hdl;
46 pitches[0] = fb->stride;
47 offsets[0] = 0;
48
49 ret = drmModeAddFB2(dev->drm.fd, fb->w, fb->h, format,
50 handles, pitches, offsets, &(fb->id), 0);
51 if (ret)
52 ret = drmModeAddFB(dev->drm.fd, fb->w, fb->h, 24, 32,
53 fb->stride, fb->hdl, &(fb->id));
54
55 if (ret) ERR("FAILED TO ADD FB: %m");
56
57 gbm_bo_set_user_data(bo, fb, _evas_outbuf_fb_cb_destroy);
58
59 return fb;
60}
61
62static void
9_evas_outbuf_cb_pageflip(void *data) 63_evas_outbuf_cb_pageflip(void *data)
10{ 64{
11 Outbuf *ob; 65 Outbuf *ob;
12 Ecore_Drm_Fb *fb; 66 Ecore_Drm_Fb *fb;
67 struct gbm_bo *bo;
13 68
14 if (!(ob = data)) return; 69 if (!(ob = data)) return;
15 70
16 if ((fb = ob->priv.buffer[ob->priv.curr])) 71 bo = ob->priv.bo[ob->priv.curr];
17 { 72
18 fb->pending_flip = EINA_FALSE; 73 fb = _evas_outbuf_fb_get(ob->info->info.dev, bo);
19 gbm_surface_release_buffer(ob->surface, ob->priv.bo[ob->priv.curr]); 74 if (fb) fb->pending_flip = EINA_FALSE;
20 } 75
76 gbm_surface_release_buffer(ob->surface, bo);
21 77
22 ob->priv.last = ob->priv.curr; 78 ob->priv.last = ob->priv.curr;
23 ob->priv.curr = (ob->priv.curr + 1) % ob->priv.num; 79 ob->priv.curr = (ob->priv.curr + 1) % ob->priv.num;
@@ -26,15 +82,17 @@ _evas_outbuf_cb_pageflip(void *data)
26static void 82static void
27_evas_outbuf_buffer_swap(Outbuf *ob, Eina_Rectangle *rects, unsigned int count) 83_evas_outbuf_buffer_swap(Outbuf *ob, Eina_Rectangle *rects, unsigned int count)
28{ 84{
29 Ecore_Drm_Fb *buff; 85 Ecore_Drm_Fb *fb;
30
31 buff = ob->priv.buffer[ob->priv.curr];
32 86
33 ob->priv.bo[ob->priv.curr] = gbm_surface_lock_front_buffer(ob->surface); 87 ob->priv.bo[ob->priv.curr] = gbm_surface_lock_front_buffer(ob->surface);
34 88
35 ecore_drm_fb_dirty(buff, rects, count); 89 fb = _evas_outbuf_fb_get(ob->info->info.dev, ob->priv.bo[ob->priv.curr]);
36 ecore_drm_fb_set(ob->info->info.dev, buff); 90 if (fb)
37 ecore_drm_fb_send(ob->info->info.dev, buff, _evas_outbuf_cb_pageflip, ob); 91 {
92 ecore_drm_fb_dirty(fb, rects, count);
93 ecore_drm_fb_set(ob->info->info.dev, fb);
94 ecore_drm_fb_send(ob->info->info.dev, fb, _evas_outbuf_cb_pageflip, ob);
95 }
38} 96}
39 97
40static Eina_Bool 98static Eina_Bool
@@ -117,16 +175,6 @@ _evas_outbuf_egl_setup(Outbuf *ob)
117 return EINA_FALSE; 175 return EINA_FALSE;
118 } 176 }
119 177
120 ob->egl.context[0] =
121 eglCreateContext(ob->egl.disp, ob->egl.config, context, ctx_attr);
122 if (ob->egl.context[0] == EGL_NO_CONTEXT)
123 {
124 ERR("eglCreateContext() fail. code=%#x", eglGetError());
125 return EINA_FALSE;
126 }
127
128 if (context == EGL_NO_CONTEXT) context = ob->egl.context[0];
129
130 ob->egl.surface[0] = 178 ob->egl.surface[0] =
131 eglCreateWindowSurface(ob->egl.disp, ob->egl.config, 179 eglCreateWindowSurface(ob->egl.disp, ob->egl.config,
132 (EGLNativeWindowType)ob->surface, NULL); 180 (EGLNativeWindowType)ob->surface, NULL);
@@ -137,6 +185,16 @@ _evas_outbuf_egl_setup(Outbuf *ob)
137 return EINA_FALSE; 185 return EINA_FALSE;
138 } 186 }
139 187
188 ob->egl.context[0] =
189 eglCreateContext(ob->egl.disp, ob->egl.config, context, ctx_attr);
190 if (ob->egl.context[0] == EGL_NO_CONTEXT)
191 {
192 ERR("eglCreateContext() fail. code=%#x", eglGetError());
193 return EINA_FALSE;
194 }
195
196 if (context == EGL_NO_CONTEXT) context = ob->egl.context[0];
197
140 if (eglMakeCurrent(ob->egl.disp, ob->egl.surface[0], 198 if (eglMakeCurrent(ob->egl.disp, ob->egl.surface[0],
141 ob->egl.surface[0], ob->egl.context[0]) == EGL_FALSE) 199 ob->egl.surface[0], ob->egl.context[0]) == EGL_FALSE)
142 { 200 {
@@ -179,6 +237,8 @@ _evas_outbuf_egl_setup(Outbuf *ob)
179 return EINA_FALSE; 237 return EINA_FALSE;
180 } 238 }
181 239
240 /* eng_gl_symbols(); */
241
182 ob->gl_context = glsym_evas_gl_common_context_new(); 242 ob->gl_context = glsym_evas_gl_common_context_new();
183 if (!ob->gl_context) return EINA_FALSE; 243 if (!ob->gl_context) return EINA_FALSE;
184 244
@@ -201,7 +261,6 @@ evas_outbuf_new(Evas_Engine_Info_GL_Drm *info, int w, int h, Render_Engine_Swap_
201{ 261{
202 Outbuf *ob; 262 Outbuf *ob;
203 char *num; 263 char *num;
204 int i = 0;
205 264
206 /* try to allocate space for outbuf */ 265 /* try to allocate space for outbuf */
207 if (!(ob = calloc(1, sizeof(Outbuf)))) return NULL; 266 if (!(ob = calloc(1, sizeof(Outbuf)))) return NULL;
@@ -236,30 +295,13 @@ evas_outbuf_new(Evas_Engine_Info_GL_Drm *info, int w, int h, Render_Engine_Swap_
236 return NULL; 295 return NULL;
237 } 296 }
238 297
239 for (; i < ob->priv.num; i++)
240 {
241 ob->priv.buffer[i] =
242 ecore_drm_fb_create(ob->info->info.dev, ob->w, ob->h);
243 if (!ob->priv.buffer[i]) break;
244
245 DBG("Evas Engine Created Dumb Buffer");
246 DBG("\tFb: %d", ob->priv.buffer[i]->id);
247 DBG("\tHandle: %d", ob->priv.buffer[i]->hdl);
248 DBG("\tStride: %d", ob->priv.buffer[i]->stride);
249 DBG("\tSize: %d", ob->priv.buffer[i]->size);
250 DBG("\tW: %d\tH: %d",
251 ob->priv.buffer[i]->w, ob->priv.buffer[i]->h);
252 }
253
254 ecore_drm_fb_set(info->info.dev, ob->priv.buffer[0]);
255
256 return ob; 298 return ob;
257} 299}
258 300
259void 301void
260evas_outbuf_free(Outbuf *ob) 302evas_outbuf_free(Outbuf *ob)
261{ 303{
262 int i = 0, ref = 0; 304 int ref = 0;
263 305
264 win_count--; 306 win_count--;
265 evas_outbuf_use(ob); 307 evas_outbuf_use(ob);
@@ -296,9 +338,6 @@ evas_outbuf_free(Outbuf *ob)
296 context = EGL_NO_CONTEXT; 338 context = EGL_NO_CONTEXT;
297 } 339 }
298 340
299 for (; i < ob->priv.num; i++)
300 ecore_drm_fb_destroy(ob->priv.buffer[i]);
301
302 free(ob); 341 free(ob);
303} 342}
304 343
@@ -390,38 +429,19 @@ evas_outbuf_unsurf(Outbuf *ob)
390void 429void
391evas_outbuf_reconfigure(Outbuf *ob, int w, int h, int rot, Outbuf_Depth depth) 430evas_outbuf_reconfigure(Outbuf *ob, int w, int h, int rot, Outbuf_Depth depth)
392{ 431{
393 int i = 0; 432 /* if (depth == OUTBUF_DEPTH_INHERIT) depth = ob->depth; */
394
395 if (depth == OUTBUF_DEPTH_INHERIT) depth = ob->depth;
396 433
397 /* check for changes */ 434 /* check for changes */
398 if ((ob->w == w) && (ob->h == h) && 435 /* if ((ob->w == w) && (ob->h == h) && */
399 (ob->destination_alpha == ob->info->info.destination_alpha) && 436 /* (ob->destination_alpha == ob->info->info.destination_alpha) && */
400 ((int)ob->rotation == rot) && (ob->depth == depth)) 437 /* ((int)ob->rotation == rot) && (ob->depth == depth)) */
401 return; 438 /* return; */
402 439
403 ob->w = w; 440 ob->w = w;
404 ob->h = h; 441 ob->h = h;
405 ob->depth = depth; 442 ob->depth = depth;
406 ob->rotation = rot; 443 ob->rotation = rot;
407
408 /* destroy the old buffers */
409 for (; i < ob->priv.num; i++)
410 ecore_drm_fb_destroy(ob->priv.buffer[i]);
411
412 for (i = 0; i < ob->priv.num; i++)
413 {
414 ob->priv.buffer[i] =
415 ecore_drm_fb_create(ob->info->info.dev, ob->w, ob->h);
416 if (!ob->priv.buffer[i])
417 {
418 ERR("Failed to create buffer %d", i);
419 break;
420 }
421 }
422
423 evas_outbuf_use(ob); 444 evas_outbuf_use(ob);
424
425 glsym_evas_gl_common_context_resize(ob->gl_context, w, h, rot); 445 glsym_evas_gl_common_context_resize(ob->gl_context, w, h, rot);
426 446
427 //TODO: need drm gbm surface destroy & re-create.? 447 //TODO: need drm gbm surface destroy & re-create.?
@@ -532,7 +552,7 @@ evas_outbuf_flush(Outbuf *ob, Tilebuf_Rect *rects EINA_UNUSED, Evas_Render_Mode
532 ob->info->callback.pre_swap(ob->info->callback.data, ob->evas); 552 ob->info->callback.pre_swap(ob->info->callback.data, ob->evas);
533 553
534// TODO: Check eglSwapBuffersWithDamage for gl_drm and apply 554// TODO: Check eglSwapBuffersWithDamage for gl_drm and apply
535#if 0 555//#if 0
536 if ((glsym_eglSwapBuffersWithDamage) && (ob->swap_mode != MODE_FULL)) 556 if ((glsym_eglSwapBuffersWithDamage) && (ob->swap_mode != MODE_FULL))
537 { 557 {
538 EGLint num = 0, *result = NULL, i = 0; 558 EGLint num = 0, *result = NULL, i = 0;
@@ -549,7 +569,7 @@ evas_outbuf_flush(Outbuf *ob, Tilebuf_Rect *rects EINA_UNUSED, Evas_Render_Mode
549 569
550 gw = ob->gl_context->w; 570 gw = ob->gl_context->w;
551 gh = ob->gl_context->h; 571 gh = ob->gl_context->h;
552 switch (ob->rot) 572 switch (ob->rotation)
553 { 573 {
554 case 0: 574 case 0:
555 result[i + 0] = r->x; 575 result[i + 0] = r->x;
@@ -589,7 +609,7 @@ evas_outbuf_flush(Outbuf *ob, Tilebuf_Rect *rects EINA_UNUSED, Evas_Render_Mode
589 } 609 }
590 } 610 }
591 else 611 else
592#endif 612//#endif
593 eglSwapBuffers(ob->egl.disp, ob->egl.surface[0]); 613 eglSwapBuffers(ob->egl.disp, ob->egl.surface[0]);
594 614
595 if (ob->info->callback.post_swap) 615 if (ob->info->callback.post_swap)
@@ -600,7 +620,7 @@ evas_outbuf_flush(Outbuf *ob, Tilebuf_Rect *rects EINA_UNUSED, Evas_Render_Mode
600 620
601 ob->priv.frame_cnt++; 621 ob->priv.frame_cnt++;
602 622
603 end: 623end:
604 //TODO: Need render unlock after drm page flip? 624 //TODO: Need render unlock after drm page flip?
605 glsym_evas_gl_preload_render_unlock(_evas_outbuf_make_current, ob); 625 glsym_evas_gl_preload_render_unlock(_evas_outbuf_make_current, ob);
606} 626}