|
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 openvg.html |
|
44 \title OpenVG Rendering in Qt |
|
45 \since 4.6 |
|
46 \ingroup best-practices |
|
47 |
|
48 \brief Efficient rendering on embedded devices with OpenVG |
|
49 |
|
50 OpenVG is a standard API from the |
|
51 \l{http://www.khronos.org/openvg}{Khronos Group} for accelerated |
|
52 2D vector graphics that is appearing in an increasing number of |
|
53 embedded devices. The QtOpenVG plugin provides support for OpenVG |
|
54 painting. |
|
55 |
|
56 OpenVG is optimized for 2D vector operations, and closely matches |
|
57 the functionality in QPainter. It can therefore be an excellent |
|
58 substitute for the default raster-based QPaintEngine on hardware |
|
59 that supports OpenVG. |
|
60 |
|
61 \tableofcontents |
|
62 |
|
63 \section1 Building Qt with OpenVG support |
|
64 |
|
65 OpenVG support can be enabled by passing the \c{-openvg} option |
|
66 to configure. It is assumed that the following qmake variables |
|
67 are set to appropriate values in the qmake.conf file for your |
|
68 platform: |
|
69 |
|
70 \list |
|
71 \o QMAKE_INCDIR_OPENVG |
|
72 \o QMAKE_LIBDIR_OPENVG |
|
73 \o QMAKE_LIBS_OPENVG |
|
74 \endlist |
|
75 |
|
76 Most OpenVG implementations are based on EGL, so the following |
|
77 variables may also need to be set: |
|
78 |
|
79 \list |
|
80 \o QMAKE_INCDIR_EGL |
|
81 \o QMAKE_LIBDIR_EGL |
|
82 \o QMAKE_LIBS_EGL |
|
83 \endlist |
|
84 |
|
85 See \l{qmake Variable Reference} for more information on these variables. |
|
86 |
|
87 Two kinds of OpenVG engines are currently supported: EGL based, |
|
88 and engines built on top of OpenGL such as |
|
89 \l{http://sourceforge.net/projects/shivavg}{ShivaVG}. |
|
90 EGL based engines are preferred. |
|
91 |
|
92 It is assumed that the EGL implementation has some way to turn a |
|
93 QWidget::winId() into an EGL rendering surface with |
|
94 \c{eglCreateWindowSurface()}. If this is not the case, then |
|
95 modifications may be needed to the code under \c{src/gui/egl} and |
|
96 \c{src/plugins/graphicssystems/openvg} to accomodate the EGL |
|
97 implementation. |
|
98 |
|
99 The ShivaVG graphics system under \c{src/plugins/graphicssystems/shivavg} |
|
100 is an example of how to integrate a non-EGL implementation of |
|
101 OpenVG into Qt. It is currently only supported with Qt/X11 |
|
102 and being an example only, the resulting screen output may not |
|
103 be as good as with other OpenVG engines. |
|
104 |
|
105 \section1 Using the OpenVG graphics system |
|
106 |
|
107 Once the graphics system plugin has been built and installed, |
|
108 applications can be run as follows to use the plugin: |
|
109 |
|
110 \code |
|
111 app -graphicssystem OpenVG |
|
112 \endcode |
|
113 |
|
114 If ShivaVG is being used, then substitute \c ShivaVG instead of |
|
115 \c OpenVG in the line above. |
|
116 |
|
117 If the plugin fails to load, try setting the \c QT_DEBUG_PLUGINS |
|
118 environment variable to 1 and try again. Usually the plugin |
|
119 cannot be loaded because Qt cannot locate it in the directory |
|
120 \c{plugins/graphicssystems} within the Qt installation, or the |
|
121 dynamic library path does not include the directory containing |
|
122 the system's \c libOpenVG.so library. |
|
123 |
|
124 \section1 Supported features |
|
125 |
|
126 \section2 Context modes |
|
127 |
|
128 The default configuration is "single-context" mode, where a single |
|
129 EGLContext object is used for all drawing, regardless of the surface. |
|
130 Multiple EGLSurfaces are created, one for each window surface or pixmap. |
|
131 eglMakeCurrent() is called with the same EGLContext every time, but a |
|
132 different EGLSurface. |
|
133 |
|
134 Single-context mode is necessary for QPixmapData to be implemented in |
|
135 terms of a VGImage. If single-context mode is not enabled, then QPixmapData |
|
136 will use the fallback QRasterPixmapData implementation, which is less |
|
137 efficient performance-wise. |
|
138 |
|
139 Single-context mode can be disabled with the QVG_NO_SINGLE_CONTEXT define |
|
140 if the OpenVG engine does not support one context with multiple surfaces. |
|
141 |
|
142 \section2 Transformation matrices |
|
143 |
|
144 All affine and projective transformation matrices are supported. |
|
145 |
|
146 QVGPaintEngine will use the engine to accelerate affine transformation |
|
147 matrices only. When a projective transformation matrix is used, |
|
148 QVGPaintEngine will transform the coordinates before passing them |
|
149 to the engine. This will probably incur a performance penalty. |
|
150 |
|
151 Pixmaps and images are always transformed by the engine, because |
|
152 OpenVG specifies that projective transformations must work for images. |
|
153 |
|
154 It is recommended that client applications should avoid using projective |
|
155 transformations for non-image elements in performance critical code. |
|
156 |
|
157 \section2 Composition modes |
|
158 |
|
159 The following composition modes are supported: |
|
160 |
|
161 \list |
|
162 \o QPainter::CompositionMode_SourceOver |
|
163 \o QPainter::CompositionMode_DestinationOver |
|
164 \o QPainter::CompositionMode_Source |
|
165 \o QPainter::CompositionMode_SourceIn |
|
166 \o QPainter::CompositionMode_DestinationIn |
|
167 \o QPainter::CompositionMode_Plus |
|
168 \o QPainter::CompositionMode_Multiply |
|
169 \o QPainter::CompositionMode_Screen |
|
170 \o QPainter::CompositionMode_Darken |
|
171 \o QPainter::CompositionMode_Lighten |
|
172 \endlist |
|
173 |
|
174 The other members of QPainter::CompositionMode are not supported |
|
175 because OpenVG 1.1 does not have an equivalent in its \c VGBlendMode |
|
176 enumeration. Any attempt to set an unsupported mode will result in |
|
177 the actual mode being set to QPainter::CompositionMode_SourceOver. |
|
178 Client applications should avoid using unsupported modes. |
|
179 |
|
180 \section2 Pens and brushes |
|
181 |
|
182 All pen styles are supported, including cosmetic pens. |
|
183 |
|
184 All brush styles are supported except for conical gradients, which are |
|
185 not supported by OpenVG 1.1. Conical gradients will be converted into a |
|
186 solid color brush corresponding to the first color in the gradient's |
|
187 color ramp. |
|
188 |
|
189 Affine matrices are supported for brush transforms, but not projective |
|
190 matrices. |
|
191 |
|
192 \section2 Rectangles, lines, and points |
|
193 |
|
194 Rectangles, lines, and rounded rectangles use cached VGPath objects |
|
195 to try to accelerate drawing operations. vgModifyPathCoords() is used |
|
196 to modify the co-ordinates in the cached VGPath object each time |
|
197 fillRect(), drawRects(), drawLines(), or drawRoundedRect() is called. |
|
198 |
|
199 If the engine does not implement vgModifyPathCoords() properly, then the |
|
200 QVG_NO_MODIFY_PATH define can be set to disable path caching. This will |
|
201 incur a performance penalty. |
|
202 |
|
203 Points are implemented as lines from the point to itself. The cached |
|
204 line drawing VGPath object is used when drawing points. |
|
205 |
|
206 \section2 Polygons and Ellipses |
|
207 |
|
208 Polygon and ellipse drawing creates a new VGPath object every time |
|
209 drawPolygon() or drawEllipse() is called. If the client application is |
|
210 making heavy use of these functions, the constant creation and destruction |
|
211 of VGPath objects could have an impact on performance. |
|
212 |
|
213 If a projective transformation is active, ellipses are converted into |
|
214 cubic curves prior to transformation, which may further impact performance. |
|
215 |
|
216 Client applications should avoid polygon and ellipse drawing in performance |
|
217 critical code if possible. |
|
218 |
|
219 \section2 Other Objects |
|
220 |
|
221 Most other objects (arcs, pies, etc) use drawPath(), which takes a |
|
222 QPainterPath argument. The default implementation in QPainterEngineEx |
|
223 converts the QPainterPath into a QVectorPath and then calls draw(), |
|
224 which in turn converts the QVectorPath into a VGPath for drawing. |
|
225 |
|
226 To reduce the overhead, we have overridden drawPath() in QVGPaintEngine |
|
227 to convert QPainterPath's directly into VGPath's. This should help improve |
|
228 performance compared to the default implementation. |
|
229 |
|
230 Client applications should try to avoid these types of objects in |
|
231 performance critical code because of the QPainterPath to VGPath |
|
232 conversion cost. |
|
233 |
|
234 \section2 Clipping |
|
235 |
|
236 Clipping with QRect, QRectF, and QRegion objects is supported on all |
|
237 OpenVG engines with vgMask() if the transformation matrix is the identity |
|
238 or a simple origin translation. |
|
239 |
|
240 Clipping with an arbitrary QPainterPath, or setting the clip region when |
|
241 the transformation matrix is simple, is supported only if the OpenVG engine |
|
242 has the vgRenderToMask() function (OpenVG 1.1 and higher). |
|
243 |
|
244 The QVG_NO_RENDER_TO_MASK define will disable the use of vgRenderToMask(). |
|
245 |
|
246 The QVG_SCISSOR_CLIP define will disable clipping with vgMask() or |
|
247 vgRenderToMask() and instead use the scissor rectangle list to perform |
|
248 clipping. Clipping with an arbitrary QPainterPath will not be supported. |
|
249 The QVG_SCISSOR_CLIP define should only be used if the OpenVG engine |
|
250 does not support vgMask() or vgRenderToMask(). |
|
251 |
|
252 \section2 Opacity |
|
253 |
|
254 Opacity is supported for all drawing operations. Solid color pens, |
|
255 solid color brushes, gradient brushes, and image drawing with drawPixmap() |
|
256 and drawImage() will probably have the best performance compared to |
|
257 other kinds of pens and brushes. |
|
258 |
|
259 \section2 Text Drawing |
|
260 |
|
261 If OpenVG 1.1 is used, the paint engine will use VG fonts to cache glyphs |
|
262 while drawing. If the engine does not support VG fonts correctly, |
|
263 QVG_NO_DRAW_GLYPHS can be defined to disable this mode. Text drawing |
|
264 performance will suffer if VG fonts are not used. |
|
265 |
|
266 By default, image-based glyphs are used. If QVG_NO_IMAGE_GLYPHS is defined, |
|
267 then path-based glyphs will be used instead. QVG_NO_IMAGE_GLYPHS is ignored |
|
268 if QVG_NO_DRAW_GLYPHS is defined. |
|
269 |
|
270 If path-based glyphs are used, then the OpenVG engine will need to |
|
271 support hinting to render text with good results. Image-based glyphs |
|
272 avoids the need for hinting and will usually give better results than |
|
273 path-based glyphs. |
|
274 |
|
275 \section2 Pixmaps |
|
276 |
|
277 In single-context mode, pixmaps will be implemented using VGImage |
|
278 unless QVG_NO_PIXMAP_DATA is defined. |
|
279 |
|
280 QVGPixmapData will convert QImage's into VGImage's when the application |
|
281 calls drawPixmap(), and the pixmap will be kept in VGImage form for the |
|
282 lifetime of the QVGPixmapData object. When the application tries to paint |
|
283 into a QPixmap with QPainter, the data will be converted back into a |
|
284 QImage and the raster paint engine will be used to render into the QImage. |
|
285 |
|
286 This arrangement optimizes for the case of drawing the same static pixmap |
|
287 over and over (e.g. for icons), but does not optimize the case of drawing |
|
288 into pixmaps. |
|
289 |
|
290 Bitmaps must use QRasterPixmapData. They are not accelerated with |
|
291 VGImage at present. |
|
292 |
|
293 \section2 Pixmap filters |
|
294 |
|
295 Convolution, colorize, drop shadow, and blur filters are accelerated |
|
296 using OpenVG operations. |
|
297 |
|
298 \section1 Known issues |
|
299 |
|
300 Performance of copying the contents of an OpenVG-rendered window to the |
|
301 screen needs platform-specific work in the QVGWindowSurface class. |
|
302 |
|
303 Clipping with arbitrary non-rectangular paths only works on engines |
|
304 that support vgRenderToMask(). Simple rectangular paths are supported |
|
305 on all engines that correctly implement vgMask(). |
|
306 |
|
307 The paint engine is not yet thread-safe, so it is not recommended for |
|
308 use in threaded Qt applications that draw from multiple threads. |
|
309 Drawing should be limited to the main GUI thread. |
|
310 |
|
311 Performance of projective matrices for non-image drawing is not as good |
|
312 as for affine matrices. |
|
313 |
|
314 QPixmap's are implemented as VGImage objects so that they can be quickly |
|
315 rendered with drawPixmap(). Rendering into a QPixmap using QPainter |
|
316 will use the default Qt raster paint engine on a QImage copy of the |
|
317 QPixmap, and will not be accelerated. This issue may be addressed in |
|
318 a future version of the engine. |
|
319 |
|
320 ShivaVG support is highly experimental and limited to Qt/X11. It is |
|
321 provided as an example of how to integrate a non-EGL engine. |
|
322 */ |