Merge change I852f8e46 into eclair

* changes:
  Only re-initialize backup state if @pm@ metadata is missing, to defensively work around a still-mysterious bug where the list of saved packages ends up being empty even though we still have state pending.  If we do re-initialize, then wipe all state to make sure the right thing happens.
diff --git a/libs/surfaceflinger/Layer.cpp b/libs/surfaceflinger/Layer.cpp
index 2894bf0..07222ec 100644
--- a/libs/surfaceflinger/Layer.cpp
+++ b/libs/surfaceflinger/Layer.cpp
@@ -294,8 +294,8 @@
                 this, index, w, h, strerror(-err));
     } else {
         LOGD_IF(DEBUG_RESIZE,
-                "Layer::requestBuffer(this=%p), index=%d, w=%d, h=%d",
-                this, index, w, h);
+                "Layer::requestBuffer(this=%p), index=%d, w=%d, h=%d, handle=%p",
+                this, index, w, h, buffer->handle);
     }
 
     if (err == NO_ERROR && buffer->handle != 0) {
@@ -318,22 +318,18 @@
     const Layer::State& front(drawingState());
     const Layer::State& temp(currentState());
 
-    // Index of the back buffer
-    const bool backbufferChanged = (front.w != temp.w) || (front.h != temp.h);
-    if (backbufferChanged) {
+    if ((front.requested_w != temp.requested_w) || 
+        (front.requested_h != temp.requested_h)) {
         // the size changed, we need to ask our client to request a new buffer
         LOGD_IF(DEBUG_RESIZE,
                     "resize (layer=%p), requested (%dx%d), "
                     "drawing (%d,%d), (%dx%d), (%dx%d)",
-                    this, int(temp.w), int(temp.h),
-                    int(drawingState().w), int(drawingState().h),
+                    this, 
+                    int(temp.requested_w), int(temp.requested_h),
+                    int(front.requested_w), int(front.requested_h),
                     int(mBuffers[0]->getWidth()), int(mBuffers[0]->getHeight()),
                     int(mBuffers[1]->getWidth()), int(mBuffers[1]->getHeight()));
 
-        // record the new size, form this point on, when the client request a
-        // buffer, it'll get the new size.
-        setDrawingSize(temp.w, temp.h);
-
         // we're being resized and there is a freeze display request,
         // acquire a freeze lock, so that the screen stays put
         // until we've redrawn at the new size; this is to avoid
@@ -346,9 +342,16 @@
             }
         }
 
-        // recompute the visible region
-        flags |= Layer::eVisibleRegion;
-        this->contentDirty = true;
+        // this will make sure LayerBase::doTransaction doesn't update
+        // the drawing state's size
+        Layer::State& editDraw(mDrawingState);
+        editDraw.requested_w = temp.requested_w;
+        editDraw.requested_h = temp.requested_h;
+
+        // record the new size, form this point on, when the client request a
+        // buffer, it'll get the new size.
+        setDrawingSize(temp.requested_w, temp.requested_h);
+
         // all buffers need reallocation
         lcblk->reallocate();
     }
@@ -392,11 +395,35 @@
     const Region dirty(lcblk->getDirtyRegion(buf));
     mPostedDirtyRegion = dirty.intersect( newFrontBuffer->getBounds() );
 
-
     const Layer::State& front(drawingState());
-    if (newFrontBuffer->getWidth() == front.w &&
-        newFrontBuffer->getHeight() ==front.h) {
-        mFreezeLock.clear();
+    if (newFrontBuffer->getWidth()  == front.requested_w &&
+        newFrontBuffer->getHeight() == front.requested_h)
+    {
+        if ((front.w != front.requested_w) ||
+            (front.h != front.requested_h))
+        {
+            // Here we pretend the transaction happened by updating the
+            // current and drawing states. Drawing state is only accessed
+            // in this thread, no need to have it locked
+            Layer::State& editDraw(mDrawingState);
+            editDraw.w = editDraw.requested_w;
+            editDraw.h = editDraw.requested_h;
+
+            // We also need to update the current state so that we don't
+            // end-up doing too much work during the next transaction.
+            // NOTE: We actually don't need hold the transaction lock here
+            // because State::w and State::h are only accessed from
+            // this thread
+            Layer::State& editTemp(currentState());
+            editTemp.w = editDraw.w;
+            editTemp.h = editDraw.h;
+
+            // recompute visible region
+            recomputeVisibleRegions = true;
+
+            // we now have the correct size, unfreeze the screen
+            mFreezeLock.clear();
+        }
     }
 
     // FIXME: signal an event if we have more buffers waiting
diff --git a/libs/surfaceflinger/LayerBase.cpp b/libs/surfaceflinger/LayerBase.cpp
index a351253..d83c842 100644
--- a/libs/surfaceflinger/LayerBase.cpp
+++ b/libs/surfaceflinger/LayerBase.cpp
@@ -34,12 +34,6 @@
 #include "DisplayHardware/DisplayHardware.h"
 
 
-// We don't honor the premultiplied alpha flags, which means that
-// premultiplied surface may be composed using a non-premultiplied
-// equation. We do this because it may be a lot faster on some hardware
-// The correct value is HONOR_PREMULTIPLIED_ALPHA = 1
-#define HONOR_PREMULTIPLIED_ALPHA   0
-
 namespace android {
 
 // ---------------------------------------------------------------------------
@@ -89,26 +83,22 @@
     if (flags & ISurfaceComposer::eNonPremultiplied)
         mPremultipliedAlpha = false;
 
-    mCurrentState.z         = 0;
-    mCurrentState.w         = w;
-    mCurrentState.h         = h;
-    mCurrentState.alpha     = 0xFF;
-    mCurrentState.flags     = layerFlags;
-    mCurrentState.sequence  = 0;
+    mCurrentState.z             = 0;
+    mCurrentState.w             = w;
+    mCurrentState.h             = h;
+    mCurrentState.requested_w   = w;
+    mCurrentState.requested_h   = h;
+    mCurrentState.alpha         = 0xFF;
+    mCurrentState.flags         = layerFlags;
+    mCurrentState.sequence      = 0;
     mCurrentState.transform.set(0, 0);
 
     // drawing state & current state are identical
     mDrawingState = mCurrentState;
 }
 
-void LayerBase::commitTransaction(bool skipSize) {
-    const uint32_t w = mDrawingState.w;
-    const uint32_t h = mDrawingState.h;
+void LayerBase::commitTransaction() {
     mDrawingState = mCurrentState;
-    if (skipSize) {
-        mDrawingState.w = w;
-        mDrawingState.h = h;
-    }
 }
 void LayerBase::forceVisibilityTransaction() {
     // this can be called without SurfaceFlinger.mStateLock, but if we
@@ -144,10 +134,10 @@
     return true;
 }
 bool LayerBase::setSize(uint32_t w, uint32_t h) {
-    if (mCurrentState.w == w && mCurrentState.h == h)
+    if (mCurrentState.requested_w == w && mCurrentState.requested_h == h)
         return false;
-    mCurrentState.w = w;
-    mCurrentState.h = h;
+    mCurrentState.requested_w = w;
+    mCurrentState.requested_h = h;
     requestTransaction();
     return true;
 }
@@ -204,13 +194,25 @@
     const Layer::State& front(drawingState());
     const Layer::State& temp(currentState());
 
-    if (temp.sequence != front.sequence) {
+    if ((front.requested_w != temp.requested_w) ||
+        (front.requested_h != temp.requested_h))  {
+        // resize the layer, set the physical size to the requested size
+        Layer::State& editTemp(currentState());
+        editTemp.w = temp.requested_w;
+        editTemp.h = temp.requested_h;
+    }
+
+    if ((front.w != temp.w) || (front.h != temp.h)) {
         // invalidate and recompute the visible regions if needed
-        flags |= eVisibleRegion;
+        flags |= Layer::eVisibleRegion;
         this->contentDirty = true;
     }
 
     if (temp.sequence != front.sequence) {
+        // invalidate and recompute the visible regions if needed
+        flags |= eVisibleRegion;
+        this->contentDirty = true;
+
         const bool linearFiltering = mUseLinearFiltering;
         mUseLinearFiltering = false;
         if (!(mFlags & DisplayHardware::SLOW_CONFIG)) {
@@ -223,7 +225,7 @@
     }
 
     // Commit the transaction
-    commitTransaction(flags & eRestartTransaction);
+    commitTransaction();
     return flags;
 }
 
diff --git a/libs/surfaceflinger/LayerBase.h b/libs/surfaceflinger/LayerBase.h
index 233737d..16ee542 100644
--- a/libs/surfaceflinger/LayerBase.h
+++ b/libs/surfaceflinger/LayerBase.h
@@ -88,6 +88,8 @@
             struct State {
                 uint32_t        w;
                 uint32_t        h;
+                uint32_t        requested_w;
+                uint32_t        requested_h;
                 uint32_t        z;
                 uint8_t         alpha;
                 uint8_t         flags;
@@ -107,7 +109,7 @@
             bool setTransparentRegionHint(const Region& opaque);
             bool setFlags(uint8_t flags, uint8_t mask);
             
-            void commitTransaction(bool skipSize);
+            void commitTransaction();
             bool requestTransaction();
             void forceVisibilityTransaction();
             
@@ -211,7 +213,6 @@
     
     enum { // flags for doTransaction()
         eVisibleRegion      = 0x00000002,
-        eRestartTransaction = 0x00000008
     };
 
 
diff --git a/libs/surfaceflinger/SurfaceFlinger.cpp b/libs/surfaceflinger/SurfaceFlinger.cpp
index 4ee176c..e468b23 100644
--- a/libs/surfaceflinger/SurfaceFlinger.cpp
+++ b/libs/surfaceflinger/SurfaceFlinger.cpp
@@ -594,12 +594,6 @@
             const uint32_t flags = layer->doTransaction(0);
             if (flags & Layer::eVisibleRegion)
                 mVisibleRegionsDirty = true;
-
-            if (flags & Layer::eRestartTransaction) {
-                // restart the transaction, but back-off a little
-                layer->setTransactionFlags(eTransactionNeeded);
-                setTransactionFlags(eTraversalNeeded, ms2ns(8));
-            }
         }
     }
 
diff --git a/opengl/tests/gl_basic/Android.mk b/opengl/tests/gl_basic/Android.mk
new file mode 100644
index 0000000..6b6341f
--- /dev/null
+++ b/opengl/tests/gl_basic/Android.mk
@@ -0,0 +1,17 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+	gl_basic.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+	libcutils \
+    libEGL \
+    libGLESv1_CM \
+    libui
+
+LOCAL_MODULE:= test-opengl-gl_basic
+
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_EXECUTABLE)
diff --git a/opengl/tests/gl_basic/gl_basic.cpp b/opengl/tests/gl_basic/gl_basic.cpp
new file mode 100644
index 0000000..7dc2378
--- /dev/null
+++ b/opengl/tests/gl_basic/gl_basic.cpp
@@ -0,0 +1,357 @@
+// Simple OpenGL ES 1.x application showing how to initialize and draw something.
+
+#include <EGL/egl.h>

+#include <GLES/gl.h>
+#include <GLES/glext.h>
+
+#include <ui/FramebufferNativeWindow.h>
+#include <ui/EGLUtils.h>
+
+#include <stdio.h>

+#include <stdlib.h>
+#include <math.h>
+
+using namespace android;
+

+EGLDisplay eglDisplay;

+EGLSurface eglSurface;

+EGLContext eglContext;

+GLuint texture;

+

+#define FIXED_ONE 0x10000
+#define ITERATIONS 50

+

+int init_gl_surface(void);

+void free_gl_surface(void);

+void init_scene(void);

+void render();

+void create_texture(void);
+int readTimer(void);

+
+static void gluLookAt(float eyeX, float eyeY, float eyeZ,
+        float centerX, float centerY, float centerZ, float upX, float upY,
+        float upZ)
+{
+    // See the OpenGL GLUT documentation for gluLookAt for a description
+    // of the algorithm. We implement it in a straightforward way:
+
+    float fx = centerX - eyeX;
+    float fy = centerY - eyeY;
+    float fz = centerZ - eyeZ;
+
+    // Normalize f
+    float rlf = 1.0f / sqrtf(fx*fx + fy*fy + fz*fz);
+    fx *= rlf;
+    fy *= rlf;
+    fz *= rlf;
+
+    // Normalize up
+    float rlup = 1.0f / sqrtf(upX*upX + upY*upY + upZ*upZ);
+    upX *= rlup;
+    upY *= rlup;
+    upZ *= rlup;
+
+    // compute s = f x up (x means "cross product")
+
+    float sx = fy * upZ - fz * upY;
+    float sy = fz * upX - fx * upZ;
+    float sz = fx * upY - fy * upX;
+
+    // compute u = s x f
+    float ux = sy * fz - sz * fy;
+    float uy = sz * fx - sx * fz;
+    float uz = sx * fy - sy * fx;
+
+    float m[16] ;
+    m[0] = sx;
+    m[1] = ux;
+    m[2] = -fx;
+    m[3] = 0.0f;
+
+    m[4] = sy;
+    m[5] = uy;
+    m[6] = -fy;
+    m[7] = 0.0f;
+
+    m[8] = sz;
+    m[9] = uz;
+    m[10] = -fz;
+    m[11] = 0.0f;
+
+    m[12] = 0.0f;
+    m[13] = 0.0f;
+    m[14] = 0.0f;
+    m[15] = 1.0f;
+
+    glMultMatrixf(m);
+    glTranslatef(-eyeX, -eyeY, -eyeZ);
+}
+
+
+void printEGLConfiguration(EGLDisplay dpy, EGLConfig config) {
+
+#define X(VAL) {VAL, #VAL}
+    struct {EGLint attribute; const char* name;} names[] = {
+    X(EGL_BUFFER_SIZE),
+    X(EGL_ALPHA_SIZE),
+    X(EGL_BLUE_SIZE),
+    X(EGL_GREEN_SIZE),
+    X(EGL_RED_SIZE),
+    X(EGL_DEPTH_SIZE),
+    X(EGL_STENCIL_SIZE),
+    X(EGL_CONFIG_CAVEAT),
+    X(EGL_CONFIG_ID),
+    X(EGL_LEVEL),
+    X(EGL_MAX_PBUFFER_HEIGHT),
+    X(EGL_MAX_PBUFFER_PIXELS),
+    X(EGL_MAX_PBUFFER_WIDTH),
+    X(EGL_NATIVE_RENDERABLE),
+    X(EGL_NATIVE_VISUAL_ID),
+    X(EGL_NATIVE_VISUAL_TYPE),
+    X(EGL_PRESERVED_RESOURCES),
+    X(EGL_SAMPLES),
+    X(EGL_SAMPLE_BUFFERS),
+    X(EGL_SURFACE_TYPE),
+    X(EGL_TRANSPARENT_TYPE),
+    X(EGL_TRANSPARENT_RED_VALUE),
+    X(EGL_TRANSPARENT_GREEN_VALUE),
+    X(EGL_TRANSPARENT_BLUE_VALUE),
+    X(EGL_BIND_TO_TEXTURE_RGB),
+    X(EGL_BIND_TO_TEXTURE_RGBA),
+    X(EGL_MIN_SWAP_INTERVAL),
+    X(EGL_MAX_SWAP_INTERVAL),
+    X(EGL_LUMINANCE_SIZE),
+    X(EGL_ALPHA_MASK_SIZE),
+    X(EGL_COLOR_BUFFER_TYPE),
+    X(EGL_RENDERABLE_TYPE),
+    X(EGL_CONFORMANT),
+   };
+#undef X
+
+    for (size_t j = 0; j < sizeof(names) / sizeof(names[0]); j++) {
+        EGLint value = -1;
+        EGLint returnVal = eglGetConfigAttrib(dpy, config, names[j].attribute, &value);
+        EGLint error = eglGetError();
+        if (returnVal && error == EGL_SUCCESS) {
+            printf(" %s: ", names[j].name);
+            printf("%d (0x%x)", value, value);
+        }
+    }
+    printf("\n");
+}
+
+static void checkEglError(const char* op, EGLBoolean returnVal = EGL_TRUE) {
+    if (returnVal != EGL_TRUE) {
+        fprintf(stderr, "%s() returned %d\n", op, returnVal);
+    }
+
+    for (EGLint error = eglGetError(); error != EGL_SUCCESS; error
+            = eglGetError()) {
+        fprintf(stderr, "after %s() eglError %s (0x%x)\n", op, EGLUtils::strerror(error),
+                error);
+    }
+}
+
+int printEGLConfigurations(EGLDisplay dpy) {
+    EGLint numConfig = 0;
+    EGLint returnVal = eglGetConfigs(dpy, NULL, 0, &numConfig);
+    checkEglError("eglGetConfigs", returnVal);
+    if (!returnVal) {
+        return false;
+    }
+
+    printf("Number of EGL configurations: %d\n", numConfig);
+
+    EGLConfig* configs = (EGLConfig*) malloc(sizeof(EGLConfig) * numConfig);
+    if (! configs) {
+        printf("Could not allocate configs.\n");
+        return false;
+    }
+
+    returnVal = eglGetConfigs(dpy, configs, numConfig, &numConfig);
+    checkEglError("eglGetConfigs", returnVal);
+    if (!returnVal) {
+        free(configs);
+        return false;
+    }
+
+    for(int i = 0; i < numConfig; i++) {
+        printf("Configuration %d\n", i);
+        printEGLConfiguration(dpy, configs[i]);
+    }
+
+    free(configs);
+    return true;
+}
+

+int main(int argc, char **argv)

+{

+    int q;
+    int start, end;

+
+    printf("Initializing EGL...\n");
+

+    if(!init_gl_surface())

+    {

+        printf("GL initialisation failed - exiting\n");

+        return 0;

+    }

+

+    init_scene();

+

+    create_texture();

+

+    printf("Running...\n");
+
+    while(true) {
+        render();
+    }

+

+    free_gl_surface();

+

+    return 0;

+}

+

+int init_gl_surface(void)

+{

+    EGLint numConfigs = 1;

+    EGLConfig myConfig = {0};

+    EGLint attrib[] =

+    {

+            EGL_SURFACE_TYPE, EGL_WINDOW_BIT,

+            EGL_NONE

+    };

+

+    if ( (eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY)) == EGL_NO_DISPLAY )

+    {

+        printf("eglGetDisplay failed\n");

+        return 0;

+    }
+

+    if ( eglInitialize(eglDisplay, NULL, NULL) != EGL_TRUE )

+    {

+        printf("eglInitialize failed\n");

+        return 0;

+    }
+
+    if (! printEGLConfigurations(eglDisplay)) {
+        printf("printEGLConfigurations failed.\n");
+        return 0;
+    }

+    EGLNativeWindowType window = android_createDisplaySurface();

+    EGLUtils::selectConfigForNativeWindow(eglDisplay, attrib, window, &myConfig);

+

+    if ( (eglSurface = eglCreateWindowSurface(eglDisplay, myConfig,
+            window, 0)) == EGL_NO_SURFACE )

+    {

+        printf("eglCreateWindowSurface failed\n");

+        return 0;

+    }

+

+    if ( (eglContext = eglCreateContext(eglDisplay, myConfig, 0, 0)) == EGL_NO_CONTEXT )

+    {

+        printf("eglCreateContext failed\n");

+        return 0;

+    }

+

+    if ( eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext) != EGL_TRUE )

+    {

+        printf("eglMakeCurrent failed\n");

+        return 0;

+    }

+

+    return 1;

+}

+

+void free_gl_surface(void)

+{

+    if (eglDisplay != EGL_NO_DISPLAY)

+    {

+        eglMakeCurrent( EGL_NO_DISPLAY, EGL_NO_SURFACE,

+                EGL_NO_SURFACE, EGL_NO_CONTEXT );

+        eglDestroyContext( eglDisplay, eglContext );

+        eglDestroySurface( eglDisplay, eglSurface );

+        eglTerminate( eglDisplay );

+        eglDisplay = EGL_NO_DISPLAY;

+    }

+}

+

+void init_scene(void)

+{

+    glDisable(GL_DITHER);
+    glEnable(GL_CULL_FACE);
+
+    float ratio = 320.0f / 480.0f;
+    glViewport(0, 0, 320, 480);
+
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    glFrustumf(-ratio, ratio, -1, 1, 1, 10);
+
+    glMatrixMode(GL_MODELVIEW);

+    glLoadIdentity();
+    gluLookAt(
+            0, 0, 3,  // eye
+            0, 0, 0,  // center
+            0, 1, 0); // up
+

+    glEnable(GL_TEXTURE_2D);

+    glEnableClientState(GL_VERTEX_ARRAY);

+    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+}

+

+void create_texture(void)

+{

+    const unsigned int on = 0xff0000ff;
+    const unsigned int off = 0xffffffff;
+    const unsigned int pixels[] =
+    {
+            on, off, on, off, on, off, on, off,
+            off, on, off, on, off, on, off, on,
+            on, off, on, off, on, off, on, off,
+            off, on, off, on, off, on, off, on,
+            on, off, on, off, on, off, on, off,
+            off, on, off, on, off, on, off, on,
+            on, off, on, off, on, off, on, off,
+            off, on, off, on, off, on, off, on,
+    };

+    glGenTextures(1, &texture);

+    glBindTexture(GL_TEXTURE_2D, texture);

+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);

+    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

+    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

+    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);

+}

+

+void render()

+{

+    int i, j;
+    int quads = 1;

+

+    const GLfloat vertices[] = {

+            -1,  -1,  0,

+             1,  -1,  0,

+             1,   1,  0,

+            -1,   1,  0

+    };

+

+    const GLfixed texCoords[] = {

+            0,            0,

+            FIXED_ONE,    0,

+            FIXED_ONE,    FIXED_ONE,

+            0,            FIXED_ONE

+    };

+

+    const GLushort indices[] = { 0, 1, 2,  0, 2, 3 };
+

+    glVertexPointer(3, GL_FLOAT, 0, vertices);

+    glTexCoordPointer(2, GL_FIXED, 0, texCoords);
+
+    glClearColor(1.0, 1.0, 1.0, 1.0);
+
+    int nelem = sizeof(indices)/sizeof(indices[0]);
+    glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
+    glDrawElements(GL_TRIANGLES, nelem, GL_UNSIGNED_SHORT, indices);
+    eglSwapBuffers(eglDisplay, eglSurface);

+}

+