[Helix-client-dev] CR:Changes to fix the Xlib crash happening during the playback with UI for LitePlayer.
Deepak Jain deepakj at real.comSynopsis:
Changes to fix the Xlib crash happening during the playback with UI for
LitePlayer.
Overview:
When we were playing a rm/wm file with UI, we were getting *Xlib:
unexpected async reply message* because we were blitting on multiple
threads. Now we have scheduled a callback before call to
_MinimalBlt(baseroot.cpp) and _UpdateOverlay(basesurf.cpp) if we detect
that we are not on the main gtk thread. When the callback occurs, the
callback occurs on the main thread and we call _MinimalBlt(baseroot.cpp)
and _UpdateOverlay(basesurf.cpp). This does the blitting on the main thread.
Files Added:
/video/sitelib/linux2.pcf
Files Modified:
/video/sitelib/baseroot.cpp
/video/sitelib/basesurf.cpp
/video/sitelib/pub/basesurf.h
/video/sitelib/pub/baseroot.h
Image Size and Heap Use impact (Client -Only):
None.
Platforms and Profiles Affected:
None
Distribution Libraries Affected:
None
Distribution library impact and planned action:
None
Platforms and Profiles Build Verified:
BIF branch -> wombat
Target(s) -> LitePlayerWombat
Profile -> helix-client-moblin
SYSTEM_ID -> linux-2.2-libc6-gcc32-i586
Branch:
hxclient_3_1_0_atlas, HEAD
Files Attached:
sitelib_diff.txt
linux2.pcf
Thanks,
Deepak Jain
-------------- next part --------------
Index: sitelib/baseroot.cpp
===================================================================
RCS file: /cvsroot/video/sitelib/baseroot.cpp,v
retrieving revision 1.12
diff -u -r1.12 baseroot.cpp
--- sitelib/baseroot.cpp 6 Jul 2007 20:53:58 -0000 1.12
+++ sitelib/baseroot.cpp 24 Apr 2008 07:47:11 -0000
@@ -123,6 +123,10 @@
, m_bUseCardMemory(FALSE)
, m_pUnlockingSite(NULL)
, zm_pColorAcc(NULL)
+#ifdef HELIX_CONFIG_USE_GTKMAIN_THREAD
+ , m_MainThreadID(0)
+ , m_pMutexMinimalBlt(NULL)
+#endif //HELIX_CONFIG_USE_GTKMAIN_THREAD
{
#ifdef _BLT_IN_DEBUG
m_nBLTMode = HX_WINDOWLESS_DEBUG;
@@ -134,7 +138,10 @@
HX_ASSERT( m_pSite );
m_pContext->AddRef();
m_pSite->AddRef();
-
+#ifdef HELIX_CONFIG_USE_GTKMAIN_THREAD
+ m_MainThreadID = pthread_self();
+ CreateInstanceCCF(CLSID_IHXMutex, (void**)&m_pMutexMinimalBlt, m_pContext);
+#endif //HELIX_CONFIG_USE_GTKMAIN_THREAD
CreateInstanceCCF(CLSID_IHXMutex, (void**)&m_pMutex, m_pContext);
CreateInstanceCCF(CLSID_IHXMutex, (void**)&m_pCompMutex, m_pContext);
@@ -190,7 +197,14 @@
#ifdef _WINDOWS
HX_RELEASE(m_pPlayer);
#endif
-
+#ifdef HELIX_CONFIG_USE_GTKMAIN_THREAD
+ while(!m_listTimeOutCallback.IsEmpty())
+ {
+ guint id = (guint)m_listTimeOutCallback.RemoveHead();
+ g_source_remove (id);
+ }
+ HX_RELEASE(m_pMutexMinimalBlt);
+#endif //HELIX_CONFIG_USE_GTKMAIN_THREAD
HX_RELEASE(m_pMutex);
HX_RELEASE(m_pCompMutex);
HX_RELEASE(m_pContext);
@@ -271,6 +285,25 @@
}
}
+#ifdef HELIX_CONFIG_USE_GTKMAIN_THREAD
+struct GtkInfoMinimalBlt
+{
+ CBaseRootSurface* pBase;
+ HXxRect rDestRect;
+};
+gboolean CBaseRootSurface::CallbackToMinimalBlt(gpointer data)
+{
+ GtkInfoMinimalBlt* pGtkInfoMinimalBlt = (GtkInfoMinimalBlt*)data;
+ pGtkInfoMinimalBlt->pBase->_MinimalBlt(pGtkInfoMinimalBlt->rDestRect);
+ if(!pGtkInfoMinimalBlt->pBase->m_listTimeOutCallback.IsEmpty())
+ {
+ pGtkInfoMinimalBlt->pBase->m_listTimeOutCallback.RemoveHead();
+ }
+ HX_DELETE(pGtkInfoMinimalBlt);
+ return FALSE;
+}
+#endif //HELIX_CONFIG_USE_GTKMAIN_THREAD
+
STDMETHODIMP CBaseRootSurface::Blt( UCHAR* pImageData,
HXBitmapInfoHeader* pBitmapInfo,
REF(HXxRect) rDestRect,
@@ -532,7 +565,26 @@
rSrcRect.left, rSrcRect.top, dxSrc, dySrc);
if( !m_pSite->IsCompositionLocked() && returnVal != -1)
+ {
+#ifdef HELIX_CONFIG_USE_GTKMAIN_THREAD
+ unsigned int cur_thread = pthread_self();
+ if (cur_thread != m_MainThreadID)
+ {
+ GtkInfoMinimalBlt* ptr = new GtkInfoMinimalBlt;
+ guint id = 0;
+ ptr->pBase = this;
+ ptr->rDestRect = rDestRect;
+ id = g_timeout_add(0, CallbackToMinimalBlt, (gpointer*)ptr);
+ m_listTimeOutCallback.AddTail((void*)id);
+ return HXR_OK;
+ }
+ m_pMutexMinimalBlt->Lock();
+#endif //HELIX_CONFIG_USE_GTKMAIN_THREAD
_MinimalBlt(rDestRect);
+#ifdef HELIX_CONFIG_USE_GTKMAIN_THREAD
+ m_pMutexMinimalBlt->Unlock();
+#endif //HELIX_CONFIG_USE_GTKMAIN_THREAD
+ }
}
}
if (!returnVal)
Index: sitelib/basesurf.cpp
===================================================================
RCS file: /cvsroot/video/sitelib/basesurf.cpp,v
retrieving revision 1.34
diff -u -r1.34 basesurf.cpp
--- sitelib/basesurf.cpp 1 Aug 2007 00:11:31 -0000 1.34
+++ sitelib/basesurf.cpp 24 Apr 2008 07:47:15 -0000
@@ -185,6 +185,9 @@
, m_bImageBlocksGood(FALSE)
, m_pOverlayManager(NULL)
, m_bAllowOverlayShrinking(FALSE)
+#ifdef HELIX_CONFIG_USE_GTKMAIN_THREAD
+ , m_IDMainThread(0)
+#endif //HELIX_CONFIG_USE_GTKMAIN_THREAD
{
HX_ASSERT( m_pContext );
m_pContext->AddRef();
@@ -201,6 +204,10 @@
m_TimeStamps.Init(m_pContext, this);
#endif
+#ifdef HELIX_CONFIG_USE_GTKMAIN_THREAD
+ m_IDMainThread = pthread_self();
+#endif //HELIX_CONFIG_USE_GTKMAIN_THREAD
+
IHXPreferences* pPreferences = NULL;
IHXBuffer* pBuffer = NULL;
HXFLOAT fTmp = (float)m_fScrollBarZoom;
@@ -235,6 +242,13 @@
HX_DELETE(m_pHwMemObj);
HX_RELEASE(m_pRootSurface);
+#ifdef HELIX_CONFIG_USE_GTKMAIN_THREAD
+ while(!m_listTimeOutCallback.IsEmpty())
+ {
+ guint id = (guint)m_listTimeOutCallback.RemoveHead();
+ g_source_remove (id);
+ }
+#endif //HELIX_CONFIG_USE_GTKMAIN_THREAD
// CBaseSite::Destroy calls EndOptimizedBlt. We can't call
// EndOptimizedBlt from the destructor since it calls DestroySurfaces
@@ -3811,6 +3825,27 @@
m_nUpdateOverlayByPassCount = OVERLAY_BYPASS_THRESHOLD+1;
}
+#ifdef HELIX_CONFIG_USE_GTKMAIN_THREAD
+struct GtkMainUpdateOverlay
+{
+ CBaseSurface* pBase;
+ HXxRect rDestRect;
+ HXxRect rSrcRect;
+ INT32 rflags;
+};
+gboolean CBaseSurface::CallbackToUpdateOverlay(gpointer data)
+{
+ GtkMainUpdateOverlay* pGtkMainUpdateOverlay = (GtkMainUpdateOverlay*)data;
+ pGtkMainUpdateOverlay->pBase->_UpdateOverlay(&pGtkMainUpdateOverlay->rDestRect, &pGtkMainUpdateOverlay->rSrcRect, pGtkMainUpdateOverlay->rflags);
+ if(!pGtkMainUpdateOverlay->pBase->m_listTimeOutCallback.IsEmpty())
+ {
+ pGtkMainUpdateOverlay->pBase->m_listTimeOutCallback.RemoveHead();
+ }
+ HX_DELETE(pGtkMainUpdateOverlay);
+ return FALSE;
+}
+#endif //HELIX_CONFIG_USE_GTKMAIN_THREAD
+
HX_RESULT CBaseSurface::UpdateOverlay( REF(HXxRect) /*IN*/ rDestRect,
REF(HXxRect) /*IN*/ rSrcRect,
int x, int y)
@@ -3993,6 +4028,21 @@
m_nUpdateOverlayByPassCount = 0;
memcpy(&m_lastUpdateDestRect, &destRect, sizeof(HXxRect)); /* Flawfinder: ignore */
memcpy(&m_lastUpdateSrcRect, &srcRect, sizeof(HXxRect)); /* Flawfinder: ignore */
+#ifdef HELIX_CONFIG_USE_GTKMAIN_THREAD
+ unsigned int cur_thread = pthread_self();
+ if (cur_thread != m_IDMainThread)
+ {
+ GtkMainUpdateOverlay* ptr = new GtkMainUpdateOverlay;
+ guint id = 0;
+ ptr->pBase = this;
+ ptr->rDestRect = destRect;
+ ptr->rSrcRect = srcRect;
+ ptr->rflags = flags;
+ id = g_timeout_add(0, CallbackToUpdateOverlay, (gpointer*)ptr);
+ m_listTimeOutCallback.AddTail((void*)id);
+ return HXR_OK;
+ }
+#endif //HELIX_CONFIG_USE_GTKMAIN_THREAD
_UpdateOverlay(&destRect, &srcRect, flags);
#ifdef _CHECK_PERFORMANCE
NumOfUpdateOverlays++;
Index: sitelib/pub/baseroot.h
===================================================================
RCS file: /cvsroot/video/sitelib/pub/baseroot.h,v
retrieving revision 1.8
diff -u -r1.8 baseroot.h
--- sitelib/pub/baseroot.h 6 Jul 2007 20:54:02 -0000 1.8
+++ sitelib/pub/baseroot.h 24 Apr 2008 07:47:17 -0000
@@ -52,7 +52,12 @@
#include "hxengin.h"
#include "hxslist.h"
#include "baseobj.h"
-
+#ifdef HELIX_CONFIG_USE_GTKMAIN_THREAD
+#include <glib/gtypes.h>
+#include <gtk/gtk.h>
+#include <glib.h>
+#include <pthread.h>
+#endif //HELIX_CONFIG_USE_GTKMAIN_THREAD
#ifndef _BASEROOT_H_
#define _BASEROOT_H_
@@ -148,7 +153,12 @@
void UnlockCompMutex();
ColorFuncAccess* GetColorAccess() {return zm_pColorAcc;}
-
+#ifdef HELIX_CONFIG_USE_GTKMAIN_THREAD
+ unsigned int m_MainThreadID;
+ static gboolean CallbackToMinimalBlt(gpointer data);
+ CHXSimpleList m_listTimeOutCallback;
+ IHXMutex* m_pMutexMinimalBlt;
+#endif //HELIX_CONFIG_USE_GTKMAIN_THREAD
protected:
IHXMutex* m_pMutex;
IHXMutex* m_pCompMutex;
Index: sitelib/pub/basesurf.h
===================================================================
RCS file: /cvsroot/video/sitelib/pub/basesurf.h,v
retrieving revision 1.11
diff -u -r1.11 basesurf.h
--- sitelib/pub/basesurf.h 6 Jul 2007 20:54:03 -0000 1.11
+++ sitelib/pub/basesurf.h 24 Apr 2008 07:47:18 -0000
@@ -58,6 +58,12 @@
#include "hxwin.h"
#include "baseobj.h"
+#ifdef HELIX_CONFIG_USE_GTKMAIN_THREAD
+#include <glib/gtypes.h>
+#include <gtk/gtk.h>
+#include <glib.h>
+#include <pthread.h>
+#endif //HELIX_CONFIG_USE_GTKMAIN_THREAD
#if !defined(_GOLD) && 0
#include "timestmp.h"
#endif
@@ -237,6 +243,12 @@
HXxSize* GetSurfaceSize() {return &m_surfaceSize;}
+#ifdef HELIX_CONFIG_USE_GTKMAIN_THREAD
+ unsigned int m_IDMainThread;
+ static gboolean CallbackToUpdateOverlay(gpointer data);
+ CHXSimpleList m_listTimeOutCallback;
+#endif //HELIX_CONFIG_USE_GTKMAIN_THREAD
+
private:
CBaseSurface();
-------------- next part --------------
# on gcc we want to turn on all warnings
extra_cflags = ""
using_gcc = 0
if string.find(platform.cc.cmd, 'gcc') != -1:
using_gcc = 1
extra_cflags = "-Wall"
# grab flags from pkgconfig
import shell
import string
# see if we're using the target gtk version (triggers setting of the
# DISABLE_DEPRECATED flag)
(exitstatus, gtk_mod_version) = shell.run("pkg-config --modversion gtk+-2.0")
if exitstatus != 0:
e = err.Error()
e.Set("pkg-config failed")
raise err.error, e
if string.find(gtk_mod_version, "2.0") == 0:
project.AddDefines('G_DISABLE_DEPRECATED',
'GDK_DISABLE_DEPRECATED',
'GTK_DISABLE_DEPRECATED')
pkg_modules = "gtk+-2.0"
if project.IsDefined('HELIX_FEATURE_LIBGLADE'):
pkg_modules = pkg_modules + " libglade-2.0 gmodule-2.0"
(exitstatus, gtk_config_output_cflags) = shell.run("pkg-config --cflags " + pkg_modules)
(exitstatus, gtk_config_output_ldflags) = shell.run("pkg-config --libs " + pkg_modules)
gtk_cflags = string.split(gtk_config_output_cflags)
gtk_ldflags = string.split(gtk_config_output_ldflags)
gtk_ld_paths = []
gtk_libs = []
gtk_includes = []
gtk_defines = []
gtk_other_cflags = ""
gtk_other_ldflags = ""
for x in gtk_cflags:
if x[0:2] == '-I':
gtk_includes[-1:-1] = [ x[2:] ]
elif x[0:2] == '-D':
gtk_defines[-1:-1] = [ x[2:] ]
else:
gtk_other_cflags = gtk_other_cflags + " " + x
for x in gtk_ldflags:
if x[0:2] == '-l':
gtk_libs[-1:-1] = [ x[2:] ]
elif x[0:2] == '-L':
gtk_ld_paths[-1:-1] = [ x ]
else:
gtk_other_ldflags = gtk_other_ldflags + " " + x
# add the flags
project.AddSystemLibraries(gtk_libs)
project.AddIncludes(gtk_includes)
project.AddSystemPaths(gtk_ld_paths)
project.AddDefines(gtk_defines)
platform.cc.args["default"] = platform.cc.args["default"] + " " + gtk_other_cflags + " " + extra_cflags
platform.cxx.args["default"] = platform.cxx.args["default"] + " " + gtk_other_cflags + " " + extra_cflags
# platform.link.args["default"] = platform.link.args["default"] + " " + gtk_other_ldflags
project.AddDynamicLibraries(gtk_other_ldflags)