Integrate from //sandbox/mathias/donut/...@145728

SurfaceFlinger rework for new EGL driver model support.
diff --git a/libs/surfaceflinger/LayerBitmap.cpp b/libs/surfaceflinger/LayerBitmap.cpp
index e844350..d633a2d 100644
--- a/libs/surfaceflinger/LayerBitmap.cpp
+++ b/libs/surfaceflinger/LayerBitmap.cpp
@@ -14,170 +14,204 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "SurfaceFlinger"
-
 #include <stdlib.h>
 #include <stdint.h>
 #include <sys/types.h>
 
-#include <cutils/memory.h>
 #include <utils/Errors.h>
 #include <utils/Log.h>
 #include <utils/MemoryDealer.h>
+#include <utils/MemoryBase.h>
 #include <utils/IMemory.h>
+
 #include <ui/PixelFormat.h>
+#include <ui/Surface.h>
 #include <pixelflinger/pixelflinger.h>
 
+#include "BufferAllocator.h"
 #include "LayerBitmap.h"
 #include "SurfaceFlinger.h"
-#include "VRamHeap.h"
 
 
 namespace android {
 
-// ---------------------------------------------------------------------------
+// ===========================================================================
+// Buffer and implementation of android_native_buffer_t
+// ===========================================================================
+
+Buffer::Buffer(uint32_t w, uint32_t h, PixelFormat format, uint32_t flags)
+    : SurfaceBuffer(), mInitCheck(NO_INIT), mFlags(flags), 
+    mVStride(0)
+{
+    this->format = format;
+    if (w>0 && h>0) {
+        mInitCheck = initSize(w, h);
+    }
+}
+
+Buffer::~Buffer()
+{
+    if (handle) {
+        BufferAllocator& allocator = BufferAllocator::get();
+        if (usage & BufferAllocator::USAGE_SW_READ_MASK) {
+            allocator.unmap(handle);
+        }
+        allocator.free(handle);
+    }
+}
+
+status_t Buffer::initCheck() const {
+    return mInitCheck;
+}
+
+android_native_buffer_t* Buffer::getNativeBuffer() const
+{
+    return static_cast<android_native_buffer_t*>(const_cast<Buffer*>(this));
+}
+
+status_t Buffer::initSize(uint32_t w, uint32_t h)
+{
+    status_t err = NO_ERROR;
+
+    BufferAllocator& allocator = BufferAllocator::get();
+        
+    /*
+     *  buffers used for software rendering, but h/w composition
+     *  are allocated with SW_READ_OFTEN | SW_WRITE_OFTEN | HW_TEXTURE
+     *  
+     *  buffers used for h/w rendering and h/w composition
+     *  are allocated with  HW_RENDER | HW_TEXTURE
+     *  
+     *  buffers used with h/w rendering and either NPOT or no egl_image_ext
+     *  are allocated with SW_READ_RARELY | HW_RENDER 
+     *  
+     */
+    
+    if (mFlags & Buffer::SECURE) {
+        // secure buffer, don't store it into the GPU
+        usage = BufferAllocator::USAGE_SW_READ_OFTEN | 
+                BufferAllocator::USAGE_SW_WRITE_OFTEN;
+    } else {
+        if (mFlags & Buffer::GPU) {
+            // the client wants to do GL rendering
+            usage = BufferAllocator::USAGE_HW_RENDER |
+                    BufferAllocator::USAGE_HW_TEXTURE;
+        } else {
+            // software rendering-client, h/w composition
+            usage = BufferAllocator::USAGE_SW_READ_OFTEN | 
+                    BufferAllocator::USAGE_SW_WRITE_OFTEN |
+                    BufferAllocator::USAGE_HW_TEXTURE;
+        }
+    }
+
+    err = allocator.alloc(w, h, format, usage, &handle, &stride);
+    
+    if (err == NO_ERROR) {
+        if (usage & BufferAllocator::USAGE_SW_READ_MASK) {
+            err = allocator.map(handle, &bits);
+        }
+        if (err == NO_ERROR) {
+            width  = w;
+            height = h;
+            mVStride = 0;
+        }
+    }
+
+    return err;
+}
+
+status_t Buffer::getBitmapSurface(copybit_image_t* img) const
+{
+    img->w = stride  ?: width;
+    img->h = mVStride ?: height;
+    img->format = format;
+    
+    // FIXME: this should use a native_handle
+    img->offset = 0;    
+    img->base = bits;
+    img->fd = getHandle()->data[0];
+    
+    return NO_ERROR;
+}
+
+status_t Buffer::getBitmapSurface(GGLSurface* sur) const
+{
+    sur->version = sizeof(GGLSurface);
+    sur->width = width;
+    sur->height = height;
+    sur->stride = stride;
+    sur->format = format;
+    sur->vstride = mVStride;
+    sur->data = static_cast<GGLubyte*>(bits);
+    return NO_ERROR;
+}
+
+// ===========================================================================
+// LayerBitmap
+// ===========================================================================
+
 
 LayerBitmap::LayerBitmap()
-    : mAllocFlags(0), mOffset(0), mSize(-1U), mAlignment(2)
+    : mInfo(0), mWidth(0), mHeight(0)
 {
-    memset(&mSurface, 0, sizeof(mSurface));
 }
 
 LayerBitmap::~LayerBitmap()
 {
-    mSurface.data = 0;
 }
 
-status_t LayerBitmap::init(const sp<MemoryDealer>& allocator)
+status_t LayerBitmap::init(surface_info_t* info,
+        uint32_t w, uint32_t h, PixelFormat format, uint32_t flags)
 {
-    if (mAllocator != NULL)
+    if (info == NULL)
         return BAD_VALUE;
-    mAllocator = allocator;
+    
+    mFormat = format;
+    mFlags = flags;
+    mWidth = w;
+    mHeight = h;
+
+    mInfo = info;
+    memset(info, 0, sizeof(surface_info_t));
+    info->flags = surface_info_t::eNeedNewBuffer;
+    
+    // init the buffer, but don't trigger an allocation
+    mBuffer = new Buffer(0, 0, format, flags);
     return NO_ERROR;
 }
 
-status_t LayerBitmap::setBits(uint32_t w, uint32_t h, uint32_t alignment, 
-        PixelFormat format, uint32_t flags)
+status_t LayerBitmap::setSize(uint32_t w, uint32_t h)
 {
-    const sp<MemoryDealer>& allocator(mAllocator);
-    if (allocator == NULL)
-        return NO_INIT;
-
-    if (UNLIKELY(w == mSurface.width && h == mSurface.height &&
-            format == mSurface.format))
-    { // same format and size, do nothing.
-        return NO_ERROR;
-    }
-
-    PixelFormatInfo info;
-    getPixelFormatInfo(format, &info);
-
-    uint32_t allocFlags = MemoryDealer::PAGE_ALIGNED;
-    const uint32_t align = 4; // must match GL_UNPACK_ALIGNMENT
-    const uint32_t Bpp = info.bytesPerPixel;
-    uint32_t stride = (w + (alignment-1)) & ~(alignment-1);
-    stride = ((stride * Bpp + (align-1)) & ~(align-1)) / Bpp;
-    size_t size = info.getScanlineSize(stride) * h;
-    if (allocFlags & MemoryDealer::PAGE_ALIGNED) {
-        size_t pagesize = getpagesize();
-        size = (size + (pagesize-1)) & ~(pagesize-1);
-    }
-
-    /* FIXME: we should be able to have a h/v stride because the user of the
-     * surface might have stride limitation (for instance h/w codecs often do)
-     */
-    int32_t vstride = 0;
-
-    mAlignment = alignment;
-    mAllocFlags = allocFlags;
-    mOffset = 0;
-    if (mSize != size) {
-        // would be nice to have a reallocate() api
-        mBitsMemory.clear(); // free-memory
-        mBitsMemory = allocator->allocate(size, allocFlags);
-        mSize = size;
-    } else {
-        // don't erase memory if we didn't have to reallocate
-        flags &= ~SECURE_BITS;
-    }
-    if (mBitsMemory != 0) {
-        mOffset = mBitsMemory->offset();
-        mSurface.data = static_cast<GGLubyte*>(mBitsMemory->pointer());
-        mSurface.version = sizeof(GGLSurface);
-        mSurface.width  = w;
-        mSurface.height = h;
-        mSurface.stride = stride;
-        mSurface.vstride = vstride;
-        mSurface.format = format;
-        if (flags & SECURE_BITS)
-            clear();
-    }
-
-    if (mBitsMemory==0 || mSurface.data==0) {
-        LOGE("not enough memory for layer bitmap size=%u", size);
-        allocator->dump("LayerBitmap");
-        mSurface.data = 0;
-        mSize = -1U;
-        return NO_MEMORY;
+    Mutex::Autolock _l(mLock);
+    if ((w != mWidth) || (h != mHeight)) {
+        mWidth  = w;
+        mHeight = h;
+        // this will signal the client that it needs to asks us for a new buffer
+        mInfo->flags = surface_info_t::eNeedNewBuffer;
     }
     return NO_ERROR;
 }
 
-void LayerBitmap::clear()
+sp<Buffer> LayerBitmap::allocate()
 {
-    // NOTE: this memset should not be necessary, at least for
-    // opaque surface. However, for security reasons it's better to keep it
-    // (in the case of pmem, it's possible that the memory contains old
-    // data)
-    if (mSurface.data) {
-        memset(mSurface.data, 0, mSize);
-        //if (bytesPerPixel(mSurface.format) == 4) {
-        //    android_memset32((uint32_t*)mSurface.data, 0xFF0000FF, mSize);
-        //} else  {
-        //    android_memset16((uint16_t*)mSurface.data, 0xF800, mSize);
-        //}
+    Mutex::Autolock _l(mLock);
+    sp<Buffer> buffer(mBuffer);
+    const uint32_t w = mWidth; 
+    const uint32_t h = mHeight;
+    if (w != buffer->getWidth() || h != buffer->getHeight()) {
+        surface_info_t* info = mInfo;
+        buffer = new Buffer(w, h, mFormat, mFlags);
+        status_t err = buffer->initCheck();
+        if (LIKELY(err == NO_ERROR)) {
+            info->flags  = surface_info_t::eBufferDirty;
+            info->status = NO_ERROR;
+        } else {
+            memset(info, 0, sizeof(surface_info_t));
+            info->status = NO_MEMORY;
+        }
+        mBuffer = buffer;
     }
-}
-
-status_t LayerBitmap::getInfo(surface_info_t* info) const
-{
-    if (mSurface.data == 0) {
-        memset(info, 0, sizeof(surface_info_t));
-        info->bits_offset = NO_MEMORY;
-        return NO_MEMORY;
-    }
-    info->w     = uint16_t(width());
-    info->h     = uint16_t(height());
-    info->stride= uint16_t(stride());
-    info->bpr   = uint16_t(stride() * bytesPerPixel(pixelFormat()));
-    info->format= uint8_t(pixelFormat());
-    info->flags = surface_info_t::eBufferDirty;
-    info->bits_offset = ssize_t(mOffset);
-    return NO_ERROR;
-}
-
-status_t LayerBitmap::resize(uint32_t w, uint32_t h)
-{
-    int err = setBits(w, h, mAlignment, pixelFormat(), SECURE_BITS);
-    return err;
-}
-
-size_t LayerBitmap::size() const
-{
-    return mSize;
-}
-
-void LayerBitmap::getBitmapSurface(copybit_image_t* img) const
-{
-    const sp<IMemoryHeap>& mh(getAllocator()->getMemoryHeap());
-    void* sbase = mh->base();
-    const GGLSurface& t(surface());
-    img->w = t.stride  ?: t.width;
-    img->h = t.vstride ?: t.height;
-    img->format = t.format;
-    img->offset = intptr_t(t.data) - intptr_t(sbase);
-    img->base = sbase;
-    img->fd = mh->heapID();
+    return buffer;
 }
 
 // ---------------------------------------------------------------------------