EGLSurface QEgl::createSurface(QPaintDevice *device, EGLConfig cfg, const QEglProperties *properties) { // Create the native drawable for the paint device. int devType = device->devType(); EGLNativePixmapType pixmapDrawable = 0; EGLNativeWindowType windowDrawable = 0; bool ok; if (devType == QInternal::Pixmap) { pixmapDrawable = nativePixmap(static_cast<QPixmap *>(device)); ok = (pixmapDrawable != 0); } else if (devType == QInternal::Widget) { windowDrawable = nativeWindow(static_cast<QWidget *>(device)); ok = (windowDrawable != 0); } else { ok = false; } if (!ok) { qWarning("QEglContext::createSurface(): Cannot create the native EGL drawable"); return EGL_NO_SURFACE; } // Create the EGL surface to draw into, based on the native drawable. const int *props; if (properties) props = properties->properties(); else props = 0; EGLSurface surf; if (devType == QInternal::Widget) surf = eglCreateWindowSurface(QEgl::display(), cfg, windowDrawable, props); else surf = eglCreatePixmapSurface(QEgl::display(), cfg, pixmapDrawable, props); if (surf == EGL_NO_SURFACE) { qWarning("QEglContext::createSurface(): Unable to create EGL surface, error = 0x%x", eglGetError()); } return surf; }
EGLSurface QEgl::createSurface(QPaintDevice *device, EGLConfig cfg, const QEglProperties *properties) { // Create the native drawable for the paint device. int devType = device->devType(); EGLNativePixmapType pixmapDrawable = 0; EGLNativeWindowType windowDrawable = 0; bool ok; if (devType == QInternal::Pixmap) { pixmapDrawable = nativePixmap(static_cast<QPixmap *>(device)); ok = (pixmapDrawable != 0); } else if (devType == QInternal::Widget) { windowDrawable = nativeWindow(static_cast<QWidget *>(device)); ok = (windowDrawable != 0); } else { ok = false; } if (!ok) { qWarning("QEglContext::createSurface(): Cannot create the native EGL drawable"); return EGL_NO_SURFACE; } // Create the EGL surface to draw into, based on the native drawable. const int *props; if (properties) props = properties->properties(); else props = 0; EGLSurface surf = EGL_NO_SURFACE; #ifdef Q_OS_SYMBIAN // On Symbian there might be situations (especially on 32MB GPU devices) // where Qt is trying to create EGL surface while some other application // is still holding all available GPU memory but is about to release it // soon. For an example when exiting native video recorder and going back to // Qt application behind it. Video stack tear down takes some time and Qt // app might be too quick in reserving its EGL surface and thus running out // of GPU memory right away. So if EGL surface creation fails due to bad // alloc, let's try recreating it four times within ~1 second if needed. // This strategy gives some time for video recorder to tear down its stack // and a chance to Qt for creating a valid surface. // If the surface is still failing however, we don't keep the app blocked. static int tries = 4; if (tries <= 0) tries = 1; while (tries-- > 0) { if (devType == QInternal::Widget) surf = eglCreateWindowSurface(QEgl::display(), cfg, windowDrawable, props); else surf = eglCreatePixmapSurface(QEgl::display(), cfg, pixmapDrawable, props); if (surf == EGL_NO_SURFACE) { EGLint error = eglGetError(); if (error == EGL_BAD_ALLOC) { if (tries > 0) { User::After(1000 * 250); // 250ms continue; } } qWarning("QEglContext::createSurface(): Unable to create EGL surface, error = 0x%x", error); S60->eglSurfaceCreationError = true; } else { tries = 4; break; } } #else if (devType == QInternal::Widget) surf = eglCreateWindowSurface(QEgl::display(), cfg, windowDrawable, props); else surf = eglCreatePixmapSurface(QEgl::display(), cfg, pixmapDrawable, props); if (surf == EGL_NO_SURFACE) { qWarning("QEglContext::createSurface(): Unable to create EGL surface, error = 0x%x", eglGetError()); } #endif return surf; }