fixed some issues with the software renderer when surfaces are made current.

there was several issues:
- when a surface was made non-current, the last frame wasn't shown and the buffer could stay locked
- when a surface was made current the 2nd time, it would not dequeue a new buffer

now, queue/dequeue are done when the surface is made current.

for this to work, a new query() hook had to be added on android_native_window_t, it allows to retrieve some attributes of a window (currently only width and height).
diff --git a/include/ui/FramebufferNativeWindow.h b/include/ui/FramebufferNativeWindow.h
index e72357a..cb9bf94 100644
--- a/include/ui/FramebufferNativeWindow.h
+++ b/include/ui/FramebufferNativeWindow.h
@@ -62,6 +62,7 @@
     static int dequeueBuffer(android_native_window_t* window, android_native_buffer_t** buffer);
     static int lockBuffer(android_native_window_t* window, android_native_buffer_t* buffer);
     static int queueBuffer(android_native_window_t* window, android_native_buffer_t* buffer);
+    static int query(android_native_window_t* window, int what, int* value);
     
     framebuffer_device_t* fbDev;
     alloc_device_t* grDev;
diff --git a/include/ui/Surface.h b/include/ui/Surface.h
index 8c4f63d..156d453 100644
--- a/include/ui/Surface.h
+++ b/include/ui/Surface.h
@@ -115,6 +115,8 @@
     sp<ISurface>                mSurface;
     SurfaceID                   mToken;
     uint32_t                    mIdentity;
+    uint32_t                    mWidth;
+    uint32_t                    mHeight;
     PixelFormat                 mFormat;
     uint32_t                    mFlags;
     mutable Mutex               mLock;
@@ -192,10 +194,12 @@
     static int dequeueBuffer(android_native_window_t* window, android_native_buffer_t** buffer);
     static int lockBuffer(android_native_window_t* window, android_native_buffer_t* buffer);
     static int queueBuffer(android_native_window_t* window, android_native_buffer_t* buffer);
+    static int query(android_native_window_t* window, int what, int* value);
 
     int dequeueBuffer(android_native_buffer_t** buffer);
     int lockBuffer(android_native_buffer_t* buffer);
     int queueBuffer(android_native_buffer_t* buffer);
+    int query(int what, int* value);
 
     status_t dequeueBuffer(sp<SurfaceBuffer>* buffer);
     status_t lockBuffer(const sp<SurfaceBuffer>& buffer);
@@ -209,6 +213,8 @@
     sp<SurfaceBuffer>           mLockedBuffer;
     SurfaceID                   mToken;
     uint32_t                    mIdentity;
+    uint32_t                    mWidth;
+    uint32_t                    mHeight;
     PixelFormat                 mFormat;
     uint32_t                    mFlags;
     mutable Region              mDirtyRegion;
diff --git a/include/ui/egl/android_natives.h b/include/ui/egl/android_natives.h
index 0398ea7..a3a1316 100644
--- a/include/ui/egl/android_natives.h
+++ b/include/ui/egl/android_natives.h
@@ -60,6 +60,12 @@
 
 // ---------------------------------------------------------------------------
 
+/* attributes queriable with query() */
+enum {
+    NATIVE_WINDOW_WIDTH     = 0,
+    NATIVE_WINDOW_HEIGHT    = 1
+};
+
 struct android_native_window_t 
 {
 #ifdef __cplusplus
@@ -129,8 +135,15 @@
     int     (*queueBuffer)(struct android_native_window_t* window,
                 struct android_native_buffer_t* buffer);
 
+    /*
+     * hook used to retrieve information about the native window.
+     * 
+     * Returns 0 on success or -errno on error.
+     */
+    int     (*query)(struct android_native_window_t* window,
+            int what, int* value);
     
-    void* reserved_proc[5];
+    void* reserved_proc[4];
 };
 
 // ---------------------------------------------------------------------------
diff --git a/libs/ui/FramebufferNativeWindow.cpp b/libs/ui/FramebufferNativeWindow.cpp
index 8c8fd6b..8b7ea21 100644
--- a/libs/ui/FramebufferNativeWindow.cpp
+++ b/libs/ui/FramebufferNativeWindow.cpp
@@ -124,6 +124,7 @@
     android_native_window_t::dequeueBuffer = dequeueBuffer;
     android_native_window_t::lockBuffer = lockBuffer;
     android_native_window_t::queueBuffer = queueBuffer;
+    android_native_window_t::query = query;
 }
 
 FramebufferNativeWindow::~FramebufferNativeWindow() {
@@ -198,6 +199,23 @@
     return res;
 }
 
+int FramebufferNativeWindow::query(android_native_window_t* window,
+        int what, int* value) 
+{
+    FramebufferNativeWindow* self = getSelf(window);
+    Mutex::Autolock _l(self->mutex);
+    framebuffer_device_t* fb = self->fbDev;
+    switch (what) {
+        case NATIVE_WINDOW_WIDTH:
+            *value = fb->width;
+            return NO_ERROR;
+        case NATIVE_WINDOW_HEIGHT:
+            *value = fb->height;
+            return NO_ERROR;
+    }
+    return BAD_VALUE;
+}
+
 // ----------------------------------------------------------------------------
 }; // namespace android
 // ----------------------------------------------------------------------------
diff --git a/libs/ui/Surface.cpp b/libs/ui/Surface.cpp
index aef47fd..04ab64c 100644
--- a/libs/ui/Surface.cpp
+++ b/libs/ui/Surface.cpp
@@ -180,7 +180,7 @@
         uint32_t w, uint32_t h, PixelFormat format, uint32_t flags)
     : mClient(client), mSurface(surface),
       mToken(data.token), mIdentity(data.identity),
-      mFormat(format), mFlags(flags)
+      mWidth(w), mHeight(h), mFormat(format), mFlags(flags)
 {
 }
         
@@ -338,6 +338,8 @@
     uint32_t format = 0;
     SurfaceID token = -1;
     uint32_t identity = 0;
+    uint32_t width = 0;
+    uint32_t height = 0;
     sp<SurfaceComposerClient> client;
     sp<ISurface> sur;
     if (SurfaceControl::isValid(control)) {
@@ -345,6 +347,8 @@
         identity = control->mIdentity;
         client   = control->mClient;
         sur      = control->mSurface;
+        width    = control->mWidth;
+        height   = control->mHeight;
         format   = control->mFormat;
         flags    = control->mFlags;
     }
@@ -352,6 +356,8 @@
     parcel->writeStrongBinder(sur!=0     ? sur->asBinder()      : NULL);
     parcel->writeInt32(token);
     parcel->writeInt32(identity);
+    parcel->writeInt32(width);
+    parcel->writeInt32(height);
     parcel->writeInt32(format);
     parcel->writeInt32(flags);
     return NO_ERROR;
@@ -373,6 +379,7 @@
 Surface::Surface(const sp<SurfaceControl>& surface)
     : mClient(surface->mClient), mSurface(surface->mSurface),
       mToken(surface->mToken), mIdentity(surface->mIdentity),
+      mWidth(surface->mWidth), mHeight(surface->mHeight),
       mFormat(surface->mFormat), mFlags(surface->mFlags),
       mBufferMapper(BufferMapper::get())
 {
@@ -386,6 +393,8 @@
     mSurface    = interface_cast<ISurface>(parcel.readStrongBinder());
     mToken      = parcel.readInt32();
     mIdentity   = parcel.readInt32();
+    mWidth      = parcel.readInt32();
+    mHeight     = parcel.readInt32();
     mFormat     = parcel.readInt32();
     mFlags      = parcel.readInt32();
 
@@ -401,6 +410,7 @@
     android_native_window_t::dequeueBuffer    = dequeueBuffer;
     android_native_window_t::lockBuffer       = lockBuffer;
     android_native_window_t::queueBuffer      = queueBuffer;
+    android_native_window_t::query            = query;
     mSwapRectangle.makeInvalid();
     DisplayInfo dinfo;
     SurfaceComposerClient::getDisplayInfo(0, &dinfo);
@@ -492,6 +502,13 @@
     return self->queueBuffer(buffer);
 }
 
+int Surface::query(android_native_window_t* window, 
+        int what, int* value)
+{
+    Surface* self = getSelf(window);
+    return self->query(what, value);
+}
+
 // ----------------------------------------------------------------------------
 
 status_t Surface::dequeueBuffer(sp<SurfaceBuffer>* buffer)
@@ -499,6 +516,9 @@
     android_native_buffer_t* out;
     status_t err = dequeueBuffer(&out);
     *buffer = SurfaceBuffer::getSelf(out);
+    // reset the width/height with the what we get from the buffer
+    mWidth  = uint32_t(out->width);
+    mHeight = uint32_t(out->height);
     return err;
 }
 
@@ -586,6 +606,19 @@
     return NO_ERROR;
 }
 
+int Surface::query(int what, int* value)
+{
+    switch (what) {
+        case NATIVE_WINDOW_WIDTH:
+            *value = int(mWidth);
+            return NO_ERROR;
+        case NATIVE_WINDOW_HEIGHT:
+            *value = int(mHeight);
+            return NO_ERROR;
+    }
+    return BAD_VALUE;
+}
+
 // ----------------------------------------------------------------------------
 
 status_t Surface::lock(SurfaceInfo* info, bool blocking) {
diff --git a/opengl/libagl/egl.cpp b/opengl/libagl/egl.cpp
index 7afcae7..b0e54d8 100644
--- a/opengl/libagl/egl.cpp
+++ b/opengl/libagl/egl.cpp
@@ -216,8 +216,8 @@
     virtual     EGLBoolean  bindReadSurface(ogles_context_t* gl);
     virtual     void        connect();
     virtual     void        disconnect();
-    virtual     EGLint      getWidth() const    { return buffer->width;  }
-    virtual     EGLint      getHeight() const   { return buffer->height; }
+    virtual     EGLint      getWidth() const    { return width;  }
+    virtual     EGLint      getHeight() const   { return height; }
     virtual     EGLint      getHorizontalResolution() const;
     virtual     EGLint      getVerticalResolution() const;
     virtual     EGLint      getRefreshRate() const;
@@ -365,26 +365,8 @@
     
     // keep a reference on the window
     nativeWindow->common.incRef(&nativeWindow->common);
-
-    // dequeue a buffer
-    nativeWindow->dequeueBuffer(nativeWindow, &buffer);
-
-    // allocate a corresponding depth-buffer
-    width = buffer->width;
-    height = buffer->height;
-    if (depthFormat) {
-        depth.width   = width;
-        depth.height  = height;
-        depth.stride  = depth.width; // use the width here
-        depth.data    = (GGLubyte*)malloc(depth.stride*depth.height*2);
-        if (depth.data == 0) {
-            setError(EGL_BAD_ALLOC, EGL_NO_SURFACE);
-            return;
-        }
-    }
-
-    // keep a reference on the buffer
-    buffer->common.incRef(&buffer->common);
+    nativeWindow->query(nativeWindow, NATIVE_WINDOW_WIDTH, &width);
+    nativeWindow->query(nativeWindow, NATIVE_WINDOW_HEIGHT, &height);
 }
 
 egl_window_surface_v2_t::~egl_window_surface_v2_t() {
@@ -402,6 +384,26 @@
 
 void egl_window_surface_v2_t::connect() 
 {
+    // dequeue a buffer
+    nativeWindow->dequeueBuffer(nativeWindow, &buffer);
+
+    // allocate a corresponding depth-buffer
+    width = buffer->width;
+    height = buffer->height;
+    if (depth.format) {
+        depth.width   = width;
+        depth.height  = height;
+        depth.stride  = depth.width; // use the width here
+        depth.data    = (GGLubyte*)malloc(depth.stride*depth.height*2);
+        if (depth.data == 0) {
+            setError(EGL_BAD_ALLOC, EGL_NO_SURFACE);
+            return;
+        }
+    }
+
+    // keep a reference on the buffer
+    buffer->common.incRef(&buffer->common);
+
     // Lock the buffer
     nativeWindow->lockBuffer(nativeWindow, buffer);
     // pin the buffer down
@@ -420,6 +422,16 @@
         bits = NULL;
         unlock(buffer);
     }
+    // enqueue the last frame
+    nativeWindow->queueBuffer(nativeWindow, buffer);
+    if (buffer) {
+        buffer->common.decRef(&buffer->common);
+        buffer = 0;
+    }
+    if (previousBuffer) {
+        previousBuffer->common.decRef(&previousBuffer->common); 
+        previousBuffer = 0;
+    }
 }
 
 status_t egl_window_surface_v2_t::lock(