Warning: That file was not part of the compilation database. It may have many parsing errors.

1/****************************************************************************
2**
3** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4** Contact: http://www.qt-project.org/legal
5**
6** This file is part of the QtOpenGL module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Digia. For licensing terms and
14** conditions see http://qt.digia.com/licensing. For further information
15** use the contact form at http://qt.digia.com/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 2.1 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 2.1 requirements
23** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24**
25** In addition, as a special exception, Digia gives you certain additional
26** rights. These rights are described in the Digia Qt LGPL Exception
27** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28**
29** GNU General Public License Usage
30** Alternatively, this file may be used under the terms of the GNU
31** General Public License version 3.0 as published by the Free Software
32** Foundation and appearing in the file LICENSE.GPL included in the
33** packaging of this file. Please review the following information to
34** ensure the GNU General Public License version 3.0 requirements will be
35** met: http://www.gnu.org/copyleft/gpl.html.
36**
37**
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "qgl.h"
43#include <private/qt_s60_p.h>
44#include <private/qpixmap_raster_symbian_p.h>
45#include <private/qimagepixmapcleanuphooks_p.h>
46#include <private/qgl_p.h>
47#include <private/qpaintengine_opengl_p.h>
48#include <private/qwidget_p.h> // to access QWExtra
49#include <private/qnativeimagehandleprovider_p.h>
50#include <private/qapplication_p.h>
51#include <private/qgraphicssystem_p.h>
52#include <private/qgraphicssystemex_symbian_p.h>
53#include "qgl_egl_p.h"
54#include "qpixmapdata_gl_p.h"
55#include "qgltexturepool_p.h"
56#include "qcolormap.h"
57
58
59QT_BEGIN_NAMESPACE
60
61// Turn off "direct to window" rendering if EGL cannot support it.
62#if !defined(EGL_RENDER_BUFFER) || !defined(EGL_SINGLE_BUFFER)
63#if defined(QGL_DIRECT_TO_WINDOW)
64#undef QGL_DIRECT_TO_WINDOW
65#endif
66#endif
67
68// Determine if preserved window contents should be used.
69#if !defined(EGL_SWAP_BEHAVIOR) || !defined(EGL_BUFFER_PRESERVED)
70#if !defined(QGL_NO_PRESERVED_SWAP)
71#define QGL_NO_PRESERVED_SWAP 1
72#endif
73#endif
74
75Q_OPENGL_EXPORT extern QGLWidget* qt_gl_share_widget();
76
77/*
78 QGLTemporaryContext implementation
79*/
80
81
82class QGLTemporaryContextPrivate
83{
84public:
85 bool initialized;
86 RWindow *window;
87 EGLContext context;
88 EGLSurface surface;
89 EGLDisplay display;
90};
91
92QGLTemporaryContext::QGLTemporaryContext(bool, QWidget *)
93 : d(new QGLTemporaryContextPrivate)
94{
95 d->initialized = false;
96 d->window = 0;
97 d->context = 0;
98 d->surface = 0;
99
100 d->display = d->display = QEgl::display();
101
102 EGLConfig config;
103 int numConfigs = 0;
104 EGLint attribs[] = {
105 EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
106#ifdef QT_OPENGL_ES_2
107 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
108#endif
109 EGL_NONE
110 };
111
112 eglChooseConfig(d->display, attribs, &config, 1, &numConfigs);
113 if (!numConfigs) {
114 qWarning("QGLTemporaryContext: No EGL configurations available.");
115 return;
116 }
117
118 d->window = new RWindow(CCoeEnv::Static()->WsSession());
119 d->window->Construct(CCoeEnv::Static()->RootWin(),(uint)this);
120
121 d->surface = eglCreateWindowSurface(d->display, config, (EGLNativeWindowType) d->window, NULL);
122
123 if (d->surface == EGL_NO_SURFACE) {
124 qWarning("QGLTemporaryContext: Error creating EGL surface.");
125 delete d->window;
126 d->window = 0;
127 return;
128 }
129
130 EGLint contextAttribs[] = {
131#ifdef QT_OPENGL_ES_2
132 EGL_CONTEXT_CLIENT_VERSION, 2,
133#endif
134 EGL_NONE
135 };
136 d->context = eglCreateContext(d->display, config, 0, contextAttribs);
137 if (d->context != EGL_NO_CONTEXT
138 && eglMakeCurrent(d->display, d->surface, d->surface, d->context))
139 {
140 d->initialized = true;
141 } else {
142 qWarning("QGLTemporaryContext: Error creating EGL context.");
143 d->window = 0;
144 return;
145 }
146}
147
148QGLTemporaryContext::~QGLTemporaryContext()
149{
150 if (d->initialized) {
151 eglMakeCurrent(d->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
152 eglDestroyContext(d->display, d->context);
153 eglDestroySurface(d->display, d->surface);
154 delete d->window;
155 }
156}
157
158bool QGLFormat::hasOpenGLOverlays()
159{
160 return false;
161}
162
163// Chooses the EGL config and creates the EGL context
164bool QGLContext::chooseContext(const QGLContext* shareContext) // almost same as in qgl_x11egl.cpp
165{
166 Q_D(QGLContext);
167
168 if (!device())
169 return false;
170
171 int devType = device()->devType();
172
173 if ((devType != QInternal::Widget) && (devType != QInternal::Pbuffer)) {
174 qWarning("WARNING: Creating a QGLContext not supported on device type %d", devType);
175 return false;
176 }
177
178 // Get the display and initialize it.
179 if (d->eglContext == 0) {
180 d->eglContext = new QEglContext();
181 d->ownsEglContext = true;
182 d->eglContext->setApi(QEgl::OpenGL);
183
184 if (d->glFormat.samples() == EGL_DONT_CARE) {
185 // Allow apps to override ability to use multisampling by setting an environment variable. Eg:
186 // qputenv("QT_SYMBIAN_DISABLE_GL_MULTISAMPLE", "1");
187 // Added to allow camera app to start with limited memory.
188 if (!QSymbianGraphicsSystemEx::hasBCM2727() && !qgetenv("QT_SYMBIAN_DISABLE_GL_MULTISAMPLE").toInt()) {
189 // Most likely we have hw support for multisampling
190 // so let's enable it.
191 d->glFormat.setSampleBuffers(1);
192 d->glFormat.setSamples(4);
193 } else {
194 d->glFormat.setSampleBuffers(0);
195 d->glFormat.setSamples(0);
196 }
197 }
198
199 // If the device is a widget with WA_TranslucentBackground set, make sure the glFormat
200 // has the alpha channel option set:
201 if (devType == QInternal::Widget) {
202 QWidget* widget = static_cast<QWidget*>(device());
203 if (widget->testAttribute(Qt::WA_TranslucentBackground))
204 d->glFormat.setAlpha(true);
205 }
206
207 // Construct the configuration we need for this surface.
208 QEglProperties configProps;
209 configProps.setDeviceType(devType);
210 configProps.setPaintDeviceFormat(device());
211 configProps.setRenderableType(QEgl::OpenGL);
212 configProps.setValue(EGL_SURFACE_TYPE, EGL_WINDOW_BIT|EGL_SWAP_BEHAVIOR_PRESERVED_BIT);
213
214 qt_eglproperties_set_glformat(configProps, d->glFormat);
215
216 if (!d->eglContext->chooseConfig(configProps, QEgl::BestPixelFormat)) {
217 delete d->eglContext;
218 d->eglContext = 0;
219 return false;
220 }
221
222 // Create a new context for the configuration.
223 QEglContext* eglSharedContext = shareContext ? shareContext->d_func()->eglContext : 0;
224 if (!d->eglContext->createContext(eglSharedContext)) {
225 delete d->eglContext;
226 d->eglContext = 0;
227 return false;
228 }
229 d->sharing = d->eglContext->isSharing();
230 if (d->sharing && shareContext)
231 const_cast<QGLContext *>(shareContext)->d_func()->sharing = true;
232 }
233
234 // Inform the higher layers about the actual format properties
235 qt_glformat_from_eglconfig(d->glFormat, d->eglContext->config());
236
237 // Do don't create the EGLSurface for everything.
238 // QWidget - yes, create the EGLSurface and store it in QGLContextPrivate::eglSurface
239 // QGLWidget - yes, create the EGLSurface and store it in QGLContextPrivate::eglSurface
240 // QGLPixelBuffer - no, it creates the surface itself and stores it in QGLPixelBufferPrivate::pbuf
241
242 if (devType == QInternal::Widget) {
243 if (d->eglSurface != EGL_NO_SURFACE)
244 eglDestroySurface(d->eglContext->display(), d->eglSurface);
245
246 d->eglSurface = QEgl::createSurface(device(), d->eglContext->config());
247
248 eglGetError(); // Clear error state first.
249
250#ifdef QGL_NO_PRESERVED_SWAP
251 eglSurfaceAttrib(QEgl::display(), d->eglSurface,
252 EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED);
253
254 if (eglGetError() != EGL_SUCCESS)
255 qWarning("QGLContext: could not enable destroyed swap behaviour");
256#else
257 eglSurfaceAttrib(QEgl::display(), d->eglSurface,
258 EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED);
259
260 if (eglGetError() != EGL_SUCCESS)
261 qWarning("QGLContext: could not enable preserved swap behaviour");
262#endif
263
264 setWindowCreated(true);
265 }
266
267 return true;
268}
269
270void QGLWidget::resizeEvent(QResizeEvent *e)
271{
272 Q_D(QGLWidget);
273 if (!isValid())
274 return;
275
276 // Shared widget can ignore resize events which
277 // may happen due to orientation change
278 if (this == qt_gl_share_widget())
279 return;
280
281 if (!d->surfaceSizeInitialized || e->oldSize() != e->size()) {
282 // On Symbian we need to recreate the surface on resize.
283 d->recreateEglSurface();
284 d->surfaceSizeInitialized = true;
285 }
286
287 makeCurrent();
288
289 if (!d->glcx->initialized())
290 glInit();
291
292 resizeGL(width(), height());
293}
294
295const QGLContext* QGLWidget::overlayContext() const
296{
297 return 0;
298}
299
300void QGLWidget::makeOverlayCurrent()
301{
302 //handle overlay
303}
304
305void QGLWidget::updateOverlayGL()
306{
307 //handle overlay
308}
309
310void QGLWidget::setContext(QGLContext *context, const QGLContext* shareContext, bool deleteOldContext)
311{
312 Q_D(QGLWidget);
313 if (context == 0) {
314 qWarning("QGLWidget::setContext: Cannot set null context");
315 return;
316 }
317 if (!context->deviceIsPixmap() && context->device() != this) {
318 qWarning("QGLWidget::setContext: Context must refer to this widget");
319 return;
320 }
321
322 if (d->glcx)
323 d->glcx->doneCurrent();
324 QGLContext* oldcx = d->glcx;
325 d->glcx = context;
326
327 bool createFailed = false;
328 if (!d->glcx->isValid()) {
329 // Create the QGLContext here, which in turn chooses the EGL config
330 // and creates the EGL context:
331 if (!d->glcx->create(shareContext ? shareContext : oldcx))
332 createFailed = true;
333 }
334 if (createFailed) {
335 if (deleteOldContext)
336 delete oldcx;
337 return;
338 }
339
340 d->eglSurfaceWindowId = winId(); // Remember the window id we created the surface for
341}
342
343void QGLWidgetPrivate::init(QGLContext *context, const QGLWidget* shareWidget)
344{
345 Q_Q(QGLWidget);
346
347 initContext(context, shareWidget);
348
349 if(q->isValid() && glcx->format().hasOverlay()) {
350 //no overlay
351 qWarning("QtOpenGL ES doesn't currently support overlays");
352 }
353}
354
355void QGLWidgetPrivate::cleanupColormaps()
356{
357}
358
359const QGLColormap & QGLWidget::colormap() const
360{
361 return d_func()->cmap;
362}
363
364void QGLWidget::setColormap(const QGLColormap &)
365{
366}
367
368void QGLWidgetPrivate::recreateEglSurface()
369{
370 Q_Q(QGLWidget);
371
372 WId currentId = q->winId();
373
374 if (glcx->d_func()->eglSurface != EGL_NO_SURFACE) {
375 if (glcx == QGLContext::currentContext())
376 glcx->doneCurrent();
377
378 eglDestroySurface(glcx->d_func()->eglContext->display(),
379 glcx->d_func()->eglSurface);
380 }
381
382 glcx->d_func()->eglSurface = QEgl::createSurface(glcx->device(),
383 glcx->d_func()->eglContext->config());
384
385#if !defined(QGL_NO_PRESERVED_SWAP)
386 eglGetError(); // Clear error state first.
387 eglSurfaceAttrib(QEgl::display(), glcx->d_func()->eglSurface,
388 EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED);
389 if (eglGetError() != EGL_SUCCESS) {
390 qWarning("QGLContext: could not enable preserved swap");
391 }
392#endif
393
394 eglSurfaceWindowId = currentId;
395}
396
397QT_END_NAMESPACE
398

Warning: That file was not part of the compilation database. It may have many parsing errors.