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 "qgl_egl_p.h" |
44 | #include "qglpixelbuffer.h" |
45 | |
46 | #include <qglscreen_qws.h> |
47 | #include <qscreenproxy_qws.h> |
48 | #include <private/qglwindowsurface_qws_p.h> |
49 | |
50 | #include <private/qbackingstore_p.h> |
51 | #include <private/qfont_p.h> |
52 | #include <private/qfontengine_p.h> |
53 | #include <private/qgl_p.h> |
54 | #include <private/qpaintengine_opengl_p.h> |
55 | #include <qpixmap.h> |
56 | #include <qtimer.h> |
57 | #include <qapplication.h> |
58 | #include <qstack.h> |
59 | #include <qdesktopwidget.h> |
60 | #include <qdebug.h> |
61 | #include <qvarlengtharray.h> |
62 | |
63 | QT_BEGIN_NAMESPACE |
64 | |
65 | static QGLScreen *glScreenForDevice(QPaintDevice *device) |
66 | { |
67 | QScreen *screen = qt_screen; |
68 | if (screen->classId() == QScreen::MultiClass) { |
69 | int screenNumber; |
70 | if (device && device->devType() == QInternal::Widget) |
71 | screenNumber = qApp->desktop()->screenNumber(static_cast<QWidget *>(device)); |
72 | else |
73 | screenNumber = 0; |
74 | screen = screen->subScreens()[screenNumber]; |
75 | } |
76 | while (screen->classId() == QScreen::ProxyClass || |
77 | screen->classId() == QScreen::TransformedClass) { |
78 | screen = static_cast<QProxyScreen *>(screen)->screen(); |
79 | } |
80 | if (screen->classId() == QScreen::GLClass) |
81 | return static_cast<QGLScreen *>(screen); |
82 | else |
83 | return 0; |
84 | } |
85 | |
86 | /* |
87 | QGLTemporaryContext implementation |
88 | */ |
89 | |
90 | class QGLTemporaryContextPrivate |
91 | { |
92 | public: |
93 | QGLWidget *widget; |
94 | }; |
95 | |
96 | QGLTemporaryContext::QGLTemporaryContext(bool, QWidget *) |
97 | : d(new QGLTemporaryContextPrivate) |
98 | { |
99 | d->widget = new QGLWidget; |
100 | d->widget->makeCurrent(); |
101 | } |
102 | |
103 | QGLTemporaryContext::~QGLTemporaryContext() |
104 | { |
105 | delete d->widget; |
106 | } |
107 | |
108 | /***************************************************************************** |
109 | QOpenGL debug facilities |
110 | *****************************************************************************/ |
111 | //#define DEBUG_OPENGL_REGION_UPDATE |
112 | |
113 | bool QGLFormat::hasOpenGLOverlays() |
114 | { |
115 | QGLScreen *glScreen = glScreenForDevice(0); |
116 | if (glScreen) |
117 | return (glScreen->options() & QGLScreen::Overlays); |
118 | else |
119 | return false; |
120 | } |
121 | |
122 | static EGLSurface qt_egl_create_surface |
123 | (QEglContext *context, QPaintDevice *device, |
124 | const QEglProperties *properties = 0) |
125 | { |
126 | // Get the screen surface functions, which are used to create native ids. |
127 | QGLScreen *glScreen = glScreenForDevice(device); |
128 | if (!glScreen) |
129 | return EGL_NO_SURFACE; |
130 | QGLScreenSurfaceFunctions *funcs = glScreen->surfaceFunctions(); |
131 | if (!funcs) |
132 | return EGL_NO_SURFACE; |
133 | |
134 | // Create the native drawable for the paint device. |
135 | int devType = device->devType(); |
136 | EGLNativePixmapType pixmapDrawable = 0; |
137 | EGLNativeWindowType windowDrawable = 0; |
138 | bool ok; |
139 | if (devType == QInternal::Pixmap) { |
140 | ok = funcs->createNativePixmap(static_cast<QPixmap *>(device), &pixmapDrawable); |
141 | } else if (devType == QInternal::Image) { |
142 | ok = funcs->createNativeImage(static_cast<QImage *>(device), &pixmapDrawable); |
143 | } else { |
144 | ok = funcs->createNativeWindow(static_cast<QWidget *>(device), &windowDrawable); |
145 | } |
146 | if (!ok) { |
147 | qWarning("QEglContext::createSurface(): Cannot create the native EGL drawable"); |
148 | return EGL_NO_SURFACE; |
149 | } |
150 | |
151 | // Create the EGL surface to draw into, based on the native drawable. |
152 | const EGLint *props; |
153 | if (properties) |
154 | props = properties->properties(); |
155 | else |
156 | props = 0; |
157 | EGLSurface surf; |
158 | if (devType == QInternal::Widget) { |
159 | surf = eglCreateWindowSurface |
160 | (context->display(), context->config(), windowDrawable, props); |
161 | } else { |
162 | surf = eglCreatePixmapSurface |
163 | (context->display(), context->config(), pixmapDrawable, props); |
164 | } |
165 | if (surf == EGL_NO_SURFACE) |
166 | qWarning("QEglContext::createSurface(): Unable to create EGL surface, error = 0x%x", eglGetError()); |
167 | return surf; |
168 | } |
169 | |
170 | bool QGLContext::chooseContext(const QGLContext* shareContext) |
171 | { |
172 | Q_D(QGLContext); |
173 | |
174 | // Validate the device. |
175 | if (!device()) |
176 | return false; |
177 | int devType = device()->devType(); |
178 | if (devType != QInternal::Pixmap && devType != QInternal::Image && devType != QInternal::Widget) { |
179 | qWarning("QGLContext::chooseContext(): Cannot create QGLContext's for paint device type %d", devType); |
180 | return false; |
181 | } |
182 | |
183 | // Get the display and initialize it. |
184 | d->eglContext = new QEglContext(); |
185 | d->ownsEglContext = true; |
186 | d->eglContext->setApi(QEgl::OpenGL); |
187 | |
188 | // Construct the configuration we need for this surface. |
189 | QEglProperties configProps; |
190 | qt_eglproperties_set_glformat(configProps, d->glFormat); |
191 | configProps.setDeviceType(devType); |
192 | configProps.setPaintDeviceFormat(device()); |
193 | configProps.setRenderableType(QEgl::OpenGL); |
194 | |
195 | // Search for a matching configuration, reducing the complexity |
196 | // each time until we get something that matches. |
197 | if (!d->eglContext->chooseConfig(configProps)) { |
198 | delete d->eglContext; |
199 | d->eglContext = 0; |
200 | return false; |
201 | } |
202 | |
203 | // Inform the higher layers about the actual format properties. |
204 | qt_glformat_from_eglconfig(d->glFormat, d->eglContext->config()); |
205 | |
206 | // Create a new context for the configuration. |
207 | if (!d->eglContext->createContext |
208 | (shareContext ? shareContext->d_func()->eglContext : 0)) { |
209 | delete d->eglContext; |
210 | d->eglContext = 0; |
211 | return false; |
212 | } |
213 | d->sharing = d->eglContext->isSharing(); |
214 | if (d->sharing && shareContext) |
215 | const_cast<QGLContext *>(shareContext)->d_func()->sharing = true; |
216 | |
217 | #if defined(EGL_VERSION_1_1) |
218 | if (d->glFormat.swapInterval() != -1 && devType == QInternal::Widget) |
219 | eglSwapInterval(d->eglContext->display(), d->glFormat.swapInterval()); |
220 | #endif |
221 | |
222 | // Create the EGL surface to draw into. We cannot use |
223 | // QEglContext::createSurface() because it does not have |
224 | // access to the QGLScreen. |
225 | d->eglSurface = qt_egl_create_surface(d->eglContext, device()); |
226 | if (d->eglSurface == EGL_NO_SURFACE) { |
227 | delete d->eglContext; |
228 | d->eglContext = 0; |
229 | return false; |
230 | } |
231 | |
232 | return true; |
233 | } |
234 | |
235 | |
236 | bool QGLWidget::event(QEvent *e) |
237 | { |
238 | return QWidget::event(e); |
239 | } |
240 | |
241 | |
242 | void QGLWidget::resizeEvent(QResizeEvent *) |
243 | { |
244 | Q_D(QGLWidget); |
245 | if (!isValid()) |
246 | return; |
247 | makeCurrent(); |
248 | if (!d->glcx->initialized()) |
249 | glInit(); |
250 | resizeGL(width(), height()); |
251 | //handle overlay |
252 | } |
253 | |
254 | const QGLContext* QGLWidget::overlayContext() const |
255 | { |
256 | return 0; |
257 | } |
258 | |
259 | void QGLWidget::makeOverlayCurrent() |
260 | { |
261 | //handle overlay |
262 | } |
263 | |
264 | void QGLWidget::updateOverlayGL() |
265 | { |
266 | //handle overlay |
267 | } |
268 | |
269 | void QGLWidget::setContext(QGLContext *context, const QGLContext* shareContext, bool deleteOldContext) |
270 | { |
271 | Q_D(QGLWidget); |
272 | if(context == 0) { |
273 | qWarning("QGLWidget::setContext: Cannot set null context"); |
274 | return; |
275 | } |
276 | |
277 | if(d->glcx) |
278 | d->glcx->doneCurrent(); |
279 | QGLContext* oldcx = d->glcx; |
280 | d->glcx = context; |
281 | if(!d->glcx->isValid()) |
282 | d->glcx->create(shareContext ? shareContext : oldcx); |
283 | if(deleteOldContext) |
284 | delete oldcx; |
285 | } |
286 | |
287 | void QGLWidgetPrivate::init(QGLContext *context, const QGLWidget* shareWidget) |
288 | { |
289 | Q_Q(QGLWidget); |
290 | |
291 | QGLScreen *glScreen = glScreenForDevice(q); |
292 | if (glScreen) { |
293 | wsurf = static_cast<QWSGLWindowSurface*>(glScreen->createSurface(q)); |
294 | q->setWindowSurface(wsurf); |
295 | } |
296 | |
297 | initContext(context, shareWidget); |
298 | |
299 | if(q->isValid() && glcx->format().hasOverlay()) { |
300 | //no overlay |
301 | qWarning("QtOpenGL ES doesn't currently support overlays"); |
302 | } |
303 | } |
304 | |
305 | void QGLWidgetPrivate::cleanupColormaps() |
306 | { |
307 | } |
308 | |
309 | const QGLColormap & QGLWidget::colormap() const |
310 | { |
311 | return d_func()->cmap; |
312 | } |
313 | |
314 | void QGLWidget::setColormap(const QGLColormap &) |
315 | { |
316 | } |
317 | |
318 | QT_END_NAMESPACE |
319 |
Warning: That file was not part of the compilation database. It may have many parsing errors.