aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile.android17
-rw-r--r--android/main.c19
-rw-r--r--android/utils/mapfile.c2
-rw-r--r--docs/ANDROID-FRAMEBUFFER.TXT88
-rw-r--r--elff/elff-common.h2
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>