From 0d5170256c1658b0f6e0d3f6c736de01655b29d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Tue, 16 Aug 2011 12:53:04 +0200 Subject: Get rid of OpenGL 1.x engine and platform code from QtOpenGL. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I646b8e26d5e7214432a044866764d57cc11b2390 Reviewed-on: http://codereview.qt.nokia.com/3006 Reviewed-by: Qt Sanity Bot Reviewed-by: Jørgen Lind --- src/opengl/qgl_x11egl.cpp | 548 ---------------------------------------------- 1 file changed, 548 deletions(-) delete mode 100644 src/opengl/qgl_x11egl.cpp (limited to 'src/opengl/qgl_x11egl.cpp') diff --git a/src/opengl/qgl_x11egl.cpp b/src/opengl/qgl_x11egl.cpp deleted file mode 100644 index e8520414d6..0000000000 --- a/src/opengl/qgl_x11egl.cpp +++ /dev/null @@ -1,548 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtOpenGL module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qgl.h" -#include -#include -#include -#include -#include "qgl_egl_p.h" -#include "qcolormap.h" -#include -#include - - -QT_BEGIN_NAMESPACE - - -/* - QGLTemporaryContext implementation -*/ - -class QGLTemporaryContextPrivate -{ -public: - bool initialized; - Window window; - EGLContext context; - EGLSurface surface; - EGLDisplay display; -}; - -QGLTemporaryContext::QGLTemporaryContext(bool, QWidget *) - : d(new QGLTemporaryContextPrivate) -{ - d->initialized = false; - d->window = 0; - d->context = 0; - d->surface = 0; - int screen = 0; - - d->display = QEgl::display(); - - EGLConfig config; - int numConfigs = 0; - EGLint attribs[] = { - EGL_SURFACE_TYPE, EGL_WINDOW_BIT, -#ifdef QT_OPENGL_ES_2 - EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, -#endif - EGL_NONE - }; - - eglChooseConfig(d->display, attribs, &config, 1, &numConfigs); - if (!numConfigs) { - qWarning("QGLTemporaryContext: No EGL configurations available."); - return; - } - - XVisualInfo visualInfo; - XVisualInfo *vi; - int numVisuals; - - 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."); - return; - } - - XSetWindowAttributes attr; - unsigned long mask; - attr.background_pixel = 0; - attr.border_pixel = 0; - attr.colormap = XCreateColormap(X11->display, DefaultRootWindow(X11->display), vi->visual, AllocNone); - attr.event_mask = StructureNotifyMask | ExposureMask; - mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; - - d->window = XCreateWindow(X11->display, RootWindow(X11->display, screen), - 0, 0, 1, 1, 0, - vi->depth, InputOutput, vi->visual, - mask, &attr); - - d->surface = eglCreateWindowSurface(d->display, config, (EGLNativeWindowType) d->window, NULL); - - if (d->surface == EGL_NO_SURFACE) { - qWarning("QGLTemporaryContext: Error creating EGL surface."); - XFree(vi); - XDestroyWindow(X11->display, d->window); - return; - } - - EGLint contextAttribs[] = { -#ifdef QT_OPENGL_ES_2 - EGL_CONTEXT_CLIENT_VERSION, 2, -#endif - EGL_NONE - }; - d->context = eglCreateContext(d->display, config, 0, contextAttribs); - if (d->context != EGL_NO_CONTEXT - && eglMakeCurrent(d->display, d->surface, d->surface, d->context)) - { - d->initialized = true; - } else { - qWarning("QGLTemporaryContext: Error creating EGL context."); - eglDestroySurface(d->display, d->surface); - XDestroyWindow(X11->display, d->window); - } - XFree(vi); -} - -QGLTemporaryContext::~QGLTemporaryContext() -{ - if (d->initialized) { - eglMakeCurrent(d->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); - eglDestroyContext(d->display, d->context); - eglDestroySurface(d->display, d->surface); - XDestroyWindow(X11->display, d->window); - } -} - -bool QGLFormat::hasOpenGLOverlays() -{ - return false; -} - -// Chooses the EGL config and creates the EGL context -bool QGLContext::chooseContext(const QGLContext* shareContext) -{ - Q_D(QGLContext); - - if (!device()) - return false; - - int devType = device()->devType(); - - QX11PlatformPixmap *x11PlatformPixmap = 0; - if (devType == QInternal::Pixmap) { - QPlatformPixmap *pmd = static_cast(device())->data_ptr().data(); - if (pmd->classId() == QPlatformPixmap::X11Class) - x11PlatformPixmap = static_cast(pmd); - else { - // TODO: Replace the pixmap's data with a new QX11PlatformPixmap - 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->ownsEglContext = true; - 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; - configProps.setDeviceType(devType); - configProps.setRenderableType(QEgl::OpenGL); - qt_eglproperties_set_glformat(configProps, d->glFormat); - - // Set buffer preserved for regular QWidgets, QGLWidgets are ok with either preserved or destroyed: - if ((devType == QInternal::Widget) && qobject_cast(static_cast(device())) == 0) - configProps.setValue(EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED); - - if (!d->eglContext->chooseConfig(configProps, QEgl::BestPixelFormat)) { - delete d->eglContext; - d->eglContext = 0; - return false; - } - - // Create a new context for the configuration. - QEglContext* eglSharedContext = shareContext ? shareContext->d_func()->eglContext : 0; - if (!d->eglContext->createContext(eglSharedContext)) { - delete d->eglContext; - d->eglContext = 0; - return false; - } - d->sharing = d->eglContext->isSharing(); - if (d->sharing && shareContext) - const_cast(shareContext)->d_func()->sharing = true; - } - - // Inform the higher layers about the actual format properties - qt_glformat_from_eglconfig(d->glFormat, d->eglContext->config()); - - // 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 QX11PlatformPixmap::gl_surface - // QGLPixelBuffer - no, it creates the surface itself and stores it in QGLPixelBufferPrivate::pbuf - - if (devType == QInternal::Widget) { - if (d->eglSurface != EGL_NO_SURFACE) - eglDestroySurface(d->eglContext->display(), d->eglSurface); - // extraWindowSurfaceCreationProps default to NULL unless were specifically set before - d->eglSurface = QEgl::createSurface(device(), d->eglContext->config(), d->extraWindowSurfaceCreationProps); - XFlush(X11->display); - setWindowCreated(true); - } - - if (x11PlatformPixmap) { - // TODO: Actually check to see if the existing surface can be re-used - if (x11PlatformPixmap->gl_surface) - eglDestroySurface(d->eglContext->display(), (EGLSurface)x11PlatformPixmap->gl_surface); - - x11PlatformPixmap->gl_surface = (void*)QEgl::createSurface(device(), d->eglContext->config()); - } - - return true; -} - -void QGLWidget::resizeEvent(QResizeEvent *) -{ - Q_D(QGLWidget); - if (!isValid()) - return; - makeCurrent(); - if (!d->glcx->initialized()) - glInit(); - resizeGL(width(), height()); - //handle overlay -} - -const QGLContext* QGLWidget::overlayContext() const -{ - return 0; -} - -void QGLWidget::makeOverlayCurrent() -{ - //handle overlay -} - -void QGLWidget::updateOverlayGL() -{ - //handle overlay -} - -void QGLWidget::setContext(QGLContext *context, const QGLContext* shareContext, bool deleteOldContext) -{ - Q_D(QGLWidget); - if (context == 0) { - qWarning("QGLWidget::setContext: Cannot set null context"); - return; - } - if (!context->deviceIsPixmap() && context->device() != this) { - qWarning("QGLWidget::setContext: Context must refer to this widget"); - return; - } - - if (d->glcx) - d->glcx->doneCurrent(); - QGLContext* oldcx = d->glcx; - d->glcx = context; - - bool createFailed = false; - if (!d->glcx->isValid()) { - // Create the QGLContext here, which in turn chooses the EGL config - // and creates the EGL context: - if (!d->glcx->create(shareContext ? shareContext : oldcx)) - createFailed = true; - } - if (createFailed) { - if (deleteOldContext) - delete oldcx; - return; - } - - - d->eglSurfaceWindowId = winId(); // Remember the window id we created the surface for -} - -void QGLWidgetPrivate::init(QGLContext *context, const QGLWidget* shareWidget) -{ - Q_Q(QGLWidget); - - initContext(context, shareWidget); - - if (q->isValid() && glcx->format().hasOverlay()) { - //no overlay - qWarning("QtOpenGL ES doesn't currently support overlays"); - } -} - -void QGLWidgetPrivate::cleanupColormaps() -{ -} - -const QGLColormap & QGLWidget::colormap() const -{ - return d_func()->cmap; -} - -void QGLWidget::setColormap(const QGLColormap &) -{ -} - -// Re-creates the EGL surface if the window ID has changed or if there isn't a surface -void QGLWidgetPrivate::recreateEglSurface() -{ - Q_Q(QGLWidget); - - Window currentId = q->winId(); - - // If the window ID has changed since the surface was created, we need to delete the - // old surface before re-creating a new one. Note: This should not be the case as the - // surface should be deleted before the old window id. - if (glcx->d_func()->eglSurface != EGL_NO_SURFACE && (currentId != eglSurfaceWindowId)) { - qWarning("EGL surface for deleted window %lx was not destroyed", uint(eglSurfaceWindowId)); - glcx->d_func()->destroyEglSurfaceForDevice(); - } - - if (glcx->d_func()->eglSurface == EGL_NO_SURFACE) { - glcx->d_func()->eglSurface = glcx->d_func()->eglContext->createSurface(q); - eglSurfaceWindowId = currentId; - } -} - - -QGLTexture *QGLContextPrivate::bindTextureFromNativePixmap(QPixmap *pixmap, const qint64 key, - QGLContext::BindOptions options) -{ - Q_Q(QGLContext); - - // The EGL texture_from_pixmap has no facility to invert the y coordinate - if (!(options & QGLContext::CanFlipNativePixmapBindOption)) - return 0; - - - static bool checkedForTFP = false; - static bool haveTFP = false; - static bool checkedForEglImageTFP = false; - static bool haveEglImageTFP = false; - - - if (!checkedForEglImageTFP) { - checkedForEglImageTFP = true; - - // We need to be able to create an EGLImage from a native pixmap, which was split - // into a separate EGL extension, EGL_KHR_image_pixmap. It is possible to have - // eglCreateImageKHR & eglDestroyImageKHR without support for pixmaps, so we must - // check we have the EGLImage from pixmap functionality. - if (QEgl::hasExtension("EGL_KHR_image") || QEgl::hasExtension("EGL_KHR_image_pixmap")) { - - // Being able to create an EGLImage from a native pixmap is also pretty useless - // without the ability to bind that EGLImage as a texture, which is provided by - // the GL_OES_EGL_image extension, which we try to resolve here: - haveEglImageTFP = qt_resolve_eglimage_gl_extensions(q); - - if (haveEglImageTFP) - qDebug("Found EGL_KHR_image_pixmap & GL_OES_EGL_image extensions (preferred method)!"); - } - } - - if (!checkedForTFP) { - // Check for texture_from_pixmap egl extension - checkedForTFP = true; - if (QEgl::hasExtension("EGL_NOKIA_texture_from_pixmap") || - QEgl::hasExtension("EGL_EXT_texture_from_pixmap")) - { - qDebug("Found texture_from_pixmap EGL extension!"); - haveTFP = true; - } - } - - if (!haveTFP && !haveEglImageTFP) - return 0; - - - QX11PlatformPixmap *handle = static_cast(pixmap->data_ptr().data()); - Q_ASSERT(handle->classId() == QPlatformPixmap::X11Class); - bool hasAlpha = handle->hasAlphaChannel(); - bool pixmapHasValidSurface = false; - bool textureIsBound = false; - GLuint textureId; - glGenTextures(1, &textureId); - glBindTexture(GL_TEXTURE_2D, textureId); - - if (haveTFP && handle->gl_surface && - hasAlpha == (handle->flags & QX11PlatformPixmap::GlSurfaceCreatedWithAlpha)) - { - pixmapHasValidSurface = true; - } - - // If we already have a valid EGL surface for the pixmap, we should use it - if (pixmapHasValidSurface) { - EGLBoolean success; - success = eglBindTexImage(QEgl::display(), (EGLSurface)handle->gl_surface, EGL_BACK_BUFFER); - if (success == EGL_FALSE) { - qWarning() << "eglBindTexImage() failed:" << QEgl::errorString(); - eglDestroySurface(QEgl::display(), (EGLSurface)handle->gl_surface); - handle->gl_surface = (void*)EGL_NO_SURFACE; - } else - textureIsBound = true; - } - - // If the pixmap doesn't already have a valid surface, try binding it via EGLImage - // first, as going through EGLImage should be faster and better supported: - if (!textureIsBound && haveEglImageTFP) { - EGLImageKHR eglImage; - - EGLint attribs[] = { - EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, - EGL_NONE - }; - eglImage = QEgl::eglCreateImageKHR(QEgl::display(), EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR, - (EGLClientBuffer)QEgl::nativePixmap(pixmap), attribs); - - QGLContext* ctx = q; - glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, eglImage); - - GLint err = glGetError(); - if (err == GL_NO_ERROR) - textureIsBound = true; - - // Once the egl image is bound, the texture becomes a new sibling image and we can safely - // destroy the EGLImage we created for the pixmap: - if (eglImage != EGL_NO_IMAGE_KHR) - QEgl::eglDestroyImageKHR(QEgl::display(), eglImage); - } - - if (!textureIsBound && haveTFP) { - // Check to see if the surface is still valid - if (handle->gl_surface && - hasAlpha != (handle->flags & QX11PlatformPixmap::GlSurfaceCreatedWithAlpha)) - { - // Surface is invalid! - destroyGlSurfaceForPixmap(handle); - } - - if (handle->gl_surface == 0) { - EGLConfig config = QEgl::defaultConfig(QInternal::Pixmap, - QEgl::OpenGL, - hasAlpha ? QEgl::Translucent : QEgl::NoOptions); - - handle->gl_surface = (void*)QEgl::createSurface(pixmap, config); - if (handle->gl_surface == (void*)EGL_NO_SURFACE) - return false; - } - - EGLBoolean success; - success = eglBindTexImage(QEgl::display(), (EGLSurface)handle->gl_surface, EGL_BACK_BUFFER); - if (success == EGL_FALSE) { - qWarning() << "eglBindTexImage() failed:" << QEgl::errorString(); - eglDestroySurface(QEgl::display(), (EGLSurface)handle->gl_surface); - handle->gl_surface = (void*)EGL_NO_SURFACE; - haveTFP = false; // If TFP isn't working, disable it's use - } else - textureIsBound = true; - } - - QGLTexture *texture = 0; - - if (textureIsBound) { - texture = new QGLTexture(q, textureId, GL_TEXTURE_2D, options); - handle->flags |= QX11PlatformPixmap::InvertedWhenBoundToTexture; - - // We assume the cost of bound pixmaps is zero - QGLTextureCache::instance()->insert(q, key, texture, 0); - - glBindTexture(GL_TEXTURE_2D, textureId); - } else - glDeleteTextures(1, &textureId); - - return texture; -} - - -void QGLContextPrivate::destroyGlSurfaceForPixmap(QPlatformPixmap* pmd) -{ - Q_ASSERT(pmd->classId() == QPlatformPixmap::X11Class); - QX11PlatformPixmap *handle = static_cast(pmd); - if (handle->gl_surface) { - EGLBoolean success; - success = eglDestroySurface(QEgl::display(), (EGLSurface)handle->gl_surface); - if (success == EGL_FALSE) { - qWarning() << "destroyGlSurfaceForPixmap() - Error deleting surface: " - << QEgl::errorString(); - } - handle->gl_surface = 0; - } -} - -void QGLContextPrivate::unbindPixmapFromTexture(QPlatformPixmap* pmd) -{ - Q_ASSERT(pmd->classId() == QPlatformPixmap::X11Class); - QX11PlatformPixmap *handle = static_cast(pmd); - if (handle->gl_surface) { - EGLBoolean success; - success = eglReleaseTexImage(QEgl::display(), - (EGLSurface)handle->gl_surface, - EGL_BACK_BUFFER); - if (success == EGL_FALSE) { - qWarning() << "unbindPixmapFromTexture() - Unable to release bound texture: " - << QEgl::errorString(); - } - } -} - -QT_END_NAMESPACE -- cgit v1.2.3