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:
parent
c7ec2f9dac
commit
7e9a31aa4e
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
@ -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)
|
||||
|
@ -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,
|
||||
|
Loading…
x
Reference in New Issue
Block a user