summaryrefslogtreecommitdiffstats
path: root/src/gui
diff options
context:
space:
mode:
authorQt Continuous Integration System <qt-info@nokia.com>2011-10-07 12:51:54 (GMT)
committerQt Continuous Integration System <qt-info@nokia.com>2011-10-07 12:51:54 (GMT)
commit95e5e8ff45d2aa8acda595186136b54f695bb9cb (patch)
tree01b74c491a6895718283d1ed73817dea451dee82 /src/gui
parentaf9d77acbf1dc80308df00526163d905e9b22421 (diff)
parent7cf9030bd7a50b6d98d454510417c6ecc3f33d49 (diff)
downloadQt-95e5e8ff45d2aa8acda595186136b54f695bb9cb.zip
Qt-95e5e8ff45d2aa8acda595186136b54f695bb9cb.tar.gz
Qt-95e5e8ff45d2aa8acda595186136b54f695bb9cb.tar.bz2
Merge branch 'qt-4.8-from-4.7' of scm.dev.nokia.troll.no:qt/qt-integration into master-integration
* 'qt-4.8-from-4.7' of scm.dev.nokia.troll.no:qt/qt-integration: Do not let QGLContext get out of sync when doing mixed VG-GL rendering Create auto test for http HEAD request QNAM - fix poor performance of HEAD request with authentication symbian - add support for ELangKazakh and ELangEnglish_India QAuthenticator::setUser() parse user name in form user@domain A patch for 'Fix to QtOpenGL crash' Update Korean Translations Document updates to Qt for Symbian installation instructions and platform notes. Always recreate backing store when TLW transparency changes Crash in QDeclarativeCompiler::indexOfProperty Fix to QtOpenGL crash Incorrect 'break' in switch-case was replaced by 'return' QLineControl: selectedTextChanged() signal is omitted in some cases QML import path puts Qt dirs in correct Symbian order Avoid runtime warning about interlace handling from libpng 1.5 symbian bearer: fix tst_qnetworksession test failures Refactor dangerous multiple inheritance Fix RConnection handle leak in symbian bearer plugin Prevent crash when cache is changed on the fly Add missing checks for httpReply in QNetworkHttpBackend.
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/egl/qegl.cpp32
-rw-r--r--src/gui/kernel/qcursor_win.cpp2
-rw-r--r--src/gui/kernel/qwidget.cpp24
-rw-r--r--src/gui/kernel/qwidget_p.h1
-rw-r--r--src/gui/kernel/qwidget_s60.cpp58
-rw-r--r--src/gui/painting/qgraphicssystemex_symbian.cpp107
-rw-r--r--src/gui/widgets/qlinecontrol.cpp4
7 files changed, 187 insertions, 41 deletions
diff --git a/src/gui/egl/qegl.cpp b/src/gui/egl/qegl.cpp
index 2a37d45..6fe1c8c 100644
--- a/src/gui/egl/qegl.cpp
+++ b/src/gui/egl/qegl.cpp
@@ -684,6 +684,37 @@ EGLSurface QEgl::createSurface(QPaintDevice *device, EGLConfig cfg, const QEglPr
else
props = 0;
EGLSurface surf;
+#ifdef Q_OS_SYMBIAN
+ // On Symbian there might be situations (especially on 32MB GPU devices)
+ // where Qt is trying to create EGL surface while some other application
+ // is still holding all available GPU memory but is about to release it
+ // soon. For an example when exiting native video recorder and going back to
+ // Qt application behind it. Video stack tear down takes some time and Qt
+ // app might be too quick in reserving its EGL surface and thus running out
+ // of GPU memory right away. So if EGL surface creation fails due to bad
+ // alloc, let's try recreating it four times within ~1 second if needed.
+ // This strategy gives some time for video recorder to tear down its stack
+ // and a chance to Qt for creating a valid surface.
+ int tries = 4;
+ while(tries--) {
+ if (devType == QInternal::Widget)
+ surf = eglCreateWindowSurface(QEgl::display(), cfg, windowDrawable, props);
+ else
+ surf = eglCreatePixmapSurface(QEgl::display(), cfg, pixmapDrawable, props);
+ if (surf == EGL_NO_SURFACE) {
+ EGLint error = eglGetError();
+ if (error == EGL_BAD_ALLOC) {
+ if (tries) {
+ User::After(1000 * 250); // 250ms
+ continue;
+ }
+ }
+ qWarning("QEglContext::createSurface(): Unable to create EGL surface, error = 0x%x", error);
+ } else {
+ break;
+ }
+ }
+#else
if (devType == QInternal::Widget)
surf = eglCreateWindowSurface(QEgl::display(), cfg, windowDrawable, props);
else
@@ -691,6 +722,7 @@ EGLSurface QEgl::createSurface(QPaintDevice *device, EGLConfig cfg, const QEglPr
if (surf == EGL_NO_SURFACE) {
qWarning("QEglContext::createSurface(): Unable to create EGL surface, error = 0x%x", eglGetError());
}
+#endif
return surf;
}
#endif
diff --git a/src/gui/kernel/qcursor_win.cpp b/src/gui/kernel/qcursor_win.cpp
index cef83f5..a68472c 100644
--- a/src/gui/kernel/qcursor_win.cpp
+++ b/src/gui/kernel/qcursor_win.cpp
@@ -477,7 +477,7 @@ void QCursorData::update()
QPixmap pixmap = QApplicationPrivate::instance()->getPixmapCursor(cshape);
hcurs = create32BitCursor(pixmap, hx, hy);
}
- break;
+ return;
default:
qWarning("QCursor::update: Invalid cursor shape %d", cshape);
return;
diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp
index 0aa1dfa..9b5a283 100644
--- a/src/gui/kernel/qwidget.cpp
+++ b/src/gui/kernel/qwidget.cpp
@@ -2260,10 +2260,16 @@ void QWidgetPrivate::updateIsOpaque()
#endif
#ifdef Q_WS_S60
- if (q->windowType() == Qt::Dialog && q->testAttribute(Qt::WA_TranslucentBackground)
- && S60->avkonComponentsSupportTransparency) {
- setOpaque(false);
- return;
+ if (q->testAttribute(Qt::WA_TranslucentBackground)) {
+ if (q->windowType() & Qt::Dialog || q->windowType() & Qt::Popup) {
+ if (S60->avkonComponentsSupportTransparency) {
+ setOpaque(false);
+ return;
+ }
+ } else {
+ setOpaque(false);
+ return;
+ }
}
#endif
@@ -2283,11 +2289,16 @@ void QWidgetPrivate::updateIsOpaque()
}
if (q->isWindow() && !q->testAttribute(Qt::WA_NoSystemBackground)) {
+#ifdef Q_WS_S60
+ setOpaque(true);
+ return;
+#else
const QBrush &windowBrush = q->palette().brush(QPalette::Window);
if (windowBrush.style() != Qt::NoBrush && windowBrush.isOpaque()) {
setOpaque(true);
return;
}
+#endif
}
setOpaque(false);
}
@@ -10948,11 +10959,14 @@ void QWidget::setAttribute(Qt::WidgetAttribute attribute, bool on)
}
break;
case Qt::WA_TranslucentBackground:
+#if defined(Q_OS_SYMBIAN)
+ setAttribute(Qt::WA_NoSystemBackground, on);
+#else
if (on) {
setAttribute(Qt::WA_NoSystemBackground);
d->updateIsTranslucent();
}
-
+#endif
break;
case Qt::WA_AcceptTouchEvents:
#if defined(Q_WS_WIN) || defined(Q_WS_MAC) || defined(Q_OS_SYMBIAN)
diff --git a/src/gui/kernel/qwidget_p.h b/src/gui/kernel/qwidget_p.h
index aefffb6..9ac9479 100644
--- a/src/gui/kernel/qwidget_p.h
+++ b/src/gui/kernel/qwidget_p.h
@@ -233,6 +233,7 @@ struct QTLWExtra {
uint inExpose : 1; // Prevents drawing recursion
uint nativeWindowTransparencyEnabled : 1; // Tracks native window transparency
uint forcedToRaster : 1;
+ uint noSystemRotationDisabled : 1;
#elif defined(Q_WS_QPA)
QPlatformWindow *platformWindow;
QPlatformWindowFormat platformWindowFormat;
diff --git a/src/gui/kernel/qwidget_s60.cpp b/src/gui/kernel/qwidget_s60.cpp
index e06b625..00661ae 100644
--- a/src/gui/kernel/qwidget_s60.cpp
+++ b/src/gui/kernel/qwidget_s60.cpp
@@ -804,19 +804,12 @@ void QWidgetPrivate::setConstraints_sys()
void QWidgetPrivate::s60UpdateIsOpaque()
{
Q_Q(QWidget);
-
if (!q->testAttribute(Qt::WA_WState_Created))
return;
-
const bool writeAlpha = extraData()->nativePaintMode == QWExtra::BlitWriteAlpha;
- if (!q->testAttribute(Qt::WA_TranslucentBackground) && !writeAlpha)
- return;
const bool requireAlphaChannel = !isOpaque || writeAlpha;
-
createTLExtra();
-
RWindow *const window = static_cast<RWindow *>(q->effectiveWinId()->DrawableWindow());
-
#ifdef Q_SYMBIAN_SEMITRANSPARENT_BG_SURFACE
if (QApplicationPrivate::instance()->useTranslucentEGLSurfaces
&& !extra->topextra->forcedToRaster) {
@@ -825,25 +818,47 @@ void QWidgetPrivate::s60UpdateIsOpaque()
return;
}
#endif
+ const bool recreateBackingStore = extra->topextra->backingStore.data() && (
+ QApplicationPrivate::graphics_system_name == QLatin1String("openvg") ||
+ QApplicationPrivate::graphics_system_name == QLatin1String("opengl")
+ );
if (requireAlphaChannel) {
- const TDisplayMode displayMode = static_cast<TDisplayMode>(window->SetRequiredDisplayMode(EColor16MA));
- if (window->SetTransparencyAlphaChannel() == KErrNone) {
+ window->SetRequiredDisplayMode(EColor16MA);
+ if (window->SetTransparencyAlphaChannel() == KErrNone)
window->SetBackgroundColor(TRgb(255, 255, 255, 0));
- extra->topextra->nativeWindowTransparencyEnabled = 1;
- if (extra->topextra->backingStore.data() && (
- QApplicationPrivate::graphics_system_name == QLatin1String("openvg")
- || QApplicationPrivate::graphics_system_name == QLatin1String("opengl"))) {
- // Semi-transparent EGL surfaces aren't supported. We need to
- // recreate backing store to get translucent surface (raster surface).
- extra->topextra->backingStore.create(q);
- extra->topextra->backingStore.registerWidget(q);
- // FixNativeOrientation() will not work without an EGL surface.
+ } else {
+ if (recreateBackingStore) {
+ // Clear the UI surface to ensure that the EGL surface content is visible
+ CWsScreenDevice *screenDevice = S60->screenDevice(q);
+ QScopedPointer<CWindowGc> gc(new CWindowGc(screenDevice));
+ const int err = gc->Construct();
+ if (!err) {
+ gc->Activate(*window);
+ window->BeginRedraw();
+ gc->SetDrawMode(CWindowGc::EDrawModeWriteAlpha);
+ gc->SetBrushColor(TRgb(0, 0, 0, 0));
+ gc->Clear(TRect(0, 0, q->width(), q->height()));
+ window->EndRedraw();
+ }
+ }
+ if (extra->topextra->nativeWindowTransparencyEnabled)
+ window->SetTransparentRegion(TRegionFix<1>());
+ }
+ extra->topextra->nativeWindowTransparencyEnabled = requireAlphaChannel;
+ if (recreateBackingStore) {
+ extra->topextra->backingStore.create(q);
+ extra->topextra->backingStore.registerWidget(q);
+ bool noSystemRotationDisabled = false;
+ if (requireAlphaChannel) {
+ if (q->testAttribute(Qt::WA_SymbianNoSystemRotation)) {
+ // FixNativeOrientation() will not work without an EGL surface
q->setAttribute(Qt::WA_SymbianNoSystemRotation, false);
+ noSystemRotationDisabled = true;
}
+ } else {
+ q->setAttribute(Qt::WA_SymbianNoSystemRotation, extra->topextra->noSystemRotationDisabled);
}
- } else if (extra->topextra->nativeWindowTransparencyEnabled) {
- window->SetTransparentRegion(TRegionFix<1>());
- extra->topextra->nativeWindowTransparencyEnabled = 0;
+ extra->topextra->noSystemRotationDisabled = noSystemRotationDisabled;
}
}
@@ -1004,6 +1019,7 @@ void QWidgetPrivate::createTLSysExtra()
extra->topextra->inExpose = 0;
extra->topextra->nativeWindowTransparencyEnabled = 0;
extra->topextra->forcedToRaster = 0;
+ extra->topextra->noSystemRotationDisabled = 0;
}
void QWidgetPrivate::deleteTLSysExtra()
diff --git a/src/gui/painting/qgraphicssystemex_symbian.cpp b/src/gui/painting/qgraphicssystemex_symbian.cpp
index 4469704..32e040f 100644
--- a/src/gui/painting/qgraphicssystemex_symbian.cpp
+++ b/src/gui/painting/qgraphicssystemex_symbian.cpp
@@ -46,31 +46,108 @@
#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;
+#ifdef Q_SYMBIAN_SUPPORTS_SURFACES
+typedef EGLBoolean (*NOK_resource_profiling)(EGLDisplay, EGLint, EGLint*, EGLint, EGLint*);
+#define EGL_PROF_TOTAL_MEMORY_NOK 0x3070
+#endif
+
+// 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 +157,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()
diff --git a/src/gui/widgets/qlinecontrol.cpp b/src/gui/widgets/qlinecontrol.cpp
index d58da37..0af2e59 100644
--- a/src/gui/widgets/qlinecontrol.cpp
+++ b/src/gui/widgets/qlinecontrol.cpp
@@ -445,6 +445,8 @@ void QLineControl::moveCursor(int pos, bool mark)
void QLineControl::processInputMethodEvent(QInputMethodEvent *event)
{
int priorState = 0;
+ int originalSelectionStart = m_selstart;
+ int originalSelectionEnd = m_selend;
bool isGettingInput = !event->commitString().isEmpty()
|| event->preeditString() != preeditAreaText()
|| event->replacementLength() > 0;
@@ -523,6 +525,8 @@ void QLineControl::processInputMethodEvent(QInputMethodEvent *event)
}
m_textLayout.setAdditionalFormats(formats);
updateDisplayText(/*force*/ true);
+ if (originalSelectionStart != m_selstart || originalSelectionEnd != m_selend)
+ emit selectionChanged();
if (cursorPositionChanged)
emitCursorPositionChanged();
else if (m_preeditCursor != oldPreeditCursor)