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_x11_p.h> |
44 | #include <private/qpixmap_x11_p.h> |
45 | #include <private/qgl_p.h> |
46 | #include <private/qpaintengine_opengl_p.h> |
47 | #include "qgl_egl_p.h" |
48 | #include "qcolormap.h" |
49 | #include <QDebug> |
50 | #include <QPixmap> |
51 | |
52 | |
53 | QT_BEGIN_NAMESPACE |
54 | |
55 | |
56 | /* |
57 | QGLTemporaryContext implementation |
58 | */ |
59 | |
60 | class QGLTemporaryContextPrivate |
61 | { |
62 | public: |
63 | bool initialized; |
64 | Window window; |
65 | EGLContext context; |
66 | EGLSurface surface; |
67 | EGLDisplay display; |
68 | }; |
69 | |
70 | QGLTemporaryContext::QGLTemporaryContext(bool, QWidget *) |
71 | : d(new QGLTemporaryContextPrivate) |
72 | { |
73 | d->initialized = false; |
74 | d->window = 0; |
75 | d->context = 0; |
76 | d->surface = 0; |
77 | int screen = 0; |
78 | |
79 | d->display = QEgl::display(); |
80 | |
81 | EGLConfig config; |
82 | int numConfigs = 0; |
83 | EGLint attribs[] = { |
84 | EGL_SURFACE_TYPE, EGL_WINDOW_BIT, |
85 | #ifdef QT_OPENGL_ES_2 |
86 | EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, |
87 | #endif |
88 | EGL_NONE |
89 | }; |
90 | |
91 | eglChooseConfig(d->display, attribs, &config, 1, &numConfigs); |
92 | if (!numConfigs) { |
93 | qWarning("QGLTemporaryContext: No EGL configurations available."); |
94 | return; |
95 | } |
96 | |
97 | XVisualInfo visualInfo; |
98 | XVisualInfo *vi; |
99 | int numVisuals; |
100 | |
101 | visualInfo.visualid = QEgl::getCompatibleVisualId(config); |
102 | vi = XGetVisualInfo(X11->display, VisualIDMask, &visualInfo, &numVisuals); |
103 | if (!vi || numVisuals < 1) { |
104 | qWarning("QGLTemporaryContext: Unable to get X11 visual info id."); |
105 | return; |
106 | } |
107 | |
108 | XSetWindowAttributes attr; |
109 | unsigned long mask; |
110 | attr.background_pixel = 0; |
111 | attr.border_pixel = 0; |
112 | attr.colormap = XCreateColormap(X11->display, DefaultRootWindow(X11->display), vi->visual, AllocNone); |
113 | attr.event_mask = StructureNotifyMask | ExposureMask; |
114 | mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; |
115 | |
116 | d->window = XCreateWindow(X11->display, RootWindow(X11->display, screen), |
117 | 0, 0, 1, 1, 0, |
118 | vi->depth, InputOutput, vi->visual, |
119 | mask, &attr); |
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 | XFree(vi); |
126 | XDestroyWindow(X11->display, d->window); |
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 | eglDestroySurface(d->display, d->surface); |
144 | XDestroyWindow(X11->display, d->window); |
145 | } |
146 | XFree(vi); |
147 | } |
148 | |
149 | QGLTemporaryContext::~QGLTemporaryContext() |
150 | { |
151 | if (d->initialized) { |
152 | eglMakeCurrent(d->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); |
153 | eglDestroyContext(d->display, d->context); |
154 | eglDestroySurface(d->display, d->surface); |
155 | XDestroyWindow(X11->display, d->window); |
156 | } |
157 | } |
158 | |
159 | bool QGLFormat::hasOpenGLOverlays() |
160 | { |
161 | return false; |
162 | } |
163 | |
164 | // Chooses the EGL config and creates the EGL context |
165 | bool QGLContext::chooseContext(const QGLContext* shareContext) |
166 | { |
167 | Q_D(QGLContext); |
168 | |
169 | if (!device()) |
170 | return false; |
171 | |
172 | int devType = device()->devType(); |
173 | |
174 | QX11PixmapData *x11PixmapData = 0; |
175 | if (devType == QInternal::Pixmap) { |
176 | QPixmapData *pmd = static_cast<QPixmap*>(device())->data_ptr().data(); |
177 | if (pmd->classId() == QPixmapData::X11Class) |
178 | x11PixmapData = static_cast<QX11PixmapData*>(pmd); |
179 | else { |
180 | // TODO: Replace the pixmap's data with a new QX11PixmapData |
181 | qWarning("WARNING: Creating a QGLContext on a QPixmap is only supported for X11 pixmap backend"); |
182 | return false; |
183 | } |
184 | } else if ((devType != QInternal::Widget) && (devType != QInternal::Pbuffer)) { |
185 | qWarning("WARNING: Creating a QGLContext not supported on device type %d", devType); |
186 | return false; |
187 | } |
188 | |
189 | // Only create the eglContext if we don't already have one: |
190 | if (d->eglContext == 0) { |
191 | d->eglContext = new QEglContext(); |
192 | d->ownsEglContext = true; |
193 | d->eglContext->setApi(QEgl::OpenGL); |
194 | |
195 | // If the device is a widget with WA_TranslucentBackground set, make sure the glFormat |
196 | // has the alpha channel option set: |
197 | if (devType == QInternal::Widget) { |
198 | QWidget* widget = static_cast<QWidget*>(device()); |
199 | if (widget->testAttribute(Qt::WA_TranslucentBackground)) |
200 | d->glFormat.setAlpha(true); |
201 | } |
202 | |
203 | // Construct the configuration we need for this surface. |
204 | QEglProperties configProps; |
205 | configProps.setDeviceType(devType); |
206 | configProps.setRenderableType(QEgl::OpenGL); |
207 | qt_eglproperties_set_glformat(configProps, d->glFormat); |
208 | |
209 | // Set buffer preserved for regular QWidgets, QGLWidgets are ok with either preserved or destroyed: |
210 | if ((devType == QInternal::Widget) && qobject_cast<QGLWidget*>(static_cast<QWidget*>(device())) == 0) |
211 | configProps.setValue(EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED); |
212 | |
213 | if (!d->eglContext->chooseConfig(configProps, QEgl::BestPixelFormat)) { |
214 | delete d->eglContext; |
215 | d->eglContext = 0; |
216 | return false; |
217 | } |
218 | |
219 | // Create a new context for the configuration. |
220 | QEglContext* eglSharedContext = shareContext ? shareContext->d_func()->eglContext : 0; |
221 | if (!d->eglContext->createContext(eglSharedContext)) { |
222 | delete d->eglContext; |
223 | d->eglContext = 0; |
224 | return false; |
225 | } |
226 | d->sharing = d->eglContext->isSharing(); |
227 | if (d->sharing && shareContext) |
228 | const_cast<QGLContext *>(shareContext)->d_func()->sharing = true; |
229 | } |
230 | |
231 | // Inform the higher layers about the actual format properties |
232 | qt_glformat_from_eglconfig(d->glFormat, d->eglContext->config()); |
233 | |
234 | // Do don't create the EGLSurface for everything. |
235 | // QWidget - yes, create the EGLSurface and store it in QGLContextPrivate::eglSurface |
236 | // QGLWidget - yes, create the EGLSurface and store it in QGLContextPrivate::eglSurface |
237 | // QPixmap - yes, create the EGLSurface but store it in QX11PixmapData::gl_surface |
238 | // QGLPixelBuffer - no, it creates the surface itself and stores it in QGLPixelBufferPrivate::pbuf |
239 | |
240 | if (devType == QInternal::Widget) { |
241 | if (d->eglSurface != EGL_NO_SURFACE) |
242 | eglDestroySurface(d->eglContext->display(), d->eglSurface); |
243 | // extraWindowSurfaceCreationProps default to NULL unless were specifically set before |
244 | d->eglSurface = QEgl::createSurface(device(), d->eglContext->config(), d->extraWindowSurfaceCreationProps); |
245 | XFlush(X11->display); |
246 | setWindowCreated(true); |
247 | } |
248 | |
249 | if (x11PixmapData) { |
250 | // TODO: Actually check to see if the existing surface can be re-used |
251 | if (x11PixmapData->gl_surface) |
252 | eglDestroySurface(d->eglContext->display(), (EGLSurface)x11PixmapData->gl_surface); |
253 | |
254 | x11PixmapData->gl_surface = (void*)QEgl::createSurface(device(), d->eglContext->config()); |
255 | } |
256 | |
257 | return true; |
258 | } |
259 | |
260 | void *QGLContext::chooseVisual() |
261 | { |
262 | qFatal("QGLContext::chooseVisual - this method must not be called as Qt is built with EGL support"); |
263 | return 0; |
264 | } |
265 | |
266 | void *QGLContext::tryVisual(const QGLFormat& f, int bufDepth) |
267 | { |
268 | Q_UNUSED(f); |
269 | Q_UNUSED(bufDepth); |
270 | qFatal("QGLContext::tryVisual - this method must not be called as Qt is built with EGL support"); |
271 | return 0; |
272 | } |
273 | |
274 | void QGLWidget::resizeEvent(QResizeEvent *) |
275 | { |
276 | Q_D(QGLWidget); |
277 | if (!isValid()) |
278 | return; |
279 | makeCurrent(); |
280 | if (!d->glcx->initialized()) |
281 | glInit(); |
282 | resizeGL(width(), height()); |
283 | //handle overlay |
284 | } |
285 | |
286 | const QGLContext* QGLWidget::overlayContext() const |
287 | { |
288 | return 0; |
289 | } |
290 | |
291 | void QGLWidget::makeOverlayCurrent() |
292 | { |
293 | //handle overlay |
294 | } |
295 | |
296 | void QGLWidget::updateOverlayGL() |
297 | { |
298 | //handle overlay |
299 | } |
300 | |
301 | void QGLWidget::setContext(QGLContext *context, const QGLContext* shareContext, bool deleteOldContext) |
302 | { |
303 | Q_D(QGLWidget); |
304 | if (context == 0) { |
305 | qWarning("QGLWidget::setContext: Cannot set null context"); |
306 | return; |
307 | } |
308 | if (!context->deviceIsPixmap() && context->device() != this) { |
309 | qWarning("QGLWidget::setContext: Context must refer to this widget"); |
310 | return; |
311 | } |
312 | |
313 | if (d->glcx) |
314 | d->glcx->doneCurrent(); |
315 | QGLContext* oldcx = d->glcx; |
316 | d->glcx = context; |
317 | |
318 | bool createFailed = false; |
319 | if (!d->glcx->isValid()) { |
320 | // Create the QGLContext here, which in turn chooses the EGL config |
321 | // and creates the EGL context: |
322 | if (!d->glcx->create(shareContext ? shareContext : oldcx)) |
323 | createFailed = true; |
324 | } |
325 | if (createFailed) { |
326 | if (deleteOldContext) |
327 | delete oldcx; |
328 | return; |
329 | } |
330 | |
331 | |
332 | d->eglSurfaceWindowId = winId(); // Remember the window id we created the surface for |
333 | } |
334 | |
335 | void QGLWidgetPrivate::init(QGLContext *context, const QGLWidget* shareWidget) |
336 | { |
337 | Q_Q(QGLWidget); |
338 | |
339 | initContext(context, shareWidget); |
340 | |
341 | if (q->isValid() && glcx->format().hasOverlay()) { |
342 | //no overlay |
343 | qWarning("QtOpenGL ES doesn't currently support overlays"); |
344 | } |
345 | } |
346 | |
347 | void QGLWidgetPrivate::cleanupColormaps() |
348 | { |
349 | } |
350 | |
351 | const QGLColormap & QGLWidget::colormap() const |
352 | { |
353 | return d_func()->cmap; |
354 | } |
355 | |
356 | void QGLWidget::setColormap(const QGLColormap &) |
357 | { |
358 | } |
359 | |
360 | // Re-creates the EGL surface if the window ID has changed or if there isn't a surface |
361 | void QGLWidgetPrivate::recreateEglSurface() |
362 | { |
363 | Q_Q(QGLWidget); |
364 | |
365 | Window currentId = q->winId(); |
366 | |
367 | // If the window ID has changed since the surface was created, we need to delete the |
368 | // old surface before re-creating a new one. Note: This should not be the case as the |
369 | // surface should be deleted before the old window id. |
370 | if (glcx->d_func()->eglSurface != EGL_NO_SURFACE && (currentId != eglSurfaceWindowId)) { |
371 | qWarning("EGL surface for deleted window %lx was not destroyed", uint(eglSurfaceWindowId)); |
372 | glcx->d_func()->destroyEglSurfaceForDevice(); |
373 | } |
374 | |
375 | if (glcx->d_func()->eglSurface == EGL_NO_SURFACE) { |
376 | glcx->d_func()->eglSurface = glcx->d_func()->eglContext->createSurface(q); |
377 | eglSurfaceWindowId = currentId; |
378 | } |
379 | } |
380 | |
381 | |
382 | QGLTexture *QGLContextPrivate::bindTextureFromNativePixmap(QPixmap *pixmap, const qint64 key, |
383 | QGLContext::BindOptions options) |
384 | { |
385 | Q_Q(QGLContext); |
386 | |
387 | // The EGL texture_from_pixmap has no facility to invert the y coordinate |
388 | if (!(options & QGLContext::CanFlipNativePixmapBindOption)) |
389 | return 0; |
390 | |
391 | |
392 | static bool checkedForTFP = false; |
393 | static bool haveTFP = false; |
394 | static bool checkedForEglImageTFP = false; |
395 | static bool haveEglImageTFP = false; |
396 | |
397 | |
398 | if (!checkedForEglImageTFP) { |
399 | checkedForEglImageTFP = true; |
400 | |
401 | // We need to be able to create an EGLImage from a native pixmap, which was split |
402 | // into a separate EGL extension, EGL_KHR_image_pixmap. It is possible to have |
403 | // eglCreateImageKHR & eglDestroyImageKHR without support for pixmaps, so we must |
404 | // check we have the EGLImage from pixmap functionality. |
405 | if (QEgl::hasExtension("EGL_KHR_image") || QEgl::hasExtension( "EGL_KHR_image_pixmap")) { |
406 | |
407 | // Being able to create an EGLImage from a native pixmap is also pretty useless |
408 | // without the ability to bind that EGLImage as a texture, which is provided by |
409 | // the GL_OES_EGL_image extension, which we try to resolve here: |
410 | haveEglImageTFP = qt_resolve_eglimage_gl_extensions(q); |
411 | |
412 | if (haveEglImageTFP) |
413 | qDebug("Found EGL_KHR_image_pixmap & GL_OES_EGL_image extensions (preferred method)!"); |
414 | } |
415 | } |
416 | |
417 | if (!checkedForTFP) { |
418 | // Check for texture_from_pixmap egl extension |
419 | checkedForTFP = true; |
420 | if (QEgl::hasExtension("EGL_NOKIA_texture_from_pixmap") || |
421 | QEgl::hasExtension("EGL_EXT_texture_from_pixmap")) |
422 | { |
423 | qDebug("Found texture_from_pixmap EGL extension!"); |
424 | haveTFP = true; |
425 | } |
426 | } |
427 | |
428 | if (!haveTFP && !haveEglImageTFP) |
429 | return 0; |
430 | |
431 | |
432 | QX11PixmapData *pixmapData = static_cast<QX11PixmapData*>(pixmap->data_ptr().data()); |
433 | Q_ASSERT(pixmapData->classId() == QPixmapData::X11Class); |
434 | bool hasAlpha = pixmapData->hasAlphaChannel(); |
435 | bool pixmapHasValidSurface = false; |
436 | bool textureIsBound = false; |
437 | GLuint textureId; |
438 | glGenTextures(1, &textureId); |
439 | glBindTexture(GL_TEXTURE_2D, textureId); |
440 | |
441 | if (haveTFP && pixmapData->gl_surface && |
442 | hasAlpha == (pixmapData->flags & QX11PixmapData::GlSurfaceCreatedWithAlpha)) |
443 | { |
444 | pixmapHasValidSurface = true; |
445 | } |
446 | |
447 | // If we already have a valid EGL surface for the pixmap, we should use it |
448 | if (pixmapHasValidSurface) { |
449 | EGLBoolean success; |
450 | success = eglBindTexImage(QEgl::display(), (EGLSurface)pixmapData->gl_surface, EGL_BACK_BUFFER); |
451 | if (success == EGL_FALSE) { |
452 | qWarning() << "eglBindTexImage() failed:"<< QEgl::errorString(); |
453 | eglDestroySurface(QEgl::display(), (EGLSurface)pixmapData->gl_surface); |
454 | pixmapData->gl_surface = (void*)EGL_NO_SURFACE; |
455 | } else |
456 | textureIsBound = true; |
457 | } |
458 | |
459 | // If the pixmap doesn't already have a valid surface, try binding it via EGLImage |
460 | // first, as going through EGLImage should be faster and better supported: |
461 | if (!textureIsBound && haveEglImageTFP) { |
462 | EGLImageKHR eglImage; |
463 | |
464 | EGLint attribs[] = { |
465 | EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, |
466 | EGL_NONE |
467 | }; |
468 | eglImage = QEgl::eglCreateImageKHR(QEgl::display(), EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR, |
469 | (EGLClientBuffer)QEgl::nativePixmap(pixmap), attribs); |
470 | |
471 | QGLContext* ctx = q; |
472 | glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, eglImage); |
473 | |
474 | GLint err = glGetError(); |
475 | if (err == GL_NO_ERROR) |
476 | textureIsBound = true; |
477 | |
478 | // Once the egl image is bound, the texture becomes a new sibling image and we can safely |
479 | // destroy the EGLImage we created for the pixmap: |
480 | if (eglImage != EGL_NO_IMAGE_KHR) |
481 | QEgl::eglDestroyImageKHR(QEgl::display(), eglImage); |
482 | } |
483 | |
484 | if (!textureIsBound && haveTFP) { |
485 | // Check to see if the surface is still valid |
486 | if (pixmapData->gl_surface && |
487 | hasAlpha != (pixmapData->flags & QX11PixmapData::GlSurfaceCreatedWithAlpha)) |
488 | { |
489 | // Surface is invalid! |
490 | destroyGlSurfaceForPixmap(pixmapData); |
491 | } |
492 | |
493 | if (pixmapData->gl_surface == 0) { |
494 | EGLConfig config = QEgl::defaultConfig(QInternal::Pixmap, |
495 | QEgl::OpenGL, |
496 | hasAlpha ? QEgl::Translucent : QEgl::NoOptions); |
497 | |
498 | pixmapData->gl_surface = (void*)QEgl::createSurface(pixmap, config); |
499 | if (pixmapData->gl_surface == (void*)EGL_NO_SURFACE) |
500 | return false; |
501 | } |
502 | |
503 | EGLBoolean success; |
504 | success = eglBindTexImage(QEgl::display(), (EGLSurface)pixmapData->gl_surface, EGL_BACK_BUFFER); |
505 | if (success == EGL_FALSE) { |
506 | qWarning() << "eglBindTexImage() failed:"<< QEgl::errorString(); |
507 | eglDestroySurface(QEgl::display(), (EGLSurface)pixmapData->gl_surface); |
508 | pixmapData->gl_surface = (void*)EGL_NO_SURFACE; |
509 | haveTFP = false; // If TFP isn't working, disable it's use |
510 | } else |
511 | textureIsBound = true; |
512 | } |
513 | |
514 | QGLTexture *texture = 0; |
515 | |
516 | if (textureIsBound) { |
517 | texture = new QGLTexture(q, textureId, GL_TEXTURE_2D, options); |
518 | pixmapData->flags |= QX11PixmapData::InvertedWhenBoundToTexture; |
519 | |
520 | // We assume the cost of bound pixmaps is zero |
521 | QGLTextureCache::instance()->insert(q, key, texture, 0); |
522 | |
523 | glBindTexture(GL_TEXTURE_2D, textureId); |
524 | } else |
525 | glDeleteTextures(1, &textureId); |
526 | |
527 | return texture; |
528 | } |
529 | |
530 | |
531 | void QGLContextPrivate::destroyGlSurfaceForPixmap(QPixmapData* pmd) |
532 | { |
533 | Q_ASSERT(pmd->classId() == QPixmapData::X11Class); |
534 | QX11PixmapData *pixmapData = static_cast<QX11PixmapData*>(pmd); |
535 | if (pixmapData->gl_surface) { |
536 | EGLBoolean success; |
537 | success = eglDestroySurface(QEgl::display(), (EGLSurface)pixmapData->gl_surface); |
538 | if (success == EGL_FALSE) { |
539 | qWarning() << "destroyGlSurfaceForPixmap() - Error deleting surface: " |
540 | << QEgl::errorString(); |
541 | } |
542 | pixmapData->gl_surface = 0; |
543 | } |
544 | } |
545 | |
546 | void QGLContextPrivate::unbindPixmapFromTexture(QPixmapData* pmd) |
547 | { |
548 | Q_ASSERT(pmd->classId() == QPixmapData::X11Class); |
549 | QX11PixmapData *pixmapData = static_cast<QX11PixmapData*>(pmd); |
550 | if (pixmapData->gl_surface) { |
551 | EGLBoolean success; |
552 | success = eglReleaseTexImage(QEgl::display(), |
553 | (EGLSurface)pixmapData->gl_surface, |
554 | EGL_BACK_BUFFER); |
555 | if (success == EGL_FALSE) { |
556 | qWarning() << "unbindPixmapFromTexture() - Unable to release bound texture: " |
557 | << QEgl::errorString(); |
558 | } |
559 | } |
560 | } |
561 | |
562 | QT_END_NAMESPACE |
563 |
Warning: That file was not part of the compilation database. It may have many parsing errors.