The reference integration for OpenGL into Qt for Embedded Linux is for the PowerVR chipset from Imagination Technologies. It consists of two components: pvreglscreen, which provides the Qt for Embedded Linux screen driver, and QWSWSEGL, which implements a plug-in to the PowerVR EGL implementation to implement low-level OpenGL drawing surfaces.
Integrating Other Chipsets
In this section, we discuss the essential features of the reference integration that need to be provided for any other chipset integration.
The QtOpenGL module assumes that a QGLWidget can be represented by an EGLNativeWindowType value in some underlying window system implementation, and that eglSwapBuffers() is sufficient to copy the contents of the native window to the screen when requested.
However, many EGL implementations do not have a pre-existing window system. Usually only a single full-screen window is provided, and everything else must be simulated some other way. This can be a problem because of QtOpenGL's assumptions. We intend to address these assumptions in a future version of Qt, but for now, it is the responsibility of the integrator to provide a rudimentary window system within the EGL implementation. This is the purpose of QWSWSEGL in the reference integration.
If it isn't possible for the EGL implementation to provide a rudimentary window system, then full-screen windows using QGLWidget can be supported, but very little else.
The screen driver needs to inherit from QGLScreen and perform the following operations in its constructor:
PvrEglScreen::PvrEglScreen(int displayId)
: QGLScreen(displayId)
{
setOptions(NativeWindows);
setSupportsBlitInClients(true);
setSurfaceFunctions(new PvrEglScreenSurfaceFunctions(this, displayId));
The setSurfaceFunctions() call supplies an object that takes care of converting Qt paint devices such as widgets and pixmaps into EGLNativeWindowType and EGLNativePixmapType values. Here we only support native windows. Because OpenGL rendering is direct to the screen, we also indicate that client blit is supported.
Next, we override the createSurface() functions in QGLScreen:
QWSWindowSurface* PvrEglScreen::createSurface(QWidget *widget) const
{
if (qobject_cast<QGLWidget*>(widget))
return new PvrEglWindowSurface(widget, (PvrEglScreen *)this, displayId);
return QScreen::createSurface(widget);
}
QWSWindowSurface* PvrEglScreen::createSurface(const QString &key) const
{
if (key == QLatin1String("PvrEgl"))
return new PvrEglWindowSurface();
return QScreen::createSurface(key);
}
Even if Qt for Embedded Linux is used in single-process mode, it is necessary to create both client-side and server-side versions of the window surface. In our case, the server-side is just a stub because the client side directly renders to the screen.
Note that we only create a PvrEglWindowSurface if the widget is a QGLWidget. All other widgets use the normal raster processing. It can be tempting to make createSurface() create an OpenGL window surface for other widget types as well. This has not been extensively tested and we do not recommend its use at this time.
The other main piece is the creation of the EGLNativeWindowType value for the widget. This is done in the createNativeWindow() override:
bool PvrEglScreenSurfaceFunctions::createNativeWindow(QWidget *widget, EGLNativeWindowType *native)
{
The details of what needs to be placed in this function will vary from chipset to chipset. The simplest is to return the native window handle corresponding to the "root" full-screen window:
*native = rootWindowHandle;
return true;
The most common value for rootWindowHandle is zero, but this may not always be the case. Consult the chipset documentation for the actual value to use. The important thing is that whatever value is returned must be suitable for passing to the eglCreateWindowSurface() function of the chipset's EGL implementation.
In the case of PowerVR, the rudimentary window system in QWSWSEGL provides a PvrQwsDrawable object to represent the EGLNativeWindowType value for the widget.