source: trunk/src/opengl/qwindowsurface_gl.cpp@ 133

Last change on this file since 133 was 2, checked in by Dmitry A. Kuminov, 16 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

File size: 19.4 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: Qt Software Information ([email protected])
5**
6** This file is part of the QtOpenGL module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial Usage
10** Licensees holding valid Qt Commercial licenses may use this file in
11** accordance with the Qt Commercial License Agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Nokia.
14**
15** GNU Lesser General Public License Usage
16** Alternatively, this file may be used under the terms of the GNU Lesser
17** General Public License version 2.1 as published by the Free Software
18** Foundation and appearing in the file LICENSE.LGPL included in the
19** packaging of this file. Please review the following information to
20** ensure the GNU Lesser General Public License version 2.1 requirements
21** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22**
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.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you are unsure which license is appropriate for your use, please
37** contact the sales department at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include <QtGui/QApplication>
43#include <QtGui/QColormap>
44#include <QtGui/QDesktopWidget>
45#include <QtGui/QPaintDevice>
46#include <QtGui/QWidget>
47
48#include <qglframebufferobject.h>
49#include <qglpixelbuffer.h>
50#include <qcolormap.h>
51#include <qdesktopwidget.h>
52#include "qdebug.h"
53
54#ifdef Q_WS_X11
55#include <private/qt_x11_p.h>
56#include <qx11info_x11.h>
57#include <private/qwidget_p.h>
58
59#ifndef QT_OPENGL_ES
60#include <GL/glx.h>
61#include <X11/Xlib.h>
62#endif
63#endif //Q_WS_X11
64
65#include <private/qglextensions_p.h>
66#include <private/qwindowsurface_gl_p.h>
67
68#include <private/qgl_p.h>
69
70#include <private/qglpixelbuffer_p.h>
71#include <private/qgraphicssystem_gl_p.h>
72#include <private/qpaintengine_opengl_p.h>
73
74#ifndef GLX_ARB_multisample
75#define GLX_SAMPLE_BUFFERS_ARB 100000
76#define GLX_SAMPLES_ARB 100001
77#endif
78
79QT_BEGIN_NAMESPACE
80
81//
82// QGLGraphicsSystem
83//
84#ifdef Q_WS_WIN
85Q_GUI_EXPORT bool qt_win_owndc_required;
86#endif
87QGLGraphicsSystem::QGLGraphicsSystem()
88 : QGraphicsSystem()
89{
90#if defined(Q_WS_X11) && !defined(QT_OPENGL_ES)
91 // only override the system defaults if the user hasn't already
92 // picked a visual
93 if (X11->visual == 0 && X11->visual_id == -1 && X11->visual_class == -1) {
94 // find a double buffered, RGBA visual that supports OpenGL
95 // and set that as the default visual for windows in Qt
96 int i = 0;
97 int spec[16];
98 spec[i++] = GLX_RGBA;
99#if 0
100 spec[i++] = GLX_DOUBLEBUFFER;
101 spec[i++] = GLX_DEPTH_SIZE;
102 spec[i++] = 8;
103 spec[i++] = GLX_STENCIL_SIZE;
104 spec[i++] = 8;
105 spec[i++] = GLX_SAMPLE_BUFFERS_ARB;
106 spec[i++] = 1;
107 spec[i++] = GLX_SAMPLES_ARB;
108 spec[i++] = 4;
109#endif
110 spec[i++] = XNone;
111
112 XVisualInfo *vi = glXChooseVisual(X11->display, X11->defaultScreen, spec);
113 if (vi) {
114 X11->visual_id = vi->visualid;
115 X11->visual_class = vi->c_class;
116
117 QGLFormat format;
118 int res;
119 glXGetConfig(X11->display, vi, GLX_LEVEL, &res);
120 format.setPlane(res);
121 glXGetConfig(X11->display, vi, GLX_DOUBLEBUFFER, &res);
122 format.setDoubleBuffer(res);
123 glXGetConfig(X11->display, vi, GLX_DEPTH_SIZE, &res);
124 format.setDepth(res);
125 if (format.depth())
126 format.setDepthBufferSize(res);
127 glXGetConfig(X11->display, vi, GLX_RGBA, &res);
128 format.setRgba(res);
129 glXGetConfig(X11->display, vi, GLX_RED_SIZE, &res);
130 format.setRedBufferSize(res);
131 glXGetConfig(X11->display, vi, GLX_GREEN_SIZE, &res);
132 format.setGreenBufferSize(res);
133 glXGetConfig(X11->display, vi, GLX_BLUE_SIZE, &res);
134 format.setBlueBufferSize(res);
135 glXGetConfig(X11->display, vi, GLX_ALPHA_SIZE, &res);
136 format.setAlpha(res);
137 if (format.alpha())
138 format.setAlphaBufferSize(res);
139 glXGetConfig(X11->display, vi, GLX_ACCUM_RED_SIZE, &res);
140 format.setAccum(res);
141 if (format.accum())
142 format.setAccumBufferSize(res);
143 glXGetConfig(X11->display, vi, GLX_STENCIL_SIZE, &res);
144 format.setStencil(res);
145 if (format.stencil())
146 format.setStencilBufferSize(res);
147 glXGetConfig(X11->display, vi, GLX_STEREO, &res);
148 format.setStereo(res);
149 glXGetConfig(X11->display, vi, GLX_SAMPLE_BUFFERS_ARB, &res);
150 format.setSampleBuffers(res);
151 if (format.sampleBuffers()) {
152 glXGetConfig(X11->display, vi, GLX_SAMPLES_ARB, &res);
153 format.setSamples(res);
154 }
155
156 QGLWindowSurface::surfaceFormat = format;
157 XFree(vi);
158
159 printf("using visual class %x, id %x\n", X11->visual_class, X11->visual_id);
160 }
161 }
162#elif defined(Q_WS_WIN)
163 QGLWindowSurface::surfaceFormat.setDoubleBuffer(false);
164
165 qt_win_owndc_required = true;
166#endif
167}
168
169//
170// QGLWindowSurface
171//
172
173class QGLGlobalShareWidget
174{
175public:
176 QGLGlobalShareWidget() : widget(0) {}
177
178 QGLWidget *shareWidget() {
179 if (!widget && !cleanedUp) {
180 widget = new QGLWidget;
181 }
182 return widget;
183 }
184
185 void cleanup() {
186 delete widget;
187 widget = 0;
188 cleanedUp = true;
189 }
190
191 static bool cleanedUp;
192
193private:
194 QGLWidget *widget;
195};
196
197bool QGLGlobalShareWidget::cleanedUp = false;
198
199static void qt_cleanup_gl_share_widget();
200Q_GLOBAL_STATIC_WITH_INITIALIZER(QGLGlobalShareWidget, _qt_gl_share_widget,
201 {
202 qAddPostRoutine(qt_cleanup_gl_share_widget);
203 })
204
205static void qt_cleanup_gl_share_widget()
206{
207 _qt_gl_share_widget()->cleanup();
208}
209
210QGLWidget* qt_gl_share_widget()
211{
212 if (QGLGlobalShareWidget::cleanedUp)
213 return 0;
214 return _qt_gl_share_widget()->shareWidget();
215}
216
217struct QGLWindowSurfacePrivate
218{