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
|
/* Copyright (C) 2007-2008 The Android Open Source Project
**
** This software is licensed under the terms of the GNU General Public
** License version 2, as published by the Free Software Foundation, and
** may be copied, distributed, and modified under those terms.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
*/
#ifndef _ANDROID_FRAMEBUFFER_H_
#define _ANDROID_FRAMEBUFFER_H_
/* A simple abstract interface to framebuffer displays. this is used to
* de-couple hardware emulation from final display.
*
* Each QFrameBuffer object holds a pixel buffer that is shared between
* one 'Producer' and one or more 'Clients'
*
* The Producer is in charge of updating the pixel buffer from the state
* of the emulated VRAM. A Client listens to updates to the pixel buffer,
* sent from the producer through qframebuffer_update()/_rotate() and
* displays them.
*
* note the 'rotation' field: it can take values 0, 1, 2 or 3 and corresponds
* to a rotation that must be performed to the pixels stored in the framebuffer
* *before* displaying them a value of 1 corresponds to a rotation of
* 90 clockwise-degrees, when the framebuffer is rotated 90 or 270 degrees,
* its width/height are swapped automatically
*
* phys_width_mm and phys_height_mm are physical dimensions expressed
* in millimeters
*
* More about the client/producer relationships below.
*/
typedef struct QFrameBuffer QFrameBuffer;
typedef enum {
QFRAME_BUFFER_NONE = 0,
QFRAME_BUFFER_RGB565 = 1,
QFRAME_BUFFER_RGBX_8888 = 2,
QFRAME_BUFFER_MAX /* do not remove */
} QFrameBufferFormat;
struct QFrameBuffer {
int width; /* width in pixels */
int height; /* height in pixels */
int pitch; /* bytes per line */
int bits_per_pixel; /* bits per pixel */
int bytes_per_pixel; /* bytes per pixel */
int rotation; /* rotation to be applied when displaying */
QFrameBufferFormat format;
void* pixels; /* pixel buffer */
int phys_width_mm;
int phys_height_mm;
/* extra data that is handled by the framebuffer implementation */
void* extra;
};
/* the default dpi resolution of a typical framebuffer. this is an average
* between various prototypes being used during the development of the
* Android system...
*/
#define DEFAULT_FRAMEBUFFER_DPI 165
/* initialize a framebuffer object and allocate its pixel buffer */
/* this computes phys_width_mm and phys_height_mm assuming a 165 dpi screen */
/* returns -1 in case of error, 0 otherwise */
extern int
qframebuffer_init( QFrameBuffer* qfbuff,
int width,
int height,
int rotation,
QFrameBufferFormat format );
/* recompute phys_width_mm and phys_height_mm according to the emulated
* screen DPI settings */
extern void
qframebuffer_set_dpi( QFrameBuffer* qfbuff,
int x_dpi,
int y_dpi );
/* alternative to qframebuffer_set_dpi where one can set the physical
* dimensions directly in millimeters. for the record 1 inch = 25.4 mm */
extern void
qframebuffer_set_mm( QFrameBuffer* qfbuff,
int width_mm,
int height_mm );
/* the Client::Update method is called to instruct a client that a given
* rectangle of the framebuffer pixels was updated and needs to be
* redrawn.
*/
typedef void (*QFrameBufferUpdateFunc)( void* opaque, int x, int y,
int w, int h );
/* the Client::Rotate method is called to instruct the client that a
* framebuffer's internal rotation has changed. This is the rotation
* that must be applied before displaying the pixels.
*
* Note that it is assumed that all framebuffer pixels have changed too
* so the client should call its Update method as well.
*/
typedef void (*QFrameBufferRotateFunc)( void* opaque, int rotation );
/* the Client::Poll method is called periodically to poll for input
* events and act on them. Putting this here is not 100% pure but
* make things simpler due to QEMU's weird architecture where the
* GUI timer drivers event polling.
*/
typedef void (*QFrameBufferPollFunc)( void* opaque );
/* the Client::Done func tells a client that a framebuffer object was freed.
* no more reference to its pixels should be done.
*/
typedef void (*QFrameBufferDoneFunc) ( void* opaque );
/* add one client to a given framebuffer.
* the current implementation only allows one client per frame-buffer,
* but we could allow more for various reasons (e.g. displaying the
* framebuffer + dispatching it through VNC at the same time)
*/
extern void
qframebuffer_add_client( QFrameBuffer* qfbuff,
void* fb_opaque,
QFrameBufferUpdateFunc fb_update,
QFrameBufferRotateFunc fb_rotate,
QFrameBufferPollFunc fb_poll,
QFrameBufferDoneFunc fb_done );
/* Producer::CheckUpdate is called to let the producer check the
* VRAM state (e.g. VRAM dirty pages) to see if anything changed since the
* last call to the method. When true, the method should call either
* qframebuffer_update() or qframebuffer_rotate() with the appropriate values.
*/
typedef void (*QFrameBufferCheckUpdateFunc)( void* opaque );
/* Producer::Invalidate tells the producer that the next call to
* CheckUpdate should act as if the whole content of VRAM had changed.
* this is normally done to force client initialization/refreshes.
*/
typedef void (*QFrameBufferInvalidateFunc) ( void* opaque );
/* the Producer::Detach method is used to tell the producer that the
* underlying QFrameBuffer object is about to be de-allocated.
*/
typedef void (*QFrameBufferDetachFunc) ( void* opaque );
/* set the producer of a given framebuffer */
extern void
qframebuffer_set_producer( QFrameBuffer* qfbuff,
void* opaque,
QFrameBufferCheckUpdateFunc fb_check,
QFrameBufferInvalidateFunc fb_invalidate,
QFrameBufferDetachFunc fb_detach );
/* tell a client that a rectangle region has been updated in the framebuffer
* pixel buffer this is typically called from a Producer::CheckUpdate method
*/
extern void
qframebuffer_update( QFrameBuffer* qfbuff, int x, int y, int w, int h );
/* rotate the framebuffer (may swap width/height), and tell all clients.
* Should be called from a Producer::CheckUpdate method
*/
extern void
qframebuffer_rotate( QFrameBuffer* qfbuff, int rotation );
/* this function is used to poll a framebuffer's client for input
* events. Should be called either explicitely, or through qframebuffer_pulse()
* periodically.
*/
extern void
qframebuffer_poll( QFrameBuffer* qfbuff );
/* finalize a framebuffer, release its pixel buffer. Should be called
* from the framebuffer object's owner
*/
extern void
qframebuffer_done( QFrameBuffer* qfbuff );
/* this is called repeatedly by the emulator. for each registered framebuffer,
* call its producer's CheckUpdate method, if any.
*/
extern void
qframebuffer_check_updates( void );
/* call this function periodically to force a poll on all franebuffers
*/
extern void
qframebuffer_pulse( void );
/* this is called by the emulator. for each registered framebuffer, call
* its producer's Invalidate method, if any
*/
extern void
qframebuffer_invalidate_all( void );
/*
* to completely separate the implementation of clients, producers, and skins,
* we use a simple global FIFO list of QFrameBuffer objects.
*
* qframebuffer_fifo_add() is typically called by the emulator initialization
* depending on the emulated device's configuration
*
* qframebuffer_fifo_get() is typically called by a hardware framebuffer
* emulation.
*/
/* add a new constructed frame buffer object to our global list */
extern void
qframebuffer_fifo_add( QFrameBuffer* qfbuff );
/* retrieve a frame buffer object from the global FIFO list */
extern QFrameBuffer*
qframebuffer_fifo_get( void );
/* */
#endif /* _ANDROID_FRAMEBUFFER_H_ */
|