src/opengl/qgl_win.cpp
branchGCC_SURGE
changeset 31 5daf16870df6
parent 30 5dc02b23752f
child 37 758a864f9613
equal deleted inserted replaced
27:93b982ccede2 31:5daf16870df6
   120 #define WGL_SWAP_UNDEFINED_ARB         0x202A
   120 #define WGL_SWAP_UNDEFINED_ARB         0x202A
   121 #define WGL_TYPE_RGBA_ARB              0x202B
   121 #define WGL_TYPE_RGBA_ARB              0x202B
   122 #define WGL_TYPE_COLORINDEX_ARB        0x202C
   122 #define WGL_TYPE_COLORINDEX_ARB        0x202C
   123 #endif
   123 #endif
   124 
   124 
       
   125 #ifndef WGL_ARB_create_context
       
   126 #define WGL_CONTEXT_MAJOR_VERSION_ARB               0x2091
       
   127 #define WGL_CONTEXT_MINOR_VERSION_ARB               0x2092
       
   128 #define WGL_CONTEXT_LAYER_PLANE_ARB                 0x2093
       
   129 #define WGL_CONTEXT_FLAGS_ARB                       0x2094
       
   130 #define WGL_CONTEXT_PROFILE_MASK_ARB                0x9126
       
   131 #define WGL_CONTEXT_DEBUG_BIT_ARB                   0x0001
       
   132 #define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB      0x0002
       
   133 #define WGL_CONTEXT_CORE_PROFILE_BIT_ARB            0x0001
       
   134 #define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB   0x0002
       
   135 // Error codes returned by GetLastError().
       
   136 #define ERROR_INVALID_VERSION_ARB                   0x2095
       
   137 #define ERROR_INVALID_PROFILE_ARB                   0x2096
       
   138 #endif
       
   139 
       
   140 #ifndef GL_VERSION_3_2
       
   141 #define GL_CONTEXT_PROFILE_MASK                     0x9126
       
   142 #define GL_MAJOR_VERSION                            0x821B
       
   143 #define GL_MINOR_VERSION                            0x821C
       
   144 #define GL_NUM_EXTENSIONS                           0x821D
       
   145 #define GL_CONTEXT_FLAGS                            0x821E
       
   146 #define GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT      0x0001
       
   147 #endif
       
   148 
   125 QT_BEGIN_NAMESPACE
   149 QT_BEGIN_NAMESPACE
   126 
   150 
   127 class QGLCmapPrivate
   151 class QGLCmapPrivate
   128 {
   152 {
   129 public:
   153 public:
   680     DestroyWindow(d->dmy_id);
   704     DestroyWindow(d->dmy_id);
   681     if (d->old_dc && d->old_context)
   705     if (d->old_dc && d->old_context)
   682         wglMakeCurrent(d->old_dc, d->old_context);
   706         wglMakeCurrent(d->old_dc, d->old_context);
   683 }
   707 }
   684 
   708 
       
   709 static bool qgl_create_context(HDC hdc, QGLContextPrivate *d, QGLContextPrivate *shareContext)
       
   710 {
       
   711     d->rc = 0;
       
   712 
       
   713     typedef HGLRC (APIENTRYP PFNWGLCREATECONTEXTATTRIBSARB)(HDC, HGLRC, const int *);
       
   714     PFNWGLCREATECONTEXTATTRIBSARB wglCreateContextAttribsARB =
       
   715         (PFNWGLCREATECONTEXTATTRIBSARB) wglGetProcAddress("wglCreateContextAttribsARB");
       
   716     if (wglCreateContextAttribsARB) {
       
   717         int attributes[11];
       
   718         int attribIndex = 0;
       
   719         const int major = d->reqFormat.majorVersion();
       
   720         const int minor = d->reqFormat.minorVersion();
       
   721         attributes[attribIndex++] = WGL_CONTEXT_MAJOR_VERSION_ARB;
       
   722         attributes[attribIndex++] = major;
       
   723         attributes[attribIndex++] = WGL_CONTEXT_MINOR_VERSION_ARB;
       
   724         attributes[attribIndex++] = minor;
       
   725 
       
   726         if (major >= 3 && !d->reqFormat.testOption(QGL::DeprecatedFunctions)) {
       
   727             attributes[attribIndex++] = WGL_CONTEXT_FLAGS_ARB;
       
   728             attributes[attribIndex++] = WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;
       
   729         }
       
   730 
       
   731         if ((major == 3 && minor >= 2) || major > 3) {
       
   732             switch (d->reqFormat.profile()) {
       
   733             case QGLFormat::NoProfile:
       
   734                 break;
       
   735             case QGLFormat::CoreProfile:
       
   736                 attributes[attribIndex++] = WGL_CONTEXT_PROFILE_MASK_ARB;
       
   737                 attributes[attribIndex++] = WGL_CONTEXT_CORE_PROFILE_BIT_ARB;
       
   738                 break;
       
   739             case QGLFormat::CompatibilityProfile:
       
   740                 attributes[attribIndex++] = WGL_CONTEXT_PROFILE_MASK_ARB;
       
   741                 attributes[attribIndex++] = WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
       
   742                 break;
       
   743             default:
       
   744                 qWarning("QGLContext::chooseContext(): Context profile not supported.");
       
   745                 return false;
       
   746             }
       
   747         }
       
   748 
       
   749         if (d->reqFormat.plane() != 0) {
       
   750             attributes[attribIndex++] = WGL_CONTEXT_LAYER_PLANE_ARB;
       
   751             attributes[attribIndex++] = d->reqFormat.plane();
       
   752         }
       
   753 
       
   754         attributes[attribIndex++] = 0; // Terminate list.
       
   755         d->rc = wglCreateContextAttribsARB(hdc, shareContext && shareContext->valid
       
   756                                            ? shareContext->rc : 0, attributes);
       
   757         if (d->rc) {
       
   758             if (shareContext)
       
   759                 shareContext->sharing = d->sharing = true;
       
   760             return true;
       
   761         }
       
   762     }
       
   763 
       
   764     d->rc = wglCreateLayerContext(hdc, d->reqFormat.plane());
       
   765     if (d->rc && shareContext && shareContext->valid)
       
   766         shareContext->sharing = d->sharing = wglShareLists(shareContext->rc, d->rc);
       
   767     return d->rc != 0;
       
   768 }
       
   769 
       
   770 void QGLContextPrivate::updateFormatVersion()
       
   771 {
       
   772     const GLubyte *s = glGetString(GL_VERSION);
       
   773 
       
   774     if (!(s && s[0] >= '0' && s[0] <= '9' && s[1] == '.' && s[2] >= '0' && s[2] <= '9')) {
       
   775         if (!s)
       
   776             qWarning("QGLContext::chooseContext(): OpenGL version string is null.");
       
   777         else
       
   778             qWarning("QGLContext::chooseContext(): Unexpected OpenGL version string format.");
       
   779         glFormat.setVersion(0, 0);
       
   780         glFormat.setProfile(QGLFormat::NoProfile);
       
   781         glFormat.setOption(QGL::DeprecatedFunctions);
       
   782         return;
       
   783     }
       
   784 
       
   785     int major = s[0] - '0';
       
   786     int minor = s[2] - '0';
       
   787     glFormat.setVersion(major, minor);
       
   788 
       
   789     if (major < 3) {
       
   790         glFormat.setProfile(QGLFormat::NoProfile);
       
   791         glFormat.setOption(QGL::DeprecatedFunctions);
       
   792     } else {
       
   793         GLint value = 0;
       
   794         if (major > 3 || minor >= 2)
       
   795             glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &value);
       
   796 
       
   797         switch (value) {
       
   798         case WGL_CONTEXT_CORE_PROFILE_BIT_ARB:
       
   799             glFormat.setProfile(QGLFormat::CoreProfile);
       
   800             break;
       
   801         case WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB:
       
   802             glFormat.setProfile(QGLFormat::CompatibilityProfile);
       
   803             break;
       
   804         default:
       
   805             glFormat.setProfile(QGLFormat::NoProfile);
       
   806             break;
       
   807         }
       
   808 
       
   809         glGetIntegerv(GL_CONTEXT_FLAGS, &value);
       
   810         if (value & GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT)
       
   811             glFormat.setOption(QGL::NoDeprecatedFunctions);
       
   812         else
       
   813             glFormat.setOption(QGL::DeprecatedFunctions);
       
   814     }
       
   815 }
       
   816 
   685 bool QGLContext::chooseContext(const QGLContext* shareContext)
   817 bool QGLContext::chooseContext(const QGLContext* shareContext)
   686 {
   818 {
       
   819     QGLContextPrivate *share = shareContext ? const_cast<QGLContext *>(shareContext)->d_func() : 0;
       
   820 
   687     Q_D(QGLContext);
   821     Q_D(QGLContext);
   688     // workaround for matrox driver:
   822     // workaround for matrox driver:
   689     // make a cheap call to opengl to force loading of DLL
   823     // make a cheap call to opengl to force loading of DLL
   690     if (!opengl32dll) {
   824     if (!opengl32dll) {
   691         GLint params;
   825         GLint params;
   739             qWarning("QGLContext::chooseContext(): Cannot create overlay context for invalid widget");
   873             qWarning("QGLContext::chooseContext(): Cannot create overlay context for invalid widget");
   740             result = false;
   874             result = false;
   741             goto end;
   875             goto end;
   742         }
   876         }
   743 
   877 
   744         d->rc = wglCreateLayerContext(myDc, d->glFormat.plane());
   878         if (!qgl_create_context(myDc, d, share)) {
   745         if (!d->rc) {
       
   746             qwglError("QGLContext::chooseContext()", "CreateLayerContext");
   879             qwglError("QGLContext::chooseContext()", "CreateLayerContext");
   747             result = false;
   880             result = false;
   748             goto end;
   881             goto end;
   749         }
   882         }
   750 
   883 
   790                 d->transpColor = QColor(qRgb(1, 2, 3));//, 0);
   923                 d->transpColor = QColor(qRgb(1, 2, 3));//, 0);
   791 
   924 
   792             d->cmap = new QGLCmap(1 << lpfd.cColorBits);
   925             d->cmap = new QGLCmap(1 << lpfd.cColorBits);
   793             d->cmap->setEntry(lpfd.crTransparent, qRgb(1, 2, 3));//, QGLCmap::Reserved);
   926             d->cmap->setEntry(lpfd.crTransparent, qRgb(1, 2, 3));//, QGLCmap::Reserved);
   794         }
   927         }
   795 
   928     } else {
   796         if (shareContext && shareContext->isValid()) {
       
   797             QGLContext *share = const_cast<QGLContext *>(shareContext);
       
   798             d->sharing = (wglShareLists(shareContext->d_func()->rc, d->rc) != 0);
       
   799             share->d_func()->sharing = d->sharing;
       
   800         }
       
   801 
       
   802         goto end;
       
   803     }
       
   804     {
       
   805         PIXELFORMATDESCRIPTOR pfd;
   929         PIXELFORMATDESCRIPTOR pfd;
   806         PIXELFORMATDESCRIPTOR realPfd;
   930         PIXELFORMATDESCRIPTOR realPfd;
   807         d->pixelFormatId = choosePixelFormat(&pfd, myDc);
   931         d->pixelFormatId = choosePixelFormat(&pfd, myDc);
   808         if (d->pixelFormatId == 0) {
   932         if (d->pixelFormatId == 0) {
   809             qwglError("QGLContext::chooseContext()", "ChoosePixelFormat");
   933             qwglError("QGLContext::chooseContext()", "ChoosePixelFormat");
   838             qwglError("QGLContext::chooseContext()", "SetPixelFormat");
   962             qwglError("QGLContext::chooseContext()", "SetPixelFormat");
   839             result = false;
   963             result = false;
   840             goto end;
   964             goto end;
   841         }
   965         }
   842 
   966 
   843         if (!(d->rc = wglCreateLayerContext(myDc, 0))) {
   967         if (!qgl_create_context(myDc, d, share)) {
   844             qwglError("QGLContext::chooseContext()", "wglCreateContext");
   968             qwglError("QGLContext::chooseContext()", "wglCreateContext");
   845             result = false;
   969             result = false;
   846             goto end;
   970             goto end;
   847         }
       
   848 
       
   849         if (shareContext && shareContext->isValid()) {
       
   850             d->sharing = (wglShareLists(shareContext->d_func()->rc, d->rc) != 0);
       
   851             const_cast<QGLContext *>(shareContext)->d_func()->sharing = d->sharing;
       
   852         }
   971         }
   853 
   972 
   854         if(!deviceIsPixmap()) {
   973         if(!deviceIsPixmap()) {
   855             QRgb* pal = qgl_create_rgb_palette(&realPfd);
   974             QRgb* pal = qgl_create_rgb_palette(&realPfd);
   856             if (pal) {
   975             if (pal) {
   863     }
   982     }
   864 
   983 
   865 end:
   984 end:
   866     // vblanking
   985     // vblanking
   867     wglMakeCurrent(myDc, d->rc);
   986     wglMakeCurrent(myDc, d->rc);
       
   987     if (d->rc)
       
   988         d->updateFormatVersion();
       
   989 
   868     typedef BOOL (APIENTRYP PFNWGLSWAPINTERVALEXT) (int interval);
   990     typedef BOOL (APIENTRYP PFNWGLSWAPINTERVALEXT) (int interval);
   869     typedef int (APIENTRYP PFNWGLGETSWAPINTERVALEXT) (void);
   991     typedef int (APIENTRYP PFNWGLGETSWAPINTERVALEXT) (void);
   870     PFNWGLSWAPINTERVALEXT wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXT) wglGetProcAddress("wglSwapIntervalEXT");
   992     PFNWGLSWAPINTERVALEXT wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXT) wglGetProcAddress("wglSwapIntervalEXT");
   871     PFNWGLGETSWAPINTERVALEXT wglGetSwapIntervalEXT = (PFNWGLGETSWAPINTERVALEXT) wglGetProcAddress("wglGetSwapIntervalEXT");
   993     PFNWGLGETSWAPINTERVALEXT wglGetSwapIntervalEXT = (PFNWGLGETSWAPINTERVALEXT) wglGetProcAddress("wglGetSwapIntervalEXT");
   872     if (wglSwapIntervalEXT && wglGetSwapIntervalEXT) {
   994     if (wglSwapIntervalEXT && wglGetSwapIntervalEXT) {
  1156 //
  1278 //
  1157 
  1279 
  1158 void QGLContext::makeCurrent()
  1280 void QGLContext::makeCurrent()
  1159 {
  1281 {
  1160     Q_D(QGLContext);
  1282     Q_D(QGLContext);
  1161     if (d->rc == wglGetCurrentContext() || !d->valid)        // already current
  1283     if (d->rc == wglGetCurrentContext() || !d->valid)       // already current
  1162         return;
  1284         return;
       
  1285 
  1163     if (d->win) {
  1286     if (d->win) {
  1164         d->dc = GetDC(d->win);
  1287         d->dc = GetDC(d->win);
  1165         if (!d->dc) {
  1288         if (!d->dc) {
  1166             qwglError("QGLContext::makeCurrent()", "GetDC()");
  1289             qwglError("QGLContext::makeCurrent()", "GetDC()");
  1167             return;
  1290             return;