Merge "bugfix for: OOM error while doing voice search repeatedly" into froyo
diff --git a/include/binder/IMemory.h b/include/binder/IMemory.h
index ae042cb..74d2cc7 100644
--- a/include/binder/IMemory.h
+++ b/include/binder/IMemory.h
@@ -36,8 +36,7 @@
 
     // flags returned by getFlags()
     enum {
-        READ_ONLY   = 0x00000001,
-        MAP_ONCE    = 0x00000002
+        READ_ONLY   = 0x00000001
     };
 
     virtual int         getHeapID() const = 0;
diff --git a/include/binder/MemoryHeapBase.h b/include/binder/MemoryHeapBase.h
index d793c24..2f2e31b 100644
--- a/include/binder/MemoryHeapBase.h
+++ b/include/binder/MemoryHeapBase.h
@@ -32,7 +32,6 @@
 public:
     enum {
         READ_ONLY = IMemoryHeap::READ_ONLY,
-        MAP_ONCE = IMemoryHeap::MAP_ONCE,
         // memory won't be mapped locally, but will be mapped in the remote
         // process.
         DONT_MAP_LOCALLY = 0x00000100,
diff --git a/include/binder/MemoryHeapPmem.h b/include/binder/MemoryHeapPmem.h
index aac164f..e1660c4 100644
--- a/include/binder/MemoryHeapPmem.h
+++ b/include/binder/MemoryHeapPmem.h
@@ -46,8 +46,7 @@
         sp<MemoryHeapPmem>  mClientHeap;
     };
     
-    MemoryHeapPmem(const sp<MemoryHeapBase>& pmemHeap,
-                uint32_t flags = IMemoryHeap::MAP_ONCE);
+    MemoryHeapPmem(const sp<MemoryHeapBase>& pmemHeap, uint32_t flags = 0);
     ~MemoryHeapPmem();
 
     /* HeapInterface additions */
diff --git a/libs/audioflinger/A2dpAudioInterface.cpp b/libs/audioflinger/A2dpAudioInterface.cpp
index 747d0e4..995e31c 100644
--- a/libs/audioflinger/A2dpAudioInterface.cpp
+++ b/libs/audioflinger/A2dpAudioInterface.cpp
@@ -302,7 +302,7 @@
 
 Error:
     // Simulate audio output timing in case of error
-    usleep(bytes * 1000000 / frameSize() / sampleRate());
+    usleep(((bytes * 1000 )/ frameSize() / sampleRate()) * 1000);
 
     return status;
 }
diff --git a/libs/binder/IMemory.cpp b/libs/binder/IMemory.cpp
index 6c1d225..bc8c412 100644
--- a/libs/binder/IMemory.cpp
+++ b/libs/binder/IMemory.cpp
@@ -46,7 +46,6 @@
     virtual void binderDied(const wp<IBinder>& who);
 
     sp<IMemoryHeap> find_heap(const sp<IBinder>& binder); 
-    void pin_heap(const sp<IBinder>& binder); 
     void free_heap(const sp<IBinder>& binder); 
     sp<IMemoryHeap> get_heap(const sp<IBinder>& binder);
     void dump_heaps();
@@ -100,13 +99,9 @@
     static inline void dump_heaps() {
         gHeapCache->dump_heaps();       
     }
-    void inline pin_heap() const {
-        gHeapCache->pin_heap(const_cast<BpMemoryHeap*>(this)->asBinder());
-    }
 
     void assertMapped() const;
     void assertReallyMapped() const;
-    void pinHeap() const;
 
     mutable volatile int32_t mHeapId;
     mutable void*       mBase;
@@ -320,11 +315,6 @@
                         asBinder().get(), size, fd, strerror(errno));
                 close(fd);
             } else {
-                if (flags & MAP_ONCE) {
-                    //LOGD("pinning heap (binder=%p, size=%d, fd=%d",
-                    //        asBinder().get(), size, fd);
-                    pin_heap();
-                }
                 mSize = size;
                 mFlags = flags;
                 android_atomic_write(fd, &mHeapId);
@@ -421,19 +411,6 @@
     }
 }
 
-void HeapCache::pin_heap(const sp<IBinder>& binder) 
-{
-    Mutex::Autolock _l(mHeapCacheLock);
-    ssize_t i = mHeapCache.indexOfKey(binder);
-    if (i>=0) {
-        heap_info_t& info(mHeapCache.editValueAt(i));
-        android_atomic_inc(&info.count);
-        binder->linkToDeath(this);
-    } else {
-        LOGE("pin_heap binder=%p not found!!!", binder.get());
-    }    
-}
-
 void HeapCache::free_heap(const sp<IBinder>& binder)  {
     free_heap( wp<IBinder>(binder) );
 }
diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
index 5969617..ea68352 100644
--- a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
+++ b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
@@ -90,6 +90,8 @@
 int DisplayHardware::getWidth() const           { return mWidth; }
 int DisplayHardware::getHeight() const          { return mHeight; }
 PixelFormat DisplayHardware::getFormat() const  { return mFormat; }
+uint32_t DisplayHardware::getMaxTextureSize() const { return mMaxTextureSize; }
+uint32_t DisplayHardware::getMaxViewportDims() const { return mMaxViewportDims; }
 
 void DisplayHardware::init(uint32_t dpy)
 {
@@ -246,6 +248,11 @@
     LOGI("version   : %s", glGetString(GL_VERSION));
     LOGI("extensions: %s", gl_extensions);
 
+    glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize);
+    glGetIntegerv(GL_MAX_VIEWPORT_DIMS, &mMaxViewportDims);
+    LOGI("GL_MAX_TEXTURE_SIZE = %d", mMaxTextureSize);
+    LOGI("GL_MAX_VIEWPORT_DIMS = %d", mMaxViewportDims);
+
 #if 0
     // for drivers that don't have proper support for flushing cached buffers
     // on gralloc unlock, uncomment this block and test for the specific
@@ -273,6 +280,7 @@
 #warning "EGL_ANDROID_image_native_buffer not supported"
 #endif
 
+
     // Unbind the context from this thread
     eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
 
diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardware.h b/libs/surfaceflinger/DisplayHardware/DisplayHardware.h
index 6914d0c..df046af 100644
--- a/libs/surfaceflinger/DisplayHardware/DisplayHardware.h
+++ b/libs/surfaceflinger/DisplayHardware/DisplayHardware.h
@@ -76,6 +76,8 @@
     PixelFormat getFormat() const;
     uint32_t    getFlags() const;
     void        makeCurrent() const;
+    uint32_t    getMaxTextureSize() const;
+    uint32_t    getMaxViewportDims() const;
 
     uint32_t getPageFlipCount() const;
     EGLDisplay getEGLDisplay() const { return mDisplay; }
@@ -104,6 +106,8 @@
     PixelFormat     mFormat;
     uint32_t        mFlags;
     mutable uint32_t mPageFlipCount;
+    GLint           mMaxViewportDims;
+    GLint           mMaxTextureSize;
     
     sp<FramebufferNativeWindow> mNativeWindow;
     overlay_control_device_t* mOverlayEngine;
diff --git a/libs/surfaceflinger/Layer.cpp b/libs/surfaceflinger/Layer.cpp
index 4dc4a15..0a3254d 100644
--- a/libs/surfaceflinger/Layer.cpp
+++ b/libs/surfaceflinger/Layer.cpp
@@ -41,6 +41,10 @@
 
 namespace android {
 
+template <typename T> inline T min(T a, T b) {
+    return a<b ? a : b;
+}
+
 // ---------------------------------------------------------------------------
 
 const uint32_t Layer::typeInfo = LayerBaseClient::typeInfo | 4;
@@ -109,17 +113,26 @@
 
     // the display's pixel format
     const DisplayHardware& hw(graphicPlane(0).displayHardware());
+    uint32_t const maxSurfaceDims = min(
+            hw.getMaxTextureSize(), hw.getMaxViewportDims());
+
+    // never allow a surface larger than what our underlying GL implementation
+    // can handle.
+    if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
+        return BAD_VALUE;
+    }
+
     PixelFormatInfo displayInfo;
     getPixelFormatInfo(hw.getFormat(), &displayInfo);
     const uint32_t hwFlags = hw.getFlags();
     
     mFormat = format;
-    mWidth = w;
+    mWidth  = w;
     mHeight = h;
     mSecure = (flags & ISurfaceComposer::eSecure) ? true : false;
     mNeedsBlending = (info.h_alpha - info.l_alpha) > 0;
     mNoEGLImageForSwBuffers = !(hwFlags & DisplayHardware::CACHED_BUFFERS);
-    
+
     // we use the red index
     int displayRedSize = displayInfo.getSize(PixelFormatInfo::INDEX_RED);
     int layerRedsize = info.getSize(PixelFormatInfo::INDEX_RED);
diff --git a/libs/surfaceflinger/LayerBase.cpp b/libs/surfaceflinger/LayerBase.cpp
index efbc77a..a8b735e 100644
--- a/libs/surfaceflinger/LayerBase.cpp
+++ b/libs/surfaceflinger/LayerBase.cpp
@@ -437,64 +437,49 @@
 
     Region::const_iterator it = clip.begin();
     Region::const_iterator const end = clip.end();
-    if (UNLIKELY(transformed()
-            || !(mFlags & DisplayHardware::DRAW_TEXTURE_EXTENSION) )) 
-    {
-        //StopWatch watch("GL transformed");
-        const GLfixed texCoords[4][2] = {
-                { 0,        0 },
-                { 0,        0x10000 },
-                { 0x10000,  0x10000 },
-                { 0x10000,  0 }
-        };
 
-        glMatrixMode(GL_TEXTURE);
-        glLoadIdentity();
+    //StopWatch watch("GL transformed");
+    const GLfixed texCoords[4][2] = {
+            { 0,        0 },
+            { 0,        0x10000 },
+            { 0x10000,  0x10000 },
+            { 0x10000,  0 }
+    };
 
-        // the texture's source is rotated
-        switch (texture.transform) {
-            case HAL_TRANSFORM_ROT_90:
-                glTranslatef(0, 1, 0);
-                glRotatef(-90, 0, 0, 1);
-                break;
-            case HAL_TRANSFORM_ROT_180:
-                glTranslatef(1, 1, 0);
-                glRotatef(-180, 0, 0, 1);
-                break;
-            case HAL_TRANSFORM_ROT_270:
-                glTranslatef(1, 0, 0);
-                glRotatef(-270, 0, 0, 1);
-                break;
-        }
+    glMatrixMode(GL_TEXTURE);
+    glLoadIdentity();
 
-        if (texture.NPOTAdjust) {
-            glScalef(texture.wScale, texture.hScale, 1.0f);
-        }
-
-        glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-        glVertexPointer(2, GL_FIXED, 0, mVertices);
-        glTexCoordPointer(2, GL_FIXED, 0, texCoords);
-
-        while (it != end) {
-            const Rect& r = *it++;
-            const GLint sy = fbHeight - (r.top + r.height());
-            glScissor(r.left, sy, r.width(), r.height());
-            glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 
-        }
-        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
-    } else {
-        GLint crop[4] = { 0, height, width, -height };
-        glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, crop);
-        int x = tx();
-        int y = ty();
-        y = fbHeight - (y + height);
-        while (it != end) {
-            const Rect& r = *it++;
-            const GLint sy = fbHeight - (r.top + r.height());
-            glScissor(r.left, sy, r.width(), r.height());
-            glDrawTexiOES(x, y, 0, width, height);
-        }
+    // the texture's source is rotated
+    switch (texture.transform) {
+        case HAL_TRANSFORM_ROT_90:
+            glTranslatef(0, 1, 0);
+            glRotatef(-90, 0, 0, 1);
+            break;
+        case HAL_TRANSFORM_ROT_180:
+            glTranslatef(1, 1, 0);
+            glRotatef(-180, 0, 0, 1);
+            break;
+        case HAL_TRANSFORM_ROT_270:
+            glTranslatef(1, 0, 0);
+            glRotatef(-270, 0, 0, 1);
+            break;
     }
+
+    if (texture.NPOTAdjust) {
+        glScalef(texture.wScale, texture.hScale, 1.0f);
+    }
+
+    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+    glVertexPointer(2, GL_FIXED, 0, mVertices);
+    glTexCoordPointer(2, GL_FIXED, 0, texCoords);
+
+    while (it != end) {
+        const Rect& r = *it++;
+        const GLint sy = fbHeight - (r.top + r.height());
+        glScissor(r.left, sy, r.width(), r.height());
+        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+    }
+    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
 }
 
 void LayerBase::validateTexture(GLint textureName) const