Fix DETA/ATTA with DRM (hopefully)

This commit is contained in:
jojo61 2020-01-07 22:22:07 +01:00
parent 2f0b1d0df9
commit 70b67f4466
3 changed files with 196 additions and 138 deletions

47
drm.c
View File

@ -23,6 +23,7 @@ struct _Drm_Render_
uint32_t connector_id, crtc_id, video_plane; uint32_t connector_id, crtc_id, video_plane;
uint32_t hdr_metadata; uint32_t hdr_metadata;
uint32_t mmWidth,mmHeight; // Size in mm uint32_t mmWidth,mmHeight; // Size in mm
uint32_t hdr_blob_id;
}; };
typedef struct _Drm_Render_ VideoRender; typedef struct _Drm_Render_ VideoRender;
@ -207,10 +208,10 @@ static int FindDevice(VideoRender * render)
fprintf(stderr, "FindDevice: cannot open /dev/dri/card0: %m\n"); fprintf(stderr, "FindDevice: cannot open /dev/dri/card0: %m\n");
return -errno; return -errno;
} }
drmSetMaster(render->fd_drm);
version = drmGetVersion(render->fd_drm); version = drmGetVersion(render->fd_drm);
fprintf(stderr, "FindDevice: open /dev/dri/card0: %i %s\n", version->name_len, version->name); fprintf(stderr, "FindDevice: open /dev/dri/card0: %s\n", version->name);
// check capability // check capability
if (drmGetCap(render->fd_drm, DRM_CAP_DUMB_BUFFER, &has_dumb) < 0 || has_dumb == 0) if (drmGetCap(render->fd_drm, DRM_CAP_DUMB_BUFFER, &has_dumb) < 0 || has_dumb == 0)
@ -375,8 +376,6 @@ static int FindDevice(VideoRender * render)
return 0; return 0;
} }
/// ///
/// Initialize video output module. /// Initialize video output module.
/// ///
@ -384,6 +383,7 @@ void VideoInitDrm()
{ {
int i; int i;
if (!(render = calloc(1, sizeof(*render)))) { if (!(render = calloc(1, sizeof(*render)))) {
Fatal(_("video/DRM: out of memory\n")); Fatal(_("video/DRM: out of memory\n"));
return; return;
@ -398,7 +398,7 @@ void VideoInitDrm()
PFNEGLGETPLATFORMDISPLAYEXTPROC get_platform_display = NULL; PFNEGLGETPLATFORMDISPLAYEXTPROC get_platform_display = NULL;
get_platform_display = get_platform_display =
(void *) eglGetProcAddress("eglGetPlatformDisplayEXT"); (void *) eglGetProcAddress("eglGetPlatformDisplay");
assert(get_platform_display != NULL); assert(get_platform_display != NULL);
eglDisplay = get_platform_display(EGL_PLATFORM_GBM_KHR, gbm.dev, NULL); eglDisplay = get_platform_display(EGL_PLATFORM_GBM_KHR, gbm.dev, NULL);
@ -418,7 +418,7 @@ void VideoInitDrm()
fprintf(stderr, "cannot allocate atomic request (%d): %m\n", errno); fprintf(stderr, "cannot allocate atomic request (%d): %m\n", errno);
return; return;
} }
printf("set CRTC %d of Connector %d aktiv\n",render->crtc_id,render->connector_id);
SetPropertyRequest(ModeReq, render->fd_drm, render->crtc_id, SetPropertyRequest(ModeReq, render->fd_drm, render->crtc_id,
DRM_MODE_OBJECT_CRTC, "MODE_ID", modeID); DRM_MODE_OBJECT_CRTC, "MODE_ID", modeID);
SetPropertyRequest(ModeReq, render->fd_drm, render->connector_id, SetPropertyRequest(ModeReq, render->fd_drm, render->connector_id,
@ -430,7 +430,7 @@ void VideoInitDrm()
fprintf(stderr, "cannot set atomic mode (%d): %m\n", errno); fprintf(stderr, "cannot set atomic mode (%d): %m\n", errno);
if (drmModeDestroyPropertyBlob(render->fd_drm, modeID) != 0) if (drmModeDestroyPropertyBlob(render->fd_drm, modeID) != 0)
fprintf(stderr, "cannot destroy prperty blob (%d): %m\n", errno); fprintf(stderr, "cannot destroy property blob (%d): %m\n", errno);
drmModeAtomicFree(ModeReq); drmModeAtomicFree(ModeReq);
@ -438,6 +438,7 @@ void VideoInitDrm()
void get_drm_aspect(int *num,int *den) void get_drm_aspect(int *num,int *den)
{ {
Debug(3,"mmHeight %d mmWidth %d VideoHeight %d VideoWidth %d\n",render->mmHeight,render->mmWidth,VideoWindowHeight,VideoWindowWidth);
*num = VideoWindowWidth * render->mmHeight; *num = VideoWindowWidth * render->mmHeight;
*den = VideoWindowHeight * render->mmWidth; *den = VideoWindowHeight * render->mmWidth;
} }
@ -456,6 +457,7 @@ void InitBo(int bpp) {
assert(gbm.surface != NULL); assert(gbm.surface != NULL);
eglSurface = eglCreateWindowSurface (eglDisplay, eglConfig, gbm.surface, NULL); eglSurface = eglCreateWindowSurface (eglDisplay, eglConfig, gbm.surface, NULL);
assert(eglSurface != NULL); assert(eglSurface != NULL);
} }
static struct gbm_bo *previous_bo = NULL; static struct gbm_bo *previous_bo = NULL;
@ -526,6 +528,7 @@ static void drm_swap_buffers () {
} }
previous_bo = bo; previous_bo = bo;
previous_fb = fb; previous_fb = fb;
} }
static void drm_clean_up () { static void drm_clean_up () {
@ -533,20 +536,36 @@ static void drm_clean_up () {
if (!render) if (!render)
return; return;
Debug(3,"drm clean up\n");
drmModeSetCrtc (render->fd_drm, render->saved_crtc->crtc_id, render->saved_crtc->buffer_id,
render->saved_crtc->x, render->saved_crtc->y, &render->connector_id, 1, &render->saved_crtc->mode);
drmModeFreeCrtc (render->saved_crtc);
if (previous_bo) { if (previous_bo) {
drmModeRmFB (render->fd_drm, previous_fb); drmModeRmFB (render->fd_drm, previous_fb);
gbm_surface_release_buffer (gbm.surface, previous_bo); gbm_surface_release_buffer (gbm.surface, previous_bo);
} }
// eglDestroySurface (display, eglSurface); drmModeSetCrtc (render->fd_drm, render->saved_crtc->crtc_id, render->saved_crtc->buffer_id,
render->saved_crtc->x, render->saved_crtc->y, &render->connector_id, 1, &render->saved_crtc->mode);
drmModeFreeCrtc (render->saved_crtc);
if (render->hdr_blob_id)
drmModeDestroyPropertyBlob(render->fd_drm, render->hdr_blob_id);
render->hdr_blob_id = 0;
eglDestroySurface (eglDisplay, eglSurface);
EglCheck();
gbm_surface_destroy (gbm.surface); gbm_surface_destroy (gbm.surface);
// eglDestroyContext (display, context); eglDestroyContext (eglDisplay, eglContext);
// eglTerminate (display); EglCheck();
eglDestroyContext (eglDisplay, eglSharedContext);
EglCheck();
eglTerminate (eglDisplay);
EglCheck();
gbm_device_destroy (gbm.dev); gbm_device_destroy (gbm.dev);
drmDropMaster(render->fd_drm);
close (render->fd_drm); close (render->fd_drm);
free(render);
} }

17
hdr.c
View File

@ -330,7 +330,6 @@ static void set_hdr_metadata(int color,int trc, AVFrameSideData *sd1, AVFrameSid
struct weston_colorspace *cs; struct weston_colorspace *cs;
enum hdr_metadata_eotf eotf; enum hdr_metadata_eotf eotf;
struct hdr_output_metadata data; struct hdr_output_metadata data;
static uint32_t blob_id = 0;
int ret,MaxCLL=1500,MaxFALL=400; int ret,MaxCLL=1500,MaxFALL=400;
int max_lum=4000,min_lum=0050; int max_lum=4000,min_lum=0050;
struct AVMasteringDisplayMetadata *md = NULL; struct AVMasteringDisplayMetadata *md = NULL;
@ -378,8 +377,8 @@ static void set_hdr_metadata(int color,int trc, AVFrameSideData *sd1, AVFrameSid
old_color = color; old_color = color;
old_trc = trc; old_trc = trc;
if (blob_id) if (render->hdr_blob_id)
drmModeDestroyPropertyBlob(render->fd_drm, blob_id); drmModeDestroyPropertyBlob(render->fd_drm, render->hdr_blob_id);
switch(trc) { switch(trc) {
case AVCOL_TRC_BT709: // 1 case AVCOL_TRC_BT709: // 1
@ -468,21 +467,21 @@ static void set_hdr_metadata(int color,int trc, AVFrameSideData *sd1, AVFrameSid
ret = drmModeCreatePropertyBlob(render->fd_drm, &data, sizeof(data), &blob_id); ret = drmModeCreatePropertyBlob(render->fd_drm, &data, sizeof(data), &render->hdr_blob_id);
if (ret) { if (ret) {
printf("DRM: HDR metadata: failed blob create \n"); printf("DRM: HDR metadata: failed blob create \n");
blob_id = 0; render->hdr_blob_id = 0;
return; return;
} }
ret = drmModeConnectorSetProperty(render->fd_drm, render->connector_id, ret = drmModeConnectorSetProperty(render->fd_drm, render->connector_id,
render->hdr_metadata, blob_id); render->hdr_metadata, render->hdr_blob_id);
if (ret) { if (ret) {
printf("DRM: HDR metadata: failed property set %d\n",ret); printf("DRM: HDR metadata: failed property set %d\n",ret);
if (blob_id) if (render->hdr_blob_id)
drmModeDestroyPropertyBlob(render->fd_drm, blob_id); drmModeDestroyPropertyBlob(render->fd_drm, render->hdr_blob_id);
blob_id = 0; render->hdr_blob_id = 0;
return; return;
} }
m_need_modeset = 1; m_need_modeset = 1;

242
video.c
View File

@ -551,6 +551,56 @@ static void X11DPMSReenable(xcb_connection_t *);
static void X11DPMSDisable(xcb_connection_t *); static void X11DPMSDisable(xcb_connection_t *);
#endif #endif
char *eglErrorString(EGLint error)
{
switch (error) {
case EGL_SUCCESS:
return "No error";
case EGL_NOT_INITIALIZED:
return "EGL not initialized or failed to initialize";
case EGL_BAD_ACCESS:
return "Resource inaccessible";
case EGL_BAD_ALLOC:
return "Cannot allocate resources";
case EGL_BAD_ATTRIBUTE:
return "Unrecognized attribute or attribute value";
case EGL_BAD_CONTEXT:
return "Invalid EGL context";
case EGL_BAD_CONFIG:
return "Invalid EGL frame buffer configuration";
case EGL_BAD_CURRENT_SURFACE:
return "Current surface is no longer valid";
case EGL_BAD_DISPLAY:
return "Invalid EGL display";
case EGL_BAD_SURFACE:
return "Invalid surface";
case EGL_BAD_MATCH:
return "Inconsistent arguments";
case EGL_BAD_PARAMETER:
return "Invalid argument";
case EGL_BAD_NATIVE_PIXMAP:
return "Invalid native pixmap";
case EGL_BAD_NATIVE_WINDOW:
return "Invalid native window";
case EGL_CONTEXT_LOST:
return "Context lost";
}
return "Unknown error ";
}
///
/// egl check error.
///
#define EglCheck(void) \
{\
EGLint err;\
\
if ((err = eglGetError()) != EGL_SUCCESS) {\
Debug(3, "video/egl: %s:%d error %d %s\n", __FILE__,__LINE__,err,eglErrorString(err));\
}\
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// DRM Helper Functions // DRM Helper Functions
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -657,6 +707,8 @@ static void VideoUpdateOutput(AVRational input_aspect_ratio, int input_width, in
#ifdef USE_DRM #ifdef USE_DRM
get_drm_aspect(&display_aspect_ratio.num,&display_aspect_ratio.den); get_drm_aspect(&display_aspect_ratio.num,&display_aspect_ratio.den);
#else #else
Debug(3,"mmHeight %d mm Width %d VideoHeight %d VideoWidth %d\n",VideoScreen->height_in_millimeters,VideoScreen->width_in_millimeters,
VideoScreen->height_in_pixels,VideoScreen->width_in_pixels);
display_aspect_ratio.num = VideoScreen->width_in_pixels * VideoScreen->height_in_millimeters; display_aspect_ratio.num = VideoScreen->width_in_pixels * VideoScreen->height_in_millimeters;
display_aspect_ratio.den = VideoScreen->height_in_pixels * VideoScreen->width_in_millimeters; display_aspect_ratio.den = VideoScreen->height_in_pixels * VideoScreen->width_in_millimeters;
#endif #endif
@ -829,54 +881,6 @@ static PFNGLXSWAPINTERVALSGIPROC GlxSwapIntervalSGI;
}\ }\
} }
char *eglErrorString(EGLint error)
{
switch (error) {
case EGL_SUCCESS:
return "No error";
case EGL_NOT_INITIALIZED:
return "EGL not initialized or failed to initialize";
case EGL_BAD_ACCESS:
return "Resource inaccessible";
case EGL_BAD_ALLOC:
return "Cannot allocate resources";
case EGL_BAD_ATTRIBUTE:
return "Unrecognized attribute or attribute value";
case EGL_BAD_CONTEXT:
return "Invalid EGL context";
case EGL_BAD_CONFIG:
return "Invalid EGL frame buffer configuration";
case EGL_BAD_CURRENT_SURFACE:
return "Current surface is no longer valid";
case EGL_BAD_DISPLAY:
return "Invalid EGL display";
case EGL_BAD_SURFACE:
return "Invalid surface";
case EGL_BAD_MATCH:
return "Inconsistent arguments";
case EGL_BAD_PARAMETER:
return "Invalid argument";
case EGL_BAD_NATIVE_PIXMAP:
return "Invalid native pixmap";
case EGL_BAD_NATIVE_WINDOW:
return "Invalid native window";
case EGL_CONTEXT_LOST:
return "Context lost";
}
return "Unknown error ";
}
///
/// egl check error.
///
#define EglCheck(void) \
{\
EGLint err;\
\
if ((err = eglGetError()) != EGL_SUCCESS) {\
Debug(3, "video/egl: %s:%d error %d %s\n", __FILE__,__LINE__,err,eglErrorString(err));\
}\
}
@ -978,6 +982,7 @@ static void EglInit(void)
XVisualInfo *vi = NULL; XVisualInfo *vi = NULL;
#ifdef PLACEBO #ifdef PLACEBO
return; return;
#endif #endif
@ -1016,7 +1021,7 @@ static void EglInit(void)
if (!glXQueryVersion(XlibDisplay, &major, &minor)) { if (!glXQueryVersion(XlibDisplay, &major, &minor)) {
Fatal(_("video/glx: no GLX support\n")); Fatal(_("video/glx: no GLX support\n"));
} }
Info(_("video/glx: glx version %d.%d\n"), major, minor); Debug(3,"video/glx: glx version %d.%d\n", major, minor);
// //
// check which extension are supported // check which extension are supported
@ -1154,6 +1159,7 @@ static void EglInit(void)
static void EglInit(void) static void EglInit(void)
{ {
int redSize, greenSize, blueSize, alphaSize; int redSize, greenSize, blueSize, alphaSize;
static int glewdone = 0;
#ifdef PLACEBO #ifdef PLACEBO
return; return;
@ -1163,11 +1169,14 @@ static void EglInit(void)
// create egl context // create egl context
setenv("MESA_GL_VERSION_OVERRIDE","3.3",0); setenv("MESA_GL_VERSION_OVERRIDE","3.3",0);
make_egl(); make_egl();
GLenum err = glewInit();
if (!glewdone) {
GLenum err = glewInit();
glewdone = 1;
if (err != GLEW_OK) { if (err != GLEW_OK) {
Debug(3, "Error: %s\n", glewGetErrorString(err)); Debug(3, "Error: %s\n", glewGetErrorString(err));
} }
}
eglGetConfigAttrib(eglDisplay, eglConfig, EGL_BLUE_SIZE, &blueSize); eglGetConfigAttrib(eglDisplay, eglConfig, EGL_BLUE_SIZE, &blueSize);
eglGetConfigAttrib(eglDisplay, eglConfig, EGL_RED_SIZE, &redSize); eglGetConfigAttrib(eglDisplay, eglConfig, EGL_RED_SIZE, &redSize);
@ -1192,7 +1201,7 @@ static void EglInit(void)
static void EglExit(void) static void EglExit(void)
{ {
Debug(3, "video/egl: %s\n", __FUNCTION__); Debug(3, "video/egl: %s\n", __FUNCTION__);
#ifdef PLACEBO #if defined PLACEBO
return; return;
#endif #endif
@ -1215,11 +1224,7 @@ static void EglExit(void)
GlxCheck(); GlxCheck();
glxContext = NULL; glxContext = NULL;
} }
if (glxThreadContext) {
glXDestroyContext(XlibDisplay, glxThreadContext);
GlxCheck();
glxThreadContext = NULL;
}
if (glxSharedContext) { if (glxSharedContext) {
glXDestroyContext(XlibDisplay, glxSharedContext); glXDestroyContext(XlibDisplay, glxSharedContext);
GlxCheck(); GlxCheck();
@ -1230,20 +1235,26 @@ static void EglExit(void)
// if currently used, set to none // if currently used, set to none
eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
} }
#ifndef USE_DRM
if (eglSharedContext) { if (eglSharedContext) {
eglDestroyContext(eglDisplay, eglSharedContext); eglDestroyContext(eglDisplay, eglSharedContext);
EglCheck(); EglCheck();
} }
if (eglContext) { if (eglContext) {
eglDestroyContext(eglDisplay, eglContext); eglDestroyContext(eglDisplay, eglContext);
EglCheck(); EglCheck();
eglContext = NULL;
} }
if (eglThreadContext) {
eglDestroyContext(eglDisplay, eglThreadContext);
EglCheck();
}
eglTerminate(eglDisplay); eglTerminate(eglDisplay);
#endif #endif
#ifdef USE_DRM
drm_clean_up();
#endif
#endif
} }
#endif #endif
@ -2112,6 +2123,7 @@ static void CuvidDelHwDecoder(CuvidDecoder * decoder)
static int CuvidGlxInit( __attribute__((unused)) static int CuvidGlxInit( __attribute__((unused))
const char *display_name) const char *display_name)
{ {
#ifndef PLACEBO #ifndef PLACEBO
EglInit(); EglInit();
@ -4889,6 +4901,7 @@ void VideoOsdExit(void)
{ {
OsdDirtyWidth = 0; OsdDirtyWidth = 0;
OsdDirtyHeight = 0; OsdDirtyHeight = 0;
VideoOsdClear();
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -5077,29 +5090,7 @@ void pl_log_intern(void *stream, enum pl_log_level level, const char *msg)
printf("%5s: %s\n", prefix[level], msg); printf("%5s: %s\n", prefix[level], msg);
} }
void delete_placebo()
{
Debug(3, "delete placebo\n");
if (p == NULL)
return;
if (osdoverlay.plane.texture)
pl_tex_destroy(p->gpu, &osdoverlay.plane.texture);
pl_renderer_destroy(&p->renderer);
if (p->renderertest) {
pl_renderer_destroy(&p->renderertest);
p->renderertest = NULL;
}
pl_swapchain_destroy(&p->swapchain);
vkDestroySurfaceKHR(p->vk_inst->instance, p->pSurface, NULL);
pl_vk_inst_destroy(&p->vk_inst);
// pl_vulkan_destroy(&p->vk);
pl_context_destroy(&p->ctx);
free(p);
p = NULL;
}
void InitPlacebo() void InitPlacebo()
{ {
@ -5199,11 +5190,17 @@ void InitPlacebo()
/// ///
/// Video render thread. /// Video render thread.
/// ///
void delete_decode() {
Debug(3,"decoder thread exit\n");
}
static void *VideoDisplayHandlerThread(void *dummy) static void *VideoDisplayHandlerThread(void *dummy)
{ {
prctl(PR_SET_NAME, "cuvid video", 0, 0, 0); prctl(PR_SET_NAME, "video decode", 0, 0, 0);
sleep(2); sleep(2);
pthread_cleanup_push(delete_decode, NULL);
for (;;) { for (;;) {
// fix dead-lock with CuvidExit // fix dead-lock with CuvidExit
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
@ -5212,10 +5209,49 @@ static void *VideoDisplayHandlerThread(void *dummy)
VideoUsedModule->DisplayHandlerThread(); VideoUsedModule->DisplayHandlerThread();
} }
pthread_cleanup_pop(NULL);
return dummy; return dummy;
} }
void exit_display()
{
#ifdef PLACEBO
Debug(3, "delete placebo\n");
if (p == NULL)
return;
if (osdoverlay.plane.texture)
pl_tex_destroy(p->gpu, &osdoverlay.plane.texture);
pl_renderer_destroy(&p->renderer);
if (p->renderertest) {
pl_renderer_destroy(&p->renderertest);
p->renderertest = NULL;
}
pl_swapchain_destroy(&p->swapchain);
vkDestroySurfaceKHR(p->vk_inst->instance, p->pSurface, NULL);
pl_vk_inst_destroy(&p->vk_inst);
// pl_vulkan_destroy(&p->vk);
pl_context_destroy(&p->ctx);
free(p);
p = NULL;
#endif
#ifdef CUVID
if (glxThreadContext) {
glXDestroyContext(XlibDisplay, glxThreadContext);
GlxCheck();
glxThreadContext = NULL;
}
#else
if (eglThreadContext) {
eglDestroyContext(eglDisplay, eglThreadContext);
EglCheck();
eglThreadContext = NULL;
}
#endif
Debug(3,"display thread exit\n");
}
static void *VideoHandlerThread(void *dummy) static void *VideoHandlerThread(void *dummy)
{ {
@ -5224,12 +5260,10 @@ static void *VideoHandlerThread(void *dummy)
EGL_NONE EGL_NONE
}; };
prctl(PR_SET_NAME, "cuvid video display", 0, 0, 0); prctl(PR_SET_NAME, "video display", 0, 0, 0);
#ifdef PLACEBO #ifdef PLACEBO
InitPlacebo(); InitPlacebo();
pthread_cleanup_push(delete_placebo, NULL);
#else #else
#ifdef CUVID #ifdef CUVID
if (EglEnabled) { if (EglEnabled) {
@ -5247,21 +5281,21 @@ static void *VideoHandlerThread(void *dummy)
eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglThreadContext); eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglThreadContext);
#endif #endif
#endif #endif
pthread_cleanup_push(exit_display, NULL);
for (;;) { for (;;) {
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
pthread_testcancel(); pthread_testcancel();
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
#ifndef USE_DRM
VideoPollEvent(); VideoPollEvent();
#endif
// first_time = GetusTicks(); // first_time = GetusTicks();
CuvidSyncDisplayFrame(); CuvidSyncDisplayFrame();
// printf("syncdisplayframe exec %d\n",(GetusTicks()-first_time)/1000); // printf("syncdisplayframe exec %d\n",(GetusTicks()-first_time)/1000);
} }
#ifdef PLACEBO
pthread_cleanup_pop(NULL); pthread_cleanup_pop(NULL);
#endif
return dummy; return dummy;
} }
@ -5276,7 +5310,7 @@ static void VideoThreadInit(void)
#ifdef CUVID #ifdef CUVID
glXMakeCurrent(XlibDisplay, None, NULL); glXMakeCurrent(XlibDisplay, None, NULL);
#else #else
eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, eglContext); // eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, eglContext);
#endif #endif
#endif #endif
pthread_mutex_init(&VideoMutex, NULL); pthread_mutex_init(&VideoMutex, NULL);
@ -5301,19 +5335,20 @@ static void VideoThreadExit(void)
// FIXME: can't cancel locked // FIXME: can't cancel locked
if (pthread_cancel(VideoThread)) { if (pthread_cancel(VideoThread)) {
Error(_("video: can't queue cancel video display thread\n")); Debug(3,"video: can't queue cancel video display thread\n");
}
usleep(200000); // 200ms
if (pthread_join(VideoThread, &retval) || retval != PTHREAD_CANCELED) {
Debug(3,"video: can't cancel video decoder thread\n");
} }
if (pthread_join(VideoThread, &retval) || retval != PTHREAD_CANCELED) {
Error(_("video: can't cancel video display thread\n"));
}
if (VideoDisplayThread) { if (VideoDisplayThread) {
if (pthread_cancel(VideoDisplayThread)) { if (pthread_cancel(VideoDisplayThread)) {
Error(_("video: can't queue cancel video display thread\n")); Debug(3,"video: can't queue cancel video display thread\n");
} }
usleep(200000); // 200ms usleep(200000); // 200ms
if (pthread_join(VideoDisplayThread, &retval) || retval != PTHREAD_CANCELED) { if (pthread_join(VideoDisplayThread, &retval) || retval != PTHREAD_CANCELED) {
Error(_("video: can't cancel video display thread\n")); Debug(3,"video: can't cancel video display thread\n");
} }
VideoDisplayThread = 0; VideoDisplayThread = 0;
} }
@ -5324,8 +5359,10 @@ static void VideoThreadExit(void)
pthread_mutex_destroy(&OSDMutex); pthread_mutex_destroy(&OSDMutex);
#ifndef PLACEBO #ifndef PLACEBO
if (OSDtexture) if (OSDtexture)
glDeleteTextures(1, &OSDtexture); glDeleteTextures(1, &OSDtexture);
if (gl_prog_osd) { if (gl_prog_osd) {
glDeleteProgram(gl_prog_osd); glDeleteProgram(gl_prog_osd);
gl_prog_osd = 0; gl_prog_osd = 0;
@ -5334,7 +5371,9 @@ static void VideoThreadExit(void)
glDeleteProgram(gl_prog); glDeleteProgram(gl_prog);
gl_prog = 0; gl_prog = 0;
} }
#endif #endif
} }
} }
@ -6699,6 +6738,7 @@ void VideoExit(void)
if (!XlibDisplay) { // no init or failed if (!XlibDisplay) { // no init or failed
return; return;
} }
// //
// Reenable screensaver / DPMS. // Reenable screensaver / DPMS.
// //
@ -6751,9 +6791,7 @@ void VideoExit(void)
Connection = 0; Connection = 0;
} }
#endif #endif
#ifdef USE_DRM
drm_clean_up();
#endif
} }
#ifdef USE_DRM #ifdef USE_DRM
@ -6762,6 +6800,8 @@ int GlxInitopengl () {
EGL_CONTEXT_CLIENT_VERSION, 3, EGL_CONTEXT_CLIENT_VERSION, 3,
EGL_NONE EGL_NONE
}; };
while (!eglSharedContext)
sleep(1);
if (!eglOSDContext) { if (!eglOSDContext) {
eglOSDContext = eglCreateContext(eglDisplay, eglConfig, eglSharedContext, contextAttrs); eglOSDContext = eglCreateContext(eglDisplay, eglConfig, eglSharedContext, contextAttrs);