Merge commit 'goog/master' into merge_master
diff --git a/include/private/opengles/gl_context.h b/include/private/opengles/gl_context.h
index 0c7ad46..641961f 100644
--- a/include/private/opengles/gl_context.h
+++ b/include/private/opengles/gl_context.h
@@ -26,6 +26,7 @@
 #endif
 
 #include <private/pixelflinger/ggl_context.h>
+#include <hardware/copybit.h>
 
 #include <GLES/gl.h>
 #include <GLES/glext.h>
@@ -39,7 +40,7 @@
 class EGLBufferObjectManager;
 
 namespace gl {
- 
+
 struct ogles_context_t;
 struct matrixx_t;
 struct transform_t;
@@ -96,7 +97,7 @@
 
 struct vertex_t {
     enum {
-        // these constant matter for our clipping 
+        // these constant matter for our clipping
         CLIP_L          = 0x0001,   // clipping flags
         CLIP_R          = 0x0002,
         CLIP_B          = 0x0004,
@@ -106,7 +107,7 @@
 
         EYE             = 0x0040,
         RESERVED        = 0x0080,
-        
+
         USER_CLIP_0     = 0x0100,   // user clipping flags
         USER_CLIP_1     = 0x0200,
         USER_CLIP_2     = 0x0400,
@@ -121,7 +122,7 @@
         USER_CLIP_ALL   = 0x3F00,
         CLIP_ALL        = 0x3F3F,
     };
-    
+
     // the fields below are arranged to minimize d-cache usage
     // we group together, by cache-line, the fields most likely to be used
 
@@ -130,7 +131,7 @@
     vec4_t          eye;
     };
     vec4_t          clip;
-    
+
     uint32_t        flags;
     size_t          index;  // cache tag, and vertex index
     GLfixed         fog;
@@ -142,7 +143,7 @@
     vec4_t          color;
     vec4_t          texture[GGL_TEXTURE_UNIT_COUNT];
     uint32_t        reserved1[4];
-    
+
     inline void clear() {
         flags = index = locked = mru = 0;
     }
@@ -199,7 +200,7 @@
     GLenum          indicesType;
     buffer_t const* array_buffer;
     buffer_t const* element_array_buffer;
-    
+
     void (*compileElements)(ogles_context_t*, vertex_t*, GLint, GLsizei);
     void (*compileElement)(ogles_context_t*, vertex_t*, GLint);
 
@@ -410,7 +411,7 @@
     matrixx_t       matrix;
     uint32_t        flags;
     uint32_t        ops;
-    
+
     union {
         struct {
             void (*point2)(transform_t const* t, vec4_t*, vec4_t const*);
@@ -509,17 +510,17 @@
     GLint       x;
     GLint       y;
     GLsizei     w;
-    GLsizei     h; 
+    GLsizei     h;
     struct {
         GLint       x;
         GLint       y;
-    } surfaceport;  
+    } surfaceport;
     struct {
         GLint       x;
         GLint       y;
         GLsizei     w;
-        GLsizei     h; 
-    } scissor;  
+        GLsizei     h;
+    } scissor;
 };
 
 // ----------------------------------------------------------------------------
@@ -594,6 +595,16 @@
     void (*renderTriangle)(GL, vertex_t*, vertex_t*, vertex_t*);
 };
 
+struct copybits_context_t {
+    // A handle to the blit engine, if it exists, else NULL.
+    copybit_device_t*       blitEngine;
+    int32_t                 minScale;
+    int32_t                 maxScale;
+    // File descriptor of current drawing surface, if it's suitable for use as
+    // a copybits destination, else -1.
+    int                     drawSurfaceFd;
+};
+
 struct ogles_context_t {
     context_t               rasterizer;
     array_machine_t         arrays         __attribute__((aligned(32)));
@@ -617,6 +628,14 @@
     uint32_t                transformTextures : 1;
     EGLSurfaceManager*      surfaceManager;
     EGLBufferObjectManager* bufferObjectManager;
+
+    // copybits is only used if LIBAGL_USE_GRALLOC_COPYBITS is
+    // defined, but it is always present because ogles_context_t is a public
+    // struct that is used by clients of libagl. We want the size and offsets
+    // to stay the same, whether or not LIBAGL_USE_GRALLOC_COPYBITS is defined.
+
+    copybits_context_t      copybits;
+
     GLenum                  error;
 
     static inline ogles_context_t* get() {
diff --git a/include/private/ui/RegionHelper.h b/include/private/ui/RegionHelper.h
new file mode 100644
index 0000000..6c847ff
--- /dev/null
+++ b/include/private/ui/RegionHelper.h
@@ -0,0 +1,279 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_UI_PRIVATE_REGION_HELPER_H
+#define ANDROID_UI_PRIVATE_REGION_HELPER_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+namespace android {
+// ----------------------------------------------------------------------------
+
+template<typename RECT>
+class region_operator
+{
+    typedef typename RECT::value_type TYPE;    
+    static const TYPE max_value = 0x7FFFFFF;
+
+public:
+    /* 
+     * Common boolean operations:
+     * value is computed as 0b101 op 0b110
+     *    other boolean operation are possible, simply compute
+     *    their corresponding value with the above formulae and use
+     *    it when instantiating a region_operator.
+     */
+    static const uint32_t LHS = 0x5;  // 0b101
+    static const uint32_t RHS = 0x6;  // 0b110
+    enum {
+        op_nand = LHS & ~RHS,
+        op_and  = LHS &  RHS,
+        op_or   = LHS |  RHS,
+        op_xor  = LHS ^  RHS
+    };
+
+    struct region {
+        RECT const* rects;
+        size_t count;
+        TYPE dx;
+        TYPE dy;
+        inline region(const region& rhs) 
+            : rects(rhs.rects), count(rhs.count), dx(rhs.dx), dy(rhs.dy) { }
+        inline region(RECT const* r, size_t c) 
+            : rects(r), count(c), dx(), dy() { }
+        inline region(RECT const* r, size_t c, TYPE dx, TYPE dy) 
+            : rects(r), count(c), dx(dx), dy(dy) { }
+    };
+
+    class region_rasterizer {
+        friend class region_operator;
+        virtual void operator()(const RECT& rect) = 0;
+    };
+    
+    inline region_operator(int op, const region& lhs, const region& rhs) 
+        : op_mask(op), spanner(lhs, rhs) 
+    {
+    }
+
+    void operator()(region_rasterizer& rasterizer) {
+        RECT current;
+        do {
+            SpannerInner spannerInner(spanner.lhs, spanner.rhs);
+            int inside = spanner.next(current.top, current.bottom);
+            spannerInner.prepare(inside);
+            do {
+                TYPE left, right;
+                int inside = spannerInner.next(current.left, current.right);
+                if ((op_mask >> inside) & 1) {
+                    if (current.left < current.right && 
+                            current.top < current.bottom) {
+                        rasterizer(current);
+                    }
+                }
+            } while(!spannerInner.isDone());            
+        } while(!spanner.isDone());
+    }
+
+private:    
+    uint32_t op_mask;
+
+    class SpannerBase
+    {
+    public:
+        enum {
+            lhs_before_rhs   = 0,
+            lhs_after_rhs    = 1,
+            lhs_coincide_rhs = 2
+        };
+
+    protected:
+        TYPE lhs_head;
+        TYPE lhs_tail;
+        TYPE rhs_head;
+        TYPE rhs_tail;
+
+        inline int next(TYPE& head, TYPE& tail,
+                bool& more_lhs, bool& more_rhs) 
+        {
+            int inside;
+            more_lhs = false;
+            more_rhs = false;
+            if (lhs_head < rhs_head) {
+                inside = lhs_before_rhs;
+                head = lhs_head;
+                if (lhs_tail <= rhs_head) {
+                    tail = lhs_tail;
+                    more_lhs = true;
+                } else {
+                    lhs_head = rhs_head;
+                    tail = rhs_head;
+                }
+            } else if (rhs_head < lhs_head) {
+                inside = lhs_after_rhs;
+                head = rhs_head;
+                if (rhs_tail <= lhs_head) {
+                    tail = rhs_tail;
+                    more_rhs = true;
+                } else {
+                    rhs_head = lhs_head;
+                    tail = lhs_head;
+                }
+            } else {
+                inside = lhs_coincide_rhs;
+                head = lhs_head;
+                if (lhs_tail <= rhs_tail) {
+                    tail = rhs_head = lhs_tail;
+                    more_lhs = true;
+                }
+                if (rhs_tail <= lhs_tail) {
+                    tail = lhs_head = rhs_tail;
+                    more_rhs = true;
+                }
+            }
+            return inside;
+        }
+    };
+
+    class Spanner : protected SpannerBase 
+    {
+        friend class region_operator;
+        region lhs;
+        region rhs;
+
+    public:
+        inline Spanner(const region& lhs, const region& rhs)
+            : lhs(lhs), rhs(rhs) 
+        {
+            SpannerBase::lhs_head = lhs.rects->top      + lhs.dy;
+            SpannerBase::lhs_tail = lhs.rects->bottom   + lhs.dy;
+            SpannerBase::rhs_head = rhs.rects->top      + rhs.dy;
+            SpannerBase::rhs_tail = rhs.rects->bottom   + rhs.dy;
+        }
+
+        inline bool isDone() const {
+            return !rhs.count && !lhs.count;
+        }
+
+        inline int next(TYPE& top, TYPE& bottom) 
+        {
+            bool more_lhs = false;
+            bool more_rhs = false;
+            int inside = SpannerBase::next(top, bottom, more_lhs, more_rhs);
+            if (more_lhs) {
+                advance(lhs, SpannerBase::lhs_head, SpannerBase::lhs_tail);
+            }
+            if (more_rhs) {
+                advance(rhs, SpannerBase::rhs_head, SpannerBase::rhs_tail);
+            }
+            return inside;
+        }
+
+    private:
+        static inline 
+        void advance(region& reg, TYPE& aTop, TYPE& aBottom) {
+            // got to next span
+            size_t count = reg.count;
+            RECT const * rects = reg.rects;
+            RECT const * const end = rects + count;
+            const int top = rects->top;
+            while (rects != end && rects->top == top) {
+                rects++;
+                count--;
+            }
+            if (rects != end) {
+                aTop    = rects->top    + reg.dy;
+                aBottom = rects->bottom + reg.dy;
+            } else {
+                aTop    = max_value;
+                aBottom = max_value;
+            }
+            reg.rects = rects;
+            reg.count = count;
+        }
+    };
+
+    class SpannerInner : protected SpannerBase 
+    {
+        region lhs;
+        region rhs;
+        
+    public:
+        inline SpannerInner(const region& lhs, const region& rhs)
+            : lhs(lhs), rhs(rhs) 
+        {
+        }
+
+        inline void prepare(int inside) {
+            SpannerBase::lhs_head = lhs.rects->left  + lhs.dx;
+            SpannerBase::lhs_tail = lhs.rects->right + lhs.dx;
+            SpannerBase::rhs_head = rhs.rects->left  + rhs.dx;
+            SpannerBase::rhs_tail = rhs.rects->right + rhs.dx;
+            if (inside == SpannerBase::lhs_before_rhs) {
+                SpannerBase::rhs_head = max_value;
+                SpannerBase::rhs_tail = max_value;
+            } else if (inside == SpannerBase::lhs_after_rhs) {
+                SpannerBase::lhs_head = max_value;
+                SpannerBase::lhs_tail = max_value;
+            } else {
+                // use both spans
+            }
+        }
+
+        inline bool isDone() const {
+            return SpannerBase::lhs_head == max_value && 
+                   SpannerBase::rhs_head == max_value;
+        }
+
+        inline int next(TYPE& left, TYPE& right) 
+        {
+            bool more_lhs = false;
+            bool more_rhs = false;
+            int inside = SpannerBase::next(left, right, more_lhs, more_rhs);
+            if (more_lhs) {
+                advance(lhs, SpannerBase::lhs_head, SpannerBase::lhs_tail);
+            }
+            if (more_rhs) {
+                advance(rhs, SpannerBase::rhs_head, SpannerBase::rhs_tail);
+            }
+            return inside;
+        }
+
+    private:
+        static inline 
+        void advance(region& reg, TYPE& left, TYPE& right) {
+            if (reg.rects && reg.count) {
+                const int cur_span_top = reg.rects->top;
+                reg.rects++;
+                reg.count--;
+                if (!reg.count || reg.rects->top != cur_span_top) {
+                    left  = max_value;
+                    right = max_value;
+                } else {
+                    left  = reg.rects->left  + reg.dx;
+                    right = reg.rects->right + reg.dx;
+                }
+            }
+        }
+    };
+
+    Spanner spanner;
+};
+
+// ----------------------------------------------------------------------------
+};
+
+#endif /* ANDROID_UI_PRIVATE_REGION_HELPER_H */
diff --git a/include/private/ui/SharedState.h b/include/private/ui/SharedState.h
index 546d0ad..646cc10 100644
--- a/include/private/ui/SharedState.h
+++ b/include/private/ui/SharedState.h
@@ -32,16 +32,12 @@
 
 struct surface_info_t { // 4 longs, 16 bytes
     enum {
-        eBufferDirty    = 0x01
+        eBufferDirty    = 0x01,
+        eNeedNewBuffer  = 0x02
     };
-    uint16_t    w;
-    uint16_t    h;
-    uint16_t    stride;
-    uint16_t    bpr;
-    uint16_t    reserved;
-    uint8_t     format;
+    uint8_t     reserved[11];
     uint8_t     flags;
-    ssize_t     bits_offset;
+    status_t    status;
 };
 
 // ---------------------------------------------------------------------------
@@ -110,8 +106,6 @@
         INSPECT  = 0x00000002
     };
 
-    per_client_cblk_t();
-
     // these functions are used by the clients
     status_t validate(size_t i) const;
     int32_t lock_layer(size_t i, uint32_t flags);
@@ -138,12 +132,9 @@
 
 struct surface_flinger_cblk_t   // 4KB max
 {
-    surface_flinger_cblk_t();
-    
     uint8_t         connected;
     uint8_t         reserved[3];
     uint32_t        pad[7];
- 
     display_cblk_t  displays[NUM_DISPLAY_MAX];
 };
 
diff --git a/include/private/ui/SurfaceBuffer.h b/include/private/ui/SurfaceBuffer.h
new file mode 100644
index 0000000..c45abeb
--- /dev/null
+++ b/include/private/ui/SurfaceBuffer.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_UI_PRIVATE_SURFACE_BUFFER_H
+#define ANDROID_UI_PRIVATE_SURFACE_BUFFER_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/RefBase.h>
+
+#include <private/ui/android_natives_priv.h>
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+class BufferMapper;
+class Rect;
+class Surface;
+class SurfaceBuffer;
+
+// ---------------------------------------------------------------------------
+
+class SurfaceBuffer 
+    : public EGLNativeBase<
+        android_native_buffer_t, 
+        SurfaceBuffer, 
+        LightRefBase<SurfaceBuffer> >
+{
+public:
+    status_t lock(uint32_t usage, void** vaddr);
+    status_t lock(uint32_t usage, const Rect& rect, void** vaddr);
+    status_t unlock();
+
+protected:
+            SurfaceBuffer();
+            SurfaceBuffer(const Parcel& reply);
+    virtual ~SurfaceBuffer();
+    bool mOwner;
+
+    inline const BufferMapper& getBufferMapper() const { return mBufferMapper; }
+    inline BufferMapper& getBufferMapper() { return mBufferMapper; }
+    
+private:
+    friend class Surface;
+    friend class BpSurface;
+    friend class BnSurface;
+    friend class LightRefBase<SurfaceBuffer>;    
+
+    SurfaceBuffer& operator = (const SurfaceBuffer& rhs);
+    const SurfaceBuffer& operator = (const SurfaceBuffer& rhs) const;
+
+    static status_t writeToParcel(Parcel* reply, 
+            android_native_buffer_t const* buffer);
+    
+    BufferMapper& mBufferMapper;
+};
+
+}; // namespace android
+
+#endif // ANDROID_UI_PRIVATE_SURFACE_BUFFER_H
+
diff --git a/include/private/ui/SurfaceFlingerSynchro.h b/include/private/ui/SurfaceFlingerSynchro.h
index ff91b61..7386d33 100644
--- a/include/private/ui/SurfaceFlingerSynchro.h
+++ b/include/private/ui/SurfaceFlingerSynchro.h
@@ -21,7 +21,6 @@
 #include <stdint.h>
 #include <sys/types.h>
 #include <utils/Errors.h>
-#include <utils/threads.h>
 #include <ui/ISurfaceComposer.h>
 
 namespace android {
@@ -31,7 +30,6 @@
 class SurfaceFlingerSynchro
 {
 public:
-
                 // client constructor
                 SurfaceFlingerSynchro(const sp<ISurfaceComposer>& flinger);
                 ~SurfaceFlingerSynchro();
@@ -40,34 +38,8 @@
     status_t    signal();
     
 private:
-    class Barrier {
-    public:
-        Barrier();
-        ~Barrier();
-        void open();
-        void close();
-        void waitAndClose();
-        status_t waitAndClose(nsecs_t timeout);
-    private:
-        enum { OPENED, CLOSED };
-        mutable     Mutex       lock;
-        mutable     Condition   cv;
-        volatile    int         state;
-    };
-
     friend class SurfaceFlinger;
-
-                // server constructor
-                SurfaceFlingerSynchro();
-                
-    void        open();
-    
-                // wait until there is some work to do
-    status_t    wait();
-    status_t    wait(nsecs_t timeout);
-    
     sp<ISurfaceComposer> mSurfaceComposer;
-    Barrier              mBarrier;
 };
 
 }; // namespace android
diff --git a/include/private/ui/android_natives_priv.h b/include/private/ui/android_natives_priv.h
new file mode 100644
index 0000000..ee843e9
--- /dev/null
+++ b/include/private/ui/android_natives_priv.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_ANDROID_NATIVES_PRIV_H
+#define ANDROID_ANDROID_NATIVES_PRIV_H
+
+#include <ui/egl/android_natives.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*****************************************************************************/
+
+struct android_native_buffer_t
+{
+#ifdef __cplusplus
+    android_native_buffer_t() { 
+        common.magic = ANDROID_NATIVE_BUFFER_MAGIC;
+        common.version = sizeof(android_native_buffer_t);
+        memset(common.reserved, 0, sizeof(common.reserved));
+    }
+#endif
+
+    struct android_native_base_t common;
+
+    int width;
+    int height;
+    int stride;
+    int format;
+    int usage;
+    
+    void* reserved[2];
+
+    buffer_handle_t handle;
+
+    void* reserved_proc[8];
+};
+
+
+/*****************************************************************************/
+
+#ifdef __cplusplus
+}
+#endif
+
+/*****************************************************************************/
+
+#endif /* ANDROID_ANDROID_NATIVES_PRIV_H */