diff options
Diffstat (limited to 'android/framebuffer.h')
-rw-r--r-- | android/framebuffer.h | 218 |
1 files changed, 218 insertions, 0 deletions
diff --git a/android/framebuffer.h b/android/framebuffer.h new file mode 100644 index 0000000..9d1f626 --- /dev/null +++ b/android/framebuffer.h @@ -0,0 +1,218 @@ +/* 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 ); + +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 ); + +/* 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_ */ |