|
1 /**************************************************************************** |
|
2 ** |
|
3 ** Copyright (C) 2010 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-embeddedLinux-directfb.html |
|
44 |
|
45 \title Qt for Embedded Linux and DirectFB |
|
46 |
|
47 \ingroup qt-embedded-linux |
|
48 |
|
49 \section1 Introduction |
|
50 |
|
51 DirectFB is an open source LGPL licensed project founded by Denis Oliver Kropp |
|
52 and generally chip vendors start out with the official version and |
|
53 implement their own plugins to optimize the operations their hardware |
|
54 supports. |
|
55 |
|
56 We recommend using Qt 4.6 with DirectFB. DirectFB support was introduced |
|
57 already into Qt for Embedded Linux as a labs project for Qt 4.3 and folded |
|
58 into Qt as a screen driver for Qt 4.4, but not supported fully. In Qt 4.5, |
|
59 major changes were made to make it work with the optimized raster paint |
|
60 engine. And in Qt 4.6 these have been further improved. |
|
61 |
|
62 \tableofcontents |
|
63 |
|
64 \section1 Using DirectFB with Qt |
|
65 DirectFB is centered around \l{DirectFB - IDirectFBSurface}{Surfaces} |
|
66 which is the equivalent of a QPaintDevice. In the Qt/DirectFB plugin, |
|
67 DirectFB maps onto either a QPixmap or a QWindowSurface which essentially |
|
68 means that drawing onto QPixmap or a QWidget can be accelerated and drawing |
|
69 onto any other paint device (e.g. QImage) cannot. |
|
70 |
|
71 \section2 Configure |
|
72 |
|
73 When configuring Qt there are two options, from which you can choose: |
|
74 |
|
75 \code |
|
76 ./configure -plugin-gfx-directfb |
|
77 ./configure -qt-gfx-directfb |
|
78 |
|
79 \endcode |
|
80 |
|
81 With either mode, Qt will try the following to look for the DirectFB |
|
82 includes/libs. |
|
83 |
|
84 \list |
|
85 \o Use pkg-config |
|
86 \o Use directfb-config |
|
87 \o Check in your qmake.conf |
|
88 \endlist |
|
89 |
|
90 Often the values returned from pkg-config/directfb-config indicates the |
|
91 locations of the libs/headers on the target rootfs, rather than their |
|
92 location on your host. The safest option is usually to explicitly populate |
|
93 these variables in your qmake.conf like this: |
|
94 |
|
95 \code |
|
96 QT_CFLAGS_DIRECTFB = |
|
97 /opt/toolchain/gcc4.3_mipsel_linux/usr/include/directfb -D_REENTRANT |
|
98 QT_LIBS_DIRECTFB = -L/opt/toolchain/gcc4.3_mipsel_linux/usr/lib/-ldirect |
|
99 -ldirectfb -lfusion |
|
100 \endcode |
|
101 |
|
102 \note While DirectFB supports a multi-process setup through a |
|
103 kernel-extension called Fusion this setup is not well tested with Qt. |
|
104 |
|
105 \section2 Supported graphics operations |
|
106 |
|
107 IDirectFBSurface supports blitting, filling, drawing lines rects etc, but |
|
108 it does not support everything Qt allows you to do. E.g. painter paths, |
|
109 polygons, complex transformations, antialiasing, gradients. Some of these |
|
110 things are handled in newer versions of DirectFB and could be supported by |
|
111 Qt. They are seemingly optional at the driver level, so you need to have |
|
112 fall back code paths for older drivers and drivers on which this is not |
|
113 implemented. |
|
114 |
|
115 The QDirectFBPaintEngine is a subclass of the QRasterPaintEngine, thus |
|
116 essentially supporting everything QRasterPaintEngine supports. This means |
|
117 that it supports all graphical operations that Qt supports, but certain |
|
118 operations will have to fall back to software rendering and that should be |
|
119 avoided due to performance issues. Instead, these operations should be |
|
120 rendered into a QPixmap once, and then reuse the pixmap. |
|
121 |
|
122 Note: Fallbacks to software rendering should be avoided. If unsupported |
|
123 operations are used, the paint engine must fallback to the |
|
124 QRasterPaintEngine engine. A good debugging tip is to make Qt warn you when |
|
125 such fall backs occur, and to disable the fall back and only return. |
|
126 Debugging options are listed below. |
|
127 |
|
128 \section2 DirectFB driver |
|
129 DirectFB also provides an abstraction for keyboard and mouse drivers. This |
|
130 simplifies the process of getting the target hardware up and running. It |
|
131 also brings us to a feature fragmentation issue between different versions |
|
132 of DirectFB. |
|
133 |
|
134 The Qt DirectFB driver currently supports DirectFB versions >= 0.9. Still, |
|
135 there are large differences in what each actual implementation handles |
|
136 correctly. It is relatively common not to properly support |
|
137 \l{DirectFB - IDirectFBWindow}{DirectFB windows}, so Qt needs to handle |
|
138 this case with a different code path. In addition, certain drivers do not |
|
139 properly support DirectFB's cursor handling. This means Qt has to have a |
|
140 code path for rendering the cursor itself when this is the case. |
|
141 Some drivers do not let us create |
|
142 \l{DirectFB - DFBSurfaceDescription}{preallocated surfaces} which means we |
|
143 have to have a conditional code path for that case. |
|
144 |
|
145 \section2 Optimize performance using define options |
|
146 |
|
147 Qt/DirectFB comes with a number of defines that can be either |
|
148 uncommented in directfb.pri or added to the QT_DEFINES_DIRECTFB variable in |
|
149 your qmake.conf. |
|
150 |
|
151 \note The defines have been moved from |
|
152 \e{src/plugins/gfxdrivers/directfb/directfb.pro} to |
|
153 \e{src/gui/embedded/directfb.pri} |
|
154 |
|
155 \code |
|
156 #DIRECTFB_DRAWINGOPERATIONS=DRAW_RECTS|DRAW_LINES|DRAW_IMAGE|DRAW_PIXMAP| |
|
157 DRAW_TILED_PIXMAP|STROKE_PATH|DRAW_PATH|DRAW_POINTS|DRAW_ELLIPSE|DRAW_POLYGON| |
|
158 DRAW_TEXT|FILL_PATH|FILL_RECT|DRAW_COLORSPANS|DRAW_ROUNDED_RECT |
|
159 |
|
160 #DEFINES += \"QT_DIRECTFB_WARN_ON_RASTERFALLBACKS=$$DIRECTFB_DRAWINGOPERATIONS\" |
|
161 #DEFINES += \"QT_DIRECTFB_DISABLE_RASTERFALLBACKS=$$DIRECTFB_DRAWINGOPERATIONS\" |
|
162 \endcode |
|
163 |
|
164 As demonstrated above, you need to Qt which drawing operations you want to |
|
165 warn/disable. Since there are varying implementations of DirectFB from |
|
166 manufacturer to manufacture, different operations will be optimized. This |
|
167 require you to define the operations you want to warn about or disable. |
|
168 These are listed above in the DIRECTFB_DRAWINGOPERATIONS variable. |
|
169 |
|
170 Following is a table showing which options you have. |
|
171 |
|
172 \table |
|
173 \header |
|
174 \o Define option |
|
175 \o Description |
|
176 \row |
|
177 \o QT_DIRECTFB_IMAGECACHE |
|
178 \o Defining this means that Qt will cache an IDirectFBSurface per |
|
179 QImage you draw based on its \l{QImage::}{cacheKey()}. |
|
180 Use this define if your application draws many QImages that |
|
181 remain the same. Note that if you in this situation draw an image and then |
|
182 change it, by calling bits() or opening a QPainter on it, the cache will |
|
183 not benefit you. You can control the cache size with the imageCacheSize |
|
184 connect option. |
|
185 |
|
186 \row |
|
187 \o QT_NO_DIRECTFB_WM |
|
188 \o If your DirectFB implementation does not support windows, you |
|
189 have to define this to make Qt work properly. You can test this by checking |
|
190 if the \l{DirectFB - df_window example}{df_window example} runs well. |
|
191 This means that all drawing operations onto a QWidget involves |
|
192 an extra blitting step since Qt essentially first has to draw into an |
|
193 off-screen buffer and then blit this buffer to the back buffer of the |
|
194 primary surface. Finally, Qt must flip the back buffer to the front buffer, |
|
195 which usually involves another blit. Still, blits are usually very fast |
|
196 with DirectFB. |
|
197 |
|
198 To work around this you can make your widget paint on screen, \l |
|
199 Qt::WA_PaintOnScreen but this comes with other limitations. This should be |
|
200 avoided if you want more than one full-screen window in your application. |
|
201 In addition, it will not work without proper DirectFB mouse support from the |
|
202 layer. Also, see QT_NO_DIRECTFB_LAYER for more. |
|
203 |
|
204 \row |
|
205 \o QT_NO_DIRECTFB_LAYER |
|
206 \o If your DirectFB display layer cannot be used for e.g. drawing |
|
207 mouse cursor, creating windows you have to define this. Defining this also |
|
208 requires defining QT_NO_DIRECTFB_WM and involves making Qt render the |
|
209 cursor rather than letting DirectFB do it. |
|
210 |
|
211 \row |
|
212 \o QT_NO_DIRECTFB_PALETTE |
|
213 \o Define this if your DirectFB driver does not support surfaces |
|
214 with \l{DirectFB - IDirectFBPalette}{color tables}. |
|
215 The effect of defining this is that Qt will have to convert |
|
216 images with \l QImage::Format_Indexed8 format to another format before |
|
217 rendering them. |
|
218 |
|
219 \row |
|
220 \o QT_NO_DIRECTFB_PREALLOCATED |
|
221 \o Define this if your DirectFB driver does not support creating a |
|
222 surface with preallocated data. This will make a more frequent use of |
|
223 \l{C++ Reference - memcpy}{memcpy()} |
|
224 when drawing images. If you define this, you might want to consider |
|
225 defining QT_DIRECTFB_IMAGECACHE for better image rendering performance. |
|
226 |
|
227 \row |
|
228 \o QT_NO_DIRECTFB_MOUSE and QT_NO_DIRECTFB_KEYBOARD |
|
229 \o Define this if your driver does not provide keyboard/mouse |
|
230 events through \l{DirectFB - CreateInputEventBuffer}{CreateInputEventBuffer}. |
|
231 This means that Qt cannot use DirectFB to receive keyboard/mouse events and |
|
232 if you want such events in your application, you will have to provide |
|
233 another driver. For more info see \l {Qt for Embedded Linux Pointer |
|
234 Handling}{Qt for Embedded Linux Pointer Handling} and \l{Qt for Embedded |
|
235 Linux Character Input}{Qt for Embedded Linux Character Input} |
|
236 |
|
237 \row |
|
238 \o QT_DIRECTFB_TIMING |
|
239 \o Define this when debugging to get output on stderr about the |
|
240 frames per second. |
|
241 |
|
242 \row |
|
243 \o QT_NO_DIRECTFB_OPAQUE_DETECTION |
|
244 \o When blitting a surface Qt has to decide whether to set the |
|
245 \l{DirectFB - DFBSurfaceBlittingFlags}{DSBLIT_BLEND_ALPHACHANNEL} |
|
246 flag. If you load an image from file or network data that has a format that |
|
247 includes an alpha channel, the image might still be completely opaque. |
|
248 Normally Qt runs through every pixel to check if there really is an alpha |
|
249 channel there. This involves some overhead but usually pays off in the end |
|
250 because blitting is cheaper than blending. If you define this Qt will |
|
251 assume that an image with a format that has alpha channel contains at least |
|
252 one pixel with an alpha value != 255. |
|
253 |
|
254 \row |
|
255 \o QT_DIRECTFB_SUBSURFACE |
|
256 \o Defining this enables a mode that tries to minimize overhead from |
|
257 locking/unlocking surfaces. Note that this currently is experimental. |
|
258 |
|
259 \row |
|
260 \o QT_DIRECTFB_WINDOW_AS_CURSOR |
|
261 \o Define this if your DirectFB implementation supports windows but |
|
262 can not render the cursor properly. This involves creating a small top level |
|
263 window and moving it around when the cursor moves. It does not always |
|
264 perform well. |
|
265 |
|
266 \row |
|
267 \o QT_NO_DIRECTFB_IMAGEPROVIDER |
|
268 \o By default Qt will use DirectFB to load QPixmaps from disk/memory. If |
|
269 your DirectFB implementation does not support this it might make sense to |
|
270 define this. If you see strange rendering issues with pixmaps that have an |
|
271 alpha channel defining this could solve the problem. |
|
272 |
|
273 \row |
|
274 \o QT_DIRECTFB_IMAGEPROVIDER_KEEPALIVE |
|
275 \o Define this to make sure Qt always keeps at least one |
|
276 \l{DirectFB - IDirectFBImageProvider}{IDirectFBImageProvider} |
|
277 object alive. This is to avoid considerable overhead when the first |
|
278 IDirectFBImageProvider is created, the last IDirectFBImageProvider is |
|
279 removed. |
|
280 |
|
281 \endtable |
|
282 |
|
283 \section2 Unsupported graphics operations |
|
284 |
|
285 There are a number of unsupported operations causing fallbacks. DirectFB |
|
286 does not support the following functions. |
|
287 |
|
288 |
|
289 |
|
290 \table |
|
291 \header |
|
292 \o Functions |
|
293 \row |
|
294 \o QPainter::strokePath(const QPainterPath & path, const QPen & pen) |
|
295 \row |
|
296 \o QPainter::drawPath(const QPainterPath & path) |
|
297 \row |
|
298 \o QPainter::fillPath(const QPainterPath & path, const QBrush & brush) |
|
299 \row |
|
300 \o QPainter::drawPoints(const QPointF * points, int pointCount) |
|
301 \row |
|
302 \o QPainter::drawEllipse(const QRectF & rectangle) |
|
303 \row |
|
304 \o QPainter::drawPolygon(const QPointF * points, int pointCount, |
|
305 Qt::FillRule fillRule = Qt::OddEvenFill) |
|
306 \row |
|
307 \o QPainter::drawText(const QPointF & position, const QString & text) |
|
308 \row |
|
309 \o QGradient |
|
310 \endtable |
|
311 |
|
312 \section2 Avoiding fallbacks |
|
313 To avoid fallbacks make sure that the following points are true: |
|
314 |
|
315 \list |
|
316 \o QPen::isSolid() returns true and uses a color with a one pixel |
|
317 width. (QPen::width() returns 1. |
|
318 \o QTransform::TransformationType() <= QTransform::TxScale are not |
|
319 supported. |
|
320 \o Clipping must be a simple rectangle or a QRegion. |
|
321 \endlist |
|
322 |
|
323 \section2 When painting images |
|
324 \note You should use QPixmap instead of QImage. QImages are drawn by |
|
325 the QRasterPaintEngine. To get a warning for every fallback to the |
|
326 QRasterPaintEngine, use QT_DIRECTFB_WARN_ON_RASTERFALLBACKS. If |
|
327 QT_DIRECTFB_DISABLE_RASTERFALLBACKS is defined, DirectFB will only return |
|
328 instead of falling back to QRasterPaintEngine. Please note that these |
|
329 defines should only be used when optimizing the application. |
|
330 |
|
331 \section2 Top level transparency |
|
332 \note DirectFB supports partially or fully transparent top level windows, |
|
333 either through QWidget::setWindowOpacity or through setting a non-opaque |
|
334 background brush. Note that for the latter it is not supported to change an |
|
335 opaque window to be transparent at runtime. |
|
336 */ |