diff options
author | Jani Hautakangas <jani.hautakangas@nokia.com> | 2011-09-23 04:47:24 (GMT) |
---|---|---|
committer | Jani Hautakangas <jani.hautakangas@nokia.com> | 2011-09-23 06:46:00 (GMT) |
commit | 872872f3d3f0d89010d3a196b70e8445a08d0784 (patch) | |
tree | 062bf85b1ad43a850c1d94d13e7a276b4e8e5ab4 /src/gui/painting/qgraphicssystemex_symbian.cpp | |
parent | a9e50cd2fe243a912a5c70f157b043bbfc6413fb (diff) | |
download | Qt-872872f3d3f0d89010d3a196b70e8445a08d0784.zip Qt-872872f3d3f0d89010d3a196b70e8445a08d0784.tar.gz Qt-872872f3d3f0d89010d3a196b70e8445a08d0784.tar.bz2 |
Fix to QtOpenGL crash
Exiting the native video recorder on Symbian and going
back to Qt app which runs on opengl graphics system
crashed on some devices because there was not enough GPU
memory and also because low GPU mem device environment
detection was flawed. This patch fixes 32MB GPU memory
detection and adds wait/retrial to EGL surface creation
if it fails.
Task-number: QTBUG-21499
Reviewed-by: Laszlo Agocs
Diffstat (limited to 'src/gui/painting/qgraphicssystemex_symbian.cpp')
-rw-r--r-- | src/gui/painting/qgraphicssystemex_symbian.cpp | 105 |
1 files changed, 91 insertions, 14 deletions
diff --git a/src/gui/painting/qgraphicssystemex_symbian.cpp b/src/gui/painting/qgraphicssystemex_symbian.cpp index 4469704..46731d8 100644 --- a/src/gui/painting/qgraphicssystemex_symbian.cpp +++ b/src/gui/painting/qgraphicssystemex_symbian.cpp @@ -46,31 +46,106 @@ #include <e32property.h> +#ifdef Q_SYMBIAN_SUPPORTS_SURFACES +#include "private/qegl_p.h" +#endif + QT_BEGIN_NAMESPACE static bool bcm2727Initialized = false; static bool bcm2727 = false; +typedef EGLBoolean (*NOK_resource_profiling)(EGLDisplay, EGLint, EGLint*, EGLint, EGLint*); +#define EGL_PROF_TOTAL_MEMORY_NOK 0x3070 + +// Detect if Qt is running on BCM2727 chip. +// BCM2727 is a special case on Symbian because +// it has only 32MB GPU memory which exposes +// significant limitations to hw accelerated UI. bool QSymbianGraphicsSystemEx::hasBCM2727() { if (bcm2727Initialized) return bcm2727; - const TUid KIvePropertyCat = {0x2726beef}; - enum TIvePropertyChipType { - EVCBCM2727B1 = 0x00000000, - EVCBCM2763A0 = 0x04000100, - EVCBCM2763B0 = 0x04000102, - EVCBCM2763C0 = 0x04000103, - EVCBCM2763C1 = 0x04000104, - EVCBCMUnknown = 0x7fffffff - }; - - TInt chipType = EVCBCMUnknown; - if (RProperty::Get(KIvePropertyCat, 0, chipType) == KErrNone) { - if (chipType == EVCBCM2727B1) +#ifdef Q_SYMBIAN_SUPPORTS_SURFACES + EGLDisplay display = QEgl::display(); +#if 1 + // Hacky but fast ~0ms. + const char* vendor = eglQueryString(display, EGL_VENDOR); + if (strstr(vendor, "Broadcom")) { + const TUid KIvePropertyCat = {0x2726beef}; + enum TIvePropertyChipType { + EVCBCM2727B1 = 0x00000000, + EVCBCM2763A0 = 0x04000100, + EVCBCM2763B0 = 0x04000102, + EVCBCM2763C0 = 0x04000103, + EVCBCM2763C1 = 0x04000104, + EVCBCMUnknown = 0x7fffffff + }; + + // Broadcom driver publishes KIvePropertyCat PS key on + // devices which are running on BCM2727 chip and post Anna Symbian. + TInt chipType = EVCBCMUnknown; + if (RProperty::Get(KIvePropertyCat, 0, chipType) == KErrNone) { + if (chipType == EVCBCM2727B1) + bcm2727 = true; + } else if (QSysInfo::symbianVersion() <= QSysInfo::SV_SF_3) { + // Device is running on Symbian Anna or older Symbian^3 in which + // KIvePropertyCat is not published. These ones are always 32MB devices. + bcm2727 = true; + } else { + // We have some other Broadcom chip on post Anna Symbian. + // Should have > 32MB GPU memory. + } + } +#else + // Fool proof but takes 15-20ms and we don't want this delay on app startup... + + // All devices with <= 32MB GPU memory should be + // dealed in similar manner to BCM2727 + // So let's query max GPU memory amount. + NOK_resource_profiling eglQueryProfilingData = (NOK_resource_profiling)eglGetProcAddress("eglQueryProfilingDataNOK"); + if (eglQueryProfilingData) { + EGLint dataCount; + eglQueryProfilingData(display, + EGL_PROF_QUERY_GLOBAL_BIT_NOK | + EGL_PROF_QUERY_MEMORY_USAGE_BIT_NOK, + NULL, + 0, + (EGLint*)&dataCount); + + // Allocate room for the profiling data + EGLint* profData = (EGLint*)malloc(dataCount * sizeof(EGLint)); + memset(profData,0,dataCount * sizeof(EGLint)); + + // Retrieve the profiling data + eglQueryProfilingData(display, + EGL_PROF_QUERY_GLOBAL_BIT_NOK | + EGL_PROF_QUERY_MEMORY_USAGE_BIT_NOK, + profData, + dataCount, + (EGLint*)&dataCount); + + int totalMemory; + EGLint i = 0; + while (profData && i < dataCount) { + switch (profData[i++]) { + case EGL_PROF_TOTAL_MEMORY_NOK: + totalMemory = profData[i++]; + break; + default: + i++; + } + } + + // ok, hasBCM2727() naming is a bit misleading but Qt must + // behave the same on all chips like BCM2727 (<= 32MB GPU memory) + // and our code (and others) are already using this function. + if (totalMemory <= 33554432) bcm2727 = true; } +#endif +#endif // Q_SYMBIAN_SUPPORTS_SURFACES bcm2727Initialized = true; @@ -80,7 +155,9 @@ bool QSymbianGraphicsSystemEx::hasBCM2727() void QSymbianGraphicsSystemEx::releaseCachedGpuResources() { // Do nothing here - // This is implemented in graphics system specific plugin + + // This virtual function should be implemented in graphics system specific + // plugin } void QSymbianGraphicsSystemEx::releaseAllGpuResources() |