From 56d32b57814cb35409bc9b0076ec753de488ae7f Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Tue, 16 Feb 2010 09:38:23 +0100 Subject: Move qegl_p.h -> qeglcontext_p.h and add a new qegl_p.h This puts the QEgl namespace in a single file which can be used by both qeglcontext and qeglproperties. Files which need QEglContext should now include qeglcontext_p.h. Reviewed-By: Aleksandar Sasha Babic --- src/gui/egl/egl.pri | 1 + src/gui/egl/qegl.cpp | 3 + src/gui/egl/qegl_p.h | 108 +++++++++++------------------ src/gui/egl/qegl_qws.cpp | 2 + src/gui/egl/qegl_symbian.cpp | 2 + src/gui/egl/qegl_wince.cpp | 2 + src/gui/egl/qegl_x11.cpp | 3 +- src/gui/egl/qeglcontext_p.h | 130 +++++++++++++++++++++++++++++++++++ src/gui/egl/qeglproperties.cpp | 3 +- src/gui/egl/qeglproperties_p.h | 42 +---------- src/opengl/qgl_egl_p.h | 3 +- src/opengl/qgl_wince.cpp | 3 +- src/opengl/qpixmapdata_x11gl_egl.cpp | 1 + src/opengl/qwindowsurface_gl.cpp | 2 +- src/openvg/qpaintengine_vg.cpp | 2 +- src/openvg/qvg_p.h | 2 +- src/openvg/qwindowsurface_vg.cpp | 2 +- src/openvg/qwindowsurface_vgegl_p.h | 2 +- 18 files changed, 196 insertions(+), 117 deletions(-) create mode 100644 src/gui/egl/qeglcontext_p.h diff --git a/src/gui/egl/egl.pri b/src/gui/egl/egl.pri index 669d311..b90b9b0 100644 --- a/src/gui/egl/egl.pri +++ b/src/gui/egl/egl.pri @@ -2,6 +2,7 @@ CONFIG += egl HEADERS += \ egl/qegl_p.h \ + egl/qeglcontext_p.h \ egl/qeglproperties_p.h SOURCES += \ diff --git a/src/gui/egl/qegl.cpp b/src/gui/egl/qegl.cpp index 0ed95ea..5052dfc 100644 --- a/src/gui/egl/qegl.cpp +++ b/src/gui/egl/qegl.cpp @@ -43,7 +43,10 @@ #include #include #include + #include "qegl_p.h" +#include "qeglcontext_p.h" + QT_BEGIN_NAMESPACE diff --git a/src/gui/egl/qegl_p.h b/src/gui/egl/qegl_p.h index 87ed818..eb83002 100644 --- a/src/gui/egl/qegl_p.h +++ b/src/gui/egl/qegl_p.h @@ -53,13 +53,34 @@ // We mean it. // -#include -#include +QT_BEGIN_INCLUDE_NAMESPACE -#include +#if defined(QT_GLES_EGL) +#include +#else +#include +#endif -QT_BEGIN_INCLUDE_NAMESPACE +#if defined(Q_WS_X11) +// If included , then the global namespace +// may have been polluted with X #define's. The following makes sure +// the X11 headers were included properly and then cleans things up. +#include +#include +#undef Bool +#undef Status +#undef None +#undef KeyPress +#undef KeyRelease +#undef FocusIn +#undef FocusOut +#undef Type +#undef FontChange +#undef CursorShape +#endif +// Internally we use the EGL-prefixed native types which are used in EGL >= 1.3. +// For older versions of EGL, we have to define these types ourselves here: #if !defined(EGL_VERSION_1_3) && !defined(QEGL_NATIVE_TYPES_DEFINED) #undef EGLNativeWindowType #undef EGLNativePixmapType @@ -69,74 +90,27 @@ typedef NativePixmapType EGLNativePixmapType; typedef NativeDisplayType EGLNativeDisplayType; #define QEGL_NATIVE_TYPES_DEFINED 1 #endif -QT_END_INCLUDE_NAMESPACE - -QT_BEGIN_NAMESPACE - -class Q_GUI_EXPORT QEglContext -{ -public: - QEglContext(); - ~QEglContext(); - - bool isValid() const; - bool isCurrent() const; - bool isSharing() const { return sharing; } - - QEgl::API api() const { return apiType; } - void setApi(QEgl::API api) { apiType = api; } - - bool chooseConfig(const QEglProperties& properties, QEgl::PixelFormatMatch match = QEgl::ExactPixelFormat); - bool createContext(QEglContext *shareContext = 0, const QEglProperties *properties = 0); - void destroyContext(); - EGLSurface createSurface(QPaintDevice *device, const QEglProperties *properties = 0); - void destroySurface(EGLSurface surface); - - bool makeCurrent(EGLSurface surface); - bool doneCurrent(); - bool lazyDoneCurrent(); - bool swapBuffers(EGLSurface surface); - void waitNative(); - void waitClient(); - - bool configAttrib(int name, EGLint *value) const; - - static void clearError() { eglGetError(); } - static EGLint error() { return eglGetError(); } - static QString errorString(EGLint code); - - static EGLDisplay display(); - - EGLContext context() const { return ctx; } - void setContext(EGLContext context) { ctx = context; ownsContext = false;} - - EGLConfig config() const { return cfg; } - void setConfig(EGLConfig config) { cfg = config; } - - QEglProperties configProperties(EGLConfig cfg = 0) const; - - void dumpAllConfigs(); - - static QString extensions(); - static bool hasExtension(const char* extensionName); +QT_END_INCLUDE_NAMESPACE -private: - QEgl::API apiType; - EGLContext ctx; - EGLConfig cfg; - EGLSurface currentSurface; - bool current; - bool ownsContext; - bool sharing; - static EGLDisplay dpy; - static EGLNativeDisplayType nativeDisplay(); +QT_BEGIN_NAMESPACE - static QEglContext *currentContext(QEgl::API api); - static void setCurrentContext(QEgl::API api, QEglContext *context); +namespace QEgl { + enum API + { + OpenGL, + OpenVG + }; + + enum PixelFormatMatch + { + ExactPixelFormat, + BestPixelFormat + }; }; + QT_END_NAMESPACE -#endif // QEGL_P_H +#endif //QEGL_P_H diff --git a/src/gui/egl/qegl_qws.cpp b/src/gui/egl/qegl_qws.cpp index 2a61beb..a40c236 100644 --- a/src/gui/egl/qegl_qws.cpp +++ b/src/gui/egl/qegl_qws.cpp @@ -42,7 +42,9 @@ #include #include #include + #include "qegl_p.h" +#include "qeglcontext_p.h" #if !defined(QT_NO_EGL) diff --git a/src/gui/egl/qegl_symbian.cpp b/src/gui/egl/qegl_symbian.cpp index 5a010cd..0c91fd8 100644 --- a/src/gui/egl/qegl_symbian.cpp +++ b/src/gui/egl/qegl_symbian.cpp @@ -42,7 +42,9 @@ #include #include #include + #include "qegl_p.h" +#include "qeglcontext_p.h" #include diff --git a/src/gui/egl/qegl_wince.cpp b/src/gui/egl/qegl_wince.cpp index c9c9773..00341ba 100644 --- a/src/gui/egl/qegl_wince.cpp +++ b/src/gui/egl/qegl_wince.cpp @@ -42,7 +42,9 @@ #include #include #include + #include "qegl_p.h" +#include "qeglcontext_p.h" #include diff --git a/src/gui/egl/qegl_x11.cpp b/src/gui/egl/qegl_x11.cpp index 634ff13..cd55849 100644 --- a/src/gui/egl/qegl_x11.cpp +++ b/src/gui/egl/qegl_x11.cpp @@ -49,8 +49,9 @@ #include #include #include -#include "qegl_p.h" +#include "qegl_p.h" +#include "qeglcontext_p.h" QT_BEGIN_NAMESPACE diff --git a/src/gui/egl/qeglcontext_p.h b/src/gui/egl/qeglcontext_p.h new file mode 100644 index 0000000..3857fb7 --- /dev/null +++ b/src/gui/egl/qeglcontext_p.h @@ -0,0 +1,130 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QEGLCONTEXT_P_H +#define QEGLCONTEXT_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience of +// the QtOpenGL and QtOpenVG modules. This header file may change from +// version to version without notice, or even be removed. +// +// We mean it. +// + +#include +#include + +#include +#include + +QT_BEGIN_NAMESPACE + +class Q_GUI_EXPORT QEglContext +{ +public: + QEglContext(); + ~QEglContext(); + + bool isValid() const; + bool isCurrent() const; + bool isSharing() const { return sharing; } + + QEgl::API api() const { return apiType; } + void setApi(QEgl::API api) { apiType = api; } + + bool chooseConfig(const QEglProperties& properties, QEgl::PixelFormatMatch match = QEgl::ExactPixelFormat); + bool createContext(QEglContext *shareContext = 0, const QEglProperties *properties = 0); + void destroyContext(); + EGLSurface createSurface(QPaintDevice *device, const QEglProperties *properties = 0); + void destroySurface(EGLSurface surface); + + bool makeCurrent(EGLSurface surface); + bool doneCurrent(); + bool lazyDoneCurrent(); + bool swapBuffers(EGLSurface surface); + + void waitNative(); + void waitClient(); + + bool configAttrib(int name, EGLint *value) const; + + static void clearError() { eglGetError(); } + static EGLint error() { return eglGetError(); } + static QString errorString(EGLint code); + + static EGLDisplay display(); + + EGLContext context() const { return ctx; } + void setContext(EGLContext context) { ctx = context; ownsContext = false;} + + EGLConfig config() const { return cfg; } + void setConfig(EGLConfig config) { cfg = config; } + + QEglProperties configProperties(EGLConfig cfg = 0) const; + + void dumpAllConfigs(); + + static QString extensions(); + static bool hasExtension(const char* extensionName); + +private: + QEgl::API apiType; + EGLContext ctx; + EGLConfig cfg; + EGLSurface currentSurface; + bool current; + bool ownsContext; + bool sharing; + + static EGLDisplay dpy; + static EGLNativeDisplayType nativeDisplay(); + + static QEglContext *currentContext(QEgl::API api); + static void setCurrentContext(QEgl::API api, QEglContext *context); +}; + +QT_END_NAMESPACE + +#endif // QEGLCONTEXT_P_H diff --git a/src/gui/egl/qeglproperties.cpp b/src/gui/egl/qeglproperties.cpp index 236ec37..b83ae4e 100644 --- a/src/gui/egl/qeglproperties.cpp +++ b/src/gui/egl/qeglproperties.cpp @@ -46,7 +46,8 @@ QT_BEGIN_NAMESPACE #include #include -#include "qegl_p.h" +#include "qeglproperties_p.h" +#include "qeglcontext_p.h" // Initialize a property block. diff --git a/src/gui/egl/qeglproperties_p.h b/src/gui/egl/qeglproperties_p.h index feed1d2..496847b 100644 --- a/src/gui/egl/qeglproperties_p.h +++ b/src/gui/egl/qeglproperties_p.h @@ -56,50 +56,10 @@ #include #include -QT_BEGIN_INCLUDE_NAMESPACE - -#if defined(QT_GLES_EGL) -#include -#else -#include -#endif - -#if defined(Q_WS_X11) -// If included , then the global namespace -// may have been polluted with X #define's. The following makes sure -// the X11 headers were included properly and then cleans things up. -#include -#include -#undef Bool -#undef Status -#undef None -#undef KeyPress -#undef KeyRelease -#undef FocusIn -#undef FocusOut -#undef Type -#undef FontChange -#undef CursorShape -#endif - -QT_END_INCLUDE_NAMESPACE +#include QT_BEGIN_NAMESPACE -namespace QEgl { - enum API - { - OpenGL, - OpenVG - }; - - enum PixelFormatMatch - { - ExactPixelFormat, - BestPixelFormat - }; -}; - class QX11Info; class QPaintDevice; diff --git a/src/opengl/qgl_egl_p.h b/src/opengl/qgl_egl_p.h index c503724..518b500 100644 --- a/src/opengl/qgl_egl_p.h +++ b/src/opengl/qgl_egl_p.h @@ -53,7 +53,8 @@ // We mean it. // -#include +#include +#include QT_BEGIN_NAMESPACE diff --git a/src/opengl/qgl_wince.cpp b/src/opengl/qgl_wince.cpp index f81115c..2b71201 100644 --- a/src/opengl/qgl_wince.cpp +++ b/src/opengl/qgl_wince.cpp @@ -54,7 +54,8 @@ #include -#include +#include +#include #include #include diff --git a/src/opengl/qpixmapdata_x11gl_egl.cpp b/src/opengl/qpixmapdata_x11gl_egl.cpp index 6a1d030..4f1543c 100644 --- a/src/opengl/qpixmapdata_x11gl_egl.cpp +++ b/src/opengl/qpixmapdata_x11gl_egl.cpp @@ -44,6 +44,7 @@ #include #include #include +#include #if !defined(QT_OPENGL_ES_1) #include diff --git a/src/opengl/qwindowsurface_gl.cpp b/src/opengl/qwindowsurface_gl.cpp index 4ac4a3a..0334cbc 100644 --- a/src/opengl/qwindowsurface_gl.cpp +++ b/src/opengl/qwindowsurface_gl.cpp @@ -83,7 +83,7 @@ #endif #ifdef QT_OPENGL_ES -#include +#include #endif QT_BEGIN_NAMESPACE diff --git a/src/openvg/qpaintengine_vg.cpp b/src/openvg/qpaintengine_vg.cpp index 35f552e..47ce11c 100644 --- a/src/openvg/qpaintengine_vg.cpp +++ b/src/openvg/qpaintengine_vg.cpp @@ -45,7 +45,7 @@ #include "qvgcompositionhelper_p.h" #include "qvgimagepool_p.h" #if !defined(QT_NO_EGL) -#include +#include #include "qwindowsurface_vgegl_p.h" #endif #include diff --git a/src/openvg/qvg_p.h b/src/openvg/qvg_p.h index 7857bb6..51abbee 100644 --- a/src/openvg/qvg_p.h +++ b/src/openvg/qvg_p.h @@ -58,7 +58,7 @@ #include #if !defined(QT_NO_EGL) -#include +#include #endif QT_BEGIN_NAMESPACE diff --git a/src/openvg/qwindowsurface_vg.cpp b/src/openvg/qwindowsurface_vg.cpp index 83b0764..07d9209 100644 --- a/src/openvg/qwindowsurface_vg.cpp +++ b/src/openvg/qwindowsurface_vg.cpp @@ -47,7 +47,7 @@ #if !defined(QT_NO_EGL) -#include +#include #include QT_BEGIN_NAMESPACE diff --git a/src/openvg/qwindowsurface_vgegl_p.h b/src/openvg/qwindowsurface_vgegl_p.h index aa0c648..f6adbf3 100644 --- a/src/openvg/qwindowsurface_vgegl_p.h +++ b/src/openvg/qwindowsurface_vgegl_p.h @@ -58,7 +58,7 @@ #if !defined(QT_NO_EGL) -#include +#include QT_BEGIN_NAMESPACE -- cgit v0.12 From 28b85c76dd0ba4796ec519b890f6fab0fc813061 Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Tue, 16 Feb 2010 13:29:36 +0100 Subject: Move static methods from QEglContext to QEgl namespace Reviewed-By: Aleksandar Sasha Babic --- src/gui/egl/qegl.cpp | 83 +++++++++++++++++++----------------- src/gui/egl/qegl_p.h | 18 ++++++++ src/gui/egl/qegl_wince.cpp | 6 +-- src/gui/egl/qegl_x11.cpp | 8 ++-- src/gui/egl/qeglcontext_p.h | 18 ++------ src/gui/egl/qeglproperties.cpp | 6 +-- src/opengl/qgl_egl.cpp | 2 +- src/opengl/qgl_x11egl.cpp | 20 ++++----- src/opengl/qglpixelbuffer_egl.cpp | 4 +- src/opengl/qpixmapdata_x11gl_egl.cpp | 20 ++++----- 10 files changed, 97 insertions(+), 88 deletions(-) diff --git a/src/gui/egl/qegl.cpp b/src/gui/egl/qegl.cpp index 5052dfc..ef5eb67 100644 --- a/src/gui/egl/qegl.cpp +++ b/src/gui/egl/qegl.cpp @@ -57,8 +57,6 @@ QT_BEGIN_NAMESPACE static QEglContext * volatile currentGLContext = 0; static QEglContext * volatile currentVGContext = 0; -EGLDisplay QEglContext::dpy = EGL_NO_DISPLAY; - QEglContext::QEglContext() : apiType(QEgl::OpenGL) , ctx(EGL_NO_CONTEXT) @@ -98,7 +96,8 @@ bool QEglContext::chooseConfig do { // Get the number of matching configurations for this set of properties. EGLint matching = 0; - if (!eglChooseConfig(display(), props.properties(), 0, 0, &matching) || !matching) + EGLDisplay dpy = QEgl::display(); + if (!eglChooseConfig(dpy, props.properties(), 0, 0, &matching) || !matching) continue; // If we want the best pixel format, then return the first @@ -145,7 +144,7 @@ bool QEglContext::chooseConfig qWarning() << "QEglContext::chooseConfig(): Could not find a suitable EGL configuration"; qWarning() << "Requested:" << props.toString(); qWarning() << "Available:"; - dumpAllConfigs(); + QEgl::dumpAllConfigs(); } return false; } @@ -175,9 +174,9 @@ bool QEglContext::createContext(QEglContext *shareContext, const QEglProperties if (shareContext && shareContext->ctx == EGL_NO_CONTEXT) shareContext = 0; if (shareContext) { - ctx = eglCreateContext(display(), cfg, shareContext->ctx, contextProps.properties()); + ctx = eglCreateContext(QEgl::display(), cfg, shareContext->ctx, contextProps.properties()); if (ctx == EGL_NO_CONTEXT) { - qWarning() << "QEglContext::createContext(): Could not share context:" << errorString(eglGetError()); + qWarning() << "QEglContext::createContext(): Could not share context:" << QEgl::errorString(); shareContext = 0; } else { sharing = true; @@ -186,7 +185,7 @@ bool QEglContext::createContext(QEglContext *shareContext, const QEglProperties if (ctx == EGL_NO_CONTEXT) { ctx = eglCreateContext(display(), cfg, 0, contextProps.properties()); if (ctx == EGL_NO_CONTEXT) { - qWarning() << "QEglContext::createContext(): Unable to create EGL context:" << errorString(eglGetError()); + qWarning() << "QEglContext::createContext(): Unable to create EGL context:" << QEgl::errorString(); return false; } } @@ -243,9 +242,9 @@ bool QEglContext::makeCurrent(EGLSurface surface) eglBindAPI(EGL_OPENVG_API); #endif - bool ok = eglMakeCurrent(display(), surface, surface, ctx); + bool ok = eglMakeCurrent(QEgl::display(), surface, surface, ctx); if (!ok) - qWarning() << "QEglContext::makeCurrent():" << errorString(eglGetError()); + qWarning() << "QEglContext::makeCurrent():" << QEgl::errorString(); return ok; } @@ -272,9 +271,9 @@ bool QEglContext::doneCurrent() eglBindAPI(EGL_OPENVG_API); #endif - bool ok = eglMakeCurrent(display(), EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); + bool ok = eglMakeCurrent(QEgl::display(), EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); if (!ok) - qWarning() << "QEglContext::doneCurrent():" << errorString(eglGetError()); + qWarning() << "QEglContext::doneCurrent():" << QEgl::errorString(); return ok; } @@ -294,9 +293,9 @@ bool QEglContext::swapBuffers(EGLSurface surface) if(ctx == EGL_NO_CONTEXT) return false; - bool ok = eglSwapBuffers(display(), surface); + bool ok = eglSwapBuffers(QEgl::display(), surface); if (!ok) - qWarning() << "QEglContext::swapBuffers():" << errorString(eglGetError()); + qWarning() << "QEglContext::swapBuffers():" << QEgl::errorString(); return ok; } @@ -333,43 +332,33 @@ void QEglContext::waitClient() // Query the value of a configuration attribute. bool QEglContext::configAttrib(int name, EGLint *value) const { - return eglGetConfigAttrib(display(), cfg, name, value); + return eglGetConfigAttrib(QEgl::display(), cfg, name, value); } -// Retrieve all of the properties on "cfg". If zero, return -// the context's configuration. -QEglProperties QEglContext::configProperties(EGLConfig cfg) const +QEglProperties QEglContext::configProperties() const { - if (!cfg) - cfg = config(); - QEglProperties props; - for (int name = 0x3020; name <= 0x304F; ++name) { - EGLint value; - if (name != EGL_NONE && eglGetConfigAttrib(display(), cfg, name, &value)) - props.setValue(name, value); - } - eglGetError(); // Clear the error state. - return props; + return QEglProperties(config()); } -EGLDisplay QEglContext::display() +EGLDisplay QEgl::display() { + static EGLDisplay dpy = EGL_NO_DISPLAY; static bool openedDisplay = false; if (!openedDisplay) { dpy = eglGetDisplay(nativeDisplay()); openedDisplay = true; if (dpy == EGL_NO_DISPLAY) { - qWarning("QEglContext::display(): Falling back to EGL_DEFAULT_DISPLAY"); + qWarning("QEgl::display(): Falling back to EGL_DEFAULT_DISPLAY"); dpy = eglGetDisplay(EGLNativeDisplayType(EGL_DEFAULT_DISPLAY)); } if (dpy == EGL_NO_DISPLAY) { - qWarning("QEglContext::display(): Can't even open the default display"); + qWarning("QEgl::display(): Can't even open the default display"); return EGL_NO_DISPLAY; } if (!eglInitialize(dpy, NULL, NULL)) { - qWarning() << "QEglContext::display(): Cannot initialize EGL display:" << errorString(eglGetError()); + qWarning() << "QEgl::display(): Cannot initialize EGL display:" << QEgl::errorString(); return EGL_NO_DISPLAY; } } @@ -378,14 +367,14 @@ EGLDisplay QEglContext::display() } #if !defined(Q_WS_X11) && !defined(Q_WS_WINCE) // WinCE & X11 implement this properly -EGLNativeDisplayType QEglContext::nativeDisplay() +EGLNativeDisplayType QEgl::nativeDisplay() { return EGL_DEFAULT_DISPLAY; } #endif // Return the error string associated with a specific code. -QString QEglContext::errorString(EGLint code) +QString QEgl::errorString(EGLint code) { static const char * const errors[] = { "Success (0x3000)", // No tr @@ -411,8 +400,24 @@ QString QEglContext::errorString(EGLint code) } } +QString QEgl::errorString() +{ + return errorString(error()); +} + +void QEgl::clearError() +{ + eglGetError(); +} + +EGLint QEgl::error() +{ + return eglGetError(); +} + + // Dump all of the EGL configurations supported by the system. -void QEglContext::dumpAllConfigs() +void QEgl::dumpAllConfigs() { QEglProperties props; EGLint count = 0; @@ -421,23 +426,23 @@ void QEglContext::dumpAllConfigs() EGLConfig *configs = new EGLConfig [count]; eglGetConfigs(display(), configs, count, &count); for (EGLint index = 0; index < count; ++index) { - props = configProperties(configs[index]); + props = QEglProperties(configs[index]); qWarning() << props.toString(); } delete [] configs; } -QString QEglContext::extensions() +QString QEgl::extensions() { - const char* exts = eglQueryString(QEglContext::display(), EGL_EXTENSIONS); + const char* exts = eglQueryString(QEgl::display(), EGL_EXTENSIONS); return QString(QLatin1String(exts)); } -bool QEglContext::hasExtension(const char* extensionName) +bool QEgl::hasExtension(const char* extensionName) { QList extensions = QByteArray(reinterpret_cast - (eglQueryString(QEglContext::display(), EGL_EXTENSIONS))).split(' '); + (eglQueryString(QEgl::display(), EGL_EXTENSIONS))).split(' '); return extensions.contains(extensionName); } diff --git a/src/gui/egl/qegl_p.h b/src/gui/egl/qegl_p.h index eb83002..e48e4a0 100644 --- a/src/gui/egl/qegl_p.h +++ b/src/gui/egl/qegl_p.h @@ -96,6 +96,8 @@ QT_END_INCLUDE_NAMESPACE QT_BEGIN_NAMESPACE +class QEglProperties; + namespace QEgl { enum API { @@ -108,6 +110,22 @@ namespace QEgl { ExactPixelFormat, BestPixelFormat }; + +// EGLConfig chooseConfig(const QEglProperties* properties, QEgl::PixelFormatMatch match = QEgl::ExactPixelFormat); +// EGLSurface createSurface(QPaintDevice *device, EGLConfig config, const QEglProperties *properties = 0); + + Q_GUI_EXPORT void dumpAllConfigs(); + + Q_GUI_EXPORT void clearError(); + Q_GUI_EXPORT EGLint error(); + Q_GUI_EXPORT QString errorString(EGLint code); + Q_GUI_EXPORT QString errorString(); + + Q_GUI_EXPORT QString extensions(); + Q_GUI_EXPORT bool hasExtension(const char* extensionName); + + Q_GUI_EXPORT EGLDisplay display(); + Q_GUI_EXPORT EGLNativeDisplayType nativeDisplay(); }; diff --git a/src/gui/egl/qegl_wince.cpp b/src/gui/egl/qegl_wince.cpp index 00341ba..2f79005 100644 --- a/src/gui/egl/qegl_wince.cpp +++ b/src/gui/egl/qegl_wince.cpp @@ -80,16 +80,16 @@ EGLSurface QEglContext::createSurface(QPaintDevice *device, const QEglProperties props = 0; EGLSurface surf; if (devType == QInternal::Widget) - surf = eglCreateWindowSurface(dpy, cfg, windowDrawable, props); + surf = eglCreateWindowSurface(QEgl::display(), cfg, windowDrawable, props); else - surf = eglCreatePixmapSurface(dpy, cfg, pixmapDrawable, props); + surf = eglCreatePixmapSurface(QEgl::display(), cfg, pixmapDrawable, props); if (surf == EGL_NO_SURFACE) { qWarning("QEglContext::createSurface(): Unable to create EGL surface, error = 0x%x", eglGetError()); } return surf; } -EGLNativeDisplayType QEglContext::nativeDisplay() +EGLNativeDisplayType QEgl::nativeDisplay() { HWND win = (static_cast(device))->winId(); HDC myDc = GetDC(win); diff --git a/src/gui/egl/qegl_x11.cpp b/src/gui/egl/qegl_x11.cpp index cd55849..4a813c6 100644 --- a/src/gui/egl/qegl_x11.cpp +++ b/src/gui/egl/qegl_x11.cpp @@ -84,17 +84,17 @@ EGLSurface QEglContext::createSurface(QPaintDevice *device, const QEglProperties props = 0; EGLSurface surf; if (devType == QInternal::Widget) - surf = eglCreateWindowSurface(dpy, cfg, windowDrawable, props); + surf = eglCreateWindowSurface(QEgl::display(), cfg, windowDrawable, props); else - surf = eglCreatePixmapSurface(dpy, cfg, pixmapDrawable, props); + surf = eglCreatePixmapSurface(QEgl::display(), cfg, pixmapDrawable, props); if (surf == EGL_NO_SURFACE) { qWarning() << "QEglContext::createSurface(): Unable to create EGL surface:" - << errorString(eglGetError()); + << QEgl::errorString(); } return surf; } -EGLNativeDisplayType QEglContext::nativeDisplay() +EGLNativeDisplayType QEgl::nativeDisplay() { Display *xdpy = QX11Info::display(); if (!xdpy) { diff --git a/src/gui/egl/qeglcontext_p.h b/src/gui/egl/qeglcontext_p.h index 3857fb7..c656d1d 100644 --- a/src/gui/egl/qeglcontext_p.h +++ b/src/gui/egl/qeglcontext_p.h @@ -90,24 +90,15 @@ public: bool configAttrib(int name, EGLint *value) const; - static void clearError() { eglGetError(); } - static EGLint error() { return eglGetError(); } - static QString errorString(EGLint code); - - static EGLDisplay display(); - EGLContext context() const { return ctx; } void setContext(EGLContext context) { ctx = context; ownsContext = false;} + EGLDisplay display() {return QEgl::display();} + EGLConfig config() const { return cfg; } void setConfig(EGLConfig config) { cfg = config; } - QEglProperties configProperties(EGLConfig cfg = 0) const; - - void dumpAllConfigs(); - - static QString extensions(); - static bool hasExtension(const char* extensionName); + QEglProperties configProperties() const; private: QEgl::API apiType; @@ -118,9 +109,6 @@ private: bool ownsContext; bool sharing; - static EGLDisplay dpy; - static EGLNativeDisplayType nativeDisplay(); - static QEglContext *currentContext(QEgl::API api); static void setCurrentContext(QEgl::API api, QEglContext *context); }; diff --git a/src/gui/egl/qeglproperties.cpp b/src/gui/egl/qeglproperties.cpp index b83ae4e..86e158b 100644 --- a/src/gui/egl/qeglproperties.cpp +++ b/src/gui/egl/qeglproperties.cpp @@ -61,7 +61,7 @@ QEglProperties::QEglProperties(EGLConfig cfg) props.append(EGL_NONE); for (int name = 0x3020; name <= 0x304F; ++name) { EGLint value; - if (name != EGL_NONE && eglGetConfigAttrib(QEglContext::display(), cfg, name, &value)) + if (name != EGL_NONE && eglGetConfigAttrib(QEgl::display(), cfg, name, &value)) setValue(name, value); } eglGetError(); // Clear the error state. @@ -274,12 +274,12 @@ static void addTag(QString& str, const QString& tag) void QEglProperties::dumpAllConfigs() { EGLint count = 0; - eglGetConfigs(QEglContext::display(), 0, 0, &count); + eglGetConfigs(QEgl::display(), 0, 0, &count); if (count < 1) return; EGLConfig *configs = new EGLConfig [count]; - eglGetConfigs(QEglContext::display(), configs, count, &count); + eglGetConfigs(QEgl::display(), configs, count, &count); for (EGLint index = 0; index < count; ++index) qWarning() << QEglProperties(configs[index]).toString(); delete [] configs; diff --git a/src/opengl/qgl_egl.cpp b/src/opengl/qgl_egl.cpp index 3addea1..90fb2bb 100644 --- a/src/opengl/qgl_egl.cpp +++ b/src/opengl/qgl_egl.cpp @@ -126,7 +126,7 @@ void qt_egl_update_format(const QEglContext& context, QGLFormat& format) // Clear the EGL error state because some of the above may // have errored out because the attribute is not applicable // to the surface type. Such errors don't matter. - context.clearError(); + QEgl::clearError(); } bool QGLFormat::hasOpenGL() diff --git a/src/opengl/qgl_x11egl.cpp b/src/opengl/qgl_x11egl.cpp index 3d183ee..972a5f6 100644 --- a/src/opengl/qgl_x11egl.cpp +++ b/src/opengl/qgl_x11egl.cpp @@ -609,7 +609,7 @@ EGLConfig Q_OPENGL_EXPORT qt_chooseEGLConfigForPixmap(bool hasAlpha, bool readOn EGLint configCount = 0; do { - eglChooseConfig(QEglContext::display(), configAttribs.properties(), targetConfig, 1, &configCount); + eglChooseConfig(QEgl::display(), configAttribs.properties(), targetConfig, 1, &configCount); if (configCount > 0) { // Got one qDebug() << "Found an" << (hasAlpha ? "ARGB" : "RGB") << (readOnly ? "readonly" : "target" ) @@ -648,7 +648,7 @@ bool Q_OPENGL_EXPORT qt_createEGLSurfaceForPixmap(QPixmapData* pmd, bool readOnl pixmapAttribs.setValue(EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGB); EGLSurface pixmapSurface; - pixmapSurface = eglCreatePixmapSurface(QEglContext::display(), + pixmapSurface = eglCreatePixmapSurface(QEgl::display(), pixmapConfig, (EGLNativePixmapType) pixmapData->handle(), pixmapAttribs.properties()); @@ -656,7 +656,7 @@ bool Q_OPENGL_EXPORT qt_createEGLSurfaceForPixmap(QPixmapData* pmd, bool readOnl // pixmapSurface, pixmapData->handle()); if (pixmapSurface == EGL_NO_SURFACE) { qWarning() << "Failed to create a pixmap surface using config" << (int)pixmapConfig - << ":" << QEglContext::errorString(eglGetError()); + << ":" << QEgl::errorString(); return false; } @@ -693,8 +693,8 @@ QGLTexture *QGLContextPrivate::bindTextureFromNativePixmap(QPixmapData* pd, cons if (!checkedForTFP) { // Check for texture_from_pixmap egl extension checkedForTFP = true; - if (eglContext->hasExtension("EGL_NOKIA_texture_from_pixmap") || - eglContext->hasExtension("EGL_EXT_texture_from_pixmap")) + if (QEgl::hasExtension("EGL_NOKIA_texture_from_pixmap") || + QEgl::hasExtension("EGL_EXT_texture_from_pixmap")) { qDebug("Found texture_from_pixmap EGL extension!"); haveTFP = true; @@ -734,7 +734,7 @@ QGLTexture *QGLContextPrivate::bindTextureFromNativePixmap(QPixmapData* pd, cons EGLBoolean success; success = eglBindTexImage(eglContext->display(), (EGLSurface)pixmapData->gl_surface, EGL_BACK_BUFFER); if (success == EGL_FALSE) { - qWarning() << "eglBindTexImage() failed:" << eglContext->errorString(eglGetError()); + qWarning() << "eglBindTexImage() failed:" << QEgl::errorString(); eglDestroySurface(eglContext->display(), (EGLSurface)pixmapData->gl_surface); pixmapData->gl_surface = (Qt::HANDLE)EGL_NO_SURFACE; haveTFP = false; @@ -757,10 +757,10 @@ void QGLContextPrivate::destroyGlSurfaceForPixmap(QPixmapData* pmd) QX11PixmapData *pixmapData = static_cast(pmd); if (pixmapData->gl_surface) { EGLBoolean success; - success = eglDestroySurface(QEglContext::display(), (EGLSurface)pixmapData->gl_surface); + success = eglDestroySurface(QEgl::display(), (EGLSurface)pixmapData->gl_surface); if (success == EGL_FALSE) { qWarning() << "destroyGlSurfaceForPixmap() - Error deleting surface: " - << QEglContext::errorString(eglGetError()); + << QEgl::errorString(); } pixmapData->gl_surface = 0; } @@ -772,12 +772,12 @@ void QGLContextPrivate::unbindPixmapFromTexture(QPixmapData* pmd) QX11PixmapData *pixmapData = static_cast(pmd); if (pixmapData->gl_surface) { EGLBoolean success; - success = eglReleaseTexImage(QEglContext::display(), + success = eglReleaseTexImage(QEgl::display(), (EGLSurface)pixmapData->gl_surface, EGL_BACK_BUFFER); if (success == EGL_FALSE) { qWarning() << "unbindPixmapFromTexture() - Unable to release bound texture: " - << QEglContext::errorString(eglGetError()); + << QEgl::errorString(); } } } diff --git a/src/opengl/qglpixelbuffer_egl.cpp b/src/opengl/qglpixelbuffer_egl.cpp index 954049d..cee5a1f 100644 --- a/src/opengl/qglpixelbuffer_egl.cpp +++ b/src/opengl/qglpixelbuffer_egl.cpp @@ -137,7 +137,7 @@ bool QGLPixelBufferPrivate::init(const QSize &size, const QGLFormat &f, QGLWidge } #endif if (pbuf == EGL_NO_SURFACE) { - qWarning() << "QGLPixelBufferPrivate::init(): Unable to create EGL pbuffer surface:" << QEglContext::errorString(eglGetError()); + qWarning() << "QGLPixelBufferPrivate::init(): Unable to create EGL pbuffer surface:" << QEgl::errorString(); return false; } @@ -204,7 +204,7 @@ GLuint QGLPixelBuffer::generateDynamicTexture() const bool QGLPixelBuffer::hasOpenGLPbuffers() { // See if we have at least 1 configuration that matches the default format. - EGLDisplay dpy = QEglContext::display(); + EGLDisplay dpy = QEgl::display(); if (dpy == EGL_NO_DISPLAY) return false; QEglProperties configProps; diff --git a/src/opengl/qpixmapdata_x11gl_egl.cpp b/src/opengl/qpixmapdata_x11gl_egl.cpp index 4f1543c..811e554 100644 --- a/src/opengl/qpixmapdata_x11gl_egl.cpp +++ b/src/opengl/qpixmapdata_x11gl_egl.cpp @@ -97,14 +97,14 @@ bool QX11GLPixmapData::hasX11GLPixmaps() #endif EGL_NONE }; - qPixmapARGBSharedEglContext = eglCreateContext(QEglContext::display(), + qPixmapARGBSharedEglContext = eglCreateContext(QEgl::display(), argbConfig, 0, contextAttribs); if (argbConfig == rgbConfig) { // If the configs are the same, we can re-use the same context. qPixmapRGBSharedEglContext = qPixmapARGBSharedEglContext; } else { - qPixmapRGBSharedEglContext = eglCreateContext(QEglContext::display(), + qPixmapRGBSharedEglContext = eglCreateContext(QEgl::display(), rgbConfig, 0, contextAttribs); } @@ -115,13 +115,12 @@ bool QX11GLPixmapData::hasX11GLPixmaps() if (!qt_createEGLSurfaceForPixmap(argbPixmapData, false)) break; - haveX11Pixmaps = eglMakeCurrent(QEglContext::display(), + haveX11Pixmaps = eglMakeCurrent(QEgl::display(), (EGLSurface)argbPixmapData->gl_surface, (EGLSurface)argbPixmapData->gl_surface, qPixmapARGBSharedEglContext); if (!haveX11Pixmaps) { - EGLint err = eglGetError(); - qWarning() << "Unable to make pixmap config current:" << err << QEglContext::errorString(err); + qWarning() << "Unable to make pixmap config current:" << QEgl::errorString(); break; } @@ -135,20 +134,19 @@ bool QX11GLPixmapData::hasX11GLPixmaps() if (!qt_createEGLSurfaceForPixmap(rgbPixmapData, false)) break; - haveX11Pixmaps = eglMakeCurrent(QEglContext::display(), + haveX11Pixmaps = eglMakeCurrent(QEgl::display(), (EGLSurface)rgbPixmapData->gl_surface, (EGLSurface)rgbPixmapData->gl_surface, qPixmapRGBSharedEglContext); if (!haveX11Pixmaps) { - EGLint err = eglGetError(); - qWarning() << "Unable to make pixmap config current:" << err << QEglContext::errorString(err); + qWarning() << "Unable to make pixmap config current:" << QEgl::errorString(); break; } } } while (0); if (qPixmapARGBSharedEglContext || qPixmapRGBSharedEglContext) { - eglMakeCurrent(QEglContext::display(), + eglMakeCurrent(QEgl::display(), EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); } @@ -168,12 +166,12 @@ bool QX11GLPixmapData::hasX11GLPixmaps() if (!haveX11Pixmaps) { // Clean up the context(s) if we can't use X11GL pixmaps if (qPixmapARGBSharedEglContext != EGL_NO_CONTEXT) - eglDestroyContext(QEglContext::display(), qPixmapARGBSharedEglContext); + eglDestroyContext(QEgl::display(), qPixmapARGBSharedEglContext); if (qPixmapRGBSharedEglContext != qPixmapARGBSharedEglContext && qPixmapRGBSharedEglContext != EGL_NO_CONTEXT) { - eglDestroyContext(QEglContext::display(), qPixmapRGBSharedEglContext); + eglDestroyContext(QEgl::display(), qPixmapRGBSharedEglContext); } qPixmapRGBSharedEglContext = EGL_NO_CONTEXT; qPixmapARGBSharedEglContext = EGL_NO_CONTEXT; -- cgit v0.12 From 6378d3d0e851f6af3e518ff53351de3253368026 Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Tue, 16 Feb 2010 16:15:04 +0100 Subject: Move chooseConfig and createSurface logic to QEgl functions We keep the methods in QEglContext, but these are useful helpers which wrap the QEgl version of the functions, which is where the bulk of the logic is (for these functions anyway). Reviewed-By: Aleksandar Sasha Babic --- src/gui/egl/qegl.cpp | 24 ++++++++++++++++++------ src/gui/egl/qegl_p.h | 7 +++++-- src/gui/egl/qegl_qws.cpp | 3 ++- src/gui/egl/qegl_symbian.cpp | 2 +- src/gui/egl/qegl_wince.cpp | 2 +- src/gui/egl/qegl_x11.cpp | 2 +- 6 files changed, 28 insertions(+), 12 deletions(-) diff --git a/src/gui/egl/qegl.cpp b/src/gui/egl/qegl.cpp index ef5eb67..6d719ba 100644 --- a/src/gui/egl/qegl.cpp +++ b/src/gui/egl/qegl.cpp @@ -89,10 +89,10 @@ bool QEglContext::isCurrent() const } // Choose a configuration that matches "properties". -bool QEglContext::chooseConfig - (const QEglProperties& properties, QEgl::PixelFormatMatch match) +EGLConfig QEgl::chooseConfig(const QEglProperties* properties, QEgl::PixelFormatMatch match) { - QEglProperties props(properties); + QEglProperties props(*properties); + EGLConfig cfg = QEGL_NO_CONFIG; do { // Get the number of matching configurations for this set of properties. EGLint matching = 0; @@ -106,7 +106,7 @@ bool QEglContext::chooseConfig eglChooseConfig(display(), props.properties(), &cfg, 1, &matching); if (matching < 1) continue; - return true; + return cfg; } // Fetch all of the matching configurations and find the @@ -127,7 +127,7 @@ bool QEglContext::chooseConfig alpha == props.value(EGL_ALPHA_SIZE))) { cfg = configs[index]; delete [] configs; - return true; + return cfg; } } delete [] configs; @@ -146,9 +146,21 @@ bool QEglContext::chooseConfig qWarning() << "Available:"; QEgl::dumpAllConfigs(); } - return false; + return QEGL_NO_CONFIG; } +bool QEglContext::chooseConfig(const QEglProperties& properties, QEgl::PixelFormatMatch match) +{ + cfg = QEgl::chooseConfig(&properties, match); + return cfg != QEGL_NO_CONFIG; +} + +EGLSurface QEglContext::createSurface(QPaintDevice* device, const QEglProperties *properties) +{ + return QEgl::createSurface(device, cfg, properties); +} + + // Create the EGLContext. bool QEglContext::createContext(QEglContext *shareContext, const QEglProperties *properties) { diff --git a/src/gui/egl/qegl_p.h b/src/gui/egl/qegl_p.h index e48e4a0..a50e4e1 100644 --- a/src/gui/egl/qegl_p.h +++ b/src/gui/egl/qegl_p.h @@ -93,9 +93,12 @@ typedef NativeDisplayType EGLNativeDisplayType; QT_END_INCLUDE_NAMESPACE +#include QT_BEGIN_NAMESPACE +#define QEGL_NO_CONFIG ((EGLConfig)-1) + class QEglProperties; namespace QEgl { @@ -111,8 +114,8 @@ namespace QEgl { BestPixelFormat }; -// EGLConfig chooseConfig(const QEglProperties* properties, QEgl::PixelFormatMatch match = QEgl::ExactPixelFormat); -// EGLSurface createSurface(QPaintDevice *device, EGLConfig config, const QEglProperties *properties = 0); + Q_GUI_EXPORT EGLConfig chooseConfig(const QEglProperties* configAttribs, QEgl::PixelFormatMatch match = QEgl::ExactPixelFormat); + Q_GUI_EXPORT EGLSurface createSurface(QPaintDevice *device, EGLConfig cfg, const QEglProperties *surfaceAttribs = 0); Q_GUI_EXPORT void dumpAllConfigs(); diff --git a/src/gui/egl/qegl_qws.cpp b/src/gui/egl/qegl_qws.cpp index a40c236..935fe67 100644 --- a/src/gui/egl/qegl_qws.cpp +++ b/src/gui/egl/qegl_qws.cpp @@ -59,9 +59,10 @@ QT_BEGIN_NAMESPACE // We don't have QGLScreen to create EGL surfaces for us, // so surface creation needs to be done in QtOpenGL or // QtOpenVG for Qt/Embedded. -EGLSurface QEglContext::createSurface(QPaintDevice *device, const QEglProperties *properties) +EGLSurface QEgl::createSurface(QPaintDevice *device, EGLConfig cfg, const QEglProperties *properties) { Q_UNUSED(device); + Q_UNUSED(cfg); Q_UNUSED(properties); return EGL_NO_SURFACE; } diff --git a/src/gui/egl/qegl_symbian.cpp b/src/gui/egl/qegl_symbian.cpp index 0c91fd8..2276ce0 100644 --- a/src/gui/egl/qegl_symbian.cpp +++ b/src/gui/egl/qegl_symbian.cpp @@ -50,7 +50,7 @@ QT_BEGIN_NAMESPACE -EGLSurface QEglContext::createSurface(QPaintDevice *device, const QEglProperties *properties) +EGLSurface QEgl::createSurface(QPaintDevice *device, EGLConfig cfg, const QEglProperties *properties) { // Create the native drawable for the paint device. int devType = device->devType(); diff --git a/src/gui/egl/qegl_wince.cpp b/src/gui/egl/qegl_wince.cpp index 2f79005..fae491b 100644 --- a/src/gui/egl/qegl_wince.cpp +++ b/src/gui/egl/qegl_wince.cpp @@ -51,7 +51,7 @@ QT_BEGIN_NAMESPACE -EGLSurface QEglContext::createSurface(QPaintDevice *device, const QEglProperties *properties) +EGLSurface QEgl::createSurface(QPaintDevice *device, EGLConfig cfg, const QEglProperties *properties) { // Create the native drawable for the paint device. int devType = device->devType(); diff --git a/src/gui/egl/qegl_x11.cpp b/src/gui/egl/qegl_x11.cpp index 4a813c6..d24727a 100644 --- a/src/gui/egl/qegl_x11.cpp +++ b/src/gui/egl/qegl_x11.cpp @@ -55,7 +55,7 @@ QT_BEGIN_NAMESPACE -EGLSurface QEglContext::createSurface(QPaintDevice *device, const QEglProperties *properties) +EGLSurface QEgl::createSurface(QPaintDevice *device, EGLConfig cfg, const QEglProperties *properties) { // Create the native drawable for the paint device. int devType = device->devType(); -- cgit v0.12 From d0a2d10dfac7be20af78988a3351d374acfdd208 Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Tue, 16 Feb 2010 17:38:25 +0100 Subject: Make QEgl::createSurface cross-platform and add native getters QEgl::createSurface was virtually identical for every platform apart from the line which returned the native window type. This patch just adds QEgl::nativePixmap and QEgl::nativeWindow which are platform specific (though the default widget->winId() works for everything apart from symbian). Reviewed-By: Aleksandar Sasha Babic --- src/gui/egl/qegl.cpp | 52 ++++++++++++++++++++++++++++++++++++++++++++ src/gui/egl/qegl_p.h | 3 +++ src/gui/egl/qegl_qws.cpp | 12 ---------- src/gui/egl/qegl_symbian.cpp | 37 ++----------------------------- src/gui/egl/qegl_wince.cpp | 38 -------------------------------- src/gui/egl/qegl_x11.cpp | 38 -------------------------------- 6 files changed, 57 insertions(+), 123 deletions(-) diff --git a/src/gui/egl/qegl.cpp b/src/gui/egl/qegl.cpp index 6d719ba..ef30029 100644 --- a/src/gui/egl/qegl.cpp +++ b/src/gui/egl/qegl.cpp @@ -385,6 +385,58 @@ EGLNativeDisplayType QEgl::nativeDisplay() } #endif +#if !defined(Q_OS_SYMBIAN) +EGLNativeWindowType QEgl::nativeWindow(QWidget* widget) +{ + return (EGLNativeWindowType)(widget->winId()); +} +#endif + +EGLNativePixmapType QEgl::nativePixmap(QPixmap* pixmap) +{ + return (EGLNativePixmapType)(pixmap->handle()); +} + +EGLSurface QEgl::createSurface(QPaintDevice *device, EGLConfig cfg, const QEglProperties *properties) +{ + // Create the native drawable for the paint device. + int devType = device->devType(); + EGLNativePixmapType pixmapDrawable = 0; + EGLNativeWindowType windowDrawable = 0; + bool ok; + if (devType == QInternal::Pixmap) { + pixmapDrawable = nativePixmap(static_cast(device)); + ok = (pixmapDrawable != 0); + } else if (devType == QInternal::Widget) { + windowDrawable = nativeWindow(static_cast(device)); + ok = (windowDrawable != 0); + } else { + ok = false; + } + if (!ok) { + qWarning("QEglContext::createSurface(): Cannot create the native EGL drawable"); + return EGL_NO_SURFACE; + } + + // Create the EGL surface to draw into, based on the native drawable. + const int *props; + if (properties) + props = properties->properties(); + else + props = 0; + EGLSurface surf; + if (devType == QInternal::Widget) + surf = eglCreateWindowSurface(QEgl::display(), cfg, windowDrawable, props); + else + surf = eglCreatePixmapSurface(QEgl::display(), cfg, pixmapDrawable, props); + if (surf == EGL_NO_SURFACE) { + qWarning("QEglContext::createSurface(): Unable to create EGL surface, error = 0x%x", eglGetError()); + } + return surf; +} + + + // Return the error string associated with a specific code. QString QEgl::errorString(EGLint code) { diff --git a/src/gui/egl/qegl_p.h b/src/gui/egl/qegl_p.h index a50e4e1..8a9d815 100644 --- a/src/gui/egl/qegl_p.h +++ b/src/gui/egl/qegl_p.h @@ -128,7 +128,10 @@ namespace QEgl { Q_GUI_EXPORT bool hasExtension(const char* extensionName); Q_GUI_EXPORT EGLDisplay display(); + Q_GUI_EXPORT EGLNativeDisplayType nativeDisplay(); + Q_GUI_EXPORT EGLNativeWindowType nativeWindow(QWidget*); + Q_GUI_EXPORT EGLNativePixmapType nativePixmap(QPixmap*); }; diff --git a/src/gui/egl/qegl_qws.cpp b/src/gui/egl/qegl_qws.cpp index 935fe67..eb41bcc 100644 --- a/src/gui/egl/qegl_qws.cpp +++ b/src/gui/egl/qegl_qws.cpp @@ -55,18 +55,6 @@ QT_BEGIN_NAMESPACE -// Create the surface for a QPixmap, QImage, or QWidget. -// We don't have QGLScreen to create EGL surfaces for us, -// so surface creation needs to be done in QtOpenGL or -// QtOpenVG for Qt/Embedded. -EGLSurface QEgl::createSurface(QPaintDevice *device, EGLConfig cfg, const QEglProperties *properties) -{ - Q_UNUSED(device); - Q_UNUSED(cfg); - Q_UNUSED(properties); - return EGL_NO_SURFACE; -} - static QScreen *screenForDevice(QPaintDevice *device) { QScreen *screen = qt_screen; diff --git a/src/gui/egl/qegl_symbian.cpp b/src/gui/egl/qegl_symbian.cpp index 2276ce0..8833b42 100644 --- a/src/gui/egl/qegl_symbian.cpp +++ b/src/gui/egl/qegl_symbian.cpp @@ -50,42 +50,9 @@ QT_BEGIN_NAMESPACE -EGLSurface QEgl::createSurface(QPaintDevice *device, EGLConfig cfg, const QEglProperties *properties) +EGLNativeWindowType QEgl::nativeWindow(QWidget* widget) { - // Create the native drawable for the paint device. - int devType = device->devType(); - EGLNativePixmapType pixmapDrawable = 0; - EGLNativeWindowType windowDrawable = 0; - bool ok; - if (devType == QInternal::Pixmap) { - pixmapDrawable = 0; - ok = (pixmapDrawable != 0); - } else if (devType == QInternal::Widget) { - QWidget *w = static_cast(device); - windowDrawable = (EGLNativeWindowType)(w->winId()->DrawableWindow()); - ok = (windowDrawable != 0); - } else { - ok = false; - } - if (!ok) { - qWarning("QEglContext::createSurface(): Cannot create the native EGL drawable"); - return EGL_NO_SURFACE; - } - - // Create the EGL surface to draw into, based on the native drawable. - const int *props; - if (properties) - props = properties->properties(); - else - props = 0; - EGLSurface surf; - if (devType == QInternal::Widget) - surf = eglCreateWindowSurface(dpy, cfg, windowDrawable, props); - else - surf = eglCreatePixmapSurface(dpy, cfg, pixmapDrawable, props); - if (surf == EGL_NO_SURFACE) - qWarning("QEglContext::createSurface(): Unable to create EGL surface, error = 0x%x", eglGetError()); - return surf; + return (EGLNativeWindowType)(widget->winId()->DrawableWindow()); } // Set pixel format and other properties based on a paint device. diff --git a/src/gui/egl/qegl_wince.cpp b/src/gui/egl/qegl_wince.cpp index fae491b..b201153 100644 --- a/src/gui/egl/qegl_wince.cpp +++ b/src/gui/egl/qegl_wince.cpp @@ -51,44 +51,6 @@ QT_BEGIN_NAMESPACE -EGLSurface QEgl::createSurface(QPaintDevice *device, EGLConfig cfg, const QEglProperties *properties) -{ - // Create the native drawable for the paint device. - int devType = device->devType(); - EGLNativePixmapType pixmapDrawable = 0; - EGLNativeWindowType windowDrawable = 0; - bool ok; - if (devType == QInternal::Pixmap) { - pixmapDrawable = 0; - ok = (pixmapDrawable != 0); - } else if (devType == QInternal::Widget) { - windowDrawable = (EGLNativeWindowType)(static_cast(device))->winId(); - ok = (windowDrawable != 0); - } else { - ok = false; - } - if (!ok) { - qWarning("QEglContext::createSurface(): Cannot create the native EGL drawable"); - return EGL_NO_SURFACE; - } - - // Create the EGL surface to draw into, based on the native drawable. - const int *props; - if (properties) - props = properties->properties(); - else - props = 0; - EGLSurface surf; - if (devType == QInternal::Widget) - surf = eglCreateWindowSurface(QEgl::display(), cfg, windowDrawable, props); - else - surf = eglCreatePixmapSurface(QEgl::display(), cfg, pixmapDrawable, props); - if (surf == EGL_NO_SURFACE) { - qWarning("QEglContext::createSurface(): Unable to create EGL surface, error = 0x%x", eglGetError()); - } - return surf; -} - EGLNativeDisplayType QEgl::nativeDisplay() { HWND win = (static_cast(device))->winId(); diff --git a/src/gui/egl/qegl_x11.cpp b/src/gui/egl/qegl_x11.cpp index d24727a..e8fb662 100644 --- a/src/gui/egl/qegl_x11.cpp +++ b/src/gui/egl/qegl_x11.cpp @@ -55,44 +55,6 @@ QT_BEGIN_NAMESPACE -EGLSurface QEgl::createSurface(QPaintDevice *device, EGLConfig cfg, const QEglProperties *properties) -{ - // Create the native drawable for the paint device. - int devType = device->devType(); - EGLNativePixmapType pixmapDrawable = 0; - EGLNativeWindowType windowDrawable = 0; - bool ok; - if (devType == QInternal::Pixmap) { - pixmapDrawable = (EGLNativePixmapType)(static_cast(device))->handle(); - ok = (pixmapDrawable != 0); - } else if (devType == QInternal::Widget) { - windowDrawable = (EGLNativeWindowType)(static_cast(device))->winId(); - ok = (windowDrawable != 0); - } else { - ok = false; - } - if (!ok) { - qWarning("QEglContext::createSurface(): Cannot create the native EGL drawable"); - return EGL_NO_SURFACE; - } - - // Create the EGL surface to draw into, based on the native drawable. - const int *props; - if (properties) - props = properties->properties(); - else - props = 0; - EGLSurface surf; - if (devType == QInternal::Widget) - surf = eglCreateWindowSurface(QEgl::display(), cfg, windowDrawable, props); - else - surf = eglCreatePixmapSurface(QEgl::display(), cfg, pixmapDrawable, props); - if (surf == EGL_NO_SURFACE) { - qWarning() << "QEglContext::createSurface(): Unable to create EGL surface:" - << QEgl::errorString(); - } - return surf; -} EGLNativeDisplayType QEgl::nativeDisplay() { -- cgit v0.12 From 551b41e20118b66edb37704a0cfbfe5d3a960067 Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Thu, 18 Feb 2010 09:58:57 +0100 Subject: Add QEgl::defaultConfig method to select configs suitable for Qt Reviewed-By: TrustMe --- src/gui/egl/qegl.cpp | 163 +++++++++++++++++++++++++++++++++++++++++ src/gui/egl/qegl_p.h | 15 ++++ src/gui/egl/qeglproperties.cpp | 10 +++ 3 files changed, 188 insertions(+) diff --git a/src/gui/egl/qegl.cpp b/src/gui/egl/qegl.cpp index ef30029..8bd4d7f 100644 --- a/src/gui/egl/qegl.cpp +++ b/src/gui/egl/qegl.cpp @@ -88,6 +88,169 @@ bool QEglContext::isCurrent() const return current; } +EGLConfig QEgl::defaultConfig(QPaintDevice* device, API api, ConfigOptions options) +{ + int devType = device->devType(); + + if ( (devType != QInternal::Pixmap) && ((options & Renderable) == 0)) + qWarning("QEgl::defaultConfig() - Only configs for pixmaps make sense to be read-only!"); + + EGLConfig* targetConfig = 0; + + static EGLConfig defaultVGConfigs[] = { + QEGL_NO_CONFIG, // 0 Window Renderable Translucent + QEGL_NO_CONFIG, // 1 Window Renderable Opaque + QEGL_NO_CONFIG, // 2 Pixmap Renderable Translucent + QEGL_NO_CONFIG, // 3 Pixmap Renderable Opaque + QEGL_NO_CONFIG, // 4 Pixmap ReadOnly Translucent + QEGL_NO_CONFIG // 5 Pixmap ReadOnly Opaque + }; + if (api == OpenVG) { + if (devType == QInternal::Widget) { + if (options & Translucent) + targetConfig = &(defaultVGConfigs[0]); + else + targetConfig = &(defaultVGConfigs[1]); + } else if (devType == QInternal::Pixmap) { + if (options & Renderable) { + if (options & Translucent) + targetConfig = &(defaultVGConfigs[2]); + else // Opaque + targetConfig = &(defaultVGConfigs[3]); + } else { // Read-only + if (options & Translucent) + targetConfig = &(defaultVGConfigs[4]); + else // Opaque + targetConfig = &(defaultVGConfigs[5]); + } + } + } + + + static EGLConfig defaultGLConfigs[] = { + QEGL_NO_CONFIG, // 0 Window Renderable Translucent + QEGL_NO_CONFIG, // 1 Window Renderable Opaque + QEGL_NO_CONFIG, // 2 PBuffer Renderable Translucent + QEGL_NO_CONFIG, // 3 PBuffer Renderable Opaque + QEGL_NO_CONFIG, // 4 Pixmap Renderable Translucent + QEGL_NO_CONFIG, // 5 Pixmap Renderable Opaque + QEGL_NO_CONFIG, // 6 Pixmap ReadOnly Translucent + QEGL_NO_CONFIG // 7 Pixmap ReadOnly Opaque + }; + if (api == OpenGL) { + if (devType == QInternal::Widget) { + if (options & Translucent) + targetConfig = &(defaultGLConfigs[0]); + else // Opaque + targetConfig = &(defaultGLConfigs[1]); + } else if (devType == QInternal::Pbuffer) { + if (options & Translucent) + targetConfig = &(defaultGLConfigs[2]); + else // Opaque + targetConfig = &(defaultGLConfigs[3]); + } else if (devType == QInternal::Pixmap) { + if (options & Renderable) { + if (options & Translucent) + targetConfig = &(defaultGLConfigs[4]); + else // Opaque + targetConfig = &(defaultGLConfigs[5]); + } else { // ReadOnly + if (options & Translucent) + targetConfig = &(defaultGLConfigs[6]); + else // Opaque + targetConfig = &(defaultGLConfigs[7]); + } + } + } + + if (!targetConfig) { + qWarning("QEgl::defaultConfig() - No default config for device/api/options combo"); + return QEGL_NO_CONFIG; + } + if (*targetConfig != QEGL_NO_CONFIG) + return *targetConfig; + + + // We haven't found an EGL config for the target config yet, so do it now: + + + // Allow overriding from an environment variable: + QByteArray configId; + if (api == OpenVG) + configId = qgetenv("QT_VG_EGL_CONFIG"); + else + configId = qgetenv("QT_GL_EGL_CONFIG"); + if (!configId.isEmpty()) { + // Overriden, so get the EGLConfig for the specified config ID: + EGLint properties[] = { + EGL_CONFIG_ID, (EGLint)configId.toInt(), + EGL_NONE + }; + EGLint configCount = 0; + eglChooseConfig(display(), properties, targetConfig, 1, &configCount); + if (configCount > 0) + return *targetConfig; + qWarning() << "QEgl::defaultConfig() -" << configId << "appears to be invalid"; + } + + QEglProperties configAttribs; + configAttribs.setRenderableType(api); + + EGLint surfaceType; + switch (devType) { + case QInternal::Widget: + surfaceType = EGL_WINDOW_BIT; + break; + case QInternal::Pixmap: + surfaceType = EGL_PIXMAP_BIT; + break; + case QInternal::Pbuffer: + surfaceType = EGL_PBUFFER_BIT; + break; + default: + qWarning("QEgl::defaultConfig() - Can't create EGL surface for %d device type", devType); + return QEGL_NO_CONFIG; + }; +#ifdef EGL_VG_ALPHA_FORMAT_PRE_BIT + // For OpenVG, we try to create a surface using a pre-multiplied format if + // the surface needs to have an alpha channel: + if (api == OpenVG && (options & Translucent)) + surfaceType |= EGL_VG_ALPHA_FORMAT_PRE_BIT; +#endif + configAttribs.setValue(EGL_SURFACE_TYPE, surfaceType); + +#ifdef EGL_BIND_TO_TEXTURE_RGBA + if (devType == QInternal::Pixmap || devType == QInternal::Pbuffer) { + if (options & Translucent) + configAttribs.setValue(EGL_BIND_TO_TEXTURE_RGBA, EGL_TRUE); + else + configAttribs.setValue(EGL_BIND_TO_TEXTURE_RGB, EGL_TRUE); + } +#endif + + // Add paint engine requirements + if (api == OpenVG) { +#ifndef QVG_SCISSOR_CLIP + configAttribs.setValue(EGL_ALPHA_MASK_SIZE, 1); +#endif + } else { + // Both OpenGL paint engines need to have stencil and sample buffers + configAttribs.setValue(EGL_STENCIL_SIZE, 1); + configAttribs.setValue(EGL_SAMPLE_BUFFERS, 1); +#ifndef QT_OPENGL_ES_2 + // Aditionally, the GL1 engine likes to have a depth buffer for clipping + configAttribs.setValue(EGL_DEPTH_SIZE, 1); +#endif + } + + // Finally, set the color format based on the device: + configAttribs.setPaintDeviceFormat(device); + + *targetConfig = chooseConfig(&configAttribs, QEgl::BestPixelFormat); + return *targetConfig; +} + + // Choose a configuration that matches "properties". EGLConfig QEgl::chooseConfig(const QEglProperties* properties, QEgl::PixelFormatMatch match) { diff --git a/src/gui/egl/qegl_p.h b/src/gui/egl/qegl_p.h index 8a9d815..1a5e4c0 100644 --- a/src/gui/egl/qegl_p.h +++ b/src/gui/egl/qegl_p.h @@ -114,6 +114,21 @@ namespace QEgl { BestPixelFormat }; + enum ConfigOptions + { + Opaque = 0x00, + Translucent = 0x01, + + ReadOnly = 0x00, + Renderable = 0x02 // Config will be compatable with the paint engines (VG or GL) + }; + + // Most of the time we use the same config for things like widgets & pixmaps, so rather than + // go through the eglChooseConfig loop every time, we use defaultConfig, which will return + // the config for a particular device/api/option combo. This function assumes that once a + // config is chosen for a particular combo, it's safe to always use that combo. + Q_GUI_EXPORT EGLConfig defaultConfig(QPaintDevice* device, API api, ConfigOptions options); + Q_GUI_EXPORT EGLConfig chooseConfig(const QEglProperties* configAttribs, QEgl::PixelFormatMatch match = QEgl::ExactPixelFormat); Q_GUI_EXPORT EGLSurface createSurface(QPaintDevice *device, EGLConfig cfg, const QEglProperties *surfaceAttribs = 0); diff --git a/src/gui/egl/qeglproperties.cpp b/src/gui/egl/qeglproperties.cpp index 86e158b..e0e8481 100644 --- a/src/gui/egl/qeglproperties.cpp +++ b/src/gui/egl/qeglproperties.cpp @@ -230,6 +230,16 @@ void QEglProperties::setRenderableType(QEgl::API api) // reductions in complexity are possible. bool QEglProperties::reduceConfiguration() { +#ifdef EGL_VG_ALPHA_FORMAT_PRE_BIT + // For OpenVG, we sometimes try to create a surface using a pre-multiplied format. If we can't + // find a config which supports pre-multiplied formats, remove the flag on the surface type: + EGLint surfaceType = value(EGL_SURFACE_TYPE); + if (surfaceType & EGL_VG_ALPHA_FORMAT_PRE_BIT) { + surfaceType ^= EGL_VG_ALPHA_FORMAT_PRE_BIT; + setValue(EGL_SURFACE_TYPE, surfaceType); + return true; + } +#endif // EGL chooses configs with the highest color depth over // those with smaller (but faster) lower color depths. One // way around this is to set EGL_BUFFER_SIZE to 16, which -- cgit v0.12 From 4c5549269144eae79bdcefc7119b2adf3044e000 Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Fri, 19 Feb 2010 15:54:09 +0100 Subject: Add getCompatibleVisualId to QEgl on X11 This method takes an EGLConfig and hands back an X11 VisualID which can be used to create native windows/pixmaps which will have an EGL surface created for them using the given EGL config. Reviewed-By: TrustMe --- src/gui/egl/qegl_p.h | 4 ++ src/gui/egl/qegl_x11.cpp | 145 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 149 insertions(+) diff --git a/src/gui/egl/qegl_p.h b/src/gui/egl/qegl_p.h index 1a5e4c0..7f753d0 100644 --- a/src/gui/egl/qegl_p.h +++ b/src/gui/egl/qegl_p.h @@ -147,6 +147,10 @@ namespace QEgl { Q_GUI_EXPORT EGLNativeDisplayType nativeDisplay(); Q_GUI_EXPORT EGLNativeWindowType nativeWindow(QWidget*); Q_GUI_EXPORT EGLNativePixmapType nativePixmap(QPixmap*); + +#ifdef Q_WS_X11 + Q_GUI_EXPORT VisualID getCompatibleVisualId(EGLConfig config); +#endif }; diff --git a/src/gui/egl/qegl_x11.cpp b/src/gui/egl/qegl_x11.cpp index e8fb662..2c0bbd3 100644 --- a/src/gui/egl/qegl_x11.cpp +++ b/src/gui/egl/qegl_x11.cpp @@ -116,4 +116,149 @@ void QEglProperties::setPaintDeviceFormat(QPaintDevice *dev) setVisualFormat(qt_x11Info(dev)); } + +VisualID QEgl::getCompatibleVisualId(EGLConfig config) +{ + VisualID visualId = 0; + EGLint eglValue = 0; + + EGLint configRedSize = 0; + eglGetConfigAttrib(display(), config, EGL_RED_SIZE, &configRedSize); + + EGLint configGreenSize = 0; + eglGetConfigAttrib(display(), config, EGL_GREEN_SIZE, &configGreenSize); + + EGLint configBlueSize = 0; + eglGetConfigAttrib(display(), config, EGL_BLUE_SIZE, &configBlueSize); + + EGLint configAlphaSize = 0; + eglGetConfigAttrib(display(), config, EGL_ALPHA_SIZE, &configAlphaSize); + + eglGetConfigAttrib(display(), config, EGL_BUFFER_SIZE, &eglValue); + int configBitDepth = eglValue; + + // See if EGL provided a valid VisualID: + eglGetConfigAttrib(display(), 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(X11->display, VisualIDMask, &visualInfoTemplate, &matchingCount); + if (chosenVisualInfo) { + if (configBitDepth == chosenVisualInfo->depth) { +#if !defined(QT_NO_XRENDER) + // If we have XRender, actually check the visual supplied by EGL is ARGB + if (configAlphaSize > 0) { + XRenderPictFormat *format; + format = XRenderFindVisualFormat(X11->display, chosenVisualInfo->visual); + if (!format || (format->type != PictTypeDirect) || (!format->direct.alphaMask)) { + qWarning("Warning: EGL suggested using X visual ID %d for config %d, but this is not ARGB", + (int)visualId, (int)config); + visualId = 0; + } + } +#endif + } else { + qWarning("Warning: EGL suggested using X visual ID %d (%d bpp) for config %d (%d bpp), but the depths do not match!", + (int)visualId, chosenVisualInfo->depth, (int)config, configBitDepth); + visualId = 0; + } + } + XFree(chosenVisualInfo); + } + + if (visualId) { +#ifdef QT_DEBUG_X11_VISUAL_SELECTION + if (configHasAlpha) + qDebug("Using ARGB Visual ID %d provided by EGL for config %d", (int)visualId, (int)config); + else + qDebug("Using Opaque Visual ID %d provided by EGL for config %d", (int)visualId, (int)config); +#endif + return visualId; + } + + + // If EGL didn't give us a valid visual ID, try XRender +#if !defined(QT_NO_XRENDER) + if (!visualId) { + XVisualInfo visualInfoTemplate; + memset(&visualInfoTemplate, 0, sizeof(XVisualInfo)); + + visualInfoTemplate.depth = configBitDepth; + visualInfoTemplate.c_class = TrueColor; + + XVisualInfo *matchingVisuals; + int matchingCount = 0; + matchingVisuals = XGetVisualInfo(X11->display, + VisualDepthMask|VisualClassMask, + &visualInfoTemplate, + &matchingCount); + + for (int i = 0; i < matchingCount; ++i) { + XRenderPictFormat *format; + format = XRenderFindVisualFormat(X11->display, matchingVisuals[i].visual); + + // Check the format for the visual matches the EGL config + if ( (countBits(format->direct.redMask) == configRedSize) && + (countBits(format->direct.greenMask) == configGreenSize) && + (countBits(format->direct.blueMask) == configBlueSize) && + (countBits(format->direct.alphaMask) == configAlphaSize) ) + { + visualId = matchingVisuals[i].visualid; + break; + } + } + if (matchingVisuals) + XFree(matchingVisuals); + + } + if (visualId) { +# ifdef QT_DEBUG_X11_VISUAL_SELECTION + if (configHasAlpha) + qDebug("Using ARGB Visual ID %d provided by XRender for EGL config %d", (int)visualId, (int)config); + else + qDebug("Using Opaque Visual ID %d provided by XRender for EGL config %d", (int)visualId, (int)config); +# endif // QT_DEBUG_X11_VISUAL_SELECTION + return visualId; + } +#endif //!defined(QT_NO_XRENDER) + + + // Finally, if XRender also failed to find a visual (or isn't present), try to + // use XGetVisualInfo and only use the bit depth to match on: + if (!visualId) { + XVisualInfo visualInfoTemplate; + memset(&visualInfoTemplate, 0, sizeof(XVisualInfo)); + + visualInfoTemplate.depth = configBitDepth; + + XVisualInfo *matchingVisuals; + int matchingCount = 0; + matchingVisuals = XGetVisualInfo(X11->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, (int)config); +#endif + return visualId; + } + + qWarning("Unable to find an X11 visual which matches EGL config %d", (int)config); + return (VisualID)0; +} + + QT_END_NAMESPACE -- cgit v0.12 From c993aef82eca9f5d5241093f407179e4189ab7f1 Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Fri, 19 Feb 2010 18:17:08 +0100 Subject: Add QEglContext::configAttrib(int name) helper Reviewed-By: TrustMe --- src/gui/egl/qegl.cpp | 10 ++++++++++ src/gui/egl/qeglcontext_p.h | 1 + 2 files changed, 11 insertions(+) diff --git a/src/gui/egl/qegl.cpp b/src/gui/egl/qegl.cpp index 8bd4d7f..d4c9913 100644 --- a/src/gui/egl/qegl.cpp +++ b/src/gui/egl/qegl.cpp @@ -510,6 +510,16 @@ bool QEglContext::configAttrib(int name, EGLint *value) const return eglGetConfigAttrib(QEgl::display(), cfg, name, value); } +int QEglContext::configAttrib(int name) const +{ + EGLint value; + EGLBoolean success = eglGetConfigAttrib(QEgl::display(), cfg, name, &value); + if (success) + return value; + else + return EGL_DONT_CARE; +} + QEglProperties QEglContext::configProperties() const { return QEglProperties(config()); diff --git a/src/gui/egl/qeglcontext_p.h b/src/gui/egl/qeglcontext_p.h index c656d1d..7eec7eb 100644 --- a/src/gui/egl/qeglcontext_p.h +++ b/src/gui/egl/qeglcontext_p.h @@ -89,6 +89,7 @@ public: void waitClient(); bool configAttrib(int name, EGLint *value) const; + int configAttrib(int name) const; EGLContext context() const { return ctx; } void setContext(EGLContext context) { ctx = context; ownsContext = false;} -- cgit v0.12 From 445b62cb432deb8aed3be766d3c37b9567e1d4ec Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Fri, 19 Feb 2010 18:29:42 +0100 Subject: Make QGLWidget use new QEgl::getCompatibleVisualId API Reviewed-By: TrustMe --- src/gui/egl/qegl_x11.cpp | 5 +++-- src/opengl/qgl_x11egl.cpp | 18 +++++++++++++++--- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/gui/egl/qegl_x11.cpp b/src/gui/egl/qegl_x11.cpp index 2c0bbd3..49c8d60 100644 --- a/src/gui/egl/qegl_x11.cpp +++ b/src/gui/egl/qegl_x11.cpp @@ -116,6 +116,7 @@ void QEglProperties::setPaintDeviceFormat(QPaintDevice *dev) setVisualFormat(qt_x11Info(dev)); } +//#define QT_DEBUG_X11_VISUAL_SELECTION 1 VisualID QEgl::getCompatibleVisualId(EGLConfig config) { @@ -174,7 +175,7 @@ VisualID QEgl::getCompatibleVisualId(EGLConfig config) if (visualId) { #ifdef QT_DEBUG_X11_VISUAL_SELECTION - if (configHasAlpha) + if (configAlphaSize > 0) qDebug("Using ARGB Visual ID %d provided by EGL for config %d", (int)visualId, (int)config); else qDebug("Using Opaque Visual ID %d provided by EGL for config %d", (int)visualId, (int)config); @@ -219,7 +220,7 @@ VisualID QEgl::getCompatibleVisualId(EGLConfig config) } if (visualId) { # ifdef QT_DEBUG_X11_VISUAL_SELECTION - if (configHasAlpha) + if (configAlphaSize > 0) qDebug("Using ARGB Visual ID %d provided by XRender for EGL config %d", (int)visualId, (int)config); else qDebug("Using Opaque Visual ID %d provided by XRender for EGL config %d", (int)visualId, (int)config); diff --git a/src/opengl/qgl_x11egl.cpp b/src/opengl/qgl_x11egl.cpp index 972a5f6..b8da156 100644 --- a/src/opengl/qgl_x11egl.cpp +++ b/src/opengl/qgl_x11egl.cpp @@ -282,6 +282,7 @@ void QGLWidget::updateOverlayGL() } //#define QT_DEBUG_X11_VISUAL_SELECTION 1 +//#undef QT_DEBUG_X11_VISUAL_SELECTION bool qt_egl_setup_x11_visual(XVisualInfo &vi, EGLDisplay display, EGLConfig config, const QX11Info &x11Info, bool useArgbVisual) { @@ -471,10 +472,21 @@ void QGLWidget::setContext(QGLContext *context, const QGLContext* shareContext, if (visible) hide(); - XVisualInfo vi; QEglContext *eglContext = d->glcx->d_func()->eglContext; - bool usingArgbVisual = qt_egl_setup_x11_visual(vi, eglContext->display(), eglContext->config(), - x11Info(), tryArgbVisual); + + XVisualInfo vi; + memset(&vi, 0, sizeof(XVisualInfo)); + vi.visualid = QEgl::getCompatibleVisualId(eglContext->config()); + + { + XVisualInfo *visualInfoPtr; + int matchingCount = 0; + visualInfoPtr = XGetVisualInfo(X11->display, VisualIDMask, &vi, &matchingCount); + vi = *visualInfoPtr; + XFree(visualInfoPtr); + } + + bool usingArgbVisual = eglContext->configAttrib(EGL_ALPHA_SIZE) > 0; XSetWindowAttributes a; -- cgit v0.12 From dbc62b34b54ec3294f1cf8248630fbd1eaad9cbc Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Tue, 23 Feb 2010 18:08:08 +0100 Subject: Remove qt_egl_setup_x11_visual This method has been re-written as QEgl::getCompatibleVisualId() which is much cleaner code. Reviewed-By: TrustMe --- src/opengl/qgl_x11egl.cpp | 150 +--------------------------------------------- 1 file changed, 1 insertion(+), 149 deletions(-) diff --git a/src/opengl/qgl_x11egl.cpp b/src/opengl/qgl_x11egl.cpp index b8da156..99ff5b8 100644 --- a/src/opengl/qgl_x11egl.cpp +++ b/src/opengl/qgl_x11egl.cpp @@ -53,9 +53,6 @@ QT_BEGIN_NAMESPACE -bool qt_egl_setup_x11_visual(XVisualInfo &vi, EGLDisplay display, EGLConfig config, - const QX11Info &x11Info, bool useArgbVisual); - /* QGLTemporaryContext implementation */ @@ -107,15 +104,7 @@ QGLTemporaryContext::QGLTemporaryContext(bool, QWidget *) int numVisuals; EGLint id = 0; - eglGetConfigAttrib(d->display, config, EGL_NATIVE_VISUAL_ID, &id); - if (id == 0) { - // EGL_NATIVE_VISUAL_ID is optional and might not be supported - // on some implementations - we'll have to do it the hard way - QX11Info xinfo; - qt_egl_setup_x11_visual(visualInfo, d->display, config, xinfo, false); - } else { - visualInfo.visualid = id; - } + visualInfo.visualid = QEgl::getCompatibleVisualId(config); vi = XGetVisualInfo(X11->display, VisualIDMask, &visualInfo, &numVisuals); if (!vi || numVisuals < 1) { qWarning("QGLTemporaryContext: Unable to get X11 visual info id."); @@ -281,143 +270,6 @@ void QGLWidget::updateOverlayGL() //handle overlay } -//#define QT_DEBUG_X11_VISUAL_SELECTION 1 -//#undef QT_DEBUG_X11_VISUAL_SELECTION - -bool qt_egl_setup_x11_visual(XVisualInfo &vi, EGLDisplay display, EGLConfig config, const QX11Info &x11Info, bool useArgbVisual) -{ - bool foundVisualIsArgb = useArgbVisual; - -#ifdef QT_DEBUG_X11_VISUAL_SELECTION - qDebug("qt_egl_setup_x11_visual() - useArgbVisual=%d", useArgbVisual); -#endif - - memset(&vi, 0, sizeof(XVisualInfo)); - - EGLint eglConfigColorSize; - eglGetConfigAttrib(display, config, EGL_BUFFER_SIZE, &eglConfigColorSize); - - // Check to see if EGL is suggesting an appropriate visual id: - EGLint nativeVisualId; - eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &nativeVisualId); - vi.visualid = nativeVisualId; - - if (vi.visualid) { - // EGL has suggested a visual id, so get the rest of the visual info for that id: - XVisualInfo *chosenVisualInfo; - int matchingCount = 0; - chosenVisualInfo = XGetVisualInfo(x11Info.display(), VisualIDMask, &vi, &matchingCount); - if (chosenVisualInfo) { -#if !defined(QT_NO_XRENDER) - if (useArgbVisual) { - // Check to make sure the visual provided by EGL is ARGB - XRenderPictFormat *format; - format = XRenderFindVisualFormat(x11Info.display(), chosenVisualInfo->visual); - if (format->type == PictTypeDirect && format->direct.alphaMask) { -#ifdef QT_DEBUG_X11_VISUAL_SELECTION - qDebug("Using ARGB X Visual ID (%d) provided by EGL", (int)vi.visualid); -#endif - foundVisualIsArgb = true; - vi = *chosenVisualInfo; - } - else { - qWarning("Warning: EGL suggested using X visual ID %d for config %d, but this is not ARGB", - nativeVisualId, (int)config); - vi.visualid = 0; - } - } else -#endif - { - if (eglConfigColorSize == chosenVisualInfo->depth) { -#ifdef QT_DEBUG_X11_VISUAL_SELECTION - qDebug("Using opaque X Visual ID (%d) provided by EGL", (int)vi.visualid); -#endif - vi = *chosenVisualInfo; - } else - qWarning("Warning: EGL suggested using X visual ID %d (%d bpp) for config %d (%d bpp), but the depths do not match!", - nativeVisualId, chosenVisualInfo->depth, (int)config, eglConfigColorSize); - } - XFree(chosenVisualInfo); - } - else { - qWarning("Warning: EGL suggested using X visual ID %d for config %d, but this seems to be invalid!", - nativeVisualId, (int)config); - vi.visualid = 0; - } - } - - // If EGL does not know the visual ID, so try to select an appropriate one ourselves, first - // using XRender if we're supposed to have an alpha, then falling back to XGetVisualInfo - -#if !defined(QT_NO_XRENDER) - if (vi.visualid == 0 && useArgbVisual) { - // Try to use XRender to find an ARGB visual we can use - vi.screen = x11Info.screen(); - vi.depth = 32; //### We might at some point (soon) get ARGB4444 - vi.c_class = TrueColor; - XVisualInfo *matchingVisuals; - int matchingCount = 0; - matchingVisuals = XGetVisualInfo(x11Info.display(), - VisualScreenMask|VisualDepthMask|VisualClassMask, - &vi, &matchingCount); - - for (int i = 0; i < matchingCount; ++i) { - XRenderPictFormat *format; - format = XRenderFindVisualFormat(x11Info.display(), matchingVisuals[i].visual); - if (format->type == PictTypeDirect && format->direct.alphaMask) { - vi = matchingVisuals[i]; - foundVisualIsArgb = true; -#ifdef QT_DEBUG_X11_VISUAL_SELECTION - qDebug("Using X Visual ID (%d) for ARGB visual as provided by XRender", (int)vi.visualid); -#endif - break; - } - } - XFree(matchingVisuals); - } -#endif - - if (vi.visualid == 0) { - EGLint depth; - eglGetConfigAttrib(display, config, EGL_BUFFER_SIZE, &depth); - int err; - err = XMatchVisualInfo(x11Info.display(), x11Info.screen(), depth, TrueColor, &vi); - if (err == 0) { - qWarning("Warning: Can't find an X visual which matches the EGL config(%d)'s depth (%d)!", - (int)config, depth); - depth = x11Info.depth(); - err = XMatchVisualInfo(x11Info.display(), x11Info.screen(), depth, TrueColor, &vi); - if (err == 0) { - qWarning("Error: Couldn't get any matching X visual!"); - return false; - } else - qWarning(" - Falling back to X11 suggested depth (%d)", depth); - } -#ifdef QT_DEBUG_X11_VISUAL_SELECTION - else - qDebug("Using X Visual ID (%d) for EGL provided depth (%d)", (int)vi.visualid, depth); -#endif - - // Don't try to use ARGB now unless the visual is 32-bit - even then it might stil fail :-( - if (useArgbVisual) - foundVisualIsArgb = vi.depth == 32; //### We might at some point (soon) get ARGB4444 - } - -#ifdef QT_DEBUG_X11_VISUAL_SELECTION - qDebug("Visual Info:"); - qDebug(" bits_per_rgb=%d", vi.bits_per_rgb); - qDebug(" red_mask=0x%x", vi.red_mask); - qDebug(" green_mask=0x%x", vi.green_mask); - qDebug(" blue_mask=0x%x", vi.blue_mask); - qDebug(" colormap_size=%d", vi.colormap_size); - qDebug(" c_class=%d", vi.c_class); - qDebug(" depth=%d", vi.depth); - qDebug(" screen=%d", vi.screen); - qDebug(" visualid=%d", vi.visualid); -#endif - return foundVisualIsArgb; -} - void QGLWidget::setContext(QGLContext *context, const QGLContext* shareContext, bool deleteOldContext) { Q_D(QGLWidget); -- cgit v0.12 From ebdfa7270f67e4ce3b5034aa5144fdabeaecbbcd Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Wed, 24 Feb 2010 13:41:29 +0100 Subject: Use QEgl::display in QGLTemporaryContext so EGL is init'd only once MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-By: Trond Kjernåsen --- src/opengl/qgl_x11egl.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/opengl/qgl_x11egl.cpp b/src/opengl/qgl_x11egl.cpp index 99ff5b8..ff58fba 100644 --- a/src/opengl/qgl_x11egl.cpp +++ b/src/opengl/qgl_x11egl.cpp @@ -76,12 +76,7 @@ QGLTemporaryContext::QGLTemporaryContext(bool, QWidget *) d->surface = 0; int screen = 0; - d->display = eglGetDisplay(EGLNativeDisplayType(X11->display)); - - if (!eglInitialize(d->display, NULL, NULL)) { - qWarning("QGLTemporaryContext: Unable to initialize EGL display."); - return; - } + d->display = QEgl::display(); EGLConfig config; int numConfigs = 0; -- cgit v0.12 From a2eddea1432d6e558dcd620cd5100ce4531975e8 Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Wed, 24 Feb 2010 17:26:11 +0100 Subject: Replace qt_egl_add_platform_config with existing QEglProperties API QEglProperties::setPaintDeviceFormat() seems to be a copy & paste of qt_egl_add_platform_config for every platform anyway. Reviewed-By: TrustMe --- src/opengl/qgl_egl_p.h | 1 - src/opengl/qgl_qws.cpp | 17 +---------------- src/opengl/qgl_wince.cpp | 12 +----------- src/opengl/qgl_x11egl.cpp | 8 +------- 4 files changed, 3 insertions(+), 35 deletions(-) diff --git a/src/opengl/qgl_egl_p.h b/src/opengl/qgl_egl_p.h index 518b500..1d8cbf1 100644 --- a/src/opengl/qgl_egl_p.h +++ b/src/opengl/qgl_egl_p.h @@ -62,7 +62,6 @@ class QGLFormat; void qt_egl_set_format(QEglProperties& props, int deviceType, const QGLFormat& f); void qt_egl_update_format(const QEglContext& context, QGLFormat& format); -void qt_egl_add_platform_config(QEglProperties& props, QPaintDevice *device); QT_END_NAMESPACE diff --git a/src/opengl/qgl_qws.cpp b/src/opengl/qgl_qws.cpp index fd17a27..c221134 100644 --- a/src/opengl/qgl_qws.cpp +++ b/src/opengl/qgl_qws.cpp @@ -119,21 +119,6 @@ bool QGLFormat::hasOpenGLOverlays() return false; } -void qt_egl_add_platform_config(QEglProperties& props, QPaintDevice *device) -{ - // Find the QGLScreen for this paint device. - QGLScreen *glScreen = glScreenForDevice(device); - if (!glScreen) { - qWarning("QGLContext::chooseContext(): The screen is not a QGLScreen"); - return; - } - int devType = device->devType(); - if (devType == QInternal::Image) - props.setPixelFormat(static_cast(device)->format()); - else - props.setPixelFormat(glScreen->pixelFormat()); -} - static EGLSurface qt_egl_create_surface (QEglContext *context, QPaintDevice *device, const QEglProperties *properties = 0) @@ -201,8 +186,8 @@ bool QGLContext::chooseContext(const QGLContext* shareContext) // Construct the configuration we need for this surface. QEglProperties configProps; - qt_egl_add_platform_config(configProps, device()); qt_egl_set_format(configProps, devType, d->glFormat); + configProps.setPaintDeviceFormat(device()); configProps.setRenderableType(QEgl::OpenGL); // Search for a matching configuration, reducing the complexity diff --git a/src/opengl/qgl_wince.cpp b/src/opengl/qgl_wince.cpp index 2b71201..ed8b4f7 100644 --- a/src/opengl/qgl_wince.cpp +++ b/src/opengl/qgl_wince.cpp @@ -122,16 +122,6 @@ QGLTemporaryContext::~QGLTemporaryContext() QGLFormat Win32/WGL-specific code *****************************************************************************/ -void qt_egl_add_platform_config(QEglProperties& props, QPaintDevice *device) -{ - int devType = device->devType(); - if (devType == QInternal::Image) - props.setPixelFormat(static_cast(device)->format()); - else - props.setPixelFormat(QImage::Format_RGB16); -} - - static bool opengl32dll = false; bool QGLFormat::hasOpenGLOverlays() @@ -159,8 +149,8 @@ bool QGLContext::chooseContext(const QGLContext* shareContext) // Construct the configuration we need for this surface. QEglProperties configProps; - qt_egl_add_platform_config(configProps, device()); qt_egl_set_format(configProps, devType, d->glFormat); + configProps.setPaintDeviceFormat(device()); configProps.setRenderableType(QEgl::OpenGL); // Search for a matching configuration, reducing the complexity diff --git a/src/opengl/qgl_x11egl.cpp b/src/opengl/qgl_x11egl.cpp index ff58fba..21ddfe3 100644 --- a/src/opengl/qgl_x11egl.cpp +++ b/src/opengl/qgl_x11egl.cpp @@ -154,12 +154,6 @@ bool QGLFormat::hasOpenGLOverlays() return false; } -void qt_egl_add_platform_config(QEglProperties& props, QPaintDevice *device) -{ - if (device->devType() == QInternal::Image) - props.setPixelFormat(static_cast(device)->format()); -} - // Chooses the EGL config and creates the EGL context bool QGLContext::chooseContext(const QGLContext* shareContext) { @@ -178,7 +172,7 @@ bool QGLContext::chooseContext(const QGLContext* shareContext) // Construct the configuration we need for this surface. QEglProperties configProps; qt_egl_set_format(configProps, devType, d->glFormat); - qt_egl_add_platform_config(configProps, device()); + configProps.setPaintDeviceFormat(device()); configProps.setRenderableType(QEgl::OpenGL); #if We_have_an_EGL_library_which_bothers_to_check_EGL_BUFFER_SIZE -- cgit v0.12 From f936cc4e2a7b377981a626b1d45dbbb1c1df1cb8 Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Mon, 1 Mar 2010 12:59:34 +0100 Subject: Move EGL surface type setting to new QEglProperties::setDeviceType Also renamed qt_egl_set_format->qt_eglproperties_set_glformat Reviewed-By: TrustMe --- src/gui/egl/qeglproperties.cpp | 11 +++++++ src/gui/egl/qeglproperties_p.h | 4 +-- src/opengl/qgl_egl.cpp | 62 ++++++++++++++++++--------------------- src/opengl/qgl_egl_p.h | 2 +- src/opengl/qgl_qws.cpp | 3 +- src/opengl/qgl_wince.cpp | 3 +- src/opengl/qgl_x11egl.cpp | 3 +- src/opengl/qglpixelbuffer_egl.cpp | 6 ++-- 8 files changed, 53 insertions(+), 41 deletions(-) diff --git a/src/gui/egl/qeglproperties.cpp b/src/gui/egl/qeglproperties.cpp index e0e8481..636f469 100644 --- a/src/gui/egl/qeglproperties.cpp +++ b/src/gui/egl/qeglproperties.cpp @@ -167,6 +167,17 @@ bool QEglProperties::removeValue(int name) return false; } +void QEglProperties::setDeviceType(int devType) +{ + if (devType == QInternal::Pixmap || devType == QInternal::Image) + setValue(EGL_SURFACE_TYPE, EGL_PIXMAP_BIT); + else if (devType == QInternal::Pbuffer) + setValue(EGL_SURFACE_TYPE, EGL_PBUFFER_BIT); + else + setValue(EGL_SURFACE_TYPE, EGL_WINDOW_BIT); +} + + // Sets the red, green, blue, and alpha sizes based on a pixel format. // Normally used to match a configuration request to the screen format. void QEglProperties::setPixelFormat(QImage::Format pixelFormat) diff --git a/src/gui/egl/qeglproperties_p.h b/src/gui/egl/qeglproperties_p.h index 496847b..eebcf72 100644 --- a/src/gui/egl/qeglproperties_p.h +++ b/src/gui/egl/qeglproperties_p.h @@ -82,9 +82,9 @@ public: #ifdef Q_WS_X11 void setVisualFormat(const QX11Info *xinfo); #endif - void setRenderableType(QEgl::API api); - + void setDeviceType(int devType); void setPaintDeviceFormat(QPaintDevice *dev); + void setRenderableType(QEgl::API api); bool reduceConfiguration(); diff --git a/src/opengl/qgl_egl.cpp b/src/opengl/qgl_egl.cpp index 90fb2bb..f1abab8 100644 --- a/src/opengl/qgl_egl.cpp +++ b/src/opengl/qgl_egl.cpp @@ -45,44 +45,40 @@ QT_BEGIN_NAMESPACE -// Set device configuration attributes from a QGLFormat instance. -void qt_egl_set_format(QEglProperties& props, int deviceType, const QGLFormat& f) +void qt_eglproperties_set_glformat(QEglProperties& eglProperties, const QGLFormat& glFormat) { - if (deviceType == QInternal::Pixmap || deviceType == QInternal::Image) - props.setValue(EGL_SURFACE_TYPE, EGL_PIXMAP_BIT); - else if (deviceType == QInternal::Pbuffer) - props.setValue(EGL_SURFACE_TYPE, EGL_PBUFFER_BIT); - else - props.setValue(EGL_SURFACE_TYPE, EGL_WINDOW_BIT); - - // Set the pixel format to that contained in the QGLFormat - // if the system hasn't already chosen a fixed format to - // match the pixmap, widget, etc. - if (props.value(EGL_RED_SIZE) == 0 || f.redBufferSize() != -1) - props.setValue(EGL_RED_SIZE, f.redBufferSize() == -1 ? 1 : f.redBufferSize()); - if (props.value(EGL_GREEN_SIZE) == 0 || f.greenBufferSize() != -1) - props.setValue(EGL_GREEN_SIZE, f.greenBufferSize() == -1 ? 1 : f.greenBufferSize()); - if (props.value(EGL_BLUE_SIZE) == 0 || f.blueBufferSize() != -1) - props.setValue(EGL_BLUE_SIZE, f.blueBufferSize() == -1 ? 1 : f.blueBufferSize()); - if (f.alpha()) { - if (props.value(EGL_ALPHA_SIZE) == 0 || f.alphaBufferSize() != -1) - props.setValue(EGL_ALPHA_SIZE, f.alphaBufferSize() == -1 ? 1 : f.alphaBufferSize()); + // NOTE: QGLFormat uses a magic value of -1 to indicate "don't care", even when a buffer of that + // type has been requested. + if (glFormat.depth()) { + int depthSize = glFormat.depthBufferSize(); + eglProperties.setValue(EGL_DEPTH_SIZE, depthSize == -1 ? 1 : depthSize); } - - if (f.depth()) - props.setValue(EGL_DEPTH_SIZE, f.depthBufferSize() == -1 ? 1 : f.depthBufferSize()); - if (f.stencil()) - props.setValue(EGL_STENCIL_SIZE, f.stencilBufferSize() == -1 ? 1 : f.stencilBufferSize()); - if (f.sampleBuffers()) { - props.setValue(EGL_SAMPLE_BUFFERS, 1); - props.setValue(EGL_SAMPLES, f.samples() == -1 ? 1 : f.samples()); - } else { - props.setValue(EGL_SAMPLE_BUFFERS, 0); + if (glFormat.stencil()) { + int stencilSize = glFormat.stencilBufferSize(); + eglProperties.setValue(EGL_STENCIL_SIZE, stencilSize == -1 ? 1 : stencilSize); + } + if (glFormat.sampleBuffers()) { + int sampleCount = glFormat.samples(); + eglProperties.setValue(EGL_SAMPLES, sampleCount == -1 ? 1 : sampleCount); + eglProperties.setValue(EGL_SAMPLE_BUFFERS, 1); + } + if (glFormat.alpha()) { + int alphaSize = glFormat.alphaBufferSize(); + eglProperties.setValue(EGL_ALPHA_SIZE, alphaSize == -1 ? 1 : alphaSize); } - if (deviceType == QInternal::Widget) - props.setValue(EGL_LEVEL, f.plane()); + + int redSize = glFormat.redBufferSize(); + int greenSize = glFormat.greenBufferSize(); + int blueSize = glFormat.blueBufferSize(); + int alphaSize = glFormat.alphaBufferSize(); + + eglProperties.setValue(EGL_RED_SIZE, redSize > 0 ? redSize : 1); + eglProperties.setValue(EGL_GREEN_SIZE, greenSize > 0 ? greenSize : 1); + eglProperties.setValue(EGL_BLUE_SIZE, blueSize > 0 ? blueSize : 1); + eglProperties.setValue(EGL_ALPHA_SIZE, alphaSize > 0 ? alphaSize : 0); } + // Updates "format" with the parameters of the selected configuration. void qt_egl_update_format(const QEglContext& context, QGLFormat& format) { diff --git a/src/opengl/qgl_egl_p.h b/src/opengl/qgl_egl_p.h index 1d8cbf1..6b65227 100644 --- a/src/opengl/qgl_egl_p.h +++ b/src/opengl/qgl_egl_p.h @@ -60,7 +60,7 @@ QT_BEGIN_NAMESPACE class QGLFormat; -void qt_egl_set_format(QEglProperties& props, int deviceType, const QGLFormat& f); +void qt_eglproperties_set_glformat(QEglProperties& props, const QGLFormat& format); void qt_egl_update_format(const QEglContext& context, QGLFormat& format); QT_END_NAMESPACE diff --git a/src/opengl/qgl_qws.cpp b/src/opengl/qgl_qws.cpp index c221134..f72f051 100644 --- a/src/opengl/qgl_qws.cpp +++ b/src/opengl/qgl_qws.cpp @@ -186,7 +186,8 @@ bool QGLContext::chooseContext(const QGLContext* shareContext) // Construct the configuration we need for this surface. QEglProperties configProps; - qt_egl_set_format(configProps, devType, d->glFormat); + qt_eglproperties_set_glformat(configProps, d->glFormat); + configProps.setDeviceType(devType); configProps.setPaintDeviceFormat(device()); configProps.setRenderableType(QEgl::OpenGL); diff --git a/src/opengl/qgl_wince.cpp b/src/opengl/qgl_wince.cpp index ed8b4f7..3bf7f3a 100644 --- a/src/opengl/qgl_wince.cpp +++ b/src/opengl/qgl_wince.cpp @@ -149,7 +149,8 @@ bool QGLContext::chooseContext(const QGLContext* shareContext) // Construct the configuration we need for this surface. QEglProperties configProps; - qt_egl_set_format(configProps, devType, d->glFormat); + qt_eglproperties_set_glformat(configProps, d->glFormat); + configProps.setDeviceType(devType); configProps.setPaintDeviceFormat(device()); configProps.setRenderableType(QEgl::OpenGL); diff --git a/src/opengl/qgl_x11egl.cpp b/src/opengl/qgl_x11egl.cpp index 21ddfe3..7be4973 100644 --- a/src/opengl/qgl_x11egl.cpp +++ b/src/opengl/qgl_x11egl.cpp @@ -171,7 +171,8 @@ bool QGLContext::chooseContext(const QGLContext* shareContext) // Construct the configuration we need for this surface. QEglProperties configProps; - qt_egl_set_format(configProps, devType, d->glFormat); + qt_eglproperties_set_glformat(configProps, d->glFormat); + configProps.setDeviceType(devType); configProps.setPaintDeviceFormat(device()); configProps.setRenderableType(QEgl::OpenGL); diff --git a/src/opengl/qglpixelbuffer_egl.cpp b/src/opengl/qglpixelbuffer_egl.cpp index cee5a1f..ee0714f 100644 --- a/src/opengl/qglpixelbuffer_egl.cpp +++ b/src/opengl/qglpixelbuffer_egl.cpp @@ -82,7 +82,8 @@ bool QGLPixelBufferPrivate::init(const QSize &size, const QGLFormat &f, QGLWidge #endif } else { QEglProperties configProps; - qt_egl_set_format(configProps, QInternal::Pbuffer, f); + qt_eglproperties_set_glformat(configProps, f); + configProps.setDeviceType(QInternal::Pbuffer); configProps.setRenderableType(ctx->api()); bool ok = false; #if QGL_RENDER_TEXTURE @@ -208,7 +209,8 @@ bool QGLPixelBuffer::hasOpenGLPbuffers() if (dpy == EGL_NO_DISPLAY) return false; QEglProperties configProps; - qt_egl_set_format(configProps, QInternal::Pbuffer, QGLFormat::defaultFormat()); + qt_eglproperties_set_glformat(configProps, QGLFormat::defaultFormat()); + configProps.setDeviceType(QInternal::Pbuffer); configProps.setRenderableType(QEgl::OpenGL); do { EGLConfig cfg = 0; -- cgit v0.12 From b2cbb880273ae6516d68be5b5f3f9b614c31ca79 Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Mon, 1 Mar 2010 14:12:23 +0100 Subject: Move QGLWidget::setContext logic into QEgl & QGLContext QEgl::createSurface() on X11 will now check to see if the device's X11 Visual is compatible with the EGLConfig passed in. If it is not compatible, the function will re-create the QPaintDevice's native drawable with a different Visual (one which is compatable with the EGLConfig). This represented the bulk of the QGLWidget::setContext method which is now much simpler. As a consequense of this change, QWidgets with graphicssystem opengl will behave much more like QGLWidget as most of the code is re-used. So things like WA_TranslucentBackground should now work with opengl graphicssystem too. Reviewed-By: TrustMe --- src/gui/egl/qegl.cpp | 3 +- src/gui/egl/qegl_x11.cpp | 121 +++++++++++++++++++++++++++ src/gui/image/qpixmap_x11_p.h | 1 + src/gui/kernel/qwidget.h | 1 + src/opengl/qgl_x11egl.cpp | 173 +++++++++++++-------------------------- src/opengl/qwindowsurface_gl.cpp | 12 --- 6 files changed, 180 insertions(+), 131 deletions(-) diff --git a/src/gui/egl/qegl.cpp b/src/gui/egl/qegl.cpp index d4c9913..e2002ed 100644 --- a/src/gui/egl/qegl.cpp +++ b/src/gui/egl/qegl.cpp @@ -570,6 +570,7 @@ EGLNativePixmapType QEgl::nativePixmap(QPixmap* pixmap) return (EGLNativePixmapType)(pixmap->handle()); } +#ifndef Q_WS_X11 EGLSurface QEgl::createSurface(QPaintDevice *device, EGLConfig cfg, const QEglProperties *properties) { // Create the native drawable for the paint device. @@ -607,7 +608,7 @@ EGLSurface QEgl::createSurface(QPaintDevice *device, EGLConfig cfg, const QEglPr } return surf; } - +#endif // Return the error string associated with a specific code. diff --git a/src/gui/egl/qegl_x11.cpp b/src/gui/egl/qegl_x11.cpp index 49c8d60..b710889 100644 --- a/src/gui/egl/qegl_x11.cpp +++ b/src/gui/egl/qegl_x11.cpp @@ -49,6 +49,7 @@ #include #include #include +#include #include "qegl_p.h" #include "qeglcontext_p.h" @@ -261,5 +262,125 @@ VisualID QEgl::getCompatibleVisualId(EGLConfig config) return (VisualID)0; } +void qt_set_winid_on_widget(QWidget* w, Qt::HANDLE id) +{ + w->create(id); +} + + +// NOTE: The X11 version of createSurface will re-create the native drawable if it's visual doesn't +// match the one for the passed in EGLConfig +EGLSurface QEgl::createSurface(QPaintDevice *device, EGLConfig config, const QEglProperties *unusedProperties) +{ + Q_UNUSED(unusedProperties); + + int devType = device->devType(); + + if (devType == QInternal::Pbuffer) { + // TODO + return EGL_NO_SURFACE; + } + + QX11PixmapData *x11PixmapData = 0; + if (devType == QInternal::Pixmap) { + QPixmapData *pmd = static_cast(device)->data_ptr().data(); + if (pmd->classId() == QPixmapData::X11Class) + x11PixmapData = static_cast(pmd); + else { + // TODO: Replace the pixmap's data with a new QX11PixmapData + qWarning("WARNING: Creating an EGL surface on a QPixmap is only supported for QX11PixmapData"); + return EGL_NO_SURFACE; + } + } else if ((devType != QInternal::Widget) && (devType != QInternal::Pbuffer)) { + qWarning("WARNING: Creating an EGLSurface for device type %d isn't supported", devType); + return EGL_NO_SURFACE; + } + + VisualID visualId = QEgl::getCompatibleVisualId(config); + EGLint alphaSize; + eglGetConfigAttrib(QEgl::display(), config, EGL_ALPHA_SIZE, &alphaSize); + + if (devType == QInternal::Widget) { + QWidget *widget = static_cast(device); + + VisualID currentVisualId = 0; + if (widget->testAttribute(Qt::WA_WState_Created)) + currentVisualId = XVisualIDFromVisual((Visual*)widget->x11Info().visual()); + + if (currentVisualId != visualId) { + // The window is either not created or has the wrong visual. Either way, we need + // to create a window with the correct visual and call create() on the widget: + + bool visible = widget->isVisible(); + if (visible) + widget->hide(); + + XVisualInfo visualInfo; + visualInfo.visualid = visualId; + { + XVisualInfo *visualInfoPtr; + int matchingCount = 0; + visualInfoPtr = XGetVisualInfo(widget->x11Info().display(), VisualIDMask, + &visualInfo, &matchingCount); + Q_ASSERT(visualInfoPtr); // visualId really should be valid! + visualInfo = *visualInfoPtr; + XFree(visualInfoPtr); + } + + Window parentWindow = RootWindow(widget->x11Info().display(), widget->x11Info().screen()); + if (widget->parentWidget()) + parentWindow = widget->parentWidget()->winId(); + + XSetWindowAttributes windowAttribs; + QColormap colmap = QColormap::instance(widget->x11Info().screen()); + windowAttribs.background_pixel = colmap.pixel(widget->palette().color(widget->backgroundRole())); + windowAttribs.border_pixel = colmap.pixel(Qt::black); + + unsigned int valueMask = CWBackPixel|CWBorderPixel; + if (alphaSize > 0) { + windowAttribs.colormap = XCreateColormap(widget->x11Info().display(), parentWindow, + visualInfo.visual, AllocNone); + valueMask |= CWColormap; + } + + Window window = XCreateWindow(widget->x11Info().display(), parentWindow, + widget->x(), widget->y(), widget->width(), widget->height(), + 0, visualInfo.depth, InputOutput, visualInfo.visual, + valueMask, &windowAttribs); + + // This is a nasty hack to get round the fact that we can't be a friend of QWidget: + qt_set_winid_on_widget(widget, window); + + if (visible) + widget->show(); + } + + // At this point, the widget's window should be created and have the correct visual. Now we + // just need to create the EGL surface for it: + return eglCreateWindowSurface(QEgl::display(), config, (EGLNativeWindowType)widget->winId(), 0); + } + + if (x11PixmapData) { + VisualID currentVisualId = XVisualIDFromVisual((Visual*)qt_x11Info(device)->visual()); + if (visualId != currentVisualId) + qWarning("Error: The QPixmap's visual does not match the EGLConfig's visual!"); + + QEglProperties surfaceAttribs; + + // If the pixmap can't be bound to a texture, it's pretty useless + surfaceAttribs.setValue(EGL_TEXTURE_TARGET, EGL_TEXTURE_2D); + if (alphaSize > 0) + surfaceAttribs.setValue(EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA); + else + surfaceAttribs.setValue(EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGB); + + return eglCreatePixmapSurface(QEgl::display(), config, + (EGLNativePixmapType) x11PixmapData->handle(), + surfaceAttribs.properties()); + } + + return EGL_NO_SURFACE; +} + QT_END_NAMESPACE diff --git a/src/gui/image/qpixmap_x11_p.h b/src/gui/image/qpixmap_x11_p.h index 0c0a9bd..7bc586d 100644 --- a/src/gui/image/qpixmap_x11_p.h +++ b/src/gui/image/qpixmap_x11_p.h @@ -105,6 +105,7 @@ private: friend class QRasterWindowSurface; friend class QGLContextPrivate; // Needs to access xinfo, gl_surface & flags friend class QEglContext; // Needs gl_surface + friend class QGLContext; // Needs gl_surface friend class QX11GLPixmapData; // Needs gl_surface friend bool qt_createEGLSurfaceForPixmap(QPixmapData*, bool); // Needs gl_surface diff --git a/src/gui/kernel/qwidget.h b/src/gui/kernel/qwidget.h index 0d7475e9..e12148b 100644 --- a/src/gui/kernel/qwidget.h +++ b/src/gui/kernel/qwidget.h @@ -773,6 +773,7 @@ private: #ifdef Q_WS_X11 friend void qt_net_update_user_time(QWidget *tlw, unsigned long timestamp); friend void qt_net_remove_user_time(QWidget *tlw); + friend void qt_set_winid_on_widget(QWidget*, Qt::HANDLE); #endif friend Q_GUI_EXPORT QWidgetData *qt_qwidget_data(QWidget *widget); diff --git a/src/opengl/qgl_x11egl.cpp b/src/opengl/qgl_x11egl.cpp index 7be4973..18a2ee5 100644 --- a/src/opengl/qgl_x11egl.cpp +++ b/src/opengl/qgl_x11egl.cpp @@ -48,6 +48,7 @@ #include "qgl_egl_p.h" #include "qcolormap.h" #include +#include QT_BEGIN_NAMESPACE @@ -164,55 +165,53 @@ bool QGLContext::chooseContext(const QGLContext* shareContext) int devType = device()->devType(); - // Get the display and initialize it. + QX11PixmapData *x11PixmapData = 0; + if (devType == QInternal::Pixmap) { + QPixmapData *pmd = static_cast(device())->data_ptr().data(); + if (pmd->classId() == QPixmapData::X11Class) + x11PixmapData = static_cast(pmd); + else { + // TODO: Replace the pixmap's data with a new QX11PixmapData + qWarning("WARNING: Creating a QGLContext on a QPixmap is only supported for X11 pixmap backend"); + return false; + } + } else if ((devType != QInternal::Widget) && (devType != QInternal::Pbuffer)) { + qWarning("WARNING: Creating a QGLContext not supported on device type %d", devType); + return false; + } + + // Only create the eglContext if we don't already have one: if (d->eglContext == 0) { d->eglContext = new QEglContext(); d->eglContext->setApi(QEgl::OpenGL); + // If the device is a widget with WA_TranslucentBackground set, make sure the glFormat + // has the alpha channel option set: + if (devType == QInternal::Widget) { + QWidget* widget = static_cast(device()); + if (widget->testAttribute(Qt::WA_TranslucentBackground)) + d->glFormat.setAlpha(true); + } + // Construct the configuration we need for this surface. QEglProperties configProps; - qt_eglproperties_set_glformat(configProps, d->glFormat); configProps.setDeviceType(devType); - configProps.setPaintDeviceFormat(device()); configProps.setRenderableType(QEgl::OpenGL); + qt_eglproperties_set_glformat(configProps, d->glFormat); -#if We_have_an_EGL_library_which_bothers_to_check_EGL_BUFFER_SIZE - if (device()->depth() == 16 && configProps.value(EGL_ALPHA_SIZE) <= 0) { - qDebug("Setting EGL_BUFFER_SIZE to 16"); + // Use EGL_BUFFER_SIZE to make sure we prefer a 16-bit config over a 32-bit config + if (device()->depth() == 16 && !d->glFormat.alpha()) configProps.setValue(EGL_BUFFER_SIZE, 16); - configProps.setValue(EGL_ALPHA_SIZE, 0); - } if (!d->eglContext->chooseConfig(configProps, QEgl::BestPixelFormat)) { delete d->eglContext; d->eglContext = 0; return false; } -#else - QEgl::PixelFormatMatch matchType = QEgl::BestPixelFormat; - if ((device()->depth() == 16) && configProps.value(EGL_ALPHA_SIZE) == 0) { - configProps.setValue(EGL_RED_SIZE, 5); - configProps.setValue(EGL_GREEN_SIZE, 6); - configProps.setValue(EGL_BLUE_SIZE, 5); - configProps.setValue(EGL_ALPHA_SIZE, 0); - matchType = QEgl::ExactPixelFormat; - } - - // Search for a matching configuration, reducing the complexity - // each time until we get something that matches. - if (!d->eglContext->chooseConfig(configProps, matchType)) { - delete d->eglContext; - d->eglContext = 0; - return false; - } -#endif - -// qDebug("QGLContext::chooseContext() - using EGL config %d:", d->eglContext->config()); -// qDebug() << QEglProperties(d->eglContext->config()).toString(); // Create a new context for the configuration. - if (!d->eglContext->createContext - (shareContext ? shareContext->d_func()->eglContext : 0)) { + QEglContext* eglSharedContext = shareContext ? shareContext->d_func()->eglContext : 0; + if (!d->eglContext->createContext(eglSharedContext)) { delete d->eglContext; d->eglContext = 0; return false; @@ -220,16 +219,34 @@ bool QGLContext::chooseContext(const QGLContext* shareContext) d->sharing = d->eglContext->isSharing(); if (d->sharing && shareContext) const_cast(shareContext)->d_func()->sharing = true; - -#if defined(EGL_VERSION_1_1) - if (d->glFormat.swapInterval() != -1 && devType == QInternal::Widget) - eglSwapInterval(d->eglContext->display(), d->glFormat.swapInterval()); -#endif } // Inform the higher layers about the actual format properties. qt_egl_update_format(*(d->eglContext), d->glFormat); + + // Do don't create the EGLSurface for everything. + // QWidget - yes, create the EGLSurface and store it in QGLContextPrivate::eglSurface + // QGLWidget - yes, create the EGLSurface and store it in QGLContextPrivate::eglSurface + // QPixmap - yes, create the EGLSurface but store it in QX11PixmapData::gl_surface + // QGLPixelBuffer - no, it creates the surface itself + + if (devType == QInternal::Widget) { + if (d->eglSurface != EGL_NO_SURFACE) + eglDestroySurface(d->eglContext->display(), d->eglSurface); + d->eglSurface = QEgl::createSurface(device(), d->eglContext->config()); + XFlush(X11->display); + setWindowCreated(true); + } + + if (x11PixmapData) { + // TODO: Actually check to see if the existing surface can be re-used + if (x11PixmapData->gl_surface) + eglDestroySurface(d->eglContext->display(), (EGLSurface)x11PixmapData->gl_surface); + + x11PixmapData->gl_surface = (Qt::HANDLE)QEgl::createSurface(device(), d->eglContext->config()); + } + return true; } @@ -277,20 +294,6 @@ void QGLWidget::setContext(QGLContext *context, const QGLContext* shareContext, QGLContext* oldcx = d->glcx; d->glcx = context; - if (parentWidget()) { - // force creation of delay-created widgets - parentWidget()->winId(); - if (parentWidget()->x11Info().screen() != x11Info().screen()) - d_func()->xinfo = parentWidget()->d_func()->xinfo; - } - - // If the application has set WA_TranslucentBackground and not explicitly set - // the alpha buffer size to zero, modify the format so it have an alpha channel - QGLFormat& fmt = d->glcx->d_func()->glFormat; - const bool tryArgbVisual = testAttribute(Qt::WA_TranslucentBackground) || fmt.alpha(); - if (tryArgbVisual && fmt.alphaBufferSize() == -1) - fmt.setAlphaBufferSize(1); - bool createFailed = false; if (!d->glcx->isValid()) { // Create the QGLContext here, which in turn chooses the EGL config @@ -304,74 +307,8 @@ void QGLWidget::setContext(QGLContext *context, const QGLContext* shareContext, return; } - if (d->glcx->windowCreated() || d->glcx->deviceIsPixmap()) { - if (deleteOldContext) - delete oldcx; - return; - } - - bool visible = isVisible(); - if (visible) - hide(); - - QEglContext *eglContext = d->glcx->d_func()->eglContext; - - XVisualInfo vi; - memset(&vi, 0, sizeof(XVisualInfo)); - vi.visualid = QEgl::getCompatibleVisualId(eglContext->config()); - - { - XVisualInfo *visualInfoPtr; - int matchingCount = 0; - visualInfoPtr = XGetVisualInfo(X11->display, VisualIDMask, &vi, &matchingCount); - vi = *visualInfoPtr; - XFree(visualInfoPtr); - } - - bool usingArgbVisual = eglContext->configAttrib(EGL_ALPHA_SIZE) > 0; - - XSetWindowAttributes a; - - Window p = RootWindow(x11Info().display(), x11Info().screen()); - if (parentWidget()) - p = parentWidget()->winId(); - - QColormap colmap = QColormap::instance(vi.screen); - a.background_pixel = colmap.pixel(palette().color(backgroundRole())); - a.border_pixel = colmap.pixel(Qt::black); - - unsigned int valueMask = CWBackPixel|CWBorderPixel; - if (usingArgbVisual) { - a.colormap = XCreateColormap(x11Info().display(), p, vi.visual, AllocNone); - valueMask |= CWColormap; - } - - Window w = XCreateWindow(x11Info().display(), p, x(), y(), width(), height(), - 0, vi.depth, InputOutput, vi.visual, valueMask, &a); - - if (deleteOldContext) - delete oldcx; - oldcx = 0; - - create(w); // Create with the ID of the window we've just created - - - // Create the EGL surface to draw into. - QGLContextPrivate *ctxpriv = d->glcx->d_func(); - ctxpriv->eglSurface = ctxpriv->eglContext->createSurface(this); - if (ctxpriv->eglSurface == EGL_NO_SURFACE) { - delete ctxpriv->eglContext; - ctxpriv->eglContext = 0; - return; - } - - d->eglSurfaceWindowId = w; // Remember the window id we created the surface for - - if (visible) - show(); - XFlush(X11->display); - d->glcx->setWindowCreated(true); + d->eglSurfaceWindowId = winId(); // Remember the window id we created the surface for } void QGLWidgetPrivate::init(QGLContext *context, const QGLWidget* shareWidget) @@ -380,7 +317,7 @@ void QGLWidgetPrivate::init(QGLContext *context, const QGLWidget* shareWidget) initContext(context, shareWidget); - if(q->isValid() && glcx->format().hasOverlay()) { + if (q->isValid() && glcx->format().hasOverlay()) { //no overlay qWarning("QtOpenGL ES doesn't currently support overlays"); } diff --git a/src/opengl/qwindowsurface_gl.cpp b/src/opengl/qwindowsurface_gl.cpp index 0334cbc..ca88de3 100644 --- a/src/opengl/qwindowsurface_gl.cpp +++ b/src/opengl/qwindowsurface_gl.cpp @@ -353,18 +353,6 @@ void QGLWindowSurface::hijackWindow(QWidget *widget) QGLContext *ctx = new QGLContext(surfaceFormat, widget); ctx->create(qt_gl_share_widget()->context()); -#if defined(Q_WS_X11) && defined(QT_OPENGL_ES) - // Create the EGL surface to draw into. QGLContext::chooseContext() - // does not do this for X11/EGL, but does do it for other platforms. - // This probably belongs in qgl_x11egl.cpp. - QGLContextPrivate *ctxpriv = ctx->d_func(); - ctxpriv->eglSurface = ctxpriv->eglContext->createSurface(widget); - if (ctxpriv->eglSurface == EGL_NO_SURFACE) { - qWarning() << "hijackWindow() could not create EGL surface"; - } - qDebug("QGLWindowSurface - using EGLConfig %d", reinterpret_cast(ctxpriv->eglContext->config())); -#endif - widgetPrivate->extraData()->glContext = ctx; union { QGLContext **ctxPtr; void **voidPtr; }; -- cgit v0.12 From 9c1ff07b427765beb71755e964b017d8258b834e Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Mon, 1 Mar 2010 16:53:17 +0100 Subject: Make bindTextureFromNativePixmap use new QEgl APIs The old qt_chooseEGLConfigForPixmap & qt_createEGLSurfaceForPixmap code will remain until QX11GLPixmapData can be re-written properly. Reviewed-By: TrustMe --- src/gui/egl/qegl.cpp | 8 +++----- src/gui/egl/qegl_p.h | 6 ++---- src/gui/egl/qegl_x11.cpp | 23 ++++++++++++++++++++--- src/gui/image/qpixmap_x11.cpp | 4 ++-- src/gui/image/qpixmap_x11_p.h | 9 +++++---- src/opengl/qgl_x11egl.cpp | 9 +++++++-- 6 files changed, 39 insertions(+), 20 deletions(-) diff --git a/src/gui/egl/qegl.cpp b/src/gui/egl/qegl.cpp index e2002ed..1bfba10 100644 --- a/src/gui/egl/qegl.cpp +++ b/src/gui/egl/qegl.cpp @@ -88,10 +88,8 @@ bool QEglContext::isCurrent() const return current; } -EGLConfig QEgl::defaultConfig(QPaintDevice* device, API api, ConfigOptions options) +EGLConfig QEgl::defaultConfig(int devType, API api, ConfigOptions options) { - int devType = device->devType(); - if ( (devType != QInternal::Pixmap) && ((options & Renderable) == 0)) qWarning("QEgl::defaultConfig() - Only configs for pixmaps make sense to be read-only!"); @@ -243,8 +241,8 @@ EGLConfig QEgl::defaultConfig(QPaintDevice* device, API api, ConfigOptions optio #endif } - // Finally, set the color format based on the device: - configAttribs.setPaintDeviceFormat(device); + if (options & Translucent) + configAttribs.setValue(EGL_ALPHA_SIZE, 1); *targetConfig = chooseConfig(&configAttribs, QEgl::BestPixelFormat); return *targetConfig; diff --git a/src/gui/egl/qegl_p.h b/src/gui/egl/qegl_p.h index 7f753d0..aa89772 100644 --- a/src/gui/egl/qegl_p.h +++ b/src/gui/egl/qegl_p.h @@ -116,10 +116,8 @@ namespace QEgl { enum ConfigOptions { - Opaque = 0x00, + NoOptions = 0, Translucent = 0x01, - - ReadOnly = 0x00, Renderable = 0x02 // Config will be compatable with the paint engines (VG or GL) }; @@ -127,7 +125,7 @@ namespace QEgl { // go through the eglChooseConfig loop every time, we use defaultConfig, which will return // the config for a particular device/api/option combo. This function assumes that once a // config is chosen for a particular combo, it's safe to always use that combo. - Q_GUI_EXPORT EGLConfig defaultConfig(QPaintDevice* device, API api, ConfigOptions options); + Q_GUI_EXPORT EGLConfig defaultConfig(int devType, API api, ConfigOptions options); Q_GUI_EXPORT EGLConfig chooseConfig(const QEglProperties* configAttribs, QEgl::PixelFormatMatch match = QEgl::ExactPixelFormat); Q_GUI_EXPORT EGLSurface createSurface(QPaintDevice *device, EGLConfig cfg, const QEglProperties *surfaceAttribs = 0); diff --git a/src/gui/egl/qegl_x11.cpp b/src/gui/egl/qegl_x11.cpp index b710889..a4bfcac 100644 --- a/src/gui/egl/qegl_x11.cpp +++ b/src/gui/egl/qegl_x11.cpp @@ -361,9 +361,26 @@ EGLSurface QEgl::createSurface(QPaintDevice *device, EGLConfig config, const QEg } if (x11PixmapData) { - VisualID currentVisualId = XVisualIDFromVisual((Visual*)qt_x11Info(device)->visual()); - if (visualId != currentVisualId) - qWarning("Error: The QPixmap's visual does not match the EGLConfig's visual!"); + // X11 Pixmaps are only created with a depth, so that's all we need to check + EGLint configDepth; + eglGetConfigAttrib(QEgl::display(), config, EGL_BUFFER_SIZE , &configDepth); + if (x11PixmapData->depth() != configDepth) { + // The bit depths are wrong which means the EGLConfig isn't compatable with + // this pixmap. So we need to replace the pixmap's existing data with a new + // one which is created with the correct depth: + +#ifndef QT_NO_XRENDER + if (configDepth == 32) { + qWarning("Warning: EGLConfig's depth (32) != pixmap's depth (%d), converting to ARGB32", + x11PixmapData->depth()); + x11PixmapData->convertToARGB32(true); + } else +#endif + { + qWarning("Warning: EGLConfig's depth (%d) != pixmap's depth (%d)", + configDepth, x11PixmapData->depth()); + } + } QEglProperties surfaceAttribs; diff --git a/src/gui/image/qpixmap_x11.cpp b/src/gui/image/qpixmap_x11.cpp index b976376..5a882af 100644 --- a/src/gui/image/qpixmap_x11.cpp +++ b/src/gui/image/qpixmap_x11.cpp @@ -314,8 +314,8 @@ static int qt_pixmap_serial = 0; int Q_GUI_EXPORT qt_x11_preferred_pixmap_depth = 0; QX11PixmapData::QX11PixmapData(PixelType type) - : QPixmapData(type, X11Class), hd(0), - flags(Uninitialized), x11_mask(0), picture(0), mask_picture(0), hd2(0), gl_surface(0), + : QPixmapData(type, X11Class), gl_surface(0), hd(0), + flags(Uninitialized), x11_mask(0), picture(0), mask_picture(0), hd2(0), share_mode(QPixmap::ImplicitlyShared), pengine(0) { } diff --git a/src/gui/image/qpixmap_x11_p.h b/src/gui/image/qpixmap_x11_p.h index 7bc586d..521a612 100644 --- a/src/gui/image/qpixmap_x11_p.h +++ b/src/gui/image/qpixmap_x11_p.h @@ -94,6 +94,11 @@ public: static Qt::HANDLE createBitmapFromImage(const QImage &image); + Qt::HANDLE gl_surface; +#ifndef QT_NO_XRENDER + void convertToARGB32(bool preserveContents = true); +#endif + protected: int metric(QPaintDevice::PaintDeviceMetric metric) const; @@ -131,10 +136,6 @@ private: Qt::HANDLE picture; Qt::HANDLE mask_picture; Qt::HANDLE hd2; // sorted in the default display depth - Qt::HANDLE gl_surface; -#ifndef QT_NO_XRENDER - void convertToARGB32(bool preserveContents = true); -#endif QPixmap::ShareMode share_mode; QX11PaintEngine *pengine; diff --git a/src/opengl/qgl_x11egl.cpp b/src/opengl/qgl_x11egl.cpp index 18a2ee5..bcde8c4 100644 --- a/src/opengl/qgl_x11egl.cpp +++ b/src/opengl/qgl_x11egl.cpp @@ -508,8 +508,13 @@ QGLTexture *QGLContextPrivate::bindTextureFromNativePixmap(QPixmapData* pd, cons } if (pixmapData->gl_surface == 0) { - bool success = qt_createEGLSurfaceForPixmap(pixmapData, true); - if (!success) { + EGLConfig config = QEgl::defaultConfig(QInternal::Pixmap, + QEgl::OpenGL, + hasAlpha ? QEgl::Translucent : QEgl::NoOptions); + + QPixmap tmpPixmap(pixmapData); //### + pixmapData->gl_surface = (Qt::HANDLE)QEgl::createSurface(&tmpPixmap, config); + if (pixmapData->gl_surface == (Qt::HANDLE)EGL_NO_SURFACE) { haveTFP = false; return 0; } -- cgit v0.12 From 3708ff474a987ddb82f7b66d8c686f499b65eeb6 Mon Sep 17 00:00:00 2001 From: aavit Date: Tue, 2 Mar 2010 13:36:55 +0100 Subject: Updates to changes file Reviewed-by: trustme --- dist/changes-4.7.0 | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/dist/changes-4.7.0 b/dist/changes-4.7.0 index 013f1ce..4d776ee 100644 --- a/dist/changes-4.7.0 +++ b/dist/changes-4.7.0 @@ -30,6 +30,12 @@ General Improvements Third party components ---------------------- + - Updated libpng to version 1.4.0 + + - Updated libjpeg to version 8 + + - Updated libtiff to version 3.9.2 + **************************************************************************** * Library * -- cgit v0.12 From a140e37fab6a1d028fd1b751a98774dacb4f1a89 Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Tue, 2 Mar 2010 13:42:05 +0100 Subject: Fix & move QEgl::native* to platform-specific files This should fix build on Symbian & WinCE Reviewed-By: TrustMe --- src/gui/egl/qegl.cpp | 19 ------------------- src/gui/egl/qegl_qws.cpp | 17 +++++++++++++++++ src/gui/egl/qegl_symbian.cpp | 11 +++++++++++ src/gui/egl/qegl_wince.cpp | 11 +++++++++++ src/gui/egl/qegl_x11.cpp | 11 ++++++++++- 5 files changed, 49 insertions(+), 20 deletions(-) diff --git a/src/gui/egl/qegl.cpp b/src/gui/egl/qegl.cpp index 1bfba10..485bfbf 100644 --- a/src/gui/egl/qegl.cpp +++ b/src/gui/egl/qegl.cpp @@ -549,25 +549,6 @@ EGLDisplay QEgl::display() return dpy; } -#if !defined(Q_WS_X11) && !defined(Q_WS_WINCE) // WinCE & X11 implement this properly -EGLNativeDisplayType QEgl::nativeDisplay() -{ - return EGL_DEFAULT_DISPLAY; -} -#endif - -#if !defined(Q_OS_SYMBIAN) -EGLNativeWindowType QEgl::nativeWindow(QWidget* widget) -{ - return (EGLNativeWindowType)(widget->winId()); -} -#endif - -EGLNativePixmapType QEgl::nativePixmap(QPixmap* pixmap) -{ - return (EGLNativePixmapType)(pixmap->handle()); -} - #ifndef Q_WS_X11 EGLSurface QEgl::createSurface(QPaintDevice *device, EGLConfig cfg, const QEglProperties *properties) { diff --git a/src/gui/egl/qegl_qws.cpp b/src/gui/egl/qegl_qws.cpp index eb41bcc..56383a5 100644 --- a/src/gui/egl/qegl_qws.cpp +++ b/src/gui/egl/qegl_qws.cpp @@ -92,6 +92,23 @@ void QEglProperties::setPaintDeviceFormat(QPaintDevice *dev) setPixelFormat(screen->pixelFormat()); } +EGLNativeDisplayType QEgl::nativeDisplay() +{ + return EGL_DEFAULT_DISPLAY; +} + +EGLNativeWindowType QEgl::nativeWindow(QWidget* widget) +{ + return (EGLNativeWindowType)(widget->winId()); // Might work +} + +EGLNativePixmapType QEgl::nativePixmap(QPixmap*) +{ + qWarning("QEgl: EGL pixmap surfaces not supported on QWS"); + return (EGLNativePixmapType)0; +} + + QT_END_NAMESPACE #endif // !QT_NO_EGL diff --git a/src/gui/egl/qegl_symbian.cpp b/src/gui/egl/qegl_symbian.cpp index 8833b42..9744ed0 100644 --- a/src/gui/egl/qegl_symbian.cpp +++ b/src/gui/egl/qegl_symbian.cpp @@ -50,11 +50,22 @@ QT_BEGIN_NAMESPACE +EGLNativeDisplayType QEgl::nativeDisplay() +{ + return EGL_DEFAULT_DISPLAY; +} + EGLNativeWindowType QEgl::nativeWindow(QWidget* widget) { return (EGLNativeWindowType)(widget->winId()->DrawableWindow()); } +EGLNativePixmapType QEgl::nativePixmap(QPixmap*) +{ + qWarning("QEgl: EGL pixmap surfaces not implemented yet on Symbian"); + return (EGLNativePixmapType)0; +} + // Set pixel format and other properties based on a paint device. void QEglProperties::setPaintDeviceFormat(QPaintDevice *dev) { diff --git a/src/gui/egl/qegl_wince.cpp b/src/gui/egl/qegl_wince.cpp index b201153..c07b20b 100644 --- a/src/gui/egl/qegl_wince.cpp +++ b/src/gui/egl/qegl_wince.cpp @@ -62,6 +62,17 @@ EGLNativeDisplayType QEgl::nativeDisplay() return EGLNativeDisplayType(myDc); } +EGLNativeWindowType QEgl::nativeWindow(QWidget* widget) +{ + return (EGLNativeWindowType)(widget->winId()); +} + +EGLNativePixmapType QEgl::nativePixmap(QPixmap*) +{ + qWarning("QEgl: EGL pixmap surfaces not supported on WinCE"); + return (EGLNativePixmapType)0; +} + // Set pixel format and other properties based on a paint device. void QEglProperties::setPaintDeviceFormat(QPaintDevice *dev) { diff --git a/src/gui/egl/qegl_x11.cpp b/src/gui/egl/qegl_x11.cpp index a4bfcac..339bd57 100644 --- a/src/gui/egl/qegl_x11.cpp +++ b/src/gui/egl/qegl_x11.cpp @@ -67,6 +67,16 @@ EGLNativeDisplayType QEgl::nativeDisplay() return EGLNativeDisplayType(xdpy); } +EGLNativeWindowType QEgl::nativeWindow(QWidget* widget) +{ + return (EGLNativeWindowType)(widget->winId()); +} + +EGLNativePixmapType QEgl::nativePixmap(QPixmap* pixmap) +{ + return (EGLNativePixmapType)(pixmap->handle()); +} + static int countBits(unsigned long mask) { int count = 0; @@ -399,5 +409,4 @@ EGLSurface QEgl::createSurface(QPaintDevice *device, EGLConfig config, const QEg return EGL_NO_SURFACE; } - QT_END_NAMESPACE -- cgit v0.12