fix remaining includes
[qt:qtbase.git] / src / opengl / qgl_qpa.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 **
7 ** This file is part of the QtOpenGL module of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** No Commercial Usage
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
14 ** this package.
15 **
16 ** GNU Lesser General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU Lesser
18 ** General Public License version 2.1 as published by the Free Software
19 ** Foundation and appearing in the file LICENSE.LGPL included in the
20 ** packaging of this file.  Please review the following information to
21 ** ensure the GNU Lesser General Public License version 2.1 requirements
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23 **
24 ** In addition, as a special exception, Nokia gives you certain additional
25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27 **
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
30 **
31 **
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include <QApplication>
43 #include <private/qapplication_p.h>
44 #include <QPixmap>
45 #include <QDebug>
46
47 #include <private/qapplication_p.h>
48 #include <QtGui/QPlatformGLContext>
49 #include <QtGui/QPlatformWindow>
50 #include <QtGui/QWindowContext>
51
52 #include "qgl.h"
53 #include "qgl_p.h"
54
55 QT_BEGIN_NAMESPACE
56
57 QGLFormat QGLFormat::fromWindowFormat(const QWindowFormat &format)
58 {
59     QGLFormat retFormat;
60     if (format.alphaBufferSize() >= 0)
61         retFormat.setAlphaBufferSize(format.alphaBufferSize());
62     if (format.blueBufferSize() >= 0)
63         retFormat.setBlueBufferSize(format.blueBufferSize());
64     if (format.greenBufferSize() >= 0)
65         retFormat.setGreenBufferSize(format.greenBufferSize());
66     if (format.redBufferSize() >= 0)
67         retFormat.setRedBufferSize(format.redBufferSize());
68     if (format.depthBufferSize() >= 0)
69         retFormat.setDepthBufferSize(format.depthBufferSize());
70     if (format.samples() > 1) {
71         retFormat.setSampleBuffers(format.samples());
72         retFormat.setSamples(true);
73     }
74     if (format.stencilBufferSize() > 0) {
75         retFormat.setStencil(true);
76         retFormat.setStencilBufferSize(format.stencilBufferSize());
77     }
78     retFormat.setDoubleBuffer(format.swapBehavior() != QWindowFormat::SingleBuffer);
79     retFormat.setStereo(format.stereo());
80     return retFormat;
81 }
82
83 QWindowFormat QGLFormat::toWindowFormat(const QGLFormat &format)
84 {
85     QWindowFormat retFormat;
86     if (format.alphaBufferSize() >= 0)
87         retFormat.setAlphaBufferSize(format.alphaBufferSize());
88     if (format.blueBufferSize() >= 0)
89         retFormat.setBlueBufferSize(format.blueBufferSize());
90     if (format.greenBufferSize() >= 0)
91         retFormat.setGreenBufferSize(format.greenBufferSize());
92     if (format.redBufferSize() >= 0)
93         retFormat.setRedBufferSize(format.redBufferSize());
94     if (format.depthBufferSize() >= 0)
95         retFormat.setDepthBufferSize(format.depthBufferSize());
96     retFormat.setSwapBehavior(format.doubleBuffer() ? QWindowFormat::DoubleBuffer : QWindowFormat::DefaultSwapBehavior);
97     if (format.sampleBuffers() && format.samples() > 1)
98         retFormat.setSamples(format.samples());
99     if (format.stencil() && format.stencilBufferSize() > 0)
100         retFormat.setStencilBufferSize(format.stencilBufferSize());
101     retFormat.setStereo(format.stereo());
102     return retFormat;
103 }
104
105 void QGLContextPrivate::setupSharing() {
106     Q_Q(QGLContext);
107     QWindowContext *sharedContext = windowContext->handle()->windowFormat().sharedContext();
108     if (sharedContext) {
109         QGLContext *actualSharedContext = QGLContext::fromWindowContext(sharedContext);
110         sharing = true;
111         QGLContextGroup::addShare(q,actualSharedContext);
112     }
113 }
114
115 bool QGLFormat::hasOpenGL()
116 {
117     return QApplicationPrivate::platformIntegration()
118             ->hasCapability(QPlatformIntegration::OpenGL);
119 }
120
121 void qDeleteQGLContext(void *handle)
122 {
123     QGLContext *context = static_cast<QGLContext *>(handle);
124     delete context;
125 }
126
127 bool QGLContext::chooseContext(const QGLContext* shareContext)
128 {
129     Q_D(QGLContext);
130     if(!d->paintDevice || d->paintDevice->devType() != QInternal::Widget) {
131         d->valid = false;
132     }else {
133         QWidget *widget = static_cast<QWidget *>(d->paintDevice);
134         if (!widget->windowHandle()->handle()) {
135             QGLFormat glformat = format();
136             QWindowFormat winFormat = QGLFormat::toWindowFormat(glformat);
137             if (shareContext) {
138                 winFormat.setSharedContext(shareContext->d_func()->windowContext);
139             }
140             widget->windowHandle()->setSurfaceType(QWindow::OpenGLSurface);
141             winFormat.setWindowSurface(false);
142             widget->windowHandle()->setWindowFormat(winFormat);
143             widget->winId();//make window
144         }
145         d->windowContext = widget->windowHandle()->glContext();
146         Q_ASSERT(d->windowContext);
147         d->glFormat = QGLFormat::fromWindowFormat(d->windowContext->handle()->windowFormat());
148         d->valid =(bool) d->windowContext;
149         if (d->valid) {
150             d->windowContext->setQGLContextHandle(this,qDeleteQGLContext);
151         }
152         d->setupSharing();
153     }
154
155
156     return d->valid;
157 }
158
159 void QGLContext::reset()
160 {
161     Q_D(QGLContext);
162     if (!d->valid)
163         return;
164     d->cleanup();
165
166     d->crWin = false;
167     d->sharing = false;
168     d->valid = false;
169     d->transpColor = QColor();
170     d->initDone = false;
171     QGLContextGroup::removeShare(this);
172     if (d->windowContext) {
173         d->windowContext->setQGLContextHandle(0,0);
174     }
175 }
176
177 void QGLContext::makeCurrent()
178 {
179     Q_D(QGLContext);
180     d->windowContext->makeCurrent();
181
182     if (!d->workaroundsCached) {
183         d->workaroundsCached = true;
184         const char *renderer = reinterpret_cast<const char *>(glGetString(GL_RENDERER));
185         if (renderer && strstr(renderer, "Mali")) {
186             d->workaround_brokenFBOReadBack = true;
187         }
188     }
189
190 }
191
192 void QGLContext::doneCurrent()
193 {
194     Q_D(QGLContext);
195     d->windowContext->doneCurrent();
196 }
197
198 void QGLContext::swapBuffers() const
199 {
200     Q_D(const QGLContext);
201     d->windowContext->swapBuffers();
202 }
203
204 void *QGLContext::getProcAddress(const QString &procName) const
205 {
206     Q_D(const QGLContext);
207     return (void *)d->windowContext->getProcAddress(procName.toAscii());
208 }
209
210 void QGLWidget::setContext(QGLContext *context,
211                             const QGLContext* shareContext,
212                             bool deleteOldContext)
213 {
214     Q_D(QGLWidget);
215     if (context == 0) {
216         qWarning("QGLWidget::setContext: Cannot set null context");
217         return;
218     }
219
220     if (context->device() == 0) // a context may refere to more than 1 window.
221         context->setDevice(this); //but its better to point to 1 of them than none of them.
222
223     QGLContext* oldcx = d->glcx;
224     d->glcx = context;
225
226     if (!d->glcx->isValid())
227         d->glcx->create(shareContext ? shareContext : oldcx);
228
229     if (deleteOldContext)
230         delete oldcx;
231 }
232
233 void QGLWidgetPrivate::init(QGLContext *context, const QGLWidget *shareWidget)
234 {
235     initContext(context, shareWidget);
236 }
237
238 bool QGLFormat::hasOpenGLOverlays()
239 {
240     return false;
241 }
242
243 QColor QGLContext::overlayTransparentColor() const
244 {
245     return QColor(); // Invalid color
246 }
247
248 uint QGLContext::colorIndex(const QColor&) const
249 {
250     return 0;
251 }
252
253 void QGLContext::generateFontDisplayLists(const QFont & fnt, int listBase)
254 {
255     Q_UNUSED(fnt);
256     Q_UNUSED(listBase);
257 }
258
259 /*
260     QGLTemporaryContext implementation
261 */
262 class QGLTemporaryContextPrivate
263 {
264 public:
265     QWindow *window;
266     QWindowContext *context;
267 };
268
269 QGLTemporaryContext::QGLTemporaryContext(bool, QWidget *)
270     : d(new QGLTemporaryContextPrivate)
271 {
272     d->context = const_cast<QWindowContext *>(QWindowContext::currentContext());
273     if (d->context)
274         d->context->doneCurrent();
275
276     d->window = new QWindow;
277     d->window->setGeometry(QRect(0, 0, 3, 3));
278     d->window->setSurfaceType(QWindow::OpenGLSurface);
279     d->window->create();
280
281     d->window->glContext()->makeCurrent();
282 }
283
284 QGLTemporaryContext::~QGLTemporaryContext()
285 {
286     if (d->context)
287         d->context->makeCurrent();
288     else
289         d->window->glContext()->doneCurrent();
290     delete d->window;
291 }
292
293
294 bool QGLWidgetPrivate::renderCxPm(QPixmap*)
295 {
296     return false;
297 }
298
299 /*! \internal
300   Free up any allocated colormaps. This fn is only called for
301   top-level widgets.
302 */
303 void QGLWidgetPrivate::cleanupColormaps()
304 {
305 }
306
307 void QGLWidget::setMouseTracking(bool enable)
308 {
309     Q_UNUSED(enable);
310 }
311
312 bool QGLWidget::event(QEvent *e)
313 {
314     return QWidget::event(e);
315 }
316
317 void QGLWidget::resizeEvent(QResizeEvent *e)
318 {
319     Q_D(QGLWidget);
320
321     QWidget::resizeEvent(e);
322     if (!isValid())
323         return;
324     makeCurrent();
325     if (!d->glcx->initialized())
326         glInit();
327     resizeGL(width(), height());
328 }
329
330
331 const QGLContext* QGLWidget::overlayContext() const
332 {
333     return 0;
334 }
335
336 void QGLWidget::makeOverlayCurrent()
337 {
338 }
339
340
341 void QGLWidget::updateOverlayGL()
342 {
343 }
344
345 const QGLColormap & QGLWidget::colormap() const
346 {
347     Q_D(const QGLWidget);
348     return d->cmap;
349 }
350
351 void QGLWidget::setColormap(const QGLColormap & c)
352 {
353     Q_UNUSED(c);
354 }
355
356 QGLContext::QGLContext(QWindowContext *windowContext)
357     : d_ptr(new QGLContextPrivate(this))
358 {
359     Q_D(QGLContext);
360     d->init(0,QGLFormat::fromWindowFormat(windowContext->handle()->windowFormat()));
361     d->windowContext = windowContext;
362     d->windowContext->setQGLContextHandle(this,qDeleteQGLContext);
363     d->valid = true;
364     d->setupSharing();
365 }
366
367 QGLContext *QGLContext::fromWindowContext(QWindowContext *windowContext)
368 {
369     if (!windowContext)
370         return 0;
371     if (windowContext->qGLContextHandle()) {
372         return reinterpret_cast<QGLContext *>(windowContext->qGLContextHandle());
373     }
374     QGLContext *glContext = new QGLContext(windowContext);
375     //Dont call create on context. This can cause the platformFormat to be set on the widget, which
376     //will cause the platformWindow to be recreated.
377     return glContext;
378 }
379
380 QT_END_NAMESPACE