Merge changes Id5584bc1,I8ca826d0

* changes:
  revert parts of dc5b63e40, which made gyro drift estimation unstable
  use gyro timestamp directly in fusion
diff --git a/cmds/atrace/atrace.cpp b/cmds/atrace/atrace.cpp
index 1911839..6d6f77e 100644
--- a/cmds/atrace/atrace.cpp
+++ b/cmds/atrace/atrace.cpp
@@ -82,6 +82,7 @@
     { "hal",        "Hardware Modules", ATRACE_TAG_HAL, { } },
     { "res",        "Resource Loading", ATRACE_TAG_RESOURCES, { } },
     { "dalvik",     "Dalvik VM",        ATRACE_TAG_DALVIK, { } },
+    { "rs",         "RenderScript",     ATRACE_TAG_RS, { } },
     { "sched",      "CPU Scheduling",   0, {
         { REQ,      "/sys/kernel/debug/tracing/events/sched/sched_switch/enable" },
         { REQ,      "/sys/kernel/debug/tracing/events/sched/sched_wakeup/enable" },
diff --git a/cmds/dumpstate/dumpstate.c b/cmds/dumpstate/dumpstate.c
index 9a332a9..89bea91 100644
--- a/cmds/dumpstate/dumpstate.c
+++ b/cmds/dumpstate/dumpstate.c
@@ -315,7 +315,13 @@
 		);
 }
 
+static void sigpipe_handler(int n) {
+    (void)n;
+    exit(EXIT_FAILURE);
+}
+
 int main(int argc, char *argv[]) {
+    struct sigaction sigact;
     int do_add_date = 0;
     int do_compress = 0;
     int do_vibrate = 1;
@@ -336,7 +342,9 @@
     }
     ALOGI("begin\n");
 
-    signal(SIGPIPE, SIG_IGN);
+    memset(&sigact, 0, sizeof(sigact));
+    sigact.sa_handler = sigpipe_handler;
+    sigaction(SIGPIPE, &sigact, NULL);
 
     /* set as high priority, and protect from OOM killer */
     setpriority(PRIO_PROCESS, 0, -20);
diff --git a/include/android/input.h b/include/android/input.h
index c8ac938..fead769 100644
--- a/include/android/input.h
+++ b/include/android/input.h
@@ -692,7 +692,7 @@
 
 /* Get the time that a historical movement occurred between this event and
  * the previous event, in the java.lang.System.nanoTime() time base. */
-int64_t AMotionEvent_getHistoricalEventTime(AInputEvent* motion_event,
+int64_t AMotionEvent_getHistoricalEventTime(const AInputEvent* motion_event,
         size_t history_index);
 
 /* Get the historical raw X coordinate of this event for the given pointer index that
@@ -719,14 +719,14 @@
  * occurred between this event and the previous motion event.
  * Whole numbers are pixels; the value may have a fraction for input devices
  * that are sub-pixel precise. */
-float AMotionEvent_getHistoricalX(AInputEvent* motion_event, size_t pointer_index,
+float AMotionEvent_getHistoricalX(const AInputEvent* motion_event, size_t pointer_index,
         size_t history_index);
 
 /* Get the historical Y coordinate of this event for the given pointer index that
  * occurred between this event and the previous motion event.
  * Whole numbers are pixels; the value may have a fraction for input devices
  * that are sub-pixel precise. */
-float AMotionEvent_getHistoricalY(AInputEvent* motion_event, size_t pointer_index,
+float AMotionEvent_getHistoricalY(const AInputEvent* motion_event, size_t pointer_index,
         size_t history_index);
 
 /* Get the historical pressure of this event for the given pointer index that
@@ -734,7 +734,7 @@
  * The pressure generally ranges from 0 (no pressure at all) to 1 (normal pressure),
  * although values higher than 1 may be generated depending on the calibration of
  * the input device. */
-float AMotionEvent_getHistoricalPressure(AInputEvent* motion_event, size_t pointer_index,
+float AMotionEvent_getHistoricalPressure(const AInputEvent* motion_event, size_t pointer_index,
         size_t history_index);
 
 /* Get the current scaled value of the approximate size for the given pointer index that
@@ -744,7 +744,7 @@
  * touch is normalized with the device specific range of values
  * and scaled to a value between 0 and 1.  The value of size can be used to
  * determine fat touch events. */
-float AMotionEvent_getHistoricalSize(AInputEvent* motion_event, size_t pointer_index,
+float AMotionEvent_getHistoricalSize(const AInputEvent* motion_event, size_t pointer_index,
         size_t history_index);
 
 /* Get the historical length of the major axis of an ellipse that describes the touch area
diff --git a/include/utils/Log.h b/include/utils/Log.h
index 98c441c..4259c86 100644
--- a/include/utils/Log.h
+++ b/include/utils/Log.h
@@ -62,7 +62,7 @@
  * }
  */
 #define ALOGD_IF_SLOW(timeoutMillis, message) \
-        LogIfSlow _logIfSlow(LOG_TAG, ANDROID_LOG_DEBUG, timeoutMillis, message);
+    android::LogIfSlow _logIfSlow(LOG_TAG, ANDROID_LOG_DEBUG, timeoutMillis, message);
 
 } // namespace android
 
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index aa19d17..359742c 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -1473,6 +1473,8 @@
         if (objectsSize) {
             objects = (size_t*)malloc(objectsSize*sizeof(size_t));
             if (!objects) {
+                free(data);
+
                 mError = NO_MEMORY;
                 return NO_MEMORY;
             }
@@ -1553,7 +1555,7 @@
             mError = NO_MEMORY;
             return NO_MEMORY;
         }
-        
+
         if(!(mDataCapacity == 0 && mObjects == NULL
              && mObjectsCapacity == 0)) {
             ALOGE("continueWrite: %d/%p/%d/%d", mDataCapacity, mObjects, mObjectsCapacity, desired);
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index c15dfd5..ee69222 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -559,31 +559,88 @@
     clearWithOpenGL(hw, clip, 0,0,0,0);
 }
 
+static void setupOpenGL10(bool premultipliedAlpha, bool opaque, int alpha) {
+    // OpenGL ES 1.0 doesn't support texture combiners.
+    // This path doesn't properly handle opaque layers that have non-opaque
+    // alpha values. The alpha channel will be copied into the framebuffer or
+    // screenshot, so if the framebuffer or screenshot is blended on top of
+    // something else,  whatever is below the window will incorrectly show
+    // through.
+    if (CC_UNLIKELY(alpha < 0xFF)) {
+        GLfloat floatAlpha = alpha * (1.0f / 255.0f);
+        if (premultipliedAlpha) {
+            glColor4f(floatAlpha, floatAlpha, floatAlpha, floatAlpha);
+        } else {
+            glColor4f(1.0f, 1.0f, 1.0f, floatAlpha);
+        }
+        glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+    } else {
+        glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+    }
+}
+
+static void setupOpenGL11(bool premultipliedAlpha, bool opaque, int alpha) {
+    GLenum combineRGB;
+    GLenum combineAlpha;
+    GLenum src0Alpha;
+    GLfloat envColor[4];
+
+    if (CC_UNLIKELY(alpha < 0xFF)) {
+        // Cv = premultiplied ? Cs*alpha : Cs
+        // Av = !opaque       ? alpha*As : 1.0
+        combineRGB   = premultipliedAlpha ? GL_MODULATE : GL_REPLACE;
+        combineAlpha = !opaque            ? GL_MODULATE : GL_REPLACE;
+        src0Alpha    = GL_CONSTANT;
+        envColor[0]  = alpha * (1.0f / 255.0f);
+    } else {
+        // Cv = Cs
+        // Av = opaque ? 1.0 : As
+        combineRGB   = GL_REPLACE;
+        combineAlpha = GL_REPLACE;
+        src0Alpha    = opaque ? GL_CONSTANT : GL_TEXTURE;
+        envColor[0]  = 1.0f;
+    }
+
+    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
+    glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, combineRGB);
+    glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_TEXTURE);
+    glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
+    if (combineRGB == GL_MODULATE) {
+        glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_CONSTANT);
+        glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
+    }
+    glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, combineAlpha);
+    glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, src0Alpha);
+    glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
+    if (combineAlpha == GL_MODULATE) {
+        glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_TEXTURE);
+        glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
+    }
+    if (combineRGB == GL_MODULATE || src0Alpha == GL_CONSTANT) {
+        envColor[1] = envColor[0];
+        envColor[2] = envColor[0];
+        envColor[3] = envColor[0];
+        glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, envColor);
+    }
+}
+
 void Layer::drawWithOpenGL(
         const sp<const DisplayDevice>& hw, const Region& clip) const {
     const uint32_t fbHeight = hw->getHeight();
     const State& s(drawingState());
 
-    GLenum src = mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA;
-    if (CC_UNLIKELY(s.alpha < 0xFF)) {
-        const GLfloat alpha = s.alpha * (1.0f/255.0f);
-        if (mPremultipliedAlpha) {
-            glColor4f(alpha, alpha, alpha, alpha);
-        } else {
-            glColor4f(1, 1, 1, alpha);
-        }
-        glEnable(GL_BLEND);
-        glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA);
-        glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+    if (mFlinger->getGlesVersion() == GLES_VERSION_1_0) {
+        setupOpenGL10(mPremultipliedAlpha, isOpaque(), s.alpha);
     } else {
-        glColor4f(1, 1, 1, 1);
-        glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
-        if (!isOpaque()) {
-            glEnable(GL_BLEND);
-            glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA);
-        } else {
-            glDisable(GL_BLEND);
-        }
+        setupOpenGL11(mPremultipliedAlpha, isOpaque(), s.alpha);
+    }
+
+    if (s.alpha < 0xFF || !isOpaque()) {
+        glEnable(GL_BLEND);
+        glBlendFunc(mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA,
+                    GL_ONE_MINUS_SRC_ALPHA);
+    } else {
+        glDisable(GL_BLEND);
     }
 
     LayerMesh mesh;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 6ab33ef..fbd9f25 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -414,6 +414,22 @@
     return ctxt;
 }
 
+static GlesVersion parseGlesVersion(const char* str) {
+    int major, minor;
+    if (sscanf(str, "OpenGL ES-CM %d.%d", &major, &minor) != 2) {
+        ALOGW("Unable to parse GL_VERSION string: \"%s\"", str);
+        return GLES_VERSION_1_0;
+    }
+
+    if (major == 1 && minor == 0) return GLES_VERSION_1_0;
+    if (major == 1 && minor >= 1) return GLES_VERSION_1_1;
+    if (major == 2 && minor >= 0) return GLES_VERSION_2_0;
+    if (major == 3 && minor >= 0) return GLES_VERSION_3_0;
+
+    ALOGW("Unrecognized OpenGL ES version: %d.%d", major, minor);
+    return GLES_VERSION_1_0;
+}
+
 void SurfaceFlinger::initializeGL(EGLDisplay display) {
     GLExtensions& extensions(GLExtensions::getInstance());
     extensions.initWithGLStrings(
@@ -425,6 +441,8 @@
             eglQueryString(display, EGL_VERSION),
             eglQueryString(display, EGL_EXTENSIONS));
 
+    mGlesVersion = parseGlesVersion(extensions.getVersion());
+
     glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize);
     glGetIntegerv(GL_MAX_VIEWPORT_DIMS, mMaxViewportDims);
 
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index e7745b8..089c265 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -72,6 +72,13 @@
     eTransactionMask          = 0x07
 };
 
+enum GlesVersion {
+    GLES_VERSION_1_0    = 0x10000,
+    GLES_VERSION_1_1    = 0x10001,
+    GLES_VERSION_2_0    = 0x20000,
+    GLES_VERSION_3_0    = 0x30000,
+};
+
 class SurfaceFlinger : public BinderService<SurfaceFlinger>,
                        public BnSurfaceComposer,
                        private IBinder::DeathRecipient,
@@ -121,6 +128,11 @@
     // TODO: this should be made accessible only to HWComposer
     const Vector< sp<Layer> >& getLayerSortedByZForHwcDisplay(int id);
 
+    // return the version of the OpenGL ES composition context
+    GlesVersion getGlesVersion() const {
+        return mGlesVersion;
+    }
+
 private:
     friend class Client;
     friend class DisplayEventConnection;
@@ -421,6 +433,7 @@
     EGLConfig mEGLConfig;
     EGLDisplay mEGLDisplay;
     EGLint mEGLNativeVisualId;
+    GlesVersion mGlesVersion;
     sp<IBinder> mBuiltinDisplays[DisplayDevice::NUM_DISPLAY_TYPES];
 
     // Can only accessed from the main thread, these members