From owner-freebsd-multimedia@FreeBSD.ORG Fri Oct 21 18:57:20 2011 Return-Path: Delivered-To: freebsd-multimedia@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id C5CE51065676; Fri, 21 Oct 2011 18:57:20 +0000 (UTC) (envelope-from nox@jelal.kn-bremen.de) Received: from smtp.kn-bremen.de (gelbbaer.kn-bremen.de [78.46.108.116]) by mx1.freebsd.org (Postfix) with ESMTP id 724648FC08; Fri, 21 Oct 2011 18:57:20 +0000 (UTC) Received: by smtp.kn-bremen.de (Postfix, from userid 10) id C688D1E00249; Fri, 21 Oct 2011 20:57:18 +0200 (CEST) Received: from triton8.kn-bremen.de (noident@localhost [127.0.0.1]) by triton8.kn-bremen.de (8.14.4/8.14.3) with ESMTP id p9LIv4sS048215; Fri, 21 Oct 2011 20:57:04 +0200 (CEST) (envelope-from nox@triton8.kn-bremen.de) Received: (from nox@localhost) by triton8.kn-bremen.de (8.14.4/8.14.3/Submit) id p9LIv3gY048214; Fri, 21 Oct 2011 20:57:03 +0200 (CEST) (envelope-from nox) From: Juergen Lock Date: Fri, 21 Oct 2011 20:57:03 +0200 To: Juergen Lock Message-ID: <20111021185703.GA48178@triton8.kn-bremen.de> References: <20111014215450.GA74605@triton8.kn-bremen.de> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20111014215450.GA74605@triton8.kn-bremen.de> User-Agent: Mutt/1.5.21 (2010-09-15) Cc: freebsd-multimedia@FreeBSD.org, freebsd-x11@FreeBSD.org Subject: Re: Testing xbmc pvr; libGL threading issues... X-BeenThere: freebsd-multimedia@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Multimedia discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 21 Oct 2011 18:57:20 -0000 On Fri, Oct 14, 2011 at 11:54:50PM +0200, Juergen Lock wrote: > Hi! > > I had been playing with opdenkamp's xbmc pvr branch and pipelka's > xvdr xbmc addon and vdr plugin for a little while now, and finally > have something that more or less runs. One issue that took me a > while to figure out were crashes in libGL when switching live > channels: > > (gdb) bt > #0 0x00000008041abca7 in glIsTexture () from /usr/local/lib/libGL.so.1 > #1 0x0000000000b2a995 in CLinuxRendererGL::DeleteYV12Texture ( > this=0x8340b8800, index=0) at LinuxRendererGL.cpp:1690 > #2 0x0000000000b2eae2 in CLinuxRendererGL::UnInit (this=0x8340b8800) > at LinuxRendererGL.cpp:1059 > #3 0x0000000000b2ed9e in CLinuxRendererGL::PreInit (this=0x8340b8800) > at LinuxRendererGL.cpp:719 > #4 0x0000000000b29049 in CXBMCRenderManager::PreInit (this=0x1546920) > at RenderManager.cpp:324 > #5 0x0000000000b8bf4f in CDVDPlayerVideo::OpenStream (this=0x835400590, > hint=@0x7ffffdfcee20) at DVDPlayerVideo.cpp:183 > #6 0x0000000000b6d88e in CDVDPlayer::OpenVideoStream (this=0x835400000, > iStream=0, source=256) at DVDPlayer.cpp:2891 > #7 0x0000000000b79734 in CDVDPlayer::Process (this=0x835400000) > at DVDPlayer.cpp:1207 > #8 0x0000000000f4a74d in CThread::staticThread (data=0x835400010) > at Thread.cpp:177 > > turns out libGL keeps thread-local pointers and xbmc called into > libGL (glIsTexture()) from (apparently) a new thread where then > _x86_64_get_dispatch in: > > work/Mesa-7.6.1/src/mesa/x86-64/glapi_x86-64.S > > returned NULL and thus the glIsTexture wrapper in the same .S > got a segfault referencing that NULL pointer here: > > [...] > .p2align 4,,15 > .globl GL_PREFIX(IsTexture) > .type GL_PREFIX(IsTexture), @function > GL_PREFIX(IsTexture): > #if defined(GLX_USE_TLS) > call _x86_64_get_dispatch@PLT > movq 2640(%rax), %r11 > jmp *%r11 > #elif defined(PTHREADS) > pushq %rdi > call _x86_64_get_dispatch@PLT > popq %rdi > movq 2640(%rax), %r11 > ^^^^^^^^^^^^^^^^^^^^^^^^ segfault > jmp *%r11 > #else > [...] > > _x86_64_get_dispatch uses pthread_getspecific() and looks like this: > > [...] > #elif defined(PTHREADS) > > .extern _glapi_Dispatch > .extern _gl_DispatchTSD > .extern pthread_getspecific > > .p2align 4,,15 > _x86_64_get_dispatch: > movq _gl_DispatchTSD@GOTPCREL(%rip), %rax > movl (%rax), %edi > jmp pthread_getspecific@PLT > > #elif defined(THREADS) > [...] > > and some documentation about these thread-local pointers is here: > > work/Mesa-7.6.1/docs/dispatch.html > > After some googling I stumbled across this debian ticket that has a patch: > > http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=536106 > > so I changed the libGL port's files/patch-src__mesa__x86-64__glapi_x86-64.S > into this: > > --------snip------ > --- ./src/mesa/x86-64/glapi_x86-64.S.orig 2009-03-13 04:28:49.000000000 +0100 > +++ ./src/mesa/x86-64/glapi_x86-64.S 2011-01-28 18:12:18.000000000 +0100 > @@ -73,7 +73,12 @@ _x86_64_get_dispatch: > > .p2align 4,,15 > _x86_64_get_dispatch: > - movq _gl_DispatchTSD(%rip), %rdi > + movq _glapi_Dispatch(%rip), %rax > + testq %rax,%rax > + je 1f > + ret > +1: movq _gl_DispatchTSD@GOTPCREL(%rip), %rax > + movl (%rax), %edi > jmp pthread_getspecific@PLT > > #elif defined(THREADS) > --------snip------ > > That fixed these crashes but now I got other crashes that seem to be > related to messages like: > > Recursive call into r300FlushCmdBufLocked! > > (this is using the xorg radeon drivers, the nvidia libGL blob on > the other box crashed in glIsTexture() too but obviously I cannot > easily debug that) - so I looked for another workaround. What I > finally ended up doing was this patch: > (files/patch-xbmc-cores-VideoRenderers-LinuxRendererGL.cpp) > > --- xbmc/cores/VideoRenderers/LinuxRendererGL.cpp.orig > +++ xbmc/cores/VideoRenderers/LinuxRendererGL.cpp > @@ -159,6 +159,10 @@ CLinuxRendererGL::CLinuxRendererGL() > m_rgbPbo = 0; > > m_dllSwScale = new DllSwScale; > + > +#ifdef __FreeBSD__ > + m_tid = NULL; > +#endif > } > > CLinuxRendererGL::~CLinuxRendererGL() > @@ -247,6 +251,9 @@ bool CLinuxRendererGL::ValidateRenderTar > (this->*m_textureCreate)(i); > > m_bValidated = true; > +#ifdef __FreeBSD__ > + m_tid = pthread_self(); > +#endif > return true; > } > return false; > @@ -716,6 +723,9 @@ unsigned int CLinuxRendererGL::PreInit() > CSingleLock lock(g_graphicsContext); > m_bConfigured = false; > m_bValidated = false; > +#ifdef __FreeBSD__ // XXX Will this leak? It's needed to avoid crashes... :( > + if (pthread_self() == m_tid) > +#endif > UnInit(); > m_resolution = g_guiSettings.m_LookAndFeelResolution; > if ( m_resolution == RES_WINDOW ) > > i.e. I only called into CLinuxRendererGL::UnInit() (where the original > crashes happened) if this was the same thread that created the textures > that CLinuxRendererGL::UnInit() tried to delete. I don't know if this > will leak memory, textures, or something else so I'd prefer libGL > to be fixed properly... (And as you might have guessed, this code runs > just fine unpatched on Linux...) And now I tested this with libGL and friends from xorg-dev, http://wiki.freebsd.org/Xorg and those no longer need this patch. (I didn't update all of xorg, just the stuff below graphics/ .) Just FYI, :) Juergen