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