source: trunk/doc/src/examples/svgalib.qdoc@ 677

Last change on this file since 677 was 651, checked in by Dmitry A. Kuminov, 16 years ago

trunk: Merged in qt 4.6.2 sources.

File size: 15.2 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the documentation of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
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** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42/*!
43 \example qws/svgalib
44 \title Accelerated Graphics Driver Example
45
46 The Accelerated Graphics Driver example shows how you can write
47 your own accelerated graphics driver and \l {add your graphics
48 driver to Qt for Embedded Linux}. In \l{Qt for Embedded Linux},
49 painting is a pure software implementation and is normally performed
50 in two steps:
51 The clients render each window onto a corresponding surface
52 (stored in memory) using a paint engine, and then the server uses
53 the graphics driver to compose the surface images and copy them to
54 the screen. (See the \l{Qt for Embedded Linux Architecture} documentation
55 for details.)
56
57 The rendering can be accelerated in two ways: Either by
58 accelerating the copying of pixels to the screen, or by
59 accelerating the explicit painting operations. The first is done
60 in the graphics driver implementation, the latter is performed by
61 the paint engine implementation. Typically, both the pixel copying
62 and the painting operations are accelerated using the following
63 approach:
64
65 \list 1
66 \o \l {Step 1: Creating a Custom Graphics Driver}
67 {Creating a Custom Graphics Driver}
68
69 \o \l {Step 2: Implementing a Custom Raster Paint Engine}
70 {Implementing a Custom Paint Engine}
71
72 \o \l {Step 3: Making the Widgets Aware of the Custom Paint
73 Engine}{Making the Widgets Aware of the Custom Paint Engine}
74
75 \endlist
76
77 After compiling the example code, install the graphics driver
78 plugin with the command \c {make install}. To start an application
79 using the graphics driver, you can either set the environment
80 variable \l QWS_DISPLAY and then run the application, or you can
81 just run the application using the \c -display switch:
82
83 \snippet doc/src/snippets/code/doc_src_examples_svgalib.qdoc 0
84
85 \table
86 \header \o SVGAlib
87 \row \o
88
89 Instead of interfacing the graphics hardware directly, this
90 example relies on \l {http://www.svgalib.org}{SVGAlib} being
91 installed on your system. \l {http://www.svgalib.org}{SVGAlib} is
92 a small graphics library which provides acceleration for many
93 common graphics cards used on desktop computers. It should work on
94 most workstations and has a small and simple API.
95
96 \endtable
97
98 \section1 Step 1: Creating a Custom Graphics Driver
99
100 The custom graphics driver is created by deriving from the QScreen
101 class. QScreen is the base class for implementing screen/graphics
102 drivers in Qt for Embedded Linux.
103
104 \snippet examples/qws/svgalib/svgalibscreen.h 0
105 \codeline
106 \snippet examples/qws/svgalib/svgalibscreen.h 1
107
108 The \l {QScreen::}{connect()}, \l {QScreen::}{disconnect()}, \l
109 {QScreen::}{initDevice()} and \l {QScreen::}{shutdownDevice()}
110 functions are declared as pure virtual functions in QScreen and
111 must be implemented. They are used to configure the hardware, or
112 query its configuration: \l {QScreen::}{connect()} and \l
113 {QScreen::}{disconnect()} are called by both the server and client
114 processes, while the \l {QScreen::}{initDevice()} and \l
115 {QScreen::}{shutdownDevice()} functions are only called by the
116 server process.
117
118 QScreen's \l {QScreen::}{setMode()} and \l {QScreen::}{blank()}
119 functions are also pure virtual, but our driver's implementations
120 are trivial. The last two functions (\l {QScreen::}{blit()} and \l
121 {QScreen::}{solidFill()}) are the ones involved in putting pixels
122 on the screen, i.e., we reimplement these functions to perform the
123 pixel copying acceleration.
124
125 Finally, the \c context variable is a pointer to a \l
126 {http://www.svgalib.org}{SVGAlib} specific type. Note that the
127 details of using the \l {http://www.svgalib.org}{SVGAlib} library
128 is beyond the scope of this example.
129
130 \section2 SvgalibScreen Class Implementation
131
132 The \l {QScreen::}{connect()} function is the first function that
133 is called after the constructor returns. It queries \l
134 {http://www.svgalib.org}{SVGAlib} about the graphics mode and
135 initializes the variables.
136
137 \snippet examples/qws/svgalib/svgalibscreen.cpp 0
138
139 It is important that the \l {QScreen::}{connect()} function
140 initializes the \c data, \c lstep, \c w, \c h, \c dw, \c dh, \c d,
141 \c physWidth and \c physHeight variables (inherited from QScreen)
142 to ensure that the driver is in a state consistent with the driver
143 configuration.
144
145 In this particular example we do not have any information of the
146 real physical size of the screen, so we set these values with the
147 assumption of a screen with 72 DPI.
148
149 \snippet examples/qws/svgalib/svgalibscreen.cpp 1
150
151 When the \l {QScreen::}{connect()} function returns, the server
152 process calls the \l {QScreen::}{initDevice()} function which is
153 expected to do the necessary hardware initialization, leaving the
154 hardware in a state consistent with the driver configuration.
155
156 Note that we have chosen to use the software cursor. If you want
157 to use a hardware cursor, you should create a subclass of
158 QScreenCursor, create an instance of it, and make the global
159 variable \c qt_screencursor point to this instance.
160
161 \snippet examples/qws/svgalib/svgalibscreen.cpp 2
162 \codeline
163 \snippet examples/qws/svgalib/svgalibscreen.cpp 3
164
165 Before exiting, the server process will call the \l
166 {QScreen::}{shutdownDevice()} function to do the necessary
167 hardware cleanup. Again, it is important that the function leaves
168 the hardware in a state consistent with the driver
169 configuration. When \l {QScreen::}{shutdownDevice()} returns, the
170 \l {QScreen::}{disconnect()} function is called. Our
171 implementation of the latter function is trivial.
172
173 Note that, provided that the \c QScreen::data variable points to a
174 valid linear framebuffer, the graphics driver is fully functional
175 as a simple screen driver at this point. The rest of this example
176 will show where to take advantage of the accelerated capabilities
177 available on the hardware.
178
179 Whenever an area on the screen needs to be updated, the server will
180 call the \l {QScreen::}{exposeRegion()} function that paints the
181 given region on screen. The default implementation will do the
182 necessary composing of the top-level windows and call \l
183 {QScreen::}{solidFill()} and \l {QScreen::}{blit()} whenever it is
184 required. We do not want to change this behavior in the driver so
185 we do not reimplement \l {QScreen::}{exposeRegion()}.
186
187 To control how the pixels are put onto the screen we need to
188 reimplement the \l {QScreen::}{solidFill()} and \l
189 {QScreen::}{blit()} functions.
190
191 \snippet examples/qws/svgalib/svgalibscreen.cpp 4
192 \codeline
193 \snippet examples/qws/svgalib/svgalibscreen.cpp 5
194
195 \section1 Step 2: Implementing a Custom Raster Paint Engine
196
197 \l{Qt for Embedded Linux} uses QRasterPaintEngine (a raster-based
198 implementation of QPaintEngine) to implement the painting
199 operations.
200
201 Acceleration of the painting operations is done by deriving from
202 QRasterPaintEngine class. This is a powerful mechanism for
203 accelerating graphic primitives while getting software fallbacks
204 for all the primitives you do not accelerate.
205
206 \snippet examples/qws/svgalib/svgalibpaintengine.h 0
207
208 In this example, we will only accelerate one of the \l
209 {QRasterPaintEngine::}{drawRects()} functions, i.e., only
210 non-rotated, aliased and opaque rectangles will be rendered using