diff options
-rw-r--r-- | Makefile.android | 17 | ||||
-rw-r--r-- | android/main.c | 19 | ||||
-rw-r--r-- | android/utils/mapfile.c | 2 | ||||
-rw-r--r-- | docs/ANDROID-FRAMEBUFFER.TXT | 88 | ||||
-rw-r--r-- | elff/elff-common.h | 2 |
5 files changed, 121 insertions, 7 deletions
diff --git a/Makefile.android b/Makefile.android index 0b719e0..38ad685 100644 --- a/Makefile.android +++ b/Makefile.android @@ -659,6 +659,8 @@ endif # LOCAL_CFLAGS += $(SDL_CFLAGS) LOCAL_LDLIBS += $(SDL_LDLIBS) +# Circular dependencies between libSDL and libSDLmain; +# We repeat the libraries in the final link to work around it. LOCAL_STATIC_LIBRARIES += libSDL libSDLmain LOCAL_STATIC_LIBRARIES += libSDL libSDLmain @@ -671,11 +673,19 @@ LOCAL_LDLIBS += $(ELFF_LDLIBS) # to use some weird pathnames to make this work... # ifeq ($(HOST_OS),windows) + +# Locate windres executable +WINDRES := windres +ifneq ($(USE_MINGW),) + # When building the Windows emulator under Linux, use the MinGW one + WINDRES := i586-mingw32msvc-windres +endif + INTERMEDIATE := $(call intermediates-dir-for,EXECUTABLES,$(LOCAL_MODULE),true) ANDROID_ICON_OBJ := android_icon.o ANDROID_ICON_PATH := $(LOCAL_PATH)/images $(ANDROID_ICON_PATH)/$(ANDROID_ICON_OBJ): $(ANDROID_ICON_PATH)/android_icon.rc - windres $< -I $(ANDROID_ICON_PATH) -o $@ + $(WINDRES) $< -I $(ANDROID_ICON_PATH) -o $@ # seems to be the only way to add an object file that was not generated from # a C/C++/Java source file to our build system. and very unfortunately, @@ -760,11 +770,12 @@ endif # other flags LOCAL_CFLAGS += -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -LOCAL_LDLIBS += -lm -lpthread - +LOCAL_LDLIBS += -lm ifeq ($(HOST_OS),windows) LOCAL_LDLIBS += -lwinmm -lws2_32 -liphlpapi +else + LOCAL_LDLIBS += -lpthread endif LOCAL_LDLIBS += $(QEMU_AUDIO_LIB) diff --git a/android/main.c b/android/main.c index 7ff7910..f00e1da 100644 --- a/android/main.c +++ b/android/main.c @@ -2778,11 +2778,24 @@ void android_emulation_setup( void ) { int tries = 16; int base_port = 5554; + int adb_host_port = 5037; // adb's default int success = 0; int s; uint32_t guest_ip; - AndroidOptions* opts = qemulator->opts; + /* Set the port where the emulator expects adb to run on the host + * machine */ + char* adb_host_port_str = getenv( "ANDROID_ADB_SERVER_PORT" ); + if ( adb_host_port_str && strlen( adb_host_port_str ) > 0 ) { + adb_host_port = (int) strtol( adb_host_port_str, NULL, 0 ); + if ( adb_host_port <= 0 ) { + derror( "env var ANDROID_ADB_SERVER_PORT must be a number > 0. Got \"%s\"\n", + adb_host_port_str ); + exit(1); + } + } + + AndroidOptions* opts = qemulator->opts; inet_strtoip("10.0.2.15", &guest_ip); @@ -2820,6 +2833,8 @@ void android_emulation_setup( void ) exit(1); } + // Set up redirect from host to guest system. adbd on the guest listens + // on 5555. slirp_redir( 0, adb_port, guest_ip, 5555 ); if ( control_console_start( console_port ) < 0 ) { slirp_unredir( 0, adb_port ); @@ -2889,7 +2904,7 @@ void android_emulation_setup( void ) break; } - sock_address_init_inet( &addr, SOCK_ADDRESS_INET_LOOPBACK, 5037 ); + sock_address_init_inet( &addr, SOCK_ADDRESS_INET_LOOPBACK, adb_host_port ); if (socket_connect( s, &addr ) < 0) { D("can't connect to ADB server: %s", errno_str ); break; diff --git a/android/utils/mapfile.c b/android/utils/mapfile.c index f964d38..c8ba8e5 100644 --- a/android/utils/mapfile.c +++ b/android/utils/mapfile.c @@ -19,7 +19,7 @@ #include "sys/types.h" #include "errno.h" #ifdef WIN32 -#include "Windows.h" +#include "windows.h" #else // WIN32 #include <sys/mman.h> #endif // WIN32 diff --git a/docs/ANDROID-FRAMEBUFFER.TXT b/docs/ANDROID-FRAMEBUFFER.TXT new file mode 100644 index 0000000..9e7ac28 --- /dev/null +++ b/docs/ANDROID-FRAMEBUFFER.TXT @@ -0,0 +1,88 @@ +Android Framebuffer emulation technical notes: +============================================== + +This document tries to explain how framebuffer emulation works in the +Android emulator. + +1 - Hardware emulation (hw/goldfish_fb.c): +------------------------------------------ + + The emulated hardware provides a bunch of i/o registers to allow + the following: + + - let the kernel query the framebuffer's dimensions (both in pixels + and millimeters) (see goldfish_fb_read) + + - let the kernel control the physical base address for the framebuffer + and the internal pixel rotation to apply before display (see + goldfish_fb_write). + + The pixel buffer is itself a set of physical pages allocated by the + kernel driver in the emulated system. These pages are contiguous in + the emulated system, but not in the emulator's process space which + places them randomly in the heap. + + Also, a function called goldfish_fb_update_display() is in charge of + checking the dirty bits of the framebuffer physical pages, in order to + compute the bounding rectangle of pixel updates since the last call, and + send them to the UI through qframebuffer_update(). More on this later. + + +2 - Framebuffer abstract interface (framebuffer.h): +--------------------------------------------------- + + The Android-specific header 'framebuffer.h' is used to provide a generic + interface between framebuffer 'producers' and 'clients'. Essentially, each + QFrameBuffer object: + + - holds a contiguous pixel buffer allocated by the emulator. + - can have one producer in charge of drawing into the pixel buffer + - can have zero or more clients, in charge of displaying the pixel + buffer to the final UI window (or remote VNC connection, whatever). + + The emulator will periodically call 'qframebuffer_check_updates()' which + does the following: + + foreach fb in framebuffers: + if fb.producer: + fb.producer.check_updates() + => in producer + foreach up in updates: + qframebuffer_update(fb, up.x, up.y, up.w, up.h) + => + foreach cl in fb.clients: + cl.update(cl.opaque, up.x, up.y. up.w, up.h) + + hw/goldfish_fb.c implements a producer + the QEmulator type in android/main.c implements a client. + + +3 - DisplayState (console.h): +----------------------------- + + The upstream QEMU sources use a DisplayState object to model the state + of each "display". This is not conceptually exactly the same thing than + a QFrameBuffer object as it can also be used to emulated text-based + displays instead of pixel framebuffers, and incorporates input state + as well. + + See sdl_display_init() in android/main.c which is called from vl-android.c + on startup to initialize the display. This really registers a function, + sdl_refresh() (in android/main.c), that will get called every 1/60th of + a second to handle pending inputs. + + sdl_refresh() also calls qframebuffer_check_updates(), ensuring that + any animation in the emulated framebuffer will be displayed at the same + frequency. + + The refresh frequency is defined by the GUI_REFRESH_INTERVAL defined + at the top of console.h + + +4 - QEmulator object: +--------------------- + + Currently defined and implemented in android/main.c (we may want to move + it to a different location). The QEmulator object bridges provides a + framebuffer client that uses the "generic" skin code under android/skin + to display the main UI window. diff --git a/elff/elff-common.h b/elff/elff-common.h index 922de10..8729736 100644 --- a/elff/elff-common.h +++ b/elff/elff-common.h @@ -23,7 +23,7 @@ #include "memory.h"
#include "errno.h"
#ifdef WIN32
-#include "Windows.h"
+#include "windows.h"
#else // WIN32
#include <sys/mman.h>
#include <sys/stat.h>
|