summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJørgen Lind <jorgen.lind@nokia.com>2011-01-05 16:14:54 (GMT)
committerJørgen Lind <jorgen.lind@nokia.com>2011-01-05 16:17:46 (GMT)
commitcc8877068dc6ae8f3142ffec0b85f6fbac4a0d81 (patch)
tree90008cb66bc91d38b230dd6ec561352a666346bf
parent1462a7ba51d25a7d022eab5533885cb1ed1c4c5c (diff)
downloadQt-cc8877068dc6ae8f3142ffec0b85f6fbac4a0d81.zip
Qt-cc8877068dc6ae8f3142ffec0b85f6fbac4a0d81.tar.gz
Qt-cc8877068dc6ae8f3142ffec0b85f6fbac4a0d81.tar.bz2
Lighthouse: Adding support for EGL to testlite
There is really no good way of detecting if to use EGL instead of GLX using qmake. So this is the behavior for now: if QtOpenGL is compiled with "desktop gl" then use GLX if its compiled with OpenGLES2 then use EGL.
-rw-r--r--src/plugins/platforms/eglconvenience/qeglconvenience.cpp8
-rw-r--r--src/plugins/platforms/eglconvenience/qeglconvenience.h1
-rw-r--r--src/plugins/platforms/testlite/qtestliteeglintegration.cpp145
-rw-r--r--src/plugins/platforms/testlite/qtestliteeglintegration.h13
-rw-r--r--src/plugins/platforms/testlite/qtestliteintegration.cpp19
-rw-r--r--src/plugins/platforms/testlite/qtestlitewindow.cpp94
-rw-r--r--src/plugins/platforms/testlite/qtestlitewindow.h2
-rw-r--r--src/plugins/platforms/testlite/testlite.pro37
8 files changed, 287 insertions, 32 deletions
diff --git a/src/plugins/platforms/eglconvenience/qeglconvenience.cpp b/src/plugins/platforms/eglconvenience/qeglconvenience.cpp
index b203fe8..1612f79 100644
--- a/src/plugins/platforms/eglconvenience/qeglconvenience.cpp
+++ b/src/plugins/platforms/eglconvenience/qeglconvenience.cpp
@@ -313,4 +313,12 @@ QPlatformWindowFormat qt_qPlatformWindowFormatFromConfig(EGLDisplay display, con
return format;
}
+bool q_hasEglExtension(EGLDisplay display, const char* extensionName)
+{
+ QList<QByteArray> extensions =
+ QByteArray(reinterpret_cast<const char *>
+ (eglQueryString(display, EGL_EXTENSIONS))).split(' ');
+ return extensions.contains(extensionName);
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglconvenience/qeglconvenience.h b/src/plugins/platforms/eglconvenience/qeglconvenience.h
index 604262b..98c30b8 100644
--- a/src/plugins/platforms/eglconvenience/qeglconvenience.h
+++ b/src/plugins/platforms/eglconvenience/qeglconvenience.h
@@ -53,6 +53,7 @@ QVector<EGLint> q_createConfigAttributesFromFormat(const QPlatformWindowFormat &
bool q_reduceConfigAttributes(QVector<EGLint> *configAttributes);
EGLConfig q_configFromQPlatformWindowFormat(EGLDisplay display, const QPlatformWindowFormat &format);
QPlatformWindowFormat qt_qPlatformWindowFormatFromConfig(EGLDisplay display, const EGLConfig config);
+bool q_hasEglExtension(EGLDisplay display,const char* extensionName);
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/testlite/qtestliteeglintegration.cpp b/src/plugins/platforms/testlite/qtestliteeglintegration.cpp
new file mode 100644
index 0000000..3cbcc05
--- /dev/null
+++ b/src/plugins/platforms/testlite/qtestliteeglintegration.cpp
@@ -0,0 +1,145 @@
+#include "qtestliteeglintegration.h"
+
+static int countBits(unsigned long mask)
+{
+ int count = 0;
+ while (mask != 0) {
+ if (mask & 1)
+ ++count;
+ mask >>= 1;
+ }
+ return count;
+}
+
+VisualID QTestLiteEglIntegration::getCompatibleVisualId(Display *display, EGLConfig config)
+{
+ VisualID visualId = 0;
+ EGLint eglValue = 0;
+
+ EGLDisplay eglDisplay = eglGetDisplay(display);
+
+ EGLint configRedSize = 0;
+ eglGetConfigAttrib(eglDisplay, config, EGL_RED_SIZE, &configRedSize);
+
+ EGLint configGreenSize = 0;
+ eglGetConfigAttrib(eglDisplay, config, EGL_GREEN_SIZE, &configGreenSize);
+
+ EGLint configBlueSize = 0;
+ eglGetConfigAttrib(eglDisplay, config, EGL_BLUE_SIZE, &configBlueSize);
+
+ EGLint configAlphaSize = 0;
+ eglGetConfigAttrib(eglDisplay, config, EGL_ALPHA_SIZE, &configAlphaSize);
+
+ eglGetConfigAttrib(eglDisplay, config, EGL_CONFIG_ID, &eglValue);
+ int configId = eglValue;
+
+ // See if EGL provided a valid VisualID:
+ eglGetConfigAttrib(eglDisplay, config, EGL_NATIVE_VISUAL_ID, &eglValue);
+ visualId = (VisualID)eglValue;
+ if (visualId) {
+ // EGL has suggested a visual id, so get the rest of the visual info for that id:
+ XVisualInfo visualInfoTemplate;
+ memset(&visualInfoTemplate, 0, sizeof(XVisualInfo));
+ visualInfoTemplate.visualid = visualId;
+
+ XVisualInfo *chosenVisualInfo;
+ int matchingCount = 0;
+ chosenVisualInfo = XGetVisualInfo(display, VisualIDMask, &visualInfoTemplate, &matchingCount);
+ if (chosenVisualInfo) {
+ // Skip size checks if implementation supports non-matching visual
+ // and config (http://bugreports.qt.nokia.com/browse/QTBUG-9444).
+ if (q_hasEglExtension(eglDisplay,"EGL_NV_post_convert_rounding")) {
+ XFree(chosenVisualInfo);
+ return visualId;
+ }
+
+ int visualRedSize = countBits(chosenVisualInfo->red_mask);
+ int visualGreenSize = countBits(chosenVisualInfo->green_mask);
+ int visualBlueSize = countBits(chosenVisualInfo->blue_mask);
+ int visualAlphaSize = -1; // Need XRender to tell us the alpha channel size
+
+ bool visualMatchesConfig = false;
+ if ( visualRedSize == configRedSize &&
+ visualGreenSize == configGreenSize &&
+ visualBlueSize == configBlueSize )
+ {
+ // We need XRender to check the alpha channel size of the visual. If we don't have
+ // the alpha size, we don't check it against the EGL config's alpha size.
+ if (visualAlphaSize >= 0)
+ visualMatchesConfig = visualAlphaSize == configAlphaSize;
+ else
+ visualMatchesConfig = true;
+ }
+
+ if (!visualMatchesConfig) {
+ if (visualAlphaSize >= 0) {
+ qWarning("Warning: EGL suggested using X Visual ID %d (ARGB%d%d%d%d) for EGL config %d (ARGB%d%d%d%d), but this is incompatable",
+ (int)visualId, visualAlphaSize, visualRedSize, visualGreenSize, visualBlueSize,
+ configId, configAlphaSize, configRedSize, configGreenSize, configBlueSize);
+ } else {
+ qWarning("Warning: EGL suggested using X Visual ID %d (RGB%d%d%d) for EGL config %d (RGB%d%d%d), but this is incompatable",
+ (int)visualId, visualRedSize, visualGreenSize, visualBlueSize,
+ configId, configRedSize, configGreenSize, configBlueSize);
+ }
+ visualId = 0;
+ }
+ } else {
+ qWarning("Warning: EGL suggested using X Visual ID %d for EGL config %d, but that isn't a valid ID",
+ (int)visualId, configId);
+ visualId = 0;
+ }
+ XFree(chosenVisualInfo);
+ }
+#ifdef QT_DEBUG_X11_VISUAL_SELECTION
+ else
+ qDebug("EGL did not suggest a VisualID (EGL_NATIVE_VISUAL_ID was zero) for EGLConfig %d", configId);
+#endif
+
+ if (visualId) {
+#ifdef QT_DEBUG_X11_VISUAL_SELECTION
+ if (configAlphaSize > 0)
+ qDebug("Using ARGB Visual ID %d provided by EGL for config %d", (int)visualId, configId);
+ else
+ qDebug("Using Opaque Visual ID %d provided by EGL for config %d", (int)visualId, configId);
+#endif
+ return visualId;
+ }
+
+ // Finally, try to
+ // use XGetVisualInfo and only use the bit depths to match on:
+ if (!visualId) {
+ XVisualInfo visualInfoTemplate;
+ memset(&visualInfoTemplate, 0, sizeof(XVisualInfo));
+ XVisualInfo *matchingVisuals;
+ int matchingCount = 0;
+
+ visualInfoTemplate.depth = configRedSize + configGreenSize + configBlueSize + configAlphaSize;
+ matchingVisuals = XGetVisualInfo(display,
+ VisualDepthMask,
+ &visualInfoTemplate,
+ &matchingCount);
+ if (!matchingVisuals) {
+ // Try again without taking the alpha channel into account:
+ visualInfoTemplate.depth = configRedSize + configGreenSize + configBlueSize;
+ matchingVisuals = XGetVisualInfo(display,
+ VisualDepthMask,
+ &visualInfoTemplate,
+ &matchingCount);
+ }
+
+ if (matchingVisuals) {
+ visualId = matchingVisuals[0].visualid;
+ XFree(matchingVisuals);
+ }
+ }
+
+ if (visualId) {
+#ifdef QT_DEBUG_X11_VISUAL_SELECTION
+ qDebug("Using Visual ID %d provided by XGetVisualInfo for EGL config %d", (int)visualId, configId);
+#endif
+ return visualId;
+ }
+
+ qWarning("Unable to find an X11 visual which matches EGL config %d", configId);
+ return (VisualID)0;
+}
diff --git a/src/plugins/platforms/testlite/qtestliteeglintegration.h b/src/plugins/platforms/testlite/qtestliteeglintegration.h
new file mode 100644
index 0000000..3717976
--- /dev/null
+++ b/src/plugins/platforms/testlite/qtestliteeglintegration.h
@@ -0,0 +1,13 @@
+#ifndef QTESTLITEEGLINTEGRATION_H
+#define QTESTLITEEGLINTEGRATION_H
+
+#include "qtestlitestaticinfo.h"
+#include "../eglconvenience/qeglconvenience.h"
+
+class QTestLiteEglIntegration
+{
+public:
+ static VisualID getCompatibleVisualId(Display *display, EGLConfig config);
+};
+
+#endif // QTESTLITEEGLINTEGRATION_H
diff --git a/src/plugins/platforms/testlite/qtestliteintegration.cpp b/src/plugins/platforms/testlite/qtestliteintegration.cpp
index 5dbe1e7..9b641d1 100644
--- a/src/plugins/platforms/testlite/qtestliteintegration.cpp
+++ b/src/plugins/platforms/testlite/qtestliteintegration.cpp
@@ -52,6 +52,8 @@
#if !defined(QT_NO_OPENGL)
#if !defined(QT_OPENGL_ES_2)
#include <GL/glx.h>
+#else
+#include <EGL/egl.h>
#endif //!defined(QT_OPENGL_ES_2)
#include <private/qwindowsurface_gl_p.h>
#include <private/qpixmapdata_gl_p.h>
@@ -59,7 +61,6 @@
QT_BEGIN_NAMESPACE
-
QTestLiteIntegration::QTestLiteIntegration(bool useOpenGL)
: mUseOpenGL(useOpenGL)
, mFontDb(new QGenericUnixFontDatabase())
@@ -130,9 +131,23 @@ QPlatformClipboard * QTestLiteIntegration::clipboard() const
bool QTestLiteIntegration::hasOpenGL() const
{
-#if !defined(QT_NO_OPENGL) && !defined(QT_OPENGL_ES_2)
+#if !defined(QT_NO_OPENGL)
+#if !defined(QT_OPENGL_ES_2)
QTestLiteScreen *screen = static_cast<const QTestLiteScreen *>(mScreens.at(0));
return glXQueryExtension(screen->display(), 0, 0) != 0;
+#else
+ static bool eglHasbeenInitialized = false;
+ static bool wasEglInitialized = false;
+ if (!eglHasbeenInitialized) {
+ eglHasbeenInitialized = true;
+ QTestLiteScreen *screen = static_cast<const QTestLiteScreen *>(mScreens.at(0));
+ EGLint major, minor;
+ eglBindAPI(EGL_OPENGL_ES_API);
+ EGLDisplay disp = eglGetDisplay(screen->display());
+ wasEglInitialized = eglInitialize(disp,&major,&minor);
+ }
+ return wasEglInitialized;
+#endif
#endif
return false;
}
diff --git a/src/plugins/platforms/testlite/qtestlitewindow.cpp b/src/plugins/platforms/testlite/qtestlitewindow.cpp
index 18fab4a..d9c69e3 100644
--- a/src/plugins/platforms/testlite/qtestlitewindow.cpp
+++ b/src/plugins/platforms/testlite/qtestlitewindow.cpp
@@ -54,9 +54,15 @@
#include <QtGui/private/qwindowsurface_p.h>
#include <QtGui/private/qapplication_p.h>
-#if !defined(QT_NO_OPENGL) && !defined(QT_OPENGL_ES_2)
+#if !defined(QT_NO_OPENGL)
+#if !defined(QT_OPENGL_ES_2)
#include "qglxintegration.h"
-#endif
+#else
+#include "../eglconvenience/qeglconvenience.h"
+#include "../eglconvenience/qeglplatformcontext.h"
+#include "qtestliteeglintegration.h"
+#endif //QT_OPENGL_ES_2
+#endif //QT_NO_OPENGL
//#define MYX11_DEBUG
@@ -74,16 +80,36 @@ QTestLiteWindow::QTestLiteWindow(QWidget *window)
if(window->platformWindowFormat().windowApi() == QPlatformWindowFormat::OpenGL
&& QApplicationPrivate::platformIntegration()->hasOpenGL() ) {
-#if !defined(QT_NO_OPENGL) && !defined(QT_OPENGL_ES_2)
+ #if !defined(QT_NO_OPENGL)
+#if !defined(QT_OPENGL_ES_2)
XVisualInfo *visualInfo = QGLXContext::findVisualInfo(mScreen,window->platformWindowFormat());
- Colormap cmap = XCreateColormap(mScreen->display(),mScreen->rootWindow(),visualInfo->visual,AllocNone);
-
- XSetWindowAttributes a;
- a.colormap = cmap;
- x_window = XCreateWindow(mScreen->display(), mScreen->rootWindow(),x, y, w, h,
- 0, visualInfo->depth, InputOutput, visualInfo->visual,
- CWColormap, &a);
-#endif //!defined(QT_NO_OPENGL) && !defined(QT_OPENGL_ES_2)
+#else
+ QPlatformWindowFormat windowFormat = correctColorBuffers(window->platformWindowFormat());
+
+ EGLDisplay eglDisplay = eglGetDisplay(mScreen->display());
+ EGLConfig eglConfig = q_configFromQPlatformWindowFormat(eglDisplay,windowFormat);
+ VisualID id = QTestLiteEglIntegration::getCompatibleVisualId(mScreen->display(),eglConfig);
+
+ XVisualInfo visualInfoTemplate;
+ memset(&visualInfoTemplate, 0, sizeof(XVisualInfo));
+ visualInfoTemplate.visualid = id;
+
+ XVisualInfo *visualInfo;
+ int matchingCount = 0;
+ visualInfo = XGetVisualInfo(mScreen->display(), VisualIDMask, &visualInfoTemplate, &matchingCount);
+#endif //!defined(QT_OPENGL_ES_2)
+ if (visualInfo) {
+ Colormap cmap = XCreateColormap(mScreen->display(),mScreen->rootWindow(),visualInfo->visual,AllocNone);
+
+ XSetWindowAttributes a;
+ a.colormap = cmap;
+ x_window = XCreateWindow(mScreen->display(), mScreen->rootWindow(),x, y, w, h,
+ 0, visualInfo->depth, InputOutput, visualInfo->visual,
+ CWColormap, &a);
+ } else {
+ qFatal("no window!");
+ }
+#endif //!defined(QT_NO_OPENGL)
} else {
x_window = XCreateSimpleWindow(mScreen->display(), mScreen->rootWindow(),
x, y, w, h, 0 /*border_width*/,
@@ -93,12 +119,6 @@ QTestLiteWindow::QTestLiteWindow(QWidget *window)
#ifdef MYX11_DEBUG
qDebug() << "QTestLiteWindow::QTestLiteWindow creating" << hex << x_window << window;
#endif
-// }
-
-// width = -1;
-// height = -1;
-// xpos = -1;
-// ypos = -1;
XSetWindowBackgroundPixmap(mScreen->display(), x_window, XNone);
@@ -548,8 +568,23 @@ QPlatformGLContext *QTestLiteWindow::glContext() const
return 0;
if (!mGLContext) {
QTestLiteWindow *that = const_cast<QTestLiteWindow *>(this);
-#if !defined(QT_NO_OPENGL) && !defined(QT_OPENGL_ES_2)
+#if !defined(QT_NO_OPENGL)
+#if !defined(QT_OPENGL_ES_2)
that->mGLContext = new QGLXContext(x_window, mScreen,widget()->platformWindowFormat());
+#else
+ EGLDisplay display = eglGetDisplay(mScreen->display());
+
+ QPlatformWindowFormat windowFormat = correctColorBuffers(widget()->platformWindowFormat());
+
+ EGLConfig config = q_configFromQPlatformWindowFormat(display,windowFormat);
+ QVector<EGLint> eglContextAttrs;
+ eglContextAttrs.append(EGL_CONTEXT_CLIENT_VERSION);
+ eglContextAttrs.append(2);
+ eglContextAttrs.append(EGL_NONE);
+
+ EGLSurface eglSurface = eglCreateWindowSurface(display,config,(EGLNativeWindowType)x_window,0);
+ that->mGLContext = new QEGLPlatformContext(display, config, eglContextAttrs.data(), eglSurface, EGL_OPENGL_ES_API);
+#endif
#endif
}
return mGLContext;
@@ -584,4 +619,27 @@ void QTestLiteWindow::doSizeHints()
XSetWMNormalHints(mScreen->display(), x_window, &s);
}
+QPlatformWindowFormat QTestLiteWindow::correctColorBuffers(const QPlatformWindowFormat &platformWindowFormat) const
+{
+ // I have only tested this setup on a dodgy intel setup, where I didn't use standard libs,
+ // so this might be not what we want to do :)
+ if ( !(platformWindowFormat.redBufferSize() == -1 &&
+ platformWindowFormat.greenBufferSize() == -1 &&
+ platformWindowFormat.blueBufferSize() == -1))
+ return platformWindowFormat;
+
+ QPlatformWindowFormat windowFormat = platformWindowFormat;
+ if (mScreen->depth() == 16) {
+ windowFormat.setRedBufferSize(5);
+ windowFormat.setGreenBufferSize(6);
+ windowFormat.setBlueBufferSize(5);
+ } else {
+ windowFormat.setRedBufferSize(8);
+ windowFormat.setGreenBufferSize(8);
+ windowFormat.setBlueBufferSize(8);
+ }
+
+ return windowFormat;
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/testlite/qtestlitewindow.h b/src/plugins/platforms/testlite/qtestlitewindow.h
index 4b952dc..e45c3fd 100644
--- a/src/plugins/platforms/testlite/qtestlitewindow.h
+++ b/src/plugins/platforms/testlite/qtestlitewindow.h
@@ -129,6 +129,8 @@ protected:
void doSizeHints();
private:
+ QPlatformWindowFormat correctColorBuffers(const QPlatformWindowFormat &windowFormat)const;
+
Window x_window;
GC gc;
diff --git a/src/plugins/platforms/testlite/testlite.pro b/src/plugins/platforms/testlite/testlite.pro
index eb196c3..7fb3304 100644
--- a/src/plugins/platforms/testlite/testlite.pro
+++ b/src/plugins/platforms/testlite/testlite.pro
@@ -9,22 +9,22 @@ SOURCES = \
qtestlitewindowsurface.cpp \
qtestlitewindow.cpp \
qtestlitecursor.cpp \
- qtestlitescreen.cpp \
- qtestlitekeyboard.cpp \
- qtestliteclipboard.cpp \
- qtestlitemime.cpp \
- qtestlitestaticinfo.cpp
+ qtestlitescreen.cpp \
+ qtestlitekeyboard.cpp \
+ qtestliteclipboard.cpp \
+ qtestlitemime.cpp \
+ qtestlitestaticinfo.cpp
HEADERS = \
qtestliteintegration.h \
qtestlitewindowsurface.h \
qtestlitewindow.h \
qtestlitecursor.h \
- qtestlitescreen.h \
- qtestlitekeyboard.h \
- qtestliteclipboard.h \
- qtestlitemime.h \
- qtestlitestaticinfo.h
+ qtestlitescreen.h \
+ qtestlitekeyboard.h \
+ qtestliteclipboard.h \
+ qtestlitemime.h \
+ qtestlitestaticinfo.h
LIBS += -lX11 -lXext
@@ -36,8 +36,21 @@ include (../fontdatabases/genericunix/genericunix.pri)
contains(QT_CONFIG, opengl) {
QT += opengl
- HEADERS += qglxintegration.h
- SOURCES += qglxintegration.cpp
+ !contains(QT_CONFIG, opengles2) {
+ HEADERS += qglxintegration.h
+ SOURCES += qglxintegration.cpp
+ } else { # There is no easy way to detect if we'r suppose to use glx or not
+ HEADERS += \
+ ../eglconvenience/qeglplatformcontext.h \
+ ../eglconvenience/qeglconvenience.h \
+ qtestliteeglintegration.h
+
+ SOURCES += \
+ ../eglconvenience/qeglplatformcontext.cpp \
+ ../eglconvenience/qeglconvenience.cpp \
+ qtestliteeglintegration.cpp
+ LIBS += -lEGL
+ }
}
target.path += $$[QT_INSTALL_PLUGINS]/platforms