|
1 /**************************************************************************** |
|
2 ** |
|
3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
4 ** All rights reserved. |
|
5 ** Contact: Nokia Corporation (qt-info@nokia.com) |
|
6 ** |
|
7 ** This file is part of the documentation of the Qt Toolkit. |
|
8 ** |
|
9 ** $QT_BEGIN_LICENSE:LGPL$ |
|
10 ** No Commercial Usage |
|
11 ** This file contains pre-release code and may not be distributed. |
|
12 ** You may use this file in accordance with the terms and conditions |
|
13 ** contained in the Technology Preview License Agreement accompanying |
|
14 ** this package. |
|
15 ** |
|
16 ** GNU Lesser General Public License Usage |
|
17 ** Alternatively, this file may be used under the terms of the GNU Lesser |
|
18 ** General Public License version 2.1 as published by the Free Software |
|
19 ** Foundation and appearing in the file LICENSE.LGPL included in the |
|
20 ** packaging of this file. Please review the following information to |
|
21 ** ensure the GNU Lesser General Public License version 2.1 requirements |
|
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. |
|
23 ** |
|
24 ** In addition, as a special exception, Nokia gives you certain additional |
|
25 ** rights. These rights are described in the Nokia Qt LGPL Exception |
|
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. |
|
27 ** |
|
28 ** If you have questions regarding the use of this file, please contact |
|
29 ** Nokia at qt-info@nokia.com. |
|
30 ** |
|
31 ** |
|
32 ** |
|
33 ** |
|
34 ** |
|
35 ** |
|
36 ** |
|
37 ** |
|
38 ** $QT_END_LICENSE$ |
|
39 ** |
|
40 ****************************************************************************/ |
|
41 |
|
42 /*! |
|
43 \page qt-embedded-opengl.html |
|
44 |
|
45 \title Qt for Embedded Linux and OpenGL |
|
46 \ingroup qt-embedded-linux |
|
47 |
|
48 \section1 Introduction |
|
49 |
|
50 \l {http://www.opengl.org}{OpenGL} is an industry standard API for |
|
51 2D/3D graphics. It provides a powerful, low-level interface between |
|
52 software and acceleration hardware, and it is operating system and |
|
53 window system independent. |
|
54 |
|
55 \l {http://www.khronos.org/opengles}{OpenGL ES} is a subset |
|
56 of the \l {http://www.opengl.org}{OpenGL} standard. |
|
57 Because it is meant for use in embedded systems, it has a smaller, |
|
58 more constrained API. |
|
59 |
|
60 For reference, Nokia provides support for integrating \l |
|
61 {http://www.khronos.org/opengles}{OpenGL ES} with Qt for Embedded Linux |
|
62 for drawing into a QGLWidget. |
|
63 |
|
64 The current implementation supports OpenGL and 2D painting within a |
|
65 QGLWidget. Using OpenGL to accelerate regular widgets and compositing |
|
66 top-level windows with OpenGL are not currently supported. These issues |
|
67 will be addressed in future versions of Qt. |
|
68 |
|
69 It is recommended that Qt for Embedded Linux is configured with the |
|
70 \c{-DQT_QWS_CLIENTBLIT} and \c{-DQT_NO_QWS_CURSOR} options for optimum |
|
71 performance. OpenGL is rendered direct to the screen and these options |
|
72 prevent Qt for Embedded Linux from trying to do its own non-OpenGL |
|
73 compositing on the QGLWidget contents. |
|
74 |
|
75 \section2 Using OpenGL 3D Graphics in Applications |
|
76 |
|
77 The \l {QtOpenGL module} offers classes that make it easy to draw 3D |
|
78 graphics in GUI applications. The module API is cross-platform, so it |
|
79 is also available on Windows, X11, and Mac OS X. |
|
80 |
|
81 To use OpenGL-enabled widgets in a Qt for Embedded Linux application, |
|
82 all that is required is to subclass the QGLWidget and draw into instances of |
|
83 the subclass with standard OpenGL functions. |
|
84 |
|
85 Note that on most embedded hardware, the OpenGL implementation is |
|
86 actually \l{http://www.khronos.org/opengles/1_X/}{OpenGL/ES 1.1} or |
|
87 \l{http://www.khronos.org/opengles/2_X/}{OpenGL/ES 2.0}. When painting |
|
88 within a QGLWidget::paintGL() override, it is necessary to limit the |
|
89 application to only the features that are present in the OpenGL/ES |
|
90 implementation. |
|
91 |
|
92 \section2 Using OpenGL to Accelerate Normal 2D Painting |
|
93 |
|
94 Qt provides a subclass of QPaintEngine that translates QPainter operations |
|
95 into OpenGL calls (there are actually two subclasses, one for OpenGL/ES 1.1 |
|
96 and another for OpenGL/ES 2.0). This specialized paint engine can be used |
|
97 to improve 2D rendering performance on appropriate hardware. It can also |
|
98 overlay controls and decorations onto 3D scenes drawn using OpenGL. |
|
99 |
|
100 As mentioned above, the OpenGL paint engine is not currently supported |
|
101 in regular widgets. However, any application that uses QGraphicsView |
|
102 can set a QGLWidget as the viewport and obtain access to the |
|
103 OpenGL paint engine that way: |
|
104 |
|
105 \code |
|
106 QGraphicsView view(&scene); |
|
107 view.setViewport(new QGLWidget); |
|
108 view.setViewportUpdateMode(QGraphicsView::FullViewportUpdate); |
|
109 view.showFullScreen(); |
|
110 \endcode |
|
111 |
|
112 It is recommended that the QGraphicsView::FullViewportUpdate flag |
|
113 be set because the default double-buffered behavior of QGLWidget |
|
114 does not support partial updates. It is also recommended that the |
|
115 window be shown full-screen because that usually has the best |
|
116 performance on current OpenGL/ES implementations. |
|
117 |
|
118 Once a QGraphicsView has been initialized as above, regular widgets |
|
119 can be added to the canvas using QGraphicsProxyWidget if the |
|
120 application requires them. |
|
121 |
|
122 \section2 Using OpenGL to Implement Window Compositing and Effects |
|
123 |
|
124 Compositing effects can be simulated by adjusting the opacity and |
|
125 other parameters of the items within a QGraphicsView canvas on a |
|
126 QGLWidget viewport. |
|
127 |
|
128 While Qt for Embedded Linux does include a complete windowing system, |
|
129 using OpenGL to composite regular window surfaces can be quite difficult. |
|
130 Most of Qt for Embedded Linux assumes that the window surface is a plain |
|
131 raster memory buffer, with QGLWidget being the sole exception. |
|
132 The need to constantly re-upload the raster memory buffers into OpenGL |
|
133 textures for compositing can have a significant impact on performance, |
|
134 which is why we do not recommend implementing that form of compositing. |
|
135 We intend to address this problem in future versions of Qt. |
|
136 |
|
137 \section1 Integrating OpenGL/ES into Qt for Embedded Linux |
|
138 |
|
139 \section2 Reference Integration |
|
140 |
|
141 The reference integration for OpenGL into Qt for Embedded Linux |
|
142 is for the PowerVR chipset from \l{http://www.imgtec.com/}{Imagination |
|
143 Technologies}. It consists of two components: \c{pvreglscreen} which |
|
144 provides the Qt for Embedded Linux screen driver, and \c{QWSWSEGL} |
|
145 which implements a plug-in to the PowerVR EGL implementation to |
|
146 implement low-level OpenGL drawing surfaces. |
|
147 |
|
148 \section2 Integrating Other Chipsets |
|
149 |
|
150 In this section we discuss the essential features of the reference |
|
151 integration that need to be provided for any other chipset integration. |
|
152 |
|
153 The QtOpenGL module assumes that a QGLWidget can be represented |
|
154 by a \c EGLNativeWindowType value in some underlying window system |
|
155 implementation, and that \c{eglSwapBuffers()} is sufficient to copy |
|
156 the contents of the native window to the screen when requested. |
|
157 |
|
158 However, many EGL implementations do not have a pre-existing window system. |
|
159 Usually only a single full-screen window is provided, and everything else |
|
160 must be simulated some other way. This can be a problem because |
|
161 of QtOpenGL's assumptions. We intend to address these assumptions in a |
|
162 future version of Qt, but for now it is the responsibility of the integrator |
|
163 to provide a rudimentary window system within the EGL implementation. |
|
164 This is the purpose of \c{QWSWSEGL} in the reference integration. |
|
165 |
|
166 If it isn't possible for the EGL implementation to provide a rudimentary |
|
167 window system, then full-screen windows using QGLWidget can be supported, |
|
168 but very little else. |
|
169 |
|
170 The screen driver needs to inherit from QGLScreen and perform the |
|
171 following operations in its constructor: |
|
172 |
|
173 \snippet src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglscreen.cpp 0 |
|
174 |
|
175 The \c{setSurfaceFunctions()} call supplies an object that takes care |
|
176 of converting Qt paint devices such as widgets and pixmaps into |
|
177 \c EGLNativeWindowType and \c EGLNativePixmapType values. Here we |
|
178 only support native windows. Because OpenGL rendering is direct to |
|
179 the screen, we also indicate that client blit is supported. |
|
180 |
|
181 Next, we override the \c{createSurface()} functions in QGLScreen: |
|
182 |
|
183 \snippet src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglscreen.cpp 1 |
|
184 |
|
185 Even if Qt for Embedded Linux is used in single-process mode, it is |
|
186 necessary to create both client-side and server-side versions of the |
|
187 window surface. In our case, the server-side is just a stub because |
|
188 the client side directly renders to the screen. |
|
189 |
|
190 Note that we only create a \c{PvrEglWindowSurface} if the widget is a |
|
191 QGLWidget. All other widgets use the normal raster processing. |
|
192 It can be tempting to make \c{createSurface()} create an OpenGL |
|
193 window surface for other widget types as well. This has not been |
|
194 extensively tested and we do not recommend its use at this time. |
|
195 |
|
196 The other main piece is the creation of the \c EGLNativeWindowType |
|
197 value for the widget. This is done in the \c{createNativeWindow()} |
|
198 override: |
|
199 |
|
200 \snippet src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglscreen.cpp 2 |
|
201 |
|
202 The details of what needs to be placed in this function will vary |
|
203 from chipset to chipset. The simplest is to return the native window |
|
204 handle corresponding to the "root" full-screen window: |
|
205 |
|
206 \code |
|
207 *native = rootWindowHandle; |
|
208 return true; |
|
209 \endcode |
|
210 |
|
211 The most common value for \c rootWindowHandle is zero, but this may |
|
212 not always be the case. Consult the chipset documentation for the |
|
213 actual value to use. The important thing is that whatever value is |
|
214 returned must be suitable for passing to the \c{eglCreateWindowSurface()} |
|
215 function of the chipset's EGL implementation. |
|
216 |
|
217 In the case of PowerVR, the rudimentary window system in \c{QWSWSEGL} |
|
218 provides a \c PvrQwsDrawable object to represent the \c EGLNativeWindowType |
|
219 value for the widget. |
|
220 |
|
221 \section1 OpenVG Support |
|
222 |
|
223 \l {http://www.khronos.org/openvg} {OpenVG} is a dedicated API for 2D |
|
224 graphics on mobile devices. It is therefore more likely to be a better |
|
225 alternative for 2D acceleration than OpenGL/ES. Acceleration of |
|
226 regular widgets is supported with OpenVG, unlike with OpenGL/ES. |
|
227 See \l{OpenVG Rendering in Qt} for more information on the |
|
228 OpenVG support in Qt. |
|
229 |
|
230 */ |