diff options
author | David 'Digit' Turner <digit@android.com> | 2011-02-02 12:12:53 -0800 |
---|---|---|
committer | Android Code Review <code-review@android.com> | 2011-02-02 12:12:53 -0800 |
commit | d6eda1d7b357746ad8d9a4c80dc0235ef56c40e0 (patch) | |
tree | b669e7b99c01bd8aafd2079321c8cb80302454e0 /android | |
parent | ce747472342237e882369e486254684ab7708362 (diff) | |
parent | 07db34976ba1dd045a51c4ab2c7f52479cddcc57 (diff) | |
download | external_qemu-d6eda1d7b357746ad8d9a4c80dc0235ef56c40e0.zip external_qemu-d6eda1d7b357746ad8d9a4c80dc0235ef56c40e0.tar.gz external_qemu-d6eda1d7b357746ad8d9a4c80dc0235ef56c40e0.tar.bz2 |
Merge changes Icd076267,I6d5ad6ec
* changes:
Simplify UI-only sources.
Simplify core framebuffer management.
Diffstat (limited to 'android')
-rw-r--r-- | android/console.c | 46 | ||||
-rw-r--r-- | android/display-core.c | 124 | ||||
-rw-r--r-- | android/display-core.h | 34 | ||||
-rw-r--r-- | android/framebuffer.c | 9 | ||||
-rw-r--r-- | android/framebuffer.h | 9 | ||||
-rw-r--r-- | android/looper-generic.c | 2 | ||||
-rw-r--r-- | android/main-common.c | 2 | ||||
-rw-r--r-- | android/main-ui.c | 11 | ||||
-rw-r--r-- | android/protocol/fb-updates-proxy.c | 70 | ||||
-rw-r--r-- | android/protocol/fb-updates-proxy.h | 13 | ||||
-rw-r--r-- | android/protocol/ui-commands-impl.c | 4 | ||||
-rw-r--r-- | android/qemulator.c | 6 |
12 files changed, 109 insertions, 221 deletions
diff --git a/android/console.c b/android/console.c index d776a5c..d883002 100644 --- a/android/console.c +++ b/android/console.c @@ -121,9 +121,6 @@ typedef struct ControlGlobalRec_ /* UI client currently attached to the core. */ ControlClient attached_ui_client = NULL; -/* Core framebuffer service client. */ -ControlClient framebuffer_client = NULL; - /* User events service client. */ ControlClient user_events_client = NULL; @@ -245,15 +242,6 @@ control_client_destroy( ControlClient client ) attached_ui_client = NULL; } - if (client == framebuffer_client) { - ProxyFramebuffer* core_fb = coredisplay_detach_fb_service(); - if (core_fb != NULL) { - proxyFb_destroy(core_fb); - AFREE(core_fb); - } - framebuffer_client = NULL; - } - if (client == user_events_client) { userEventsImpl_destroy(); user_events_client = NULL; @@ -2525,14 +2513,12 @@ destroy_attach_ui_client(void) } } -/* Core display instance. */ -extern CoreDisplay core_display; - static int do_create_framebuffer_service( ControlClient client, char* args ) { ProxyFramebuffer* core_fb; const char* protocol = "-raw"; // Default framebuffer exchange protocol. + char reply_buf[64]; // Protocol type is defined by the arguments passed with the stream switch // command. @@ -2555,38 +2541,20 @@ do_create_framebuffer_service( ControlClient client, char* args ) } } - // Make sure that there are no framebuffer client already existing. - if (framebuffer_client != NULL) { - control_write( client, "KO: Another framebuffer service is already existing!\r\n" ); - control_client_destroy(client); - return -1; - } - - core_fb = proxyFb_create(client->sock, protocol, coredisplay_get_framebuffer()); - if (!coredisplay_attach_fb_service(core_fb)) { - char reply_buf[4096]; - framebuffer_client = client; - // Reply "OK" with the framebuffer's bits per pixel - snprintf(reply_buf, sizeof(reply_buf), "OK: -bitsperpixel=%d\r\n", - proxyFb_get_bits_per_pixel(core_fb)); - control_write( client, reply_buf); - } else { + core_fb = proxyFb_create(client->sock, protocol); + if (core_fb == NULL) { control_write( client, "KO\r\n" ); control_client_destroy(client); return -1; } + // Reply "OK" with the framebuffer's bits per pixel + snprintf(reply_buf, sizeof(reply_buf), "OK: -bitsperpixel=%d\r\n", + proxyFb_get_bits_per_pixel(core_fb)); + control_write( client, reply_buf); return 0; } -void -destroy_control_fb_client(void) -{ - if (framebuffer_client != NULL) { - control_client_destroy(framebuffer_client); - } -} - static int do_create_user_events_service( ControlClient client, char* args ) { diff --git a/android/display-core.c b/android/display-core.c index 6834cd6..80b7665 100644 --- a/android/display-core.c +++ b/android/display-core.c @@ -15,120 +15,54 @@ * by the core to communicate display changes to the attached UI */ -#include "android/utils/system.h" #include "android/display-core.h" +#include "qemu-common.h" -/* Core display descriptor. */ -struct CoreDisplay { - /* Display state for this core display. */ - DisplayState* ds; - - /* Framebuffer for this core display. */ - QFrameBuffer* fb; - - /* Framebuffer service associated with this core display. */ - ProxyFramebuffer* core_fb; -}; - -/* One and only one core display instance. */ -CoreDisplay core_display; - -/* - * Framebuffer calls this routine when it detects changes. This routine will - * initiate a "push" of the framebuffer changes to the UI. - * See QFrameBufferUpdateFunc in framebuffer.h for more info on this callback. - */ -static void -coredisplay_fb_update(void* opaque, int x, int y, int w, int h) -{ - CoreDisplay* cd = (CoreDisplay*)opaque; - if (cd->core_fb) { - proxyFb_update(cd->core_fb, cd->fb, x, y, w, h); - } -} - -/* - * Framebuffer callback. See QFrameBufferRotateFunc in framebuffer.h for more - * info on this callback. +/* This callback is call periodically by the GUI timer. + * Its purpose is to ensure that hw framebuffer updates are properly + * detected. Call the normal QEMU function for this here. */ static void -coredisplay_fb_rotate(void* opaque, int rotation) +coredisplay_refresh(DisplayState* ds) { + (void)ds; + vga_hw_update(); } -/* - * Framebuffer callback. See QFrameBufferPollFunc in framebuffer.h for more - * info on this callback. +/* Don't do anything here because this callback can't differentiate + * between several listeners. This will be handled by a DisplayUpdateListener + * instead. See Android-specific changes in console.h + * + * In the core, the DisplayUpdateListener is registered by the ProxyFramebuffer + * object. See android/protocol/fb-updates-proxy.c. */ static void -coredisplay_fb_poll(void* opaque) +coredisplay_update(DisplayState* ds, int x, int y, int w, int h) { - // This will eventually call core_display_fb_update. - qframebuffer_check_updates(); + (void)ds; + (void)x; + (void)y; + (void)w; + (void)h; } -/* - * Framebuffer callback. See QFrameBufferDoneFunc in framebuffer.h for more - * info on this callback. +/* This callback is normally used to indicate that the display resolution + * was changed by the guest (e.g. when a Windows PC changes the display from + * 1024x768 to 800x600. Since this doesn't happen in Android, ignore it. */ static void -coredisplay_fb_done(void* opaque) +coredisplay_resize(DisplayState* ds) { + (void)ds; } void coredisplay_init(DisplayState* ds) { - int format; - - core_display.ds = ds; - /* Create and initialize framebuffer instance that will be used for core - * display. - */ - ANEW0(core_display.fb); - core_display.core_fb = NULL; - - /* In the core, there is no skin to parse and the format of ds->surface - * is determined by the -android-gui option. - */ - format = QFRAME_BUFFER_RGB565; - if (ds->surface->pf.bytes_per_pixel == 4) - format = QFRAME_BUFFER_RGBX_8888; - - qframebuffer_init(core_display.fb, ds->surface->width, ds->surface->height, - 0, format); - qframebuffer_fifo_add(core_display.fb); - /* Register core display as the client for the framebuffer, so we can start - * receiving framebuffer notifications. Note that until UI connects to the - * core all framebuffer callbacks are essentially no-ops. - */ - qframebuffer_add_client(core_display.fb, &core_display, - coredisplay_fb_update, coredisplay_fb_rotate, - coredisplay_fb_poll, coredisplay_fb_done); - android_display_init(ds, core_display.fb); -} - -int -coredisplay_attach_fb_service(ProxyFramebuffer* core_fb) -{ - if (core_display.core_fb == NULL) { - core_display.core_fb = core_fb; - return 0; - } else { - return -1; - } -} - -ProxyFramebuffer* -coredisplay_detach_fb_service(void) -{ - ProxyFramebuffer* ret = core_display.core_fb; - core_display.core_fb = NULL; - return ret; -} + static DisplayChangeListener dcl[1]; -QFrameBuffer* -coredisplay_get_framebuffer(void) -{ - return core_display.fb; + dcl->dpy_update = coredisplay_update; + dcl->dpy_refresh = coredisplay_refresh; + dcl->dpy_resize = coredisplay_resize; + register_displaychangelistener(ds, dcl); } diff --git a/android/display-core.h b/android/display-core.h index edeccac..e6a1b7d 100644 --- a/android/display-core.h +++ b/android/display-core.h @@ -18,42 +18,14 @@ #ifndef _ANDROID_DISPLAY_CORE_H #define _ANDROID_DISPLAY_CORE_H -#include "android/framebuffer.h" -#include "android/display.h" -#include "android/protocol/fb-updates-proxy.h" - -/* Descriptor for a core display instance */ -typedef struct CoreDisplay CoreDisplay; +#include "console.h" /* * Initializes one and only one instance of a core display. - * Param: + * Only used to register a dummy display change listener that + * will trigger a timer. * ds - Display state to use for the core display. */ extern void coredisplay_init(DisplayState* ds); -/* - * Attaches framebuffer service to the core display. - * Param: - * core_fb - Framebuffer service descriptor to attach. - * Return: - * 0 on success, or -1 on failure. - */ -extern int coredisplay_attach_fb_service(ProxyFramebuffer* core_fb); - -/* - * Detaches framebuffer service previously attached to the core display. - * Return: - * Framebuffer service descriptor attached to the core display, or NULL if - * the core display didn't have framebuffer service attached to it. - */ -extern ProxyFramebuffer* coredisplay_detach_fb_service(void); - -/* - * Get framebuffer descriptor for core display. - * Return: - * Framebuffer descriptor for core display. - */ -extern QFrameBuffer* coredisplay_get_framebuffer(void); - #endif /* _ANDROID_DISPLAY_CORE_H */ diff --git a/android/framebuffer.c b/android/framebuffer.c index 53c6a48..b9b968e 100644 --- a/android/framebuffer.c +++ b/android/framebuffer.c @@ -281,6 +281,15 @@ qframebuffer_check_updates( void ) } void +qframebuffer_pulse( void ) +{ + int nn; + for (nn = 0; nn < framebuffer_fifo_count; nn++) { + qframebuffer_poll(framebuffer_fifo[nn]); + } +} + +void qframebuffer_invalidate_all( void ) { int nn; diff --git a/android/framebuffer.h b/android/framebuffer.h index 9d1f626..faf2f41 100644 --- a/android/framebuffer.h +++ b/android/framebuffer.h @@ -172,6 +172,10 @@ qframebuffer_update( QFrameBuffer* qfbuff, int x, int y, int w, int h ); 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 ); @@ -188,6 +192,11 @@ qframebuffer_done( QFrameBuffer* qfbuff ); 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 */ diff --git a/android/looper-generic.c b/android/looper-generic.c index 6ec0db4..d75fbff 100644 --- a/android/looper-generic.c +++ b/android/looper-generic.c @@ -289,7 +289,7 @@ glooper_addActiveTimer(GLooper* looper, GLoopTimer* tt) pnode = &node->activeNext; } tt->activeNext = *pnode; - *pnode = tt->activeNext; + *pnode = tt; } static void diff --git a/android/main-common.c b/android/main-common.c index 23ba5b9..bcae501 100644 --- a/android/main-common.c +++ b/android/main-common.c @@ -315,7 +315,9 @@ void sdl_display_init(DisplayState *ds, int full_screen, int no_frame) } snprintf(buf, sizeof buf, "width=%d,height=%d", width, height); +#if !defined(CONFIG_STANDALONE_UI) && !defined(CONFIG_STANDALONE_CORE) android_display_init(ds, qframebuffer_fifo_get()); +#endif } /* list of skin aliases */ diff --git a/android/main-ui.c b/android/main-ui.c index 9981b76..daf71cb 100644 --- a/android/main-ui.c +++ b/android/main-ui.c @@ -1507,16 +1507,5 @@ int main(int argc, char **argv) } } - // Connect to the core's framebuffer service - if (implFb_create(attachUiImpl_get_console_socket(), "-raw", - qemulator_get_first_framebuffer(qemulator_get()))) { - return -1; - } - - // Attach the recepient of UI commands. - if (uiCmdImpl_create(attachUiImpl_get_console_socket())) { - return -1; - } - return qemu_main(n, args); } diff --git a/android/protocol/fb-updates-proxy.c b/android/protocol/fb-updates-proxy.c index 359c942..ec7414d 100644 --- a/android/protocol/fb-updates-proxy.c +++ b/android/protocol/fb-updates-proxy.c @@ -16,7 +16,6 @@ */ #include "console.h" -#include "android/framebuffer.h" #include "android/looper.h" #include "android/display-core.h" #include "android/async-utils.h" @@ -37,8 +36,9 @@ struct ProxyFramebuffer { /* I/O associated with this descriptor. */ LoopIo io; - /* Framebuffer used for this service. */ - QFrameBuffer* fb; + /* Display state used for this service */ + DisplayState* ds; + DisplayUpdateListener* ds_listener; /* Looper used to communicate framebuffer updates. */ Looper* looper; @@ -80,9 +80,9 @@ typedef struct FBUpdateNotify { * Pointer in framebuffer's pixels for the given pixel. */ static const uint8_t* -_pixel_offset(const QFrameBuffer* fb, int x, int y) +_pixel_offset(const DisplaySurface* dsu, int x, int y) { - return (const uint8_t*)fb->pixels + y * fb->pitch + x * fb->bytes_per_pixel; + return (const uint8_t*)dsu->data + y * dsu->linesize + x * dsu->pf.bytes_per_pixel; } /* @@ -93,13 +93,13 @@ _pixel_offset(const QFrameBuffer* fb, int x, int y) * x, y, w, and h - dimensions of the rectangle to copy. */ static void -_copy_fb_rect(uint8_t* rect, const QFrameBuffer* fb, int x, int y, int w, int h) +_copy_fb_rect(uint8_t* rect, const DisplaySurface* dsu, int x, int y, int w, int h) { - const uint8_t* start = _pixel_offset(fb, x, y); + const uint8_t* start = _pixel_offset(dsu, x, y); for (; h > 0; h--) { - memcpy(rect, start, w * fb->bytes_per_pixel); - start += fb->pitch; - rect += w * fb->bytes_per_pixel; + memcpy(rect, start, w * dsu->pf.bytes_per_pixel); + start += dsu->linesize; + rect += w * dsu->pf.bytes_per_pixel; } } @@ -113,10 +113,10 @@ _copy_fb_rect(uint8_t* rect, const QFrameBuffer* fb, int x, int y, int w, int h) * Initialized framebuffer update notification descriptor. */ static FBUpdateNotify* -fbupdatenotify_create(ProxyFramebuffer* proxy_fb, const QFrameBuffer* fb, +fbupdatenotify_create(ProxyFramebuffer* proxy_fb, int x, int y, int w, int h) { - const size_t rect_size = w * h * fb->bytes_per_pixel; + const size_t rect_size = w * h * proxy_fb->ds->surface->pf.bytes_per_pixel; FBUpdateNotify* ret = malloc(sizeof(FBUpdateNotify) + rect_size); ret->next_fb_update = NULL; @@ -126,7 +126,7 @@ fbupdatenotify_create(ProxyFramebuffer* proxy_fb, const QFrameBuffer* fb, ret->message.y = y; ret->message.w = w; ret->message.h = h; - _copy_fb_rect(ret->message.rect, fb, x, y, w, h); + _copy_fb_rect(ret->message.rect, proxy_fb->ds->surface, x, y, w, h); return ret; } @@ -143,9 +143,6 @@ fbupdatenotify_delete(FBUpdateNotify* desc) } } -/* Implemented in android/console.c */ -extern void destroy_control_fb_client(void); - /* * Asynchronous write I/O callback launched when writing framebuffer * notifications to the socket. @@ -191,6 +188,8 @@ _proxyFb_io_write(ProxyFramebuffer* proxy_fb) } } +static void proxyFb_update(void* opaque, int x, int y, int w, int h); + /* * Asynchronous read I/O callback launched when reading framebuffer requests * from the socket. @@ -201,6 +200,7 @@ static void _proxyFb_io_read(ProxyFramebuffer* proxy_fb) { // Read the request header. + DisplaySurface* dsu; const AsyncStatus status = asyncReader_read(&proxy_fb->fb_req_reader, &proxy_fb->io); switch (status) { @@ -209,9 +209,9 @@ _proxyFb_io_read(ProxyFramebuffer* proxy_fb) switch (proxy_fb->fb_req_header.request_type) { case AFB_REQUEST_REFRESH: // Force full screen update to be sent - proxyFb_update(proxy_fb, proxy_fb->fb, - 0, 0, proxy_fb->fb->width, - proxy_fb->fb->height); + dsu = proxy_fb->ds->surface; + proxyFb_update(proxy_fb, + 0, 0, dsu->width, dsu->height); break; default: derror("Unknown framebuffer request %d\n", @@ -226,7 +226,7 @@ _proxyFb_io_read(ProxyFramebuffer* proxy_fb) loopIo_dontWantRead(&proxy_fb->io); if (errno == ECONNRESET) { // UI has exited. We need to destroy framebuffer service. - destroy_control_fb_client(); + proxyFb_destroy(proxy_fb); } break; @@ -253,14 +253,24 @@ _proxyFb_io_fun(void* opaque, int fd, unsigned events) } ProxyFramebuffer* -proxyFb_create(int sock, const char* protocol, QFrameBuffer* fb) +proxyFb_create(int sock, const char* protocol) { // At this point we're implementing the -raw protocol only. ProxyFramebuffer* ret; + DisplayState* ds = get_displaystate(); + DisplayUpdateListener* dul; + ANEW0(ret); ret->sock = sock; ret->looper = looper_newCore(); - ret->fb = fb; + ret->ds = ds; + + ANEW0(dul); + dul->opaque = ret; + dul->dpy_update = proxyFb_update; + register_displayupdatelistener(ds, dul); + ret->ds_listener = dul; + ret->fb_update_head = NULL; ret->fb_update_tail = NULL; loopIo_init(&ret->io, ret->looper, sock, _proxyFb_io_fun, ret); @@ -273,6 +283,7 @@ void proxyFb_destroy(ProxyFramebuffer* proxy_fb) { if (proxy_fb != NULL) { + unregister_displayupdatelistener(proxy_fb->ds, proxy_fb->ds_listener); if (proxy_fb->looper != NULL) { // Stop all I/O that may still be going on. loopIo_done(&proxy_fb->io); @@ -286,15 +297,16 @@ proxyFb_destroy(ProxyFramebuffer* proxy_fb) looper_free(proxy_fb->looper); proxy_fb->looper = NULL; } + AFREE(proxy_fb); } } -void -proxyFb_update(ProxyFramebuffer* proxy_fb, - struct QFrameBuffer* fb, int x, int y, int w, int h) +static void +proxyFb_update(void* opaque, int x, int y, int w, int h) { + ProxyFramebuffer* proxy_fb = opaque; AsyncStatus status; - FBUpdateNotify* descr = fbupdatenotify_create(proxy_fb, fb, x, y, w, h); + FBUpdateNotify* descr = fbupdatenotify_create(proxy_fb, x, y, w, h); // Lets see if we should list it behind other pending updates. if (proxy_fb->fb_update_tail != NULL) { @@ -327,6 +339,8 @@ proxyFb_update(ProxyFramebuffer* proxy_fb, int proxyFb_get_bits_per_pixel(ProxyFramebuffer* proxy_fb) { - return (proxy_fb != NULL && proxy_fb->fb != NULL) ? - proxy_fb->fb->bits_per_pixel : -1; + if (proxy_fb == NULL || proxy_fb->ds == NULL) + return -1; + + return proxy_fb->ds->surface->pf.bits_per_pixel; } diff --git a/android/protocol/fb-updates-proxy.h b/android/protocol/fb-updates-proxy.h index e750f1a..15b1d5b 100644 --- a/android/protocol/fb-updates-proxy.h +++ b/android/protocol/fb-updates-proxy.h @@ -29,11 +29,10 @@ typedef struct ProxyFramebuffer ProxyFramebuffer; * supported values ar: * -raw Transfers the updating rectangle buffer over the socket. * -shared Used a shared memory to transfer the updating rectangle buffer. - * fb - Framebuffer descriptor for this service. * Return: * Framebuffer service descriptor. */ -ProxyFramebuffer* proxyFb_create(int sock, const char* protocol, struct QFrameBuffer* fb); +ProxyFramebuffer* proxyFb_create(int sock, const char* protocol); /* * Destroys framebuffer service created with proxyFb_create. @@ -43,16 +42,6 @@ ProxyFramebuffer* proxyFb_create(int sock, const char* protocol, struct QFrameBu void proxyFb_destroy(ProxyFramebuffer* core_fb); /* - * Notifies framebuffer client about changes in framebuffer. - * Param: - * core_fb - Framebuffer service descriptor created with proxyFb_create - * fb Framebuffer containing pixels. - * x, y, w, and h identify the rectangle that has benn changed. - */ -void proxyFb_update(ProxyFramebuffer* core_fb, struct QFrameBuffer* fb, - int x, int y, int w, int h); - -/* * Gets number of bits used to encode a single pixel. * Param: * core_fb - Framebuffer service descriptor created with proxyFb_create diff --git a/android/protocol/ui-commands-impl.c b/android/protocol/ui-commands-impl.c index f265514..2ca4194 100644 --- a/android/protocol/ui-commands-impl.c +++ b/android/protocol/ui-commands-impl.c @@ -124,7 +124,7 @@ _uiCmdImpl_io_read(void* opaque) status = read(uicmd->sock, uicmd->reader_buffer + uicmd->reader_offset, uicmd->reader_bytes - uicmd->reader_offset); if (status == 0) { - /* Disconnection, meaning that the core process got termonated. */ + /* Disconnection, meaning that the core process got terminated. */ fprintf(stderr, "core-ui-control service got disconnected\n"); uiCmdImpl_destroy(); return; @@ -201,7 +201,7 @@ uiCmdImpl_create(SockAddress* console_socket) return -1; } - // Initialze UI command reader. + // Initialize UI command reader. _uiCmdImpl.sock = core_connection_get_socket(_uiCmdImpl.core_connection); if (qemu_set_fd_handler(_uiCmdImpl.sock, _uiCmdImpl_io_read, NULL, &_uiCmdImpl)) { diff --git a/android/qemulator.c b/android/qemulator.c index 36a9ec8..c90a674 100644 --- a/android/qemulator.c +++ b/android/qemulator.c @@ -97,8 +97,10 @@ qemulator_fb_update( void* _emulator, int x, int y, int w, int h ) { QEmulator* emulator = _emulator; - if (emulator->window) - skin_window_update_display( emulator->window, x, y, w, h ); + if (!emulator->window) { + qemulator_setup( emulator ); + } + skin_window_update_display( emulator->window, x, y, w, h ); } static void |