devilhorns pushed a commit to branch master. http://git.enlightenment.org/core/efl.git/commit/?id=a83bb5e45d9b58788f7a98c2d3f74513495aff68
commit a83bb5e45d9b58788f7a98c2d3f74513495aff68 Author: Chris Michael <cp.mich...@samsung.com> Date: Thu Jun 4 11:52:22 2015 -0400 evas-gl-drm: Refactor gl_drm engine to not use dumb buffers @fix Signed-off-by: Chris Michael <cp.mich...@samsung.com> --- src/modules/evas/engines/gl_drm/evas_engine.c | 127 +++++++++++--------- src/modules/evas/engines/gl_drm/evas_engine.h | 3 +- src/modules/evas/engines/gl_drm/evas_outbuf.c | 162 +++++++++++++++----------- 3 files changed, 168 insertions(+), 124 deletions(-) diff --git a/src/modules/evas/engines/gl_drm/evas_engine.c b/src/modules/evas/engines/gl_drm/evas_engine.c index 835417c..ceddf5c 100644 --- a/src/modules/evas/engines/gl_drm/evas_engine.c +++ b/src/modules/evas/engines/gl_drm/evas_engine.c @@ -8,6 +8,10 @@ # error gl_drm should not get compiled if dlsym is not found on the system! #endif +#ifdef EVAS_CSERVE2 +# include "evas_cs2_private.h" +#endif + #define EVAS_GL_NO_GL_H_CHECK 1 #include "Evas_GL.h" @@ -40,6 +44,15 @@ struct _Native void *egl_surface; }; +/* local function prototype types */ +typedef void (*_eng_fn)(void); +typedef _eng_fn (*glsym_func_eng_fn)(); +typedef void (*glsym_func_void)(); +typedef void *(*glsym_func_void_ptr)(); +typedef int (*glsym_func_int)(); +typedef unsigned int (*glsym_func_uint)(); +typedef const char *(*glsym_func_const_char_ptr)(); + /* external dynamic loaded Evas_GL function pointers */ Evas_GL_Common_Image_Call glsym_evas_gl_common_image_ref = NULL; Evas_GL_Common_Image_Call glsym_evas_gl_common_image_unref = NULL; @@ -51,6 +64,7 @@ Evas_GL_Common_Context_Call glsym_evas_gl_common_image_all_unload = NULL; Evas_GL_Preload glsym_evas_gl_preload_init = NULL; Evas_GL_Preload glsym_evas_gl_preload_shutdown = NULL; EVGL_Engine_Call glsym_evgl_engine_shutdown = NULL; +EVGL_Current_Native_Context_Get_Call glsym_evgl_current_native_context_get = NULL; Evas_Gl_Symbols glsym_evas_gl_symbols = NULL; Evas_GL_Common_Context_New glsym_evas_gl_common_context_new = NULL; @@ -65,14 +79,7 @@ Evas_GL_Preload_Render_Call glsym_evas_gl_preload_render_lock = NULL; Evas_GL_Preload_Render_Call glsym_evas_gl_preload_render_unlock = NULL; Evas_GL_Preload_Render_Call glsym_evas_gl_preload_render_relax = NULL; -/* local function prototype types */ -typedef void (*_eng_fn)(void); -typedef _eng_fn (*glsym_func_eng_fn)(); -typedef void (*glsym_func_void)(); -typedef void *(*glsym_func_void_ptr)(); -typedef int (*glsym_func_int)(); -typedef unsigned int (*glsym_func_uint)(); -typedef const char *(*glsym_func_const_char_ptr)(); +glsym_func_void_ptr glsym_evas_gl_common_current_context_get = NULL; /* dynamic loaded local egl function pointers */ _eng_fn (*glsym_eglGetProcAddress)(const char *a) = NULL; @@ -163,7 +170,9 @@ gl_symbols(void) LINK2GENERIC(evas_gl_preload_init); LINK2GENERIC(evas_gl_preload_shutdown); LINK2GENERIC(evgl_engine_shutdown); + LINK2GENERIC(evgl_current_native_context_get); LINK2GENERIC(evas_gl_symbols); + LINK2GENERIC(evas_gl_common_current_context_get); #define FINDSYM(dst, sym, typ) \ if (glsym_eglGetProcAddress) { \ @@ -248,7 +257,7 @@ evgl_eng_display_get(void *data) } if (eng_get_ob(re)) - return (void*)eng_get_ob(re)->egl.disp; + return (void *)eng_get_ob(re)->egl.disp; else return NULL; } @@ -266,7 +275,7 @@ evgl_eng_evas_surface_get(void *data) } if (eng_get_ob(re)) - return (void*)eng_get_ob(re)->egl.surface[0]; + return (void *)eng_get_ob(re)->egl.surface[0]; else return NULL; } @@ -371,6 +380,9 @@ evgl_eng_native_window_destroy(void *data, void *native_window) } gbm_surface_destroy((struct gbm_surface *)native_window); + + native_window = NULL; + return 1; } @@ -468,7 +480,7 @@ evgl_eng_context_create(void *data, void *share_ctx, Evas_GL_Context_Version ver if (!context) { - ERR("Engine Context Creations Failed. Error: %#x.", eglGetError()); + ERR("eglMakeCurrent() failed! Error Code=%#x", eglGetError()); return NULL; } @@ -596,6 +608,8 @@ _native_cb_bind(void *data EINA_UNUSED, void *image) } else if (n->ns.type == EVAS_NATIVE_SURFACE_OPENGL) glBindTexture(GL_TEXTURE_2D, n->ns.data.opengl.texture_id); + + /* TODO: NATIVE_SURFACE_TBM and NATIVE_SURFACE_EVASGL */ } static void @@ -613,6 +627,8 @@ _native_cb_unbind(void *data EINA_UNUSED, void *image) } else if (n->ns.type == EVAS_NATIVE_SURFACE_OPENGL) glBindTexture(GL_TEXTURE_2D, 0); + + /* TODO: NATIVE_SURFACE_TBM and NATIVE_SURFACE_EVASGL */ } static void @@ -669,7 +685,6 @@ eng_gbm_init(Evas_Engine_Info_GL_Drm *info, int w, int h) if (!info) return EINA_FALSE; if (!(dev = info->info.dev)) return EINA_FALSE; - DBG("Create GBM Device"); if (!(info->info.gbm = gbm_create_device(dev->drm.fd))) { ERR("Coult not create gbm device: %m"); @@ -769,7 +784,7 @@ eng_setup(Evas *evas, void *in) if (!(re = epd->engine.data.output)) { Outbuf *ob; - Render_Engine_Merge_Mode merge_mode = MERGE_FULL; + Render_Engine_Merge_Mode merge_mode = MERGE_BOUNDING; if (!initted) { @@ -850,57 +865,45 @@ eng_setup(Evas *evas, void *in) (info->info.depth != eng_get_ob(re)->depth) || (info->info.destination_alpha != eng_get_ob(re)->destination_alpha)) { - Outbuf *ob; + Outbuf *ob, *ob_old; - eng_get_ob(re)->gl_context->references++; + ob_old = re->generic.software.ob; + re->generic.software.ob = NULL; gl_wins--; ob = evas_outbuf_new(info, epd->output.w, epd->output.h, swap_mode); - - evas_outbuf_free(eng_get_ob(re)); - re->generic.software.ob = NULL; + if (!ob) + { + if (ob_old) evas_outbuf_free(ob_old); + free(re); + return 0; + } evas_outbuf_use(ob); - if (ob) - { - ob->evas = evas; + if (ob_old) evas_outbuf_free(ob_old); - evas_render_engine_software_generic_update(&re->generic.software, ob, - epd->output.w, epd->output.h); + ob->evas = evas; - gl_wins++; - eng_get_ob(re)->gl_context->references--; - } + evas_render_engine_software_generic_update(&re->generic.software, ob, + epd->output.w, epd->output.h); + + gl_wins++; } else if ((eng_get_ob(re)->w != epd->output.w) || (eng_get_ob(re)->h != epd->output.h) || (info->info.rotation != eng_get_ob(re)->rotation)) { - Outbuf *ob; - - eng_get_ob(re)->gl_context->references++; - gl_wins--; - - evas_outbuf_free(eng_get_ob(re)); - re->generic.software.ob = NULL; - - eng_gbm_shutdown(eng_get_ob(re)->info); - if (!eng_gbm_init(info, epd->output.w, epd->output.h)) - return 0; - - ob = evas_outbuf_new(info, epd->output.w, epd->output.h, swap_mode); - - evas_outbuf_use(ob); - if (ob) - { - ob->evas = evas; - - evas_render_engine_software_generic_update(&re->generic.software, ob, - epd->output.w, epd->output.h); - - gl_wins++; - eng_get_ob(re)->gl_context->references--; - } + evas_outbuf_reconfigure(eng_get_ob(re), + epd->output.w, epd->output.h, + info->info.rotation, + info->info.depth); + if (re->generic.software.tb) + evas_common_tilebuf_free(re->generic.software.tb); + re->generic.software.tb = + evas_common_tilebuf_new(epd->output.w, epd->output.h); + if (re->generic.software.tb) + evas_common_tilebuf_set_tile_size(re->generic.software.tb, + TILESIZE, TILESIZE); } } } @@ -923,7 +926,8 @@ eng_setup(Evas *evas, void *in) return 0; } - evas_render_engine_software_generic_tile_strict_set(&re->generic.software, EINA_TRUE); + if (re->generic.software.tb) + evas_render_engine_software_generic_tile_strict_set(&re->generic.software, EINA_TRUE); if (!epd->engine.data.context) { @@ -1208,9 +1212,26 @@ eng_image_native_set(void *data, void *image, void *native) } } + /* TODO: NATIVE_SURFACE_TBM and NATIVE_SURFACE_EVASGL */ + return img; } +static void * +eng_gl_current_context_get(void *data EINA_UNUSED) +{ + EVGL_Context *ctx; + EVGLNative_Context context; + + ctx = glsym_evas_gl_common_current_context_get(); + if (!ctx) return NULL; + + context = glsym_evgl_current_native_context_get(ctx); + if (eglGetCurrentContext() == context) return ctx; + + return NULL; +} + /* module api functions */ static int module_open(Evas_Module *em) @@ -1246,10 +1267,12 @@ module_open(Evas_Module *em) EVAS_API_OVERRIDE(output_free, &func, eng_); EVAS_API_OVERRIDE(output_dump, &func, eng_); EVAS_API_OVERRIDE(image_native_set, &func, eng_); + EVAS_API_OVERRIDE(gl_current_context_get, &func, eng_); /* Mesa's EGL driver loads wayland egl by default. (called by eglGetProcaddr() ) * implicit env set (EGL_PLATFORM=drm) prevent that. */ setenv("EGL_PLATFORM", "drm", 1); + gl_symbols(); /* now advertise out own api */ diff --git a/src/modules/evas/engines/gl_drm/evas_engine.h b/src/modules/evas/engines/gl_drm/evas_engine.h index 3aa25e4..2892893 100644 --- a/src/modules/evas/engines/gl_drm/evas_engine.h +++ b/src/modules/evas/engines/gl_drm/evas_engine.h @@ -87,7 +87,6 @@ struct _Outbuf { int prev_age, frame_cnt; int curr, last, num; - Ecore_Drm_Fb *buffer[4]; struct gbm_bo *bo[4]; Eina_List *pending_writes; } priv; @@ -127,4 +126,6 @@ _re_wincheck(Outbuf *ob) return EINA_FALSE; } +extern unsigned int (*glsym_eglSwapBuffersWithDamage)(EGLDisplay a, void *b, const EGLint *d, EGLint c); + #endif diff --git a/src/modules/evas/engines/gl_drm/evas_outbuf.c b/src/modules/evas/engines/gl_drm/evas_outbuf.c index 9df628f..09f2981 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; static int win_count = 0; static void +_evas_outbuf_fb_cb_destroy(struct gbm_bo *bo, void *data) +{ + Ecore_Drm_Fb *fb; + + fb = data; + if (fb) + { + struct gbm_device *gbm; + + gbm = gbm_bo_get_device(bo); + drmModeRmFB(gbm_device_get_fd(gbm), fb->id); + free(fb); + } +} + +static Ecore_Drm_Fb * +_evas_outbuf_fb_get(Ecore_Drm_Device *dev, struct gbm_bo *bo) +{ + int ret; + Ecore_Drm_Fb *fb; + uint32_t format; + uint32_t handles[4], pitches[4], offsets[4]; + + fb = gbm_bo_get_user_data(bo); + if (fb) return fb; + + if (!(fb = calloc(1, sizeof(Ecore_Drm_Fb)))) return NULL; + + format = gbm_bo_get_format(bo); + + fb->w = gbm_bo_get_width(bo); + fb->h = gbm_bo_get_height(bo); + fb->hdl = gbm_bo_get_handle(bo).u32; + fb->stride = gbm_bo_get_stride(bo); + fb->size = fb->stride * fb->h; + + handles[0] = fb->hdl; + pitches[0] = fb->stride; + offsets[0] = 0; + + ret = drmModeAddFB2(dev->drm.fd, fb->w, fb->h, format, + handles, pitches, offsets, &(fb->id), 0); + if (ret) + ret = drmModeAddFB(dev->drm.fd, fb->w, fb->h, 24, 32, + fb->stride, fb->hdl, &(fb->id)); + + if (ret) ERR("FAILED TO ADD FB: %m"); + + gbm_bo_set_user_data(bo, fb, _evas_outbuf_fb_cb_destroy); + + return fb; +} + +static void _evas_outbuf_cb_pageflip(void *data) { Outbuf *ob; Ecore_Drm_Fb *fb; + struct gbm_bo *bo; if (!(ob = data)) return; - if ((fb = ob->priv.buffer[ob->priv.curr])) - { - fb->pending_flip = EINA_FALSE; - gbm_surface_release_buffer(ob->surface, ob->priv.bo[ob->priv.curr]); - } + bo = ob->priv.bo[ob->priv.curr]; + + fb = _evas_outbuf_fb_get(ob->info->info.dev, bo); + if (fb) fb->pending_flip = EINA_FALSE; + + gbm_surface_release_buffer(ob->surface, bo); ob->priv.last = ob->priv.curr; ob->priv.curr = (ob->priv.curr + 1) % ob->priv.num; @@ -26,15 +82,17 @@ _evas_outbuf_cb_pageflip(void *data) static void _evas_outbuf_buffer_swap(Outbuf *ob, Eina_Rectangle *rects, unsigned int count) { - Ecore_Drm_Fb *buff; - - buff = ob->priv.buffer[ob->priv.curr]; + Ecore_Drm_Fb *fb; ob->priv.bo[ob->priv.curr] = gbm_surface_lock_front_buffer(ob->surface); - ecore_drm_fb_dirty(buff, rects, count); - ecore_drm_fb_set(ob->info->info.dev, buff); - ecore_drm_fb_send(ob->info->info.dev, buff, _evas_outbuf_cb_pageflip, ob); + fb = _evas_outbuf_fb_get(ob->info->info.dev, ob->priv.bo[ob->priv.curr]); + if (fb) + { + ecore_drm_fb_dirty(fb, rects, count); + ecore_drm_fb_set(ob->info->info.dev, fb); + ecore_drm_fb_send(ob->info->info.dev, fb, _evas_outbuf_cb_pageflip, ob); + } } static Eina_Bool @@ -117,16 +175,6 @@ _evas_outbuf_egl_setup(Outbuf *ob) return EINA_FALSE; } - ob->egl.context[0] = - eglCreateContext(ob->egl.disp, ob->egl.config, context, ctx_attr); - if (ob->egl.context[0] == EGL_NO_CONTEXT) - { - ERR("eglCreateContext() fail. code=%#x", eglGetError()); - return EINA_FALSE; - } - - if (context == EGL_NO_CONTEXT) context = ob->egl.context[0]; - ob->egl.surface[0] = eglCreateWindowSurface(ob->egl.disp, ob->egl.config, (EGLNativeWindowType)ob->surface, NULL); @@ -137,6 +185,16 @@ _evas_outbuf_egl_setup(Outbuf *ob) return EINA_FALSE; } + ob->egl.context[0] = + eglCreateContext(ob->egl.disp, ob->egl.config, context, ctx_attr); + if (ob->egl.context[0] == EGL_NO_CONTEXT) + { + ERR("eglCreateContext() fail. code=%#x", eglGetError()); + return EINA_FALSE; + } + + if (context == EGL_NO_CONTEXT) context = ob->egl.context[0]; + if (eglMakeCurrent(ob->egl.disp, ob->egl.surface[0], ob->egl.surface[0], ob->egl.context[0]) == EGL_FALSE) { @@ -179,6 +237,8 @@ _evas_outbuf_egl_setup(Outbuf *ob) return EINA_FALSE; } + /* eng_gl_symbols(); */ + ob->gl_context = glsym_evas_gl_common_context_new(); if (!ob->gl_context) return EINA_FALSE; @@ -201,7 +261,6 @@ evas_outbuf_new(Evas_Engine_Info_GL_Drm *info, int w, int h, Render_Engine_Swap_ { Outbuf *ob; char *num; - int i = 0; /* try to allocate space for outbuf */ 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_ return NULL; } - for (; i < ob->priv.num; i++) - { - ob->priv.buffer[i] = - ecore_drm_fb_create(ob->info->info.dev, ob->w, ob->h); - if (!ob->priv.buffer[i]) break; - - DBG("Evas Engine Created Dumb Buffer"); - DBG("\tFb: %d", ob->priv.buffer[i]->id); - DBG("\tHandle: %d", ob->priv.buffer[i]->hdl); - DBG("\tStride: %d", ob->priv.buffer[i]->stride); - DBG("\tSize: %d", ob->priv.buffer[i]->size); - DBG("\tW: %d\tH: %d", - ob->priv.buffer[i]->w, ob->priv.buffer[i]->h); - } - - ecore_drm_fb_set(info->info.dev, ob->priv.buffer[0]); - return ob; } void evas_outbuf_free(Outbuf *ob) { - int i = 0, ref = 0; + int ref = 0; win_count--; evas_outbuf_use(ob); @@ -296,9 +338,6 @@ evas_outbuf_free(Outbuf *ob) context = EGL_NO_CONTEXT; } - for (; i < ob->priv.num; i++) - ecore_drm_fb_destroy(ob->priv.buffer[i]); - free(ob); } @@ -390,38 +429,19 @@ evas_outbuf_unsurf(Outbuf *ob) void evas_outbuf_reconfigure(Outbuf *ob, int w, int h, int rot, Outbuf_Depth depth) { - int i = 0; - - if (depth == OUTBUF_DEPTH_INHERIT) depth = ob->depth; + /* if (depth == OUTBUF_DEPTH_INHERIT) depth = ob->depth; */ /* check for changes */ - if ((ob->w == w) && (ob->h == h) && - (ob->destination_alpha == ob->info->info.destination_alpha) && - ((int)ob->rotation == rot) && (ob->depth == depth)) - return; + /* if ((ob->w == w) && (ob->h == h) && */ + /* (ob->destination_alpha == ob->info->info.destination_alpha) && */ + /* ((int)ob->rotation == rot) && (ob->depth == depth)) */ + /* return; */ ob->w = w; ob->h = h; ob->depth = depth; ob->rotation = rot; - - /* destroy the old buffers */ - for (; i < ob->priv.num; i++) - ecore_drm_fb_destroy(ob->priv.buffer[i]); - - for (i = 0; i < ob->priv.num; i++) - { - ob->priv.buffer[i] = - ecore_drm_fb_create(ob->info->info.dev, ob->w, ob->h); - if (!ob->priv.buffer[i]) - { - ERR("Failed to create buffer %d", i); - break; - } - } - evas_outbuf_use(ob); - glsym_evas_gl_common_context_resize(ob->gl_context, w, h, rot); //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 ob->info->callback.pre_swap(ob->info->callback.data, ob->evas); // TODO: Check eglSwapBuffersWithDamage for gl_drm and apply -#if 0 +//#if 0 if ((glsym_eglSwapBuffersWithDamage) && (ob->swap_mode != MODE_FULL)) { EGLint num = 0, *result = NULL, i = 0; @@ -549,7 +569,7 @@ evas_outbuf_flush(Outbuf *ob, Tilebuf_Rect *rects EINA_UNUSED, Evas_Render_Mode gw = ob->gl_context->w; gh = ob->gl_context->h; - switch (ob->rot) + switch (ob->rotation) { case 0: result[i + 0] = r->x; @@ -589,7 +609,7 @@ evas_outbuf_flush(Outbuf *ob, Tilebuf_Rect *rects EINA_UNUSED, Evas_Render_Mode } } else -#endif +//#endif eglSwapBuffers(ob->egl.disp, ob->egl.surface[0]); if (ob->info->callback.post_swap) @@ -600,7 +620,7 @@ evas_outbuf_flush(Outbuf *ob, Tilebuf_Rect *rects EINA_UNUSED, Evas_Render_Mode ob->priv.frame_cnt++; - end: +end: //TODO: Need render unlock after drm page flip? glsym_evas_gl_preload_render_unlock(_evas_outbuf_make_current, ob); } --