Changeset 561 for trunk/src/opengl/qgl_x11.cpp
- Timestamp:
- Feb 11, 2010, 11:19:06 PM (15 years ago)
- Location:
- trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk
-
Property svn:mergeinfo
set to (toggle deleted branches)
/branches/vendor/nokia/qt/4.6.1 merged eligible /branches/vendor/nokia/qt/current merged eligible /branches/vendor/trolltech/qt/current 3-149
-
Property svn:mergeinfo
set to (toggle deleted branches)
-
trunk/src/opengl/qgl_x11.cpp
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtOpenGL module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 53 53 #include <private/qfontengine_ft_p.h> 54 54 #include <private/qt_x11_p.h> 55 #include <private/qpixmap_x11_p.h> 56 #include <private/qimagepixmapcleanuphooks_p.h> 55 57 #ifdef Q_OS_HPUX 56 58 // for GLXPBuffer 57 59 #include <private/qglpixelbuffer_p.h> 58 60 #endif 61 62 // We always define GLX_EXT_texture_from_pixmap ourselves because 63 // we can't trust system headers to do it properly 64 #define GLX_EXT_texture_from_pixmap 1 59 65 60 66 #define INT8 dummy_INT8 … … 63 69 #undef INT8 64 70 #undef INT32 71 65 72 #include <X11/Xlib.h> 66 73 #include <X11/Xutil.h> 67 74 #include <X11/Xos.h> 75 #ifdef Q_OS_VXWORS 76 # ifdef open 77 # undef open 78 # endif 79 # ifdef getpid 80 # undef getpid 81 # endif 82 #endif // Q_OS_VXWORKS 68 83 #include <X11/Xatom.h> 69 84 … … 80 95 #define GLX_SAMPLE_BUFFERS_ARB 100000 81 96 #define GLX_SAMPLES_ARB 100001 97 #endif 98 99 #ifndef GLX_TEXTURE_2D_BIT_EXT 100 #define GLX_TEXTURE_2D_BIT_EXT 0x00000002 101 #define GLX_TEXTURE_RECTANGLE_BIT_EXT 0x00000004 102 #define GLX_BIND_TO_TEXTURE_RGB_EXT 0x20D0 103 #define GLX_BIND_TO_TEXTURE_RGBA_EXT 0x20D1 104 #define GLX_BIND_TO_MIPMAP_TEXTURE_EXT 0x20D2 105 #define GLX_BIND_TO_TEXTURE_TARGETS_EXT 0x20D3 106 #define GLX_Y_INVERTED_EXT 0x20D4 107 #define GLX_TEXTURE_FORMAT_EXT 0x20D5 108 #define GLX_TEXTURE_TARGET_EXT 0x20D6 109 #define GLX_MIPMAP_TEXTURE_EXT 0x20D7 110 #define GLX_TEXTURE_FORMAT_NONE_EXT 0x20D8 111 #define GLX_TEXTURE_FORMAT_RGB_EXT 0x20D9 112 #define GLX_TEXTURE_FORMAT_RGBA_EXT 0x20DA 113 #define GLX_TEXTURE_2D_EXT 0x20DC 114 #define GLX_TEXTURE_RECTANGLE_EXT 0x20DD 115 #define GLX_FRONT_LEFT_EXT 0x20DE 82 116 #endif 83 117 … … 130 164 GLCMapHash *qglcmap_hash; 131 165 }; 132 Q_GLOBAL_STATIC(QGLCMapCleanupHandler, cmap_handler) ;166 Q_GLOBAL_STATIC(QGLCMapCleanupHandler, cmap_handler) 133 167 134 168 static void cleanup_cmaps() … … 298 332 QGLFormat UNIX/GLX-specific code 299 333 *****************************************************************************/ 334 335 void* qglx_getProcAddress(const char* procName) 336 { 337 // On systems where the GL driver is pluggable (like Mesa), we have to use 338 // the glXGetProcAddressARB extension to resolve other function pointers as 339 // the symbols wont be in the GL library, but rather in a plugin loaded by 340 // the GL library. 341 typedef void* (*qt_glXGetProcAddressARB)(const char *); 342 static qt_glXGetProcAddressARB glXGetProcAddressARB = 0; 343 static bool triedResolvingGlxGetProcAddress = false; 344 if (!triedResolvingGlxGetProcAddress) { 345 triedResolvingGlxGetProcAddress = true; 346 QGLExtensionMatcher extensions(glXGetClientString(QX11Info::display(), GLX_EXTENSIONS)); 347 if (extensions.match("GLX_ARB_get_proc_address")) { 348 #if defined(Q_OS_LINUX) || defined(Q_OS_BSD4) 349 void *handle = dlopen(NULL, RTLD_LAZY); 350 if (handle) { 351 glXGetProcAddressARB = (qt_glXGetProcAddressARB) dlsym(handle, "glXGetProcAddressARB"); 352 dlclose(handle); 353 } 354 if (!glXGetProcAddressARB) 355 #endif 356 { 357 #if !defined(QT_NO_LIBRARY) 358 extern const QString qt_gl_library_name(); 359 QLibrary lib(qt_gl_library_name()); 360 glXGetProcAddressARB = (qt_glXGetProcAddressARB) lib.resolve("glXGetProcAddressARB"); 361 #endif 362 } 363 } 364 } 365 366 void *procAddress = 0; 367 if (glXGetProcAddressARB) 368 procAddress = glXGetProcAddressARB(procName); 369 370 // If glXGetProcAddress didn't work, try looking the symbol up in the GL library 371 #if defined(Q_OS_LINUX) || defined(Q_OS_BSD4) 372 if (!procAddress) { 373 void *handle = dlopen(NULL, RTLD_LAZY); 374 if (handle) { 375 procAddress = dlsym(handle, procName); 376 dlclose(handle); 377 } 378 } 379 #endif 380 #if !defined(QT_NO_LIBRARY) 381 if (!procAddress) { 382 extern const QString qt_gl_library_name(); 383 QLibrary lib(qt_gl_library_name()); 384 procAddress = lib.resolve(procName); 385 } 386 #endif 387 388 return procAddress; 389 } 300 390 301 391 bool QGLFormat::hasOpenGL() … … 434 524 return false; 435 525 } 436 Q String glxExt = QString(QLatin1String(glXGetClientString(QX11Info::display(), GLX_EXTENSIONS)));437 if ( glxExt.contains(QLatin1String("GLX_SGI_video_sync"))) {526 QGLExtensionMatcher extensions(glXQueryExtensionsString(xinfo->display(), xinfo->screen())); 527 if (extensions.match("GLX_SGI_video_sync")) { 438 528 if (d->glFormat.swapInterval() == -1) 439 529 d->glFormat.setSwapInterval(0); … … 444 534 } 445 535 446 447 /*! 448 \bold{X11 only:} This virtual function tries to find a 449 visual that matches the format, reducing the demands if the original 450 request cannot be met. 451 452 The algorithm for reducing the demands of the format is quite 453 simple-minded, so override this method in your subclass if your 454 application has spcific requirements on visual selection. 455 456 \sa chooseContext() 457 */ 458 536 /* 537 See qgl.cpp for qdoc comment. 538 */ 459 539 void *QGLContext::chooseVisual() 460 540 { … … 520 600 } 521 601 522 523 /*! 524 \internal 525 526 \bold{X11 only:} This virtual function chooses a visual 527 that matches the OpenGL \link format() format\endlink. Reimplement this 528 function in a subclass if you need a custom visual. 529 530 \sa chooseContext() 531 */ 532 602 /* 603 See qgl.cpp for qdoc comment. 604 */ 533 605 void *QGLContext::tryVisual(const QGLFormat& f, int bufDepth) 534 606 { 535 607 Q_D(QGLContext); 536 int spec[4 0];608 int spec[45]; 537 609 int i = 0; 538 610 spec[i++] = GLX_LEVEL; 539 611 spec[i++] = f.plane(); 540 612 const QX11Info *xinfo = qt_x11Info(d->paintDevice); 613 bool useFBConfig = false; 614 615 #if defined(GLX_VERSION_1_3) && !defined(QT_NO_XRENDER) && !defined(Q_OS_HPUX) 616 /* 617 HPUX defines GLX_VERSION_1_3 but does not implement the corresponding functions. 618 Specifically glXChooseFBConfig and glXGetVisualFromFBConfig are not implemented. 619 */ 620 QWidget* widget = 0; 621 if (d->paintDevice->devType() == QInternal::Widget) 622 widget = static_cast<QWidget*>(d->paintDevice); 623 624 // Only use glXChooseFBConfig for widgets if we're trying to get an ARGB visual 625 if (widget && widget->testAttribute(Qt::WA_TranslucentBackground) && X11->use_xrender) 626 useFBConfig = true; 627 #endif 541 628 542 629 #if defined(GLX_VERSION_1_1) && defined(GLX_EXT_visual_info) … … 544 631 static bool useTranspExtChecked = false; 545 632 if (f.plane() && !useTranspExtChecked && d->paintDevice) { 546 Q ByteArray estr(glXQueryExtensionsString(xinfo->display(), xinfo->screen()));547 useTranspExt = e str.contains("GLX_EXT_visual_info");633 QGLExtensionMatcher extensions(glXQueryExtensionsString(xinfo->display(), xinfo->screen())); 634 useTranspExt = extensions.match("GLX_EXT_visual_info"); 548 635 //# (A bit simplistic; that could theoretically be a substring) 549 636 if (useTranspExt) { … … 566 653 useTranspExtChecked = true; 567 654 } 568 if (f.plane() && useTranspExt ) {655 if (f.plane() && useTranspExt && !useFBConfig) { 569 656 // Required to avoid non-transparent overlay visual(!) on some systems 570 657 spec[i++] = GLX_TRANSPARENT_TYPE_EXT; … … 573 660 #endif 574 661 662 #if defined(GLX_VERSION_1_3) && !defined(Q_OS_HPUX) 663 // GLX_RENDER_TYPE is only in glx >=1.3 664 if (useFBConfig) { 665 spec[i++] = GLX_RENDER_TYPE; 666 spec[i++] = f.rgba() ? GLX_RGBA_BIT : GLX_COLOR_INDEX_BIT; 667 } 668 #endif 669 575 670 if (f.doubleBuffer()) 576 671 spec[i++] = GLX_DOUBLEBUFFER; 672 if (useFBConfig) 673 spec[i++] = True; 577 674 if (f.depth()) { 578 675 spec[i++] = GLX_DEPTH_SIZE; … … 581 678 if (f.stereo()) { 582 679 spec[i++] = GLX_STEREO; 680 if (useFBConfig) 681 spec[i++] = True; 583 682 } 584 683 if (f.stencil()) { … … 587 686 } 588 687 if (f.rgba()) { 589 spec[i++] = GLX_RGBA; 688 if (!useFBConfig) 689 spec[i++] = GLX_RGBA; 590 690 spec[i++] = GLX_RED_SIZE; 591 691 spec[i++] = f.redBufferSize() == -1 ? 1 : f.redBufferSize(); … … 622 722 } 623 723 724 #if defined(GLX_VERSION_1_3) && !defined(Q_OS_HPUX) 725 if (useFBConfig) { 726 spec[i++] = GLX_DRAWABLE_TYPE; 727 switch(d->paintDevice->devType()) { 728 case QInternal::Pixmap: 729 spec[i++] = GLX_PIXMAP_BIT; 730 break; 731 case QInternal::Pbuffer: 732 spec[i++] = GLX_PBUFFER_BIT; 733 break; 734 default: 735 qWarning("QGLContext: Unknown paint device type %d", d->paintDevice->devType()); 736 // Fall-through & assume it's a window 737 case QInternal::Widget: 738 spec[i++] = GLX_WINDOW_BIT; 739 break; 740 }; 741 } 742 #endif 743 624 744 spec[i] = XNone; 625 return glXChooseVisual(xinfo->display(), xinfo->screen(), spec); 745 746 747 XVisualInfo* chosenVisualInfo = 0; 748 749 #if defined(GLX_VERSION_1_3) && !defined(Q_OS_HPUX) 750 while (useFBConfig) { 751 GLXFBConfig *configs; 752 int configCount = 0; 753 configs = glXChooseFBConfig(xinfo->display(), xinfo->screen(), spec, &configCount); 754 755 if (!configs) 756 break; // fallback to trying glXChooseVisual 757 758 for (i = 0; i < configCount; ++i) { 759 XVisualInfo* vi; 760 vi = glXGetVisualFromFBConfig(xinfo->display(), configs[i]); 761 if (!vi) 762 continue; 763 764 #if !defined(QT_NO_XRENDER) 765 QWidget* w = 0; 766 if (d->paintDevice->devType() == QInternal::Widget) 767 w = static_cast<QWidget*>(d->paintDevice); 768 769 if (w && w->testAttribute(Qt::WA_TranslucentBackground) && f.alpha()) { 770 // Attempt to find a config who's visual has a proper alpha channel 771 XRenderPictFormat *pictFormat; 772 pictFormat = XRenderFindVisualFormat(xinfo->display(), vi->visual); 773 774 if (pictFormat && (pictFormat->type == PictTypeDirect) && pictFormat->direct.alphaMask) { 775 // The pict format for the visual matching the FBConfig indicates ARGB 776 if (chosenVisualInfo) 777 XFree(chosenVisualInfo); 778 chosenVisualInfo = vi; 779 break; 780 } 781 } else 782 #endif //QT_NO_XRENDER 783 if (chosenVisualInfo) { 784 // If we've got a visual we can use and we're not trying to find one with a 785 // real alpha channel, we might as well just use the one we've got 786 break; 787 } 788 789 if (!chosenVisualInfo) 790 chosenVisualInfo = vi; // Have something to fall back to 791 else 792 XFree(vi); 793 } 794 795 XFree(configs); 796 break; 797 } 798 #endif // defined(GLX_VERSION_1_3) 799 800 if (!chosenVisualInfo) 801 chosenVisualInfo = glXChooseVisual(xinfo->display(), xinfo->screen(), spec); 802 803 return chosenVisualInfo; 626 804 } 627 805 … … 671 849 qWarning("QGLContext::makeCurrent(): Failed."); 672 850 673 if (ok) { 674 if (!qgl_context_storage.hasLocalData() && QThread::currentThread()) 675 qgl_context_storage.setLocalData(new QGLThreadContext); 676 if (qgl_context_storage.hasLocalData()) 677 qgl_context_storage.localData()->context = this; 678 currentCtx = this; 679 } 851 if (ok) 852 QGLContextPrivate::setCurrentContext(this); 680 853 } 681 854 … … 684 857 Q_D(QGLContext); 685 858 glXMakeCurrent(qt_x11Info(d->paintDevice)->display(), 0, 0); 686 if (qgl_context_storage.hasLocalData()) 687 qgl_context_storage.localData()->context = 0; 688 currentCtx = 0; 859 QGLContextPrivate::setCurrentContext(0); 689 860 } 690 861 … … 704 875 static bool resolved = false; 705 876 if (!resolved) { 706 QString glxExt = QString(QLatin1String(glXGetClientString(QX11Info::display(), GLX_EXTENSIONS))); 707 if (glxExt.contains(QLatin1String("GLX_SGI_video_sync"))) { 708 #if defined(Q_OS_LINUX) || defined(Q_OS_BSD4) 709 void *handle = dlopen(NULL, RTLD_LAZY); 710 if (handle) { 711 glXGetVideoSyncSGI = (qt_glXGetVideoSyncSGI) dlsym(handle, "glXGetVideoSyncSGI"); 712 glXWaitVideoSyncSGI = (qt_glXWaitVideoSyncSGI) dlsym(handle, "glXWaitVideoSyncSGI"); 713 dlclose(handle); 714 } 715 if (!glXGetVideoSyncSGI) 716 #endif 717 { 718 extern const QString qt_gl_library_name(); 719 QLibrary lib(qt_gl_library_name()); 720 glXGetVideoSyncSGI = (qt_glXGetVideoSyncSGI) lib.resolve("glXGetVideoSyncSGI"); 721 glXWaitVideoSyncSGI = (qt_glXWaitVideoSyncSGI) lib.resolve("glXWaitVideoSyncSGI"); 722 } 877 const QX11Info *xinfo = qt_x11Info(d->paintDevice); 878 QGLExtensionMatcher extensions(glXQueryExtensionsString(xinfo->display(), xinfo->screen())); 879 if (extensions.match("GLX_SGI_video_sync")) { 880 glXGetVideoSyncSGI = (qt_glXGetVideoSyncSGI)qglx_getProcAddress("glXGetVideoSyncSGI"); 881 glXWaitVideoSyncSGI = (qt_glXWaitVideoSyncSGI)qglx_getProcAddress("glXWaitVideoSyncSGI"); 723 882 } 724 883 resolved = true; … … 949 1108 return 0; 950 1109 if (!glXGetProcAddressARB) { 951 Q String glxExt = QString(QLatin1String(glXGetClientString(QX11Info::display(), GLX_EXTENSIONS)));952 if ( glxExt.contains(QLatin1String("GLX_ARB_get_proc_address"))) {1110 QGLExtensionMatcher extensions(glXGetClientString(QX11Info::display(), GLX_EXTENSIONS)); 1111 if (extensions.match("GLX_ARB_get_proc_address")) { 953 1112 #if defined(Q_OS_LINUX) || defined(Q_OS_BSD4) 954 1113 void *handle = dlopen(NULL, RTLD_LAZY); … … 960 1119 #endif 961 1120 { 1121 #if !defined(QT_NO_LIBRARY) 962 1122 extern const QString qt_gl_library_name(); 963 1123 QLibrary lib(qt_gl_library_name()); 964 1124 glXGetProcAddressARB = (qt_glXGetProcAddressARB) lib.resolve("glXGetProcAddressARB"); 1125 #endif 965 1126 } 966 1127 } … … 1184 1345 d->glcx = context; 1185 1346 1186 1187 1347 if (parentWidget()) { 1188 1348 // force creation of delay-created widgets … … 1191 1351 d_func()->xinfo = parentWidget()->d_func()->xinfo; 1192 1352 } 1353 1354 // If the application has set WA_TranslucentBackground and not explicitly set 1355 // the alpha buffer size to zero, modify the format so it have an alpha channel 1356 QGLFormat& fmt = d->glcx->d_func()->glFormat; 1357 if (testAttribute(Qt::WA_TranslucentBackground) && fmt.alphaBufferSize() == -1) 1358 fmt.setAlphaBufferSize(1); 1193 1359 1194 1360 bool createFailed = false; … … 1423 1589 } 1424 1590 1591 // Solaris defines glXBindTexImageEXT as part of the GL library 1592 #if defined(GLX_VERSION_1_3) && !defined(Q_OS_HPUX) 1593 typedef void (*qt_glXBindTexImageEXT)(Display*, GLXDrawable, int, const int*); 1594 typedef void (*qt_glXReleaseTexImageEXT)(Display*, GLXDrawable, int); 1595 static qt_glXBindTexImageEXT glXBindTexImageEXT = 0; 1596 static qt_glXReleaseTexImageEXT glXReleaseTexImageEXT = 0; 1597 1598 static bool qt_resolveTextureFromPixmap(QPaintDevice *paintDevice) 1599 { 1600 static bool resolvedTextureFromPixmap = false; 1601 1602 if (!resolvedTextureFromPixmap) { 1603 resolvedTextureFromPixmap = true; 1604 1605 // Check to see if we have NPOT texture support 1606 if ( !(QGLExtensions::glExtensions & QGLExtensions::NPOTTextures) && 1607 !(QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_2_0)) 1608 { 1609 return false; // Can't use TFP without NPOT 1610 } 1611 const QX11Info *xinfo = qt_x11Info(paintDevice); 1612 QGLExtensionMatcher extensions(glXQueryExtensionsString(xinfo->display(), xinfo->screen())); 1613 if (extensions.match("GLX_EXT_texture_from_pixmap")) { 1614 glXBindTexImageEXT = (qt_glXBindTexImageEXT) qglx_getProcAddress("glXBindTexImageEXT"); 1615 glXReleaseTexImageEXT = (qt_glXReleaseTexImageEXT) qglx_getProcAddress("glXReleaseTexImageEXT"); 1616 } 1617 } 1618 1619 return glXBindTexImageEXT && glXReleaseTexImageEXT; 1620 } 1621 #endif //defined(GLX_VERSION_1_3) && !defined(Q_OS_HPUX) 1622 1623 1624 QGLTexture *QGLContextPrivate::bindTextureFromNativePixmap(QPixmapData *pmd, const qint64 key, 1625 QGLContext::BindOptions options) 1626 { 1627 #if !defined(GLX_VERSION_1_3) || defined(Q_OS_HPUX) 1628 return 0; 1629 #else 1630 Q_Q(QGLContext); 1631 1632 Q_ASSERT(pmd->classId() == QPixmapData::X11Class); 1633 1634 if (!qt_resolveTextureFromPixmap(paintDevice)) 1635 return 0; 1636 1637 QX11PixmapData *pixmapData = static_cast<QX11PixmapData*>(pmd); 1638 const QX11Info &x11Info = pixmapData->xinfo; 1639 1640 // Store the configs (Can be static because configs aren't dependent on current context) 1641 static GLXFBConfig glxRGBPixmapConfig = 0; 1642 static bool RGBConfigInverted = false; 1643 static GLXFBConfig glxRGBAPixmapConfig = 0; 1644 static bool RGBAConfigInverted = false; 1645 1646 bool hasAlpha = pixmapData->hasAlphaChannel(); 1647 1648 // Check to see if we need a config 1649 if ( (hasAlpha && !glxRGBAPixmapConfig) || (!hasAlpha && !glxRGBPixmapConfig) ) { 1650 GLXFBConfig *configList = 0; 1651 int configCount = 0; 1652 1653 int configAttribs[] = { 1654 hasAlpha ? GLX_BIND_TO_TEXTURE_RGBA_EXT : GLX_BIND_TO_TEXTURE_RGB_EXT, True, 1655 GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT, 1656 GLX_BIND_TO_TEXTURE_TARGETS_EXT, GLX_TEXTURE_2D_BIT_EXT, 1657 // QGLContext::bindTexture() can't return an inverted texture, but QPainter::drawPixmap() can: 1658 GLX_Y_INVERTED_EXT, options & QGLContext::CanFlipNativePixmapBindOption ? GLX_DONT_CARE : False, 1659 XNone 1660 }; 1661 configList = glXChooseFBConfig(x11Info.display(), x11Info.screen(), configAttribs, &configCount); 1662 if (!configList) 1663 return 0; 1664 1665 int yInv; 1666 glXGetFBConfigAttrib(x11Info.display(), configList[0], GLX_Y_INVERTED_EXT, &yInv); 1667 1668 if (hasAlpha) { 1669 glxRGBAPixmapConfig = configList[0]; 1670 RGBAConfigInverted = yInv; 1671 } 1672 else { 1673 glxRGBPixmapConfig = configList[0]; 1674 RGBConfigInverted = yInv; 1675 } 1676 1677 XFree(configList); 1678 } 1679 1680 // Check to see if the surface is still valid 1681 if (pixmapData->gl_surface && 1682 hasAlpha != (pixmapData->flags & QX11PixmapData::GlSurfaceCreatedWithAlpha)) 1683 { 1684 // Surface is invalid! 1685 destroyGlSurfaceForPixmap(pixmapData); 1686 } 1687 1688 // Check to see if we need a surface 1689 if (!pixmapData->gl_surface) { 1690 GLXPixmap glxPixmap; 1691 int pixmapAttribs[] = { 1692 GLX_TEXTURE_FORMAT_EXT, hasAlpha ? GLX_TEXTURE_FORMAT_RGBA_EXT : GLX_TEXTURE_FORMAT_RGB_EXT, 1693 GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT, 1694 GLX_MIPMAP_TEXTURE_EXT, False, // Maybe needs to be don't care 1695 XNone 1696 }; 1697 1698 // Wrap the X Pixmap into a GLXPixmap: 1699 glxPixmap = glXCreatePixmap(x11Info.display(), 1700 hasAlpha ? glxRGBAPixmapConfig : glxRGBPixmapConfig, 1701 pixmapData->handle(), pixmapAttribs); 1702 1703 if (!glxPixmap) 1704 return 0; 1705 1706 pixmapData->gl_surface = (Qt::HANDLE)glxPixmap; 1707 1708 // Make sure the cleanup hook gets called so we can delete the glx pixmap 1709 QImagePixmapCleanupHooks::enableCleanupHooks(pixmapData); 1710 } 1711 1712 GLuint textureId; 1713 glGenTextures(1, &textureId); 1714 glBindTexture(GL_TEXTURE_2D, textureId); 1715 glXBindTexImageEXT(x11Info.display(), (GLXPixmap)pixmapData->gl_surface, GLX_FRONT_LEFT_EXT, 0); 1716 1717 glBindTexture(GL_TEXTURE_2D, textureId); 1718 1719 if (!((hasAlpha && RGBAConfigInverted) || (!hasAlpha && RGBConfigInverted))) 1720 options &= ~QGLContext::InvertedYBindOption; 1721 1722 QGLTexture *texture = new QGLTexture(q, textureId, GL_TEXTURE_2D, options); 1723 if (texture->options & QGLContext::InvertedYBindOption) 1724 pixmapData->flags |= QX11PixmapData::InvertedWhenBoundToTexture; 1725 1726 // We assume the cost of bound pixmaps is zero 1727 QGLTextureCache::instance()->insert(q, key, texture, 0); 1728 1729 return texture; 1730 #endif //!defined(GLX_VERSION_1_3) || defined(Q_OS_HPUX) 1731 } 1732 1733 1734 void QGLContextPrivate::destroyGlSurfaceForPixmap(QPixmapData* pmd) 1735 { 1736 #if defined(GLX_VERSION_1_3) && !defined(Q_OS_HPUX) 1737 Q_ASSERT(pmd->classId() == QPixmapData::X11Class); 1738 QX11PixmapData *pixmapData = static_cast<QX11PixmapData*>(pmd); 1739 if (pixmapData->gl_surface) { 1740 glXDestroyPixmap(QX11Info::display(), (GLXPixmap)pixmapData->gl_surface); 1741 pixmapData->gl_surface = 0; 1742 } 1743 #endif 1744 } 1745 1746 void QGLContextPrivate::unbindPixmapFromTexture(QPixmapData* pmd) 1747 { 1748 #if defined(GLX_VERSION_1_3) && !defined(Q_OS_HPUX) 1749 Q_ASSERT(pmd->classId() == QPixmapData::X11Class); 1750 Q_ASSERT(QGLContext::currentContext()); 1751 QX11PixmapData *pixmapData = static_cast<QX11PixmapData*>(pmd); 1752 if (pixmapData->gl_surface) 1753 glXReleaseTexImageEXT(QX11Info::display(), (GLXPixmap)pixmapData->gl_surface, GLX_FRONT_LEFT_EXT); 1754 #endif 1755 } 1756 1425 1757 QT_END_NAMESPACE
Note:
See TracChangeset
for help on using the changeset viewer.