uterm_video: allow explicitely activating GL ctx

We may have to use multiple GL contexts if we mix DRM and fbdev devices.
Therefore, we need explicit GL-ctx management.
We now allow to explicitely activate a specific GL context. This means,
the user needs to use the right GL context before he creates textures or
similar.

Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
This commit is contained in:
David Herrmann 2012-04-25 17:35:03 +02:00
parent c7ec2f9dac
commit 7e9a31aa4e
5 changed files with 55 additions and 13 deletions

View File

@ -122,6 +122,10 @@ static int setup_app(struct kmscon_app *app)
if (ret)
goto err_app;
ret = uterm_video_use(app->video);
if (ret)
goto err_app;
ret = kmscon_input_new(&app->input);
if (ret)
goto err_app;

View File

@ -183,6 +183,7 @@ void uterm_video_ref(struct uterm_video *video);
void uterm_video_unref(struct uterm_video *video);
void uterm_video_segfault(struct uterm_video *video);
int uterm_video_use(struct uterm_video *video);
struct uterm_display *uterm_video_get_displays(struct uterm_video *video);
int uterm_video_register_cb(struct uterm_video *video, uterm_video_cb cb,
void *data);

View File

@ -60,6 +60,7 @@ struct video_ops {
int (*init) (struct uterm_video *video);
void (*destroy) (struct uterm_video *video);
void (*segfault) (struct uterm_video *video);
int (*use) (struct uterm_video *video);
int (*poll) (struct uterm_video *video, int mask);
void (*sleep) (struct uterm_video *video);
int (*wake_up) (struct uterm_video *video);
@ -288,4 +289,9 @@ static inline bool video_need_hotplug(const struct uterm_video *video)
.action = (act), \
})
static inline int video_do_use(struct uterm_video *video)
{
return VIDEO_CALL(video->ops->use, 0, video);
}
#endif /* UTERM_INTERNAL_H */

View File

@ -518,6 +518,14 @@ void uterm_video_segfault(struct uterm_video *video)
VIDEO_CALL(video->ops->segfault, 0, video);
}
int uterm_video_use(struct uterm_video *video)
{
if (!video)
return -EINVAL;
return video_do_use(video);
}
struct uterm_display *uterm_video_get_displays(struct uterm_video *video)
{
if (!video)

View File

@ -163,6 +163,10 @@ static int display_activate(struct uterm_display *disp, struct uterm_mode *mode)
if (display_is_online(disp))
return 0;
ret = video_do_use(disp->video);
if (ret)
return ret;
log_info("activating display %p to %ux%u", disp,
mode->drm.info.hdisplay, mode->drm.info.vdisplay);
@ -251,6 +255,8 @@ err_saved:
static void display_deactivate(struct uterm_display *disp)
{
int ret;
if (!display_is_online(disp))
return;
@ -269,6 +275,10 @@ static void display_deactivate(struct uterm_display *disp)
disp->drm.saved_crtc = NULL;
}
ret = video_do_use(disp->video);
if (ret)
return;
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glDeleteFramebuffers(1, &disp->drm.fb);
destroy_rb(disp, &disp->drm.rb[1]);
@ -344,9 +354,15 @@ static int display_set_dpms(struct uterm_display *disp, int state)
static int display_use(struct uterm_display *disp)
{
int ret;
if (!display_is_online(disp))
return -EINVAL;
ret = video_do_use(disp->video);
if (ret)
return ret;
/* TODO: we need triple buffering as a VSYNC may still be pending */
glBindFramebuffer(GL_FRAMEBUFFER, disp->drm.fb);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
@ -622,18 +638,6 @@ static int init_device(struct uterm_video *video, struct udev_device *dev)
goto err_disp;
}
/*
* We allow only one global video object. See uterm_video_new for the
* reasons. If we every change this we need proper context-management
* and should remove this call here.
*/
if (!eglMakeCurrent(drm->disp, EGL_NO_SURFACE, EGL_NO_SURFACE,
drm->ctx)) {
log_err("cannot activate egl context");
ret = -EFAULT;
goto err_ctx;
}
ret = ev_eloop_new_fd(video->eloop, &drm->efd, drm->fd,
EV_READABLE, event, video);
if (ret)
@ -755,7 +759,11 @@ static void video_destroy(struct uterm_video *video)
log_info("free drm device");
ev_eloop_rm_fd(drm->efd);
eglMakeCurrent(drm->disp, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
if (eglGetCurrentContext() == drm->ctx)
eglMakeCurrent(drm->disp,
EGL_NO_SURFACE,
EGL_NO_SURFACE,
EGL_NO_CONTEXT);
eglDestroyContext(drm->disp, drm->ctx);
eglTerminate(drm->disp);
gbm_device_destroy(drm->gbm);
@ -763,6 +771,20 @@ static void video_destroy(struct uterm_video *video)
close(drm->fd);
}
static int video_use(struct uterm_video *video)
{
if (eglGetCurrentContext() == video->drm.ctx)
return 0;
if (!eglMakeCurrent(video->drm.disp, EGL_NO_SURFACE, EGL_NO_SURFACE,
video->drm.ctx)) {
log_err("cannot activate egl context");
return -EFAULT;
}
return 0;
}
static int hotplug(struct uterm_video *video)
{
drmModeRes *res;
@ -931,6 +953,7 @@ const struct video_ops drm_video_ops = {
.init = video_init,
.destroy = video_destroy,
.segfault = NULL, /* TODO: reset all saved CRTCs on segfault */
.use = video_use,
.poll = video_poll,
.sleep = video_sleep,
.wake_up = video_wake_up,