Merge "Fix sockfd leakage in SensorService." into lmp-dev
diff --git a/cmds/dumpstate/dumpstate.c b/cmds/dumpstate/dumpstate.c
index f142095..1fbcef6 100644
--- a/cmds/dumpstate/dumpstate.c
+++ b/cmds/dumpstate/dumpstate.c
@@ -438,6 +438,12 @@
         }
     }
 
+    // If we are going to use a socket, do it as early as possible
+    // to avoid timeouts from bugreport.
+    if (use_socket) {
+        redirect_to_socket(stdout, "dumpstate");
+    }
+
     /* open the vibrator before dropping root */
     FILE *vibrator = 0;
     if (do_vibrate) {
@@ -504,9 +510,7 @@
     char path[PATH_MAX], tmp_path[PATH_MAX];
     pid_t gzip_pid = -1;
 
-    if (use_socket) {
-        redirect_to_socket(stdout, "dumpstate");
-    } else if (use_outfile) {
+    if (!use_socket && use_outfile) {
         strlcpy(path, use_outfile, sizeof(path));
         if (do_add_date) {
             char date[80];
diff --git a/include/media/openmax/OMX_Video.h b/include/media/openmax/OMX_Video.h
index 21dc5a6..89425e0 100644
--- a/include/media/openmax/OMX_Video.h
+++ b/include/media/openmax/OMX_Video.h
@@ -818,6 +818,7 @@
     OMX_VIDEO_AVCLevel42  = 0x2000,   /**< Level 4.2 */
     OMX_VIDEO_AVCLevel5   = 0x4000,   /**< Level 5 */
     OMX_VIDEO_AVCLevel51  = 0x8000,   /**< Level 5.1 */
+    OMX_VIDEO_AVCLevel52  = 0x10000,  /**< Level 5.2 */
     OMX_VIDEO_AVCLevelKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ 
     OMX_VIDEO_AVCLevelVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
     OMX_VIDEO_AVCLevelMax = 0x7FFFFFFF  
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index 76504ce..ba5688c 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -36,6 +36,7 @@
 
 #include <private/binder/binder_module.h>
 
+#include <fcntl.h>
 #include <inttypes.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -1280,11 +1281,22 @@
 
     status_t err = NO_ERROR;
     for (size_t i=0 ; i<fd_count && err==NO_ERROR ; i++) {
-        fds[i] = dup(this->readFileDescriptor());
+        int oldfd = this->readFileDescriptor();
+        fds[i] = dup(oldfd);
         if (fds[i] < 0) {
+            int dupErrno = errno;
             err = BAD_VALUE;
-            ALOGE("dup() failed in Parcel::read, i is %zu, fds[i] is %d, fd_count is %zu, error: %s",
-                i, fds[i], fd_count, strerror(errno));
+            int flags = fcntl(oldfd, F_GETFD);
+            int fcntlErrno = errno;
+            const flat_binder_object* flat = readObject(true);
+            ALOGE("dup failed in Parcel::read, fd %zu of %zu\n"
+                "  dup(%d) = %d [errno: %d (%s)]\n"
+                "  fcntl(%d, F_GETFD) = %d [errno: %d (%s)]\n"
+                "  flat %p type %d",
+                i, fd_count,
+                oldfd, fds[i], dupErrno, strerror(dupErrno),
+                oldfd, flags, fcntlErrno, strerror(fcntlErrno),
+                flat, flat ? flat->type : 0);
         }
     }
 
diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp
index b56030e..0e2baa2 100644
--- a/libs/gui/Surface.cpp
+++ b/libs/gui/Surface.cpp
@@ -237,6 +237,7 @@
         result = mGraphicBufferProducer->requestBuffer(buf, &gbuf);
         if (result != NO_ERROR) {
             ALOGE("dequeueBuffer: IGraphicBufferProducer::requestBuffer failed: %d", result);
+            mGraphicBufferProducer->cancelBuffer(buf, fence);
             return result;
         }
     }
diff --git a/services/surfaceflinger/RenderEngine/ProgramCache.cpp b/services/surfaceflinger/RenderEngine/ProgramCache.cpp
index d130506..0de5cca 100644
--- a/services/surfaceflinger/RenderEngine/ProgramCache.cpp
+++ b/services/surfaceflinger/RenderEngine/ProgramCache.cpp
@@ -77,13 +77,44 @@
 
 ANDROID_SINGLETON_STATIC_INSTANCE(ProgramCache)
 
-
 ProgramCache::ProgramCache() {
+    // Until surfaceflinger has a dependable blob cache on the filesystem,
+    // generate shaders on initialization so as to avoid jank.
+    primeCache();
 }
 
 ProgramCache::~ProgramCache() {
 }
 
+void ProgramCache::primeCache() {
+    uint32_t shaderCount = 0;
+    uint32_t keyMask = Key::BLEND_MASK | Key::OPACITY_MASK |
+                       Key::PLANE_ALPHA_MASK | Key::TEXTURE_MASK;
+    // Prime the cache for all combinations of the above masks,
+    // leaving off the experimental color matrix mask options.
+
+    nsecs_t timeBefore = systemTime();
+    for (uint32_t keyVal = 0; keyVal <= keyMask; keyVal++) {
+        Key shaderKey;
+        shaderKey.set(keyMask, keyVal);
+        uint32_t tex = shaderKey.getTextureTarget();
+        if (tex != Key::TEXTURE_OFF &&
+            tex != Key::TEXTURE_EXT &&
+            tex != Key::TEXTURE_2D) {
+            continue;
+        }
+        Program* program = mCache.valueFor(shaderKey);
+        if (program == NULL) {
+            program = generateProgram(shaderKey);
+            mCache.add(shaderKey, program);
+            shaderCount++;
+        }
+    }
+    nsecs_t timeAfter = systemTime();
+    float compileTimeMs = static_cast<float>(timeAfter - timeBefore) / 1.0E6;
+    ALOGD("shader cache generated - %u shaders in %f ms\n", shaderCount, compileTimeMs);
+}
+
 ProgramCache::Key ProgramCache::computeKey(const Description& description) {
     Key needs;
     needs.set(Key::TEXTURE_MASK,
diff --git a/services/surfaceflinger/RenderEngine/ProgramCache.h b/services/surfaceflinger/RenderEngine/ProgramCache.h
index e8b9dcd..1fa53d3 100644
--- a/services/surfaceflinger/RenderEngine/ProgramCache.h
+++ b/services/surfaceflinger/RenderEngine/ProgramCache.h
@@ -112,6 +112,8 @@
     void useProgram(const Description& description);
 
 private:
+    // Generate shaders to populate the cache
+    void primeCache();
     // compute a cache Key from a Description
     static Key computeKey(const Description& description);
     // generates a program from the Key