diff options
| -rw-r--r-- | adb/OVERVIEW.TXT | 2 | ||||
| -rw-r--r-- | adb/SERVICES.TXT | 12 | ||||
| -rw-r--r-- | adb/adb.c | 38 | ||||
| -rw-r--r-- | adb/adb.h | 10 | ||||
| -rw-r--r-- | adb/adb_client.c | 16 | ||||
| -rw-r--r-- | adb/adb_client.h | 4 | ||||
| -rw-r--r-- | adb/commandline.c | 41 | ||||
| -rw-r--r-- | adb/transport_local.c | 4 | ||||
| -rw-r--r-- | adb/usb_linux.c | 11 | ||||
| -rw-r--r-- | adb/usb_vendors.c | 12 | ||||
| -rw-r--r-- | libpixelflinger/Android.mk | 6 | ||||
| -rw-r--r-- | libpixelflinger/codeflinger/ARMAssembler.cpp | 10 | ||||
| -rw-r--r-- | libpixelflinger/codeflinger/ARMAssembler.h | 1 | ||||
| -rw-r--r-- | libpixelflinger/codeflinger/ARMAssemblerInterface.h | 3 | ||||
| -rw-r--r-- | libpixelflinger/codeflinger/ARMAssemblerProxy.cpp | 3 | ||||
| -rw-r--r-- | libpixelflinger/codeflinger/ARMAssemblerProxy.h | 2 | ||||
| -rw-r--r-- | libpixelflinger/codeflinger/disassem.c | 8 | ||||
| -rw-r--r-- | libpixelflinger/codeflinger/texturing.cpp | 106 | ||||
| -rw-r--r-- | libpixelflinger/col32cb16blend.S | 78 | ||||
| -rw-r--r-- | libpixelflinger/col32cb16blend_neon.S | 153 | ||||
| -rw-r--r-- | libpixelflinger/scanline.cpp | 47 | ||||
| -rw-r--r-- | logwrapper/logwrapper.c | 6 | ||||
| -rw-r--r-- | sh/trap.c | 14 |
23 files changed, 522 insertions, 65 deletions
diff --git a/adb/OVERVIEW.TXT b/adb/OVERVIEW.TXT index 6a5191ae..c40695af 100644 --- a/adb/OVERVIEW.TXT +++ b/adb/OVERVIEW.TXT @@ -35,7 +35,7 @@ As a whole, everything works through the following components: (through USB for devices, through TCP for emulators) and provide a few services for clients that run on the host. - The ADB server considers that a device is ONLINE when it has succesfully + The ADB server considers that a device is ONLINE when it has successfully connected to the adbd program within it. Otherwise, the device is OFFLINE, meaning that the ADB server detected a new device/emulator, but could not connect to the adbd daemon. diff --git a/adb/SERVICES.TXT b/adb/SERVICES.TXT index b0124a4d..be4d50be 100644 --- a/adb/SERVICES.TXT +++ b/adb/SERVICES.TXT @@ -74,7 +74,7 @@ host-usb:<request> host-local:<request> A variant of host-serial used to target the single emulator instance - running on the host. This will fail if therre is none or more than one. + running on the host. This will fail if there is none or more than one. host:<request> When asking for information related to a device, 'host:' can also be @@ -146,7 +146,7 @@ remount: dev:<path> Opens a device file and connects the client directly to it for read/write purposes. Useful for debugging, but may require special - priviledges and thus may not run on all devices. <path> is a full + privileges and thus may not run on all devices. <path> is a full path from the root of the filesystem. tcp:<port> @@ -173,7 +173,7 @@ log:<name> framebuffer: This service is used to send snapshots of the framebuffer to a client. - It requires sufficient priviledges but works as follow: + It requires sufficient privileges but works as follow: After the OKAY, the service sends 16-byte binary structure containing the following fields (little-endian format): @@ -190,14 +190,14 @@ framebuffer: one byte through the channel, which will trigger the service to send it 'size' bytes of framebuffer data. - If the adbd daemon doesn't have sufficient priviledges to open + If the adbd daemon doesn't have sufficient privileges to open the framebuffer device, the connection is simply closed immediately. dns:<server-name> This service is an exception because it only runs within the ADB server. It is used to implement USB networking, i.e. to provide a network connection to the device through the host machine (note: this is the exact opposite of - network thetering). + network tethering). It is used to perform a gethostbyname(<address>) on the host and return the corresponding IP address as a 4-byte string. @@ -209,7 +209,7 @@ recover:<size> - creating a file named /tmp/update - reading 'size' bytes from the client and writing them to /tmp/update - - when everything is read succesfully, create a file named /tmp/update.start + - when everything is read successfully, create a file named /tmp/update.start This service can only work when the device is in recovery mode. Otherwise, the /tmp directory doesn't exist and the connection will be closed immediately. @@ -144,9 +144,6 @@ void put_apacket(apacket *p) void handle_online(void) { D("adb: online\n"); -#if !ADB_HOST - property_set("adb.connected","1"); -#endif } void handle_offline(atransport *t) @@ -154,9 +151,6 @@ void handle_offline(atransport *t) D("adb: offline\n"); //Close the associated usb run_transport_disconnects(t); -#if !ADB_HOST - property_set("adb.connected",""); -#endif } #if TRACE_PACKETS @@ -693,7 +687,7 @@ void start_device_log(void) #endif #if ADB_HOST -int launch_server() +int launch_server(int server_port) { #ifdef HAVE_WIN32_PROC /* we need to start the server in the background */ @@ -828,7 +822,17 @@ int launch_server() } #endif -int adb_main(int is_daemon) +/* Constructs a local name of form tcp:port. + * target_str points to the target string, it's content will be overwritten. + * target_size is the capacity of the target string. + * server_port is the port number to use for the local name. + */ +void build_local_name(char* target_str, size_t target_size, int server_port) +{ + snprintf(target_str, target_size, "tcp:%d", server_port); +} + +int adb_main(int is_daemon, int server_port) { #if !ADB_HOST int secure = 0; @@ -851,9 +855,11 @@ int adb_main(int is_daemon) HOST = 1; usb_vendors_init(); usb_init(); - local_init(ADB_LOCAL_TRANSPORT_PORT); + local_init(DEFAULT_ADB_LOCAL_TRANSPORT_PORT); - if(install_listener("tcp:5037", "*smartsocket*", NULL)) { + char local_name[30]; + build_local_name(local_name, sizeof(local_name), server_port); + if(install_listener(local_name, "*smartsocket*", NULL)) { exit(1); } #else @@ -879,7 +885,7 @@ int adb_main(int is_daemon) } } - /* don't listen on port 5037 if we are running in secure mode */ + /* don't listen on a port (default 5037) if running in secure mode */ /* don't run as root if we are running in secure mode */ if (secure) { struct __user_cap_header_struct header; @@ -911,9 +917,11 @@ int adb_main(int is_daemon) cap.inheritable = 0; capset(&header, &cap); - D("Local port 5037 disabled\n"); + D("Local port disabled\n"); } else { - if(install_listener("tcp:5037", "*smartsocket*", NULL)) { + char local_name[30]; + build_local_name(local_name, sizeof(local_name), server_port); + if(install_listener(local_name, "*smartsocket*", NULL)) { exit(1); } } @@ -934,7 +942,7 @@ int adb_main(int is_daemon) usb_init(); } else { // listen on default port - local_init(ADB_LOCAL_TRANSPORT_PORT); + local_init(DEFAULT_ADB_LOCAL_TRANSPORT_PORT); } init_jdwp(); #endif @@ -1175,6 +1183,6 @@ int main(int argc, char **argv) } start_device_log(); - return adb_main(0); + return adb_main(0, DEFAULT_ADB_PORT); #endif } @@ -33,7 +33,7 @@ #define ADB_VERSION_MAJOR 1 // Used for help/version information #define ADB_VERSION_MINOR 0 // Used for help/version information -#define ADB_SERVER_VERSION 25 // Increment this when we want to force users to start a new adb server +#define ADB_SERVER_VERSION 26 // Increment this when we want to force users to start a new adb server typedef struct amessage amessage; typedef struct apacket apacket; @@ -237,8 +237,8 @@ void handle_packet(apacket *p, atransport *t); void send_packet(apacket *p, atransport *t); void get_my_path(char *s, size_t maxLen); -int launch_server(); -int adb_main(int is_daemon); +int launch_server(int server_port); +int adb_main(int is_daemon, int server_port); /* transports are ref-counted @@ -358,8 +358,8 @@ typedef enum { #define print_packet(tag,p) do {} while (0) #endif -#define ADB_PORT 5037 -#define ADB_LOCAL_TRANSPORT_PORT 5555 +#define DEFAULT_ADB_PORT 5037 +#define DEFAULT_ADB_LOCAL_TRANSPORT_PORT 5555 #define ADB_CLASS 0xff #define ADB_SUBCLASS 0x42 diff --git a/adb/adb_client.c b/adb/adb_client.c index 243f0fa5..882810a9 100644 --- a/adb/adb_client.c +++ b/adb/adb_client.c @@ -16,12 +16,19 @@ static transport_type __adb_transport = kTransportAny; static const char* __adb_serial = NULL; +static int __adb_server_port = DEFAULT_ADB_PORT; + void adb_set_transport(transport_type type, const char* serial) { __adb_transport = type; __adb_serial = serial; } +void adb_set_tcp_specifics(int server_port) +{ + __adb_server_port = server_port; +} + int adb_get_emulator_console_port(void) { const char* serial = __adb_serial; @@ -174,7 +181,7 @@ int _adb_connect(const char *service) } snprintf(tmp, sizeof tmp, "%04x", len); - fd = socket_loopback_client(ADB_PORT, SOCK_STREAM); + fd = socket_loopback_client(__adb_server_port, SOCK_STREAM); if(fd < 0) { strcpy(__adb_error, "cannot connect to daemon"); return -2; @@ -204,9 +211,10 @@ int adb_connect(const char *service) int fd = _adb_connect("host:version"); if(fd == -2) { - fprintf(stdout,"* daemon not running. starting it now *\n"); + fprintf(stdout,"* daemon not running. starting it now on port %d *\n", + __adb_server_port); start_server: - if(launch_server(0)) { + if(launch_server(__adb_server_port)) { fprintf(stderr,"* failed to start daemon *\n"); return -1; } else { @@ -314,5 +322,3 @@ oops: adb_close(fd); return 0; } - - diff --git a/adb/adb_client.h b/adb/adb_client.h index 80615790..40ab1897 100644 --- a/adb/adb_client.h +++ b/adb/adb_client.h @@ -25,6 +25,10 @@ char *adb_query(const char *service); */ void adb_set_transport(transport_type type, const char* serial); +/* Set TCP specifics of the transport to use +*/ +void adb_set_tcp_specifics(int server_port); + /* Return the console port of the currently connected emulator (if any) * of -1 if there is no emulator, and -2 if there is more than one. * assumes adb_set_transport() was alled previously... diff --git a/adb/commandline.c b/adb/commandline.c index 3ee54c73..8003a644 100644 --- a/adb/commandline.c +++ b/adb/commandline.c @@ -105,8 +105,8 @@ void help() " environment variable is used, which must\n" " be an absolute path.\n" " devices - list all connected devices\n" - " connect <host>:<port> - connect to a device via TCP/IP" - " disconnect <host>:<port> - disconnect from a TCP/IP device" + " connect <host>:<port> - connect to a device via TCP/IP\n" + " disconnect <host>:<port> - disconnect from a TCP/IP device\n" "\n" "device commands:\n" " adb push <local> <remote> - copy file/dir to device\n" @@ -170,6 +170,12 @@ void help() "\n" " - If it is \"system\" or \"data\", only the corresponding partition\n" " is updated.\n" + "\n" + "environmental variables:\n" + " ADB_TRACE - Print debug information. A comma separated list of the following values\n" + " 1 or all, adb, sockets, packets, rwx, usb, sync, sysdeps, transport, jdwp\n" + " ANDROID_SERIAL - The serial number to connect to. -s takes priority over this if given.\n" + " ANDROID_LOG_TAGS - When used with the logcat option, only these debug tags are printed.\n" ); } @@ -221,8 +227,8 @@ static void read_and_dump(int fd) if(errno == EINTR) continue; break; } - /* we want to output to stdout, so no adb_write here !! */ - unix_write(1, buf, len); + fwrite(buf, 1, len, stdout); + fflush(stdout); } } @@ -761,6 +767,7 @@ int adb_commandline(int argc, char **argv) int quote; transport_type ttype = kTransportAny; char* serial = NULL; + char* server_port_str = NULL; /* If defined, this should be an absolute path to * the directory containing all of the various system images @@ -776,7 +783,20 @@ int adb_commandline(int argc, char **argv) serial = getenv("ANDROID_SERIAL"); - /* modifiers and flags */ + /* Validate and assign the server port */ + server_port_str = getenv("ANDROID_ADB_SERVER_PORT"); + int server_port = DEFAULT_ADB_PORT; + if (server_port_str && strlen(server_port_str) > 0) { + server_port = (int) strtol(server_port_str, NULL, 0); + if (server_port <= 0) { + fprintf(stderr, + "adb: Env var ANDROID_ADB_SERVER_PORT must be a positive number. Got \"%s\"\n", + server_port_str); + return usage(); + } + } + + /* modifiers and flags */ while(argc > 0) { if(!strcmp(argv[0],"nodaemon")) { no_daemon = 1; @@ -805,7 +825,7 @@ int adb_commandline(int argc, char **argv) if (isdigit(argv[0][2])) { serial = argv[0] + 2; } else { - if(argc < 2) return usage(); + if(argc < 2 || argv[0][2] != '\0') return usage(); serial = argv[1]; argc--; argv++; @@ -823,12 +843,13 @@ int adb_commandline(int argc, char **argv) } adb_set_transport(ttype, serial); + adb_set_tcp_specifics(server_port); if ((argc > 0) && (!strcmp(argv[0],"server"))) { if (no_daemon || is_daemon) { - r = adb_main(is_daemon); + r = adb_main(is_daemon, server_port); } else { - r = launch_server(); + r = launch_server(server_port); } if(r) { fprintf(stderr,"* could not start server *\n"); @@ -893,10 +914,10 @@ top: /* quote empty strings and strings with spaces */ quote = (**argv == 0 || strchr(*argv, ' ')); if (quote) - strcat(buf, "\""); + strcat(buf, "\""); strcat(buf, *argv++); if (quote) - strcat(buf, "\""); + strcat(buf, "\""); } for(;;) { diff --git a/adb/transport_local.c b/adb/transport_local.c index 81d120ef..cfd3b4bc 100644 --- a/adb/transport_local.c +++ b/adb/transport_local.c @@ -132,7 +132,7 @@ int local_connect(int port) static void *client_socket_thread(void *x) { #if ADB_HOST - int port = ADB_LOCAL_TRANSPORT_PORT; + int port = DEFAULT_ADB_LOCAL_TRANSPORT_PORT; int count = ADB_LOCAL_TRANSPORT_MAX; D("transport: client_socket_thread() starting\n"); @@ -244,7 +244,7 @@ int init_socket_transport(atransport *t, int s, int port, int local) if (HOST && local) { adb_mutex_lock( &local_transports_lock ); { - int index = (port - ADB_LOCAL_TRANSPORT_PORT)/2; + int index = (port - DEFAULT_ADB_LOCAL_TRANSPORT_PORT)/2; if (!(port & 1) || index < 0 || index >= ADB_LOCAL_TRANSPORT_MAX) { D("bad local transport port number: %d\n", port); diff --git a/adb/usb_linux.c b/adb/usb_linux.c index 66ee317e..bb868135 100644 --- a/adb/usb_linux.c +++ b/adb/usb_linux.c @@ -21,6 +21,7 @@ #include <sys/ioctl.h> #include <sys/types.h> +#include <sys/time.h> #include <dirent.h> #include <fcntl.h> #include <errno.h> @@ -287,6 +288,8 @@ static int usb_bulk_write(usb_handle *h, const void *data, int len) { struct usbdevfs_urb *urb = &h->urb_out; int res; + struct timeval tv; + struct timespec ts; memset(urb, 0, sizeof(*urb)); urb->type = USBDEVFS_URB_TYPE_BULK; @@ -313,8 +316,12 @@ static int usb_bulk_write(usb_handle *h, const void *data, int len) res = -1; h->urb_out_busy = 1; for(;;) { - adb_cond_wait(&h->notify, &h->lock); - if(h->dead) { + /* time out after five seconds */ + gettimeofday(&tv, NULL); + ts.tv_sec = tv.tv_sec + 5; + ts.tv_nsec = tv.tv_usec * 1000L; + res = pthread_cond_timedwait(&h->notify, &h->lock, &ts); + if(res < 0 || h->dead) { break; } if(h->urb_out_busy == 0) { diff --git a/adb/usb_vendors.c b/adb/usb_vendors.c index 73bf4184..7f3cb543 100644 --- a/adb/usb_vendors.c +++ b/adb/usb_vendors.c @@ -59,6 +59,14 @@ #define VENDOR_ID_NVIDIA 0x0955 // Garmin-Asus's USB Vendor ID #define VENDOR_ID_GARMIN_ASUS 0x091E +// Sharp's USB Vendor ID +#define VENDOR_ID_SHARP 0x04dd +// ZTE's USB Vendor ID +#define VENDOR_ID_ZTE 0x19D2 +// Kyocera's USB Vendor ID +#define VENDOR_ID_KYOCERA 0x0482 +// Pantech's USB Vendor ID +#define VENDOR_ID_PANTECH 0x10A9 /** built-in vendor list */ @@ -75,6 +83,10 @@ int builtInVendorIds[] = { VENDOR_ID_DELL, VENDOR_ID_NVIDIA, VENDOR_ID_GARMIN_ASUS, + VENDOR_ID_SHARP, + VENDOR_ID_ZTE, + VENDOR_ID_KYOCERA, + VENDOR_ID_PANTECH, }; #define BUILT_IN_VENDOR_COUNT (sizeof(builtInVendorIds)/sizeof(builtInVendorIds[0])) diff --git a/libpixelflinger/Android.mk b/libpixelflinger/Android.mk index 0cc85d9d..6491d243 100644 --- a/libpixelflinger/Android.mk +++ b/libpixelflinger/Android.mk @@ -40,7 +40,13 @@ PIXELFLINGER_SRC_FILES:= \ buffer.cpp ifeq ($(TARGET_ARCH),arm) +ifeq ($(TARGET_ARCH_VERSION),armv7-a) +PIXELFLINGER_SRC_FILES += col32cb16blend_neon.S +PIXELFLINGER_SRC_FILES += col32cb16blend.S +else PIXELFLINGER_SRC_FILES += t32cb16blend.S +PIXELFLINGER_SRC_FILES += col32cb16blend.S +endif endif ifeq ($(TARGET_ARCH),arm) diff --git a/libpixelflinger/codeflinger/ARMAssembler.cpp b/libpixelflinger/codeflinger/ARMAssembler.cpp index ff7b0b3e..d3720c3e 100644 --- a/libpixelflinger/codeflinger/ARMAssembler.cpp +++ b/libpixelflinger/codeflinger/ARMAssembler.cpp @@ -424,5 +424,15 @@ void ARMAssembler::SMLAW(int cc, int y, *mPC++ = (cc<<28) | 0x1200080 | (Rd<<16) | (Rn<<12) | (Rs<<8) | (y<<4) | Rm; } +#if 0 +#pragma mark - +#pragma mark Byte/half word extract and extend (ARMv6+ only)... +#endif + +void ARMAssembler::UXTB16(int cc, int Rd, int Rm, int rotate) +{ + *mPC++ = (cc<<28) | 0x6CF0070 | (Rd<<12) | ((rotate >> 3) << 10) | Rm; +} + }; // namespace android diff --git a/libpixelflinger/codeflinger/ARMAssembler.h b/libpixelflinger/codeflinger/ARMAssembler.h index ef3b66af..a667cb51 100644 --- a/libpixelflinger/codeflinger/ARMAssembler.h +++ b/libpixelflinger/codeflinger/ARMAssembler.h @@ -123,6 +123,7 @@ public: int RdHi, int RdLo, int Rs, int Rm); virtual void SMLAW(int cc, int y, int Rd, int Rm, int Rs, int Rn); + virtual void UXTB16(int cc, int Rd, int Rm, int rotate); private: ARMAssembler(const ARMAssembler& rhs); diff --git a/libpixelflinger/codeflinger/ARMAssemblerInterface.h b/libpixelflinger/codeflinger/ARMAssemblerInterface.h index 465b3bd9..ff6af2a2 100644 --- a/libpixelflinger/codeflinger/ARMAssemblerInterface.h +++ b/libpixelflinger/codeflinger/ARMAssemblerInterface.h @@ -203,6 +203,9 @@ public: virtual void SMLAW(int cc, int y, int Rd, int Rm, int Rs, int Rn) = 0; + // byte/half word extract... + virtual void UXTB16(int cc, int Rd, int Rm, int rotate) = 0; + // ----------------------------------------------------------------------- // convenience... // ----------------------------------------------------------------------- diff --git a/libpixelflinger/codeflinger/ARMAssemblerProxy.cpp b/libpixelflinger/codeflinger/ARMAssemblerProxy.cpp index 18c46186..7c422dba 100644 --- a/libpixelflinger/codeflinger/ARMAssemblerProxy.cpp +++ b/libpixelflinger/codeflinger/ARMAssemblerProxy.cpp @@ -195,6 +195,9 @@ void ARMAssemblerProxy::SMLAW(int cc, int y, int Rd, int Rm, int Rs, int Rn) { mTarget->SMLAW(cc, y, Rd, Rm, Rs, Rn); } +void ARMAssemblerProxy::UXTB16(int cc, int Rd, int Rm, int rotate) { + mTarget->UXTB16(cc, Rd, Rm, rotate); +} }; // namespace android diff --git a/libpixelflinger/codeflinger/ARMAssemblerProxy.h b/libpixelflinger/codeflinger/ARMAssemblerProxy.h index 4bdca9cf..9134cce6 100644 --- a/libpixelflinger/codeflinger/ARMAssemblerProxy.h +++ b/libpixelflinger/codeflinger/ARMAssemblerProxy.h @@ -114,6 +114,8 @@ public: virtual void SMLAW(int cc, int y, int Rd, int Rm, int Rs, int Rn); + virtual void UXTB16(int cc, int Rd, int Rm, int rotate); + private: ARMAssemblerInterface* mTarget; }; diff --git a/libpixelflinger/codeflinger/disassem.c b/libpixelflinger/codeflinger/disassem.c index 4676da0d..c17f3ecc 100644 --- a/libpixelflinger/codeflinger/disassem.c +++ b/libpixelflinger/codeflinger/disassem.c @@ -80,6 +80,7 @@ * f - 1st fp operand (register) (bits 12-14) * g - 2nd fp operand (register) (bits 16-18) * h - 3rd fp operand (register/immediate) (bits 0-4) + * j - xtb rotate literal (bits 10-11) * b - branch address * t - thumb branch address (bits 24, 0-23) * k - breakpoint comment (bits 0-3, 8-19) @@ -122,6 +123,7 @@ static const struct arm32_insn arm32_i[] = { { 0x0fe000f0, 0x00c00090, "smull", "Sdnms" }, { 0x0fe000f0, 0x00a00090, "umlal", "Sdnms" }, { 0x0fe000f0, 0x00e00090, "smlal", "Sdnms" }, + { 0x0fff03f0, 0x06cf0070, "uxtb16", "dmj" }, { 0x0d700000, 0x04200000, "strt", "daW" }, { 0x0d700000, 0x04300000, "ldrt", "daW" }, { 0x0d700000, 0x04600000, "strbt", "daW" }, @@ -276,7 +278,7 @@ static char const insn_fpaconstants[][8] = { #define insn_condition(x) arm32_insn_conditions[(x >> 28) & 0x0f] #define insn_blktrans(x) insn_block_transfers[(x >> 23) & 3] -#define insn_stkblktrans(x) insn_stack_block_transfers[(x >> 23) & 3] +#define insn_stkblktrans(x) insn_stack_block_transfers[(3*((x >> 20)&1))^((x >> 23)&3)] #define op2_shift(x) op_shifts[(x >> 5) & 3] #define insn_fparnd(x) insn_fpa_rounding[(x >> 5) & 0x03] #define insn_fpaprec(x) insn_fpa_precision[(((x >> 18) & 2)|(x >> 7)) & 1] @@ -406,6 +408,10 @@ disasm(const disasm_interface_t *di, u_int loc, int altfmt) else di->di_printf("f%d", insn & 7); break; + /* j - xtb rotate literal (bits 10-11) */ + case 'j': + di->di_printf("ror #%d", ((insn >> 10) & 3) << 3); + break; /* b - branch address */ case 'b': branch = ((insn << 2) & 0x03ffffff); diff --git a/libpixelflinger/codeflinger/texturing.cpp b/libpixelflinger/codeflinger/texturing.cpp index 90e65840..7f6f8da4 100644 --- a/libpixelflinger/codeflinger/texturing.cpp +++ b/libpixelflinger/codeflinger/texturing.cpp @@ -25,6 +25,9 @@ #include "codeflinger/GGLAssembler.h" +#ifdef __ARM_ARCH__ +#include <machine/cpu-features.h> +#endif namespace android { @@ -567,7 +570,7 @@ void GGLAssembler::build_textures( fragment_parts_t& parts, RSB(GE, 0, height, height, imm(0)); MUL(AL, 0, height, stride, height); } else { - // u has not been CLAMPed yet + // v has not been CLAMPed yet CMP(AL, height, reg_imm(v, ASR, FRAC_BITS)); MOV(LE, 0, v, reg_imm(height, LSL, FRAC_BITS)); MOV(LE, 0, height, imm(0)); @@ -868,6 +871,106 @@ void GGLAssembler::filter24( load(txPtr, texel, 0); } +#if __ARM_ARCH__ >= 6 +// ARMv6 version, using UXTB16, and scheduled for Cortex-A8 pipeline +void GGLAssembler::filter32( + const fragment_parts_t& parts, + pixel_t& texel, const texture_unit_t& tmu, + int U, int V, pointer_t& txPtr, + int FRAC_BITS) +{ + const int adjust = FRAC_BITS*2 - 8; + const int round = 0; + const int prescale = 16 - adjust; + + Scratch scratches(registerFile()); + + int pixel= scratches.obtain(); + int dh = scratches.obtain(); + int u = scratches.obtain(); + int k = scratches.obtain(); + + int temp = scratches.obtain(); + int dl = scratches.obtain(); + + int offsetrt = scratches.obtain(); + int offsetlb = scratches.obtain(); + + int pixellb = offsetlb; + + // RB -> U * V + CONTEXT_LOAD(offsetrt, generated_vars.rt); + CONTEXT_LOAD(offsetlb, generated_vars.lb); + if(!round) { + MOV(AL, 0, U, reg_imm(U, LSL, prescale)); + } + ADD(AL, 0, u, offsetrt, offsetlb); + + LDR(AL, pixel, txPtr.reg, reg_scale_pre(u)); + if (round) { + SMULBB(AL, u, U, V); + RSB(AL, 0, U, U, imm(1<<FRAC_BITS)); + } else { + SMULWB(AL, u, U, V); + RSB(AL, 0, U, U, imm(1<<(FRAC_BITS+prescale))); + } + UXTB16(AL, temp, pixel, 0); + if (round) { + ADD(AL, 0, u, u, imm(1<<(adjust-1))); + MOV(AL, 0, u, reg_imm(u, LSR, adjust)); + } + LDR(AL, pixellb, txPtr.reg, reg_scale_pre(offsetlb)); + MUL(AL, 0, dh, temp, u); + UXTB16(AL, temp, pixel, 8); + MUL(AL, 0, dl, temp, u); + RSB(AL, 0, k, u, imm(0x100)); + + // LB -> (1-U) * V + if (round) { + SMULBB(AL, u, U, V); + } else { + SMULWB(AL, u, U, V); + } + UXTB16(AL, temp, pixellb, 0); + if (round) { + ADD(AL, 0, u, u, imm(1<<(adjust-1))); + MOV(AL, 0, u, reg_imm(u, LSR, adjust)); + } + MLA(AL, 0, dh, temp, u, dh); + UXTB16(AL, temp, pixellb, 8); + MLA(AL, 0, dl, temp, u, dl); + SUB(AL, 0, k, k, u); + + // LT -> (1-U)*(1-V) + RSB(AL, 0, V, V, imm(1<<FRAC_BITS)); + LDR(AL, pixel, txPtr.reg); + if (round) { + SMULBB(AL, u, U, V); + } else { + SMULWB(AL, u, U, V); + } + UXTB16(AL, temp, pixel, 0); + if (round) { + ADD(AL, 0, u, u, imm(1<<(adjust-1))); + MOV(AL, 0, u, reg_imm(u, LSR, adjust)); + } + MLA(AL, 0, dh, temp, u, dh); + UXTB16(AL, temp, pixel, 8); + MLA(AL, 0, dl, temp, u, dl); + + // RT -> U*(1-V) + LDR(AL, pixel, txPtr.reg, reg_scale_pre(offsetrt)); + SUB(AL, 0, u, k, u); + UXTB16(AL, temp, pixel, 0); + MLA(AL, 0, dh, temp, u, dh); + UXTB16(AL, temp, pixel, 8); + MLA(AL, 0, dl, temp, u, dl); + + UXTB16(AL, dh, dh, 8); + UXTB16(AL, dl, dl, 8); + ORR(AL, 0, texel.reg, dh, reg_imm(dl, LSL, 8)); +} +#else void GGLAssembler::filter32( const fragment_parts_t& parts, pixel_t& texel, const texture_unit_t& tmu, @@ -955,6 +1058,7 @@ void GGLAssembler::filter32( AND(AL, 0, dl, dl, reg_imm(mask, LSL, 8)); ORR(AL, 0, texel.reg, dh, dl); } +#endif void GGLAssembler::build_texture_environment( component_t& fragment, diff --git a/libpixelflinger/col32cb16blend.S b/libpixelflinger/col32cb16blend.S new file mode 100644 index 00000000..1450bde8 --- /dev/null +++ b/libpixelflinger/col32cb16blend.S @@ -0,0 +1,78 @@ +/* libs/pixelflinger/col32cb16blend.S +** +** (C) COPYRIGHT 2009 ARM Limited. +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +** +*/ + + .text + .align + + .global scanline_col32cb16blend_arm + +// +// This function alpha blends a fixed color into a destination scanline, using +// the formula: +// +// d = s + (((a + (a >> 7)) * d) >> 8) +// +// where d is the destination pixel, +// s is the source color, +// a is the alpha channel of the source color. +// + +// r0 = destination buffer pointer +// r1 = color value +// r2 = count + + +scanline_col32cb16blend_arm: + push {r4-r10, lr} // stack ARM regs + + mov r5, r1, lsr #24 // shift down alpha + mov r9, #0xff // create mask + add r5, r5, r5, lsr #7 // add in top bit + rsb r5, r5, #256 // invert alpha + and r10, r1, #0xff // extract red + and r12, r9, r1, lsr #8 // extract green + and r4, r9, r1, lsr #16 // extract blue + mov r10, r10, lsl #5 // prescale red + mov r12, r12, lsl #6 // prescale green + mov r4, r4, lsl #5 // prescale blue + mov r9, r9, lsr #2 // create dest green mask + +1: + ldrh r8, [r0] // load dest pixel + subs r2, r2, #1 // decrement loop counter + mov r6, r8, lsr #11 // extract dest red + and r7, r9, r8, lsr #5 // extract dest green + and r8, r8, #0x1f // extract dest blue + + smlabb r6, r6, r5, r10 // dest red * alpha + src red + smlabb r7, r7, r5, r12 // dest green * alpha + src green + smlabb r8, r8, r5, r4 // dest blue * alpha + src blue + + mov r6, r6, lsr #8 // shift down red + mov r7, r7, lsr #8 // shift down green + mov r6, r6, lsl #11 // shift red into 565 + orr r6, r7, lsl #5 // shift green into 565 + orr r6, r8, lsr #8 // shift blue into 565 + + strh r6, [r0], #2 // store pixel to dest, update ptr + bne 1b // if count != 0, loop + + pop {r4-r10, pc} // return + + + diff --git a/libpixelflinger/col32cb16blend_neon.S b/libpixelflinger/col32cb16blend_neon.S new file mode 100644 index 00000000..17b0d01a --- /dev/null +++ b/libpixelflinger/col32cb16blend_neon.S @@ -0,0 +1,153 @@ +/* libs/pixelflinger/col32cb16blend_neon.S +** +** (C) COPYRIGHT 2009 ARM Limited. +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +** +*/ + + .text + .align + + .global scanline_col32cb16blend_neon + +// +// This function alpha blends a fixed color into a destination scanline, using +// the formula: +// +// d = s + (((a + (a >> 7)) * d) >> 8) +// +// where d is the destination pixel, +// s is the source color, +// a is the alpha channel of the source color. +// +// The NEON implementation processes 16 pixels per iteration. The remaining 0 - 15 +// pixels are processed in ARM code. +// + +// r0 = destination buffer pointer +// r1 = color pointer +// r2 = count + + +scanline_col32cb16blend_neon: + push {r4-r11, lr} // stack ARM regs + + vmov.u16 q15, #256 // create alpha constant + movs r3, r2, lsr #4 // calc. sixteens iterations + vmov.u16 q14, #0x1f // create blue mask + + beq 2f // if r3 == 0, branch to singles + + vld4.8 {d0[], d2[], d4[], d6[]}, [r1] // load color into four registers + // split and duplicate them, such that + // d0 = 8 equal red values + // d2 = 8 equal green values + // d4 = 8 equal blue values + // d6 = 8 equal alpha values + vshll.u8 q0, d0, #5 // shift up red and widen + vshll.u8 q1, d2, #6 // shift up green and widen + vshll.u8 q2, d4, #5 // shift up blue and widen + + vshr.u8 d7, d6, #7 // extract top bit of alpha + vaddl.u8 q3, d6, d7 // add top bit into alpha + vsub.u16 q3, q15, q3 // invert alpha + +1: + // This loop processes 16 pixels per iteration. In the comments, references to + // the first eight pixels are suffixed with "0" (red0, green0, blue0), + // the second eight are suffixed "1". + // q8 = dst red0 + // q9 = dst green0 + // q10 = dst blue0 + // q13 = dst red1 + // q12 = dst green1 + // q11 = dst blue1 + + vld1.16 {d20, d21, d22, d23}, [r0] // load 16 dest pixels + vshr.u16 q8, q10, #11 // shift dst red0 to low 5 bits + pld [r0, #63] // preload next dest pixels + vshl.u16 q9, q10, #5 // shift dst green0 to top 6 bits + vand q10, q10, q14 // extract dst blue0 + vshr.u16 q9, q9, #10 // shift dst green0 to low 6 bits + vmul.u16 q8, q8, q3 // multiply dst red0 by src alpha + vshl.u16 q12, q11, #5 // shift dst green1 to top 6 bits + vmul.u16 q9, q9, q3 // multiply dst green0 by src alpha + vshr.u16 q13, q11, #11 // shift dst red1 to low 5 bits + vmul.u16 q10, q10, q3 // multiply dst blue0 by src alpha + vshr.u16 q12, q12, #10 // shift dst green1 to low 6 bits + vand q11, q11, q14 // extract dst blue1 + vadd.u16 q8, q8, q0 // add src red to dst red0 + vmul.u16 q13, q13, q3 // multiply dst red1 by src alpha + vadd.u16 q9, q9, q1 // add src green to dst green0 + vmul.u16 q12, q12, q3 // multiply dst green1 by src alpha + vadd.u16 q10, q10, q2 // add src blue to dst blue0 + vmul.u16 q11, q11, q3 // multiply dst blue1 by src alpha + vshr.u16 q8, q8, #8 // shift down red0 + vadd.u16 q13, q13, q0 // add src red to dst red1 + vshr.u16 q9, q9, #8 // shift down green0 + vadd.u16 q12, q12, q1 // add src green to dst green1 + vshr.u16 q10, q10, #8 // shift down blue0 + vadd.u16 q11, q11, q2 // add src blue to dst blue1 + vsli.u16 q10, q9, #5 // shift & insert green0 into blue0 + vshr.u16 q13, q13, #8 // shift down red1 + vsli.u16 q10, q8, #11 // shift & insert red0 into blue0 + vshr.u16 q12, q12, #8 // shift down green1 + vshr.u16 q11, q11, #8 // shift down blue1 + subs r3, r3, #1 // decrement loop counter + vsli.u16 q11, q12, #5 // shift & insert green1 into blue1 + vsli.u16 q11, q13, #11 // shift & insert red1 into blue1 + + vst1.16 {d20, d21, d22, d23}, [r0]! // write 16 pixels back to dst + bne 1b // if count != 0, loop + +2: + ands r3, r2, #15 // calc. single iterations + beq 4f // if r3 == 0, exit + + ldr r4, [r1] // load source color + mov r5, r4, lsr #24 // shift down alpha + add r5, r5, r5, lsr #7 // add in top bit + rsb r5, r5, #256 // invert alpha + and r11, r4, #0xff // extract red + ubfx r12, r4, #8, #8 // extract green + ubfx r4, r4, #16, #8 // extract blue + mov r11, r11, lsl #5 // prescale red + mov r12, r12, lsl #6 // prescale green + mov r4, r4, lsl #5 // prescale blue + +3: + ldrh r8, [r0] // load dest pixel + subs r3, r3, #1 // decrement loop counter + mov r6, r8, lsr #11 // extract dest red + ubfx r7, r8, #5, #6 // extract dest green + and r8, r8, #0x1f // extract dest blue + + smlabb r6, r6, r5, r11 // dest red * alpha + src red + smlabb r7, r7, r5, r12 // dest green * alpha + src green + smlabb r8, r8, r5, r4 // dest blue * alpha + src blue + + mov r6, r6, lsr #8 // shift down red + mov r7, r7, lsr #8 // shift down green + mov r6, r6, lsl #11 // shift red into 565 + orr r6, r7, lsl #5 // shift green into 565 + orr r6, r8, lsr #8 // shift blue into 565 + + strh r6, [r0], #2 // store pixel to dest, update ptr + bne 3b // if count != 0, loop +4: + + pop {r4-r11, pc} // return + + + diff --git a/libpixelflinger/scanline.cpp b/libpixelflinger/scanline.cpp index f7003068..a2f43eb0 100644 --- a/libpixelflinger/scanline.cpp +++ b/libpixelflinger/scanline.cpp @@ -80,6 +80,7 @@ static void scanline_perspective(context_t* c); static void scanline_perspective_single(context_t* c); static void scanline_t32cb16blend(context_t* c); static void scanline_t32cb16(context_t* c); +static void scanline_col32cb16blend(context_t* c); static void scanline_memcpy(context_t* c); static void scanline_memset8(context_t* c); static void scanline_memset16(context_t* c); @@ -93,6 +94,8 @@ static void rect_memcpy(context_t* c, size_t yc); extern "C" void scanline_t32cb16blend_arm(uint16_t*, uint32_t*, size_t); extern "C" void scanline_t32cb16_arm(uint16_t *dst, uint32_t *src, size_t ct); +extern "C" void scanline_col32cb16blend_neon(uint16_t *dst, uint32_t *col, size_t ct); +extern "C" void scanline_col32cb16blend_arm(uint16_t *dst, uint32_t col, size_t ct); // ---------------------------------------------------------------------------- @@ -111,6 +114,9 @@ static shortcut_t shortcuts[] = { { { { 0x03010104, 0x00000077, { 0x00000A01, 0x00000000 } }, { 0xFFFFFFFF, 0xFFFFFFFF, { 0xFFFFFFFF, 0x0000003F } } }, "565 fb, 8888 tx", scanline_t32cb16, init_y_noop }, + { { { 0x03515104, 0x00000077, { 0x00000000, 0x00000000 } }, + { 0xFFFFFFFF, 0xFFFFFFFF, { 0xFFFFFFFF, 0xFFFFFFFF } } }, + "565 fb, 8888 fixed color", scanline_col32cb16blend, init_y_packed }, { { { 0x00000000, 0x00000000, { 0x00000000, 0x00000000 } }, { 0x00000000, 0x00000007, { 0x00000000, 0x00000000 } } }, "(nop) alpha test", scanline_noop, init_y_noop }, @@ -943,6 +949,8 @@ void init_y_packed(context_t* c, int32_t y0) uint8_t f = c->state.buffers.color.format; c->packed = ggl_pack_color(c, f, c->shade.r0, c->shade.g0, c->shade.b0, c->shade.a0); + c->packed8888 = ggl_pack_color(c, GGL_PIXEL_FORMAT_RGBA_8888, + c->shade.r0, c->shade.g0, c->shade.b0, c->shade.a0); c->iterators.y = y0; c->step_y = step_y__nop; // choose the rectangle blitter @@ -1253,6 +1261,45 @@ finish: // ---------------------------------------------------------------------------- +void scanline_col32cb16blend(context_t* c) +{ + int32_t x = c->iterators.xl; + size_t ct = c->iterators.xr - x; + int32_t y = c->iterators.y; + surface_t* cb = &(c->state.buffers.color); + union { + uint16_t* dst; + uint32_t* dst32; + }; + dst = reinterpret_cast<uint16_t*>(cb->data) + (x+(cb->stride*y)); + +#if ((ANDROID_CODEGEN >= ANDROID_CODEGEN_ASM) && defined(__arm__)) +#if defined(__ARM_HAVE_NEON) && BYTE_ORDER == LITTLE_ENDIAN + scanline_col32cb16blend_neon(dst, &(c->packed8888), ct); +#else // defined(__ARM_HAVE_NEON) && BYTE_ORDER == LITTLE_ENDIAN + scanline_col32cb16blend_arm(dst, GGL_RGBA_TO_HOST(c->packed8888), ct); +#endif // defined(__ARM_HAVE_NEON) && BYTE_ORDER == LITTLE_ENDIAN +#else + uint32_t s = GGL_RGBA_TO_HOST(c->packed8888); + int sA = (s>>24); + int f = 0x100 - (sA + (sA>>7)); + while (ct--) { + uint16_t d = *dst; + int dR = (d>>11)&0x1f; + int dG = (d>>5)&0x3f; + int dB = (d)&0x1f; + int sR = (s >> ( 3))&0x1F; + int sG = (s >> ( 8+2))&0x3F; + int sB = (s >> (16+3))&0x1F; + sR += (f*dR)>>8; + sG += (f*dG)>>8; + sB += (f*dB)>>8; + *dst++ = uint16_t((sR<<11)|(sG<<5)|sB); + } +#endif + +} + void scanline_t32cb16(context_t* c) { int32_t x = c->iterators.xl; diff --git a/logwrapper/logwrapper.c b/logwrapper/logwrapper.c index f00bfbf3..64667956 100644 --- a/logwrapper/logwrapper.c +++ b/logwrapper/logwrapper.c @@ -60,7 +60,7 @@ void parent(const char *tag, int seg_fault_on_exit, int parent_read) { buffer[b] = '\0'; } else if (buffer[b] == '\n') { buffer[b] = '\0'; - LOG(LOG_INFO, tag, &buffer[a]); + LOG(LOG_INFO, tag, "%s", &buffer[a]); a = b + 1; } } @@ -68,7 +68,7 @@ void parent(const char *tag, int seg_fault_on_exit, int parent_read) { if (a == 0 && b == sizeof(buffer) - 1) { // buffer is full, flush buffer[b] = '\0'; - LOG(LOG_INFO, tag, &buffer[a]); + LOG(LOG_INFO, tag, "%s", &buffer[a]); b = 0; } else if (a != b) { // Keep left-overs @@ -84,7 +84,7 @@ void parent(const char *tag, int seg_fault_on_exit, int parent_read) { // Flush remaining data if (a != b) { buffer[b] = '\0'; - LOG(LOG_INFO, tag, &buffer[a]); + LOG(LOG_INFO, tag, "%s", &buffer[a]); } status = 0xAAAA; if (wait(&status) != -1) { // Wait for child @@ -60,20 +60,6 @@ __RCSID("$NetBSD: trap.c,v 1.31 2005/01/11 19:38:57 christos Exp $"); #include "mystring.h" #include "var.h" -static const char *sys_signame[NSIG] = { - "Unused", - "HUP", "INT", "QUIT", "ILL", - "TRAP", "ABRT", "BUS", "FPE", - "KILL", "USR1", "SEGV", "USR2", - "PIPE", "ALRM", "TERM", - "Unknown", - "CHLD", - "CONT", "STOP", "TSTP", "TTIN", - "TTOU", "URG", "XCPU", "XFSZ", - "VTALRM", "PROF", "WINCH", "IO", - "PWR", "SYS" -}; - /* * Sigmode records the current value of the signal handlers for the various * modes. A value of zero means that the current handler is not known. |
