1 /**************************************************************************** |
1 /**************************************************************************** |
2 ** |
2 ** |
3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). |
3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). |
4 ** All rights reserved. |
4 ** All rights reserved. |
5 ** Contact: Nokia Corporation (qt-info@nokia.com) |
5 ** Contact: Nokia Corporation (qt-info@nokia.com) |
6 ** |
6 ** |
7 ** This file is part of the QtOpenGL module of the Qt Toolkit. |
7 ** This file is part of the QtOpenGL module of the Qt Toolkit. |
8 ** |
8 ** |
547 QGLFormat fmt = format(); |
547 QGLFormat fmt = format(); |
548 bool tryDouble = !fmt.doubleBuffer(); // Some GL impl's only have double |
548 bool tryDouble = !fmt.doubleBuffer(); // Some GL impl's only have double |
549 bool triedDouble = false; |
549 bool triedDouble = false; |
550 bool triedSample = false; |
550 bool triedSample = false; |
551 if (fmt.sampleBuffers()) |
551 if (fmt.sampleBuffers()) |
552 fmt.setSampleBuffers(QGLExtensions::glExtensions & QGLExtensions::SampleBuffers); |
552 fmt.setSampleBuffers(QGLExtensions::glExtensions() & QGLExtensions::SampleBuffers); |
553 while(!fail && !(vis = tryVisual(fmt, bufDepths[i]))) { |
553 while(!fail && !(vis = tryVisual(fmt, bufDepths[i]))) { |
554 if (!fmt.rgba() && bufDepths[i] > 1) { |
554 if (!fmt.rgba() && bufDepths[i] > 1) { |
555 i++; |
555 i++; |
556 continue; |
556 continue; |
557 } |
557 } |
1130 if (!glXGetProcAddressARB) |
1130 if (!glXGetProcAddressARB) |
1131 return 0; |
1131 return 0; |
1132 return glXGetProcAddressARB(reinterpret_cast<const GLubyte *>(proc.toLatin1().data())); |
1132 return glXGetProcAddressARB(reinterpret_cast<const GLubyte *>(proc.toLatin1().data())); |
1133 } |
1133 } |
1134 |
1134 |
|
1135 /* |
|
1136 QGLTemporaryContext implementation |
|
1137 */ |
|
1138 |
|
1139 class QGLTemporaryContextPrivate { |
|
1140 public: |
|
1141 bool initialized; |
|
1142 Window drawable; |
|
1143 GLXContext context; |
|
1144 GLXDrawable oldDrawable; |
|
1145 GLXContext oldContext; |
|
1146 }; |
|
1147 |
|
1148 QGLTemporaryContext::QGLTemporaryContext(bool, QWidget *) |
|
1149 : d(new QGLTemporaryContextPrivate) |
|
1150 { |
|
1151 d->initialized = false; |
|
1152 d->oldDrawable = 0; |
|
1153 d->oldContext = 0; |
|
1154 int screen = 0; |
|
1155 |
|
1156 int attribs[] = {GLX_RGBA, XNone}; |
|
1157 XVisualInfo *vi = glXChooseVisual(X11->display, screen, attribs); |
|
1158 if (!vi) { |
|
1159 qWarning("QGLTempContext: No GL capable X visuals available."); |
|
1160 return; |
|
1161 } |
|
1162 |
|
1163 int useGL; |
|
1164 glXGetConfig(X11->display, vi, GLX_USE_GL, &useGL); |
|
1165 if (!useGL) { |
|
1166 XFree(vi); |
|
1167 return; |
|
1168 } |
|
1169 |
|
1170 d->oldDrawable = glXGetCurrentDrawable(); |
|
1171 d->oldContext = glXGetCurrentContext(); |
|
1172 |
|
1173 XSetWindowAttributes a; |
|
1174 a.colormap = qt_gl_choose_cmap(X11->display, vi); |
|
1175 d->drawable = XCreateWindow(X11->display, RootWindow(X11->display, screen), |
|
1176 0, 0, 1, 1, 0, |
|
1177 vi->depth, InputOutput, vi->visual, |
|
1178 CWColormap, &a); |
|
1179 d->context = glXCreateContext(X11->display, vi, 0, True); |
|
1180 if (d->context && glXMakeCurrent(X11->display, d->drawable, d->context)) { |
|
1181 d->initialized = true; |
|
1182 } else { |
|
1183 qWarning("QGLTempContext: Unable to create GL context."); |
|
1184 XDestroyWindow(X11->display, d->drawable); |
|
1185 } |
|
1186 XFree(vi); |
|
1187 } |
|
1188 |
|
1189 QGLTemporaryContext::~QGLTemporaryContext() |
|
1190 { |
|
1191 if (d->initialized) { |
|
1192 glXMakeCurrent(X11->display, 0, 0); |
|
1193 glXDestroyContext(X11->display, d->context); |
|
1194 XDestroyWindow(X11->display, d->drawable); |
|
1195 } |
|
1196 if (d->oldDrawable && d->oldContext) |
|
1197 glXMakeCurrent(X11->display, d->oldDrawable, d->oldContext); |
|
1198 } |
|
1199 |
1135 /***************************************************************************** |
1200 /***************************************************************************** |
1136 QGLOverlayWidget (Internal overlay class for X11) |
1201 QGLOverlayWidget (Internal overlay class for X11) |
1137 *****************************************************************************/ |
1202 *****************************************************************************/ |
1138 |
1203 |
1139 class QGLOverlayWidget : public QGLWidget |
1204 class QGLOverlayWidget : public QGLWidget |
1564 } |
1629 } |
1565 XSetWMColormapWindows(X11->display, tlw->winId(), cmw, count); |
1630 XSetWMColormapWindows(X11->display, tlw->winId(), cmw, count); |
1566 delete [] cmw; |
1631 delete [] cmw; |
1567 } |
1632 } |
1568 |
1633 |
1569 void QGLExtensions::init() |
|
1570 { |
|
1571 static bool init_done = false; |
|
1572 |
|
1573 if (init_done) |
|
1574 return; |
|
1575 init_done = true; |
|
1576 |
|
1577 QGLWidget dmy; |
|
1578 dmy.makeCurrent(); |
|
1579 init_extensions(); |
|
1580 |
|
1581 // nvidia 9x.xx unix drivers contain a bug which requires us to call glFinish before releasing an fbo |
|
1582 // to avoid painting artifacts |
|
1583 const QByteArray versionString(reinterpret_cast<const char*>(glGetString(GL_VERSION))); |
|
1584 const int pos = versionString.indexOf("NVIDIA"); |
|
1585 if (pos >= 0) { |
|
1586 const float nvidiaDriverVersion = versionString.mid(pos + strlen("NVIDIA")).toFloat(); |
|
1587 nvidiaFboNeedsFinish = nvidiaDriverVersion >= 90.0 && nvidiaDriverVersion < 100.0; |
|
1588 } |
|
1589 } |
|
1590 |
|
1591 // Solaris defines glXBindTexImageEXT as part of the GL library |
1634 // Solaris defines glXBindTexImageEXT as part of the GL library |
1592 #if defined(GLX_VERSION_1_3) && !defined(Q_OS_HPUX) |
1635 #if defined(GLX_VERSION_1_3) && !defined(Q_OS_HPUX) |
1593 typedef void (*qt_glXBindTexImageEXT)(Display*, GLXDrawable, int, const int*); |
1636 typedef void (*qt_glXBindTexImageEXT)(Display*, GLXDrawable, int, const int*); |
1594 typedef void (*qt_glXReleaseTexImageEXT)(Display*, GLXDrawable, int); |
1637 typedef void (*qt_glXReleaseTexImageEXT)(Display*, GLXDrawable, int); |
1595 static qt_glXBindTexImageEXT glXBindTexImageEXT = 0; |
1638 static qt_glXBindTexImageEXT glXBindTexImageEXT = 0; |
1601 |
1644 |
1602 if (!resolvedTextureFromPixmap) { |
1645 if (!resolvedTextureFromPixmap) { |
1603 resolvedTextureFromPixmap = true; |
1646 resolvedTextureFromPixmap = true; |
1604 |
1647 |
1605 // Check to see if we have NPOT texture support |
1648 // Check to see if we have NPOT texture support |
1606 if ( !(QGLExtensions::glExtensions & QGLExtensions::NPOTTextures) && |
1649 if ( !(QGLExtensions::glExtensions() & QGLExtensions::NPOTTextures) && |
1607 !(QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_2_0)) |
1650 !(QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_2_0)) |
1608 { |
1651 { |
1609 return false; // Can't use TFP without NPOT |
1652 return false; // Can't use TFP without NPOT |
1610 } |
1653 } |
|
1654 |
1611 const QX11Info *xinfo = qt_x11Info(paintDevice); |
1655 const QX11Info *xinfo = qt_x11Info(paintDevice); |
1612 QGLExtensionMatcher extensions(glXQueryExtensionsString(xinfo->display(), xinfo->screen())); |
1656 Display *display = xinfo ? xinfo->display() : X11->display; |
|
1657 int screen = xinfo ? xinfo->screen() : X11->defaultScreen; |
|
1658 |
|
1659 QGLExtensionMatcher extensions(glXQueryExtensionsString(display, screen)); |
1613 if (extensions.match("GLX_EXT_texture_from_pixmap")) { |
1660 if (extensions.match("GLX_EXT_texture_from_pixmap")) { |
1614 glXBindTexImageEXT = (qt_glXBindTexImageEXT) qglx_getProcAddress("glXBindTexImageEXT"); |
1661 glXBindTexImageEXT = (qt_glXBindTexImageEXT) qglx_getProcAddress("glXBindTexImageEXT"); |
1615 glXReleaseTexImageEXT = (qt_glXReleaseTexImageEXT) qglx_getProcAddress("glXReleaseTexImageEXT"); |
1662 glXReleaseTexImageEXT = (qt_glXReleaseTexImageEXT) qglx_getProcAddress("glXReleaseTexImageEXT"); |
1616 } |
1663 } |
1617 } |
1664 } |