summaryrefslogtreecommitdiffstats
path: root/src/opengl/qgl_x11.cpp
diff options
context:
space:
mode:
authorJason Barron <jbarron@trolltech.com>2009-07-24 09:45:33 (GMT)
committerJason Barron <jbarron@trolltech.com>2009-07-27 13:04:30 (GMT)
commit3643028959f0b38350e57e60ba4000435b75e592 (patch)
treec129e4dee11487abd437ab8ebd993ba261e06fa6 /src/opengl/qgl_x11.cpp
parentcf66c667a97c0079141eb3f2d9e997b7378ae792 (diff)
parentc36139c665e61866aff4bf8572890a735167a7d0 (diff)
downloadQt-3643028959f0b38350e57e60ba4000435b75e592.zip
Qt-3643028959f0b38350e57e60ba4000435b75e592.tar.gz
Qt-3643028959f0b38350e57e60ba4000435b75e592.tar.bz2
Merge commit 'qt/master-stable'
Conflicts: configure.exe qmake/Makefile.unix qmake/generators/makefile.cpp src/corelib/global/qglobal.h src/corelib/kernel/kernel.pri src/corelib/kernel/qcoreevent.cpp src/corelib/kernel/qsharedmemory_unix.cpp src/gui/graphicsview/qgraphicsscene.cpp src/gui/kernel/qaction.cpp src/gui/kernel/qaction.h src/gui/kernel/qaction_p.h src/gui/kernel/qapplication.cpp src/gui/kernel/qapplication.h src/gui/kernel/qwidget.cpp src/gui/kernel/qwidget.h src/gui/kernel/qwidget_mac.mm src/gui/painting/qgraphicssystemfactory.cpp src/gui/styles/qwindowsstyle.cpp src/gui/text/qfontengine_qpf.cpp src/gui/widgets/qabstractscrollarea_p.h src/network/access/qnetworkaccessdebugpipebackend.cpp src/network/socket/qlocalsocket_unix.cpp src/network/socket/qnativesocketengine_p.h src/network/socket/qnativesocketengine_unix.cpp src/openvg/qpaintengine_vg.cpp tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp tests/auto/qcssparser/qcssparser.pro tests/auto/qdir/tst_qdir.cpp tests/auto/qfile/tst_qfile.cpp tests/auto/qobject/tst_qobject.cpp tests/auto/qpathclipper/qpathclipper.pro tests/auto/qprocess/tst_qprocess.cpp tests/auto/qsettings/tst_qsettings.cpp tests/auto/qsharedpointer/qsharedpointer.pro tests/auto/qsqlquerymodel/qsqlquerymodel.pro tests/auto/qsqlrelationaltablemodel/qsqlrelationaltablemodel.pro tests/auto/qsqltablemodel/qsqltablemodel.pro tests/auto/qsqlthread/qsqlthread.pro tests/auto/qwidget/tst_qwidget.cpp
Diffstat (limited to 'src/opengl/qgl_x11.cpp')
-rw-r--r--src/opengl/qgl_x11.cpp140
1 files changed, 140 insertions, 0 deletions
diff --git a/src/opengl/qgl_x11.cpp b/src/opengl/qgl_x11.cpp
index 631625b..43bdec7 100644
--- a/src/opengl/qgl_x11.cpp
+++ b/src/opengl/qgl_x11.cpp
@@ -52,6 +52,7 @@
#include "qdebug.h"
#include <private/qfontengine_ft_p.h>
#include <private/qt_x11_p.h>
+#include <private/qpixmap_x11_p.h>
#ifdef Q_OS_HPUX
// for GLXPBuffer
#include <private/qglpixelbuffer_p.h>
@@ -81,6 +82,25 @@ extern const QX11Info *qt_x11Info(const QPaintDevice *pd);
#define GLX_SAMPLES_ARB 100001
#endif
+#ifndef GLX_EXT_texture_from_pixmap
+#define GLX_TEXTURE_2D_BIT_EXT 0x00000002
+#define GLX_TEXTURE_RECTANGLE_BIT_EXT 0x00000004
+#define GLX_BIND_TO_TEXTURE_RGB_EXT 0x20D0
+#define GLX_BIND_TO_TEXTURE_RGBA_EXT 0x20D1
+#define GLX_BIND_TO_MIPMAP_TEXTURE_EXT 0x20D2
+#define GLX_BIND_TO_TEXTURE_TARGETS_EXT 0x20D3
+#define GLX_Y_INVERTED_EXT 0x20D4
+#define GLX_TEXTURE_FORMAT_EXT 0x20D5
+#define GLX_TEXTURE_TARGET_EXT 0x20D6
+#define GLX_MIPMAP_TEXTURE_EXT 0x20D7
+#define GLX_TEXTURE_FORMAT_NONE_EXT 0x20D8
+#define GLX_TEXTURE_FORMAT_RGB_EXT 0x20D9
+#define GLX_TEXTURE_FORMAT_RGBA_EXT 0x20DA
+#define GLX_TEXTURE_2D_EXT 0x20DC
+#define GLX_TEXTURE_RECTANGLE_EXT 0x20DD
+#define GLX_FRONT_LEFT_EXT 0x20DE
+#endif
+
/*
The qt_gl_choose_cmap function is internal and used by QGLWidget::setContext()
and GLX (not Windows). If the application can't find any sharable
@@ -1516,4 +1536,124 @@ void QGLExtensions::init()
}
}
+
+typedef void (*qt_glXBindTexImageEXT)(Display*, GLXDrawable, int, const int*);
+typedef void (*qt_glXReleaseTexImageEXT)(Display*, GLXDrawable, int);
+static qt_glXBindTexImageEXT glXBindTexImageEXT = 0;
+static qt_glXReleaseTexImageEXT glXReleaseTexImageEXT = 0;
+static bool qt_resolved_texture_from_pixmap = false;
+
+QGLTexture *QGLContextPrivate::bindTextureFromNativePixmap(QPixmap *pm, const qint64 key, bool canInvert)
+{
+ Q_Q(QGLContext);
+
+ if (pm->data_ptr()->classId() != QPixmapData::X11Class)
+ return 0;
+ QX11PixmapData *pixmapData = static_cast<QX11PixmapData*>(pm->data_ptr());
+ const QX11Info *x11Info = qt_x11Info(pm);
+
+
+ // Check to see if we have NPOT texture support
+ // TODO: Use GLX_TEXTURE_RECTANGLE_EXT texture target on systems without npot textures
+ if ( !(QGLExtensions::glExtensions & QGLExtensions::NPOTTextures) &&
+ !(QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_2_0))
+ return 0;
+
+ if (!qt_resolved_texture_from_pixmap) {
+ qt_resolved_texture_from_pixmap = true;
+
+ QString glxExt = QLatin1String(glXGetClientString(QX11Info::display(), GLX_EXTENSIONS));
+ if (glxExt.contains(QLatin1String("GLX_EXT_texture_from_pixmap"))) {
+#if defined(Q_OS_LINUX) || defined(Q_OS_BSD4)
+ void *handle = dlopen(NULL, RTLD_LAZY);
+ if (handle) {
+ glXBindTexImageEXT = (qt_glXBindTexImageEXT) dlsym(handle, "glXBindTexImageEXT");
+ glXReleaseTexImageEXT = (qt_glXReleaseTexImageEXT) dlsym(handle, "glXReleaseTexImageEXT");
+ dlclose(handle);
+ }
+ if (!glXBindTexImageEXT)
+#endif
+ {
+ extern const QString qt_gl_library_name();
+ QLibrary lib(qt_gl_library_name());
+ glXBindTexImageEXT = (qt_glXBindTexImageEXT) lib.resolve("glXBindTexImageEXT");
+ glXReleaseTexImageEXT = (qt_glXReleaseTexImageEXT) lib.resolve("glXReleaseTexImageEXT");
+ }
+ }
+ }
+
+ if (!glXBindTexImageEXT)
+ return 0;
+
+#if !defined(GLX_VERSION_1_3) || defined(Q_OS_HPUX)
+ return 0;
+#else
+ GLXFBConfig *configList = 0;
+ GLXFBConfig glxPixmapConfig;
+ int configCount = 0;
+ bool hasAlpha = pixmapData->hasAlphaChannel();
+
+ int configAttribs[] = {
+ hasAlpha ? GLX_BIND_TO_TEXTURE_RGBA_EXT : GLX_BIND_TO_TEXTURE_RGB_EXT, True,
+ GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT,
+ GLX_BIND_TO_TEXTURE_TARGETS_EXT, GLX_TEXTURE_2D_BIT_EXT,
+ // QGLContext::bindTexture() can't return an inverted texture, but QPainter::drawPixmap() can:
+ GLX_Y_INVERTED_EXT, canInvert ? GLX_DONT_CARE : False,
+ XNone
+// GLX_BIND_TO_MIPMAP_TEXTURE_EXT, False,
+// GLX_BIND_TO_TEXTURE_TARGETS_EXT, GLX_TEXTURE_1D_BIT_EXT or GLX_TEXTURE_2D_BIT_EXT or GLX_TEXTURE_RECTANGLE_BIT_EXT
+ };
+ configList = glXChooseFBConfig(x11Info->display(), x11Info->screen(), configAttribs, &configCount);
+ if (!configList)
+ return 0;
+ glxPixmapConfig = configList[0];
+ XFree(configList);
+
+ GLXPixmap glxPixmap;
+ int pixmapAttribs[] = {
+ GLX_TEXTURE_FORMAT_EXT, hasAlpha ? GLX_TEXTURE_FORMAT_RGBA_EXT : GLX_TEXTURE_FORMAT_RGB_EXT,
+ GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT,
+ GLX_MIPMAP_TEXTURE_EXT, False,
+ XNone
+// GLX_TEXTURE_FORMAT_EXT, GLX_TEXTURE_FORMAT_RGBA_EXT or GLX_TEXTURE_FORMAT_RGB_EXT or GLX_TEXTURE_FORMAT_NONE_EXT,
+// GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT or GLX_TEXTURE_RECTANGLE_EXT,
+// GLX_MIPMAP_TEXTURE_EXT, True or False,
+ };
+
+ // Wrap the X Pixmap into a GLXPixmap:
+ glxPixmap = glXCreatePixmap(x11Info->display(), glxPixmapConfig, pixmapData->handle(), pixmapAttribs);
+
+ if (!glxPixmap)
+ return 0;
+
+ int yInverted;
+ glXGetFBConfigAttrib(x11Info->display(), glxPixmapConfig, GLX_Y_INVERTED_EXT, &yInverted);
+
+ GLuint textureId;
+ glGenTextures(1, &textureId);
+ glBindTexture(GL_TEXTURE_2D, textureId);
+ glXBindTexImageEXT(x11Info->display(), glxPixmap, GLX_FRONT_LEFT_EXT, 0);
+
+ glBindTexture(GL_TEXTURE_2D, textureId);
+
+ QGLTexture *texture = new QGLTexture(q, textureId, GL_TEXTURE_2D, canInvert, yInverted);
+ texture->boundPixmap = glxPixmap;
+
+ // We assume the cost of bound pixmaps is zero
+ QGLTextureCache::instance()->insert(q, key, texture, 0);
+
+ return texture;
+#endif //!defined(GLX_VERSION_1_3) || defined(Q_OS_HPUX)
+}
+
+void QGLTexture::deleteBoundPixmap()
+{
+ if (boundPixmap) {
+ glXReleaseTexImageEXT(QX11Info::display(), boundPixmap, GLX_FRONT_LEFT_EXT);
+ glXDestroyPixmap(QX11Info::display(), boundPixmap);
+ boundPixmap = 0;
+ }
+}
+
+
QT_END_NAMESPACE