void QVGEGLWindowSurfaceVGImage::beginPaint(QWidget *widget) { QEglContext *context = ensureContext(widget); if (context) { if (recreateBackBuffer || backBufferSurface == EGL_NO_SURFACE) { // Create a VGImage object to act as the back buffer // for this window. We have to create the VGImage with a // current context, so activate the main surface for the window. context->makeCurrent(mainSurface()); recreateBackBuffer = false; if (backBufferSurface != EGL_NO_SURFACE) { eglDestroySurface(QEgl::display(), backBufferSurface); backBufferSurface = EGL_NO_SURFACE; } if (backBuffer != VG_INVALID_HANDLE) { vgDestroyImage(backBuffer); } VGImageFormat format = qt_vg_config_to_vg_format(context); backBuffer = vgCreateImage (format, size.width(), size.height(), VG_IMAGE_QUALITY_FASTER); if (backBuffer != VG_INVALID_HANDLE) { // Create an EGL surface for rendering into the VGImage. backBufferSurface = eglCreatePbufferFromClientBuffer (QEgl::display(), EGL_OPENVG_IMAGE, (EGLClientBuffer)(backBuffer), context->config(), NULL); if (backBufferSurface == EGL_NO_SURFACE) { vgDestroyImage(backBuffer); backBuffer = VG_INVALID_HANDLE; } } } if (backBufferSurface != EGL_NO_SURFACE) context->makeCurrent(backBufferSurface); else context->makeCurrent(mainSurface()); isPaintingActive = true; } }
QT_BEGIN_NAMESPACE #ifdef EGL_BIND_TO_TEXTURE_RGBA #define QGL_RENDER_TEXTURE 1 #else #define QGL_RENDER_TEXTURE 0 #endif bool QGLPixelBufferPrivate::init(const QSize &size, const QGLFormat &f, QGLWidget *shareWidget) { // Create the EGL context. ctx = new QEglContext(); ctx->setApi(QEgl::OpenGL); // Find the shared context. QEglContext *shareContext = 0; if (shareWidget && shareWidget->d_func()->glcx) shareContext = shareWidget->d_func()->glcx->d_func()->eglContext; // Choose an appropriate configuration. We use the best format // we can find, even if it is greater than the requested format. // We try for a pbuffer that is capable of texture rendering if possible. textureFormat = EGL_NONE; if (shareContext) { // Use the same configuration as the widget we are sharing with. ctx->setConfig(shareContext->config()); #if QGL_RENDER_TEXTURE if (ctx->configAttrib(EGL_BIND_TO_TEXTURE_RGBA) == EGL_TRUE) textureFormat = EGL_TEXTURE_RGBA; else if (ctx->configAttrib(EGL_BIND_TO_TEXTURE_RGB) == EGL_TRUE) textureFormat = EGL_TEXTURE_RGB; #endif } else { QEglProperties configProps; qt_eglproperties_set_glformat(configProps, f); configProps.setDeviceType(QInternal::Pbuffer); configProps.setRenderableType(ctx->api()); bool ok = false; #if QGL_RENDER_TEXTURE textureFormat = EGL_TEXTURE_RGBA; configProps.setValue(EGL_BIND_TO_TEXTURE_RGBA, EGL_TRUE); ok = ctx->chooseConfig(configProps, QEgl::BestPixelFormat); if (!ok) { // Try again with RGB texture rendering. textureFormat = EGL_TEXTURE_RGB; configProps.removeValue(EGL_BIND_TO_TEXTURE_RGBA); configProps.setValue(EGL_BIND_TO_TEXTURE_RGB, EGL_TRUE); ok = ctx->chooseConfig(configProps, QEgl::BestPixelFormat); if (!ok) { // One last try for a pbuffer with no texture rendering. configProps.removeValue(EGL_BIND_TO_TEXTURE_RGB); textureFormat = EGL_NONE; } } #endif if (!ok) { if (!ctx->chooseConfig(configProps, QEgl::BestPixelFormat)) { delete ctx; ctx = 0; return false; } } } // Retrieve the actual format properties. qt_glformat_from_eglconfig(format, ctx->config()); // Create the attributes needed for the pbuffer. QEglProperties attribs; attribs.setValue(EGL_WIDTH, size.width()); attribs.setValue(EGL_HEIGHT, size.height()); #if QGL_RENDER_TEXTURE if (textureFormat != EGL_NONE) { attribs.setValue(EGL_TEXTURE_FORMAT, textureFormat); attribs.setValue(EGL_TEXTURE_TARGET, EGL_TEXTURE_2D); } #endif // Create the pbuffer surface. pbuf = eglCreatePbufferSurface(ctx->display(), ctx->config(), attribs.properties()); #if QGL_RENDER_TEXTURE if (pbuf == EGL_NO_SURFACE && textureFormat != EGL_NONE) { // Try again with texture rendering disabled. textureFormat = EGL_NONE; attribs.removeValue(EGL_TEXTURE_FORMAT); attribs.removeValue(EGL_TEXTURE_TARGET); pbuf = eglCreatePbufferSurface(ctx->display(), ctx->config(), attribs.properties()); } #endif if (pbuf == EGL_NO_SURFACE) { qWarning() << "QGLPixelBufferPrivate::init(): Unable to create EGL pbuffer surface:" << QEgl::errorString(); return false; } // Create a new context for the configuration. if (!ctx->createContext(shareContext)) { delete ctx; ctx = 0; return false; } return true; }