aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Michael <cp.michael@samsung.com>2014-01-10 07:03:22 +0000
committerChris Michael <cp.michael@samsung.com>2014-01-29 15:27:23 +0000
commitc50fbc1e2cec57c71ebb2587f5f61b9c6cefc799 (patch)
tree7e58daebff6463cd0fadf98e8982cdb1376e5a66
parentExpose ecore_drm_fb functions as API functions (diff)
downloadefl-c50fbc1e2cec57c71ebb2587f5f61b9c6cefc799.tar.gz
Add code to initialize EGL (for hardware acceleration).
Add code to repaint outputs on page_flip or vblank events. Signed-off-by: Chris Michael <cp.michael@samsung.com>
-rw-r--r--src/lib/ecore_drm/ecore_drm_device.c165
1 files changed, 160 insertions, 5 deletions
diff --git a/src/lib/ecore_drm/ecore_drm_device.c b/src/lib/ecore_drm/ecore_drm_device.c
index 2135cab90e..db19a30d3f 100644
--- a/src/lib/ecore_drm/ecore_drm_device.c
+++ b/src/lib/ecore_drm/ecore_drm_device.c
@@ -5,16 +5,87 @@
#include "ecore_drm_private.h"
#include <dlfcn.h>
+#ifdef HAVE_GBM
+static Eina_Bool
+_ecore_drm_device_egl_config_get(Ecore_Drm_Device *dev, const EGLint *attribs, const EGLint *visual)
+{
+ EGLint c = 0, m = 0;
+ EGLConfig *cfgs;
+ int i = 0;
+
+ if (!eglGetConfigs(dev->egl.disp, NULL, 0, &c) || (c < 1))
+ return EINA_FALSE;
+
+ if (!(cfgs = calloc(c, sizeof(*cfgs)))) return EINA_FALSE;
+
+ if (!eglChooseConfig(dev->egl.disp, attribs, cfgs, c, &m))
+ {
+ free(cfgs);
+ return EINA_FALSE;
+ }
+
+ for (i = 0; i < m; i++)
+ {
+ EGLint id;
+
+ if (visual)
+ {
+ if (!eglGetConfigAttrib(dev->egl.disp, cfgs[i],
+ EGL_NATIVE_VISUAL_ID, &id))
+ continue;
+
+ if ((id != 0) && (id != *visual))
+ continue;
+ }
+
+ dev->egl.cfg = cfgs[i];
+ free(cfgs);
+ return EINA_TRUE;
+ }
+
+ free(cfgs);
+ return EINA_FALSE;
+}
+#endif
+
static void
-_ecore_drm_device_cb_page_flip(int fd, unsigned int frame, unsigned int sec, unsigned int usec, void *data)
+_ecore_drm_device_cb_page_flip(int fd EINA_UNUSED, unsigned int frame EINA_UNUSED, unsigned int sec EINA_UNUSED, unsigned int usec EINA_UNUSED, void *data)
{
+ Ecore_Drm_Output *output;
+
DBG("Drm Page Flip Event");
+
+ if (!(output = data)) return;
+
+ if (output->pending_flip)
+ {
+ ecore_drm_output_fb_release(output, output->current);
+ output->current = output->next;
+ output->next = NULL;
+ }
+
+ output->pending_flip = EINA_FALSE;
+ if (!output->pending_vblank) ecore_drm_output_repaint(output);
}
static void
-_ecore_drm_device_cb_vblank(int fd, unsigned int frame, unsigned int sec, unsigned int usec, void *data)
+_ecore_drm_device_cb_vblank(int fd EINA_UNUSED, unsigned int frame EINA_UNUSED, unsigned int sec EINA_UNUSED, unsigned int usec EINA_UNUSED, void *data)
{
+ Ecore_Drm_Sprite *sprite;
+ Ecore_Drm_Output *output;
+
DBG("Drm VBlank Event");
+
+ if (!(sprite = data)) return;
+
+ output = sprite->output;
+ output->pending_vblank = EINA_FALSE;
+
+ ecore_drm_output_fb_release(output, sprite->current_fb);
+ sprite->current_fb = sprite->next_fb;
+ sprite->next_fb = NULL;
+
+ if (!output->pending_flip) _ecore_drm_output_frame_finish(output);
}
static Eina_Bool
@@ -25,6 +96,8 @@ _ecore_drm_device_cb_event(void *data, Ecore_Fd_Handler *hdlr EINA_UNUSED)
if (!(dev = data)) return ECORE_CALLBACK_RENEW;
+ DBG("Drm Device Event");
+
memset(&ctx, 0, sizeof(ctx));
ctx.version = DRM_EVENT_CONTEXT_VERSION;
@@ -36,6 +109,25 @@ _ecore_drm_device_cb_event(void *data, Ecore_Fd_Handler *hdlr EINA_UNUSED)
return ECORE_CALLBACK_RENEW;
}
+static Eina_Bool
+_ecore_drm_device_cb_idle(void *data)
+{
+ Ecore_Drm_Device *dev;
+ Ecore_Drm_Output *output;
+ Eina_List *l;
+
+ if (!(dev = data)) return ECORE_CALLBACK_CANCEL;
+
+ EINA_LIST_FOREACH(dev->outputs, l, output)
+ {
+ output->need_repaint = EINA_TRUE;
+ if (output->repaint_scheduled) continue;
+ _ecore_drm_output_repaint_start(output);
+ }
+
+ return ECORE_CALLBACK_RENEW;
+}
+
/**
* @defgroup Ecore_Drm_Device_Group Device manipulation functions
*
@@ -176,7 +268,7 @@ ecore_drm_device_find(const char *name, const char *seat)
dev->seat = eina_stringshare_add(seat);
-// dev->format = GBM_FORMAT_XRGB8888;
+ dev->format = GBM_FORMAT_XRGB8888;
dev->use_hw_accel = EINA_FALSE;
}
}
@@ -272,18 +364,73 @@ ecore_drm_device_open(Ecore_Drm_Device *dev)
if ((dev->gbm = gbm_create_device(dev->drm.fd)))
{
+ EGLint major, minor, visual;
+ const EGLint attribs[] =
+ {
+ EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
+ EGL_RED_SIZE, 1, EGL_GREEN_SIZE, 1,
+ EGL_BLUE_SIZE, 1, EGL_ALPHA_SIZE, 0,
+ EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_NONE
+ };
+
dev->use_hw_accel = EINA_TRUE;
- dev->format = GBM_FORMAT_ARGB8888;
+ /* TODO: gbm_device_is_format_supported to check that
+ * argb can be used for scanout | rendering */
+ dev->format = GBM_FORMAT_XRGB8888;
+
+ dev->egl.disp = eglGetDisplay(dev->gbm);
+ if (dev->egl.disp == EGL_NO_DISPLAY)
+ {
+ ERR("Could not get egl display");
+ goto init_software;
+ }
+
+ if (!eglInitialize(dev->egl.disp, &major, &minor))
+ {
+ ERR("Could not initialize egl");
+ goto init_software;
+ }
+
+ visual = dev->format;
+ if (!_ecore_drm_device_egl_config_get(dev, attribs, &visual))
+ {
+ ERR("Could not get egl config");
+ goto init_software;
+ }
}
else
- WRN("Failed to create gbm device: %m");
+ {
+ WRN("Failed to create gbm device");
+ goto init_software;
+ }
}
+ else
+#endif
+ {
+ /* TODO: init software */
+init_software:
+ DBG("Init Software Engine");
+#ifdef HAVE_GBM
+ if (dev->egl.disp)
+ {
+ eglMakeCurrent(dev->egl.disp, EGL_NO_SURFACE, EGL_NO_SURFACE,
+ EGL_NO_CONTEXT);
+ eglTerminate(dev->egl.disp);
+ eglReleaseThread();
+ }
+
+ if (dev->gbm) gbm_device_destroy(dev->gbm);
+ dev->gbm = NULL;
#endif
+ }
dev->drm.hdlr =
ecore_main_fd_handler_add(dev->drm.fd, ECORE_FD_READ,
_ecore_drm_device_cb_event, dev, NULL, NULL);
+ dev->drm.idler =
+ ecore_idle_enterer_add(_ecore_drm_device_cb_idle, dev);
+
return EINA_TRUE;
}
@@ -307,6 +454,14 @@ ecore_drm_device_close(Ecore_Drm_Device *dev)
#ifdef HAVE_GBM
if (dev->use_hw_accel)
{
+ if (dev->egl.disp)
+ {
+ eglMakeCurrent(dev->egl.disp, EGL_NO_SURFACE, EGL_NO_SURFACE,
+ EGL_NO_CONTEXT);
+ eglTerminate(dev->egl.disp);
+ eglReleaseThread();
+ }
+
if (dev->gbm) gbm_device_destroy(dev->gbm);
dev->gbm = NULL;
}