Merge "Recreate EGLImage for previously used slots" into jb-dev
diff --git a/cmds/dumpstate/dumpstate.c b/cmds/dumpstate/dumpstate.c
index 880f81f..2bcda11 100644
--- a/cmds/dumpstate/dumpstate.c
+++ b/cmds/dumpstate/dumpstate.c
@@ -144,6 +144,7 @@
 
     dump_file("NETWORK DEV INFO", "/proc/net/dev");
     dump_file("QTAGUID NETWORK INTERFACES INFO", "/proc/net/xt_qtaguid/iface_stat_all");
+    dump_file("QTAGUID NETWORK INTERFACES INFO (xt)", "/proc/net/xt_qtaguid/iface_stat_fmt");
     dump_file("QTAGUID CTRL INFO", "/proc/net/xt_qtaguid/ctrl");
     dump_file("QTAGUID STATS INFO", "/proc/net/xt_qtaguid/stats");
 
@@ -176,8 +177,10 @@
     dump_file("ARP CACHE", "/proc/net/arp");
     run_command("IPTABLES", 10, SU_PATH, "root", "iptables", "-L", "-nvx", NULL);
     run_command("IP6TABLES", 10, SU_PATH, "root", "ip6tables", "-L", "-nvx", NULL);
-    run_command("IPTABLE NAT", 10, SU_PATH, "root", "iptables", "-t", "nat", "-L", "-n", NULL);
-    run_command("IPT6ABLE NAT", 10, SU_PATH, "root", "ip6tables", "-t", "nat", "-L", "-n", NULL);
+    run_command("IPTABLE NAT", 10, SU_PATH, "root", "iptables", "-t", "nat", "-L", "-nvx", NULL);
+    /* no ip6 nat */
+    run_command("IPTABLE RAW", 10, SU_PATH, "root", "iptables", "-t", "raw", "-L", "-nvx", NULL);
+    run_command("IP6TABLE RAW", 10, SU_PATH, "root", "ip6tables", "-t", "raw", "-L", "-nvx", NULL);
 
     run_command("WIFI NETWORKS", 20,
             SU_PATH, "root", "wpa_cli", "list_networks", NULL);
diff --git a/opengl/libs/GLES_trace/src/gltrace_eglapi.cpp b/opengl/libs/GLES_trace/src/gltrace_eglapi.cpp
index c442153..9698bf9 100644
--- a/opengl/libs/GLES_trace/src/gltrace_eglapi.cpp
+++ b/opengl/libs/GLES_trace/src/gltrace_eglapi.cpp
@@ -44,9 +44,14 @@
     GLTraceState *state = (GLTraceState *)arg;
     TCPStream *stream = state->getStream();
 
-    // Currently, there are very few user configurable settings.
-    // As a result, they can be encoded in a single integer.
-    int cmd;
+    // The control stream always receives an integer size of the
+    // command buffer, followed by the actual command buffer.
+    uint32_t cmdSize;
+
+    // Command Buffer
+    void *cmdBuf = NULL;
+    uint32_t cmdBufSize = 0;
+
     enum TraceSettingsMasks {
         READ_FB_ON_EGLSWAP_MASK = 1 << 0,
         READ_FB_ON_GLDRAW_MASK = 1 << 1,
@@ -54,12 +59,33 @@
     };
 
     while (true) {
-        int n = stream->receive(&cmd, 4);
-        if (n != 4) {
+        // read command size
+        if (stream->receive(&cmdSize, sizeof(uint32_t)) < 0) {
+            break;
+        }
+        cmdSize = ntohl(cmdSize);
+
+        // ensure command buffer is of required size
+        if (cmdBufSize < cmdSize) {
+            free(cmdBuf);
+            cmdBufSize = cmdSize;
+            cmdBuf = malloc(cmdSize);
+            if (cmdBuf == NULL)
+                break;
+        }
+
+        // receive the command
+        if (stream->receive(cmdBuf, cmdSize) < 0) {
             break;
         }
 
-        cmd = ntohl(cmd);
+        if (cmdSize != sizeof(uint32_t)) {
+            // Currently, we only support commands that are a single integer,
+            // so we skip all other commands
+            continue;
+        }
+
+        uint32_t cmd = ntohl(*(uint32_t*)cmdBuf);
 
         bool collectFbOnEglSwap = (cmd & READ_FB_ON_EGLSWAP_MASK) != 0;
         bool collectFbOnGlDraw = (cmd & READ_FB_ON_GLDRAW_MASK) != 0;
@@ -73,6 +99,9 @@
             collectFbOnEglSwap, collectFbOnGlDraw, collectTextureData);
     }
 
+    ALOGE("Stopping OpenGL Trace Command Receiver\n");
+
+    free(cmdBuf);
     return NULL;
 }
 
diff --git a/opengl/libs/GLES_trace/src/gltrace_transport.cpp b/opengl/libs/GLES_trace/src/gltrace_transport.cpp
index 157bd24..2996d32 100644
--- a/opengl/libs/GLES_trace/src/gltrace_transport.cpp
+++ b/opengl/libs/GLES_trace/src/gltrace_transport.cpp
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
+#include <errno.h>
 #include <stdlib.h>
 #include <unistd.h>
 
@@ -123,7 +124,18 @@
         return -1;
     }
 
-    return read(mSocket, data, len);
+    size_t totalRead = 0;
+    while (totalRead < len) {
+        int n = read(mSocket, (uint8_t*)data + totalRead, len - totalRead);
+        if (n < 0) {
+            ALOGE("Error receiving data from stream: %d", errno);
+            return -1;
+        }
+
+        totalRead += n;
+    }
+
+    return 0;
 }
 
 BufferedOutputStream::BufferedOutputStream(TCPStream *stream, size_t bufferSize) {
diff --git a/opengl/libs/GLES_trace/src/gltrace_transport.h b/opengl/libs/GLES_trace/src/gltrace_transport.h
index 3665035..9cf5b45 100644
--- a/opengl/libs/GLES_trace/src/gltrace_transport.h
+++ b/opengl/libs/GLES_trace/src/gltrace_transport.h
@@ -42,8 +42,11 @@
     /** Send @data of size @len to host. . Returns -1 on error, 0 on success. */
     int send(void *data, size_t len);
 
-    /** Receive data into @buf from the remote end. This is a blocking call. */
-    int receive(void *buf, size_t size);
+    /**
+     * Receive @len bytes of data into @buf from the remote end. This is a blocking call.
+     * Returns -1 on failure, 0 on success.
+     */
+    int receive(void *buf, size_t len);
 };
 
 /**
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 7eba89b..6ec4f49 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -232,27 +232,28 @@
     // ... then reduce that in the same proportions as the window crop reduces
     // the window size.
     const State& s(drawingState());
-    if (!s.crop.isEmpty()) {
+    if (!s.active.crop.isEmpty()) {
         // Transform the window crop to match the buffer coordinate system,
         // which means using the inverse of the current transform set on the
         // SurfaceTexture.
         uint32_t invTransform = mCurrentTransform;
-        int winWidth = s.w;
-        int winHeight = s.h;
+        int winWidth = s.active.w;
+        int winHeight = s.active.h;
         if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
             invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
                     NATIVE_WINDOW_TRANSFORM_FLIP_H;
-            winWidth = s.h;
-            winHeight = s.w;
+            winWidth = s.active.h;
+            winHeight = s.active.w;
         }
-        Rect winCrop = s.crop.transform(invTransform, s.w, s.h);
+        Rect winCrop = s.active.crop.transform(invTransform,
+                s.active.w, s.active.h);
 
         float xScale = float(crop.width()) / float(winWidth);
         float yScale = float(crop.height()) / float(winHeight);
-        crop.left += int(ceil(float(winCrop.left) * xScale));
-        crop.top += int(ceil(float(winCrop.top) * yScale));
-        crop.right -= int(ceil(float(winWidth - winCrop.right) * xScale));
-        crop.bottom -= int(ceil(float(winHeight - winCrop.bottom) * yScale));
+        crop.left += int(ceilf(float(winCrop.left) * xScale));
+        crop.top += int(ceilf(float(winCrop.top) * yScale));
+        crop.right -= int(ceilf(float(winWidth - winCrop.right) * xScale));
+        crop.bottom -= int(ceilf(float(winHeight - winCrop.bottom) * yScale));
     }
 
     return crop;
@@ -427,32 +428,44 @@
     const Layer::State& front(drawingState());
     const Layer::State& temp(currentState());
 
-    const bool sizeChanged = (front.requested_w != temp.requested_w) ||
-            (front.requested_h != temp.requested_h);
+    const bool sizeChanged = (front.requested.w != temp.requested.w) ||
+            (front.requested.h != temp.requested.h);
 
     if (sizeChanged) {
         // the size changed, we need to ask our client to request a new buffer
         ALOGD_IF(DEBUG_RESIZE,
                 "doTransaction: "
-                "resize (layer=%p), requested (%dx%d), drawing (%d,%d), "
+                "geometry (layer=%p), size: current (%dx%d), drawing (%dx%d), "
+                "crop: current (%d,%d,%d,%d [%dx%d]), drawing (%d,%d,%d,%d [%dx%d]), "
                 "scalingMode=%d",
                 this,
-                int(temp.requested_w), int(temp.requested_h),
-                int(front.requested_w), int(front.requested_h),
+                int(temp.requested.w), int(temp.requested.h),
+                int(front.requested.w), int(front.requested.h),
+                temp.requested.crop.left,
+                temp.requested.crop.top,
+                temp.requested.crop.right,
+                temp.requested.crop.bottom,
+                temp.requested.crop.getWidth(),
+                temp.requested.crop.getHeight(),
+                front.requested.crop.left,
+                front.requested.crop.top,
+                front.requested.crop.right,
+                front.requested.crop.bottom,
+                front.requested.crop.getWidth(),
+                front.requested.crop.getHeight(),
                 mCurrentScalingMode);
 
         if (!isFixedSize()) {
             // this will make sure LayerBase::doTransaction doesn't update
-            // the drawing state's size
+            // the drawing state's geometry
             Layer::State& editDraw(mDrawingState);
-            editDraw.requested_w = temp.requested_w;
-            editDraw.requested_h = temp.requested_h;
+            editDraw.requested = temp.requested;
         }
 
         // record the new size, form this point on, when the client request
         // a buffer, it'll get the new size.
-        mSurfaceTexture->setDefaultBufferSize(temp.requested_w,
-                temp.requested_h);
+        mSurfaceTexture->setDefaultBufferSize(
+                temp.requested.w, temp.requested.h);
     }
 
     return LayerBase::doTransaction(flags);
@@ -551,11 +564,9 @@
         const Layer::State& front(drawingState());
 
         // FIXME: mPostedDirtyRegion = dirty & bounds
-        mPostedDirtyRegion.set(front.w, front.h);
+        mPostedDirtyRegion.set(front.active.w, front.active.h);
 
-        if ((front.w != front.requested_w) ||
-            (front.h != front.requested_h))
-        {
+        if (front.active != front.requested) {
             // check that we received a buffer of the right size
             // (Take the buffer's orientation into account)
             if (mCurrentTransform & Transform::ROT_90) {
@@ -563,15 +574,14 @@
             }
 
             if (isFixedSize() ||
-                    (bufWidth == front.requested_w &&
-                    bufHeight == front.requested_h))
+                    (bufWidth == front.requested.w &&
+                    bufHeight == 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;
+                editDraw.active = editDraw.requested;
 
                 // We also need to update the current state so that we don't
                 // end-up doing too much work during the next transaction.
@@ -579,8 +589,7 @@
                 // because State::w and State::h are only accessed from
                 // this thread
                 Layer::State& editTemp(currentState());
-                editTemp.w = editDraw.w;
-                editTemp.h = editDraw.h;
+                editTemp.active = editDraw.active;
 
                 // recompute visible region
                 recomputeVisibleRegions = true;
@@ -592,7 +601,7 @@
                     "requested (%dx%d)",
                     this,
                     bufWidth, bufHeight, mCurrentTransform,
-                    front.requested_w, front.requested_h);
+                    front.requested.w, front.requested.h);
         }
     }
 }
diff --git a/services/surfaceflinger/LayerBase.cpp b/services/surfaceflinger/LayerBase.cpp
index 81031b1..7c6a28a 100644
--- a/services/surfaceflinger/LayerBase.cpp
+++ b/services/surfaceflinger/LayerBase.cpp
@@ -84,16 +84,15 @@
     if (flags & ISurfaceComposer::eNonPremultiplied)
         mPremultipliedAlpha = false;
 
-    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.active.w = w;
+    mCurrentState.active.h = h;
+    mCurrentState.active.crop.makeInvalid();
+    mCurrentState.z = 0;
+    mCurrentState.alpha = 0xFF;
+    mCurrentState.flags = layerFlags;
+    mCurrentState.sequence = 0;
     mCurrentState.transform.set(0, 0);
-    mCurrentState.crop.makeInvalid();
+    mCurrentState.requested = mCurrentState.active;
 
     // drawing state & current state are identical
     mDrawingState = mCurrentState;
@@ -136,10 +135,10 @@
     return true;
 }
 bool LayerBase::setSize(uint32_t w, uint32_t h) {
-    if (mCurrentState.requested_w == w && mCurrentState.requested_h == h)
+    if (mCurrentState.requested.w == w && mCurrentState.requested.h == h)
         return false;
-    mCurrentState.requested_w = w;
-    mCurrentState.requested_h = h;
+    mCurrentState.requested.w = w;
+    mCurrentState.requested.h = h;
     requestTransaction();
     return true;
 }
@@ -174,10 +173,10 @@
     return true;
 }
 bool LayerBase::setCrop(const Rect& crop) {
-    if (mCurrentState.crop == crop)
+    if (mCurrentState.requested.crop == crop)
         return false;
     mCurrentState.sequence++;
-    mCurrentState.crop = crop;
+    mCurrentState.requested.crop = crop;
     requestTransaction();
     return true;
 }
@@ -202,15 +201,13 @@
     const Layer::State& front(drawingState());
     const Layer::State& temp(currentState());
 
-    if ((front.requested_w != temp.requested_w) ||
-        (front.requested_h != temp.requested_h))  {
-        // resize the layer, set the physical size to the requested size
+    if (front.requested != temp.requested)  {
+        // geometry of the layer has changed, set the active geometry
+        // to the requested geometry.
         Layer::State& editTemp(currentState());
-        editTemp.w = temp.requested_w;
-        editTemp.h = temp.requested_h;
+        editTemp.active = temp.requested;
     }
-
-    if ((front.w != temp.w) || (front.h != temp.h)) {
+    if (front.active != temp.active) {
         // invalidate and recompute the visible regions if needed
         flags |= Layer::eVisibleRegion;
     }
@@ -238,9 +235,9 @@
     const bool transformed = tr.transformed();
     const DisplayHardware& hw(graphicPlane(0).displayHardware());
     const uint32_t hw_h = hw.getHeight();
-    const Rect& crop(s.crop);
+    const Rect& crop(s.active.crop);
 
-    Rect win(s.w, s.h);
+    Rect win(s.active.w, s.active.h);
     if (!crop.isEmpty()) {
         win.intersect(crop, &win);
     }
@@ -403,14 +400,14 @@
         GLfloat v;
     };
 
-    Rect crop(s.w, s.h);
-    if (!s.crop.isEmpty()) {
-        crop = s.crop;
+    Rect crop(s.active.w, s.active.h);
+    if (!s.active.crop.isEmpty()) {
+        crop = s.active.crop;
     }
-    GLfloat left = GLfloat(crop.left) / GLfloat(s.w);
-    GLfloat top = GLfloat(crop.top) / GLfloat(s.h);
-    GLfloat right = GLfloat(crop.right) / GLfloat(s.w);
-    GLfloat bottom = GLfloat(crop.bottom) / GLfloat(s.h);
+    GLfloat left = GLfloat(crop.left) / GLfloat(s.active.w);
+    GLfloat top = GLfloat(crop.top) / GLfloat(s.active.h);
+    GLfloat right = GLfloat(crop.right) / GLfloat(s.active.w);
+    GLfloat bottom = GLfloat(crop.bottom) / GLfloat(s.active.h);
 
     TexCoords texCoords[4];
     texCoords[0].u = left;
@@ -449,10 +446,12 @@
 
     snprintf(buffer, SIZE,
             "      "
-            "z=%9d, pos=(%g,%g), size=(%4d,%4d), "
+            "z=%9d, pos=(%g,%g), size=(%4d,%4d), crop=(%4d,%4d,%4d,%4d), "
             "isOpaque=%1d, needsDithering=%1d, invalidate=%1d, "
             "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n",
-            s.z, s.transform.tx(), s.transform.ty(), s.w, s.h,
+            s.z, s.transform.tx(), s.transform.ty(), s.active.w, s.active.h,
+            s.active.crop.left, s.active.crop.top,
+            s.active.crop.right, s.active.crop.bottom,
             isOpaque(), needsDithering(), contentDirty,
             s.alpha, s.flags,
             s.transform[0][0], s.transform[0][1],
diff --git a/services/surfaceflinger/LayerBase.h b/services/surfaceflinger/LayerBase.h
index 31f6dfd..9542424 100644
--- a/services/surfaceflinger/LayerBase.h
+++ b/services/surfaceflinger/LayerBase.h
@@ -65,20 +65,28 @@
             Region      coveredRegionScreen;
             int32_t     sequence;
             
+            struct Geometry {
+                uint32_t w;
+                uint32_t h;
+                Rect crop;
+                inline bool operator == (const Geometry& rhs) const {
+                    return (w==rhs.w && h==rhs.h && crop==rhs.crop);
+                }
+                inline bool operator != (const Geometry& rhs) const {
+                    return !operator == (rhs);
+                }
+            };
+
             struct State {
-                uint32_t        w;
-                uint32_t        h;
-                uint32_t        requested_w;
-                uint32_t        requested_h;
+                Geometry        active;
+                Geometry        requested;
                 uint32_t        z;
                 uint8_t         alpha;
                 uint8_t         flags;
                 uint8_t         reserved[2];
                 int32_t         sequence;   // changes when visible regions can change
-                uint32_t        tint;
                 Transform       transform;
                 Region          transparentRegion;
-                Rect            crop;
             };
 
     virtual void setName(const String8& name);