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