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