source: trunk/src/opengl/qgl_x11egl.cpp@ 385

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

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

File size: 9.8 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 "qgl.h"
43#include <private/qt_x11_p.h>
44#include <private/qgl_p.h>
45#include <private/qpaintengine_opengl_p.h>
46#include "qgl_egl_p.h"
47#include "qcolormap.h"
48
49
50QT_BEGIN_NAMESPACE
51
52
53bool QGLFormat::hasOpenGL()
54{
55 return true;
56}
57
58bool QGLFormat::hasOpenGLOverlays()
59{
60 return false;
61}
62
63void qt_egl_add_platform_config(QEglProperties& props, QPaintDevice *device)
64{
65 if (device->devType() == QInternal::Image)
66 props.setPixelFormat(static_cast<QImage *>(device)->format());
67}
68
69bool QGLContext::chooseContext(const QGLContext* shareContext)
70{
71 Q_D(QGLContext);
72
73 if (!device())
74 return false;
75
76 int devType = device()->devType();
77
78 // Get the display and initialize it.
79 d->eglContext = new QEglContext();
80 d->eglContext->setApi(QEglContext::OpenGL);
81 if (!d->eglContext->openDisplay(device())) {
82 delete d->eglContext;
83 d->eglContext = 0;
84 return false;
85 }
86
87 // Construct the configuration we need for this surface.
88 QEglProperties configProps;
89 qt_egl_set_format(configProps, devType, d->glFormat);
90 qt_egl_add_platform_config(configProps, device());
91 configProps.setRenderableType(QEglContext::OpenGL);
92
93 // Search for a matching configuration, reducing the complexity
94 // each time until we get something that matches.
95 if (!d->eglContext->chooseConfig(configProps, QEglContext::BestPixelFormat)) {
96 delete d->eglContext;
97 d->eglContext = 0;
98 return false;
99 }
100
101 // Inform the higher layers about the actual format properties.
102 qt_egl_update_format(*(d->eglContext), d->glFormat);
103
104 // Create a new context for the configuration.
105 if (!d->eglContext->createContext
106 (shareContext ? shareContext->d_func()->eglContext : 0)) {
107 delete d->eglContext;
108 d->eglContext = 0;
109 return false;
110 }
111
112#if defined(EGL_VERSION_1_1)
113 if (d->glFormat.swapInterval() != -1 && devType == QInternal::Widget)
114 eglSwapInterval(d->eglContext->display(), d->glFormat.swapInterval());
115#endif
116
117 // Create the EGL surface to draw into.
118 if (!d->eglContext->createSurface(device())) {
119 delete d->eglContext;
120 d->eglContext = 0;
121 return false;
122 }
123
124 return true;
125}
126
127
128void QGLContext::reset()
129{
130 Q_D(QGLContext);
131 if (!d->valid)
132 return;
133 d->cleanup();
134 doneCurrent();
135 if (d->eglContext) {
136 delete d->eglContext;
137 d->eglContext = 0;
138 }
139 d->crWin = false;
140 d->sharing = false;
141 d->valid = false;
142 d->transpColor = QColor();
143 d->initDone = false;
144 qgl_share_reg()->removeShare(this);
145}
146
147void QGLContext::makeCurrent()
148{
149 Q_D(QGLContext);
150 if(!d->valid || !d->eglContext) {
151 qWarning("QGLContext::makeCurrent(): Cannot make invalid context current");
152 return;
153 }
154
155 if (d->eglContext->makeCurrent()) {
156 if (!qgl_context_storage.hasLocalData() && QThread::currentThread())
157 qgl_context_storage.setLocalData(new QGLThreadContext);
158 if (qgl_context_storage.hasLocalData())
159 qgl_context_storage.localData()->context = this;
160 currentCtx = this;
161 }
162}
163
164void QGLContext::doneCurrent()
165{
166 Q_D(QGLContext);
167 if (d->eglContext)
168 d->eglContext->doneCurrent();
169
170 if (qgl_context_storage.hasLocalData())
171 qgl_context_storage.localData()->context = 0;
172 currentCtx = 0;
173}
174
175
176void QGLContext::swapBuffers() const
177{
178 Q_D(const QGLContext);
179 if(!d->valid || !d->eglContext)
180 return;
181
182 d->eglContext->swapBuffers();
183}
184
185QColor QGLContext::overlayTransparentColor() const
186{
187 return QColor(0, 0, 0); // Invalid color
188}
189
190uint QGLContext::colorIndex(const QColor &c) const
191{
192 //### color index doesn't work on egl
193 Q_UNUSED(c);
194 return 0;
195}
196
197void QGLContext::generateFontDisplayLists(const QFont & fnt, int listBase)
198{
199 Q_UNUSED(fnt);
200 Q_UNUSED(listBase);
201}
202
203void *QGLContext::getProcAddress(const QString &proc) const
204{
205 return (void*)eglGetProcAddress(reinterpret_cast<const char *>(proc.toLatin1().data()));
206}
207
208void QGLWidget::setMouseTracking(bool enable)
209{
210 QWidget::setMouseTracking(enable);
211}
212
213
214void QGLWidget::resizeEvent(QResizeEvent *)
215{
216 Q_D(QGLWidget);
217 if (!isValid())
218 return;
219 makeCurrent();
220 if (!d->glcx->initialized())
221 glInit();
222 resizeGL(width(), height());
223 //handle overlay
224}
225
226const QGLContext* QGLWidget::overlayContext() const
227{
228 return 0;
229}
230
231void QGLWidget::makeOverlayCurrent()
232{
233 //handle overlay
234}
235
236void QGLWidget::updateOverlayGL()
237{
238 //handle overlay
239}
240
241void QGLWidget::setContext(QGLContext *context, const QGLContext* shareContext, bool deleteOldContext)
242{
243 Q_D(QGLWidget);
244 if (context == 0) {
245 qWarning("QGLWidget::setContext: Cannot set null context");
246 return;
247 }
248 if (!context->deviceIsPixmap() && context->device() != this) {
249 qWarning("QGLWidget::setContext: Context must refer to this widget");
250 return;
251 }
252
253 if (d->glcx)
254 d->glcx->doneCurrent();
255 QGLContext* oldcx = d->glcx;
256 d->glcx = context;
257
258 if (parentWidget()) {
259 // force creation of delay-created widgets
260 parentWidget()->winId();
261 if (parentWidget()->x11Info().screen() != x11Info().screen())
262 d_func()->xinfo = parentWidget()->d_func()->xinfo;
263 }
264
265 bool visible = isVisible();
266 if (visible)
267 hide();
268
269 XVisualInfo vi;
270
271 int err = XMatchVisualInfo(x11Info().display(), x11Info().screen(), x11Info().depth(), TrueColor, &vi);
272 if (err == 0) {
273 qWarning("Error: Couldn't get a matching X visual for format");
274 return;
275 }
276
277 XSetWindowAttributes a;
278
279 Window p = RootWindow(X11->display, vi.screen);
280 if (parentWidget())
281 p = parentWidget()->winId();
282
283 QColormap colmap = QColormap::instance(vi.screen);
284 a.background_pixel = colmap.pixel(palette().color(backgroundRole()));
285 a.border_pixel = colmap.pixel(Qt::black);
286
287 Window w = XCreateWindow(X11->display, p, x(), y(), width(), height(),
288 0, vi.depth, InputOutput, vi.visual,
289 CWBackPixel|CWBorderPixel, &a);
290
291 if (deleteOldContext)
292 delete oldcx;
293 oldcx = 0;
294
295 create(w); // Create with the ID of the window we've just created
296
297 d->eglSurfaceWindowId = w; // Remember the window id we created the surface for
298
299 if (visible)
300 show();
301
302 bool createFailed = false;
303 if (!d->glcx->isValid()) {
304 if (!d->glcx->create(shareContext ? shareContext : oldcx))
305 createFailed = true;
306 }
307 if (createFailed) {
308 if (deleteOldContext)
309 delete oldcx;
310 return;
311 }
312
313 if (d->glcx->windowCreated() || d->glcx->deviceIsPixmap()) {
314 if (deleteOldContext)
315 delete oldcx;
316 return;
317 }
318
319 d->glcx->setWindowCreated(true);
320}
321
322void QGLWidgetPrivate::init(QGLContext *context, const QGLWidget* shareWidget)
323{
324 Q_Q(QGLWidget);
325
326 initContext(context, shareWidget);
327
328 if(q->isValid() && glcx->format().hasOverlay()) {
329 //no overlay
330 qWarning("QtOpenGL ES doesn't currently support overlays");
331 }
332}
333
334bool QGLWidgetPrivate::renderCxPm(QPixmap*)
335{
336 return false;
337}
338
339void QGLWidgetPrivate::cleanupColormaps()
340{
341}
342
343const QGLColormap & QGLWidget::colormap() const
344{
345 return d_func()->cmap;
346}
347
348void QGLWidget::setColormap(const QGLColormap &)
349{
350}
351
352void QGLExtensions::init()
353{
354 static bool init_done = false;
355
356 if (init_done)
357 return;
358 init_done = true;
359 init_extensions();
360}
361
362// Re-creates the EGL surface if the window ID has changed or if force is true
363void QGLWidgetPrivate::recreateEglSurface(bool force)
364{
365 Q_Q(QGLWidget);
366
367 Window currentId = q->winId();
368
369 if ( force || (currentId != eglSurfaceWindowId) ) {
370 // The window id has changed so we need to re-create the EGL surface
371 if (!glcx->d_func()->eglContext->recreateSurface(q))
372 qWarning("Error creating EGL window surface: 0x%x", eglGetError());
373
374 eglSurfaceWindowId = currentId;
375 }
376}
377
378QT_END_NAMESPACE
Note: See TracBrowser for help on using the repository browser.