diff options
author | Jørgen Lind <jorgen.lind@nokia.com> | 2011-01-05 16:14:54 (GMT) |
---|---|---|
committer | Jørgen Lind <jorgen.lind@nokia.com> | 2011-01-05 16:17:46 (GMT) |
commit | cc8877068dc6ae8f3142ffec0b85f6fbac4a0d81 (patch) | |
tree | 90008cb66bc91d38b230dd6ec561352a666346bf /src/plugins/platforms | |
parent | 1462a7ba51d25a7d022eab5533885cb1ed1c4c5c (diff) | |
download | Qt-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.
Diffstat (limited to 'src/plugins/platforms')
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 |