Changeset 846 for trunk/src/opengl/qgl_x11.cpp
- Timestamp:
- May 5, 2011, 5:36:53 AM (14 years ago)
- Location:
- trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk
- Property svn:mergeinfo changed
/branches/vendor/nokia/qt/4.7.2 (added) merged: 845 /branches/vendor/nokia/qt/current merged: 844 /branches/vendor/nokia/qt/4.6.3 removed
- Property svn:mergeinfo changed
-
trunk/src/opengl/qgl_x11.cpp
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 55 55 #include <private/qpixmap_x11_p.h> 56 56 #include <private/qimagepixmapcleanuphooks_p.h> 57 #include <private/qunicodetables_p.h> 57 58 #ifdef Q_OS_HPUX 58 59 // for GLXPBuffer … … 114 115 #define GLX_TEXTURE_RECTANGLE_EXT 0x20DD 115 116 #define GLX_FRONT_LEFT_EXT 0x20DE 117 #endif 118 119 #ifndef GLX_ARB_create_context 120 #define GLX_CONTEXT_DEBUG_BIT_ARB 0x00000001 121 #define GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002 122 #define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091 123 #define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092 124 #define GLX_CONTEXT_FLAGS_ARB 0x2094 125 #endif 126 127 #ifndef GLX_ARB_create_context_profile 128 #define GLX_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001 129 #define GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002 130 #define GLX_CONTEXT_PROFILE_MASK_ARB 0x9126 116 131 #endif 117 132 … … 400 415 find_trans_colors(); 401 416 return trans_colors.size() > 0; 417 } 418 419 static bool buildSpec(int* spec, const QGLFormat& f, QPaintDevice* paintDevice, 420 int bufDepth, bool onlyFBConfig = false) 421 { 422 int i = 0; 423 spec[i++] = GLX_LEVEL; 424 spec[i++] = f.plane(); 425 const QX11Info *xinfo = qt_x11Info(paintDevice); 426 bool useFBConfig = onlyFBConfig; 427 428 #if defined(GLX_VERSION_1_3) && !defined(QT_NO_XRENDER) && !defined(Q_OS_HPUX) 429 /* 430 HPUX defines GLX_VERSION_1_3 but does not implement the corresponding functions. 431 Specifically glXChooseFBConfig and glXGetVisualFromFBConfig are not implemented. 432 */ 433 QWidget* widget = 0; 434 if (paintDevice->devType() == QInternal::Widget) 435 widget = static_cast<QWidget*>(paintDevice); 436 437 // Only use glXChooseFBConfig for widgets if we're trying to get an ARGB visual 438 if (widget && widget->testAttribute(Qt::WA_TranslucentBackground) && X11->use_xrender) 439 useFBConfig = true; 440 #endif 441 442 #if defined(GLX_VERSION_1_1) && defined(GLX_EXT_visual_info) 443 static bool useTranspExt = false; 444 static bool useTranspExtChecked = false; 445 if (f.plane() && !useTranspExtChecked && paintDevice) { 446 QGLExtensionMatcher extensions(glXQueryExtensionsString(xinfo->display(), xinfo->screen())); 447 useTranspExt = extensions.match("GLX_EXT_visual_info"); 448 //# (A bit simplistic; that could theoretically be a substring) 449 if (useTranspExt) { 450 QByteArray cstr(glXGetClientString(xinfo->display(), GLX_VENDOR)); 451 useTranspExt = !cstr.contains("Xi Graphics"); // bug workaround 452 if (useTranspExt) { 453 // bug workaround - some systems (eg. FireGL) refuses to return an overlay 454 // visual if the GLX_TRANSPARENT_TYPE_EXT attribute is specified, even if 455 // the implementation supports transparent overlays 456 int tmpSpec[] = { GLX_LEVEL, f.plane(), GLX_TRANSPARENT_TYPE_EXT, 457 f.rgba() ? GLX_TRANSPARENT_RGB_EXT : GLX_TRANSPARENT_INDEX_EXT, 458 XNone }; 459 XVisualInfo * vinf = glXChooseVisual(xinfo->display(), xinfo->screen(), tmpSpec); 460 if (!vinf) { 461 useTranspExt = false; 462 } 463 } 464 } 465 466 useTranspExtChecked = true; 467 } 468 if (f.plane() && useTranspExt && !useFBConfig) { 469 // Required to avoid non-transparent overlay visual(!) on some systems 470 spec[i++] = GLX_TRANSPARENT_TYPE_EXT; 471 spec[i++] = f.rgba() ? GLX_TRANSPARENT_RGB_EXT : GLX_TRANSPARENT_INDEX_EXT; 472 } 473 #endif 474 475 #if defined(GLX_VERSION_1_3) && !defined(Q_OS_HPUX) 476 // GLX_RENDER_TYPE is only in glx >=1.3 477 if (useFBConfig) { 478 spec[i++] = GLX_RENDER_TYPE; 479 spec[i++] = f.rgba() ? GLX_RGBA_BIT : GLX_COLOR_INDEX_BIT; 480 } 481 #endif 482 483 if (f.doubleBuffer()) 484 spec[i++] = GLX_DOUBLEBUFFER; 485 if (useFBConfig) 486 spec[i++] = True; 487 if (f.depth()) { 488 spec[i++] = GLX_DEPTH_SIZE; 489 spec[i++] = f.depthBufferSize() == -1 ? 1 : f.depthBufferSize(); 490 } 491 if (f.stereo()) { 492 spec[i++] = GLX_STEREO; 493 if (useFBConfig) 494 spec[i++] = True; 495 } 496 if (f.stencil()) { 497 spec[i++] = GLX_STENCIL_SIZE; 498 spec[i++] = f.stencilBufferSize() == -1 ? 1 : f.stencilBufferSize(); 499 } 500 if (f.rgba()) { 501 if (!useFBConfig) 502 spec[i++] = GLX_RGBA; 503 spec[i++] = GLX_RED_SIZE; 504 spec[i++] = f.redBufferSize() == -1 ? 1 : f.redBufferSize(); 505 spec[i++] = GLX_GREEN_SIZE; 506 spec[i++] = f.greenBufferSize() == -1 ? 1 : f.greenBufferSize(); 507 spec[i++] = GLX_BLUE_SIZE; 508 spec[i++] = f.blueBufferSize() == -1 ? 1 : f.blueBufferSize(); 509 if (f.alpha()) { 510 spec[i++] = GLX_ALPHA_SIZE; 511 spec[i++] = f.alphaBufferSize() == -1 ? 1 : f.alphaBufferSize(); 512 } 513 if (f.accum()) { 514 spec[i++] = GLX_ACCUM_RED_SIZE; 515 spec[i++] = f.accumBufferSize() == -1 ? 1 : f.accumBufferSize(); 516 spec[i++] = GLX_ACCUM_GREEN_SIZE; 517 spec[i++] = f.accumBufferSize() == -1 ? 1 : f.accumBufferSize(); 518 spec[i++] = GLX_ACCUM_BLUE_SIZE; 519 spec[i++] = f.accumBufferSize() == -1 ? 1 : f.accumBufferSize(); 520 if (f.alpha()) { 521 spec[i++] = GLX_ACCUM_ALPHA_SIZE; 522 spec[i++] = f.accumBufferSize() == -1 ? 1 : f.accumBufferSize(); 523 } 524 } 525 } else { 526 spec[i++] = GLX_BUFFER_SIZE; 527 spec[i++] = bufDepth; 528 } 529 530 if (f.sampleBuffers()) { 531 spec[i++] = GLX_SAMPLE_BUFFERS_ARB; 532 spec[i++] = 1; 533 spec[i++] = GLX_SAMPLES_ARB; 534 spec[i++] = f.samples() == -1 ? 4 : f.samples(); 535 } 536 537 #if defined(GLX_VERSION_1_3) && !defined(Q_OS_HPUX) 538 if (useFBConfig) { 539 spec[i++] = GLX_DRAWABLE_TYPE; 540 switch(paintDevice->devType()) { 541 case QInternal::Pixmap: 542 spec[i++] = GLX_PIXMAP_BIT; 543 break; 544 case QInternal::Pbuffer: 545 spec[i++] = GLX_PBUFFER_BIT; 546 break; 547 default: 548 qWarning("QGLContext: Unknown paint device type %d", paintDevice->devType()); 549 // Fall-through & assume it's a window 550 case QInternal::Widget: 551 spec[i++] = GLX_WINDOW_BIT; 552 break; 553 }; 554 } 555 #endif 556 557 spec[i] = XNone; 558 return useFBConfig; 402 559 } 403 560 … … 494 651 } 495 652 653 const int major = d->reqFormat.majorVersion(); 654 const int minor = d->reqFormat.minorVersion(); 655 const int profile = d->reqFormat.profile() == QGLFormat::CompatibilityProfile 656 ? GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 657 : GLX_CONTEXT_CORE_PROFILE_BIT_ARB; 658 496 659 d->cx = 0; 497 if (shareContext) { 660 661 #if defined(GLX_VERSION_1_3) && !defined(Q_OS_HPUX) 662 /* 663 HPUX defines GLX_VERSION_1_3 but does not implement the corresponding functions. 664 Specifically glXChooseFBConfig and glXGetVisualFromFBConfig are not implemented. 665 */ 666 if ((major == 3 && minor >= 2) || major > 3) { 667 QGLTemporaryContext *tmpContext = 0; 668 if (!QGLContext::currentContext()) 669 tmpContext = new QGLTemporaryContext; 670 671 int attributes[] = { GLX_CONTEXT_MAJOR_VERSION_ARB, major, 672 GLX_CONTEXT_MINOR_VERSION_ARB, minor, 673 GLX_CONTEXT_PROFILE_MASK_ARB, profile, 674 0 }; 675 676 typedef GLXContext ( * Q_PFNGLXCREATECONTEXTATTRIBSARBPROC) 677 (Display* dpy, GLXFBConfig config, GLXContext share_context, Bool direct, const int *attrib_list); 678 679 680 Q_PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribs = 681 (Q_PFNGLXCREATECONTEXTATTRIBSARBPROC) qglx_getProcAddress("glXCreateContextAttribsARB"); 682 683 if (glXCreateContextAttribs) { 684 int spec[45]; 685 glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_BUFFER_SIZE, &res); 686 buildSpec(spec, format(), d->paintDevice, res, true); 687 688 GLXFBConfig *configs; 689 int configCount = 0; 690 configs = glXChooseFBConfig(disp, xinfo->screen(), spec, &configCount); 691 692 if (configs && configCount > 0) { 693 d->cx = glXCreateContextAttribs(disp, configs[0], 694 shareContext ? (GLXContext)shareContext->d_func()->cx : 0, direct, attributes); 695 if (!d->cx && shareContext) { 696 shareContext = 0; 697 d->cx = glXCreateContextAttribs(disp, configs[0], 0, direct, attributes); 698 } 699 d->screen = ((XVisualInfo*)d->vi)->screen; 700 } 701 XFree(configs); 702 } else { 703 qWarning("QGLContext::chooseContext(): OpenGL %d.%d is not supported", major, minor); 704 } 705 706 if (tmpContext) 707 delete tmpContext; 708 } 709 #else 710 Q_UNUSED(major); 711 Q_UNUSED(minor); 712 Q_UNUSED(profile); 713 #endif 714 715 if (!d->cx && shareContext) { 498 716 d->cx = glXCreateContext(disp, (XVisualInfo *)d->vi, 499 717 (GLXContext)shareContext->d_func()->cx, direct); 500 718 d->screen = ((XVisualInfo*)d->vi)->screen; 501 if (d->cx) {502 QGLContext *share = const_cast<QGLContext *>(shareContext);503 d->sharing = true;504 share->d_func()->sharing = true;505 }506 719 } 507 720 if (!d->cx) { 508 721 d->cx = glXCreateContext(disp, (XVisualInfo *)d->vi, NULL, direct); 509 722 d->screen = ((XVisualInfo*)d->vi)->screen; 510 } 723 shareContext = 0; 724 } 725 726 if (shareContext && d->cx) { 727 QGLContext *share = const_cast<QGLContext *>(shareContext); 728 d->sharing = true; 729 share->d_func()->sharing = true; 730 } 731 511 732 if (!d->cx) 512 733 return false; … … 607 828 Q_D(QGLContext); 608 829 int spec[45]; 609 int i = 0;610 spec[i++] = GLX_LEVEL;611 spec[i++] = f.plane();612 830 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 628 629 #if defined(GLX_VERSION_1_1) && defined(GLX_EXT_visual_info) 630 static bool useTranspExt = false; 631 static bool useTranspExtChecked = false; 632 if (f.plane() && !useTranspExtChecked && d->paintDevice) { 633 QGLExtensionMatcher extensions(glXQueryExtensionsString(xinfo->display(), xinfo->screen())); 634 useTranspExt = extensions.match("GLX_EXT_visual_info"); 635 //# (A bit simplistic; that could theoretically be a substring) 636 if (useTranspExt) { 637 QByteArray cstr(glXGetClientString(xinfo->display(), GLX_VENDOR)); 638 useTranspExt = !cstr.contains("Xi Graphics"); // bug workaround 639 if (useTranspExt) { 640 // bug workaround - some systems (eg. FireGL) refuses to return an overlay 641 // visual if the GLX_TRANSPARENT_TYPE_EXT attribute is specified, even if 642 // the implementation supports transparent overlays 643 int tmpSpec[] = { GLX_LEVEL, f.plane(), GLX_TRANSPARENT_TYPE_EXT, 644 f.rgba() ? GLX_TRANSPARENT_RGB_EXT : GLX_TRANSPARENT_INDEX_EXT, 645 XNone }; 646 XVisualInfo * vinf = glXChooseVisual(xinfo->display(), xinfo->screen(), tmpSpec); 647 if (!vinf) { 648 useTranspExt = false; 649 } 650 } 651 } 652 653 useTranspExtChecked = true; 654 } 655 if (f.plane() && useTranspExt && !useFBConfig) { 656 // Required to avoid non-transparent overlay visual(!) on some systems 657 spec[i++] = GLX_TRANSPARENT_TYPE_EXT; 658 spec[i++] = f.rgba() ? GLX_TRANSPARENT_RGB_EXT : GLX_TRANSPARENT_INDEX_EXT; 659 } 660 #endif 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 670 if (f.doubleBuffer()) 671 spec[i++] = GLX_DOUBLEBUFFER; 672 if (useFBConfig) 673 spec[i++] = True; 674 if (f.depth()) { 675 spec[i++] = GLX_DEPTH_SIZE; 676 spec[i++] = f.depthBufferSize() == -1 ? 1 : f.depthBufferSize(); 677 } 678 if (f.stereo()) { 679 spec[i++] = GLX_STEREO; 680 if (useFBConfig) 681 spec[i++] = True; 682 } 683 if (f.stencil()) { 684 spec[i++] = GLX_STENCIL_SIZE; 685 spec[i++] = f.stencilBufferSize() == -1 ? 1 : f.stencilBufferSize(); 686 } 687 if (f.rgba()) { 688 if (!useFBConfig) 689 spec[i++] = GLX_RGBA; 690 spec[i++] = GLX_RED_SIZE; 691 spec[i++] = f.redBufferSize() == -1 ? 1 : f.redBufferSize(); 692 spec[i++] = GLX_GREEN_SIZE; 693 spec[i++] = f.greenBufferSize() == -1 ? 1 : f.greenBufferSize(); 694 spec[i++] = GLX_BLUE_SIZE; 695 spec[i++] = f.blueBufferSize() == -1 ? 1 : f.blueBufferSize(); 696 if (f.alpha()) { 697 spec[i++] = GLX_ALPHA_SIZE; 698 spec[i++] = f.alphaBufferSize() == -1 ? 1 : f.alphaBufferSize(); 699 } 700 if (f.accum()) { 701 spec[i++] = GLX_ACCUM_RED_SIZE; 702 spec[i++] = f.accumBufferSize() == -1 ? 1 : f.accumBufferSize(); 703 spec[i++] = GLX_ACCUM_GREEN_SIZE; 704 spec[i++] = f.accumBufferSize() == -1 ? 1 : f.accumBufferSize(); 705 spec[i++] = GLX_ACCUM_BLUE_SIZE; 706 spec[i++] = f.accumBufferSize() == -1 ? 1 : f.accumBufferSize(); 707 if (f.alpha()) { 708 spec[i++] = GLX_ACCUM_ALPHA_SIZE; 709 spec[i++] = f.accumBufferSize() == -1 ? 1 : f.accumBufferSize(); 710 } 711 } 712 } else { 713 spec[i++] = GLX_BUFFER_SIZE; 714 spec[i++] = bufDepth; 715 } 716 717 if (f.sampleBuffers()) { 718 spec[i++] = GLX_SAMPLE_BUFFERS_ARB; 719 spec[i++] = 1; 720 spec[i++] = GLX_SAMPLES_ARB; 721 spec[i++] = f.samples() == -1 ? 4 : f.samples(); 722 } 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 744 spec[i] = XNone; 745 831 bool useFBConfig = buildSpec(spec, f, d->paintDevice, bufDepth, false); 746 832 747 833 XVisualInfo* chosenVisualInfo = 0; … … 756 842 break; // fallback to trying glXChooseVisual 757 843 758 for (i = 0; i < configCount; ++i) {844 for (int i = 0; i < configCount; ++i) { 759 845 XVisualInfo* vi; 760 846 vi = glXGetVisualFromFBConfig(xinfo->display(), configs[i]); … … 844 930 ok = glXMakeCurrent(xinfo->display(), (GLXPbuffer)d->pbuf, (GLXContext)d->cx); 845 931 } else if (d->paintDevice->devType() == QInternal::Widget) { 846 ok = glXMakeCurrent(xinfo->display(), ((QWidget *)d->paintDevice)-> winId(), (GLXContext)d->cx);932 ok = glXMakeCurrent(xinfo->display(), ((QWidget *)d->paintDevice)->internalWinId(), (GLXContext)d->cx); 847 933 } 848 934 if (!ok) … … 1672 1758 1673 1759 1674 QGLTexture *QGLContextPrivate::bindTextureFromNativePixmap(QPixmap Data *pmd, const qint64 key,1760 QGLTexture *QGLContextPrivate::bindTextureFromNativePixmap(QPixmap *pixmap, const qint64 key, 1675 1761 QGLContext::BindOptions options) 1676 1762 { … … 1678 1764 return 0; 1679 1765 #else 1766 1767 // Check we have GLX 1.3, as it is needed for glXCreatePixmap & glXDestroyPixmap 1768 int majorVersion = 0; 1769 int minorVersion = 0; 1770 glXQueryVersion(X11->display, &majorVersion, &minorVersion); 1771 if (majorVersion < 1 || (majorVersion == 1 && minorVersion < 3)) 1772 return 0; 1773 1680 1774 Q_Q(QGLContext); 1681 1775 1682 Q_ASSERT(pmd->classId() == QPixmapData::X11Class); 1776 QX11PixmapData *pixmapData = static_cast<QX11PixmapData*>(pixmap->data_ptr().data()); 1777 Q_ASSERT(pixmapData->classId() == QPixmapData::X11Class); 1778 1779 // We can't use TFP if the pixmap has a separate X11 mask 1780 if (pixmapData->x11_mask) 1781 return 0; 1683 1782 1684 1783 if (!qt_resolveTextureFromPixmap(paintDevice)) 1685 1784 return 0; 1686 1785 1687 QX11PixmapData *pixmapData = static_cast<QX11PixmapData*>(pmd);1688 1786 const QX11Info &x11Info = pixmapData->xinfo; 1689 1787 … … 1754 1852 return 0; 1755 1853 1756 pixmapData->gl_surface = ( Qt::HANDLE)glxPixmap;1854 pixmapData->gl_surface = (void*)glxPixmap; 1757 1855 1758 1856 // Make sure the cleanup hook gets called so we can delete the glx pixmap … … 1766 1864 1767 1865 glBindTexture(GL_TEXTURE_2D, textureId); 1866 GLuint filtering = (options & QGLContext::LinearFilteringBindOption) ? GL_LINEAR : GL_NEAREST; 1867 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filtering); 1868 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering); 1768 1869 1769 1870 if (!((hasAlpha && RGBAConfigInverted) || (!hasAlpha && RGBConfigInverted)))
Note:
See TracChangeset
for help on using the changeset viewer.