diff options
Diffstat (limited to 'src/opengl/qgl_win.cpp')
-rw-r--r-- | src/opengl/qgl_win.cpp | 1601 |
1 files changed, 0 insertions, 1601 deletions
diff --git a/src/opengl/qgl_win.cpp b/src/opengl/qgl_win.cpp deleted file mode 100644 index 3b1643f4c2..0000000000 --- a/src/opengl/qgl_win.cpp +++ /dev/null @@ -1,1601 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtOpenGL module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#include <qgl.h> -#include <qlist.h> -#include <qmap.h> -#include <qpixmap.h> -#include <qevent.h> -#include <private/qgl_p.h> -#include <qcolormap.h> -#include <qvarlengtharray.h> -#include <qdebug.h> -#include <qcolor.h> - -#include <qt_windows.h> - -typedef bool (APIENTRY *PFNWGLGETPIXELFORMATATTRIBIVARB)(HDC hdc, - int iPixelFormat, - int iLayerPlane, - uint nAttributes, - const int *piAttributes, - int *piValues); -typedef bool (APIENTRY *PFNWGLCHOOSEPIXELFORMATARB)(HDC hdc, - const int *piAttribList, - const float *pfAttribFList, - uint nMaxFormats, - int *piFormats, - UINT *nNumFormats); -#ifndef WGL_ARB_multisample -#define WGL_SAMPLE_BUFFERS_ARB 0x2041 -#define WGL_SAMPLES_ARB 0x2042 -#endif - -#ifndef WGL_ARB_pixel_format -#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000 -#define WGL_DRAW_TO_WINDOW_ARB 0x2001 -#define WGL_DRAW_TO_BITMAP_ARB 0x2002 -#define WGL_ACCELERATION_ARB 0x2003 -#define WGL_NEED_PALETTE_ARB 0x2004 -#define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005 -#define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006 -#define WGL_SWAP_METHOD_ARB 0x2007 -#define WGL_NUMBER_OVERLAYS_ARB 0x2008 -#define WGL_NUMBER_UNDERLAYS_ARB 0x2009 -#define WGL_TRANSPARENT_ARB 0x200A -#define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037 -#define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038 -#define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039 -#define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A -#define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B -#define WGL_SHARE_DEPTH_ARB 0x200C -#define WGL_SHARE_STENCIL_ARB 0x200D -#define WGL_SHARE_ACCUM_ARB 0x200E -#define WGL_SUPPORT_GDI_ARB 0x200F -#define WGL_SUPPORT_OPENGL_ARB 0x2010 -#define WGL_DOUBLE_BUFFER_ARB 0x2011 -#define WGL_STEREO_ARB 0x2012 -#define WGL_PIXEL_TYPE_ARB 0x2013 -#define WGL_COLOR_BITS_ARB 0x2014 -#define WGL_RED_BITS_ARB 0x2015 -#define WGL_RED_SHIFT_ARB 0x2016 -#define WGL_GREEN_BITS_ARB 0x2017 -#define WGL_GREEN_SHIFT_ARB 0x2018 -#define WGL_BLUE_BITS_ARB 0x2019 -#define WGL_BLUE_SHIFT_ARB 0x201A -#define WGL_ALPHA_BITS_ARB 0x201B -#define WGL_ALPHA_SHIFT_ARB 0x201C -#define WGL_ACCUM_BITS_ARB 0x201D -#define WGL_ACCUM_RED_BITS_ARB 0x201E -#define WGL_ACCUM_GREEN_BITS_ARB 0x201F -#define WGL_ACCUM_BLUE_BITS_ARB 0x2020 -#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021 -#define WGL_DEPTH_BITS_ARB 0x2022 -#define WGL_STENCIL_BITS_ARB 0x2023 -#define WGL_AUX_BUFFERS_ARB 0x2024 -#define WGL_NO_ACCELERATION_ARB 0x2025 -#define WGL_GENERIC_ACCELERATION_ARB 0x2026 -#define WGL_FULL_ACCELERATION_ARB 0x2027 -#define WGL_SWAP_EXCHANGE_ARB 0x2028 -#define WGL_SWAP_COPY_ARB 0x2029 -#define WGL_SWAP_UNDEFINED_ARB 0x202A -#define WGL_TYPE_RGBA_ARB 0x202B -#define WGL_TYPE_COLORINDEX_ARB 0x202C -#endif - -#ifndef WGL_ARB_create_context -#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091 -#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092 -#define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093 -#define WGL_CONTEXT_FLAGS_ARB 0x2094 -#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126 -#define WGL_CONTEXT_DEBUG_BIT_ARB 0x0001 -#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002 -#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x0001 -#define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x0002 -// Error codes returned by GetLastError(). -#define ERROR_INVALID_VERSION_ARB 0x2095 -#define ERROR_INVALID_PROFILE_ARB 0x2096 -#endif - -#ifndef GL_VERSION_3_2 -#define GL_CONTEXT_PROFILE_MASK 0x9126 -#define GL_MAJOR_VERSION 0x821B -#define GL_MINOR_VERSION 0x821C -#define GL_NUM_EXTENSIONS 0x821D -#define GL_CONTEXT_FLAGS 0x821E -#define GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT 0x0001 -#endif - -QT_BEGIN_NAMESPACE - -class QGLCmapPrivate -{ -public: - QGLCmapPrivate() : count(1) { } - void ref() { ++count; } - bool deref() { return !--count; } - uint count; - - enum AllocState{ UnAllocated = 0, Allocated = 0x01, Reserved = 0x02 }; - - int maxSize; - QVector<uint> colorArray; - QVector<quint8> allocArray; - QVector<quint8> contextArray; - QMap<uint,int> colorMap; -}; - -/***************************************************************************** - QColorMap class - temporarily here, until it is ready for prime time - *****************************************************************************/ - -/**************************************************************************** -** -** Definition of QColorMap class -** -****************************************************************************/ - -class QGLCmapPrivate; - -class /*Q_EXPORT*/ QGLCmap -{ -public: - enum Flags { Reserved = 0x01 }; - - QGLCmap(int maxSize = 256); - QGLCmap(const QGLCmap& map); - ~QGLCmap(); - - QGLCmap& operator=(const QGLCmap& map); - - // isEmpty and/or isNull ? - int size() const; - int maxSize() const; - - void resize(int newSize); - - int find(QRgb color) const; - int findNearest(QRgb color) const; - int allocate(QRgb color, uint flags = 0, quint8 context = 0); - - void setEntry(int idx, QRgb color, uint flags = 0, quint8 context = 0); - - const QRgb* colors() const; - -private: - void detach(); - QGLCmapPrivate* d; -}; - - -QGLCmap::QGLCmap(int maxSize) // add a bool prealloc? -{ - d = new QGLCmapPrivate; - d->maxSize = maxSize; -} - - -QGLCmap::QGLCmap(const QGLCmap& map) -{ - d = map.d; - d->ref(); -} - - -QGLCmap::~QGLCmap() -{ - if (d && d->deref()) - delete d; - d = 0; -} - - -QGLCmap& QGLCmap::operator=(const QGLCmap& map) -{ - map.d->ref(); - if (d->deref()) - delete d; - d = map.d; - return *this; -} - - -int QGLCmap::size() const -{ - return d->colorArray.size(); -} - - -int QGLCmap::maxSize() const -{ - return d->maxSize; -} - - -void QGLCmap::detach() -{ - if (d->count != 1) { - d->deref(); - QGLCmapPrivate* newd = new QGLCmapPrivate; - newd->maxSize = d->maxSize; - newd->colorArray = d->colorArray; - newd->allocArray = d->allocArray; - newd->contextArray = d->contextArray; - newd->colorArray.detach(); - newd->allocArray.detach(); - newd->contextArray.detach(); - newd->colorMap = d->colorMap; - d = newd; - } -} - - -void QGLCmap::resize(int newSize) -{ - if (newSize < 0 || newSize > d->maxSize) { - qWarning("QGLCmap::resize(): size out of range"); - return; - } - int oldSize = size(); - detach(); - //if shrinking; remove the lost elems from colorMap - d->colorArray.resize(newSize); - d->allocArray.resize(newSize); - d->contextArray.resize(newSize); - if (newSize > oldSize) { - memset(d->allocArray.data() + oldSize, 0, newSize - oldSize); - memset(d->contextArray.data() + oldSize, 0, newSize - oldSize); - } -} - - -int QGLCmap::find(QRgb color) const -{ - QMap<uint,int>::ConstIterator it = d->colorMap.find(color); - if (it != d->colorMap.end()) - return *it; - return -1; -} - - -int QGLCmap::findNearest(QRgb color) const -{ - int idx = find(color); - if (idx >= 0) - return idx; - int mapSize = size(); - int mindist = 200000; - int r = qRed(color); - int g = qGreen(color); - int b = qBlue(color); - int rx, gx, bx, dist; - for (int i=0; i < mapSize; i++) { - if (!(d->allocArray[i] & QGLCmapPrivate::Allocated)) - continue; - QRgb ci = d->colorArray[i]; - rx = r - qRed(ci); - gx = g - qGreen(ci); - bx = b - qBlue(ci); - dist = rx*rx + gx*gx + bx*bx; // calculate distance - if (dist < mindist) { // minimal? - mindist = dist; - idx = i; - } - } - return idx; -} - - - - -// Does not always allocate; returns existing c idx if found - -int QGLCmap::allocate(QRgb color, uint flags, quint8 context) -{ - int idx = find(color); - if (idx >= 0) - return idx; - - int mapSize = d->colorArray.size(); - int newIdx = d->allocArray.indexOf(QGLCmapPrivate::UnAllocated); - - if (newIdx < 0) { // Must allocate more room - if (mapSize < d->maxSize) { - newIdx = mapSize; - mapSize++; - resize(mapSize); - } - else { - //# add a bool param that says what to do in case no more room - - // fail (-1) or return nearest? - return -1; - } - } - - d->colorArray[newIdx] = color; - if (flags & QGLCmap::Reserved) { - d->allocArray[newIdx] = QGLCmapPrivate::Reserved; - } - else { - d->allocArray[newIdx] = QGLCmapPrivate::Allocated; - d->colorMap.insert(color, newIdx); - } - d->contextArray[newIdx] = context; - return newIdx; -} - - -void QGLCmap::setEntry(int idx, QRgb color, uint flags, quint8 context) -{ - if (idx < 0 || idx >= d->maxSize) { - qWarning("QGLCmap::set(): Index out of range"); - return; - } - detach(); - int mapSize = size(); - if (idx >= mapSize) { - mapSize = idx + 1; - resize(mapSize); - } - d->colorArray[idx] = color; - if (flags & QGLCmap::Reserved) { - d->allocArray[idx] = QGLCmapPrivate::Reserved; - } - else { - d->allocArray[idx] = QGLCmapPrivate::Allocated; - d->colorMap.insert(color, idx); - } - d->contextArray[idx] = context; -} - - -const QRgb* QGLCmap::colors() const -{ - return d->colorArray.data(); -} - - - -/***************************************************************************** - QGLFormat Win32/WGL-specific code - *****************************************************************************/ - - -void qwglError(const char* method, const char* func) -{ -#ifndef QT_NO_DEBUG - char* lpMsgBuf; - FormatMessageA( - FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, - 0, GetLastError(), - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (char*) &lpMsgBuf, 0, 0); - qWarning("%s : %s failed: %s", method, func, lpMsgBuf); - LocalFree(lpMsgBuf); -#else - Q_UNUSED(method); - Q_UNUSED(func); -#endif -} - - - -bool QGLFormat::hasOpenGL() -{ - return true; -} - -static bool opengl32dll = false; - -bool QGLFormat::hasOpenGLOverlays() -{ - // workaround for matrox driver: - // make a cheap call to opengl to force loading of DLL - if (!opengl32dll) { - GLint params; - glGetIntegerv(GL_DEPTH_BITS, ¶ms); - opengl32dll = true; - } - - static bool checkDone = false; - static bool hasOl = false; - - if (!checkDone) { - checkDone = true; - HDC display_dc = GetDC(0); - int pfiMax = DescribePixelFormat(display_dc, 0, 0, NULL); - PIXELFORMATDESCRIPTOR pfd; - for (int pfi = 1; pfi <= pfiMax; pfi++) { - DescribePixelFormat(display_dc, pfi, sizeof(PIXELFORMATDESCRIPTOR), &pfd); - if ((pfd.bReserved & 0x0f) && (pfd.dwFlags & PFD_SUPPORT_OPENGL)) { - // This format has overlays/underlays - LAYERPLANEDESCRIPTOR lpd; - wglDescribeLayerPlane(display_dc, pfi, 1, - sizeof(LAYERPLANEDESCRIPTOR), &lpd); - if (lpd.dwFlags & LPD_SUPPORT_OPENGL) { - hasOl = true; - break; - } - } - } - ReleaseDC(0, display_dc); - } - return hasOl; -} - - -/***************************************************************************** - QGLContext Win32/WGL-specific code - *****************************************************************************/ - -static uchar qgl_rgb_palette_comp(int idx, uint nbits, uint shift) -{ - const uchar map_3_to_8[8] = { - 0, 0111>>1, 0222>>1, 0333>>1, 0444>>1, 0555>>1, 0666>>1, 0377 - }; - const uchar map_2_to_8[4] = { - 0, 0x55, 0xaa, 0xff - }; - const uchar map_1_to_8[2] = { - 0, 255 - }; - - uchar val = (uchar) (idx >> shift); - uchar res = 0; - switch (nbits) { - case 1: - val &= 0x1; - res = map_1_to_8[val]; - break; - case 2: - val &= 0x3; - res = map_2_to_8[val]; - break; - case 3: - val &= 0x7; - res = map_3_to_8[val]; - break; - default: - res = 0; - } - return res; -} - - -static QRgb* qgl_create_rgb_palette(const PIXELFORMATDESCRIPTOR* pfd) -{ - if ((pfd->iPixelType != PFD_TYPE_RGBA) || - !(pfd->dwFlags & PFD_NEED_PALETTE) || - (pfd->cColorBits != 8)) - return 0; - int numEntries = 1 << pfd->cColorBits; - QRgb* pal = new QRgb[numEntries]; - for (int i = 0; i < numEntries; i++) { - int r = qgl_rgb_palette_comp(i, pfd->cRedBits, pfd->cRedShift); - int g = qgl_rgb_palette_comp(i, pfd->cGreenBits, pfd->cGreenShift); - int b = qgl_rgb_palette_comp(i, pfd->cBlueBits, pfd->cBlueShift); - pal[i] = qRgb(r, g, b); - } - - const int syscol_indices[12] = { - 3, 24, 27, 64, 67, 88, 173, 181, 236, 247, 164, 91 - }; - - const uint syscols[20] = { - 0x000000, 0x800000, 0x008000, 0x808000, 0x000080, 0x800080, - 0x008080, 0xc0c0c0, 0xc0dcc0, 0xa6caf0, 0xfffbf0, 0xa0a0a4, - 0x808080, 0xff0000, 0x00ff00, 0xffff00, 0x0000ff, 0xff00ff, - 0x00ffff, 0xffffff - }; // colors #1 - #12 are not present in pal; gets added below - - if ((pfd->cColorBits == 8) && - (pfd->cRedBits == 3) && (pfd->cRedShift == 0) && - (pfd->cGreenBits == 3) && (pfd->cGreenShift == 3) && - (pfd->cBlueBits == 2) && (pfd->cBlueShift == 6)) { - for (int j = 0 ; j < 12 ; j++) - pal[syscol_indices[j]] = QRgb(syscols[j+1]); - } - - return pal; -} - -static QGLFormat pfdToQGLFormat(const PIXELFORMATDESCRIPTOR* pfd) -{ - QGLFormat fmt; - fmt.setDoubleBuffer(pfd->dwFlags & PFD_DOUBLEBUFFER); - fmt.setDepth(pfd->cDepthBits); - if (fmt.depth()) - fmt.setDepthBufferSize(pfd->cDepthBits); - fmt.setRgba(pfd->iPixelType == PFD_TYPE_RGBA); - fmt.setRedBufferSize(pfd->cRedBits); - fmt.setGreenBufferSize(pfd->cGreenBits); - fmt.setBlueBufferSize(pfd->cBlueBits); - fmt.setAlpha(pfd->cAlphaBits); - if (fmt.alpha()) - fmt.setAlphaBufferSize(pfd->cAlphaBits); - fmt.setAccum(pfd->cAccumBits); - if (fmt.accum()) - fmt.setAccumBufferSize(pfd->cAccumRedBits); - fmt.setStencil(pfd->cStencilBits); - if (fmt.stencil()) - fmt.setStencilBufferSize(pfd->cStencilBits); - fmt.setStereo(pfd->dwFlags & PFD_STEREO); - fmt.setDirectRendering((pfd->dwFlags & PFD_GENERIC_ACCELERATED) || - !(pfd->dwFlags & PFD_GENERIC_FORMAT)); - fmt.setOverlay((pfd->bReserved & 0x0f) != 0); - return fmt; -} - -/* - NB! requires a current GL context to work -*/ -QGLFormat pfiToQGLFormat(HDC hdc, int pfi) -{ - QGLFormat fmt; - QVarLengthArray<int> iAttributes(40); - QVarLengthArray<int> iValues(40); - int i = 0; - bool has_sample_buffers = QGLExtensions::glExtensions() & QGLExtensions::SampleBuffers; - - iAttributes[i++] = WGL_DOUBLE_BUFFER_ARB; // 0 - iAttributes[i++] = WGL_DEPTH_BITS_ARB; // 1 - iAttributes[i++] = WGL_PIXEL_TYPE_ARB; // 2 - iAttributes[i++] = WGL_RED_BITS_ARB; // 3 - iAttributes[i++] = WGL_GREEN_BITS_ARB; // 4 - iAttributes[i++] = WGL_BLUE_BITS_ARB; // 5 - iAttributes[i++] = WGL_ALPHA_BITS_ARB; // 6 - iAttributes[i++] = WGL_ACCUM_BITS_ARB; // 7 - iAttributes[i++] = WGL_STENCIL_BITS_ARB; // 8 - iAttributes[i++] = WGL_STEREO_ARB; // 9 - iAttributes[i++] = WGL_ACCELERATION_ARB; // 10 - iAttributes[i++] = WGL_NUMBER_OVERLAYS_ARB; // 11 - if (has_sample_buffers) { - iAttributes[i++] = WGL_SAMPLE_BUFFERS_ARB; // 12 - iAttributes[i++] = WGL_SAMPLES_ARB; // 13 - } - PFNWGLGETPIXELFORMATATTRIBIVARB wglGetPixelFormatAttribivARB = - (PFNWGLGETPIXELFORMATATTRIBIVARB) wglGetProcAddress("wglGetPixelFormatAttribivARB"); - - if (wglGetPixelFormatAttribivARB - && wglGetPixelFormatAttribivARB(hdc, pfi, 0, i, - iAttributes.constData(), - iValues.data())) - { - fmt.setDoubleBuffer(iValues[0]); - fmt.setDepth(iValues[1]); - if (fmt.depth()) - fmt.setDepthBufferSize(iValues[1]); - fmt.setRgba(iValues[2] == WGL_TYPE_RGBA_ARB); - fmt.setRedBufferSize(iValues[3]); - fmt.setGreenBufferSize(iValues[4]); - fmt.setBlueBufferSize(iValues[5]); - fmt.setAlpha(iValues[6]); - if (fmt.alpha()) - fmt.setAlphaBufferSize(iValues[6]); - fmt.setAccum(iValues[7]); - if (fmt.accum()) - fmt.setAccumBufferSize(iValues[7]); - fmt.setStencil(iValues[8]); - if (fmt.stencil()) - fmt.setStencilBufferSize(iValues[8]); - fmt.setStereo(iValues[9]); - if (iValues[10] == WGL_FULL_ACCELERATION_ARB) - fmt.setDirectRendering(true); - else - fmt.setDirectRendering(false); - fmt.setOverlay(iValues[11]); - if (has_sample_buffers) { - fmt.setSampleBuffers(iValues[12]); - if (fmt.sampleBuffers()) - fmt.setSamples(iValues[13]); - } - } -#if 0 - qDebug() << "values for pfi:" << pfi; - qDebug() << "doublebuffer 0:" << fmt.doubleBuffer(); - qDebug() << "depthbuffer 1:" << fmt.depthBufferSize(); - qDebug() << "rgba 2:" << fmt.rgba(); - qDebug() << "red size 3:" << fmt.redBufferSize(); - qDebug() << "green size 4:" << fmt.greenBufferSize(); - qDebug() << "blue size 5:" << fmt.blueBufferSize(); - qDebug() << "alpha size 6:" << fmt.alphaBufferSize(); - qDebug() << "accum size 7:" << fmt.accumBufferSize(); - qDebug() << "stencil size 8:" << fmt.stencilBufferSize(); - qDebug() << "stereo 9:" << fmt.stereo(); - qDebug() << "direct 10:" << fmt.directRendering(); - qDebug() << "has overlays 11:" << fmt.hasOverlay(); - qDebug() << "sample buff 12:" << fmt.sampleBuffers(); - qDebug() << "num samples 13:" << fmt.samples(); -#endif - return fmt; -} - - -/* - QGLTemporaryContext implementation -*/ - -Q_GUI_EXPORT const QString qt_getRegisteredWndClass(); - -class QGLTemporaryContextPrivate -{ -public: - HDC dmy_pdc; - HGLRC dmy_rc; - HDC old_dc; - HGLRC old_context; - WId dmy_id; -}; - -QGLTemporaryContext::QGLTemporaryContext(bool directRendering, QWidget *parent) - : d(new QGLTemporaryContextPrivate) -{ - QString windowClassName = qt_getRegisteredWndClass(); - if (parent && !parent->internalWinId()) - parent = parent->nativeParentWidget(); - - d->dmy_id = CreateWindow((const wchar_t *)windowClassName.utf16(), - 0, 0, 0, 0, 1, 1, - parent ? parent->winId() : 0, 0, qWinAppInst(), 0); - - d->dmy_pdc = GetDC(d->dmy_id); - PIXELFORMATDESCRIPTOR dmy_pfd; - memset(&dmy_pfd, 0, sizeof(PIXELFORMATDESCRIPTOR)); - dmy_pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); - dmy_pfd.nVersion = 1; - dmy_pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW; - dmy_pfd.iPixelType = PFD_TYPE_RGBA; - if (!directRendering) - dmy_pfd.dwFlags |= PFD_GENERIC_FORMAT; - - int dmy_pf = ChoosePixelFormat(d->dmy_pdc, &dmy_pfd); - SetPixelFormat(d->dmy_pdc, dmy_pf, &dmy_pfd); - d->dmy_rc = wglCreateContext(d->dmy_pdc); - d->old_dc = wglGetCurrentDC(); - d->old_context = wglGetCurrentContext(); - wglMakeCurrent(d->dmy_pdc, d->dmy_rc); -} - -QGLTemporaryContext::~QGLTemporaryContext() -{ - wglMakeCurrent(d->dmy_pdc, 0); - wglDeleteContext(d->dmy_rc); - ReleaseDC(d->dmy_id, d->dmy_pdc); - DestroyWindow(d->dmy_id); - if (d->old_dc && d->old_context) - wglMakeCurrent(d->old_dc, d->old_context); -} - -static bool qgl_create_context(HDC hdc, QGLContextPrivate *d, QGLContextPrivate *shareContext) -{ - d->rc = 0; - - typedef HGLRC (APIENTRYP PFNWGLCREATECONTEXTATTRIBSARB)(HDC, HGLRC, const int *); - PFNWGLCREATECONTEXTATTRIBSARB wglCreateContextAttribsARB = - (PFNWGLCREATECONTEXTATTRIBSARB) wglGetProcAddress("wglCreateContextAttribsARB"); - if (wglCreateContextAttribsARB) { - int attributes[11]; - int attribIndex = 0; - const int major = d->reqFormat.majorVersion(); - const int minor = d->reqFormat.minorVersion(); - attributes[attribIndex++] = WGL_CONTEXT_MAJOR_VERSION_ARB; - attributes[attribIndex++] = major; - attributes[attribIndex++] = WGL_CONTEXT_MINOR_VERSION_ARB; - attributes[attribIndex++] = minor; - - if (major >= 3 && !d->reqFormat.testOption(QGL::DeprecatedFunctions)) { - attributes[attribIndex++] = WGL_CONTEXT_FLAGS_ARB; - attributes[attribIndex++] = WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB; - } - - if ((major == 3 && minor >= 2) || major > 3) { - switch (d->reqFormat.profile()) { - case QGLFormat::NoProfile: - break; - case QGLFormat::CoreProfile: - attributes[attribIndex++] = WGL_CONTEXT_PROFILE_MASK_ARB; - attributes[attribIndex++] = WGL_CONTEXT_CORE_PROFILE_BIT_ARB; - break; - case QGLFormat::CompatibilityProfile: - attributes[attribIndex++] = WGL_CONTEXT_PROFILE_MASK_ARB; - attributes[attribIndex++] = WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; - break; - default: - qWarning("QGLContext::chooseContext(): Context profile not supported."); - return false; - } - } - - if (d->reqFormat.plane() != 0) { - attributes[attribIndex++] = WGL_CONTEXT_LAYER_PLANE_ARB; - attributes[attribIndex++] = d->reqFormat.plane(); - } - - attributes[attribIndex++] = 0; // Terminate list. - d->rc = wglCreateContextAttribsARB(hdc, shareContext && shareContext->valid - ? shareContext->rc : 0, attributes); - if (d->rc) { - if (shareContext) - shareContext->sharing = d->sharing = true; - return true; - } - } - - d->rc = wglCreateLayerContext(hdc, d->reqFormat.plane()); - if (d->rc && shareContext && shareContext->valid) - shareContext->sharing = d->sharing = wglShareLists(shareContext->rc, d->rc); - return d->rc != 0; -} - -void QGLContextPrivate::updateFormatVersion() -{ - const GLubyte *s = glGetString(GL_VERSION); - - if (!(s && s[0] >= '0' && s[0] <= '9' && s[1] == '.' && s[2] >= '0' && s[2] <= '9')) { - if (!s) - qWarning("QGLContext::chooseContext(): OpenGL version string is null."); - else - qWarning("QGLContext::chooseContext(): Unexpected OpenGL version string format."); - glFormat.setVersion(0, 0); - glFormat.setProfile(QGLFormat::NoProfile); - glFormat.setOption(QGL::DeprecatedFunctions); - return; - } - - int major = s[0] - '0'; - int minor = s[2] - '0'; - glFormat.setVersion(major, minor); - - if (major < 3) { - glFormat.setProfile(QGLFormat::NoProfile); - glFormat.setOption(QGL::DeprecatedFunctions); - } else { - GLint value = 0; - if (major > 3 || minor >= 2) - glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &value); - - switch (value) { - case WGL_CONTEXT_CORE_PROFILE_BIT_ARB: - glFormat.setProfile(QGLFormat::CoreProfile); - break; - case WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB: - glFormat.setProfile(QGLFormat::CompatibilityProfile); - break; - default: - glFormat.setProfile(QGLFormat::NoProfile); - break; - } - - glGetIntegerv(GL_CONTEXT_FLAGS, &value); - if (value & GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT) - glFormat.setOption(QGL::NoDeprecatedFunctions); - else - glFormat.setOption(QGL::DeprecatedFunctions); - } -} - -bool QGLContext::chooseContext(const QGLContext* shareContext) -{ - QGLContextPrivate *share = shareContext ? const_cast<QGLContext *>(shareContext)->d_func() : 0; - - Q_D(QGLContext); - // workaround for matrox driver: - // make a cheap call to opengl to force loading of DLL - if (!opengl32dll) { - GLint params; - glGetIntegerv(GL_DEPTH_BITS, ¶ms); - opengl32dll = true; - } - - bool result = true; - HDC myDc; - QWidget *widget = 0; - - if (deviceIsPixmap()) { - if (d->glFormat.plane()) - return false; // Pixmaps can't have overlay - d->win = 0; - HDC display_dc = GetDC(0); - myDc = d->hbitmap_hdc = CreateCompatibleDC(display_dc); - QPixmap *px = static_cast<QPixmap *>(d->paintDevice); - - BITMAPINFO bmi; - memset(&bmi, 0, sizeof(bmi)); - bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - bmi.bmiHeader.biWidth = px->width(); - bmi.bmiHeader.biHeight = px->height(); - bmi.bmiHeader.biPlanes = 1; - bmi.bmiHeader.biBitCount = 32; - bmi.bmiHeader.biCompression = BI_RGB; - d->hbitmap = CreateDIBSection(display_dc, &bmi, DIB_RGB_COLORS, 0, 0, 0); - SelectObject(myDc, d->hbitmap); - ReleaseDC(0, display_dc); - } else { - widget = static_cast<QWidget *>(d->paintDevice); - d->win = widget->winId(); - myDc = GetDC(d->win); - } - - // NB! the QGLTemporaryContext object is needed for the - // wglGetProcAddress() calls to succeed and are absolutely - // necessary - don't remove! - QGLTemporaryContext tmp_ctx(d->glFormat.directRendering(), widget); - - if (!myDc) { - qWarning("QGLContext::chooseContext(): Paint device cannot be null"); - result = false; - goto end; - } - - if (d->glFormat.plane()) { - d->pixelFormatId = ((QGLWidget*)d->paintDevice)->context()->d_func()->pixelFormatId; - if (!d->pixelFormatId) { // I.e. the glwidget is invalid - qWarning("QGLContext::chooseContext(): Cannot create overlay context for invalid widget"); - result = false; - goto end; - } - - if (!qgl_create_context(myDc, d, share)) { - qwglError("QGLContext::chooseContext()", "CreateLayerContext"); - result = false; - goto end; - } - - LAYERPLANEDESCRIPTOR lpfd; - wglDescribeLayerPlane(myDc, d->pixelFormatId, d->glFormat.plane(), sizeof(LAYERPLANEDESCRIPTOR), &lpfd); - d->glFormat.setDoubleBuffer(lpfd.dwFlags & LPD_DOUBLEBUFFER); - d->glFormat.setDepth(lpfd.cDepthBits); - d->glFormat.setRgba(lpfd.iPixelType == PFD_TYPE_RGBA); - if (d->glFormat.rgba()) { - if (d->glFormat.redBufferSize() != -1) - d->glFormat.setRedBufferSize(lpfd.cRedBits); - if (d->glFormat.greenBufferSize() != -1) - d->glFormat.setGreenBufferSize(lpfd.cGreenBits); - if (d->glFormat.blueBufferSize() != -1) - d->glFormat.setBlueBufferSize(lpfd.cBlueBits); - } - d->glFormat.setAlpha(lpfd.cAlphaBits); - d->glFormat.setAccum(lpfd.cAccumBits); - d->glFormat.setStencil(lpfd.cStencilBits); - d->glFormat.setStereo(lpfd.dwFlags & LPD_STEREO); - d->glFormat.setDirectRendering(false); - if (d->glFormat.depth()) - d->glFormat.setDepthBufferSize(lpfd.cDepthBits); - if (d->glFormat.alpha()) - d->glFormat.setAlphaBufferSize(lpfd.cAlphaBits); - if (d->glFormat.accum()) - d->glFormat.setAccumBufferSize(lpfd.cAccumRedBits); - if (d->glFormat.stencil()) - d->glFormat.setStencilBufferSize(lpfd.cStencilBits); - - if (d->glFormat.rgba()) { - if (lpfd.dwFlags & LPD_TRANSPARENT) - d->transpColor = QColor(lpfd.crTransparent & 0xff, - (lpfd.crTransparent >> 8) & 0xff, - (lpfd.crTransparent >> 16) & 0xff); - else - d->transpColor = QColor(0, 0, 0); - } - else { - if (lpfd.dwFlags & LPD_TRANSPARENT) - d->transpColor = QColor(qRgb(1, 2, 3));//, lpfd.crTransparent); - else - d->transpColor = QColor(qRgb(1, 2, 3));//, 0); - - d->cmap = new QGLCmap(1 << lpfd.cColorBits); - d->cmap->setEntry(lpfd.crTransparent, qRgb(1, 2, 3));//, QGLCmap::Reserved); - } - } else { - PIXELFORMATDESCRIPTOR pfd; - PIXELFORMATDESCRIPTOR realPfd; - d->pixelFormatId = choosePixelFormat(&pfd, myDc); - if (d->pixelFormatId == 0) { - qwglError("QGLContext::chooseContext()", "ChoosePixelFormat"); - result = false; - goto end; - } - - bool overlayRequested = d->glFormat.hasOverlay(); - DescribePixelFormat(myDc, d->pixelFormatId, sizeof(PIXELFORMATDESCRIPTOR), &realPfd); - - if (!deviceIsPixmap() && wglGetProcAddress("wglGetPixelFormatAttribivARB")) - d->glFormat = pfiToQGLFormat(myDc, d->pixelFormatId); - else - d->glFormat = pfdToQGLFormat(&realPfd); - - d->glFormat.setOverlay(d->glFormat.hasOverlay() && overlayRequested); - - if (deviceIsPixmap() && !(realPfd.dwFlags & PFD_DRAW_TO_BITMAP)) { - qWarning("QGLContext::chooseContext(): Failed to get pixmap rendering context."); - result = false; - goto end; - } - - if (deviceIsPixmap() && - (((QPixmap*)d->paintDevice)->depth() != realPfd.cColorBits)) { - qWarning("QGLContext::chooseContext(): Failed to get pixmap rendering context of suitable depth."); - result = false; - goto end; - } - - if (!SetPixelFormat(myDc, d->pixelFormatId, &realPfd)) { - qwglError("QGLContext::chooseContext()", "SetPixelFormat"); - result = false; - goto end; - } - - if (!qgl_create_context(myDc, d, share)) { - qwglError("QGLContext::chooseContext()", "wglCreateContext"); - result = false; - goto end; - } - - if(!deviceIsPixmap()) { - QRgb* pal = qgl_create_rgb_palette(&realPfd); - if (pal) { - QGLColormap cmap; - cmap.setEntries(256, pal); - ((QGLWidget*)d->paintDevice)->setColormap(cmap); - delete[] pal; - } - } - } - -end: - // vblanking - wglMakeCurrent(myDc, d->rc); - if (d->rc) - d->updateFormatVersion(); - - typedef BOOL (APIENTRYP PFNWGLSWAPINTERVALEXT) (int interval); - typedef int (APIENTRYP PFNWGLGETSWAPINTERVALEXT) (void); - PFNWGLSWAPINTERVALEXT wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXT) wglGetProcAddress("wglSwapIntervalEXT"); - PFNWGLGETSWAPINTERVALEXT wglGetSwapIntervalEXT = (PFNWGLGETSWAPINTERVALEXT) wglGetProcAddress("wglGetSwapIntervalEXT"); - if (wglSwapIntervalEXT && wglGetSwapIntervalEXT) { - if (d->reqFormat.swapInterval() != -1) - wglSwapIntervalEXT(d->reqFormat.swapInterval()); - d->glFormat.setSwapInterval(wglGetSwapIntervalEXT()); - } - - if (d->win) - ReleaseDC(d->win, myDc); - return result; -} - - - -static bool qLogEq(bool a, bool b) -{ - return (((!a) && (!b)) || (a && b)); -} - -/* - See qgl.cpp for qdoc comment. - */ -int QGLContext::choosePixelFormat(void* dummyPfd, HDC pdc) -{ - Q_D(QGLContext); - // workaround for matrox driver: - // make a cheap call to opengl to force loading of DLL - if (!opengl32dll) { - GLint params; - glGetIntegerv(GL_DEPTH_BITS, ¶ms); - opengl32dll = true; - } - - PFNWGLCHOOSEPIXELFORMATARB wglChoosePixelFormatARB = - (PFNWGLCHOOSEPIXELFORMATARB) wglGetProcAddress("wglChoosePixelFormatARB"); - int chosenPfi = 0; - if (!deviceIsPixmap() && wglChoosePixelFormatARB) { - bool valid; - int pixelFormat = 0; - uint numFormats = 0; - QVarLengthArray<int> iAttributes(40); - int i = 0; - iAttributes[i++] = WGL_ACCELERATION_ARB; - if (d->glFormat.directRendering()) - iAttributes[i++] = WGL_FULL_ACCELERATION_ARB; - else - iAttributes[i++] = WGL_NO_ACCELERATION_ARB; - iAttributes[i++] = WGL_SUPPORT_OPENGL_ARB; - iAttributes[i++] = TRUE; - iAttributes[i++] = WGL_DRAW_TO_WINDOW_ARB; - iAttributes[i++] = TRUE; - iAttributes[i++] = WGL_COLOR_BITS_ARB; - iAttributes[i++] = 24; - iAttributes[i++] = WGL_DOUBLE_BUFFER_ARB; - iAttributes[i++] = d->glFormat.doubleBuffer(); - if (d->glFormat.stereo()) { - iAttributes[i++] = WGL_STEREO_ARB; - iAttributes[i++] = TRUE; - } - if (d->glFormat.depth()) { - iAttributes[i++] = WGL_DEPTH_BITS_ARB; - iAttributes[i++] = d->glFormat.depthBufferSize() == -1 ? 24 : d->glFormat.depthBufferSize(); - } - iAttributes[i++] = WGL_PIXEL_TYPE_ARB; - if (d->glFormat.rgba()) { - iAttributes[i++] = WGL_TYPE_RGBA_ARB; - if (d->glFormat.redBufferSize() != -1) { - iAttributes[i++] = WGL_RED_BITS_ARB; - iAttributes[i++] = d->glFormat.redBufferSize(); - } - if (d->glFormat.greenBufferSize() != -1) { - iAttributes[i++] = WGL_GREEN_BITS_ARB; - iAttributes[i++] = d->glFormat.greenBufferSize(); - } - if (d->glFormat.blueBufferSize() != -1) { - iAttributes[i++] = WGL_BLUE_BITS_ARB; - iAttributes[i++] = d->glFormat.blueBufferSize(); - } - } else { - iAttributes[i++] = WGL_TYPE_COLORINDEX_ARB; - } - if (d->glFormat.alpha()) { - iAttributes[i++] = WGL_ALPHA_BITS_ARB; - iAttributes[i++] = d->glFormat.alphaBufferSize() == -1 ? 8 : d->glFormat.alphaBufferSize(); - } - if (d->glFormat.accum()) { - iAttributes[i++] = WGL_ACCUM_BITS_ARB; - iAttributes[i++] = d->glFormat.accumBufferSize() == -1 ? 16 : d->glFormat.accumBufferSize(); - } - if (d->glFormat.stencil()) { - iAttributes[i++] = WGL_STENCIL_BITS_ARB; - iAttributes[i++] = d->glFormat.stencilBufferSize() == -1 ? 8 : d->glFormat.stencilBufferSize(); - } - if (d->glFormat.hasOverlay()) { - iAttributes[i++] = WGL_NUMBER_OVERLAYS_ARB; - iAttributes[i++] = 1; - } - int si = 0; - bool trySampleBuffers = QGLExtensions::glExtensions() & QGLExtensions::SampleBuffers; - if (trySampleBuffers && d->glFormat.sampleBuffers()) { - iAttributes[i++] = WGL_SAMPLE_BUFFERS_ARB; - iAttributes[i++] = TRUE; - iAttributes[i++] = WGL_SAMPLES_ARB; - si = i; - iAttributes[i++] = d->glFormat.samples() == -1 ? 4 : d->glFormat.samples(); - } - iAttributes[i] = 0; - - do { - valid = wglChoosePixelFormatARB(pdc, iAttributes.constData(), 0, 1, - &pixelFormat, &numFormats); - if (trySampleBuffers && (!valid || numFormats < 1) && d->glFormat.sampleBuffers()) - iAttributes[si] /= 2; // try different no. samples - we aim for the best one - else - break; - } while ((!valid || numFormats < 1) && iAttributes[si] > 1); - chosenPfi = pixelFormat; - } - - if (!chosenPfi) { // fallback if wglChoosePixelFormatARB() failed - int pmDepth = deviceIsPixmap() ? ((QPixmap*)d->paintDevice)->depth() : 0; - PIXELFORMATDESCRIPTOR* p = (PIXELFORMATDESCRIPTOR*)dummyPfd; - memset(p, 0, sizeof(PIXELFORMATDESCRIPTOR)); - p->nSize = sizeof(PIXELFORMATDESCRIPTOR); - p->nVersion = 1; - p->dwFlags = PFD_SUPPORT_OPENGL; - if (deviceIsPixmap()) - p->dwFlags |= PFD_DRAW_TO_BITMAP; - else - p->dwFlags |= PFD_DRAW_TO_WINDOW; - if (!d->glFormat.directRendering()) - p->dwFlags |= PFD_GENERIC_FORMAT; - if (d->glFormat.doubleBuffer() && !deviceIsPixmap()) - p->dwFlags |= PFD_DOUBLEBUFFER; - if (d->glFormat.stereo()) - p->dwFlags |= PFD_STEREO; - if (d->glFormat.depth()) - p->cDepthBits = d->glFormat.depthBufferSize() == -1 ? 32 : d->glFormat.depthBufferSize(); - else - p->dwFlags |= PFD_DEPTH_DONTCARE; - if (d->glFormat.rgba()) { - p->iPixelType = PFD_TYPE_RGBA; - if (d->glFormat.redBufferSize() != -1) - p->cRedBits = d->glFormat.redBufferSize(); - if (d->glFormat.greenBufferSize() != -1) - p->cGreenBits = d->glFormat.greenBufferSize(); - if (d->glFormat.blueBufferSize() != -1) - p->cBlueBits = d->glFormat.blueBufferSize(); - if (deviceIsPixmap()) - p->cColorBits = pmDepth; - else - p->cColorBits = 32; - } else { - p->iPixelType = PFD_TYPE_COLORINDEX; - p->cColorBits = 8; - } - if (d->glFormat.alpha()) - p->cAlphaBits = d->glFormat.alphaBufferSize() == -1 ? 8 : d->glFormat.alphaBufferSize(); - if (d->glFormat.accum()) { - p->cAccumRedBits = p->cAccumGreenBits = p->cAccumBlueBits = p->cAccumAlphaBits = - d->glFormat.accumBufferSize() == -1 ? 16 : d->glFormat.accumBufferSize(); - } - if (d->glFormat.stencil()) - p->cStencilBits = d->glFormat.stencilBufferSize() == -1 ? 8 : d->glFormat.stencilBufferSize(); - p->iLayerType = PFD_MAIN_PLANE; - chosenPfi = ChoosePixelFormat(pdc, p); - - if (!chosenPfi) - qErrnoWarning("QGLContext: ChoosePixelFormat failed"); - - // Since the GDI function ChoosePixelFormat() does not handle - // overlay and direct-rendering requests, we must roll our own here - - bool doSearch = chosenPfi <= 0; - PIXELFORMATDESCRIPTOR pfd; - QGLFormat fmt; - if (!doSearch) { - DescribePixelFormat(pdc, chosenPfi, sizeof(PIXELFORMATDESCRIPTOR), - &pfd); - fmt = pfdToQGLFormat(&pfd); - if (d->glFormat.hasOverlay() && !fmt.hasOverlay()) - doSearch = true; - else if (!qLogEq(d->glFormat.directRendering(), fmt.directRendering())) - doSearch = true; - else if (deviceIsPixmap() && (!(pfd.dwFlags & PFD_DRAW_TO_BITMAP) || - pfd.cColorBits != pmDepth)) - doSearch = true; - else if (!deviceIsPixmap() && !(pfd.dwFlags & PFD_DRAW_TO_WINDOW)) - doSearch = true; - else if (!qLogEq(d->glFormat.rgba(), fmt.rgba())) - doSearch = true; - } - - if (doSearch) { - int pfiMax = DescribePixelFormat(pdc, 0, 0, NULL); - int bestScore = -1; - int bestPfi = -1; - for (int pfi = 1; pfi <= pfiMax; pfi++) { - DescribePixelFormat(pdc, pfi, sizeof(PIXELFORMATDESCRIPTOR), &pfd); - if (!(pfd.dwFlags & PFD_SUPPORT_OPENGL)) - continue; - if (deviceIsPixmap() && (!(pfd.dwFlags & PFD_DRAW_TO_BITMAP) || - pfd.cColorBits != pmDepth)) - continue; - if (!deviceIsPixmap() && !(pfd.dwFlags & PFD_DRAW_TO_WINDOW)) - continue; - - fmt = pfdToQGLFormat(&pfd); - if (d->glFormat.hasOverlay() && !fmt.hasOverlay()) - continue; - - int score = pfd.cColorBits; - if (qLogEq(d->glFormat.depth(), fmt.depth())) - score += pfd.cDepthBits; - if (qLogEq(d->glFormat.alpha(), fmt.alpha())) - score += pfd.cAlphaBits; - if (qLogEq(d->glFormat.accum(), fmt.accum())) - score += pfd.cAccumBits; - if (qLogEq(d->glFormat.stencil(), fmt.stencil())) - score += pfd.cStencilBits; - if (qLogEq(d->glFormat.doubleBuffer(), fmt.doubleBuffer())) - score += 1000; - if (qLogEq(d->glFormat.stereo(), fmt.stereo())) - score += 2000; - if (qLogEq(d->glFormat.directRendering(), fmt.directRendering())) - score += 4000; - if (qLogEq(d->glFormat.rgba(), fmt.rgba())) - score += 8000; - if (score > bestScore) { - bestScore = score; - bestPfi = pfi; - } - } - - if (bestPfi > 0) - chosenPfi = bestPfi; - } - } - return chosenPfi; -} - - - -void QGLContext::reset() -{ - Q_D(QGLContext); - // workaround for matrox driver: - // make a cheap call to opengl to force loading of DLL - if (!opengl32dll) { - GLint params; - glGetIntegerv(GL_DEPTH_BITS, ¶ms); - opengl32dll = true; - } - - if (!d->valid) - return; - d->cleanup(); - doneCurrent(); - if (d->rc) - wglDeleteContext(d->rc); - d->rc = 0; - if (d->win && d->dc) - ReleaseDC(d->win, d->dc); - if (deviceIsPixmap()) { - DeleteDC(d->hbitmap_hdc); - DeleteObject(d->hbitmap); - d->hbitmap_hdc = 0; - d->hbitmap = 0; - } - d->dc = 0; - d->win = 0; - d->threadId = 0; - d->pixelFormatId = 0; - d->sharing = false; - d->valid = false; - d->transpColor = QColor(); - delete d->cmap; - d->cmap = 0; - d->initDone = false; - QGLContextGroup::removeShare(this); -} - -// -// NOTE: In a multi-threaded environment, each thread has a current -// context. If we want to make this code thread-safe, we probably -// have to use TLS (thread local storage) for keeping current contexts. -// - -void QGLContext::makeCurrent() -{ - Q_D(QGLContext); - if (d->rc == wglGetCurrentContext() || !d->valid) // already current - return; - - if (d->win && (!d->dc || d->threadId != QThread::currentThreadId())) { - d->dc = GetDC(d->win); - d->threadId = QThread::currentThreadId(); - if (!d->dc) { - qwglError("QGLContext::makeCurrent()", "GetDC()"); - return; - } - } else if (deviceIsPixmap()) { - d->dc = d->hbitmap_hdc; - } - - HPALETTE hpal = QColormap::hPal(); - if (hpal) { - SelectPalette(d->dc, hpal, FALSE); - RealizePalette(d->dc); - } - if (d->glFormat.plane()) { - wglRealizeLayerPalette(d->dc, d->glFormat.plane(), TRUE); - } - - if (wglMakeCurrent(d->dc, d->rc)) { - QGLContextPrivate::setCurrentContext(this); - } else { - qwglError("QGLContext::makeCurrent()", "wglMakeCurrent"); - } -} - - -void QGLContext::doneCurrent() -{ - Q_D(QGLContext); - wglMakeCurrent(0, 0); - QGLContextPrivate::setCurrentContext(0); - if (deviceIsPixmap() && d->hbitmap) { - QPixmap *pm = static_cast<QPixmap *>(d->paintDevice); - *pm = QPixmap::fromWinHBITMAP(d->hbitmap); - } - if (d->win && d->dc) { - ReleaseDC(d->win, d->dc); - d->dc = 0; - d->threadId = 0; - } -} - -void QGLContext::swapBuffers() const -{ - Q_D(const QGLContext); - if (d->dc && d->glFormat.doubleBuffer() && !deviceIsPixmap()) { - if (d->glFormat.plane()) - wglSwapLayerBuffers(d->dc, WGL_SWAP_OVERLAY1); - else { - if (d->glFormat.hasOverlay()) - wglSwapLayerBuffers(d->dc, WGL_SWAP_MAIN_PLANE); - else - SwapBuffers(d->dc); - } - } -} - - -QColor QGLContext::overlayTransparentColor() const -{ - return d_func()->transpColor; -} - - -uint QGLContext::colorIndex(const QColor& c) const -{ - Q_D(const QGLContext); - if (!isValid()) - return 0; - if (d->cmap) { - int idx = d->cmap->find(c.rgb()); - if (idx >= 0) - return idx; - if (d->dc && d->glFormat.plane()) { - idx = d->cmap->allocate(c.rgb()); - if (idx >= 0) { - COLORREF r = RGB(qRed(c.rgb()),qGreen(c.rgb()),qBlue(c.rgb())); - wglSetLayerPaletteEntries(d->dc, d->glFormat.plane(), idx, 1, &r); - wglRealizeLayerPalette(d->dc, d->glFormat.plane(), TRUE); - return idx; - } - } - return d->cmap->findNearest(c.rgb()); - } - QColormap cmap = QColormap::instance(); - return cmap.pixel(c) & 0x00ffffff; // Assumes standard palette -} - -void QGLContext::generateFontDisplayLists(const QFont & fnt, int listBase) -{ - if (!isValid()) - return; - - HDC display_dc = GetDC(0); - HDC tmp_dc = CreateCompatibleDC(display_dc); - HGDIOBJ old_font = SelectObject(tmp_dc, fnt.handle()); - - ReleaseDC(0, display_dc); - - if (!wglUseFontBitmaps(tmp_dc, 0, 256, listBase)) - qWarning("QGLContext::generateFontDisplayLists: Could not generate display lists for font '%s'", fnt.family().toLatin1().data()); - - SelectObject(tmp_dc, old_font); - DeleteDC(tmp_dc); -} - -void *QGLContext::getProcAddress(const QString &proc) const -{ - return (void *)wglGetProcAddress(proc.toLatin1()); -} - -/***************************************************************************** - QGLWidget Win32/WGL-specific code - *****************************************************************************/ - -void QGLWidgetPrivate::init(QGLContext *ctx, const QGLWidget* shareWidget) -{ - Q_Q(QGLWidget); - olcx = 0; - initContext(ctx, shareWidget); - - if (q->isValid() && q->context()->format().hasOverlay()) { - olcx = new QGLContext(QGLFormat::defaultOverlayFormat(), q); - if (!olcx->create(shareWidget ? shareWidget->overlayContext() : 0)) { - delete olcx; - olcx = 0; - glcx->d_func()->glFormat.setOverlay(false); - } - } else { - olcx = 0; - } -} - -/*\internal - Store color values in the given colormap. -*/ -static void qStoreColors(HPALETTE cmap, const QGLColormap & cols) -{ - QRgb color; - PALETTEENTRY pe; - - for (int i = 0; i < cols.size(); i++) { - color = cols.entryRgb(i); - pe.peRed = qRed(color); - pe.peGreen = qGreen(color); - pe.peBlue = qBlue(color); - pe.peFlags = 0; - - SetPaletteEntries(cmap, i, 1, &pe); - } -} - -void QGLWidgetPrivate::updateColormap() -{ - Q_Q(QGLWidget); - if (!cmap.handle()) - return; - HDC hdc = GetDC(q->winId()); - SelectPalette(hdc, (HPALETTE) cmap.handle(), TRUE); - qStoreColors((HPALETTE) cmap.handle(), cmap); - RealizePalette(hdc); - ReleaseDC(q->winId(), hdc); -} - -void QGLWidget::setMouseTracking(bool enable) -{ - QWidget::setMouseTracking(enable); -} - - -void QGLWidget::resizeEvent(QResizeEvent *) -{ - Q_D(QGLWidget); - if (!isValid()) - return; - makeCurrent(); - if (!d->glcx->initialized()) - glInit(); - resizeGL(width(), height()); - if (d->olcx) { - makeOverlayCurrent(); - resizeOverlayGL(width(), height()); - } -} - - -const QGLContext* QGLWidget::overlayContext() const -{ - return d_func()->olcx; -} - - -void QGLWidget::makeOverlayCurrent() -{ - Q_D(QGLWidget); - if (d->olcx) { - d->olcx->makeCurrent(); - if (!d->olcx->initialized()) { - initializeOverlayGL(); - d->olcx->setInitialized(true); - } - } -} - - -void QGLWidget::updateOverlayGL() -{ - Q_D(QGLWidget); - if (d->olcx) { - makeOverlayCurrent(); - paintOverlayGL(); - if (d->olcx->format().doubleBuffer()) { - if (d->autoSwap) - d->olcx->swapBuffers(); - } - else { - glFlush(); - } - } -} - - -void QGLWidget::setContext(QGLContext *context, - const QGLContext* shareContext, - bool deleteOldContext) -{ - Q_D(QGLWidget); - if (context == 0) { - qWarning("QGLWidget::setContext: Cannot set null context"); - return; - } - if (!context->deviceIsPixmap() && context->device() != this) { - qWarning("QGLWidget::setContext: Context must refer to this widget"); - return; - } - - if (d->glcx) - d->glcx->doneCurrent(); - QGLContext* oldcx = d->glcx; - d->glcx = context; - - bool doShow = false; - if (oldcx && oldcx->d_func()->win == winId() && !d->glcx->deviceIsPixmap()) { - // We already have a context and must therefore create a new - // window since Windows does not permit setting a new OpenGL - // context for a window that already has one set. - doShow = isVisible(); - QWidget *pW = static_cast<QWidget *>(parent()); - QPoint pos = geometry().topLeft(); - setParent(pW, windowFlags()); - move(pos); - } - - if (!d->glcx->isValid()) { - bool wasSharing = shareContext || (oldcx && oldcx->isSharing()); - d->glcx->create(shareContext ? shareContext : oldcx); - // the above is a trick to keep disp lists etc when a - // QGLWidget has been reparented, so remove the sharing - // flag if we don't actually have a sharing context. - if (!wasSharing) - d->glcx->d_ptr->sharing = false; - } - - if (deleteOldContext) - delete oldcx; - - if (doShow) - show(); -} - - -bool QGLWidgetPrivate::renderCxPm(QPixmap*) -{ - return false; -} - -void QGLWidgetPrivate::cleanupColormaps() -{ - Q_Q(QGLWidget); - if (cmap.handle()) { - HDC hdc = GetDC(q->winId()); - SelectPalette(hdc, (HPALETTE) GetStockObject(DEFAULT_PALETTE), FALSE); - DeleteObject((HPALETTE) cmap.handle()); - ReleaseDC(q->winId(), hdc); - cmap.setHandle(0); - } - return; -} - -const QGLColormap & QGLWidget::colormap() const -{ - return d_func()->cmap; -} - -void QGLWidget::setColormap(const QGLColormap & c) -{ - Q_D(QGLWidget); - d->cmap = c; - - if (d->cmap.handle()) { // already have an allocated cmap - d->updateColormap(); - } else { - LOGPALETTE *lpal = (LOGPALETTE *) malloc(sizeof(LOGPALETTE) - +c.size()*sizeof(PALETTEENTRY)); - lpal->palVersion = 0x300; - lpal->palNumEntries = c.size(); - d->cmap.setHandle(CreatePalette(lpal)); - free(lpal); - d->updateColormap(); - } -} - -QT_END_NAMESPACE |