aboutsummaryrefslogtreecommitdiffstats
path: root/android/framebuffer.h
blob: faf2f41399ffcdd0ff1ec99641396bd974bcf690 (plain)
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_ */