diff --git a/libs/surfaceflinger/Android.mk b/libs/surfaceflinger/Android.mk
new file mode 100644
index 0000000..7741456
--- /dev/null
+++ b/libs/surfaceflinger/Android.mk
@@ -0,0 +1,47 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+    clz.cpp.arm \
+    DisplayHardware/DisplayHardware.cpp \
+    DisplayHardware/DisplayHardwareBase.cpp \
+    GPUHardware/GPUHardware.cpp \
+    BootAnimation.cpp \
+    BlurFilter.cpp.arm \
+    CPUGauge.cpp \
+    Layer.cpp \
+    LayerBase.cpp \
+    LayerBuffer.cpp \
+    LayerBlur.cpp \
+    LayerBitmap.cpp \
+    LayerDim.cpp \
+    LayerScreenshot.cpp \
+    RFBServer.cpp \
+    SurfaceFlinger.cpp \
+    Tokenizer.cpp \
+    Transform.cpp \
+    VRamHeap.cpp
+
+
+# need "-lrt" on Linux simulator to pick up clock_gettime
+ifeq ($(TARGET_SIMULATOR),true)
+	ifeq ($(HOST_OS),linux)
+		LOCAL_LDLIBS += -lrt
+	endif
+endif
+
+LOCAL_SHARED_LIBRARIES := \
+	libutils \
+	libcutils \
+	libui \
+	libcorecg \
+	libsgl \
+	libpixelflinger \
+	libGLES_CM
+
+LOCAL_C_INCLUDES := \
+	$(call include-path-for, corecg graphics)
+
+LOCAL_MODULE:= libsurfaceflinger
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/libs/surfaceflinger/Barrier.h b/libs/surfaceflinger/Barrier.h
new file mode 100644
index 0000000..e2bcf6a
--- /dev/null
+++ b/libs/surfaceflinger/Barrier.h
@@ -0,0 +1,59 @@
+/*
+ * 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_BARRIER_H
+#define ANDROID_BARRIER_H
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <utils/threads.h>
+
+namespace android {
+
+class Barrier
+{
+public:
+    inline Barrier() : state(CLOSED) { }
+    inline ~Barrier() { }
+    void open() {
+        // gcc memory barrier, this makes sure all memory writes
+        // have been issued by gcc. On an SMP system we'd need a real
+        // h/w barrier.
+        asm volatile ("":::"memory");
+        Mutex::Autolock _l(lock);
+        state = OPENED;
+        cv.broadcast();
+    }
+    void close() {
+        Mutex::Autolock _l(lock);
+        state = CLOSED;
+    }
+    void wait() const {
+        Mutex::Autolock _l(lock);
+        while (state == CLOSED) {
+            cv.wait(lock);
+        }
+    }
+private:
+    enum { OPENED, CLOSED };
+    mutable     Mutex       lock;
+    mutable     Condition   cv;
+    volatile    int         state;
+};
+
+}; // namespace android
+
+#endif // ANDROID_BARRIER_H
diff --git a/libs/surfaceflinger/BlurFilter.cpp b/libs/surfaceflinger/BlurFilter.cpp
new file mode 100644
index 0000000..5dc0ba0
--- /dev/null
+++ b/libs/surfaceflinger/BlurFilter.cpp
@@ -0,0 +1,326 @@
+/* 
+**
+** Copyright 2006, 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.
+*/
+
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+#include <utils/Errors.h>
+
+#include <pixelflinger/pixelflinger.h>
+
+#include "clz.h"
+
+#define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
+#define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))
+
+namespace android {
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+inline uint32_t BLUR_RGBA_TO_HOST(uint32_t v) {
+    return v;
+}
+inline uint32_t BLUR_HOST_TO_RGBA(uint32_t v) {
+    return v;
+}
+#else
+inline uint32_t BLUR_RGBA_TO_HOST(uint32_t v) {
+    return (v<<24) | (v>>24) | ((v<<8)&0xff0000) | ((v>>8)&0xff00);
+}
+inline uint32_t BLUR_HOST_TO_RGBA(uint32_t v) {
+    return (v<<24) | (v>>24) | ((v<<8)&0xff0000) | ((v>>8)&0xff00);
+}
+#endif
+
+const int BLUR_DITHER_BITS = 6;  // dither weights stored on 6 bits
+const int BLUR_DITHER_ORDER_SHIFT= 3;
+const int BLUR_DITHER_ORDER      = (1<<BLUR_DITHER_ORDER_SHIFT);
+const int BLUR_DITHER_SIZE       = BLUR_DITHER_ORDER * BLUR_DITHER_ORDER;
+const int BLUR_DITHER_MASK       = BLUR_DITHER_ORDER-1;
+
+static const uint8_t gDitherMatrix[BLUR_DITHER_SIZE] = {
+     0, 32,  8, 40,  2, 34, 10, 42,
+    48, 16, 56, 24, 50, 18, 58, 26,
+    12, 44,  4, 36, 14, 46,  6, 38,
+    60, 28, 52, 20, 62, 30, 54, 22,
+     3, 35, 11, 43,  1, 33,  9, 41,
+    51, 19, 59, 27, 49, 17, 57, 25,
+    15, 47,  7, 39, 13, 45,  5, 37,
+    63, 31, 55, 23, 61, 29, 53, 21
+};
+
+
+template <int FACTOR = 0>
+struct BlurColor565
+{
+    typedef uint16_t type;
+    int r, g, b;    
+    inline BlurColor565() { }
+    inline BlurColor565(uint16_t v) {
+        r = v >> 11;
+        g = (v >> 5) & 0x3E;
+        b = v & 0x1F;
+    }
+    inline void clear() { r=g=b=0; }
+    inline uint16_t to(int shift, int last, int dither) const {
+        int R = r;
+        int G = g;
+        int B = b;
+        if  (UNLIKELY(last)) {
+            if (FACTOR>0) {
+                int L = (R+G+B)>>1;
+                R += (((L>>1) - R) * FACTOR) >> 8;
+                G += (((L   ) - G) * FACTOR) >> 8;
+                B += (((L>>1) - B) * FACTOR) >> 8;
+            }
+            R += (dither << shift) >> BLUR_DITHER_BITS;
+            G += (dither << shift) >> BLUR_DITHER_BITS;
+            B += (dither << shift) >> BLUR_DITHER_BITS;
+        }
+        R >>= shift;
+        G >>= shift;
+        B >>= shift;
+        return (R<<11) | (G<<5) | B;
+    }    
+    inline BlurColor565& operator += (const BlurColor565& rhs) {
+        r += rhs.r;
+        g += rhs.g;
+        b += rhs.b;
+        return *this;
+    }
+    inline BlurColor565& operator -= (const BlurColor565& rhs) {
+        r -= rhs.r;
+        g -= rhs.g;
+        b -= rhs.b;
+        return *this;
+    }
+};
+
+struct BlurGray565
+{
+    typedef uint16_t type;
+    int l;    
+    inline BlurGray565() { }
+    inline BlurGray565(uint16_t v) {
+        int r = v >> 11;
+        int g = (v >> 5) & 0x3F;
+        int b = v & 0x1F;
+        l = (r + g + b + 1)>>1;
+    }
+    inline void clear() { l=0; }
+    inline uint16_t to(int shift, int last, int dither) const {
+        int L = l;
+        if  (UNLIKELY(last)) {
+            L += (dither << shift) >> BLUR_DITHER_BITS;
+        }
+        L >>= shift;
+        return ((L>>1)<<11) | (L<<5) | (L>>1);
+    }
+    inline BlurGray565& operator += (const BlurGray565& rhs) {
+        l += rhs.l;
+        return *this;
+    }
+    inline BlurGray565& operator -= (const BlurGray565& rhs) {
+        l -= rhs.l;
+        return *this;
+    }
+};
+
+struct BlurGray8888
+{
+    typedef uint32_t type;
+    int l, a;    
+    inline BlurGray8888() { }
+    inline BlurGray8888(uint32_t v) {
+        v = BLUR_RGBA_TO_HOST(v);
+        int r = v & 0xFF;
+        int g = (v >>  8) & 0xFF;
+        int b = (v >> 16) & 0xFF;
+        a = v >> 24;
+        l = r + g + g + b;
+    }    
+    inline void clear() { l=a=0; }
+    inline uint32_t to(int shift, int last, int dither) const {
+        int L = l;
+        int A = a;
+        if  (UNLIKELY(last)) {
+            L += (dither << (shift+2)) >> BLUR_DITHER_BITS;
+            A += (dither << shift) >> BLUR_DITHER_BITS;
+        }
+        L >>= (shift+2);
+        A >>= shift;
+        return BLUR_HOST_TO_RGBA((A<<24) | (L<<16) | (L<<8) | L);
+    }
+    inline BlurGray8888& operator += (const BlurGray8888& rhs) {
+        l += rhs.l;
+        a += rhs.a;
+        return *this;
+    }
+    inline BlurGray8888& operator -= (const BlurGray8888& rhs) {
+        l -= rhs.l;
+        a -= rhs.a;
+        return *this;
+    }
+};
+
+
+template<typename PIXEL>
+static status_t blurFilter(
+        GGLSurface const* dst,
+        GGLSurface const* src,
+        int kernelSizeUser,
+        int repeat)
+{
+    typedef typename PIXEL::type TYPE;
+
+    const int shift             = 31 - clz(kernelSizeUser);
+    const int areaShift         = shift*2;
+    const int kernelSize        = 1<<shift;
+    const int kernelHalfSize    = kernelSize/2;
+    const int mask              = kernelSize-1;
+    const int w                 = src->width;
+    const int h                 = src->height;
+    const uint8_t* ditherMatrix = gDitherMatrix;
+
+    // we need a temporary buffer to store one line of blurred columns
+    // as well as kernelSize lines of source pixels organized as a ring buffer.
+    void* const temporary_buffer = malloc(
+            (w + kernelSize) * sizeof(PIXEL) +
+            (src->stride * kernelSize) * sizeof(TYPE));
+    if (!temporary_buffer)
+        return NO_MEMORY;
+
+    PIXEL* const sums = (PIXEL*)temporary_buffer;
+    TYPE* const scratch = (TYPE*)(sums + w + kernelSize);
+
+    // Apply the blur 'repeat' times, this is used to approximate
+    // gaussian blurs. 3 times gives good results.
+    for (int k=0 ; k<repeat ; k++) {
+
+        // Clear the columns sums for this round
+        memset(sums, 0, (w + kernelSize) * sizeof(PIXEL));
+        TYPE* head;
+        TYPE pixel;
+        PIXEL current;
+
+        // Since we're going to override the source data we need
+        // to copy it in a temporary buffer. Only kernelSize lines are
+        // required. But since we start in the center of the kernel,
+        // we only copy half of the data, and fill the rest with zeros
+        // (assuming black/transparent pixels).
+        memcpy( scratch + src->stride*kernelHalfSize,
+                src->data,
+                src->stride*kernelHalfSize*sizeof(TYPE));
+
+        // sum half of each column, because we assume the first half is
+        // zeros (black/transparent).
+        for (int y=0 ; y<kernelHalfSize ; y++) {
+            head = (TYPE*)src->data + y*src->stride;
+            for (int x=0 ; x<w ; x++)
+                sums[x] += PIXEL( *head++ );
+        }
+
+        for (int y=0 ; y<h ; y++) {
+            TYPE* fb = (TYPE*)dst->data + y*dst->stride;
+
+            // compute the dither matrix line
+            uint8_t const * ditherY = ditherMatrix
+                    + (y & BLUR_DITHER_MASK)*BLUR_DITHER_ORDER;
+
+            // Horizontal blur pass on the columns sums
+            int count, dither, x=0;
+            PIXEL const * out= sums;
+            PIXEL const * in = sums;
+            current.clear();
+
+            count = kernelHalfSize;
+            do {
+                current += *in;
+                in++;
+            } while (--count);
+            
+            count = kernelHalfSize;
+            do {
+                current += *in;
+                dither = *(ditherY + ((x++)&BLUR_DITHER_MASK));
+                *fb++ = current.to(areaShift, k==repeat-1, dither);
+                in++;
+            } while (--count);
+
+            count = w-kernelSize;
+            do {
+                current += *in;
+                current -= *out;
+                dither = *(ditherY + ((x++)&BLUR_DITHER_MASK));
+                *fb++ = current.to(areaShift, k==repeat-1, dither);
+                in++, out++;
+            } while (--count);
+
+            count = kernelHalfSize;
+            do {
+                current -= *out;
+                dither = *(ditherY + ((x++)&BLUR_DITHER_MASK));
+                *fb++ = current.to(areaShift, k==repeat-1, dither);
+                out++;
+            } while (--count);
+
+            // vertical blur pass, subtract the oldest line from each columns
+            // and add a new line. Subtract or add zeros at the top
+            // and bottom edges.
+            TYPE* const tail = scratch + (y & mask) * src->stride;
+            if (y >= kernelHalfSize) {
+                for (int x=0 ; x<w ; x++)
+                    sums[x] -= PIXEL( tail[x] );
+            }
+            if (y < h-kernelSize) {
+                memcpy( tail,
+                        (TYPE*)src->data + (y+kernelHalfSize)*src->stride,
+                        src->stride*sizeof(TYPE));
+                for (int x=0 ; x<w ; x++)
+                    sums[x] += PIXEL( tail[x] );
+            }
+        }
+
+        // The subsequent passes are always done in-place.
+        src = dst;
+    }
+    
+    free(temporary_buffer);
+
+    return NO_ERROR;
+}
+
+template status_t blurFilter< BlurColor565<0x80> >(
+        GGLSurface const* dst,
+        GGLSurface const* src,
+        int kernelSizeUser,
+        int repeat);
+
+status_t blurFilter(
+        GGLSurface const* image,
+        int kernelSizeUser,
+        int repeat)
+{
+    return blurFilter< BlurColor565<0x80> >(image, image, kernelSizeUser, repeat);
+}
+
+} // namespace android
+
+//err = blur< BlurColor565<0x80> >(dst, src, kernelSizeUser, repeat);
+//err = blur<BlurGray565>(dst, src, kernelSizeUser, repeat);
+//err = blur<BlurGray8888>(dst, src, kernelSizeUser, repeat);
diff --git a/libs/surfaceflinger/BlurFilter.h b/libs/surfaceflinger/BlurFilter.h
new file mode 100644
index 0000000..294db43
--- /dev/null
+++ b/libs/surfaceflinger/BlurFilter.h
@@ -0,0 +1,35 @@
+/* 
+**
+** Copyright 2006, 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_BLUR_FILTER_H
+#define ANDROID_BLUR_FILTER_H
+
+#include <stdint.h>
+#include <utils/Errors.h>
+
+#include <pixelflinger/pixelflinger.h>
+
+namespace android {
+
+status_t blurFilter(
+        GGLSurface const* image,
+        int kernelSizeUser,
+        int repeat);
+
+} // namespace android
+
+#endif // ANDROID_BLUR_FILTER_H
diff --git a/libs/surfaceflinger/BootAnimation.cpp b/libs/surfaceflinger/BootAnimation.cpp
new file mode 100644
index 0000000..e9e34c3
--- /dev/null
+++ b/libs/surfaceflinger/BootAnimation.cpp
@@ -0,0 +1,424 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "BootAnimation"
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <math.h>
+#include <fcntl.h>
+#include <utils/misc.h>
+
+#include <utils/threads.h>
+#include <utils/Atomic.h>
+#include <utils/Errors.h>
+#include <utils/Log.h>
+#include <utils/AssetManager.h>
+
+#include <ui/PixelFormat.h>
+#include <ui/Rect.h>
+#include <ui/Region.h>
+#include <ui/DisplayInfo.h>
+#include <ui/ISurfaceComposer.h>
+#include <ui/ISurfaceFlingerClient.h>
+#include <ui/EGLNativeWindowSurface.h>
+
+#include <graphics/SkBitmap.h>
+#include <graphics/SkImageDecoder.h>
+
+#include <GLES/egl.h>
+
+#include "BootAnimation.h"
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+BootAnimation::BootAnimation(const sp<ISurfaceComposer>& composer)
+:   Thread(false)
+{
+    mSession = SurfaceComposerClient::clientForConnection(
+            composer->createConnection()->asBinder());
+}
+
+BootAnimation::~BootAnimation()
+{
+}
+
+void BootAnimation::onFirstRef()
+{
+    run("BootAnimation", PRIORITY_DISPLAY);
+}
+
+const sp<SurfaceComposerClient>& BootAnimation::session() const 
+{
+    return mSession;
+}
+
+status_t BootAnimation::initTexture(
+        Texture* texture, AssetManager& assets, const char* name)
+{
+    Asset* asset = assets.open(name, Asset::ACCESS_BUFFER);
+    if (!asset) return NO_INIT;
+    SkBitmap bitmap;
+    SkImageDecoder::DecodeMemory(asset->getBuffer(false), asset->getLength(),
+            &bitmap, SkBitmap::kNo_Config, SkImageDecoder::kDecodePixels_Mode);
+    asset->close();
+    delete asset;
+
+    // ensure we can call getPixels(). No need to call unlock, since the
+    // bitmap will go out of scope when we return from this method.
+    bitmap.lockPixels();
+
+    const int w = bitmap.width();
+    const int h = bitmap.height();    
+    const void* p = bitmap.getPixels();
+    
+    GLint crop[4] = { 0, h, w, -h };
+    texture->w = w;
+    texture->h = h;
+
+    glGenTextures(1, &texture->name);
+    glBindTexture(GL_TEXTURE_2D, texture->name);
+    
+    switch(bitmap.getConfig()) {
+        case SkBitmap::kA8_Config:
+            glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, w, h, 0,
+                    GL_ALPHA, GL_UNSIGNED_BYTE, p);
+            break;
+        case SkBitmap::kARGB_4444_Config:
+            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0,
+                    GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, p);
+            break;
+        case SkBitmap::kARGB_8888_Config:
+            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0,
+                    GL_RGBA, GL_UNSIGNED_BYTE, p);
+            break;
+        case SkBitmap::kRGB_565_Config:
+            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0,
+                    GL_RGB, GL_UNSIGNED_SHORT_5_6_5, p);
+            break;
+        default:
+            break;
+    }
+
+    glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, crop);
+    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+    return NO_ERROR;
+}
+
+status_t BootAnimation::readyToRun()
+{
+    mAssets.addDefaultAssets();
+
+    DisplayInfo dinfo;
+    status_t status = session()->getDisplayInfo(0, &dinfo);
+    if (status)
+        return -1;
+
+    // create the native surface
+    sp<Surface> s = session()->createSurface(getpid(), 0, 
+            dinfo.w, dinfo.h, PIXEL_FORMAT_RGB_565);
+    session()->openTransaction();
+    s->setLayer(0x40000000);
+    session()->closeTransaction();
+
+    // initialize opengl and egl
+    const EGLint attribs[] = {
+            EGL_RED_SIZE,       5,
+            EGL_GREEN_SIZE,     6,
+            EGL_BLUE_SIZE,      5,
+            EGL_DEPTH_SIZE,     0,
+            EGL_NONE
+    };
+    EGLint w, h, dummy;
+    EGLint numConfigs;
+    EGLConfig config;
+    EGLSurface surface;
+    EGLContext context;
+    EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+    eglInitialize(display, NULL, NULL);
+    eglChooseConfig(display, attribs, &config, 1, &numConfigs);
+
+    surface = eglCreateWindowSurface(
+            display, config, new EGLNativeWindowSurface(s), NULL);
+    
+    context = eglCreateContext(display, config, NULL, NULL);
+    eglQuerySurface(display, surface, EGL_WIDTH, &w);
+    eglQuerySurface(display, surface, EGL_HEIGHT, &h);
+    eglMakeCurrent(display, surface, surface, context);
+    mDisplay = display;
+    mContext = context;
+    mSurface = surface;
+    mWidth = w;
+    mHeight= h;
+    mFlingerSurface = s;
+
+    // initialize GL
+    glShadeModel(GL_FLAT);
+    glEnable(GL_DITHER);
+    glEnable(GL_TEXTURE_2D);
+    glEnable(GL_SCISSOR_TEST);
+    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+
+    return NO_ERROR;
+}
+
+void BootAnimation::requestExit()
+{
+    mBarrier.open();
+    Thread::requestExit();
+}
+
+bool BootAnimation::threadLoop()
+{
+    bool r = android();
+    eglMakeCurrent(mDisplay, 0, 0, 0);
+    eglDestroyContext(mDisplay, mContext);    
+    eglDestroySurface(mDisplay, mSurface);
+    eglTerminate(mDisplay);
+    return r;
+}
+
+
+bool BootAnimation::android()
+{
+    initTexture(&mAndroid[0], mAssets, "images/android_320x480.png");
+    initTexture(&mAndroid[1], mAssets, "images/boot_robot.png");
+    initTexture(&mAndroid[2], mAssets, "images/boot_robot_glow.png");
+
+    // erase screen
+    glDisable(GL_SCISSOR_TEST);
+    glBindTexture(GL_TEXTURE_2D, mAndroid[0].name);
+
+    // clear screen
+    glClear(GL_COLOR_BUFFER_BIT);
+    eglSwapBuffers(mDisplay, mSurface);
+
+    // wait ~1s
+    usleep(800000);
+
+    // fade in
+    glEnable(GL_BLEND);
+    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+    const int steps = 8;
+    for (int i=1 ; i<steps ; i++) {
+        float fade = i / float(steps);
+        glColor4f(1, 1, 1, fade*fade);
+        glClear(GL_COLOR_BUFFER_BIT);
+        glDrawTexiOES(0, 0, 0, mAndroid[0].w, mAndroid[0].h);
+        eglSwapBuffers(mDisplay, mSurface);
+    }
+
+    // draw last frame
+    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+    glDisable(GL_BLEND);
+    glDrawTexiOES(0, 0, 0, mAndroid[0].w, mAndroid[0].h);
+    eglSwapBuffers(mDisplay, mSurface);
+    
+    
+    // update rect for the robot
+    const int x = mWidth - mAndroid[1].w - 33;
+    const int y = (mHeight - mAndroid[1].h)/2 - 1;
+    const Rect updateRect(x, y, x+mAndroid[1].w, y+mAndroid[1].h);
+
+    // draw and update only what we need
+    eglSwapRectangleANDROID(mDisplay, mSurface,
+            updateRect.left, updateRect.top, 
+            updateRect.width(), updateRect.height());
+
+    glEnable(GL_SCISSOR_TEST);
+    glScissor(updateRect.left, mHeight-updateRect.bottom,
+            updateRect.width(), updateRect.height()); 
+
+    const nsecs_t startTime = systemTime();
+    do
+    {
+        // glow speed and shape
+        nsecs_t time = systemTime() - startTime;
+        float t = ((4.0f/(360.0f*us2ns(16667))) * time);
+        t = t - floorf(t);
+        const float fade = 0.5f + 0.5f*sinf(t * 2*M_PI);
+
+        // fade the glow in and out
+        glDisable(GL_BLEND);
+        glBindTexture(GL_TEXTURE_2D, mAndroid[2].name);
+        glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+        glColor4f(fade, fade, fade, fade);
+        glDrawTexiOES(updateRect.left, mHeight-updateRect.bottom, 0,
+                updateRect.width(), updateRect.height());
+
+        // draw the robot
+        glEnable(GL_BLEND);
+        glBindTexture(GL_TEXTURE_2D, mAndroid[1].name);
+        glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+        glDrawTexiOES(updateRect.left, mHeight-updateRect.bottom, 0,
+                updateRect.width(), updateRect.height());
+
+        // make sure sleep a lot to not take too much CPU away from 
+        // the boot process. With this "glow" animation there is no
+        // visible difference. 
+        usleep(16667*4);
+
+        eglSwapBuffers(mDisplay, mSurface);
+    } while (!exitPending());
+    
+    
+    glDeleteTextures(1, &mAndroid[0].name);
+    glDeleteTextures(1, &mAndroid[1].name);
+    glDeleteTextures(1, &mAndroid[2].name);
+    return false;
+}
+
+
+bool BootAnimation::cylon()
+{
+    // initialize the textures...
+    initTexture(&mLeftTrail,  mAssets, "images/cylon_left.png");
+    initTexture(&mRightTrail, mAssets, "images/cylon_right.png");
+    initTexture(&mBrightSpot, mAssets, "images/cylon_dot.png");
+
+    int w = mWidth;
+    int h = mHeight;
+
+    const Point c(w/2 , h/2);
+    const GLint amplitude = 60;
+    const int scx = c.x - amplitude - mBrightSpot.w/2;
+    const int scy = c.y - mBrightSpot.h/2;
+    const int scw = amplitude*2 + mBrightSpot.w;
+    const int sch = mBrightSpot.h;
+    const Rect updateRect(scx, h-scy-sch, scx+scw, h-scy);
+
+    // erase screen
+    glDisable(GL_SCISSOR_TEST);
+    glClear(GL_COLOR_BUFFER_BIT);
+
+    eglSwapBuffers(mDisplay, mSurface);
+
+    glClear(GL_COLOR_BUFFER_BIT);
+
+    eglSwapRectangleANDROID(mDisplay, mSurface,
+            updateRect.left, updateRect.top, 
+            updateRect.width(), updateRect.height());
+
+    glEnable(GL_SCISSOR_TEST);
+    glEnable(GL_BLEND);
+    glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+
+
+    // clear the screen to white
+    Point p;
+    float t = 0;
+    float alpha = 1.0f;
+    const nsecs_t startTime = systemTime();
+    nsecs_t fadeTime = 0;
+    
+    do
+    {
+        // Set scissor in interesting area
+        glScissor(scx, scy, scw, sch); 
+
+        // erase screen
+        glClear(GL_COLOR_BUFFER_BIT);
+
+
+        // compute wave
+        const float a = (t * 2*M_PI) - M_PI/2;
+        const float sn = sinf(a);
+        const float cs = cosf(a);
+        GLint x = GLint(amplitude * sn);
+        float derivative = cs;
+
+        glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+
+        if (derivative > 0) {
+            // vanishing trail...
+            p.x = (-amplitude + c.x) - mBrightSpot.w/2;
+            p.y = c.y-mLeftTrail.h/2;
+            float fade = 2.0f*(0.5f-t);
+            //fade *= fade;
+            glColor4f(fade, fade, fade, fade);
+            glBindTexture(GL_TEXTURE_2D, mLeftTrail.name);
+            glDrawTexiOES(p.x, p.y, 0, mLeftTrail.w, mLeftTrail.h);
+
+            // trail...
+            p.x = (x + c.x) - (mRightTrail.w + mBrightSpot.w/2) + 16;
+            p.y = c.y-mRightTrail.h/2;
+            fade = t<0.25f ? t*4.0f : 1.0f;
+            fade *= fade;
+            glColor4f(fade, fade, fade, fade);
+            glBindTexture(GL_TEXTURE_2D, mRightTrail.name);
+            glDrawTexiOES(p.x, p.y, 0, mRightTrail.w, mRightTrail.h);
+        } else { 
+            // vanishing trail..
+            p.x = (amplitude + c.x) - (mRightTrail.w + mBrightSpot.w/2) + 16;
+            p.y = c.y-mRightTrail.h/2;
+            float fade = 2.0f*(0.5f-(t-0.5f));
+            //fade *= fade;
+            glColor4f(fade, fade, fade, fade);
+            glBindTexture(GL_TEXTURE_2D, mRightTrail.name);
+            glDrawTexiOES(p.x, p.y, 0, mRightTrail.w, mRightTrail.h);
+
+            // trail...
+            p.x = (x + c.x) - mBrightSpot.w/2;
+            p.y = c.y-mLeftTrail.h/2;
+            fade = t<0.5f+0.25f ? (t-0.5f)*4.0f : 1.0f;
+            fade *= fade;
+            glColor4f(fade, fade, fade, fade);
+            glBindTexture(GL_TEXTURE_2D, mLeftTrail.name);
+            glDrawTexiOES(p.x, p.y, 0, mLeftTrail.w, mLeftTrail.h);
+        }
+
+        const Point p( x + c.x-mBrightSpot.w/2, c.y-mBrightSpot.h/2 );
+        glBindTexture(GL_TEXTURE_2D, mBrightSpot.name);
+        glColor4f(1,0.5,0.5,1);
+        glDrawTexiOES(p.x, p.y, 0, mBrightSpot.w, mBrightSpot.h);
+
+        // update animation
+        nsecs_t time = systemTime() - startTime;
+        t = ((4.0f/(360.0f*us2ns(16667))) * time);
+        t = t - floorf(t);
+
+        eglSwapBuffers(mDisplay, mSurface);
+
+        if (exitPending()) {
+            if (fadeTime == 0) {
+                fadeTime = time;
+            }
+            time -= fadeTime;
+            alpha = 1.0f - ((float(time) * 6.0f) / float(s2ns(1)));
+
+            session()->openTransaction();
+            mFlingerSurface->setAlpha(alpha*alpha);
+            session()->closeTransaction();
+        }
+    } while (alpha > 0);
+
+    // cleanup
+    glFinish();
+    glDeleteTextures(1, &mLeftTrail.name);
+    glDeleteTextures(1, &mRightTrail.name);
+    glDeleteTextures(1, &mBrightSpot.name);
+    return false;
+}
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
diff --git a/libs/surfaceflinger/BootAnimation.h b/libs/surfaceflinger/BootAnimation.h
new file mode 100644
index 0000000..a4a6d49
--- /dev/null
+++ b/libs/surfaceflinger/BootAnimation.h
@@ -0,0 +1,84 @@
+/*
+ * 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_BOOTANIMATION_H
+#define ANDROID_BOOTANIMATION_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/threads.h>
+#include <utils/AssetManager.h>
+
+#include <ui/ISurfaceComposer.h>
+#include <ui/SurfaceComposerClient.h>
+
+#include <GLES/egl.h>
+
+#include "Barrier.h"
+
+class SkBitmap;
+
+namespace android {
+
+class AssetManager;
+
+// ---------------------------------------------------------------------------
+
+class BootAnimation : public Thread
+{
+public:
+                BootAnimation(const sp<ISurfaceComposer>& composer);
+    virtual     ~BootAnimation();
+
+    const sp<SurfaceComposerClient>& session() const;
+    virtual void        requestExit();
+
+private:
+    virtual bool        threadLoop();
+    virtual status_t    readyToRun();
+    virtual void        onFirstRef();
+
+    struct Texture {
+        GLint   w;
+        GLint   h;
+        GLuint  name;
+    };
+
+    status_t initTexture(Texture* texture, AssetManager& asset, const char* name);
+    bool android();
+    bool cylon();
+
+    sp<SurfaceComposerClient>       mSession;
+    AssetManager mAssets;
+    Texture mLeftTrail;
+    Texture mRightTrail;
+    Texture mBrightSpot;
+    Texture mAndroid[3];
+    int     mWidth;
+    int     mHeight;
+    EGLDisplay  mDisplay;
+    EGLDisplay  mContext;
+    EGLDisplay  mSurface;
+    sp<Surface> mFlingerSurface;
+    Barrier mBarrier;
+};
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // ANDROID_BOOTANIMATION_H
diff --git a/libs/surfaceflinger/CPUGauge.cpp b/libs/surfaceflinger/CPUGauge.cpp
new file mode 100644
index 0000000..74a9270
--- /dev/null
+++ b/libs/surfaceflinger/CPUGauge.cpp
@@ -0,0 +1,171 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "CPUGauge"
+
+#include <stdint.h>
+#include <limits.h>
+#include <sys/types.h>
+#include <math.h>
+
+#include <utils/threads.h>
+#include <utils/Errors.h>
+#include <utils/Log.h>
+
+#include <ui/PixelFormat.h>
+#include <ui/Rect.h>
+#include <ui/Region.h>
+#include <ui/DisplayInfo.h>
+#include <ui/ISurfaceComposer.h>
+#include <ui/ISurfaceFlingerClient.h>
+
+#include <pixelflinger/pixelflinger.h>
+
+#include "CPUGauge.h"
+
+namespace android {
+
+CPUGauge::CPUGauge( const sp<ISurfaceComposer>& composer,
+                    nsecs_t interval,
+                    int clock,
+                    int refclock)
+    :   Thread(false), 
+        mInterval(interval), mClock(clock), mRefClock(refclock),
+        mReferenceTime(0),
+        mReferenceWorkingTime(0), mCpuUsage(0),
+        mRefIdleTime(0), mIdleTime(0)
+{
+    mFd = fopen("/proc/stat", "r");
+    setvbuf(mFd, NULL, _IONBF, 0);
+
+    mSession = SurfaceComposerClient::clientForConnection(
+        composer->createConnection()->asBinder());
+}
+
+CPUGauge::~CPUGauge()
+{
+    fclose(mFd);
+}
+
+const sp<SurfaceComposerClient>& CPUGauge::session() const 
+{
+    return mSession;
+}
+
+void CPUGauge::onFirstRef()
+{
+    run("CPU Gauge");
+}
+
+status_t CPUGauge::readyToRun()
+{
+    LOGI("Starting CPU gauge...");
+    return NO_ERROR;
+}
+
+bool CPUGauge::threadLoop()
+{
+    DisplayInfo dinfo;
+    session()->getDisplayInfo(0, &dinfo);
+    sp<Surface> s(session()->createSurface(getpid(), 0, dinfo.w, 4, PIXEL_FORMAT_OPAQUE));
+    session()->openTransaction();
+    s->setLayer(INT_MAX);
+    session()->closeTransaction();
+    
+    static const GGLfixed colors[4][4] = {
+            { 0x00000, 0x10000, 0x00000, 0x10000 },
+            { 0x10000, 0x10000, 0x00000, 0x10000 },
+            { 0x10000, 0x00000, 0x00000, 0x10000 },
+            { 0x00000, 0x00000, 0x00000, 0x10000 },
+        };
+
+    GGLContext* gl;
+    gglInit(&gl);
+    gl->activeTexture(gl, 0);
+    gl->disable(gl, GGL_TEXTURE_2D);
+    gl->disable(gl, GGL_BLEND);
+
+    const int w = dinfo.w;
+
+    while(!exitPending())
+    {
+        mLock.lock();
+            const float cpuUsage = this->cpuUsage();
+            const float totalCpuUsage = 1.0f - idle();
+        mLock.unlock();
+
+        Surface::SurfaceInfo info;
+        s->lock(&info);
+            GGLSurface fb;
+                fb.version = sizeof(GGLSurface);
+                fb.width   = info.w;
+                fb.height  = info.h;
+                fb.stride  = info.w;
+                fb.format  = info.format;
+                fb.data = (GGLubyte*)info.bits;
+
+            gl->colorBuffer(gl, &fb);
+            gl->color4xv(gl, colors[3]);
+            gl->recti(gl, 0, 0, w, 4);
+            gl->color4xv(gl, colors[2]); // red
+            gl->recti(gl, 0, 0, int(totalCpuUsage*w), 2);
+            gl->color4xv(gl, colors[0]); // green
+            gl->recti(gl, 0, 2, int(cpuUsage*w), 4);
+        
+        s->unlockAndPost(); 
+
+        usleep(ns2us(mInterval));
+    }
+
+    gglUninit(gl);
+    return false;
+}
+
+void CPUGauge::sample()
+{
+    if (mLock.tryLock() == NO_ERROR) {
+        const nsecs_t now = systemTime(mRefClock);
+        const nsecs_t referenceTime = now-mReferenceTime;
+        if (referenceTime >= mInterval) {
+            const float reftime = 1.0f / referenceTime;
+            const nsecs_t nowWorkingTime = systemTime(mClock);
+            
+            char buf[256];
+            fgets(buf, 256, mFd);
+            rewind(mFd);
+            char *str = buf+5;
+            char const * const usermode = strsep(&str, " ");  (void)usermode;
+            char const * const usernice = strsep(&str, " ");  (void)usernice;
+            char const * const systemmode = strsep(&str, " ");(void)systemmode;
+            char const * const idle = strsep(&str, " ");
+            const nsecs_t nowIdleTime = atoi(idle) * 10000000LL;
+            mIdleTime = float(nowIdleTime - mRefIdleTime) * reftime;
+            mRefIdleTime = nowIdleTime;
+            
+            const nsecs_t workingTime = nowWorkingTime - mReferenceWorkingTime;
+            const float newCpuUsage = float(workingTime) * reftime;
+            if (mCpuUsage != newCpuUsage) {        
+                mCpuUsage = newCpuUsage;
+                mReferenceWorkingTime = nowWorkingTime;
+                mReferenceTime = now;
+            }
+        }
+        mLock.unlock();
+    }
+}
+
+
+}; // namespace android
diff --git a/libs/surfaceflinger/CPUGauge.h b/libs/surfaceflinger/CPUGauge.h
new file mode 100644
index 0000000..5bb53c0
--- /dev/null
+++ b/libs/surfaceflinger/CPUGauge.h
@@ -0,0 +1,74 @@
+/*
+ * 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_CPUGAUGE_H
+#define ANDROID_CPUGAUGE_H
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Timers.h>
+
+#include <ui/SurfaceComposerClient.h>
+
+namespace android {
+
+class CPUGauge : public Thread
+{
+public:
+    CPUGauge(   const sp<ISurfaceComposer>& composer,
+                nsecs_t interval=s2ns(1),
+                int clock=SYSTEM_TIME_THREAD,
+                int refclock=SYSTEM_TIME_MONOTONIC);
+                
+    ~CPUGauge();
+
+    const sp<SurfaceComposerClient>& session() const;
+
+    void sample();
+ 
+    inline float cpuUsage() const { return mCpuUsage; }
+    inline float idle() const { return mIdleTime; }
+
+private:
+    virtual void        onFirstRef();
+    virtual status_t    readyToRun();
+    virtual bool        threadLoop();
+
+    Mutex mLock;
+
+    sp<SurfaceComposerClient> mSession;
+
+    const nsecs_t mInterval;
+    const int mClock;
+    const int mRefClock;
+
+    nsecs_t mReferenceTime;
+    nsecs_t mReferenceWorkingTime;
+    float mCpuUsage;
+    nsecs_t mRefIdleTime;
+    float mIdleTime;
+    FILE*   mFd;
+};
+
+
+}; // namespace android
+
+#endif // ANDROID_CPUGAUGE_H
diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
new file mode 100644
index 0000000..5dd9446
--- /dev/null
+++ b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
@@ -0,0 +1,335 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "SurfaceFlinger"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <GLES/egl.h>
+
+#include <utils/Log.h>
+
+#include <ui/EGLDisplaySurface.h>
+
+#include "DisplayHardware/DisplayHardware.h"
+#include "ui/BlitHardware.h"
+
+using namespace android;
+
+static __attribute__((noinline))
+const char *egl_strerror(EGLint err)
+{
+    switch (err){
+        case EGL_SUCCESS:           return "EGL_SUCCESS";
+        case EGL_NOT_INITIALIZED:   return "EGL_NOT_INITIALIZED";
+        case EGL_BAD_ACCESS:        return "EGL_BAD_ACCESS";
+        case EGL_BAD_ALLOC:         return "EGL_BAD_ALLOC";
+        case EGL_BAD_ATTRIBUTE:     return "EGL_BAD_ATTRIBUTE";
+        case EGL_BAD_CONFIG:        return "EGL_BAD_CONFIG";
+        case EGL_BAD_CONTEXT:       return "EGL_BAD_CONTEXT";
+        case EGL_BAD_CURRENT_SURFACE: return "EGL_BAD_CURRENT_SURFACE";
+        case EGL_BAD_DISPLAY:       return "EGL_BAD_DISPLAY";
+        case EGL_BAD_MATCH:         return "EGL_BAD_MATCH";
+        case EGL_BAD_NATIVE_PIXMAP: return "EGL_BAD_NATIVE_PIXMAP";
+        case EGL_BAD_NATIVE_WINDOW: return "EGL_BAD_NATIVE_WINDOW";
+        case EGL_BAD_PARAMETER:     return "EGL_BAD_PARAMETER";
+        case EGL_BAD_SURFACE:       return "EGL_BAD_SURFACE";
+        case EGL_CONTEXT_LOST:      return "EGL_CONTEXT_LOST";
+        default: return "UNKNOWN";
+    }
+}
+
+static __attribute__((noinline))
+void checkGLErrors()
+{
+    GLenum error = glGetError();
+    if (error != GL_NO_ERROR)
+        LOGE("GL error 0x%04x", int(error));
+}
+
+static __attribute__((noinline))
+void checkEGLErrors(const char* token)
+{
+    EGLint error = eglGetError();
+    // GLESonGL seems to be returning 0 when there is no errors?
+    if (error && error != EGL_SUCCESS)
+        LOGE("%s error 0x%04x (%s)",
+                token, int(error), egl_strerror(error));
+}
+
+
+/*
+ * Initialize the display to the specified values.
+ *
+ */
+
+DisplayHardware::DisplayHardware(
+        const sp<SurfaceFlinger>& flinger,
+        uint32_t dpy)
+    : DisplayHardwareBase(flinger, dpy)
+{
+    init(dpy);
+}
+
+DisplayHardware::~DisplayHardware()
+{
+    fini();
+}
+
+float DisplayHardware::getDpiX() const           { return mDpiX; }
+float DisplayHardware::getDpiY() const           { return mDpiY; }
+float DisplayHardware::getRefreshRate() const    { return mRefreshRate; }
+
+int DisplayHardware::getWidth() const {
+    return mWidth;
+}
+int DisplayHardware::getHeight() const {
+    return mHeight;
+}
+PixelFormat DisplayHardware::getFormat() const {
+    return mFormat;
+}
+
+void DisplayHardware::init(uint32_t dpy)
+{
+    // initialize EGL
+    const EGLint attribs[] = {
+            EGL_RED_SIZE,       5,
+            EGL_GREEN_SIZE,     6,
+            EGL_BLUE_SIZE,      5,
+            EGL_DEPTH_SIZE,     0,
+            EGL_NONE
+    };
+    EGLint w, h, dummy;
+    EGLint numConfigs, n;
+    EGLConfig config;
+    EGLSurface surface;
+    EGLContext context;
+    mFlags = 0;
+
+    // TODO: all the extensions below should be queried through
+    // eglGetProcAddress().
+
+    EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+    eglInitialize(display, NULL, NULL);
+    eglGetConfigs(display, NULL, 0, &numConfigs);
+    eglChooseConfig(display, attribs, &config, 1, &n);
+
+    /*
+     * Gather EGL extensions
+     */
+
+    const char* const egl_extensions = eglQueryString(
+            display, EGL_EXTENSIONS);
+    
+    const char* egl_extensions_config = egl_extensions;
+    
+    if (strstr(egl_extensions, "EGL_ANDROID_query_string_config")) {
+        egl_extensions_config = eglQueryStringConfigANDROID(
+                display, config, EGL_EXTENSIONS);
+    }
+
+    LOGI("EGL informations:");
+    LOGI("# of configs : %d", numConfigs);
+    LOGI("vendor    : %s", eglQueryString(display, EGL_VENDOR));
+    LOGI("version   : %s", eglQueryString(display, EGL_VERSION));
+    LOGI("extensions: %s", egl_extensions);
+    LOGI("ext/config: %s", egl_extensions_config);
+    LOGI("Client API: %s", eglQueryString(display, EGL_CLIENT_APIS)?:"Not Supported");
+
+    if (strstr(egl_extensions_config, "EGL_ANDROID_swap_rectangle")) {
+        mFlags |= SWAP_RECTANGLE_EXTENSION;
+        // TODO: get the real "update_on_demand" behavior
+        mFlags |= UPDATE_ON_DEMAND;
+    }
+    if (eglGetConfigAttrib(display, config, EGL_CONFIG_CAVEAT, &dummy) == EGL_TRUE) {
+        if (dummy == EGL_SLOW_CONFIG)
+            mFlags |= SLOW_CONFIG;
+    }
+
+    /*
+     * Create our main surface
+     */
+
+    mDisplaySurface = new EGLDisplaySurface();
+
+    surface = eglCreateWindowSurface(display, config, mDisplaySurface.get(), NULL);
+    //checkEGLErrors("eglCreateDisplaySurfaceANDROID");
+
+    if (eglQuerySurface(display, surface, EGL_SWAP_BEHAVIOR, &dummy) == EGL_TRUE) {
+        if (dummy == EGL_BUFFER_PRESERVED) {
+            mFlags |= BUFFER_PRESERVED;
+            if (strstr(egl_extensions_config, "EGL_ANDROID_copy_front_to_back")) {
+                mFlags |= COPY_BACK_EXTENSION;
+            }
+        }
+    }
+    
+    GLint value = EGL_UNKNOWN;
+    eglQuerySurface(display, surface, EGL_HORIZONTAL_RESOLUTION, &value);
+    if (value == EGL_UNKNOWN) {
+        mDpiX = 160.0f;
+    } else {
+        mDpiX = 25.4f * float(value)/EGL_DISPLAY_SCALING;
+    }
+    value = EGL_UNKNOWN;
+    eglQuerySurface(display, surface, EGL_VERTICAL_RESOLUTION, &value);
+    if (value == EGL_UNKNOWN) {
+        mDpiY = 160.0f;
+    } else {
+        mDpiY = 25.4f * float(value)/EGL_DISPLAY_SCALING;
+    }
+    mRefreshRate = 60.f;    // TODO: get the real refresh rate 
+
+    /*
+     * Create our OpenGL ES context
+     */
+    
+    context = eglCreateContext(display, config, NULL, NULL);
+    //checkEGLErrors("eglCreateContext");
+    
+    eglQuerySurface(display, surface, EGL_WIDTH, &mWidth);
+    eglQuerySurface(display, surface, EGL_HEIGHT, &mHeight);
+    
+    
+    /*
+     * Gather OpenGL ES extensions
+     */
+
+    eglMakeCurrent(display, surface, surface, context);
+    const char* const  gl_extensions = (const char*)glGetString(GL_EXTENSIONS);
+    LOGI("OpenGL informations:");
+    LOGI("vendor    : %s", glGetString(GL_VENDOR));
+    LOGI("renderer  : %s", glGetString(GL_RENDERER));
+    LOGI("version   : %s", glGetString(GL_VERSION));
+    LOGI("extensions: %s", gl_extensions);
+
+    if (strstr(gl_extensions, "GL_ARB_texture_non_power_of_two")) {
+        mFlags |= NPOT_EXTENSION;
+    }
+    if (strstr(gl_extensions, "GL_OES_draw_texture")) {
+        mFlags |= DRAW_TEXTURE_EXTENSION;
+    }
+    if (strstr(gl_extensions, "GL_ANDROID_direct_texture")) {
+        mFlags |= DIRECT_TEXTURE;
+    }
+
+    // Unbind the context from this thread
+    eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+
+    mDisplay = display;
+    mConfig  = config;
+    mSurface = surface;
+    mContext = context;
+    mFormat  = GGL_PIXEL_FORMAT_RGB_565;
+
+    mBlitEngine = copybit_init();
+}
+
+/*
+ * Clean up.  Throw out our local state.
+ *
+ * (It's entirely possible we'll never get here, since this is meant
+ * for real hardware, which doesn't restart.)
+ */
+
+void DisplayHardware::fini()
+{
+    eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+    eglTerminate(mDisplay);
+    copybit_term(mBlitEngine);
+}
+
+void DisplayHardware::releaseScreen() const
+{
+    DisplayHardwareBase::releaseScreen();
+}
+
+void DisplayHardware::acquireScreen() const
+{
+    DisplayHardwareBase::acquireScreen();
+}
+
+void DisplayHardware::getDisplaySurface(copybit_image_t* img) const
+{
+    img->w      = mDisplaySurface->stride;
+    img->h      = mDisplaySurface->height;
+    img->format = mDisplaySurface->format;
+    img->offset = mDisplaySurface->offset;
+    img->base   = (void*)mDisplaySurface->base;
+    img->fd     = mDisplaySurface->fd;
+}
+
+void DisplayHardware::getDisplaySurface(GGLSurface* fb) const
+{
+    fb->version= sizeof(GGLSurface);
+    fb->width  = mDisplaySurface->width;
+    fb->height = mDisplaySurface->height;
+    fb->stride = mDisplaySurface->stride;
+    fb->format = mDisplaySurface->format;
+    fb->data   = (GGLubyte*)mDisplaySurface->base + mDisplaySurface->offset;
+}
+
+uint32_t DisplayHardware::getPageFlipCount() const {
+    return mDisplaySurface->getPageFlipCount();
+}
+
+/*
+ * "Flip" the front and back buffers.
+ */
+
+void DisplayHardware::flip(const Region& dirty) const
+{
+    checkGLErrors();
+
+    EGLDisplay dpy = mDisplay;
+    EGLSurface surface = mSurface;
+
+    Region newDirty(dirty);
+    newDirty.andSelf(Rect(mWidth, mHeight));
+
+    if (mFlags & BUFFER_PRESERVED) {
+        const Region copyback(mDirty.subtract(newDirty));
+        mDirty = newDirty;
+        mDisplaySurface->copyFrontToBack(copyback);
+    } 
+
+    if (mFlags & SWAP_RECTANGLE_EXTENSION) {
+        const Rect& b(newDirty.bounds());
+        eglSwapRectangleANDROID(
+                dpy, surface,
+                b.left, b.top, b.width(), b.height());
+    }
+
+    eglSwapBuffers(dpy, surface);
+    checkEGLErrors("eglSwapBuffers");
+
+    // for debugging
+    //glClearColor(1,0,0,0);
+    //glClear(GL_COLOR_BUFFER_BIT);
+}
+
+uint32_t DisplayHardware::getFlags() const
+{
+    return mFlags;
+}
+
+void DisplayHardware::makeCurrent() const
+{
+    eglMakeCurrent(mDisplay, mSurface, mSurface, mContext);
+}
diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardware.h b/libs/surfaceflinger/DisplayHardware/DisplayHardware.h
new file mode 100644
index 0000000..299e236
--- /dev/null
+++ b/libs/surfaceflinger/DisplayHardware/DisplayHardware.h
@@ -0,0 +1,105 @@
+/*
+ * 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_DISPLAY_HARDWARE_H
+#define ANDROID_DISPLAY_HARDWARE_H
+
+#include <stdlib.h>
+
+#include <ui/PixelFormat.h>
+#include <ui/Region.h>
+
+#include <GLES/egl.h>
+
+#include "DisplayHardware/DisplayHardwareBase.h"
+
+struct copybit_image_t;
+struct copybit_t;
+
+namespace android {
+
+class EGLDisplaySurface;
+
+class DisplayHardware : public DisplayHardwareBase
+{
+public:
+    enum {
+        COPY_BACK_EXTENSION     = 0x00000001,
+        DIRECT_TEXTURE          = 0x00000002,
+        SWAP_RECTANGLE_EXTENSION= 0x00000004,
+        COPY_BITS_EXTENSION     = 0x00000008,
+        NPOT_EXTENSION          = 0x00000100,
+        DRAW_TEXTURE_EXTENSION  = 0x00000200,
+        BUFFER_PRESERVED        = 0x00010000,
+        UPDATE_ON_DEMAND        = 0x00020000,   // video driver feature
+        SLOW_CONFIG             = 0x00040000,   // software
+    };
+
+    DisplayHardware(
+            const sp<SurfaceFlinger>& flinger,
+            uint32_t displayIndex);
+
+    ~DisplayHardware();
+
+    void releaseScreen() const;
+    void acquireScreen() const;
+
+    // Flip the front and back buffers if the back buffer is "dirty".  Might
+    // be instantaneous, might involve copying the frame buffer around.
+    void flip(const Region& dirty) const;
+
+    float       getDpiX() const;
+    float       getDpiY() const;
+    float       getRefreshRate() const;
+    int         getWidth() const;
+    int         getHeight() const;
+    PixelFormat getFormat() const;
+    uint32_t    getFlags() const;
+    void        makeCurrent() const;
+
+    uint32_t getPageFlipCount() const;
+    void getDisplaySurface(copybit_image_t* img) const;
+    void getDisplaySurface(GGLSurface* fb) const;
+    EGLDisplay getEGLDisplay() const { return mDisplay; }
+    copybit_t* getBlitEngine() const { return mBlitEngine; }
+    
+    Rect bounds() const {
+        return Rect(mWidth, mHeight);
+    }
+
+private:
+    void init(uint32_t displayIndex) __attribute__((noinline));
+    void fini() __attribute__((noinline));
+
+    EGLDisplay      mDisplay;
+    EGLSurface      mSurface;
+    EGLContext      mContext;
+    EGLConfig       mConfig;
+    float           mDpiX;
+    float           mDpiY;
+    float           mRefreshRate;
+    int             mWidth;
+    int             mHeight;
+    PixelFormat     mFormat;
+    uint32_t        mFlags;
+    mutable Region  mDirty;
+    sp<EGLDisplaySurface> mDisplaySurface;
+    copybit_t*      mBlitEngine;
+};
+
+}; // namespace android
+
+#endif // ANDROID_DISPLAY_HARDWARE_H
diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardwareBase.cpp b/libs/surfaceflinger/DisplayHardware/DisplayHardwareBase.cpp
new file mode 100644
index 0000000..90f6287
--- /dev/null
+++ b/libs/surfaceflinger/DisplayHardware/DisplayHardwareBase.cpp
@@ -0,0 +1,395 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "SurfaceFlinger"
+
+#include <assert.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <termios.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/resource.h>
+
+#include <linux/unistd.h>
+
+#include <utils/Log.h>
+
+#include "DisplayHardware/DisplayHardwareBase.h"
+#include "SurfaceFlinger.h"
+
+// ----------------------------------------------------------------------------
+// the sim build doesn't have gettid
+
+#ifndef HAVE_GETTID
+# define gettid getpid
+#endif
+
+// ----------------------------------------------------------------------------
+namespace android {
+
+static char const * const kSleepFileName = "/sys/android_power/wait_for_fb_sleep";
+static char const * const kWakeFileName = "/sys/android_power/wait_for_fb_wake";
+
+// This dir exists if the framebuffer console is present, either built into
+// the kernel or loaded as a module.
+static char const * const kFbconSysDir = "/sys/class/graphics/fbcon";
+
+// ----------------------------------------------------------------------------
+
+DisplayHardwareBase::DisplayEventThreadBase::DisplayEventThreadBase(
+        const sp<SurfaceFlinger>& flinger)
+    : Thread(false), mFlinger(flinger) {
+}
+
+DisplayHardwareBase::DisplayEventThreadBase::~DisplayEventThreadBase() {
+}
+
+// ----------------------------------------------------------------------------
+
+DisplayHardwareBase::DisplayEventThread::DisplayEventThread(
+        const sp<SurfaceFlinger>& flinger)
+    : DisplayEventThreadBase(flinger)
+{
+}
+
+DisplayHardwareBase::DisplayEventThread::~DisplayEventThread()
+{
+}
+
+bool DisplayHardwareBase::DisplayEventThread::threadLoop()
+{
+    int err = 0;
+    char buf;
+    int fd;
+
+    fd = open(kSleepFileName, O_RDONLY, 0);
+    do {
+      err = read(fd, &buf, 1);
+    } while (err < 0 && errno == EINTR);
+    close(fd);
+    LOGW_IF(err<0, "ANDROID_WAIT_FOR_FB_SLEEP failed (%s)", strerror(errno));
+    if (err >= 0) {
+        sp<SurfaceFlinger> flinger = mFlinger.promote();
+        LOGD("About to give-up screen, flinger = %p", flinger.get());
+        if (flinger != 0) {
+            mBarrier.close();
+            flinger->screenReleased(0);
+            mBarrier.wait();
+        }
+    }
+    fd = open(kWakeFileName, O_RDONLY, 0);
+    do {
+      err = read(fd, &buf, 1);
+    } while (err < 0 && errno == EINTR);
+    close(fd);
+    LOGW_IF(err<0, "ANDROID_WAIT_FOR_FB_WAKE failed (%s)", strerror(errno));
+    if (err >= 0) {
+        sp<SurfaceFlinger> flinger = mFlinger.promote();
+        LOGD("Screen about to return, flinger = %p", flinger.get());
+        if (flinger != 0)
+            flinger->screenAcquired(0);
+    }
+    return true;
+}
+
+status_t DisplayHardwareBase::DisplayEventThread::releaseScreen() const
+{
+    mBarrier.open();
+    return NO_ERROR;
+}
+
+status_t DisplayHardwareBase::DisplayEventThread::readyToRun()
+{
+    if (access(kSleepFileName, R_OK) || access(kWakeFileName, R_OK)) {
+        LOGE("Couldn't open %s or %s", kSleepFileName, kWakeFileName);
+        return NO_INIT;
+    }
+    return NO_ERROR;
+}
+
+status_t DisplayHardwareBase::DisplayEventThread::initCheck() const
+{
+    return (access(kSleepFileName, R_OK) == 0 &&
+            access(kWakeFileName, R_OK) == 0 &&
+            access(kFbconSysDir, F_OK) != 0) ? NO_ERROR : NO_INIT;
+}
+
+// ----------------------------------------------------------------------------
+
+pid_t DisplayHardwareBase::ConsoleManagerThread::sSignalCatcherPid = 0;
+
+DisplayHardwareBase::ConsoleManagerThread::ConsoleManagerThread(
+        const sp<SurfaceFlinger>& flinger)
+    : DisplayEventThreadBase(flinger), consoleFd(-1)
+{   
+    sSignalCatcherPid = 0;
+
+    // create a new console
+    char const * const ttydev = "/dev/tty0";
+    int fd = open(ttydev, O_RDWR | O_SYNC);
+    if (fd<0) {
+        LOGE("Can't open %s", ttydev);
+        this->consoleFd = -errno;
+        return;
+    }
+
+    // to make sure that we are in text mode
+    int res = ioctl(fd, KDSETMODE, (void*) KD_TEXT);
+    if (res<0) {
+        LOGE("ioctl(%d, KDSETMODE, ...) failed, res %d (%s)",
+                fd, res, strerror(errno));
+    }
+    
+    // get the current console
+    struct vt_stat vs;
+    res = ioctl(fd, VT_GETSTATE, &vs);
+    if (res<0) {
+        LOGE("ioctl(%d, VT_GETSTATE, ...) failed, res %d (%s)",
+                fd, res, strerror(errno));
+        this->consoleFd = -errno;
+        return;
+    }
+
+    // switch to console 7 (which is what X normaly uses)
+    int vtnum = 7;
+    do {
+        res = ioctl(fd, VT_ACTIVATE, (void*)vtnum);
+    } while(res < 0 && errno == EINTR);
+    if (res<0) {
+        LOGE("ioctl(%d, VT_ACTIVATE, ...) failed, %d (%s) for %d",
+                fd, errno, strerror(errno), vtnum);
+        this->consoleFd = -errno;
+        return;
+    }
+
+    do {
+        res = ioctl(fd, VT_WAITACTIVE, (void*)vtnum);
+    } while(res < 0 && errno == EINTR);
+    if (res<0) {
+        LOGE("ioctl(%d, VT_WAITACTIVE, ...) failed, %d %d %s for %d",
+                fd, res, errno, strerror(errno), vtnum);
+        this->consoleFd = -errno;
+        return;
+    }
+
+    // open the new console
+    close(fd);
+    fd = open(ttydev, O_RDWR | O_SYNC);
+    if (fd<0) {
+        LOGE("Can't open new console %s", ttydev);
+        this->consoleFd = -errno;
+        return;
+    }
+
+    /* disable console line buffer, echo, ... */
+    struct termios ttyarg;
+    ioctl(fd, TCGETS , &ttyarg);
+    ttyarg.c_iflag = 0;
+    ttyarg.c_lflag = 0;
+    ioctl(fd, TCSETS , &ttyarg);
+
+    // set up signals so we're notified when the console changes
+    // we can't use SIGUSR1 because it's used by the java-vm
+    vm.mode = VT_PROCESS;
+    vm.waitv = 0;
+    vm.relsig = SIGUSR2;
+    vm.acqsig = SIGUNUSED;
+    vm.frsig = 0;
+
+    struct sigaction act;
+    sigemptyset(&act.sa_mask);
+    act.sa_handler = sigHandler;
+    act.sa_flags = 0;
+    sigaction(vm.relsig, &act, NULL);
+
+    sigemptyset(&act.sa_mask);
+    act.sa_handler = sigHandler;
+    act.sa_flags = 0;
+    sigaction(vm.acqsig, &act, NULL);
+
+    sigset_t mask;
+    sigemptyset(&mask);
+    sigaddset(&mask, vm.relsig);
+    sigaddset(&mask, vm.acqsig);
+    sigprocmask(SIG_BLOCK, &mask, NULL);
+
+    // switch to graphic mode
+    res = ioctl(fd, KDSETMODE, (void*)KD_GRAPHICS);
+    LOGW_IF(res<0,
+            "ioctl(%d, KDSETMODE, KD_GRAPHICS) failed, res %d", fd, res);
+
+    this->prev_vt_num = vs.v_active;
+    this->vt_num = vtnum;
+    this->consoleFd = fd;
+}
+
+DisplayHardwareBase::ConsoleManagerThread::~ConsoleManagerThread()
+{   
+    if (this->consoleFd >= 0) {
+        int fd = this->consoleFd;
+        int prev_vt_num = this->prev_vt_num;
+        int res;
+        ioctl(fd, KDSETMODE, (void*)KD_TEXT);
+        do {
+            res = ioctl(fd, VT_ACTIVATE, (void*)prev_vt_num);
+        } while(res < 0 && errno == EINTR);
+        do {
+            res = ioctl(fd, VT_WAITACTIVE, (void*)prev_vt_num);
+        } while(res < 0 && errno == EINTR);
+        close(fd);    
+        char const * const ttydev = "/dev/tty0";
+        fd = open(ttydev, O_RDWR | O_SYNC);
+        ioctl(fd, VT_DISALLOCATE, 0);
+        close(fd);
+    }
+}
+
+status_t DisplayHardwareBase::ConsoleManagerThread::readyToRun()
+{
+    if (this->consoleFd >= 0) {
+        sSignalCatcherPid = gettid();
+        
+        sigset_t mask;
+        sigemptyset(&mask);
+        sigaddset(&mask, vm.relsig);
+        sigaddset(&mask, vm.acqsig);
+        sigprocmask(SIG_BLOCK, &mask, NULL);
+
+        int res = ioctl(this->consoleFd, VT_SETMODE, &vm);
+        if (res<0) {
+            LOGE("ioctl(%d, VT_SETMODE, ...) failed, %d (%s)",
+                    this->consoleFd, errno, strerror(errno));
+        }
+        return NO_ERROR;
+    }
+    return this->consoleFd;
+}
+
+void DisplayHardwareBase::ConsoleManagerThread::requestExit()
+{
+    Thread::requestExit();
+    if (sSignalCatcherPid != 0) {
+        // wake the thread up
+        kill(sSignalCatcherPid, SIGINT);
+        // wait for it...
+    }
+}
+
+void DisplayHardwareBase::ConsoleManagerThread::sigHandler(int sig)
+{
+    // resend the signal to our signal catcher thread
+    LOGW("received signal %d in thread %d, resending to %d",
+            sig, gettid(), sSignalCatcherPid);
+
+    // we absolutely need the delays below because without them
+    // our main thread never gets a chance to handle the signal.
+    usleep(10000);
+    kill(sSignalCatcherPid, sig);
+    usleep(10000);
+}
+
+status_t DisplayHardwareBase::ConsoleManagerThread::releaseScreen() const
+{
+    int fd = this->consoleFd;
+    int err = ioctl(fd, VT_RELDISP, (void*)1);
+    LOGE_IF(err<0, "ioctl(%d, VT_RELDISP, 1) failed %d (%s)",
+        fd, errno, strerror(errno));
+    return (err<0) ? (-errno) : status_t(NO_ERROR);
+}
+
+bool DisplayHardwareBase::ConsoleManagerThread::threadLoop()
+{
+    sigset_t mask;
+    sigemptyset(&mask);
+    sigaddset(&mask, vm.relsig);
+    sigaddset(&mask, vm.acqsig);
+
+    int sig = 0;
+    sigwait(&mask, &sig);
+
+    if (sig == vm.relsig) {
+        sp<SurfaceFlinger> flinger = mFlinger.promote();
+        //LOGD("About to give-up screen, flinger = %p", flinger.get());
+        if (flinger != 0)
+            flinger->screenReleased(0);
+    } else if (sig == vm.acqsig) {
+        sp<SurfaceFlinger> flinger = mFlinger.promote();
+        //LOGD("Screen about to return, flinger = %p", flinger.get());
+        if (flinger != 0) 
+            flinger->screenAcquired(0);
+    }
+    
+    return true;
+}
+
+status_t DisplayHardwareBase::ConsoleManagerThread::initCheck() const
+{
+    return consoleFd >= 0 ? NO_ERROR : NO_INIT;
+}
+
+// ----------------------------------------------------------------------------
+
+DisplayHardwareBase::DisplayHardwareBase(const sp<SurfaceFlinger>& flinger,
+        uint32_t displayIndex) 
+    : mCanDraw(true)
+{
+    mDisplayEventThread = new DisplayEventThread(flinger);
+    if (mDisplayEventThread->initCheck() != NO_ERROR) {
+        // fall-back on the console
+        mDisplayEventThread = new ConsoleManagerThread(flinger);
+    }
+}
+
+DisplayHardwareBase::~DisplayHardwareBase()
+{
+    // request exit
+    mDisplayEventThread->requestExitAndWait();
+}
+
+
+bool DisplayHardwareBase::canDraw() const
+{
+    return mCanDraw;
+}
+
+void DisplayHardwareBase::releaseScreen() const
+{
+    status_t err = mDisplayEventThread->releaseScreen();
+    if (err >= 0) {
+        //LOGD("screen given-up");
+        mCanDraw = false;
+    }
+}
+
+void DisplayHardwareBase::acquireScreen() const
+{
+    status_t err = mDisplayEventThread->acquireScreen();
+    if (err >= 0) {
+        //LOGD("screen returned");
+        mCanDraw = true;
+    }
+}
+
+}; // namespace android
diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardwareBase.h b/libs/surfaceflinger/DisplayHardware/DisplayHardwareBase.h
new file mode 100644
index 0000000..8369bb8
--- /dev/null
+++ b/libs/surfaceflinger/DisplayHardware/DisplayHardwareBase.h
@@ -0,0 +1,96 @@
+/*
+ * 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_DISPLAY_HARDWARE_BASE_H
+#define ANDROID_DISPLAY_HARDWARE_BASE_H
+
+#include <stdint.h>
+#include <utils/RefBase.h>
+#include <utils/threads.h>
+#include <linux/kd.h>
+#include <linux/vt.h>
+#include "Barrier.h"
+
+namespace android {
+
+class SurfaceFlinger; 
+
+class DisplayHardwareBase
+{
+public:
+                DisplayHardwareBase(
+                        const sp<SurfaceFlinger>& flinger,
+                        uint32_t displayIndex);
+
+                ~DisplayHardwareBase();
+
+    // console managment
+    void releaseScreen() const;
+    void acquireScreen() const;
+    bool canDraw() const;
+
+private:
+    class DisplayEventThreadBase : public Thread {
+    protected:
+        wp<SurfaceFlinger> mFlinger;
+    public:
+        DisplayEventThreadBase(const sp<SurfaceFlinger>& flinger);
+        virtual ~DisplayEventThreadBase();
+        virtual void onFirstRef() {
+            run("DisplayEventThread", PRIORITY_URGENT_DISPLAY);
+        }
+        virtual status_t acquireScreen() const { return NO_ERROR; };
+        virtual status_t releaseScreen() const { return NO_ERROR; };
+        virtual status_t initCheck() const = 0;
+    };
+
+    class DisplayEventThread : public DisplayEventThreadBase 
+    {
+        mutable Barrier mBarrier;
+    public:
+                DisplayEventThread(const sp<SurfaceFlinger>& flinger);
+        virtual ~DisplayEventThread();
+        virtual bool threadLoop();
+        virtual status_t readyToRun();
+        virtual status_t releaseScreen() const;
+        virtual status_t initCheck() const;
+    };
+
+    class ConsoleManagerThread : public DisplayEventThreadBase 
+    {
+        int consoleFd;
+        int vt_num;
+        int prev_vt_num;
+        vt_mode vm;
+        static void sigHandler(int sig);
+        static pid_t sSignalCatcherPid;
+    public:
+                ConsoleManagerThread(const sp<SurfaceFlinger>& flinger);
+        virtual ~ConsoleManagerThread();
+        virtual bool threadLoop();
+        virtual status_t readyToRun();
+        virtual void requestExit();
+        virtual status_t releaseScreen() const;
+        virtual status_t initCheck() const;
+    };
+
+    sp<DisplayEventThreadBase>  mDisplayEventThread;
+    mutable int                 mCanDraw;
+};
+
+}; // namespace android
+
+#endif // ANDROID_DISPLAY_HARDWARE_BASE_H
diff --git a/libs/surfaceflinger/GPUHardware/GPUHardware.cpp b/libs/surfaceflinger/GPUHardware/GPUHardware.cpp
new file mode 100644
index 0000000..b24a0f2
--- /dev/null
+++ b/libs/surfaceflinger/GPUHardware/GPUHardware.cpp
@@ -0,0 +1,557 @@
+/*
+ * Copyright (C) 2008 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.
+ */
+
+#define LOG_TAG "SurfaceFlinger"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <math.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+
+#include <cutils/log.h>
+#include <cutils/properties.h>
+
+#include <utils/MemoryDealer.h>
+#include <utils/MemoryBase.h>
+#include <utils/MemoryHeapPmem.h>
+#include <utils/MemoryHeapBase.h>
+#include <utils/IPCThreadState.h>
+#include <utils/StopWatch.h>
+
+#include <ui/ISurfaceComposer.h>
+
+#include "VRamHeap.h"
+#include "GPUHardware.h"
+
+#if HAVE_ANDROID_OS
+#include <linux/android_pmem.h>
+#endif
+
+#include "GPUHardware/GPUHardware.h"
+
+/* 
+ * This file manages the GPU if there is one. The intent is that this code
+ * needs to be different for every devce. Currently there is no abstraction,
+ * but in the long term, this code needs to be refactored so that API and
+ * implementation are separated.
+ * 
+ * In this particular implementation, the GPU, its memory and register are
+ * managed here. Clients (such as OpenGL ES) request the GPU when then need
+ * it and are given a revokable heap containing the registers on memory. 
+ * 
+ */
+
+namespace android {
+// ---------------------------------------------------------------------------
+
+// size reserved for GPU surfaces
+// 1200 KB fits exactly:
+//  - two 320*480 16-bits double-buffered surfaces
+//  - one 320*480 32-bits double-buffered surface
+//  - one 320*240 16-bits double-bufferd, 4x anti-aliased surface
+static const int GPU_RESERVED_SIZE  = 1200 * 1024;
+
+static const int GPUR_SIZE          = 1 * 1024 * 1024;
+
+// ---------------------------------------------------------------------------
+
+/* 
+ * GPUHandle is a special IMemory given to the client. It represents their
+ * handle to the GPU. Once they give it up, they loose GPU access, or if
+ * they explicitely revoke their acces through the binder code 1000.
+ * In both cases, this triggers a callback to revoke()
+ * first, and then actually powers down the chip.
+ * 
+ * In the case of a misbehaving app, GPUHardware can ask for an immediate
+ * release of the GPU to the target process which should answer by calling
+ * code 1000 on GPUHandle. If it doesn't in a timely manner, the GPU will
+ * be revoked from under their feet.
+ * 
+ * We should never hold a strong reference on GPUHandle. In practice this
+ * shouldn't be a big issue though because clients should use code 1000 and
+ * not rely on the dtor being called.
+ * 
+ */
+
+class GPUHandle : public BnMemory
+{
+public:
+            GPUHandle(const sp<GPUHardware>& gpu, const sp<IMemoryHeap>& heap)
+                : mGPU(gpu), mClientHeap(heap) {
+            }
+    virtual ~GPUHandle();
+    virtual sp<IMemoryHeap> getMemory(ssize_t* offset, size_t* size) const;
+    virtual status_t onTransact(
+            uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags);
+    void setOwner(int owner) { mOwner = owner; }
+private:
+    void revokeNotification();
+    wp<GPUHardware> mGPU;
+    sp<IMemoryHeap> mClientHeap;
+    int mOwner;
+};
+
+GPUHandle::~GPUHandle() { 
+    //LOGD("GPUHandle %p released, revoking GPU", this);
+    revokeNotification(); 
+}
+
+void GPUHandle::revokeNotification()  {
+    sp<GPUHardware> hw(mGPU.promote());
+    if (hw != 0) {
+        hw->revoke(mOwner);
+    }
+}
+sp<IMemoryHeap> GPUHandle::getMemory(ssize_t* offset, size_t* size) const
+{
+    if (offset) *offset = 0;
+    if (size)   *size = mClientHeap !=0 ? mClientHeap->virtualSize() : 0;
+    return mClientHeap;
+}
+status_t GPUHandle::onTransact(
+        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    status_t err = BnMemory::onTransact(code, data, reply, flags);
+    if (err == UNKNOWN_TRANSACTION && code == 1000) {
+        int callingPid = IPCThreadState::self()->getCallingPid();
+        //LOGD("pid %d voluntarily revoking gpu", callingPid);
+        if (callingPid == mOwner) {
+            revokeNotification();
+            // we've revoked the GPU, don't do it again later when we
+            // are destroyed.
+            mGPU.clear();
+        } else {
+            LOGW("%d revoking someone else's gpu? (owner=%d)",
+                    callingPid, mOwner);            
+        }
+        err = NO_ERROR;
+    }
+    return err;
+}
+
+// ---------------------------------------------------------------------------
+
+class MemoryHeapRegs : public MemoryHeapPmem 
+{
+public:
+            MemoryHeapRegs(const wp<GPUHardware>& gpu, const sp<MemoryHeapBase>& heap);
+    virtual ~MemoryHeapRegs();
+    sp<IMemory> mapMemory(size_t offset, size_t size);
+    virtual void revoke();
+private:
+    wp<GPUHardware> mGPU;
+};
+
+MemoryHeapRegs::MemoryHeapRegs(const wp<GPUHardware>& gpu, const sp<MemoryHeapBase>& heap)
+    :  MemoryHeapPmem(heap), mGPU(gpu)
+{
+#if HAVE_ANDROID_OS
+    if (heapID()>0) {
+        /* this is where the GPU is powered on and the registers are mapped
+         * in the client */
+        //LOGD("ioctl(HW3D_GRANT_GPU)");
+        int err = ioctl(heapID(), HW3D_GRANT_GPU, base());
+        if (err) {
+            // it can happen if the master heap has been closed already
+            // in which case the GPU already is revoked (app crash for
+            // instance).
+            //LOGW("HW3D_GRANT_GPU failed (%s), mFD=%d, base=%p",
+            //        strerror(errno), heapID(), base());
+        }
+    }
+#endif
+}
+
+MemoryHeapRegs::~MemoryHeapRegs() 
+{
+}
+
+sp<IMemory> MemoryHeapRegs::mapMemory(size_t offset, size_t size)
+{
+    sp<GPUHandle> memory;
+    sp<GPUHardware> gpu = mGPU.promote();
+    if (heapID()>0 && gpu!=0) 
+        memory = new GPUHandle(gpu, this);
+    return memory;
+}
+
+void MemoryHeapRegs::revoke() 
+{
+    MemoryHeapPmem::revoke();
+#if HAVE_ANDROID_OS
+    if (heapID() > 0) {
+        //LOGD("ioctl(HW3D_REVOKE_GPU)");
+        int err = ioctl(heapID(), HW3D_REVOKE_GPU, base());
+        LOGE_IF(err, "HW3D_REVOKE_GPU failed (%s), mFD=%d, base=%p",
+                strerror(errno), heapID(), base());
+    }
+#endif
+}
+
+// ---------------------------------------------------------------------------
+
+class GPURegisterHeap : public PMemHeapInterface
+{
+public:
+    GPURegisterHeap(const sp<GPUHardware>& gpu)
+        : PMemHeapInterface("/dev/hw3d", GPUR_SIZE), mGPU(gpu)
+    {
+    }
+    virtual ~GPURegisterHeap() {
+    }
+    virtual sp<MemoryHeapPmem> createClientHeap() {
+        sp<MemoryHeapBase> parentHeap(this);
+        return new MemoryHeapRegs(mGPU, parentHeap);
+    }
+private:
+    wp<GPUHardware> mGPU;
+};
+
+/*****************************************************************************/
+
+GPUHardware::GPUHardware()
+    : mOwner(NO_OWNER)
+{
+}
+
+GPUHardware::~GPUHardware()
+{
+}
+
+sp<MemoryDealer> GPUHardware::request(int pid)
+{
+    sp<MemoryDealer> dealer;
+
+    LOGD("pid %d requesting gpu surface (current owner = %d)", pid, mOwner);
+
+    const int self_pid = getpid();
+    if (pid == self_pid) {
+        // can't use GPU from surfaceflinger's process
+        return dealer;
+    }
+
+    Mutex::Autolock _l(mLock);
+    
+    if (mOwner != pid) {
+        // someone already has the gpu.
+        takeBackGPULocked();
+
+        // releaseLocked() should be a no-op most of the time
+        releaseLocked();
+
+        requestLocked(); 
+    }
+
+    dealer = mAllocator;
+    mOwner = pid;
+    if (dealer == 0) {
+        mOwner = SURFACE_FAILED;
+    }
+    
+    LOGD_IF(dealer!=0, "gpu surface granted to pid %d", mOwner);
+    return dealer;
+}
+
+status_t GPUHardware::request(const sp<IGPUCallback>& callback,
+        ISurfaceComposer::gpu_info_t* gpu)
+{
+    sp<IMemory> gpuHandle;
+    IPCThreadState* ipc = IPCThreadState::self();
+    const int pid = ipc->getCallingPid();
+    const int self_pid = getpid();
+
+    LOGD("pid %d requesting gpu core (owner = %d)", pid, mOwner);
+
+    if (pid == self_pid) {
+        // can't use GPU from surfaceflinger's process
+        return PERMISSION_DENIED;
+    }
+
+    Mutex::Autolock _l(mLock);
+    if (mOwner != pid) {
+        // someone already has the gpu.
+        takeBackGPULocked();
+
+        // releaseLocked() should be a no-op most of the time
+        releaseLocked();
+
+        requestLocked(); 
+    }
+
+    if (mHeapR.isValid()) {
+        gpu->count = 2;
+        gpu->regions[0].region = mHeap0.map(true);
+        gpu->regions[0].reserved = mHeap0.reserved;
+        gpu->regions[1].region = mHeap1.map(true);
+        gpu->regions[1].reserved = mHeap1.reserved;
+        gpu->regs = mHeapR.map();
+        if (gpu->regs != 0) {
+            static_cast< GPUHandle* >(gpu->regs.get())->setOwner(pid);
+        }
+        mCallback = callback;
+        mOwner = pid;
+        //LOGD("gpu core granted to pid %d, handle base=%p",
+        //        mOwner, gpu->regs->pointer());
+    } else {
+        LOGW("couldn't grant gpu core to pid %d", pid);
+    }
+
+    return NO_ERROR;
+}
+
+void GPUHardware::revoke(int pid)
+{
+    Mutex::Autolock _l(mLock);
+    if (mOwner > 0) {
+        if (pid != mOwner) {
+            LOGW("GPU owned by %d, revoke from %d", mOwner, pid);
+            return;
+        }
+        //LOGD("revoke pid=%d, owner=%d", pid, mOwner);
+        // mOwner could be <0 if the same process acquired the GPU
+        // several times without releasing it first.
+        mCondition.signal();
+        releaseLocked(true);
+    }
+}
+
+status_t GPUHardware::friendlyRevoke()
+{
+    Mutex::Autolock _l(mLock);
+    takeBackGPULocked();
+    //LOGD("friendlyRevoke owner=%d", mOwner);
+    releaseLocked(true);
+    return NO_ERROR;
+}
+
+void GPUHardware::takeBackGPULocked()
+{
+    sp<IGPUCallback> callback = mCallback;
+    mCallback.clear();
+    if (callback != 0) {
+        callback->gpuLost(); // one-way
+        mCondition.waitRelative(mLock, ms2ns(250));
+    }
+}
+
+void GPUHardware::requestLocked()
+{
+    if (mAllocator == 0) {
+        GPUPart* part = 0;
+        sp<PMemHeap> surfaceHeap;
+        if (mHeap1.promote() == false) {
+            //LOGD("requestLocked: (1) creating new heap");
+            mHeap1.set(new PMemHeap("/dev/pmem_gpu1", 0, GPU_RESERVED_SIZE));
+        }
+        if (mHeap1.isValid()) {
+            //LOGD("requestLocked: (1) heap is valid");
+            // NOTE: if GPU1 is available we use it for our surfaces
+            // this could be device specific, so we should do something more
+            // generic
+            surfaceHeap = static_cast< PMemHeap* >( mHeap1.getHeap().get() );
+            part = &mHeap1;
+            if (mHeap0.promote() == false) {
+                //LOGD("requestLocked: (0) creating new heap");
+                mHeap0.set(new PMemHeap("/dev/pmem_gpu0"));
+            }
+        } else {
+            //LOGD("requestLocked: (1) heap is not valid");
+            // No GPU1, use GPU0 only
+            if (mHeap0.promote() == false) {
+                //LOGD("requestLocked: (0) creating new heap");
+                mHeap0.set(new PMemHeap("/dev/pmem_gpu0", 0, GPU_RESERVED_SIZE));
+            }
+            if (mHeap0.isValid()) {
+                //LOGD("requestLocked: (0) heap is valid");
+                surfaceHeap = static_cast< PMemHeap* >( mHeap0.getHeap().get() );
+                part = &mHeap0;
+            }
+        }
+        
+        if (mHeap0.isValid() || mHeap1.isValid()) {
+            if (mHeapR.promote() == false) {
+                //LOGD("requestLocked: (R) creating new register heap");
+                mHeapR.set(new GPURegisterHeap(this));
+            }
+        } else {
+            // we got nothing...
+            mHeap0.clear();
+            mHeap1.clear();
+        }
+
+        if (mHeapR.isValid() == false) {
+            //LOGD("requestLocked: (R) register heap not valid!!!");
+            // damn, couldn't get the gpu registers!
+            mHeap0.clear();
+            mHeap1.clear();
+            surfaceHeap.clear();
+            part = NULL;
+        }
+
+        if (surfaceHeap != 0 && part && part->getClientHeap()!=0) {
+            part->reserved = GPU_RESERVED_SIZE;
+            part->surface = true;
+            mAllocatorDebug = static_cast<SimpleBestFitAllocator*>(
+                    surfaceHeap->getAllocator().get());
+            mAllocator = new MemoryDealer(
+                    part->getClientHeap(),
+                    surfaceHeap->getAllocator());
+        }
+    }
+}
+
+void GPUHardware::releaseLocked(bool dispose)
+{
+    /* 
+     * if dispose is set, we will force the destruction of the heap,
+     * so it is given back to other systems, such as camera.
+     * Otherwise, we'll keep a weak pointer to it, this way we might be able
+     * to reuse it later if it's still around. 
+     */
+    //LOGD("revoking gpu from pid %d", mOwner);
+    mOwner = NO_OWNER;
+    mAllocator.clear();
+    mCallback.clear();
+
+    /* if we're asked for a full revoke, dispose only of the heap
+     * we're not using for surface (as we might need it while drawing) */
+    mHeap0.release(mHeap0.surface ? false : dispose);
+    mHeap1.release(mHeap1.surface ? false : dispose);
+    mHeapR.release(false);
+}
+
+// ----------------------------------------------------------------------------
+// for debugging / testing ...
+
+sp<SimpleBestFitAllocator> GPUHardware::getAllocator() const {
+    Mutex::Autolock _l(mLock);
+    sp<SimpleBestFitAllocator> allocator = mAllocatorDebug.promote();
+    return allocator;
+}
+
+void GPUHardware::unconditionalRevoke()
+{
+    Mutex::Autolock _l(mLock);
+    releaseLocked();
+}
+
+// ---------------------------------------------------------------------------
+
+
+GPUHardware::GPUPart::GPUPart()
+    : surface(false), reserved(0)
+{
+}
+
+GPUHardware::GPUPart::~GPUPart() {
+}
+    
+const sp<PMemHeapInterface>& GPUHardware::GPUPart::getHeap() const {
+    return mHeap;
+}
+
+const sp<MemoryHeapPmem>& GPUHardware::GPUPart::getClientHeap() const {
+    return mClientHeap;
+}
+
+bool GPUHardware::GPUPart::isValid() const {
+    return ((mHeap!=0) && (mHeap->base() != MAP_FAILED));
+}
+
+void GPUHardware::GPUPart::clear() 
+{
+    mHeap.clear();
+    mHeapWeak.clear();
+    mClientHeap.clear();
+    surface = false;
+}
+
+void GPUHardware::GPUPart::set(const sp<PMemHeapInterface>& heap) 
+{
+    mHeapWeak.clear();
+    if (heap!=0 && heap->base() == MAP_FAILED) {
+        mHeap.clear();
+        mClientHeap.clear();
+    } else { 
+        mHeap = heap;
+        mClientHeap = mHeap->createClientHeap();
+    }
+}
+
+bool GPUHardware::GPUPart::promote() 
+{
+    //LOGD("mHeapWeak=%p, mHeap=%p", mHeapWeak.unsafe_get(), mHeap.get());
+    if (mHeap == 0) {
+        mHeap = mHeapWeak.promote();
+    }
+    if (mHeap != 0) {
+        if (mClientHeap != 0) {
+            mClientHeap->revoke();
+        }
+        mClientHeap = mHeap->createClientHeap();
+    }  else {
+        surface = false;
+    }
+    return mHeap != 0;
+}
+
+sp<IMemory> GPUHardware::GPUPart::map(bool clear) 
+{
+    sp<IMemory> memory;
+    if (mClientHeap != NULL) {
+        memory = mClientHeap->mapMemory(0, mHeap->virtualSize());
+        if (clear && memory!=0) {
+            //StopWatch sw("memset");
+            memset(memory->pointer(), 0, memory->size());
+        }
+    }
+    return memory;
+}
+
+void GPUHardware::GPUPart::release(bool dispose)
+{
+    if (mClientHeap != 0) {
+        mClientHeap->revoke();
+        mClientHeap.clear();
+    }
+    if (dispose) {
+        if (mHeapWeak!=0 && mHeap==0) {
+            mHeap = mHeapWeak.promote();
+        }
+        if (mHeap != 0) {
+            mHeap->dispose();
+            mHeapWeak.clear();
+            mHeap.clear();
+        } else {
+            surface = false;
+        }
+    } else {
+        if (mHeap != 0) {
+            mHeapWeak = mHeap;
+            mHeap.clear();
+        }
+    }
+}
+
+// ---------------------------------------------------------------------------
+}; // namespace android
+
diff --git a/libs/surfaceflinger/GPUHardware/GPUHardware.h b/libs/surfaceflinger/GPUHardware/GPUHardware.h
new file mode 100644
index 0000000..9a78b99
--- /dev/null
+++ b/libs/surfaceflinger/GPUHardware/GPUHardware.h
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2008 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_GPU_HARDWARE_H
+#define ANDROID_GPU_HARDWARE_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/RefBase.h>
+#include <utils/threads.h>
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+class GPUHardwareInterface : public RefBase
+{
+public:
+    virtual void                revoke(int pid) = 0;
+    virtual sp<MemoryDealer>    request(int pid) = 0;
+    virtual status_t            request(const sp<IGPUCallback>& callback,
+            ISurfaceComposer::gpu_info_t* gpu) = 0;
+
+    virtual status_t            friendlyRevoke() = 0;
+    virtual void                unconditionalRevoke() = 0;
+    
+    // used for debugging only...
+    virtual sp<SimpleBestFitAllocator> getAllocator() const  = 0;
+    virtual pid_t getOwner() const = 0;
+};
+
+// ---------------------------------------------------------------------------
+
+class IMemory;
+class MemoryHeapPmem;
+class PMemHeap;
+
+class GPUHardware : public GPUHardwareInterface
+{
+public:
+            GPUHardware();
+    virtual ~GPUHardware();
+    
+    virtual void                revoke(int pid);
+    virtual sp<MemoryDealer>    request(int pid);
+    virtual status_t            request(const sp<IGPUCallback>& callback,
+            ISurfaceComposer::gpu_info_t* gpu);
+
+    virtual status_t            friendlyRevoke();
+    virtual void                unconditionalRevoke();
+    
+    // used for debugging only...
+    virtual sp<SimpleBestFitAllocator> getAllocator() const;
+    virtual pid_t getOwner() const { return mOwner; }
+    
+private:
+    enum {
+        NO_OWNER        = -1,
+        SURFACE_FAILED  = -2
+    };
+    
+    void requestLocked();
+    void releaseLocked(bool dispose = false);
+    void takeBackGPULocked();
+    
+    class GPUPart
+    {
+    public:
+        bool surface;
+        size_t reserved;
+        GPUPart();
+        ~GPUPart();
+        const sp<PMemHeapInterface>& getHeap() const;
+        const sp<MemoryHeapPmem>& getClientHeap() const;
+        bool isValid() const;
+        void clear();
+        void set(const sp<PMemHeapInterface>& heap);
+        bool promote();
+        sp<IMemory> map(bool clear = false);
+        void release(bool dispose);
+    private:
+        sp<PMemHeapInterface>   mHeap;
+        wp<PMemHeapInterface>   mHeapWeak;
+        sp<MemoryHeapPmem>      mClientHeap;
+    };
+    
+    mutable Mutex   mLock;
+    GPUPart         mHeap0; // SMI
+    GPUPart         mHeap1; // EBI1
+    GPUPart         mHeapR;
+    sp<MemoryDealer> mAllocator;
+    pid_t            mOwner;
+    sp<IGPUCallback> mCallback;
+    wp<SimpleBestFitAllocator> mAllocatorDebug;
+    
+    Condition       mCondition;
+};
+
+// ---------------------------------------------------------------------------
+}; // namespace android
+
+#endif // ANDROID_GPU_HARDWARE_H
diff --git a/libs/surfaceflinger/Layer.cpp b/libs/surfaceflinger/Layer.cpp
new file mode 100644
index 0000000..4f6bae1
--- /dev/null
+++ b/libs/surfaceflinger/Layer.cpp
@@ -0,0 +1,565 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "SurfaceFlinger"
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <cutils/properties.h>
+
+#include <utils/Errors.h>
+#include <utils/Log.h>
+#include <utils/StopWatch.h>
+
+#include <ui/PixelFormat.h>
+#include <ui/EGLDisplaySurface.h>
+
+#include "clz.h"
+#include "Layer.h"
+#include "LayerBitmap.h"
+#include "SurfaceFlinger.h"
+#include "VRamHeap.h"
+#include "DisplayHardware/DisplayHardware.h"
+
+
+#define DEBUG_RESIZE    0
+
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+const uint32_t Layer::typeInfo = LayerBaseClient::typeInfo | 4;
+const char* const Layer::typeID = "Layer";
+
+// ---------------------------------------------------------------------------
+
+Layer::Layer(SurfaceFlinger* flinger, DisplayID display, Client* c, int32_t i)
+    :   LayerBaseClient(flinger, display, c, i),
+        mSecure(false),
+        mFrontBufferIndex(1),
+        mNeedsBlending(true),
+        mResizeTransactionDone(false),
+        mTextureName(-1U), mTextureWidth(0), mTextureHeight(0)
+{
+    // no OpenGL operation is possible here, since we might not be
+    // in the OpenGL thread.
+}
+
+Layer::~Layer()
+{
+    client->free(clientIndex());
+    // this should always be called from the OpenGL thread
+    if (mTextureName != -1U) {
+        //glDeleteTextures(1, &mTextureName);
+        deletedTextures.add(mTextureName);
+    }
+}
+
+void Layer::initStates(uint32_t w, uint32_t h, uint32_t flags)
+{
+    LayerBase::initStates(w,h,flags);
+
+    if (flags & ISurfaceComposer::eDestroyBackbuffer)
+        lcblk->flags |= eNoCopyBack;
+}
+
+sp<LayerBaseClient::Surface> Layer::getSurface() const
+{
+    return mSurface;
+}
+
+status_t Layer::setBuffers( Client* client,
+                            uint32_t w, uint32_t h,
+                            PixelFormat format, uint32_t flags)
+{
+    PixelFormatInfo info;
+    status_t err = getPixelFormatInfo(format, &info);
+    if (err) return err;
+
+    // TODO: if eHardware is explicitely requested, we should fail
+    // on systems where we can't allocate memory that can be used with
+    // DMA engines for instance.
+
+    int memory_type = NATIVE_MEMORY_TYPE_PMEM;
+    
+    // pixel-alignment. the final alignment may be bigger because
+    // we always force a 4-byte aligned bpr.
+    uint32_t alignment = 1;
+
+    const uint32_t mask = ISurfaceComposer::eGPU | ISurfaceComposer::eSecure;
+    if ((flags & mask) == ISurfaceComposer::eGPU) {
+        // don't grant GPU memory if GPU is disabled
+        char value[PROPERTY_VALUE_MAX];
+        property_get("debug.egl.hw", value, "1");
+        if (atoi(value) != 0) {
+            flags |= ISurfaceComposer::eHardware;
+            memory_type = NATIVE_MEMORY_TYPE_GPU;
+            // TODO: this value should come from the h/w
+            alignment = 8; 
+        }
+    }
+
+    mSecure = (flags & ISurfaceComposer::eSecure) ? true : false;
+    mNeedsBlending = (info.h_alpha - info.l_alpha) > 0;
+    sp<MemoryDealer> allocators[2];
+    for (int i=0 ; i<2 ; i++) {
+        allocators[i] = client->createAllocator(memory_type);
+        if (allocators[i] == 0)
+            return NO_MEMORY;
+        mBuffers[i].init(allocators[i]);
+        int err = mBuffers[i].setBits(w, h, alignment, format, LayerBitmap::SECURE_BITS);
+        if (err != NO_ERROR)
+            return err;
+        mBuffers[i].clear(); // clear the bits for security
+        mBuffers[i].getInfo(lcblk->surface + i);
+    }
+
+    mSurface = new Surface(clientIndex(),
+            allocators[0]->getMemoryHeap(),
+            allocators[1]->getMemoryHeap(),
+            memory_type, mIdentity);
+
+    return NO_ERROR;
+}
+
+void Layer::reloadTexture(const Region& dirty)
+{
+    if (UNLIKELY(mTextureName == -1U)) {
+        // create the texture name the first time
+        // can't do that in the ctor, because it runs in another thread.
+        mTextureName = createTexture();
+    }
+    const GGLSurface& t(frontBuffer().surface());
+    loadTexture(dirty, mTextureName, t, mTextureWidth, mTextureHeight);
+}
+
+
+void Layer::onDraw(const Region& clip) const
+{
+    if (UNLIKELY(mTextureName == -1LU)) {
+        //LOGW("Layer %p doesn't have a texture", this);
+        // the texture has not been created yet, this Layer has
+        // in fact never been drawn into. this happens frequently with
+        // SurfaceView.
+        clearWithOpenGL(clip);
+        return;
+    }
+
+    const DisplayHardware& hw(graphicPlane(0).displayHardware());
+    const LayerBitmap& front(frontBuffer());
+    const GGLSurface& t(front.surface());
+
+    status_t err = NO_ERROR;
+    const int can_use_copybit = canUseCopybit();
+    if (can_use_copybit)  {
+        // StopWatch watch("copybit");
+        const State& s(drawingState());
+
+        copybit_image_t dst;
+        hw.getDisplaySurface(&dst);
+        const copybit_rect_t& drect
+            = reinterpret_cast<const copybit_rect_t&>(mTransformedBounds);
+
+        copybit_image_t src;
+        front.getBitmapSurface(&src);
+        copybit_rect_t srect = { 0, 0, t.width, t.height };
+
+        copybit_t* copybit = mFlinger->getBlitEngine();
+        copybit->set_parameter(copybit, COPYBIT_TRANSFORM, getOrientation());
+        copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, s.alpha);
+        copybit->set_parameter(copybit, COPYBIT_DITHER,
+                s.flags & ISurfaceComposer::eLayerDither ?
+                        COPYBIT_ENABLE : COPYBIT_DISABLE);
+
+        region_iterator it(clip);
+        err = copybit->stretch(copybit, &dst, &src, &drect, &srect, &it);
+    }
+
+    if (!can_use_copybit || err) {
+        drawWithOpenGL(clip, mTextureName, t);
+    }
+}
+
+status_t Layer::reallocateBuffer(int32_t index, uint32_t w, uint32_t h)
+{
+    LOGD_IF(DEBUG_RESIZE,
+                "reallocateBuffer (layer=%p), "
+                "requested (%dx%d), "
+                "index=%d, (%dx%d), (%dx%d)",
+                this,
+                int(w), int(h),
+                int(index),
+                int(mBuffers[0].width()), int(mBuffers[0].height()),
+                int(mBuffers[1].width()), int(mBuffers[1].height()));
+
+    status_t err = mBuffers[index].resize(w, h);
+    if (err == NO_ERROR) {
+        mBuffers[index].getInfo(lcblk->surface + index);
+    } else {
+        LOGE("resizing buffer %d to (%u,%u) failed [%08x] %s",
+            index, w, h, err, strerror(err));
+        // XXX: what to do, what to do? We could try to free some
+        // hidden surfaces, instead of killing this one?
+    }
+    return err;
+}
+
+uint32_t Layer::doTransaction(uint32_t flags)
+{
+    const Layer::State& front(drawingState());
+    const Layer::State& temp(currentState());
+
+    // the test front.{w|h} != temp.{w|h} is not enough because it is possible
+    // that the size changed back to its previous value before the buffer
+    // was resized (in the eLocked case below), in which case, we still
+    // need to execute the code below so the clients have a chance to be
+    // release. resze() deals with the fact that the size can be the same.
+
+    /*
+     *  Various states we could be in...
+
+         resize = state & eResizeRequested;
+         if (backbufferChanged) {
+             if (resize == 0) {
+                 // ERROR, the resized buffer doesn't have its resize flag set
+             } else if (resize == mask) {
+                 // ERROR one of the buffer has already been resized
+             } else if (resize == mask ^ eResizeRequested) {
+                 // ERROR, the resized buffer doesn't have its resize flag set
+             } else if (resize == eResizeRequested) {
+                 // OK, Normal case, proceed with resize
+             }
+         } else {
+             if (resize == 0) {
+                 // OK, nothing special, do nothing
+             } else if (resize == mask) {
+                 // restarted transaction, do nothing
+             } else if (resize == mask ^ eResizeRequested) {
+                 // restarted transaction, do nothing
+             } else if (resize == eResizeRequested) {
+                 // OK, size reset to previous value, proceed with resize
+             }
+         }
+     */
+
+    // Index of the back buffer
+    const bool backbufferChanged = (front.w != temp.w) || (front.h != temp.h);
+    const uint32_t state = lcblk->swapState;
+    const int32_t clientBackBufferIndex = layer_cblk_t::backBuffer(state);
+    const uint32_t mask = clientBackBufferIndex ? eResizeBuffer1 : eResizeBuffer0;
+    uint32_t resizeFlags = state & eResizeRequested;
+
+    if (UNLIKELY(backbufferChanged && (resizeFlags != eResizeRequested))) {
+        LOGE(   "backbuffer size changed, but both resize flags are not set! "
+                "(layer=%p), state=%08x, requested (%dx%d), drawing (%d,%d), "
+                "index=%d, (%dx%d), (%dx%d)",
+                this,  state,
+                int(temp.w), int(temp.h),
+                int(drawingState().w), int(drawingState().h),
+                int(clientBackBufferIndex),
+                int(mBuffers[0].width()), int(mBuffers[0].height()),
+                int(mBuffers[1].width()), int(mBuffers[1].height()));
+        // if we get there we're pretty screwed. the only reasonable
+        // thing to do is to pretend we should do the resize since
+        // backbufferChanged is set (this also will give a chance to
+        // client to get unblocked)
+        resizeFlags = eResizeRequested;
+    }
+
+    if (resizeFlags == eResizeRequested)  {
+        // NOTE: asserting that clientBackBufferIndex!=mFrontBufferIndex
+        // here, would be wrong and misleading because by this point
+        // mFrontBufferIndex has not been updated yet.
+
+        LOGD_IF(DEBUG_RESIZE,
+                    "resize (layer=%p), state=%08x, "
+                    "requested (%dx%d), "
+                    "drawing (%d,%d), "
+                    "index=%d, (%dx%d), (%dx%d)",
+                    this,  state,
+                    int(temp.w), int(temp.h),
+                    int(drawingState().w), int(drawingState().h),
+                    int(clientBackBufferIndex),
+                    int(mBuffers[0].width()), int(mBuffers[0].height()),
+                    int(mBuffers[1].width()), int(mBuffers[1].height()));
+
+        if (state & eLocked) {
+            // if the buffer is locked, we can't resize anything because
+            // - the backbuffer is currently in use by the user
+            // - the front buffer is being shown
+            // We just act as if the transaction didn't happen and we
+            // reschedule it later...
+            flags |= eRestartTransaction;
+        } else {
+            // This buffer needs to be resized
+            status_t err =
+                resize(clientBackBufferIndex, temp.w, temp.h, "transaction");
+            if (err == NO_ERROR) {
+                const uint32_t mask = clientBackBufferIndex ? eResizeBuffer1 : eResizeBuffer0;
+                android_atomic_and(~mask, &(lcblk->swapState));
+                // since a buffer became availlable, we can let the client go...
+                mFlinger->scheduleBroadcast(client);
+                mResizeTransactionDone = true;
+
+                // 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
+                // glitches upon orientation changes.
+                if (mFlinger->hasFreezeRequest()) {
+                    // if the surface is hidden, don't try to acquire the
+                    // freeze lock, since hidden surfaces may never redraw
+                    if (!(front.flags & ISurfaceComposer::eLayerHidden)) {
+                        mFreezeLock = mFlinger->getFreezeLock();
+                    }
+                }
+            }
+        }
+    }
+    
+    if (temp.sequence != front.sequence) {
+        if (temp.flags & ISurfaceComposer::eLayerHidden || temp.alpha == 0) {
+            // this surface is now hidden, so it shouldn't hold a freeze lock
+            // (it may never redraw, which is fine if it is hidden)
+            mFreezeLock.clear();
+        }
+    }
+        
+    return LayerBase::doTransaction(flags);
+}
+
+status_t Layer::resize(
+        int32_t clientBackBufferIndex,
+        uint32_t width, uint32_t height,
+        const char* what)
+{
+    /*
+     * handle resize (backbuffer and frontbuffer reallocation)
+     */
+
+    const LayerBitmap& clientBackBuffer(mBuffers[clientBackBufferIndex]);
+
+    // if the new (transaction) size is != from the the backbuffer
+    // then we need to reallocate the backbuffer
+    bool backbufferChanged = (clientBackBuffer.width()  != width) ||
+                             (clientBackBuffer.height() != height);
+
+    LOGD_IF(!backbufferChanged,
+            "(%s) eResizeRequested (layer=%p), but size not changed: "
+            "requested (%dx%d), drawing (%d,%d), current (%d,%d),"
+            "state=%08lx, index=%d, (%dx%d), (%dx%d)",
+            what, this,
+            int(width), int(height),
+            int(drawingState().w), int(drawingState().h),
+            int(currentState().w), int(currentState().h),
+            long(lcblk->swapState),
+            int(clientBackBufferIndex),
+            int(mBuffers[0].width()), int(mBuffers[0].height()),
+            int(mBuffers[1].width()), int(mBuffers[1].height()));
+
+    // this can happen when changing the size back and forth quickly
+    status_t err = NO_ERROR;
+    if (backbufferChanged) {
+        err = reallocateBuffer(clientBackBufferIndex, width, height);
+    }
+    if (UNLIKELY(err != NO_ERROR)) {
+        // couldn't reallocate the surface
+        android_atomic_write(eInvalidSurface, &lcblk->swapState);
+        memset(lcblk->surface+clientBackBufferIndex, 0, sizeof(surface_info_t));
+    }
+    return err;
+}
+
+void Layer::setSizeChanged(uint32_t w, uint32_t h)
+{
+    LOGD_IF(DEBUG_RESIZE,
+            "setSizeChanged w=%d, h=%d (old: w=%d, h=%d)",
+            w, h, mCurrentState.w, mCurrentState.h);
+    android_atomic_or(eResizeRequested, &(lcblk->swapState));
+}
+
+// ----------------------------------------------------------------------------
+// pageflip handling...
+// ----------------------------------------------------------------------------
+
+void Layer::lockPageFlip(bool& recomputeVisibleRegions)
+{
+    uint32_t state = android_atomic_or(eBusy, &(lcblk->swapState));
+    // preemptively block the client, because he might set
+    // eFlipRequested at any time and want to use this buffer
+    // for the next frame. This will be unset below if it
+    // turns out we didn't need it.
+
+    uint32_t mask = eInvalidSurface | eFlipRequested | eResizeRequested;
+    if (!(state & mask))
+        return;
+
+    if (UNLIKELY(state & eInvalidSurface)) {
+        // if eInvalidSurface is set, this means the surface
+        // became invalid during a transaction (NO_MEMORY for instance)
+        mFlinger->scheduleBroadcast(client);
+        return;
+    }
+
+    if (UNLIKELY(state & eFlipRequested)) {
+        uint32_t oldState;
+        mPostedDirtyRegion = post(&oldState, recomputeVisibleRegions);
+        if (oldState & eNextFlipPending) {
+            // Process another round (we know at least a buffer
+            // is ready for that client).
+            mFlinger->signalEvent();
+        }
+    }
+}
+
+Region Layer::post(uint32_t* previousSate, bool& recomputeVisibleRegions)
+{
+    // atomically swap buffers and (re)set eFlipRequested
+    int32_t oldValue, newValue;
+    layer_cblk_t * const lcblk = this->lcblk;
+    do {
+        oldValue = lcblk->swapState;
+            // get the current value
+
+        LOG_ASSERT(oldValue&eFlipRequested,
+            "eFlipRequested not set, yet we're flipping! (state=0x%08lx)",
+            long(oldValue));
+
+        newValue = (oldValue ^ eIndex);
+            // swap buffers
+
+        newValue &= ~(eFlipRequested | eNextFlipPending);
+            // clear eFlipRequested and eNextFlipPending
+
+        if (oldValue & eNextFlipPending)
+            newValue |= eFlipRequested;
+            // if eNextFlipPending is set (second buffer already has something
+            // in it) we need to reset eFlipRequested because the client
+            // might never do it
+
+    } while(android_atomic_cmpxchg(oldValue, newValue, &(lcblk->swapState)));
+    *previousSate = oldValue;
+
+    const int32_t index = (newValue & eIndex) ^ 1;
+    mFrontBufferIndex = index;
+
+    // ... post the new front-buffer
+    Region dirty(lcblk->region + index);
+    dirty.andSelf(frontBuffer().bounds());
+
+    //LOGI("Did post oldValue=%08lx, newValue=%08lx, mFrontBufferIndex=%u\n",
+    //    oldValue, newValue, mFrontBufferIndex);
+    //dirty.dump("dirty");
+
+    if (UNLIKELY(oldValue & eResizeRequested)) {
+
+        LOGD_IF(DEBUG_RESIZE,
+                     "post (layer=%p), state=%08x, "
+                     "index=%d, (%dx%d), (%dx%d)",
+                     this,  newValue,
+                     int(1-index),
+                     int(mBuffers[0].width()), int(mBuffers[0].height()),
+                     int(mBuffers[1].width()), int(mBuffers[1].height()));
+
+        // here, we just posted the surface and we have resolved
+        // the front/back buffer indices. The client is blocked, so
+        // it cannot start using the new backbuffer.
+
+        // If the backbuffer was resized in THIS round, we actually cannot
+        // resize the frontbuffer because it has *just* been drawn (and we
+        // would have nothing to draw). In this case we just skip the resize
+        // it'll happen after the next page flip or during the next
+        // transaction.
+
+        const uint32_t mask = (1-index) ? eResizeBuffer1 : eResizeBuffer0;
+        if (mResizeTransactionDone && (newValue & mask)) {
+            // Resize the layer's second buffer only if the transaction
+            // happened. It may not have happened yet if eResizeRequested
+            // was set immediately after the "transactionRequested" test,
+            // in which case the drawing state's size would be wrong.
+            mFreezeLock.clear();
+            const Layer::State& s(drawingState());
+            if (resize(1-index, s.w, s.h, "post") == NO_ERROR) {
+                do {
+                    oldValue = lcblk->swapState;
+                    if ((oldValue & eResizeRequested) == eResizeRequested) {
+                        // ugh, another resize was requested since we processed
+                        // the first buffer, don't free the client, and let
+                        // the next transaction handle everything.
+                        break;
+                    }
+                    newValue = oldValue & ~mask;
+                } while(android_atomic_cmpxchg(oldValue, newValue, &(lcblk->swapState)));
+            }
+            mResizeTransactionDone = false;
+            recomputeVisibleRegions = true;
+            invalidate = true;
+        }
+    }
+
+    reloadTexture(dirty);
+
+    return dirty;
+}
+
+Point Layer::getPhysicalSize() const
+{
+    const LayerBitmap& front(frontBuffer());
+    return Point(front.width(), front.height());
+}
+
+void Layer::unlockPageFlip(
+        const Transform& planeTransform, Region& outDirtyRegion)
+{
+    Region dirtyRegion(mPostedDirtyRegion);
+    if (!dirtyRegion.isEmpty()) {
+        mPostedDirtyRegion.clear();
+        // The dirty region is given in the layer's coordinate space
+        // transform the dirty region by the surface's transformation
+        // and the global transformation.
+        const Layer::State& s(drawingState());
+        const Transform tr(planeTransform * s.transform);
+        dirtyRegion = tr.transform(dirtyRegion);
+
+        // At this point, the dirty region is in screen space.
+        // Make sure it's constrained by the visible region (which
+        // is in screen space as well).
+        dirtyRegion.andSelf(visibleRegionScreen);
+        outDirtyRegion.orSelf(dirtyRegion);
+
+        // client could be blocked, so signal them so they get a
+        // chance to reevaluate their condition.
+        mFlinger->scheduleBroadcast(client);
+    }
+}
+
+void Layer::finishPageFlip()
+{
+    if (LIKELY(!(lcblk->swapState & eInvalidSurface))) {
+        LOGE_IF(!(lcblk->swapState & eBusy),
+                "layer %p wasn't locked!", this);
+        android_atomic_and(~eBusy, &(lcblk->swapState));
+    }
+    mFlinger->scheduleBroadcast(client);
+}
+
+
+// ---------------------------------------------------------------------------
+
+
+}; // namespace android
diff --git a/libs/surfaceflinger/Layer.h b/libs/surfaceflinger/Layer.h
new file mode 100644
index 0000000..2867f2b
--- /dev/null
+++ b/libs/surfaceflinger/Layer.h
@@ -0,0 +1,120 @@
+/*
+ * 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_LAYER_H
+#define ANDROID_LAYER_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <ui/PixelFormat.h>
+
+#include <private/ui/SharedState.h>
+#include <private/ui/LayerState.h>
+
+#include <pixelflinger/pixelflinger.h>
+
+#include "LayerBitmap.h"
+#include "LayerBase.h"
+#include "Transform.h"
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+class Client;
+class LayerBitmap;
+class MemoryDealer;
+class FreezeLock;
+
+// ---------------------------------------------------------------------------
+
+class Layer : public LayerBaseClient
+{
+public:    
+    static const uint32_t typeInfo;
+    static const char* const typeID;
+    virtual char const* getTypeID() const { return typeID; }
+    virtual uint32_t getTypeInfo() const { return typeInfo; }
+
+                 Layer(SurfaceFlinger* flinger, DisplayID display,
+                         Client* c, int32_t i);
+
+        virtual ~Layer();
+
+    inline PixelFormat pixelFormat() const {
+        return frontBuffer().pixelFormat();
+    }
+
+    status_t setBuffers(    Client* client,
+                            uint32_t w, uint32_t h,
+                            PixelFormat format, uint32_t flags=0);
+
+    virtual void onDraw(const Region& clip) const;
+    virtual void initStates(uint32_t w, uint32_t h, uint32_t flags);
+    virtual void setSizeChanged(uint32_t w, uint32_t h);
+    virtual uint32_t doTransaction(uint32_t transactionFlags);
+    virtual Point getPhysicalSize() const;
+    virtual void lockPageFlip(bool& recomputeVisibleRegions);
+    virtual void unlockPageFlip(const Transform& planeTransform, Region& outDirtyRegion);
+    virtual void finishPageFlip();
+    virtual bool needsBlending() const      { return mNeedsBlending; }
+    virtual bool isSecure() const           { return mSecure; }
+    virtual GLuint getTextureName() const   { return mTextureName; }
+    virtual sp<Surface> getSurface() const;
+
+    const LayerBitmap& getBuffer(int i) const { return mBuffers[i]; }
+          LayerBitmap& getBuffer(int i)       { return mBuffers[i]; }
+
+    // only for debugging
+    const sp<FreezeLock>&  getFreezeLock() const { return mFreezeLock; }
+
+private:
+    inline const LayerBitmap&
+            frontBuffer() const { return getBuffer(mFrontBufferIndex); }
+    inline LayerBitmap&
+            frontBuffer()       { return getBuffer(mFrontBufferIndex); }
+    inline const LayerBitmap&
+            backBuffer() const  { return getBuffer(1-mFrontBufferIndex); }
+    inline LayerBitmap&
+            backBuffer()        { return getBuffer(1-mFrontBufferIndex); }
+
+    void reloadTexture(const Region& dirty);
+
+    status_t resize(int32_t index, uint32_t w, uint32_t h, const char* what);
+    Region post(uint32_t* oldState, bool& recomputeVisibleRegions);
+    status_t reallocateBuffer(int32_t index, uint32_t w, uint32_t h);
+
+    sp<Surface>             mSurface;
+
+            bool            mSecure;
+            LayerBitmap     mBuffers[2];
+            int32_t         mFrontBufferIndex;
+            bool            mNeedsBlending;
+            bool            mResizeTransactionDone;
+            Region          mPostedDirtyRegion;
+            sp<FreezeLock>  mFreezeLock;
+            
+            GLuint          mTextureName;
+            GLuint          mTextureWidth;
+            GLuint          mTextureHeight;
+};
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // ANDROID_LAYER_H
diff --git a/libs/surfaceflinger/LayerBase.cpp b/libs/surfaceflinger/LayerBase.cpp
new file mode 100644
index 0000000..17c9f42
--- /dev/null
+++ b/libs/surfaceflinger/LayerBase.cpp
@@ -0,0 +1,700 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "SurfaceFlinger"
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Errors.h>
+#include <utils/Log.h>
+
+#include "clz.h"
+#include "LayerBase.h"
+#include "LayerBlur.h"
+#include "SurfaceFlinger.h"
+#include "DisplayHardware/DisplayHardware.h"
+
+
+// We don't honor the premultipliad 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 {
+
+// ---------------------------------------------------------------------------
+
+const uint32_t LayerBase::typeInfo = 1;
+const char* const LayerBase::typeID = "LayerBase";
+
+const uint32_t LayerBaseClient::typeInfo = LayerBase::typeInfo | 2;
+const char* const LayerBaseClient::typeID = "LayerBaseClient";
+
+// ---------------------------------------------------------------------------
+
+Vector<GLuint> LayerBase::deletedTextures; 
+
+int32_t LayerBase::sIdentity = 0;
+
+LayerBase::LayerBase(SurfaceFlinger* flinger, DisplayID display)
+    : dpy(display), invalidate(false),
+      mFlinger(flinger),
+      mTransformed(false),
+      mOrientation(0),
+      mCanUseCopyBit(false),
+      mTransactionFlags(0),
+      mPremultipliedAlpha(true),
+      mIdentity(uint32_t(android_atomic_inc(&sIdentity)))
+{
+    const DisplayHardware& hw(flinger->graphicPlane(0).displayHardware());
+    mFlags = hw.getFlags();
+}
+
+LayerBase::~LayerBase()
+{
+}
+
+const GraphicPlane& LayerBase::graphicPlane(int dpy) const
+{ 
+    return mFlinger->graphicPlane(dpy);
+}
+
+GraphicPlane& LayerBase::graphicPlane(int dpy)
+{
+    return mFlinger->graphicPlane(dpy); 
+}
+
+void LayerBase::initStates(uint32_t w, uint32_t h, uint32_t flags)
+{
+    uint32_t layerFlags = 0;
+    if (flags & ISurfaceComposer::eHidden)
+        layerFlags = ISurfaceComposer::eLayerHidden;
+
+    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.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;
+    mDrawingState = mCurrentState;
+    if (skipSize) {
+        mDrawingState.w = w;
+        mDrawingState.h = h;
+    }
+}
+bool LayerBase::requestTransaction() {
+    int32_t old = setTransactionFlags(eTransactionNeeded);
+    return ((old & eTransactionNeeded) == 0);
+}
+uint32_t LayerBase::getTransactionFlags(uint32_t flags) {
+    return android_atomic_and(~flags, &mTransactionFlags) & flags;
+}
+uint32_t LayerBase::setTransactionFlags(uint32_t flags) {
+    return android_atomic_or(flags, &mTransactionFlags);
+}
+
+void LayerBase::setSizeChanged(uint32_t w, uint32_t h) {
+}
+
+bool LayerBase::setPosition(int32_t x, int32_t y) {
+    if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y)
+        return false;
+    mCurrentState.sequence++;
+    mCurrentState.transform.set(x, y);
+    requestTransaction();
+    return true;
+}
+bool LayerBase::setLayer(uint32_t z) {
+    if (mCurrentState.z == z)
+        return false;
+    mCurrentState.sequence++;
+    mCurrentState.z = z;
+    requestTransaction();
+    return true;
+}
+bool LayerBase::setSize(uint32_t w, uint32_t h) {
+    if (mCurrentState.w == w && mCurrentState.h == h)
+        return false;
+    setSizeChanged(w, h);
+    mCurrentState.w = w;
+    mCurrentState.h = h;
+    requestTransaction();
+    return true;
+}
+bool LayerBase::setAlpha(uint8_t alpha) {
+    if (mCurrentState.alpha == alpha)
+        return false;
+    mCurrentState.sequence++;
+    mCurrentState.alpha = alpha;
+    requestTransaction();
+    return true;
+}
+bool LayerBase::setMatrix(const layer_state_t::matrix22_t& matrix) {
+    // TODO: check the matrix has changed
+    mCurrentState.sequence++;
+    mCurrentState.transform.set(
+            matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
+    requestTransaction();
+    return true;
+}
+bool LayerBase::setTransparentRegionHint(const Region& transparent) {
+    // TODO: check the region has changed
+    mCurrentState.sequence++;
+    mCurrentState.transparentRegion = transparent;
+    requestTransaction();
+    return true;
+}
+bool LayerBase::setFlags(uint8_t flags, uint8_t mask) {
+    const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
+    if (mCurrentState.flags == newFlags)
+        return false;
+    mCurrentState.sequence++;
+    mCurrentState.flags = newFlags;
+    requestTransaction();
+    return true;
+}
+
+Rect LayerBase::visibleBounds() const
+{
+    return mTransformedBounds;
+}      
+
+void LayerBase::setVisibleRegion(const Region& visibleRegion) {
+    // always called from main thread
+    visibleRegionScreen = visibleRegion;
+}
+
+void LayerBase::setCoveredRegion(const Region& coveredRegion) {
+    // always called from main thread
+    coveredRegionScreen = coveredRegion;
+}
+
+uint32_t LayerBase::doTransaction(uint32_t flags)
+{
+    const Layer::State& front(drawingState());
+    const Layer::State& temp(currentState());
+
+    if (temp.sequence != front.sequence) {
+        // invalidate and recompute the visible regions if needed
+        flags |= eVisibleRegion;
+        this->invalidate = true;
+    }
+    
+    // Commit the transaction
+    commitTransaction(flags & eRestartTransaction);
+    return flags;
+}
+
+Point LayerBase::getPhysicalSize() const
+{
+    const Layer::State& front(drawingState());
+    return Point(front.w, front.h);
+}
+
+void LayerBase::validateVisibility(const Transform& planeTransform)
+{
+    const Layer::State& s(drawingState());
+    const Transform tr(planeTransform * s.transform);
+    const bool transformed = tr.transformed();
+   
+    const Point size(getPhysicalSize());
+    uint32_t w = size.x;
+    uint32_t h = size.y;    
+    tr.transform(mVertices[0], 0, 0);
+    tr.transform(mVertices[1], 0, h);
+    tr.transform(mVertices[2], w, h);
+    tr.transform(mVertices[3], w, 0);
+    if (UNLIKELY(transformed)) {
+        // NOTE: here we could also punt if we have too many rectangles
+        // in the transparent region
+        if (tr.preserveRects()) {
+            // transform the transparent region
+            transparentRegionScreen = tr.transform(s.transparentRegion);
+        } else {
+            // transformation too complex, can't do the transparent region
+            // optimization.
+            transparentRegionScreen.clear();
+        }
+    } else {
+        transparentRegionScreen = s.transparentRegion;
+    }
+
+    // cache a few things...
+    mOrientation = tr.getOrientation();
+    mTransformedBounds = tr.makeBounds(w, h);
+    mTransformed = transformed;
+    mLeft = tr.tx();
+    mTop  = tr.ty();
+
+    // see if we can/should use 2D h/w with the new configuration
+    mCanUseCopyBit = false;
+    copybit_t* copybit = mFlinger->getBlitEngine();
+    if (copybit) { 
+        const int step = copybit->get(copybit, COPYBIT_ROTATION_STEP_DEG);
+        const int scaleBits = copybit->get(copybit, COPYBIT_SCALING_FRAC_BITS);
+        mCanUseCopyBit = true;
+        if ((mOrientation < 0) && (step > 1)) {
+            // arbitrary orientations not supported
+            mCanUseCopyBit = false;
+        } else if ((mOrientation > 0) && (step > 90)) {
+            // 90 deg rotations not supported
+            mCanUseCopyBit = false;
+        } else if ((tr.getType() & SkMatrix::kScale_Mask) && (scaleBits < 12)) { 
+            // arbitrary scaling not supported
+            mCanUseCopyBit = false;
+        }
+#if HONOR_PREMULTIPLIED_ALPHA 
+        else if (needsBlending() && mPremultipliedAlpha) {
+            // pre-multiplied alpha not supported
+            mCanUseCopyBit = false;
+        }
+#endif
+        else {
+            // here, we determined we can use copybit
+            if (tr.getType() & SkMatrix::kScale_Mask) {
+                // and we have scaling
+                if (!transparentRegionScreen.isRect()) {
+                    // we punt because blending is cheap (h/w) and the region is
+                    // complex, which may causes artifacts when copying
+                    // scaled content
+                    transparentRegionScreen.clear();
+                }
+            }
+        }
+    }
+}
+
+void LayerBase::lockPageFlip(bool& recomputeVisibleRegions)
+{
+}
+
+void LayerBase::unlockPageFlip(
+        const Transform& planeTransform, Region& outDirtyRegion)
+{
+}
+
+void LayerBase::finishPageFlip()
+{
+}
+
+void LayerBase::drawRegion(const Region& reg) const
+{
+    Region::iterator iterator(reg);
+    if (iterator) {
+        Rect r;
+        const DisplayHardware& hw(graphicPlane(0).displayHardware());
+        const int32_t fbWidth  = hw.getWidth();
+        const int32_t fbHeight = hw.getHeight();
+        const GLshort vertices[][2] = { { 0, 0 }, { fbWidth, 0 }, 
+                { fbWidth, fbHeight }, { 0, fbHeight }  };
+        glVertexPointer(2, GL_SHORT, 0, vertices);
+        while (iterator.iterate(&r)) {
+            const GLint sy = fbHeight - (r.top + r.height());
+            glScissor(r.left, sy, r.width(), r.height());
+            glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 
+        }
+    }
+}
+
+void LayerBase::draw(const Region& inClip) const
+{
+    // invalidate the region we'll update
+    Region clip(inClip);  // copy-on-write, so no-op most of the time
+
+    // Remove the transparent area from the clipping region
+    const State& s = drawingState();
+    if (LIKELY(!s.transparentRegion.isEmpty())) {
+        clip.subtract(transparentRegionScreen);
+        if (clip.isEmpty()) {
+            // usually this won't happen because this should be taken care of
+            // by SurfaceFlinger::computeVisibleRegions()
+            return;
+        }        
+    }
+    onDraw(clip);
+
+    /*
+    glDisable(GL_TEXTURE_2D);
+    glDisable(GL_DITHER);
+    glEnable(GL_BLEND);
+    glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+    glColor4x(0, 0x8000, 0, 0x10000);
+    drawRegion(transparentRegionScreen);
+    glDisable(GL_BLEND);
+    */
+}
+
+GLuint LayerBase::createTexture() const
+{
+    GLuint textureName = -1;
+    glGenTextures(1, &textureName);
+    glBindTexture(GL_TEXTURE_2D, textureName);
+    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+    if (mFlags & DisplayHardware::SLOW_CONFIG) {
+        glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+        glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    } else {
+        glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+        glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+    }
+    return textureName;
+}
+
+void LayerBase::clearWithOpenGL(const Region& clip) const
+{
+    const DisplayHardware& hw(graphicPlane(0).displayHardware());
+    const uint32_t fbHeight = hw.getHeight();
+    glColor4x(0,0,0,0);
+    glDisable(GL_TEXTURE_2D);
+    glDisable(GL_BLEND);
+    glDisable(GL_DITHER);
+    Rect r;
+    Region::iterator iterator(clip);
+    if (iterator) {
+        glVertexPointer(2, GL_FIXED, 0, mVertices);
+        while (iterator.iterate(&r)) {
+            const GLint sy = fbHeight - (r.top + r.height());
+            glScissor(r.left, sy, r.width(), r.height());
+            glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 
+        }
+    }
+}
+
+void LayerBase::drawWithOpenGL(const Region& clip,
+        GLint textureName, const GGLSurface& t) const
+{
+    const DisplayHardware& hw(graphicPlane(0).displayHardware());
+    const uint32_t fbHeight = hw.getHeight();
+    const State& s(drawingState());
+
+    // bind our texture
+    validateTexture(textureName);
+    glEnable(GL_TEXTURE_2D);
+
+    // Dithering...
+    if (s.flags & ISurfaceComposer::eLayerDither) {
+        glEnable(GL_DITHER);
+    } else {
+        glDisable(GL_DITHER);
+    }
+
+    if (UNLIKELY(s.alpha < 0xFF)) {
+        // We have an alpha-modulation. We need to modulate all
+        // texture components by alpha because we're always using 
+        // premultiplied alpha.
+        
+        // If the texture doesn't have an alpha channel we can
+        // use REPLACE and switch to non premultiplied-alpha
+        // blending (SRCA/ONE_MINUS_SRCA).
+        
+        GLenum env, src;
+        if (needsBlending()) {
+            env = GL_MODULATE;
+            src = mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA;
+        } else {
+            env = GL_REPLACE;
+            src = GL_SRC_ALPHA;
+        }
+        const GGLfixed alpha = (s.alpha << 16)/255;
+        glColor4x(alpha, alpha, alpha, alpha);
+        glEnable(GL_BLEND);
+        glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA);
+        glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, env);
+    } else {
+        glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+        if (needsBlending()) {
+            GLenum src = mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA;
+            glEnable(GL_BLEND);
+            glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA);
+            glColor4x(0x10000, 0x10000, 0x10000, 0x10000);
+        } else {
+            glDisable(GL_BLEND);
+        }
+    }
+
+    if (UNLIKELY(transformed()
+            || !(mFlags & DisplayHardware::DRAW_TEXTURE_EXTENSION) )) 
+    {
+        //StopWatch watch("GL transformed");
+        Region::iterator iterator(clip);
+        if (iterator) {
+            // always use high-quality filtering with fast configurations
+            bool fast = !(mFlags & DisplayHardware::SLOW_CONFIG);
+            if (!fast && s.flags & ISurfaceComposer::eLayerFilter) {
+                glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+                glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+            }            
+            const GLfixed texCoords[4][2] = {
+                    { 0,        0 },
+                    { 0,        0x10000 },
+                    { 0x10000,  0x10000 },
+                    { 0x10000,  0 }
+            };
+
+            glMatrixMode(GL_TEXTURE);
+            glLoadIdentity();
+            if (!(mFlags & DisplayHardware::NPOT_EXTENSION)) {
+                // find the smalest power-of-two that will accomodate our surface
+                GLuint tw = 1 << (31 - clz(t.width));
+                GLuint th = 1 << (31 - clz(t.height));
+                if (tw < t.width)  tw <<= 1;
+                if (th < t.height) th <<= 1;
+                // this divide should be relatively fast because it's
+                // a power-of-two (optimized path in libgcc)
+                GLfloat ws = GLfloat(t.width) /tw;
+                GLfloat hs = GLfloat(t.height)/th;
+                glScalef(ws, hs, 1.0f);
+            }
+
+            glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+            glVertexPointer(2, GL_FIXED, 0, mVertices);
+            glTexCoordPointer(2, GL_FIXED, 0, texCoords);
+
+            Rect r;
+            while (iterator.iterate(&r)) {
+                const GLint sy = fbHeight - (r.top + r.height());
+                glScissor(r.left, sy, r.width(), r.height());
+                glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 
+            }
+
+            if (!fast && s.flags & ISurfaceComposer::eLayerFilter) {
+                glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+                glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+            }
+            glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+        }
+    } else {
+        Region::iterator iterator(clip);
+        if (iterator) {
+            Rect r;
+            GLint crop[4] = { 0, t.height, t.width, -t.height };
+            glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, crop);
+            int x = tx();
+            int y = ty();
+            y = fbHeight - (y + t.height);
+            while (iterator.iterate(&r)) {
+                const GLint sy = fbHeight - (r.top + r.height());
+                glScissor(r.left, sy, r.width(), r.height());
+                glDrawTexiOES(x, y, 0, t.width, t.height);
+            }
+        }
+    }
+}
+
+void LayerBase::validateTexture(GLint textureName) const
+{
+    glBindTexture(GL_TEXTURE_2D, textureName);
+    // TODO: reload the texture if needed
+    // this is currently done in loadTexture() below
+}
+
+void LayerBase::loadTexture(const Region& dirty,
+        GLint textureName, const GGLSurface& t,
+        GLuint& textureWidth, GLuint& textureHeight) const
+{
+    // TODO: defer the actual texture reload until LayerBase::validateTexture
+    // is called.
+
+    uint32_t flags = mFlags;
+    glBindTexture(GL_TEXTURE_2D, textureName);
+
+    GLuint tw = t.width;
+    GLuint th = t.height;
+
+    /*
+     * In OpenGL ES we can't specify a stride with glTexImage2D (however,
+     * GL_UNPACK_ALIGNMENT is 4, which in essence allows a limited form of
+     * stride).
+     * So if the stride here isn't representable with GL_UNPACK_ALIGNMENT, we
+     * need to do something reasonable (here creating a bigger texture).
+     * 
+     * extra pixels = (((stride - width) * pixelsize) / GL_UNPACK_ALIGNMENT);
+     * 
+     * This situation doesn't happen often, but some h/w have a limitation
+     * for their framebuffer (eg: must be multiple of 8 pixels), and
+     * we need to take that into account when using these buffers as
+     * textures.
+     *
+     * This should never be a problem with POT textures
+     */
+
+    tw += (((t.stride - tw) * bytesPerPixel(t.format)) / 4);
+
+    /*
+     * round to POT if needed 
+     */
+    
+    GLuint texture_w = tw;
+    GLuint texture_h = th;
+    if (!(flags & DisplayHardware::NPOT_EXTENSION)) {
+        // find the smalest power-of-two that will accomodate our surface
+        texture_w = 1 << (31 - clz(t.width));
+        texture_h = 1 << (31 - clz(t.height));
+        if (texture_w < t.width)  texture_w <<= 1;
+        if (texture_h < t.height) texture_h <<= 1;
+        if (texture_w != tw || texture_h != th) {
+            // we can't use DIRECT_TEXTURE since we changed the size
+            // of the texture
+            flags &= ~DisplayHardware::DIRECT_TEXTURE;
+        }
+    }
+
+    if (flags & DisplayHardware::DIRECT_TEXTURE) {
+        // here we're guaranteed that texture_{w|h} == t{w|h}
+        if (t.format == GGL_PIXEL_FORMAT_RGB_565) {
+            glTexImage2D(GL_DIRECT_TEXTURE_2D_QUALCOMM, 0,
+                    GL_RGB, tw, th, 0,
+                    GL_RGB, GL_UNSIGNED_SHORT_5_6_5, t.data);
+        } else if (t.format == GGL_PIXEL_FORMAT_RGBA_4444) {
+            glTexImage2D(GL_DIRECT_TEXTURE_2D_QUALCOMM, 0,
+                    GL_RGBA, tw, th, 0,
+                    GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, t.data);
+        } else if (t.format == GGL_PIXEL_FORMAT_RGBA_8888) {
+            glTexImage2D(GL_DIRECT_TEXTURE_2D_QUALCOMM, 0,
+                    GL_RGBA, tw, th, 0,
+                    GL_RGBA, GL_UNSIGNED_BYTE, t.data);
+        } else {
+            // oops, we don't handle this format, try the regular path
+            goto regular;
+        }
+        textureWidth = tw;
+        textureHeight = th;
+    } else {
+regular:
+        Rect bounds(dirty.bounds());
+        GLvoid* data = 0;
+        if (texture_w!=textureWidth || texture_w!=textureHeight) {
+            // texture size changed, we need to create a new one
+
+            if (!textureWidth || !textureHeight) {
+                // this is the first time, load the whole texture
+                if (texture_w==tw && texture_h==th) {
+                    // we can do it one pass
+                    data = t.data;
+                } else {
+                    // we have to create the texture first because it
+                    // doesn't match the size of the buffer
+                    bounds.set(Rect(tw, th));
+                }
+            }
+
+            if (t.format == GGL_PIXEL_FORMAT_RGB_565) {
+                glTexImage2D(GL_TEXTURE_2D, 0,
+                        GL_RGB, tw, th, 0,
+                        GL_RGB, GL_UNSIGNED_SHORT_5_6_5, data);
+            } else if (t.format == GGL_PIXEL_FORMAT_RGBA_4444) {
+                glTexImage2D(GL_TEXTURE_2D, 0,
+                        GL_RGBA, tw, th, 0,
+                        GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, data);
+            } else if (t.format == GGL_PIXEL_FORMAT_RGBA_8888) {
+                glTexImage2D(GL_TEXTURE_2D, 0,
+                        GL_RGBA, tw, th, 0,
+                        GL_RGBA, GL_UNSIGNED_BYTE, data);
+            } else if ( t.format == GGL_PIXEL_FORMAT_YCbCr_422_SP ||
+                        t.format == GGL_PIXEL_FORMAT_YCbCr_420_SP) {
+                // just show the Y plane of YUV buffers
+                data = t.data;
+                glTexImage2D(GL_TEXTURE_2D, 0,
+                        GL_LUMINANCE, tw, th, 0,
+                        GL_LUMINANCE, GL_UNSIGNED_BYTE, data);
+            }
+            textureWidth = tw;
+            textureHeight = th;
+        }
+        if (!data) {
+            if (t.format == GGL_PIXEL_FORMAT_RGB_565) {
+                glTexSubImage2D(GL_TEXTURE_2D, 0,
+                        0, bounds.top, t.width, bounds.height(),
+                        GL_RGB, GL_UNSIGNED_SHORT_5_6_5,
+                        t.data + bounds.top*t.width*2);
+            } else if (t.format == GGL_PIXEL_FORMAT_RGBA_4444) {
+                glTexSubImage2D(GL_TEXTURE_2D, 0,
+                        0, bounds.top, t.width, bounds.height(),
+                        GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4,
+                        t.data + bounds.top*t.width*2);
+            } else if (t.format == GGL_PIXEL_FORMAT_RGBA_8888) {
+                glTexSubImage2D(GL_TEXTURE_2D, 0,
+                        0, bounds.top, t.width, bounds.height(),
+                        GL_RGBA, GL_UNSIGNED_BYTE,
+                        t.data + bounds.top*t.width*4);
+            }
+        }
+    }
+}
+
+bool LayerBase::canUseCopybit() const
+{
+    return mCanUseCopyBit;
+}
+
+// ---------------------------------------------------------------------------
+
+LayerBaseClient::LayerBaseClient(SurfaceFlinger* flinger, DisplayID display,
+        Client* c, int32_t i)
+    : LayerBase(flinger, display), client(c),
+      lcblk( c ? &(c->ctrlblk->layers[i]) : 0 ),
+      mIndex(i)
+{
+    if (client) {
+        client->bindLayer(this, i);
+
+        // Initialize this layer's control block
+        memset(this->lcblk, 0, sizeof(layer_cblk_t));
+        this->lcblk->identity = mIdentity;
+        Region::writeEmpty(&(this->lcblk->region[0]), sizeof(flat_region_t));
+        Region::writeEmpty(&(this->lcblk->region[1]), sizeof(flat_region_t));
+    }
+}
+
+LayerBaseClient::~LayerBaseClient()
+{
+    if (client) {
+        client->free(mIndex);
+    }
+}
+
+int32_t LayerBaseClient::serverIndex() const {
+    if (client) {
+        return (client->cid<<16)|mIndex;
+    }
+    return 0xFFFF0000 | mIndex;
+}
+
+sp<LayerBaseClient::Surface> LayerBaseClient::getSurface() const
+{
+    return new Surface(clientIndex(), mIdentity);
+}
+
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
diff --git a/libs/surfaceflinger/LayerBase.h b/libs/surfaceflinger/LayerBase.h
new file mode 100644
index 0000000..10c1bc1
--- /dev/null
+++ b/libs/surfaceflinger/LayerBase.h
@@ -0,0 +1,271 @@
+/*
+ * 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_LAYER_BASE_H
+#define ANDROID_LAYER_BASE_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <private/ui/LayerState.h>
+
+#include <ui/Region.h>
+#include <pixelflinger/pixelflinger.h>
+
+#include "Transform.h"
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+class SurfaceFlinger;
+class DisplayHardware;
+class GraphicPlane;
+class Client;
+
+// ---------------------------------------------------------------------------
+
+class LayerBase
+{
+    // poor man's dynamic_cast below
+    template<typename T>
+    struct getTypeInfoOfAnyType {
+        static uint32_t get() { return T::typeInfo; }
+    };
+
+    template<typename T>
+    struct getTypeInfoOfAnyType<T*> {
+        static uint32_t get() { return getTypeInfoOfAnyType<T>::get(); }
+    };
+
+public:
+    static const uint32_t typeInfo;
+    static const char* const typeID;
+    virtual char const* getTypeID() const { return typeID; }
+    virtual uint32_t getTypeInfo() const { return typeInfo; }
+    
+    template<typename T>
+    static T dynamicCast(LayerBase* base) {
+        uint32_t mostDerivedInfo = base->getTypeInfo();
+        uint32_t castToInfo = getTypeInfoOfAnyType<T>::get();
+        if ((mostDerivedInfo & castToInfo) == castToInfo)
+            return static_cast<T>(base);
+        return 0;
+    }
+
+    
+    static Vector<GLuint> deletedTextures; 
+
+    LayerBase(SurfaceFlinger* flinger, DisplayID display);
+    virtual ~LayerBase();
+    
+    DisplayID           dpy;
+    mutable bool        invalidate;
+            Region      visibleRegionScreen;
+            Region      transparentRegionScreen;
+            Region      coveredRegionScreen;
+            
+            struct State {
+                uint32_t        w;
+                uint32_t        h;
+                uint32_t        z;
+                uint8_t         alpha;
+                uint8_t         flags;
+                uint8_t         sequence;   // changes when visible regions can change
+                uint8_t         reserved;
+                uint32_t        tint;
+                Transform       transform;
+                Region          transparentRegion;
+            };
+
+            // modify current state
+            bool setPosition(int32_t x, int32_t y);
+            bool setLayer(uint32_t z);
+            bool setSize(uint32_t w, uint32_t h);
+            bool setAlpha(uint8_t alpha);
+            bool setMatrix(const layer_state_t::matrix22_t& matrix);
+            bool setTransparentRegionHint(const Region& opaque);
+            bool setFlags(uint8_t flags, uint8_t mask);
+            
+            void commitTransaction(bool skipSize);
+            bool requestTransaction();
+
+            uint32_t getTransactionFlags(uint32_t flags);
+            uint32_t setTransactionFlags(uint32_t flags);
+            
+            void validateVisibility(const Transform& globalTransform);
+            Rect visibleBounds() const;
+            void drawRegion(const Region& reg) const;
+
+    virtual void draw(const Region& clip) const;
+    virtual void onDraw(const Region& clip) const = 0;
+    virtual void initStates(uint32_t w, uint32_t h, uint32_t flags);
+    virtual void setSizeChanged(uint32_t w, uint32_t h);
+    virtual uint32_t doTransaction(uint32_t transactionFlags);
+    virtual void setVisibleRegion(const Region& visibleRegion);
+    virtual void setCoveredRegion(const Region& coveredRegion);
+    virtual Point getPhysicalSize() const;
+    virtual void lockPageFlip(bool& recomputeVisibleRegions);
+    virtual void unlockPageFlip(const Transform& planeTransform, Region& outDirtyRegion);
+    virtual void finishPageFlip();
+    virtual bool needsBlending() const  { return false; }
+    virtual bool isSecure() const       { return false; }
+
+            enum { // flags for doTransaction()
+                eVisibleRegion      = 0x00000002,
+                eRestartTransaction = 0x00000008
+            };
+
+
+    inline  const State&    drawingState() const    { return mDrawingState; }
+    inline  const State&    currentState() const    { return mCurrentState; }
+    inline  State&          currentState()          { return mCurrentState; }
+
+    static int compareCurrentStateZ(LayerBase*const* layerA, LayerBase*const* layerB) {
+        return layerA[0]->currentState().z - layerB[0]->currentState().z;
+    }
+
+    int32_t  getOrientation() const { return mOrientation; }
+    bool transformed() const    { return mTransformed; }
+    int  tx() const             { return mLeft; }
+    int  ty() const             { return mTop; }
+    
+protected:
+    const GraphicPlane& graphicPlane(int dpy) const;
+          GraphicPlane& graphicPlane(int dpy);
+
+          GLuint createTexture() const;
+    
+          void drawWithOpenGL(const Region& clip,
+                  GLint textureName, const GGLSurface& surface) const;
+
+          void clearWithOpenGL(const Region& clip) const;
+
+          void loadTexture(const Region& dirty,
+                  GLint textureName, const GGLSurface& t,
+                  GLuint& textureWidth, GLuint& textureHeight) const;
+
+          bool canUseCopybit() const;
+          
+          
+                SurfaceFlinger* mFlinger;
+                uint32_t        mFlags;
+
+                // cached during validateVisibility()
+                bool            mTransformed;
+                int32_t         mOrientation;
+                GLfixed         mVertices[4][2];
+                Rect            mTransformedBounds;
+                bool            mCanUseCopyBit;
+                int             mLeft;
+                int             mTop;
+            
+                // these are protected by an external lock
+                State           mCurrentState;
+                State           mDrawingState;
+    volatile    int32_t         mTransactionFlags;
+
+                // don't change, don't need a lock
+                bool            mPremultipliedAlpha;
+
+                // only read
+     const      uint32_t        mIdentity;
+                
+
+private:
+                void validateTexture(GLint textureName) const;
+    static      int32_t         sIdentity;
+};
+
+
+// ---------------------------------------------------------------------------
+
+class LayerBaseClient : public LayerBase
+{
+public:
+    class Surface;
+   static const uint32_t typeInfo;
+    static const char* const typeID;
+    virtual char const* getTypeID() const { return typeID; }
+    virtual uint32_t getTypeInfo() const { return typeInfo; }
+
+    LayerBaseClient(SurfaceFlinger* flinger, DisplayID display, 
+            Client* client, int32_t i);
+    virtual ~LayerBaseClient();
+
+
+    Client*             const client;
+    layer_cblk_t*       const lcblk;
+
+    inline  int32_t     clientIndex() const { return mIndex; }
+            int32_t     serverIndex() const;
+
+    virtual sp<Surface> getSurface() const;
+   
+            uint32_t    getIdentity() const { return mIdentity; }
+
+    class Surface : public BnSurface 
+    {
+    public:
+        Surface(SurfaceID id, int identity) { 
+            mParams.token = id;
+            mParams.identity = identity;
+            mParams.type = 0;
+        }
+        Surface(SurfaceID id, 
+                const sp<IMemoryHeap>& heap0,
+                const sp<IMemoryHeap>& heap1,
+                int memory_type, int identity)
+        {
+            mParams.token = id;
+            mParams.identity = identity;
+            mParams.type = memory_type;
+            mParams.heap[0] = heap0;
+            mParams.heap[1] = heap1;
+        }
+        virtual ~Surface() {
+            // TODO: We now have a point here were we can clean-up the
+            // client's mess.
+            // This is also where surface id should be recycled.
+            //LOGD("Surface %d, heaps={%p, %p}, type=%d destroyed",
+            //        mId, mHeap[0].get(), mHeap[1].get(), mMemoryType);
+        }
+
+        virtual void getSurfaceData(
+                ISurfaceFlingerClient::surface_data_t* params) const {
+            *params = mParams;
+        }
+
+        virtual status_t registerBuffers(int w, int h, int hstride, int vstride,
+                PixelFormat format, const sp<IMemoryHeap>& heap) 
+                { return INVALID_OPERATION; }
+        virtual void postBuffer(ssize_t offset) { }
+        virtual void unregisterBuffers() { };
+
+    private:
+        ISurfaceFlingerClient::surface_data_t mParams;
+    };
+
+private:
+    int32_t mIndex;
+
+};
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // ANDROID_LAYER_BASE_H
diff --git a/libs/surfaceflinger/LayerBitmap.cpp b/libs/surfaceflinger/LayerBitmap.cpp
new file mode 100644
index 0000000..7c98857
--- /dev/null
+++ b/libs/surfaceflinger/LayerBitmap.cpp
@@ -0,0 +1,188 @@
+/*
+ * 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.
+ */
+
+#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/IMemory.h>
+#include <ui/PixelFormat.h>
+#include <pixelflinger/pixelflinger.h>
+
+#include "LayerBitmap.h"
+#include "SurfaceFlinger.h"
+#include "VRamHeap.h"
+
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+LayerBitmap::LayerBitmap()
+    : mAllocFlags(0), mOffset(0), mSize(-1U), mAlignment(2)
+{
+    memset(&mSurface, 0, sizeof(mSurface));
+}
+
+LayerBitmap::~LayerBitmap()
+{
+    mSurface.data = 0;
+}
+
+status_t LayerBitmap::init(const sp<MemoryDealer>& allocator)
+{
+    if (mAllocator != NULL)
+        return BAD_VALUE;
+    mAllocator = allocator;
+    return NO_ERROR;
+}
+
+status_t LayerBitmap::setBits(uint32_t w, uint32_t h, uint32_t alignment, 
+        PixelFormat format, uint32_t flags)
+{
+    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;
+    }
+
+    uint32_t allocFlags = MemoryDealer::PAGE_ALIGNED;
+    const uint32_t align = 4; // must match GL_UNPACK_ALIGNMENT
+    const uint32_t Bpp = bytesPerPixel(format);
+    uint32_t stride = (w + (alignment-1)) & ~(alignment-1);
+    stride = ((stride * Bpp + (align-1)) & ~(align-1)) / Bpp;
+    size_t size = stride * h * Bpp;
+    if (format == PIXEL_FORMAT_YCbCr_422_SP ||
+        format == PIXEL_FORMAT_YCbCr_420_SP) {
+        // in YUV planar, bitsPerPixel is for the Y plane
+        size = (size * bitsPerPixel(format)) / 8;
+    }
+
+    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;
+    }
+    return NO_ERROR;
+}
+
+void LayerBitmap::clear()
+{
+    // 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);
+        //}
+    }
+}
+
+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();
+}
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
diff --git a/libs/surfaceflinger/LayerBitmap.h b/libs/surfaceflinger/LayerBitmap.h
new file mode 100644
index 0000000..4c2eb50
--- /dev/null
+++ b/libs/surfaceflinger/LayerBitmap.h
@@ -0,0 +1,87 @@
+/*
+ * 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_LAYER_BITMAP_H
+#define ANDROID_LAYER_BITMAP_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Atomic.h>
+#include <ui/PixelFormat.h>
+#include <ui/Rect.h>
+#include <private/ui/SharedState.h>
+#include <pixelflinger/pixelflinger.h>
+
+class copybit_image_t;
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+class IMemory;
+class MemoryDealer;
+class LayerBitmap;
+
+// ---------------------------------------------------------------------------
+
+class LayerBitmap
+{
+public:
+
+    enum {
+        // erase memory to ensure security when necessary
+        SECURE_BITS = 0x00000001
+    };
+
+                LayerBitmap();
+                ~LayerBitmap();
+    status_t    init(const sp<MemoryDealer>& allocator);
+
+    status_t    setBits(uint32_t w, uint32_t h, uint32_t alignment,
+                        PixelFormat format, uint32_t flags = 0);
+    void        clear();
+
+    status_t    getInfo(surface_info_t* info) const;
+    status_t    resize(uint32_t w, uint32_t h);
+
+    const GGLSurface& surface() const   { return mSurface; }
+    Rect bounds() const                 { return Rect(width(), height()); }
+    uint32_t width() const              { return surface().width; }
+    uint32_t height() const             { return surface().height; }
+    uint32_t stride() const             { return surface().stride; }
+    PixelFormat pixelFormat() const     { return surface().format; }
+    void* serverBits() const            { return surface().data; }
+    size_t size() const;
+    const sp<MemoryDealer>& getAllocator() const { return mAllocator; }
+    void getBitmapSurface(copybit_image_t* img) const;
+
+private:
+    LayerBitmap(const LayerBitmap& rhs);
+    LayerBitmap& operator = (const LayerBitmap& rhs);
+
+    sp<MemoryDealer>        mAllocator;
+    sp<IMemory>             mBitsMemory;
+    uint32_t                mAllocFlags;
+    ssize_t                 mOffset;
+    GGLSurface              mSurface;
+    size_t                  mSize;
+    uint32_t                mAlignment;
+};
+
+}; // namespace android
+
+#endif // ANDROID_LAYER_BITMAP_H
diff --git a/libs/surfaceflinger/LayerBlur.cpp b/libs/surfaceflinger/LayerBlur.cpp
new file mode 100644
index 0000000..192ceda
--- /dev/null
+++ b/libs/surfaceflinger/LayerBlur.cpp
@@ -0,0 +1,229 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "SurfaceFlinger"
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Errors.h>
+#include <utils/Log.h>
+
+#include "BlurFilter.h"
+#include "LayerBlur.h"
+#include "SurfaceFlinger.h"
+#include "DisplayHardware/DisplayHardware.h"
+
+namespace android {
+// ---------------------------------------------------------------------------
+
+const uint32_t LayerBlur::typeInfo = LayerBaseClient::typeInfo | 8;
+const char* const LayerBlur::typeID = "LayerBlur";
+
+// ---------------------------------------------------------------------------
+
+LayerBlur::LayerBlur(SurfaceFlinger* flinger, DisplayID display,
+        Client* client, int32_t i)
+     : LayerBaseClient(flinger, display, client, i), mCacheDirty(true),
+     mRefreshCache(true), mCacheAge(0), mTextureName(-1U)
+{
+}
+
+LayerBlur::~LayerBlur()
+{
+    if (mTextureName != -1U) {
+        //glDeleteTextures(1, &mTextureName);
+        deletedTextures.add(mTextureName);
+    }
+}
+
+void LayerBlur::setVisibleRegion(const Region& visibleRegion)
+{
+    LayerBaseClient::setVisibleRegion(visibleRegion);
+    if (visibleRegionScreen.isEmpty()) {
+        if (mTextureName != -1U) {
+            // We're not visible, free the texture up.
+            glBindTexture(GL_TEXTURE_2D, 0);
+            glDeleteTextures(1, &mTextureName);
+            mTextureName = -1U;
+        }
+    }
+}
+
+uint32_t LayerBlur::doTransaction(uint32_t flags)
+{
+    // we're doing a transaction, refresh the cache!
+    if (!mFlinger->isFrozen()) {
+        mRefreshCache = true;
+        mCacheDirty = true;
+        flags |= eVisibleRegion;
+        this->invalidate = true;
+    }
+    return LayerBase::doTransaction(flags);    
+}
+
+void LayerBlur::unlockPageFlip(const Transform& planeTransform, Region& outDirtyRegion)
+{
+    // this code-path must be as tight as possible, it's called each time
+    // the screen is composited.
+    if (UNLIKELY(!visibleRegionScreen.isEmpty())) {
+        // if anything visible below us is invalidated, the cache becomes dirty
+        if (!mCacheDirty && 
+                !visibleRegionScreen.intersect(outDirtyRegion).isEmpty()) {
+            mCacheDirty = true;
+        }
+        if (mCacheDirty) {
+            if (!mFlinger->isFrozen()) {
+                // update everything below us that is visible
+                outDirtyRegion.orSelf(visibleRegionScreen);
+                nsecs_t now = systemTime();
+                if ((now - mCacheAge) >= ms2ns(500)) {
+                    mCacheAge = now;
+                    mRefreshCache = true;
+                    mCacheDirty = false;
+                } else {
+                    if (!mAutoRefreshPending) {
+                        mFlinger->signalDelayedEvent(ms2ns(500));
+                        mAutoRefreshPending = true;
+                    }
+                }
+            }
+        }
+    }
+    LayerBase::unlockPageFlip(planeTransform, outDirtyRegion);
+}
+
+void LayerBlur::onDraw(const Region& clip) const
+{
+    const DisplayHardware& hw(graphicPlane(0).displayHardware());
+    const uint32_t fbHeight = hw.getHeight();
+    int x = mTransformedBounds.left;
+    int y = mTransformedBounds.top;
+    int w = mTransformedBounds.width();
+    int h = mTransformedBounds.height();
+    GLint X = x;
+    GLint Y = fbHeight - (y + h);
+    if (X < 0) {
+        w += X;
+        X = 0;
+    }
+    if (Y < 0) {
+        h += Y;
+        Y = 0;
+    }
+    if (w<0 || h<0) {
+        // we're outside of the framebuffer
+        return;
+    }
+
+    if (mTextureName == -1U) {
+        // create the texture name the first time
+        // can't do that in the ctor, because it runs in another thread.
+        glGenTextures(1, &mTextureName);
+    }
+
+    Region::iterator iterator(clip);
+    if (iterator) {
+        glEnable(GL_TEXTURE_2D);
+        glBindTexture(GL_TEXTURE_2D, mTextureName);
+    
+        if (mRefreshCache) {
+            mRefreshCache = false;
+            mAutoRefreshPending = false;
+            
+            uint16_t* const pixels = (uint16_t*)malloc(w*h*2);
+
+            // this reads the frame-buffer, so a h/w GL would have to
+            // finish() its rendering first. we don't want to do that
+            // too often.
+            glReadPixels(X, Y, w, h, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, pixels);
+            
+            // blur that texture.
+            GGLSurface bl;
+            bl.version = sizeof(GGLSurface);
+            bl.width = w;
+            bl.height = h;
+            bl.stride = w;
+            bl.format = GGL_PIXEL_FORMAT_RGB_565;
+            bl.data = (GGLubyte*)pixels;            
+            blurFilter(&bl, 8, 2);
+            
+            // NOTE: this works only because we have POT. we'd have to round the
+            // texture size up, otherwise.
+            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0,
+                    GL_RGB, GL_UNSIGNED_SHORT_5_6_5, pixels);
+
+            free((void*)pixels);
+        }
+        
+        const State& s = drawingState();
+        if (UNLIKELY(s.alpha < 0xFF)) {
+            const GGLfixed alpha = (s.alpha << 16)/255;
+            glColor4x(0, 0, 0, alpha);
+            glEnable(GL_BLEND);
+            glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+            glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+        } else {
+            glDisable(GL_BLEND);
+        }
+
+        glDisable(GL_DITHER);
+        glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+        glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+        glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+
+        if (UNLIKELY(transformed()
+                || !(mFlags & DisplayHardware::DRAW_TEXTURE_EXTENSION) )) {
+            // This is a very rare scenario.
+            glMatrixMode(GL_TEXTURE);
+            glLoadIdentity();
+            glScalef(1.0f/w, -1.0f/h, 1);
+            glTranslatef(-x, -y, 0);
+            glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+            glVertexPointer(2, GL_FIXED, 0, mVertices);
+            glTexCoordPointer(2, GL_FIXED, 0, mVertices);
+            Rect r;
+            while (iterator.iterate(&r)) {
+                const GLint sy = fbHeight - (r.top + r.height());
+                glScissor(r.left, sy, r.width(), r.height());
+                glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 
+            }       
+        } else {
+            Region::iterator iterator(clip);
+            if (iterator) {
+                // NOTE: this is marginally faster with the software gl, because
+                // glReadPixels() reads the fb bottom-to-top, however we'll
+                // skip all the jaccobian computations.
+                Rect r;
+                GLint crop[4] = { 0, 0, w, h };
+                glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, crop);
+                y = fbHeight - (y + h);
+                while (iterator.iterate(&r)) {
+                    const GLint sy = fbHeight - (r.top + r.height());
+                    glScissor(r.left, sy, r.width(), r.height());
+                    glDrawTexiOES(x, y, 0, w, h);
+                }
+            }
+        }
+    }
+
+    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+}
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
diff --git a/libs/surfaceflinger/LayerBlur.h b/libs/surfaceflinger/LayerBlur.h
new file mode 100644
index 0000000..24b1156
--- /dev/null
+++ b/libs/surfaceflinger/LayerBlur.h
@@ -0,0 +1,65 @@
+/*
+ * 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_LAYER_BLUR_H
+#define ANDROID_LAYER_BLUR_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <private/ui/LayerState.h>
+
+#include <ui/Region.h>
+
+#include "LayerBase.h"
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+class LayerBlur : public LayerBaseClient
+{
+public:    
+    static const uint32_t typeInfo;
+    static const char* const typeID;
+    virtual char const* getTypeID() const { return typeID; }
+    virtual uint32_t getTypeInfo() const { return typeInfo; }
+    
+                LayerBlur(SurfaceFlinger* flinger, DisplayID display,
+                        Client* client, int32_t i);
+        virtual ~LayerBlur();
+
+    virtual void onDraw(const Region& clip) const;
+    virtual bool needsBlending() const  { return true; }
+    virtual bool isSecure() const       { return false; }
+
+    virtual uint32_t doTransaction(uint32_t flags);
+    virtual void setVisibleRegion(const Region& visibleRegion);
+    virtual void unlockPageFlip(const Transform& planeTransform, Region& outDirtyRegion);
+
+private:
+            bool    mCacheDirty;
+    mutable bool    mRefreshCache;
+    mutable bool    mAutoRefreshPending;
+            nsecs_t mCacheAge;
+    mutable GLuint  mTextureName;
+};
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // ANDROID_LAYER_BLUR_H
diff --git a/libs/surfaceflinger/LayerBuffer.cpp b/libs/surfaceflinger/LayerBuffer.cpp
new file mode 100644
index 0000000..d871fc3
--- /dev/null
+++ b/libs/surfaceflinger/LayerBuffer.cpp
@@ -0,0 +1,366 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "SurfaceFlinger"
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <math.h>
+#include <sys/types.h>
+
+#include <utils/Errors.h>
+#include <utils/Log.h>
+#include <utils/StopWatch.h>
+
+#include <ui/PixelFormat.h>
+#include <ui/EGLDisplaySurface.h>
+
+#include "LayerBuffer.h"
+#include "SurfaceFlinger.h"
+#include "VRamHeap.h"
+#include "DisplayHardware/DisplayHardware.h"
+
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+const uint32_t LayerBuffer::typeInfo = LayerBaseClient::typeInfo | 0x20;
+const char* const LayerBuffer::typeID = "LayerBuffer";
+
+// ---------------------------------------------------------------------------
+
+LayerBuffer::LayerBuffer(SurfaceFlinger* flinger, DisplayID display,
+        Client* client, int32_t i)
+    : LayerBaseClient(flinger, display, client, i),
+    mBuffer(0), mTextureName(-1U), mInvalidate(false), mNeedsBlending(false)
+{
+}
+
+LayerBuffer::~LayerBuffer()
+{
+    sp<SurfaceBuffer> s(getClientSurface());
+    if (s != 0) {
+        s->disown();
+        mClientSurface.clear();
+    }
+
+    // this should always be called from the OpenGL thread
+    if (mTextureName != -1U) {
+        //glDeleteTextures(1, &mTextureName);
+        deletedTextures.add(mTextureName);
+    }
+    // to help debugging we set those to zero
+    mWidth = mHeight = 0;
+}
+
+bool LayerBuffer::needsBlending() const
+{
+    Mutex::Autolock _l(mLock);
+    return mNeedsBlending;
+}
+
+void LayerBuffer::onDraw(const Region& clip) const
+{
+    sp<Buffer> buffer(getBuffer());
+    if (UNLIKELY(buffer == 0))  {
+        // nothing to do, we don't have a buffer
+        clearWithOpenGL(clip);
+        return;
+    }
+
+    status_t err = NO_ERROR;
+    NativeBuffer src(buffer->getBuffer());
+    const int can_use_copybit = canUseCopybit();
+
+    if (can_use_copybit)  {
+        //StopWatch watch("MDP");
+
+        const int src_width  = src.crop.r - src.crop.l;
+        const int src_height = src.crop.b - src.crop.t;
+        int W = mTransformedBounds.width();
+        int H = mTransformedBounds.height();
+        if (getOrientation() & Transform::ROT_90) {
+            int t(W); W=H; H=t;
+        }
+
+        /* With LayerBuffer, it is likely that we'll have to rescale the
+         * surface, because this is often used for video playback or
+         * camera-preview. Since we want these operation as fast as possible
+         * we make sure we can use the 2D H/W even if it doesn't support
+         * the requested scale factor, in which case we perform the scaling
+         * in several passes. */
+
+        copybit_t* copybit = mFlinger->getBlitEngine();
+        const float min = copybit->get(copybit, COPYBIT_MINIFICATION_LIMIT);
+        const float mag = copybit->get(copybit, COPYBIT_MAGNIFICATION_LIMIT);
+
+        float xscale = 1.0f;
+        if (src_width > W*min)          xscale = 1.0f / min;
+        else if (src_width*mag < W)     xscale = mag;
+
+        float yscale = 1.0f;
+        if (src_height > H*min)         yscale = 1.0f / min;
+        else if (src_height*mag < H)    yscale = mag;
+
+        if (UNLIKELY(xscale!=1.0f || yscale!=1.0f)) {
+            //LOGD("MDP scaling hack w=%d, h=%d, ww=%d, wh=%d, xs=%f, ys=%f",
+            //        src_width, src_height, W, H, xscale, yscale);
+
+            if (UNLIKELY(mTemporaryDealer == 0)) {
+                // allocate a memory-dealer for this the first time
+                mTemporaryDealer = mFlinger->getSurfaceHeapManager()
+                        ->createHeap(NATIVE_MEMORY_TYPE_PMEM);
+                mTempBitmap.init(mTemporaryDealer);
+            }
+
+            const int tmp_w = floorf(src_width  * xscale);
+            const int tmp_h = floorf(src_height * yscale);
+            err = mTempBitmap.setBits(tmp_w, tmp_h, 1, src.img.format);
+
+            if (LIKELY(err == NO_ERROR)) {
+                NativeBuffer tmp;
+                mTempBitmap.getBitmapSurface(&tmp.img);
+                tmp.crop.l = 0;
+                tmp.crop.t = 0;
+                tmp.crop.r = tmp.img.w;
+                tmp.crop.b = tmp.img.h;
+
+                region_iterator tmp_it(Region(Rect(tmp.crop.r, tmp.crop.b)));
+                copybit->set_parameter(copybit, COPYBIT_TRANSFORM, 0);
+                copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, 0xFF);
+                copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_DISABLE);
+                err = copybit->stretch(copybit,
+                        &tmp.img, &src.img, &tmp.crop, &src.crop, &tmp_it);
+                src = tmp;
+            }
+        }
+
+        const DisplayHardware& hw(graphicPlane(0).displayHardware());
+        copybit_image_t dst;
+        hw.getDisplaySurface(&dst);
+        const copybit_rect_t& drect
+                = reinterpret_cast<const copybit_rect_t&>(mTransformedBounds);
+        const State& s(drawingState());
+        region_iterator it(clip);
+        copybit->set_parameter(copybit, COPYBIT_TRANSFORM, getOrientation());
+        copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, s.alpha);
+        copybit->set_parameter(copybit, COPYBIT_DITHER,
+                s.flags & ISurfaceComposer::eLayerDither ?
+                        COPYBIT_ENABLE : COPYBIT_DISABLE);
+        err = copybit->stretch(copybit,
+                &dst, &src.img, &drect, &src.crop, &it);
+    }
+
+    if (!can_use_copybit || err) {
+        if (UNLIKELY(mTextureName == -1LU)) {
+            mTextureName = createTexture();
+        }
+        GLuint w = 0;
+        GLuint h = 0;
+        GGLSurface t;
+            t.version = sizeof(GGLSurface);
+            t.width  = src.crop.r;
+            t.height = src.crop.b;
+            t.stride = src.img.w;
+            t.vstride= src.img.h;
+            t.format = src.img.format;
+            t.data = (GGLubyte*)(intptr_t(src.img.base) + src.img.offset);
+        const Region dirty(Rect(t.width, t.height));
+        loadTexture(dirty, mTextureName, t, w, h);
+        drawWithOpenGL(clip, mTextureName, t);
+    }
+}
+
+void LayerBuffer::invalidateLocked()
+{
+    mInvalidate = true;
+    mFlinger->signalEvent();
+}
+
+void LayerBuffer::invalidate()
+{
+    Mutex::Autolock _l(mLock);
+    invalidateLocked();
+}
+
+void LayerBuffer::unlockPageFlip(const Transform& planeTransform,
+        Region& outDirtyRegion)
+{
+    Mutex::Autolock _l(mLock);
+    if (mInvalidate) {
+        mInvalidate = false;
+        outDirtyRegion.orSelf(visibleRegionScreen);
+    }
+}
+
+sp<LayerBuffer::SurfaceBuffer> LayerBuffer::getClientSurface() const
+{
+    Mutex::Autolock _l(mLock);
+    return mClientSurface.promote();
+}
+
+sp<LayerBaseClient::Surface> LayerBuffer::getSurface() const
+{
+    sp<SurfaceBuffer> s;
+    Mutex::Autolock _l(mLock);
+    s = mClientSurface.promote();
+    if (s == 0) {
+        s = new SurfaceBuffer(clientIndex(),
+                const_cast<LayerBuffer *>(this));
+        mClientSurface = s;
+    }
+    return s;
+}
+
+
+status_t LayerBuffer::registerBuffers(int w, int h, int hstride, int vstride,
+            PixelFormat format, const sp<IMemoryHeap>& memoryHeap)
+{
+    status_t err = (memoryHeap!=0 && memoryHeap->heapID() >= 0) ? NO_ERROR : NO_INIT;
+    if (err != NO_ERROR)
+        return err;
+
+    // TODO: validate format/parameters
+
+    Mutex::Autolock _l(mLock);
+    mHeap = memoryHeap;
+    mWidth = w;
+    mHeight = h;
+    mHStride = hstride;
+    mVStride = vstride;
+    mFormat = format;
+    PixelFormatInfo info;
+    getPixelFormatInfo(format, &info);
+    mNeedsBlending = (info.h_alpha - info.l_alpha) > 0;
+    return NO_ERROR;
+}
+
+void LayerBuffer::postBuffer(ssize_t offset)
+{
+    sp<IMemoryHeap> heap;
+    int w, h, hs, vs, f;
+    { // scope for the lock
+        Mutex::Autolock _l(mLock);
+        w = mWidth;
+        h = mHeight;
+        hs= mHStride;
+        vs= mVStride;
+        f = mFormat;
+        heap = mHeap;
+    }
+
+    sp<Buffer> buffer;
+    if (heap != 0) {
+        buffer = new Buffer(heap, offset, w, h, hs, vs, f);
+        if (buffer->getStatus() != NO_ERROR)
+            buffer.clear();
+        setBuffer(buffer);
+        invalidate();
+    }
+}
+
+void LayerBuffer::unregisterBuffers()
+{
+    Mutex::Autolock _l(mLock);
+    mHeap.clear();
+    mBuffer.clear();
+    invalidateLocked();
+}
+
+sp<LayerBuffer::Buffer> LayerBuffer::getBuffer() const
+{
+    Mutex::Autolock _l(mLock);
+    return mBuffer;
+}
+
+void LayerBuffer::setBuffer(const sp<LayerBuffer::Buffer>& buffer)
+{
+    Mutex::Autolock _l(mLock);
+    mBuffer = buffer;
+}
+
+// ---------------------------------------------------------------------------
+
+LayerBuffer::SurfaceBuffer::SurfaceBuffer(SurfaceID id, LayerBuffer* owner)
+    : LayerBaseClient::Surface(id, owner->getIdentity()), mOwner(owner)
+{
+}
+
+LayerBuffer::SurfaceBuffer::~SurfaceBuffer()
+{
+    unregisterBuffers();
+    mOwner = 0;
+}
+
+status_t LayerBuffer::SurfaceBuffer::registerBuffers(
+        int w, int h, int hs, int vs,
+        PixelFormat format, const sp<IMemoryHeap>& heap)
+{
+    LayerBuffer* owner(getOwner());
+    if (owner)
+        return owner->registerBuffers(w, h, hs, vs, format, heap);
+    return NO_INIT;
+}
+
+void LayerBuffer::SurfaceBuffer::postBuffer(ssize_t offset)
+{
+    LayerBuffer* owner(getOwner());
+    if (owner)
+        owner->postBuffer(offset);
+}
+
+void LayerBuffer::SurfaceBuffer::unregisterBuffers()
+{
+    LayerBuffer* owner(getOwner());
+    if (owner)
+        owner->unregisterBuffers();
+}
+
+void LayerBuffer::SurfaceBuffer::disown()
+{
+    Mutex::Autolock _l(mLock);
+    mOwner = 0;
+}
+
+
+// ---------------------------------------------------------------------------
+
+LayerBuffer::Buffer::Buffer(const sp<IMemoryHeap>& heap, ssize_t offset,
+        int w, int h, int hs, int vs, int f)
+    : mCount(0), mHeap(heap)
+{
+    NativeBuffer& src(mNativeBuffer);
+    src.crop.l = 0;
+    src.crop.t = 0;
+    src.crop.r = w;
+    src.crop.b = h;
+    src.img.w = hs ?: w;
+    src.img.h = vs ?: h;
+    src.img.format = f;
+    src.img.offset = offset;
+    src.img.base   = heap->base();
+    src.img.fd     = heap->heapID();
+    // FIXME: make sure this buffer lies within the heap, in which case, set
+    // mHeap to null
+}
+
+LayerBuffer::Buffer::~Buffer()
+{
+}
+
+// ---------------------------------------------------------------------------
+}; // namespace android
diff --git a/libs/surfaceflinger/LayerBuffer.h b/libs/surfaceflinger/LayerBuffer.h
new file mode 100644
index 0000000..ef473dd
--- /dev/null
+++ b/libs/surfaceflinger/LayerBuffer.h
@@ -0,0 +1,145 @@
+/*
+ * 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_LAYER_BUFFER_H
+#define ANDROID_LAYER_BUFFER_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/IMemory.h>
+#include <private/ui/LayerState.h>
+#include <GLES/eglnatives.h>
+
+#include "LayerBase.h"
+#include "LayerBitmap.h"
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+class MemoryDealer;
+class Region;
+
+class LayerBuffer : public LayerBaseClient
+{
+public:
+    static const uint32_t typeInfo;
+    static const char* const typeID;
+    virtual char const* getTypeID() const { return typeID; }
+    virtual uint32_t getTypeInfo() const { return typeInfo; }
+
+            LayerBuffer(SurfaceFlinger* flinger, DisplayID display,
+                        Client* client, int32_t i);
+        virtual ~LayerBuffer();
+
+    virtual bool needsBlending() const;
+
+    virtual sp<LayerBaseClient::Surface> getSurface() const;
+    virtual void onDraw(const Region& clip) const;
+    virtual void unlockPageFlip(const Transform& planeTransform, Region& outDirtyRegion);
+
+    status_t registerBuffers(int w, int h, int hstride, int vstride,
+            PixelFormat format, const sp<IMemoryHeap>& heap);
+    void postBuffer(ssize_t offset);
+    void unregisterBuffers();
+    void invalidate();
+    void invalidateLocked();
+
+private:
+
+    struct NativeBuffer
+    {
+        copybit_image_t   img;
+        copybit_rect_t    crop;
+    };
+
+    class Buffer
+    {
+    public:
+        Buffer(const sp<IMemoryHeap>& heap, ssize_t offset,
+                int w, int h, int hs, int vs, int f);
+        inline void incStrong(void*) const {
+            android_atomic_inc(&mCount);
+        }
+        inline void decStrong(void*) const {
+            int32_t c = android_atomic_dec(&mCount);
+            //LOGE_IF(c<1, "Buffer::decStrong() called too many times");
+            if (c == 1) {
+                 delete this;
+             }
+        }
+        inline status_t getStatus() const {
+            return mHeap!=0 ? NO_ERROR : NO_INIT;
+        }
+        inline const NativeBuffer& getBuffer() const {
+            return mNativeBuffer;
+        }
+    protected:
+        Buffer& operator = (const Buffer& rhs);
+        Buffer(const Buffer& rhs);
+        ~Buffer();
+        mutable volatile int32_t mCount;
+    private:
+        sp<IMemoryHeap>    mHeap;
+        NativeBuffer       mNativeBuffer;
+    };
+
+    class SurfaceBuffer : public LayerBaseClient::Surface
+    {
+    public:
+                SurfaceBuffer(SurfaceID id, LayerBuffer* owner);
+        virtual ~SurfaceBuffer();
+        virtual status_t registerBuffers(int w, int h, int hstride, int vstride,
+                PixelFormat format, const sp<IMemoryHeap>& heap);
+        virtual void postBuffer(ssize_t offset);
+        virtual void unregisterBuffers();
+        void disown();
+    private:
+        LayerBuffer* getOwner() const {
+            Mutex::Autolock _l(mLock);
+            return mOwner;
+        }
+        mutable Mutex   mLock;
+        LayerBuffer*    mOwner;
+    };
+
+    friend class SurfaceFlinger;
+    sp<Buffer> getBuffer() const;
+    void       setBuffer(const sp<Buffer>& buffer);
+    sp<SurfaceBuffer>   getClientSurface() const;
+
+    mutable Mutex   mLock;
+    sp<IMemoryHeap> mHeap;
+    sp<Buffer>      mBuffer;
+    int             mWidth;
+    int             mHeight;
+    int             mHStride;
+    int             mVStride;
+    int             mFormat;
+    mutable GLuint  mTextureName;
+    bool            mInvalidate;
+    bool            mNeedsBlending;
+    mutable wp<SurfaceBuffer> mClientSurface;
+    mutable sp<MemoryDealer> mTemporaryDealer;
+    mutable LayerBitmap mTempBitmap;
+};
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // ANDROID_LAYER_BUFFER_H
diff --git a/libs/surfaceflinger/LayerDim.cpp b/libs/surfaceflinger/LayerDim.cpp
new file mode 100644
index 0000000..fc23d53
--- /dev/null
+++ b/libs/surfaceflinger/LayerDim.cpp
@@ -0,0 +1,113 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "SurfaceFlinger"
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Errors.h>
+#include <utils/Log.h>
+
+#include "LayerDim.h"
+#include "SurfaceFlinger.h"
+#include "VRamHeap.h"
+#include "DisplayHardware/DisplayHardware.h"
+
+namespace android {
+// ---------------------------------------------------------------------------
+
+const uint32_t LayerDim::typeInfo = LayerBaseClient::typeInfo | 0x10;
+const char* const LayerDim::typeID = "LayerDim";
+sp<MemoryDealer> LayerDim::mDimmerDealer;
+LayerBitmap LayerDim::mDimmerBitmap;
+
+// ---------------------------------------------------------------------------
+
+LayerDim::LayerDim(SurfaceFlinger* flinger, DisplayID display,
+        Client* client, int32_t i)
+     : LayerBaseClient(flinger, display, client, i)
+{
+}
+
+void LayerDim::initDimmer(SurfaceFlinger* flinger, uint32_t w, uint32_t h)
+{
+    // must only be called once.
+    mDimmerDealer = flinger->getSurfaceHeapManager()
+            ->createHeap(NATIVE_MEMORY_TYPE_PMEM);
+    if (mDimmerDealer != 0) {
+        mDimmerBitmap.init(mDimmerDealer);
+        mDimmerBitmap.setBits(w, h, 1, PIXEL_FORMAT_RGB_565);
+        mDimmerBitmap.clear();
+    }
+}
+
+LayerDim::~LayerDim()
+{
+}
+
+void LayerDim::onDraw(const Region& clip) const
+{
+    const State& s(drawingState());
+
+    Region::iterator iterator(clip);
+    if (s.alpha>0 && iterator) {
+        const DisplayHardware& hw(graphicPlane(0).displayHardware());
+
+        status_t err = NO_ERROR;
+        const int can_use_copybit = canUseCopybit();
+        if (can_use_copybit)  {
+            // StopWatch watch("copybit");
+            copybit_image_t dst;
+            hw.getDisplaySurface(&dst);
+            const copybit_rect_t& drect
+                = reinterpret_cast<const copybit_rect_t&>(mTransformedBounds);
+
+            copybit_image_t src;
+            mDimmerBitmap.getBitmapSurface(&src);
+            const copybit_rect_t& srect(drect);
+
+            copybit_t* copybit = mFlinger->getBlitEngine();
+            copybit->set_parameter(copybit, COPYBIT_TRANSFORM, 0);
+            copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, s.alpha);
+            copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_ENABLE);
+            region_iterator it(clip);
+            err = copybit->stretch(copybit, &dst, &src, &drect, &srect, &it);
+        }
+
+        if (!can_use_copybit || err) {
+            const GGLfixed alpha = (s.alpha << 16)/255;
+            const uint32_t fbHeight = hw.getHeight();
+            glDisable(GL_TEXTURE_2D);
+            glDisable(GL_DITHER);
+            glEnable(GL_BLEND);
+            glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+            glColor4x(0, 0, 0, alpha);
+            glVertexPointer(2, GL_FIXED, 0, mVertices);
+            Rect r;
+            while (iterator.iterate(&r)) {
+                const GLint sy = fbHeight - (r.top + r.height());
+                glScissor(r.left, sy, r.width(), r.height());
+                glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 
+            }
+        }
+    }
+}
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
diff --git a/libs/surfaceflinger/LayerDim.h b/libs/surfaceflinger/LayerDim.h
new file mode 100644
index 0000000..3e37a47
--- /dev/null
+++ b/libs/surfaceflinger/LayerDim.h
@@ -0,0 +1,57 @@
+/*
+ * 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_LAYER_DIM_H
+#define ANDROID_LAYER_DIM_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include "LayerBase.h"
+#include "LayerBitmap.h"
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+class LayerDim : public LayerBaseClient
+{
+public:    
+    static const uint32_t typeInfo;
+    static const char* const typeID;
+    virtual char const* getTypeID() const { return typeID; }
+    virtual uint32_t getTypeInfo() const { return typeInfo; }
+    
+                LayerDim(SurfaceFlinger* flinger, DisplayID display,
+                        Client* client, int32_t i);
+        virtual ~LayerDim();
+
+    virtual void onDraw(const Region& clip) const;
+    virtual bool needsBlending() const  { return true; }
+    virtual bool isSecure() const       { return false; }
+
+    static void initDimmer(SurfaceFlinger* flinger, uint32_t w, uint32_t h);
+
+private:
+    static sp<MemoryDealer> mDimmerDealer;
+    static LayerBitmap mDimmerBitmap;
+};
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // ANDROID_LAYER_DIM_H
diff --git a/libs/surfaceflinger/LayerScreenshot.cpp b/libs/surfaceflinger/LayerScreenshot.cpp
new file mode 100644
index 0000000..9b82bad
--- /dev/null
+++ b/libs/surfaceflinger/LayerScreenshot.cpp
@@ -0,0 +1,110 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "SurfaceFlinger"
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Errors.h>
+#include <utils/Log.h>
+
+#include <graphics/SkBitmap.h>
+
+#include <ui/EGLDisplaySurface.h>
+
+#include "LayerBase.h"
+#include "LayerScreenshot.h"
+#include "SurfaceFlinger.h"
+#include "DisplayHardware/DisplayHardware.h"
+
+namespace android {
+// ---------------------------------------------------------------------------
+
+const uint32_t LayerScreenshot::typeInfo = LayerBase::typeInfo | 0x20;
+const char* const LayerScreenshot::typeID = "LayerScreenshot";
+
+// ---------------------------------------------------------------------------
+
+LayerScreenshot::LayerScreenshot(SurfaceFlinger* flinger, DisplayID display)
+    : LayerBase(flinger, display), mReply(0)
+{
+}
+
+LayerScreenshot::~LayerScreenshot()
+{
+}
+
+void LayerScreenshot::onDraw(const Region& clip) const
+{
+    const DisplayHardware& hw(graphicPlane(0).displayHardware());
+    copybit_image_t dst;
+    hw.getDisplaySurface(&dst);
+    if (dst.base != 0) {
+        uint8_t const* src = (uint8_t const*)(intptr_t(dst.base) + dst.offset); 
+        const int fbWidth = dst.w;
+        const int fbHeight = dst.h;
+        const int fbFormat = dst.format;
+
+        int x = mTransformedBounds.left;
+        int y = mTransformedBounds.top;
+        int w = mTransformedBounds.width();
+        int h = mTransformedBounds.height();
+        Parcel* const reply = mReply;
+        if (reply) {
+            const size_t Bpp = bytesPerPixel(fbFormat);
+            const size_t size = w * h * Bpp;
+            int32_t cfg = SkBitmap::kNo_Config;
+            switch (fbFormat) {
+                case PIXEL_FORMAT_RGBA_4444: cfg = SkBitmap::kARGB_4444_Config;
+                case PIXEL_FORMAT_RGBA_8888: cfg = SkBitmap::kARGB_8888_Config;
+                case PIXEL_FORMAT_RGB_565:   cfg = SkBitmap::kRGB_565_Config;
+                case PIXEL_FORMAT_A_8:       cfg = SkBitmap::kA8_Config;
+            }
+            reply->writeInt32(0);
+            reply->writeInt32(cfg);
+            reply->writeInt32(w);
+            reply->writeInt32(h);
+            reply->writeInt32(w * Bpp);
+            void* data = reply->writeInplace(size);
+            if (data) {
+                uint8_t* d = (uint8_t*)data;
+                uint8_t const* s = src + (x + y*fbWidth) * Bpp;
+                if (w == fbWidth) {
+                    memcpy(d, s, w*h*Bpp);   
+                } else {
+                    for (int y=0 ; y<h ; y++) {
+                        memcpy(d, s, w*Bpp);
+                        d += w*Bpp;
+                        s += fbWidth*Bpp;
+                    }
+                }
+            }
+        }
+    }
+    mCV.broadcast();
+}
+
+void LayerScreenshot::takeScreenshot(Mutex& lock, Parcel* reply)
+{
+    mReply = reply;
+    mCV.wait(lock);
+}
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
diff --git a/libs/surfaceflinger/LayerScreenshot.h b/libs/surfaceflinger/LayerScreenshot.h
new file mode 100644
index 0000000..2d9a8ec
--- /dev/null
+++ b/libs/surfaceflinger/LayerScreenshot.h
@@ -0,0 +1,57 @@
+/*
+ * 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_LAYER_SCREENSHOT_H
+#define ANDROID_LAYER_SCREENSHOT_H
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <utils/threads.h>
+#include <utils/Parcel.h>
+
+#include "LayerBase.h"
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+class LayerScreenshot : public LayerBase
+{
+public:    
+    static const uint32_t typeInfo;
+    static const char* const typeID;
+    virtual char const* getTypeID() const { return typeID; }
+    virtual uint32_t getTypeInfo() const { return typeInfo; }
+    
+                LayerScreenshot(SurfaceFlinger* flinger, DisplayID display);
+        virtual ~LayerScreenshot();
+
+    virtual void onDraw(const Region& clip) const;
+    virtual bool needsBlending() const  { return true; }
+    virtual bool isSecure() const       { return false; }
+
+    void takeScreenshot(Mutex& lock, Parcel* reply);
+    
+private:
+    mutable Condition   mCV;
+    Parcel*             mReply;
+};
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // ANDROID_LAYER_SCREENSHOT_H
diff --git a/libs/surfaceflinger/MODULE_LICENSE_APACHE2 b/libs/surfaceflinger/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/libs/surfaceflinger/MODULE_LICENSE_APACHE2
diff --git a/libs/surfaceflinger/RFBServer.cpp b/libs/surfaceflinger/RFBServer.cpp
new file mode 100644
index 0000000..c2c1989
--- /dev/null
+++ b/libs/surfaceflinger/RFBServer.cpp
@@ -0,0 +1,722 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "RFBServer"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <errno.h>
+#include <fcntl.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+
+#include <netinet/in.h>
+
+#include <cutils/sockets.h>
+
+#include <utils/Log.h>
+#include <ui/Rect.h>
+
+#ifdef HAVE_ANDROID_OS
+#include <linux/input.h>
+#endif
+
+#include "RFBServer.h"
+#include "SurfaceFlinger.h"
+
+/* BUG=773511: this is a temporary hack required while developing the new
+   set of "clean kernel headers" for the Bionic C library. */
+#ifndef KEY_STAR
+#define KEY_STAR    227
+#endif
+#ifndef KEY_SHARP
+#define KEY_SHARP   228
+#endif
+#ifndef KEY_SOFT1
+#define KEY_SOFT1   229
+#endif
+#ifndef KEY_SOFT2
+#define KEY_SOFT2   230
+#endif
+#ifndef KEY_CENTER
+#define KEY_CENTER  232
+#endif
+
+// ----------------------------------------------------------------------------
+
+#define DEBUG_MSG   0
+
+// ----------------------------------------------------------------------------
+
+namespace android {
+
+const int VNC_PORT = 5900;
+
+RFBServer::RFBServer(uint32_t w, uint32_t h, android::PixelFormat format)
+    : Thread(false), mFD(-1), mStatus(NO_INIT), mIoVec(0)
+{
+    mFrameBuffer.version = sizeof(mFrameBuffer);
+    mFrameBuffer.width = w;
+    mFrameBuffer.height = h;
+    mFrameBuffer.stride = w;
+    mFrameBuffer.format = format;
+    mFrameBuffer.data = 0;
+}
+
+RFBServer::~RFBServer()
+{
+    if (mRobinThread != 0) {
+        // ask the thread to exit first
+        mRobinThread->exitAndWait();
+    }
+
+    free(mFrameBuffer.data);
+
+    delete [] mIoVec;
+}
+
+void RFBServer::onFirstRef()
+{
+    run("Batman");
+}
+
+status_t RFBServer::readyToRun()
+{
+    LOGI("RFB server ready to run");
+    return NO_ERROR;
+}
+
+bool RFBServer::threadLoop()
+{
+    struct sockaddr addr;
+    socklen_t alen;
+    int serverfd = -1;
+    int port = VNC_PORT;
+
+    do {
+        retry:
+        if (serverfd < 0) {
+            serverfd = socket_loopback_server(port, SOCK_STREAM);
+            if (serverfd < 0) {
+                if ((errno == EADDRINUSE) && (port < (VNC_PORT+10))) {
+                    LOGW("port %d already in use, trying %d", port, port+1);
+                    port++;
+                    goto retry;
+                }
+                LOGE("couldn't create socket, port=%d, error %d (%s)",
+                        port, errno, strerror(errno));
+                sleep(1);
+                break;
+            }
+            fcntl(serverfd, F_SETFD, FD_CLOEXEC);
+        }
+
+        alen = sizeof(addr);
+        mFD = accept(serverfd, &addr, &alen);
+
+        if (mFD < 0) {
+            LOGE("couldn't accept(), error %d (%s)", errno, strerror(errno));
+            // we could have run out of file descriptors, wait a bit and
+            // try again.
+            sleep(1);
+            goto retry;
+        }
+        fcntl(mFD, F_SETFD, FD_CLOEXEC);
+
+        // send protocol version and Authentication method
+        mStatus = NO_ERROR;
+        handshake(3, 3, Authentication::None);
+
+        if (alive()) {
+            // create the thread we use to send data to the client
+            mRobinThread = new ServerThread(this);
+        }
+
+        while( alive() ) {
+            // client message must be destroyed at each iteration
+            // (most of the time this is a no-op)
+            ClientMessage msg;
+            waitForClientMessage(msg);
+            if (alive()) {
+                handleClientMessage(msg);
+            }
+        }
+
+    } while( alive() );
+
+    // free-up some resources
+    if (mRobinThread != 0) {
+        mRobinThread->exitAndWait();
+        mRobinThread.clear();
+    }
+
+    free(mFrameBuffer.data);
+    mFrameBuffer.data = 0;
+
+    close(mFD);
+    close(serverfd);
+    mFD = -1;
+
+    // we'll try again
+    return true;
+}
+
+// ----------------------------------------------------------------------------
+
+RFBServer::ServerThread::ServerThread(const sp<RFBServer>& receiver)
+            : Thread(false), mReceiver(receiver)
+{
+    LOGD("RFB Server Thread created");
+}
+
+RFBServer::ServerThread::~ServerThread()
+{
+    LOGD("RFB Server Thread destroyed");
+}
+
+void RFBServer::ServerThread::onFirstRef()
+{
+    mUpdateBarrier.close();
+    run("Robin");
+}
+
+status_t RFBServer::ServerThread::readyToRun()
+{
+    return NO_ERROR;
+}
+
+void RFBServer::ServerThread::wake()
+{
+    mUpdateBarrier.open();
+}
+
+void RFBServer::ServerThread::exitAndWait()
+{
+    requestExit();
+    mUpdateBarrier.open();
+    requestExitAndWait();
+}
+
+bool RFBServer::ServerThread::threadLoop()
+{
+    sp<RFBServer> receiver(mReceiver.promote());
+    if (receiver == 0)
+        return false;
+
+    // wait for something to do
+    mUpdateBarrier.wait();
+
+    // we're asked to quit, abort everything
+    if (exitPending())
+        return false;
+
+    mUpdateBarrier.close();
+
+    // process updates
+    receiver->sendFrameBufferUpdates();
+    return !exitPending();
+}
+
+// ----------------------------------------------------------------------------
+
+void RFBServer::handshake(uint8_t major, uint8_t minor, uint32_t auth)
+{
+    ProtocolVersion protocolVersion(major, minor);
+    if( !write(protocolVersion) )
+        return;
+
+    if ( !read(protocolVersion) )
+        return;
+
+    int maj, min;
+    if ( protocolVersion.decode(maj, min) != NO_ERROR ) {
+        mStatus = -1;
+        return;
+    }
+
+#if DEBUG_MSG
+    LOGD("client protocol string: <%s>", (char*)protocolVersion.payload());
+    LOGD("client wants protocol version %d.%d\n", maj, min);
+#endif
+
+    Authentication authentication(auth);
+    if( !write(authentication) )
+        return;
+
+    ClientInitialization clientInit;
+    if ( !read(clientInit) )
+        return;
+
+#if DEBUG_MSG
+    LOGD("client initialization: sharedFlags = %d\n", clientInit.sharedFlags());
+#endif
+
+    ServerInitialization serverInit("Android RFB");
+    ServerInitialization::Payload& message(serverInit.message());
+        message.framebufferWidth = htons(mFrameBuffer.width);
+        message.framebufferHeight = htons(mFrameBuffer.height);
+        message.serverPixelFormat.bitsPerPixel = 16;
+        message.serverPixelFormat.depth = 16;
+        message.serverPixelFormat.bigEndianFlag = 0;
+        message.serverPixelFormat.trueColorFlag = 1;
+        message.serverPixelFormat.redMax   = htons((1<<5)-1);
+        message.serverPixelFormat.greenMax = htons((1<<6)-1);
+        message.serverPixelFormat.blueMax  = htons((1<<5)-1);
+        message.serverPixelFormat.redShift     = 11;
+        message.serverPixelFormat.greenShift   = 5;
+        message.serverPixelFormat.blueShift    = 0;
+
+    mIoVec = new iovec[mFrameBuffer.height];
+
+    write(serverInit);
+}
+
+void RFBServer::handleClientMessage(const ClientMessage& msg)
+{
+    switch(msg.type()) {
+    case SET_PIXEL_FORMAT:
+        handleSetPixelFormat(msg.messages().setPixelFormat);
+        break;
+    case SET_ENCODINGS:
+        handleSetEncodings(msg.messages().setEncodings);
+        break;
+    case FRAME_BUFFER_UPDATE_REQ:
+        handleFrameBufferUpdateReq(msg.messages().frameBufferUpdateRequest);
+        break;
+    case KEY_EVENT:
+        handleKeyEvent(msg.messages().keyEvent);
+        break;
+    }
+}
+
+void RFBServer::handleSetPixelFormat(const SetPixelFormat& msg)
+{
+    if (!validatePixelFormat(msg.pixelFormat)) {
+        LOGE("The builtin VNC server only supports the RGB 565 pixel format");
+        LOGD("requested pixel format:");
+        LOGD("bitsPerPixel:     %d", msg.pixelFormat.bitsPerPixel);
+        LOGD("depth:            %d", msg.pixelFormat.depth);
+        LOGD("bigEndianFlag:    %d", msg.pixelFormat.bigEndianFlag);
+        LOGD("trueColorFlag:    %d", msg.pixelFormat.trueColorFlag);
+        LOGD("redmax:           %d", ntohs(msg.pixelFormat.redMax));
+        LOGD("bluemax:          %d", ntohs(msg.pixelFormat.greenMax));
+        LOGD("greenmax:         %d", ntohs(msg.pixelFormat.blueMax));
+        LOGD("redshift:         %d", msg.pixelFormat.redShift);
+        LOGD("greenshift:       %d", msg.pixelFormat.greenShift);
+        LOGD("blueshift:        %d", msg.pixelFormat.blueShift);
+        mStatus = -1;
+    }
+}
+
+bool RFBServer::validatePixelFormat(const PixelFormat& pf)
+{
+    if ((pf.bitsPerPixel != 16) || (pf.depth != 16))
+        return false;
+
+    if (pf.bigEndianFlag || !pf.trueColorFlag)
+        return false;
+
+    if (ntohs(pf.redMax)!=0x1F ||
+        ntohs(pf.greenMax)!=0x3F ||
+        ntohs(pf.blueMax)!=0x1F) {
+        return false;
+    }
+
+    if (pf.redShift!=11 || pf.greenShift!=5 || pf.blueShift!=0)
+        return false;
+
+    return true;
+}
+
+void RFBServer::handleSetEncodings(const SetEncodings& msg)
+{
+    /* From the RFB specification:
+        Sets the encoding types in which pixel data can be sent by the server.
+        The order of the encoding types given in this message is a hint by the
+        client as to its preference (the first encoding specified being most
+        preferred). The server may or may not choose to make use of this hint.
+        Pixel data may always be sent in raw encoding even if not specified
+        explicitly here.
+    */
+
+    LOGW("SetEncodings received. Only RAW is supported.");
+}
+
+void RFBServer::handleFrameBufferUpdateReq(const FrameBufferUpdateRequest& msg)
+{
+#if DEBUG_MSG
+    LOGD("handle FrameBufferUpdateRequest");
+#endif
+
+    Rect r;
+    r.left = ntohs(msg.x);
+    r.top = ntohs(msg.y);
+    r.right = r.left + ntohs(msg.width);
+    r.bottom = r.top + ntohs(msg.height);
+
+    Mutex::Autolock _l(mRegionLock);
+    mClientRegionRequest.set(r);
+    if (!msg.incremental)
+        mDirtyRegion.orSelf(r);
+
+    mRobinThread->wake();
+}
+
+void RFBServer::handleKeyEvent(const KeyEvent& msg)
+{
+#ifdef HAVE_ANDROID_OS
+
+    int scancode = 0;
+    int code = ntohl(msg.key);
+
+    if (code>='0' && code<='9') {
+        scancode = (code & 0xF) - 1;
+        if (scancode<0) scancode += 10;
+        scancode += KEY_1;
+    } else if (code>=0xFF50 && code<=0xFF58) {
+        static const uint16_t map[] =
+             {  KEY_HOME, KEY_LEFT, KEY_UP, KEY_RIGHT, KEY_DOWN,
+                KEY_SOFT1, KEY_SOFT2, KEY_END, 0 };
+        scancode = map[code & 0xF];
+    } else if (code>=0xFFE1 && code<=0xFFEE) {
+        static const uint16_t map[] =
+             {  KEY_LEFTSHIFT, KEY_LEFTSHIFT,
+                KEY_COMPOSE, KEY_COMPOSE,
+                KEY_LEFTSHIFT, KEY_LEFTSHIFT,
+                0,0,
+                KEY_LEFTALT, KEY_RIGHTALT,
+                0, 0, 0, 0 };
+        scancode = map[code & 0xF];
+    } else if ((code>='A' && code<='Z') || (code>='a' && code<='z')) {
+        static const uint16_t map[] = {
+                KEY_A, KEY_B, KEY_C, KEY_D, KEY_E,
+                KEY_F, KEY_G, KEY_H, KEY_I, KEY_J,
+                KEY_K, KEY_L, KEY_M, KEY_N, KEY_O,
+                KEY_P, KEY_Q, KEY_R, KEY_S, KEY_T,
+                KEY_U, KEY_V, KEY_W, KEY_X, KEY_Y, KEY_Z };
+        scancode = map[(code & 0x5F) - 'A'];
+    } else {
+        switch (code) {
+            case 0x0003:    scancode = KEY_CENTER;      break;
+            case 0x0020:    scancode = KEY_SPACE;       break;
+            case 0x0023:    scancode = KEY_SHARP;       break;
+            case 0x0033:    scancode = KEY_SHARP;       break;
+            case 0x002C:    scancode = KEY_COMMA;       break;
+            case 0x003C:    scancode = KEY_COMMA;       break;
+            case 0x002E:    scancode = KEY_DOT;         break;
+            case 0x003E:    scancode = KEY_DOT;         break;
+            case 0x002F:    scancode = KEY_SLASH;       break;
+            case 0x003F:    scancode = KEY_SLASH;       break;
+            case 0x0032:    scancode = KEY_EMAIL;       break;
+            case 0x0040:    scancode = KEY_EMAIL;       break;
+            case 0xFF08:    scancode = KEY_BACKSPACE;   break;
+            case 0xFF1B:    scancode = KEY_BACK;        break;
+            case 0xFF09:    scancode = KEY_TAB;         break;
+            case 0xFF0D:    scancode = KEY_ENTER;       break;
+            case 0x002A:    scancode = KEY_STAR;        break;
+            case 0xFFBE:    scancode = KEY_SEND;        break; // F1
+            case 0xFFBF:    scancode = KEY_END;         break; // F2
+            case 0xFFC0:    scancode = KEY_HOME;        break; // F3
+            case 0xFFC5:    scancode = KEY_POWER;       break; // F8
+        }
+    }
+
+#if DEBUG_MSG
+   LOGD("handle KeyEvent 0x%08x, %d, scancode=%d\n", code, msg.downFlag, scancode);
+#endif
+
+    if (scancode) {
+        mEventInjector.injectKey(uint16_t(scancode),
+             msg.downFlag ? EventInjector::DOWN : EventInjector::UP);
+    }
+#endif
+}
+
+void RFBServer::waitForClientMessage(ClientMessage& msg)
+{
+    if ( !read(msg.payload(), 1) )
+        return;
+
+    switch(msg.type()) {
+
+    case SET_PIXEL_FORMAT:
+        read(msg.payload(1), sizeof(SetPixelFormat)-1);
+        break;
+
+    case FIX_COLOUR_MAP_ENTRIES:
+        mStatus = UNKNOWN_ERROR;
+        return;
+
+    case SET_ENCODINGS:
+    {
+        if ( !read(msg.payload(1), sizeof(SetEncodings)-1) )
+            return;
+
+        size_t size = ntohs( msg.messages().setEncodings.numberOfEncodings ) * 4;
+        if (msg.resize(sizeof(SetEncodings) + size) != NO_ERROR) {
+            mStatus = NO_MEMORY;
+            return;
+        }
+
+        if ( !read(msg.payload(sizeof(SetEncodings)), size) )
+            return;
+
+        break;
+    }
+
+    case FRAME_BUFFER_UPDATE_REQ:
+        read(msg.payload(1), sizeof(FrameBufferUpdateRequest)-1);
+        break;
+
+    case KEY_EVENT:
+        read(msg.payload(1), sizeof(KeyEvent)-1);
+        break;
+
+    case POINTER_EVENT:
+        read(msg.payload(1), sizeof(PointerEvent)-1);
+        break;
+
+    case CLIENT_CUT_TEXT:
+    {
+        if ( !read(msg.payload(1), sizeof(ClientCutText)-1) )
+            return;
+
+        size_t size = ntohl( msg.messages().clientCutText.length );
+        if (msg.resize(sizeof(ClientCutText) + size) != NO_ERROR) {
+            mStatus = NO_MEMORY;
+            return;
+        }
+
+        if ( !read(msg.payload(sizeof(SetEncodings)), size) )
+            return;
+
+        break;
+    }
+
+    default:
+        LOGE("Unknown Message %d", msg.type());
+        mStatus = UNKNOWN_ERROR;
+        return;
+    }
+}
+
+// ----------------------------------------------------------------------------
+
+bool RFBServer::write(const Message& msg)
+{
+    write(msg.payload(), msg.size());
+    return alive();
+}
+
+bool RFBServer::read(Message& msg)
+{
+    read(msg.payload(), msg.size());
+    return alive();
+}
+
+bool RFBServer::write(const void* buffer, int size)
+{
+    int wr = ::write(mFD, buffer, size);
+    if (wr != size) {
+        //LOGE("write(%d) error %d (%s)", size, wr, strerror(errno));
+        mStatus = (wr == -1) ? errno : -1;
+    }
+    return alive();
+}
+
+bool RFBServer::read(void* buffer, int size)
+{
+    int rd = ::read(mFD, buffer, size);
+    if (rd != size) {
+        //LOGE("read(%d) error %d (%s)", size, rd, strerror(errno));
+        mStatus = (rd == -1) ? errno : -1;
+    }
+    return alive();
+}
+
+bool RFBServer::alive() const
+{
+    return  mStatus == 0;
+}
+
+bool RFBServer::isConnected() const
+{
+    return alive();
+}
+
+// ----------------------------------------------------------------------------
+
+void RFBServer::frameBufferUpdated(const GGLSurface& front, const Region& reg)
+{
+    Mutex::Autolock _l(mRegionLock);
+
+    // update dirty region
+    mDirtyRegion.orSelf(reg);
+
+    // remember the front-buffer
+    mFrontBuffer = front;
+
+    // The client has not requested anything, don't do anything more
+    if (mClientRegionRequest.isEmpty())
+        return;
+
+    // wake the sending thread up
+    mRobinThread->wake();
+}
+
+void RFBServer::sendFrameBufferUpdates()
+{
+    Vector<Rect> rects;
+    size_t countRects;
+    GGLSurface fb;
+
+    { // Scope for the lock
+        Mutex::Autolock _l(mRegionLock);
+        if (mFrontBuffer.data == 0)
+            return;
+
+        const Region reg( mDirtyRegion.intersect(mClientRegionRequest) );
+        if (reg.isEmpty())
+            return;
+
+        mDirtyRegion.subtractSelf(reg);
+        countRects = reg.rects(rects);
+
+        // copy the frame-buffer so we can stay responsive
+        size_t bytesPerPix = bytesPerPixel(mFrameBuffer.format);
+        size_t bpr = mFrameBuffer.stride * bytesPerPix;
+        if (mFrameBuffer.data == 0) {
+            mFrameBuffer.data = (GGLubyte*)malloc(bpr * mFrameBuffer.height);
+            if (mFrameBuffer.data == 0)
+            	return;
+        }
+
+        memcpy(mFrameBuffer.data, mFrontBuffer.data, bpr*mFrameBuffer.height);
+        fb = mFrameBuffer;
+    }
+
+    FrameBufferUpdate msgHeader;
+    msgHeader.type = 0;
+    msgHeader.numberOfRectangles = htons(countRects);
+    write(&msgHeader, sizeof(msgHeader));
+
+    Rectangle rectangle;
+    for (size_t i=0 ; i<countRects ; i++) {
+        const Rect& r = rects[i];
+        rectangle.x = htons( r.left );
+        rectangle.y = htons( r.top );
+        rectangle.w = htons( r.width() );
+        rectangle.h = htons( r.height() );
+        rectangle.encoding = htons( SetEncodings::Raw );
+        write(&rectangle, sizeof(rectangle));
+        size_t h = r.height();
+        size_t w = r.width();
+        size_t bytesPerPix = bytesPerPixel(fb.format);
+        size_t bpr = fb.stride * bytesPerPix;
+        size_t bytes = w * bytesPerPix;
+        size_t offset = (r.top * bpr) + (r.left * bytesPerPix);
+        uint8_t* src = static_cast<uint8_t*>(fb.data) + offset;
+        iovec* iov = mIoVec;
+        while (h--) {
+            iov->iov_base = src;
+            iov->iov_len = bytes;
+            src += bpr;
+            iov++;
+        }
+        size_t iovcnt = iov - mIoVec;
+        int wr = ::writev(mFD, mIoVec, iovcnt);
+        if (wr < 0) {
+            //LOGE("write(%d) error %d (%s)", size, wr, strerror(errno));
+            mStatus =  errno;
+        }
+    }
+}
+
+// ----------------------------------------------------------------------------
+
+RFBServer::Message::Message(size_t size)
+    : mSize(size), mAllocatedSize(size)
+{
+    mPayload = malloc(size);
+}
+
+RFBServer::Message::Message(void* payload, size_t size)
+    : mPayload(payload), mSize(size), mAllocatedSize(0)
+{
+}
+
+RFBServer::Message::~Message()
+{
+    if (mAllocatedSize)
+        free(mPayload);
+}
+
+status_t RFBServer::Message::resize(size_t size)
+{
+    if (size > mAllocatedSize) {
+        void* newp;
+        if (mAllocatedSize) {
+            newp = realloc(mPayload, size);
+            if (!newp) return NO_MEMORY;
+        } else {
+            newp = malloc(size);
+            if (!newp) return NO_MEMORY;
+            memcpy(newp, mPayload, mSize);
+            mAllocatedSize = size;
+        }
+        mPayload = newp;
+    }
+    mSize = size;
+    return NO_ERROR;
+}
+
+// ----------------------------------------------------------------------------
+
+RFBServer::EventInjector::EventInjector()
+    : mFD(-1)
+{
+}
+
+RFBServer::EventInjector::~EventInjector()
+{
+}
+
+void RFBServer::EventInjector::injectKey(uint16_t code, uint16_t value)
+{
+#ifdef HAVE_ANDROID_OS
+    // XXX: we need to open the right event device
+    int version;
+    mFD = open("/dev/input/event0", O_RDWR);
+    ioctl(mFD, EVIOCGVERSION, &version);
+
+    input_event ev;
+    memset(&ev, 0, sizeof(ev));
+    ev.type = EV_KEY;
+    ev.code = code;
+    ev.value = value;
+    ::write(mFD, &ev, sizeof(ev));
+
+    close(mFD);
+    mFD = -1;
+#endif
+}
+
+
+}; // namespace android
+
diff --git a/libs/surfaceflinger/RFBServer.h b/libs/surfaceflinger/RFBServer.h
new file mode 100644
index 0000000..420912e
--- /dev/null
+++ b/libs/surfaceflinger/RFBServer.h
@@ -0,0 +1,316 @@
+/*
+ * 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_RFB_SERVER_H
+#define ANDROID_RFB_SERVER_H
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <unistd.h>
+#include <arpa/inet.h>
+
+#include <utils/Errors.h>
+#include <utils/threads.h>
+#include <ui/Region.h>
+#include <ui/PixelFormat.h>
+
+#include <pixelflinger/pixelflinger.h>
+
+#include "Barrier.h"
+
+namespace android {
+
+class SurfaceFlinger;
+
+class RFBServer : public Thread
+{
+public:
+                        RFBServer(uint32_t w, uint32_t h, android::PixelFormat format);
+    virtual             ~RFBServer();
+
+    void    frameBufferUpdated(const GGLSurface& front, const Region& reg);
+    bool    isConnected() const;
+
+private:
+            typedef uint8_t     card8;
+            typedef uint16_t    card16;
+            typedef uint32_t    card32;
+
+            struct Message {
+                                Message(size_t size);
+                virtual         ~Message();
+                void*           payload(int offset=0) {
+                    return static_cast<char*>(mPayload)+offset;
+                }
+                void const *    payload(int offset=0) const {
+                    return static_cast<char const *>(mPayload)+offset;
+                }
+                size_t          size() const { return mSize; }
+            protected:
+                                Message(void* payload, size_t size);
+                status_t        resize(size_t size);
+            private:
+                void*       mPayload;
+                size_t      mSize;
+                size_t      mAllocatedSize;
+            };
+
+            struct ProtocolVersion : public Message {
+                ProtocolVersion(uint8_t major, uint8_t minor)
+                    : Message(&messageData, 12) {
+                    char* p = static_cast<char*>(payload());
+                    snprintf(p, 13, "RFB %03u.%03u%c", major, minor, 0xA);
+                }
+                status_t decode(int& maj, int& min) {
+                    char* p = static_cast<char*>(payload());
+                    int n = sscanf(p, "RFB %03u.%03u", &maj, &min);
+                    return (n == 2) ? NO_ERROR : NOT_ENOUGH_DATA;
+                }
+            private:
+                char messageData[12+1];
+            };
+            
+            struct Authentication : public Message {
+                enum { Failed=0, None=1, Vnc=2 };
+                Authentication(int auth) : Message(&messageData, 4) {
+                    *static_cast<card32*>(payload()) = htonl(auth);
+                }
+            private:
+                card32 messageData;
+            };
+            
+            struct ClientInitialization : public Message {
+                ClientInitialization() : Message(&messageData, 1) { }
+                int sharedFlags() {
+                    return messageData;
+                }
+            private:
+                card8 messageData;
+            };
+
+            struct PixelFormat {
+                card8   bitsPerPixel;
+                card8   depth;
+                card8   bigEndianFlag;
+                card8   trueColorFlag;
+                card16  redMax;
+                card16  greenMax;
+                card16  blueMax;
+                card8   redShift;
+                card8   greenShift;
+                card8   blueShift;
+                uint8_t padding[3];
+            } __attribute__((packed));
+            
+            struct ServerInitialization : public Message {
+                ServerInitialization(char const * name)
+                    : Message(sizeof(Payload) + strlen(name))
+                {
+                    const size_t nameLength = size() - sizeof(Payload);
+                    message().nameLength = htonl(nameLength); 
+                    memcpy((char*)message().nameString, name,nameLength);
+                }
+                struct Payload {
+                    card16      framebufferWidth;
+                    card16      framebufferHeight;
+                    PixelFormat serverPixelFormat;
+                    card32      nameLength;
+                    card8       nameString[0];
+                } __attribute__((packed));
+                Payload& message() {
+                    return *static_cast<Payload*>(payload());
+                }
+            };
+
+            // client messages...
+            
+            struct SetPixelFormat {
+                card8           type;
+                uint8_t         padding[3];
+                PixelFormat     pixelFormat;
+            } __attribute__((packed));
+
+            struct SetEncodings {
+                enum { Raw=0, CoR=1, RRE=2, CoRRE=4, Hextile=5 };
+                card8           type;
+                uint8_t         padding;
+                card16          numberOfEncodings;
+                card32          encodings[0];
+            } __attribute__((packed));
+
+            struct FrameBufferUpdateRequest {
+                card8           type;
+                card8           incremental;
+                card16          x;
+                card16          y;
+                card16          width;
+                card16          height;
+            } __attribute__((packed));
+            
+            struct KeyEvent {
+                card8           type;
+                card8           downFlag;
+                uint8_t         padding[2];
+                card32          key;
+            } __attribute__((packed));
+
+            struct PointerEvent {
+                card8           type;
+                card8           buttonMask;
+                card16          x;
+                card16          y;
+            } __attribute__((packed));
+
+            struct ClientCutText {
+                card8           type;
+                uint8_t         padding[3];
+                card32          length;
+                card8           text[0];
+            } __attribute__((packed));
+            
+            union ClientMessages {
+                card8                       type;
+                SetPixelFormat              setPixelFormat;
+                SetEncodings                setEncodings;
+                FrameBufferUpdateRequest    frameBufferUpdateRequest;
+                KeyEvent                    keyEvent;
+                PointerEvent                pointerEvent;
+                ClientCutText               clientCutText;
+            };
+
+            struct Rectangle {
+                card16      x;
+                card16      y;
+                card16      w;
+                card16      h;
+                card32      encoding;
+            } __attribute__((packed));
+
+            struct FrameBufferUpdate {
+                card8       type;
+                uint8_t     padding;
+                card16      numberOfRectangles;
+                Rectangle   rectangles[0];            
+            } __attribute__((packed));
+
+            enum {
+                SET_PIXEL_FORMAT        = 0,
+                FIX_COLOUR_MAP_ENTRIES  = 1,
+                SET_ENCODINGS           = 2,
+                FRAME_BUFFER_UPDATE_REQ = 3,
+                KEY_EVENT               = 4,
+                POINTER_EVENT           = 5,
+                CLIENT_CUT_TEXT         = 6,
+            };
+
+            struct ClientMessage : public Message {
+                ClientMessage()
+                    : Message(&messageData, sizeof(messageData)) {
+                }
+                const ClientMessages& messages() const {
+                    return *static_cast<ClientMessages const *>(payload());
+                }
+                const int type() const {
+                    return messages().type;
+                }
+                status_t resize(size_t size) {
+                    return Message::resize(size);
+                }
+
+                ClientMessages messageData;
+            };
+
+            
+            class ServerThread : public Thread
+            {
+                friend class RFBServer;
+            public:
+                        ServerThread(const sp<RFBServer>& receiver);
+                virtual ~ServerThread();
+                void wake();
+                void exitAndWait();
+            private:
+                virtual bool threadLoop();
+                virtual status_t readyToRun();
+                virtual void onFirstRef();
+                wp<RFBServer> mReceiver;
+                bool (RFBServer::*mAction)();
+                Barrier mUpdateBarrier;
+            };
+            
+            class EventInjector {
+            public:
+                enum { UP=0, DOWN=1 };
+                EventInjector();
+                ~EventInjector();
+                void injectKey(uint16_t code, uint16_t value);
+            private:
+                struct input_event {
+                    struct timeval time;
+                    uint16_t type;
+                    uint16_t code;
+                    uint32_t value;
+                };
+                int mFD;
+            };
+            
+            void        handshake(uint8_t major, uint8_t minor, uint32_t auth);
+            void        waitForClientMessage(ClientMessage& msg);
+            void        handleClientMessage(const ClientMessage& msg);
+            void        handleSetPixelFormat(const SetPixelFormat& msg);
+            void        handleSetEncodings(const SetEncodings& msg);
+            void        handleFrameBufferUpdateReq(const FrameBufferUpdateRequest& msg);
+            void        handleKeyEvent(const KeyEvent& msg);
+            void        sendFrameBufferUpdates();
+
+            bool        validatePixelFormat(const PixelFormat& pf);
+            bool        alive() const;
+            bool        write(const Message& msg);
+            bool        read(Message& msg);
+
+            bool        write(const void* buffer, int size);
+            bool        read(void* buffer, int size);
+
+    virtual bool        threadLoop();
+    virtual status_t    readyToRun();
+    virtual void        onFirstRef();
+
+            sp<ServerThread>    mRobinThread;
+
+            int         mFD;
+            int         mStatus;
+            iovec*      mIoVec;
+    
+            EventInjector   mEventInjector;
+
+            Mutex       mRegionLock;
+            // This is the region requested by the client since the last
+            // time we updated it
+            Region      mClientRegionRequest;
+            // This is the region of the screen that needs to be sent to the
+            // client since the last time we updated it.
+            // Typically this is the dirty region, but not necessarily, for
+            // instance if the client asked for a non incremental update.
+            Region      mDirtyRegion;
+            
+            GGLSurface  mFrameBuffer;
+            GGLSurface  mFrontBuffer;
+};
+
+}; // namespace android
+
+#endif // ANDROID_RFB_SERVER_H
diff --git a/libs/surfaceflinger/SurfaceFlinger.cpp b/libs/surfaceflinger/SurfaceFlinger.cpp
new file mode 100644
index 0000000..45496b2
--- /dev/null
+++ b/libs/surfaceflinger/SurfaceFlinger.cpp
@@ -0,0 +1,1895 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "SurfaceFlinger"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <math.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+
+#include <cutils/log.h>
+#include <cutils/properties.h>
+
+#include <utils/IPCThreadState.h>
+#include <utils/IServiceManager.h>
+#include <utils/MemoryDealer.h>
+#include <utils/MemoryBase.h>
+#include <utils/String8.h>
+#include <utils/String16.h>
+#include <utils/StopWatch.h>
+
+#include <ui/BlitHardware.h>
+#include <ui/PixelFormat.h>
+#include <ui/DisplayInfo.h>
+#include <ui/EGLDisplaySurface.h>
+
+#include <pixelflinger/pixelflinger.h>
+#include <GLES/gl.h>
+
+#include "clz.h"
+#include "CPUGauge.h"
+#include "Layer.h"
+#include "LayerBlur.h"
+#include "LayerBuffer.h"
+#include "LayerDim.h"
+#include "LayerBitmap.h"
+#include "LayerScreenshot.h"
+#include "SurfaceFlinger.h"
+#include "RFBServer.h"
+#include "VRamHeap.h"
+
+#include "DisplayHardware/DisplayHardware.h"
+#include "GPUHardware/GPUHardware.h"
+
+
+// the VNC server even on local ports presents a significant
+// thread as it can allow an application to control and "see" other
+// applications, de-facto bypassing security permissions.
+#define ENABLE_VNC_SERVER   0
+
+#define DISPLAY_COUNT       1
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+void SurfaceFlinger::instantiate() {
+    defaultServiceManager()->addService(
+            String16("SurfaceFlinger"), new SurfaceFlinger());
+}
+
+void SurfaceFlinger::shutdown() {
+    // we should unregister here, but not really because
+    // when (if) the service manager goes away, all the services
+    // it has a reference to will leave too.
+}
+
+// ---------------------------------------------------------------------------
+
+SurfaceFlinger::LayerVector::LayerVector(const SurfaceFlinger::LayerVector& rhs)
+    : lookup(rhs.lookup), layers(rhs.layers)
+{
+}
+
+ssize_t SurfaceFlinger::LayerVector::indexOf(
+        LayerBase* key, size_t guess) const
+{
+    if (guess<size() && lookup.keyAt(guess) == key)
+        return guess;
+    const ssize_t i = lookup.indexOfKey(key);
+    if (i>=0) {
+        const size_t idx = lookup.valueAt(i);
+        LOG_ASSERT(layers[idx]==key,
+            "LayerVector[%p]: layers[%d]=%p, key=%p",
+            this, int(idx), layers[idx], key);
+        return idx;
+    }
+    return i;
+}
+
+ssize_t SurfaceFlinger::LayerVector::add(
+        LayerBase* layer,
+        Vector<LayerBase*>::compar_t cmp)
+{
+    size_t count = layers.size();
+    ssize_t l = 0;
+    ssize_t h = count-1;
+    ssize_t mid;
+    LayerBase* const* a = layers.array();
+    while (l <= h) {
+        mid = l + (h - l)/2;
+        const int c = cmp(a+mid, &layer);
+        if (c == 0)     { l = mid; break; }
+        else if (c<0)   { l = mid+1; }
+        else            { h = mid-1; }
+    }
+    size_t order = l;
+    while (order<count && !cmp(&layer, a+order)) {
+        order++;
+    }
+    count = lookup.size();
+    for (size_t i=0 ; i<count ; i++) {
+        if (lookup.valueAt(i) >= order) {
+            lookup.editValueAt(i)++;
+        }
+    }
+    layers.insertAt(layer, order);
+    lookup.add(layer, order);
+    return order;
+}
+
+ssize_t SurfaceFlinger::LayerVector::remove(LayerBase* layer)
+{
+    const ssize_t keyIndex = lookup.indexOfKey(layer);
+    if (keyIndex >= 0) {
+        const size_t index = lookup.valueAt(keyIndex);
+        LOG_ASSERT(layers[index]==layer,
+                "LayerVector[%p]: layers[%u]=%p, layer=%p",
+                this, int(index), layers[index], layer);
+        layers.removeItemsAt(index);
+        lookup.removeItemsAt(keyIndex);
+        const size_t count = lookup.size();
+        for (size_t i=0 ; i<count ; i++) {
+            if (lookup.valueAt(i) >= size_t(index)) {
+                lookup.editValueAt(i)--;
+            }
+        }
+        return index;
+    }
+    return NAME_NOT_FOUND;
+}
+
+ssize_t SurfaceFlinger::LayerVector::reorder(
+        LayerBase* layer,
+        Vector<LayerBase*>::compar_t cmp)
+{
+    // XXX: it's a little lame. but oh well...
+    ssize_t err = remove(layer);
+    if (err >=0)
+        err = add(layer, cmp);
+    return err;
+}
+
+// ---------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#endif
+
+SurfaceFlinger::SurfaceFlinger()
+    :   BnSurfaceComposer(), Thread(false),
+        mTransactionFlags(0),
+        mTransactionCount(0),
+        mBootTime(systemTime()),
+        mLastScheduledBroadcast(NULL),
+        mVisibleRegionsDirty(false),
+        mDeferReleaseConsole(false),
+        mFreezeDisplay(false),
+        mFreezeCount(0),
+        mDebugRegion(0),
+        mDebugCpu(0),
+        mDebugFps(0),
+        mDebugBackground(0),
+        mDebugNoBootAnimation(0),
+        mSyncObject(),
+        mDeplayedTransactionPending(0),
+        mConsoleSignals(0),
+        mSecureFrameBuffer(0)
+{
+    init();
+}
+
+void SurfaceFlinger::init()
+{
+    LOGI("SurfaceFlinger is starting");
+
+    // create the shared control-block
+    mServerHeap = new MemoryDealer(4096, MemoryDealer::READ_ONLY);
+    LOGE_IF(mServerHeap==0, "can't create shared memory dealer");
+
+    mServerCblkMemory = mServerHeap->allocate(4096);
+    LOGE_IF(mServerCblkMemory==0, "can't create shared control block");
+
+    mServerCblk = static_cast<surface_flinger_cblk_t *>(mServerCblkMemory->pointer());
+    LOGE_IF(mServerCblk==0, "can't get to shared control block's address");
+    new(mServerCblk) surface_flinger_cblk_t;
+
+    // create the surface Heap manager, which manages the heaps
+    // (be it in RAM or VRAM) where surfaces are allocated
+    // We give 8 MB per client.
+    mSurfaceHeapManager = new SurfaceHeapManager(8 << 20);
+    mGPU = new GPUHardware();
+
+    // debugging stuff...
+    char value[PROPERTY_VALUE_MAX];
+    property_get("debug.sf.showupdates", value, "0");
+    mDebugRegion = atoi(value);
+    property_get("debug.sf.showcpu", value, "0");
+    mDebugCpu = atoi(value);
+    property_get("debug.sf.showbackground", value, "0");
+    mDebugBackground = atoi(value);
+    property_get("debug.sf.showfps", value, "0");
+    mDebugFps = atoi(value);
+    property_get("debug.sf.nobootanimation", value, "0");
+    mDebugNoBootAnimation = atoi(value);
+
+    LOGI_IF(mDebugRegion,           "showupdates enabled");
+    LOGI_IF(mDebugCpu,              "showcpu enabled");
+    LOGI_IF(mDebugBackground,       "showbackground enabled");
+    LOGI_IF(mDebugFps,              "showfps enabled");
+    LOGI_IF(mDebugNoBootAnimation,  "boot animation disabled");
+}
+
+SurfaceFlinger::~SurfaceFlinger()
+{
+    glDeleteTextures(1, &mWormholeTexName);
+}
+
+copybit_t* SurfaceFlinger::getBlitEngine() const
+{
+    return graphicPlane(0).displayHardware().getBlitEngine();
+}
+
+sp<IMemory> SurfaceFlinger::getCblk() const
+{
+    return mServerCblkMemory;
+}
+
+status_t SurfaceFlinger::requestGPU(const sp<IGPUCallback>& callback,
+        gpu_info_t* gpu)
+{
+    status_t err = mGPU->request(callback, gpu);
+    return err;
+}
+
+status_t SurfaceFlinger::revokeGPU()
+{
+    return mGPU->friendlyRevoke();
+}
+
+sp<ISurfaceFlingerClient> SurfaceFlinger::createConnection()
+{
+    Mutex::Autolock _l(mStateLock);
+    uint32_t token = mTokens.acquire();
+
+    Client* client = new Client(token, this);
+    if ((client == 0) || (client->ctrlblk == 0)) {
+        mTokens.release(token);
+        return 0;
+    }
+    status_t err = mClientsMap.add(token, client);
+    if (err < 0) {
+        delete client;
+        mTokens.release(token);
+        return 0;
+    }
+    sp<BClient> bclient =
+        new BClient(this, token, client->controlBlockMemory());
+    return bclient;
+}
+
+void SurfaceFlinger::destroyConnection(ClientID cid)
+{
+    Mutex::Autolock _l(mStateLock);
+    Client* const client = mClientsMap.valueFor(cid);
+    if (client) {
+        // free all the layers this client owns
+        const Vector<LayerBaseClient*>& layers = client->getLayers();
+        const size_t count = layers.size();
+        for (size_t i=0 ; i<count ; i++) {
+            LayerBaseClient* const layer = layers[i];
+            removeLayer_l(layer);
+        }
+
+        // the resources associated with this client will be freed
+        // during the next transaction, after these surfaces have been
+        // properly removed from the screen
+
+        // remove this client from our ClientID->Client mapping.
+        mClientsMap.removeItem(cid);
+
+        // and add it to the list of disconnected clients
+        mDisconnectedClients.add(client);
+
+        // request a transaction
+        setTransactionFlags(eTransactionNeeded);
+    }
+}
+
+const GraphicPlane& SurfaceFlinger::graphicPlane(int dpy) const
+{
+    LOGE_IF(uint32_t(dpy) >= DISPLAY_COUNT, "Invalid DisplayID %d", dpy);
+    const GraphicPlane& plane(mGraphicPlanes[dpy]);
+    return plane;
+}
+
+GraphicPlane& SurfaceFlinger::graphicPlane(int dpy)
+{
+    return const_cast<GraphicPlane&>(
+        const_cast<SurfaceFlinger const *>(this)->graphicPlane(dpy));
+}
+
+void SurfaceFlinger::bootFinished()
+{
+    const nsecs_t now = systemTime();
+    const nsecs_t duration = now - mBootTime;
+    LOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) );
+    if (mBootAnimation != 0) {
+        mBootAnimation->requestExit();
+        mBootAnimation.clear();
+    }
+}
+
+void SurfaceFlinger::onFirstRef()
+{
+    run("SurfaceFlinger", PRIORITY_URGENT_DISPLAY);
+
+    // Wait for the main thread to be done with its initialization
+    mReadyToRunBarrier.wait();
+}
+
+
+static inline uint16_t pack565(int r, int g, int b) {
+    return (r<<11)|(g<<5)|b;
+}
+
+// this is defined in libGLES_CM.so
+extern ISurfaceComposer* GLES_localSurfaceManager;
+
+status_t SurfaceFlinger::readyToRun()
+{
+    LOGI(   "SurfaceFlinger's main thread ready to run. "
+            "Initializing graphics H/W...");
+
+    //
+    GLES_localSurfaceManager = static_cast<ISurfaceComposer*>(this);
+
+    // we only support one display currently
+    int dpy = 0;
+
+    {
+        // initialize the main display
+        GraphicPlane& plane(graphicPlane(dpy));
+        DisplayHardware* const hw = new DisplayHardware(this, dpy);
+        plane.setDisplayHardware(hw);
+    }
+
+    // initialize primary screen
+    // (other display should be initialized in the same manner, but
+    // asynchronously, as they could come and go. None of this is supported
+    // yet).
+    const GraphicPlane& plane(graphicPlane(dpy));
+    const DisplayHardware& hw = plane.displayHardware();
+    const uint32_t w = hw.getWidth();
+    const uint32_t h = hw.getHeight();
+    const uint32_t f = hw.getFormat();
+    hw.makeCurrent();
+
+    // initialize the shared control block
+    mServerCblk->connected |= 1<<dpy;
+    display_cblk_t* dcblk = mServerCblk->displays + dpy;
+    memset(dcblk, 0, sizeof(display_cblk_t));
+    dcblk->w            = w;
+    dcblk->h            = h;
+    dcblk->format       = f;
+    dcblk->orientation  = ISurfaceComposer::eOrientationDefault;
+    dcblk->xdpi         = hw.getDpiX();
+    dcblk->ydpi         = hw.getDpiY();
+    dcblk->fps          = hw.getRefreshRate();
+    dcblk->density      = 1.0f; // XXX: do someting more real here...
+    asm volatile ("":::"memory");
+
+    // Initialize OpenGL|ES
+    glActiveTexture(GL_TEXTURE0);
+    glBindTexture(GL_TEXTURE_2D, 0);
+    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
+    glEnableClientState(GL_VERTEX_ARRAY);
+    glEnable(GL_SCISSOR_TEST);
+    glShadeModel(GL_FLAT);
+    glDisable(GL_DITHER);
+    glDisable(GL_CULL_FACE);
+
+    const uint16_t g0 = pack565(0x0F,0x1F,0x0F);
+    const uint16_t g1 = pack565(0x17,0x2f,0x17);
+    const uint16_t textureData[4] = { g0, g1, g1, g0 };
+    glGenTextures(1, &mWormholeTexName);
+    glBindTexture(GL_TEXTURE_2D, mWormholeTexName);
+    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0,
+            GL_RGB, GL_UNSIGNED_SHORT_5_6_5, textureData);
+
+    glViewport(0, 0, w, h);
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    glOrthof(0, w, h, 0, 0, 1);
+
+   LayerDim::initDimmer(this, w, h);
+
+    mReadyToRunBarrier.open();
+
+    /*
+     *  We're now ready to accept clients...
+     */
+
+    // start CPU gauge display
+    if (mDebugCpu)
+        mCpuGauge = new CPUGauge(this, ms2ns(500));
+
+    // the boot animation!
+    if (mDebugNoBootAnimation == false)
+        mBootAnimation = new BootAnimation(this);
+
+    if (ENABLE_VNC_SERVER)
+        mRFBServer = new RFBServer(w, h, f);
+
+    return NO_ERROR;
+}
+
+// ----------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#pragma mark Events Handler
+#endif
+
+void SurfaceFlinger::waitForEvent()
+{
+    // wait for something to do
+    if (UNLIKELY(isFrozen())) {
+        // wait 2 seconds
+        int err = mSyncObject.wait(ms2ns(3000));
+        if (err != NO_ERROR) {
+            if (isFrozen()) {
+                // we timed out and are still frozen
+                LOGW("timeout expired mFreezeDisplay=%d, mFreezeCount=%d",
+                        mFreezeDisplay, mFreezeCount);
+                mFreezeCount = 0;
+            }
+        }
+    } else {
+        mSyncObject.wait();
+    }
+}
+
+void SurfaceFlinger::signalEvent() {
+    mSyncObject.open();
+}
+
+void SurfaceFlinger::signal() const {
+    mSyncObject.open();
+}
+
+void SurfaceFlinger::signalDelayedEvent(nsecs_t delay)
+{
+    if (android_atomic_or(1, &mDeplayedTransactionPending) == 0) {
+        sp<DelayedTransaction> delayedEvent(new DelayedTransaction(this, delay));
+        delayedEvent->run("DelayedeEvent", PRIORITY_URGENT_DISPLAY);
+    }
+}
+
+// ----------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#pragma mark Main loop
+#endif
+
+bool SurfaceFlinger::threadLoop()
+{
+    waitForEvent();
+
+    // check for transactions
+    if (UNLIKELY(mConsoleSignals)) {
+        handleConsoleEvents();
+    }
+
+    if (LIKELY(mTransactionCount == 0)) {
+        // if we're in a global transaction, don't do anything.
+        const uint32_t mask = eTransactionNeeded | eTraversalNeeded;
+        uint32_t transactionFlags = getTransactionFlags(mask);
+        if (LIKELY(transactionFlags)) {
+            handleTransaction(transactionFlags);
+        }
+    }
+
+    // post surfaces (if needed)
+    handlePageFlip();
+
+    const DisplayHardware& hw(graphicPlane(0).displayHardware());
+    if (LIKELY(hw.canDraw())) {
+        // repaint the framebuffer (if needed)
+        handleRepaint();
+
+        // release the clients before we flip ('cause flip might block)
+        unlockClients();
+        executeScheduledBroadcasts();
+
+        // sample the cpu gauge
+        if (UNLIKELY(mDebugCpu)) {
+            handleDebugCpu();
+        }
+
+        postFramebuffer();
+    } else {
+        // pretend we did the post
+        unlockClients();
+        executeScheduledBroadcasts();
+        usleep(16667); // 60 fps period
+    }
+    return true;
+}
+
+void SurfaceFlinger::postFramebuffer()
+{
+    if (UNLIKELY(isFrozen())) {
+        // we are not allowed to draw, but pause a bit to make sure
+        // apps don't end up using the whole CPU, if they depend on
+        // surfaceflinger for synchronization.
+        usleep(8333); // 8.3ms ~ 120fps
+        return;
+    }
+
+    if (!mInvalidRegion.isEmpty()) {
+        const DisplayHardware& hw(graphicPlane(0).displayHardware());
+
+        if (UNLIKELY(mDebugFps)) {
+            debugShowFPS();
+        }
+
+        if (UNLIKELY(ENABLE_VNC_SERVER &&
+                mRFBServer!=0 && mRFBServer->isConnected())) {
+            if (!mSecureFrameBuffer) {
+                GGLSurface fb;
+                // backbufer, is going to become the front buffer really soon
+                hw.getDisplaySurface(&fb);
+                if (LIKELY(fb.data != 0)) {
+                    mRFBServer->frameBufferUpdated(fb, mInvalidRegion);
+                }
+            }
+        }
+
+        hw.flip(mInvalidRegion);
+
+        mInvalidRegion.clear();
+
+        if (Layer::deletedTextures.size()) {
+            glDeleteTextures(
+                    Layer::deletedTextures.size(),
+                    Layer::deletedTextures.array());
+            Layer::deletedTextures.clear();
+        }
+    }
+}
+
+void SurfaceFlinger::handleConsoleEvents()
+{
+    // something to do with the console
+    const DisplayHardware& hw = graphicPlane(0).displayHardware();
+
+    int what = android_atomic_and(0, &mConsoleSignals);
+    if (what & eConsoleAcquired) {
+        hw.acquireScreen();
+    }
+
+    if (mDeferReleaseConsole && hw.canDraw()) {
+        // We got the release signal before the aquire signal
+        mDeferReleaseConsole = false;
+        revokeGPU();
+        hw.releaseScreen();
+    }
+
+    if (what & eConsoleReleased) {
+        if (hw.canDraw()) {
+            revokeGPU();
+            hw.releaseScreen();
+        } else {
+            mDeferReleaseConsole = true;
+        }
+    }
+
+    mDirtyRegion.set(hw.bounds());
+}
+
+void SurfaceFlinger::handleTransaction(uint32_t transactionFlags)
+{
+    Mutex::Autolock _l(mStateLock);
+
+    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
+    const size_t count = currentLayers.size();
+
+    /*
+     * Traversal of the children
+     * (perform the transaction for each of them if needed)
+     */
+
+    const bool layersNeedTransaction = transactionFlags & eTraversalNeeded;
+    if (layersNeedTransaction) {
+        for (size_t i=0 ; i<count ; i++) {
+            LayerBase* const layer = currentLayers[i];
+            uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);
+            if (!trFlags) continue;
+
+            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));
+            }
+        }
+    }
+
+    /*
+     * Perform our own transaction if needed
+     */
+
+    if (transactionFlags & eTransactionNeeded) {
+        if (mCurrentState.orientation != mDrawingState.orientation) {
+            // the orientation has changed, recompute all visible regions
+            // and invalidate everything.
+
+            const int dpy = 0;
+            const int orientation = mCurrentState.orientation;
+            GraphicPlane& plane(graphicPlane(dpy));
+            plane.setOrientation(orientation);
+
+            // update the shared control block
+            const DisplayHardware& hw(plane.displayHardware());
+            volatile display_cblk_t* dcblk = mServerCblk->displays + dpy;
+            dcblk->orientation = orientation;
+            if (orientation & eOrientationSwapMask) {
+                // 90 or 270 degrees orientation
+                dcblk->w = hw.getHeight();
+                dcblk->h = hw.getWidth();
+            } else {
+                dcblk->w = hw.getWidth();
+                dcblk->h = hw.getHeight();
+            }
+
+            mVisibleRegionsDirty = true;
+            mDirtyRegion.set(hw.bounds());
+        }
+
+        if (mCurrentState.freezeDisplay != mDrawingState.freezeDisplay) {
+            // freezing or unfreezing the display -> trigger animation if needed
+            mFreezeDisplay = mCurrentState.freezeDisplay;
+            const nsecs_t now = systemTime();
+            if (mFreezeDisplay) {
+                mFreezeDisplayTime = now;
+            } else {
+                //LOGD("Screen was frozen for %llu us",
+                //        ns2us(now-mFreezeDisplayTime));
+            }
+        }
+
+        // some layers might have been removed, so
+        // we need to update the regions they're exposing.
+        size_t c = mRemovedLayers.size();
+        if (c) {
+            mVisibleRegionsDirty = true;
+        }
+
+        const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
+        if (currentLayers.size() > mDrawingState.layersSortedByZ.size()) {
+            // layers have been added
+            mVisibleRegionsDirty = true;
+        }
+
+        // get rid of all resources we don't need anymore
+        // (layers and clients)
+        free_resources_l();
+    }
+
+    commitTransaction();
+}
+
+sp<FreezeLock> SurfaceFlinger::getFreezeLock() const
+{
+    return new FreezeLock(const_cast<SurfaceFlinger *>(this));
+}
+
+void SurfaceFlinger::computeVisibleRegions(
+    LayerVector& currentLayers, Region& dirtyRegion, Region& opaqueRegion)
+{
+    const GraphicPlane& plane(graphicPlane(0));
+    const Transform& planeTransform(plane.transform());
+
+    Region aboveOpaqueLayers;
+    Region aboveCoveredLayers;
+    Region dirty;
+
+    bool secureFrameBuffer = false;
+
+    size_t i = currentLayers.size();
+    while (i--) {
+        LayerBase* const layer = currentLayers[i];
+        layer->validateVisibility(planeTransform);
+
+        // start with the whole surface at its current location
+        const Layer::State& s = layer->drawingState();
+        const Rect bounds(layer->visibleBounds());
+
+        // handle hidden surfaces by setting the visible region to empty
+        Region opaqueRegion;
+        Region visibleRegion;
+        Region coveredRegion;
+        if (UNLIKELY((s.flags & ISurfaceComposer::eLayerHidden) || !s.alpha)) {
+            visibleRegion.clear();
+        } else {
+            const bool translucent = layer->needsBlending();
+            visibleRegion.set(bounds);
+            coveredRegion = visibleRegion;
+
+            // Remove the transparent area from the visible region
+            if (translucent) {
+                visibleRegion.subtractSelf(layer->transparentRegionScreen);
+            }
+
+            // compute the opaque region
+            if (s.alpha==255 && !translucent && layer->getOrientation()>=0) {
+                // the opaque region is the visible region
+                opaqueRegion = visibleRegion;
+            }
+        }
+
+        // subtract the opaque region covered by the layers above us
+        visibleRegion.subtractSelf(aboveOpaqueLayers);
+        coveredRegion.andSelf(aboveCoveredLayers);
+
+        // compute this layer's dirty region
+        if (layer->invalidate) {
+            // we need to invalidate the whole region
+            dirty = visibleRegion;
+            // as well, as the old visible region
+            dirty.orSelf(layer->visibleRegionScreen);
+            layer->invalidate = false;
+        } else {
+            // compute the exposed region
+            // dirty = what's visible now - what's wasn't covered before
+            //       = what's visible now & what's was covered before
+            dirty = visibleRegion.intersect(layer->coveredRegionScreen);            
+        }
+        dirty.subtractSelf(aboveOpaqueLayers);
+
+        // accumulate to the screen dirty region
+        dirtyRegion.orSelf(dirty);
+
+        // updade aboveOpaqueLayers/aboveCoveredLayers for next (lower) layer
+        aboveOpaqueLayers.orSelf(opaqueRegion);
+        aboveCoveredLayers.orSelf(bounds);
+        
+        // Store the visible region is screen space
+        layer->setVisibleRegion(visibleRegion);
+        layer->setCoveredRegion(coveredRegion);
+
+        // If a secure layer is partially visible, lockdown the screen!
+        if (layer->isSecure() && !visibleRegion.isEmpty()) {
+            secureFrameBuffer = true;
+        }
+    }
+
+    mSecureFrameBuffer = secureFrameBuffer;
+    opaqueRegion = aboveOpaqueLayers;
+}
+
+
+void SurfaceFlinger::commitTransaction()
+{
+    mDrawingState = mCurrentState;
+    mTransactionCV.signal();
+}
+
+void SurfaceFlinger::handlePageFlip()
+{
+    bool visibleRegions = mVisibleRegionsDirty;
+    LayerVector& currentLayers = const_cast<LayerVector&>(mDrawingState.layersSortedByZ);
+    visibleRegions |= lockPageFlip(currentLayers);
+
+        const DisplayHardware& hw = graphicPlane(0).displayHardware();
+        const Region screenRegion(hw.bounds());
+        if (visibleRegions) {
+            Region opaqueRegion;
+            computeVisibleRegions(currentLayers, mDirtyRegion, opaqueRegion);
+            mWormholeRegion = screenRegion.subtract(opaqueRegion);
+            mVisibleRegionsDirty = false;
+        }
+
+    unlockPageFlip(currentLayers);
+    mDirtyRegion.andSelf(screenRegion);
+}
+
+bool SurfaceFlinger::lockPageFlip(const LayerVector& currentLayers)
+{
+    bool recomputeVisibleRegions = false;
+    size_t count = currentLayers.size();
+    LayerBase* const* layers = currentLayers.array();
+    for (size_t i=0 ; i<count ; i++) {
+        LayerBase* const layer = layers[i];
+        layer->lockPageFlip(recomputeVisibleRegions);
+    }
+    return recomputeVisibleRegions;
+}
+
+void SurfaceFlinger::unlockPageFlip(const LayerVector& currentLayers)
+{
+    const GraphicPlane& plane(graphicPlane(0));
+    const Transform& planeTransform(plane.transform());
+    size_t count = currentLayers.size();
+    LayerBase* const* layers = currentLayers.array();
+    for (size_t i=0 ; i<count ; i++) {
+        LayerBase* const layer = layers[i];
+        layer->unlockPageFlip(planeTransform, mDirtyRegion);
+    }
+}
+
+void SurfaceFlinger::handleRepaint()
+{
+    // set the frame buffer
+    const DisplayHardware& hw(graphicPlane(0).displayHardware());
+    glMatrixMode(GL_MODELVIEW);
+    glLoadIdentity();
+
+    if (UNLIKELY(mDebugRegion)) {
+        debugFlashRegions();
+    }
+
+    // compute the invalid region
+    mInvalidRegion.orSelf(mDirtyRegion);
+
+    uint32_t flags = hw.getFlags();
+    if (flags & DisplayHardware::BUFFER_PRESERVED) {
+        if (flags & DisplayHardware::COPY_BACK_EXTENSION) {
+            // yay. nothing to do here.
+        } else {
+            if (flags & DisplayHardware::UPDATE_ON_DEMAND) {
+                // we need to fully redraw the part that will be updated
+                mDirtyRegion.set(mInvalidRegion.bounds());
+            } else {
+                // TODO: we only need te redraw the part that had been drawn
+                // the round before and is not drawn now
+            }
+        }
+    } else {
+        // COPY_BACK_EXTENSION makes no sense here
+        if (flags & DisplayHardware::UPDATE_ON_DEMAND) {
+            // we need to fully redraw the part that will be updated
+            mDirtyRegion.set(mInvalidRegion.bounds());
+        } else {
+            // we need to redraw everything
+            mDirtyRegion.set(hw.bounds());
+            mInvalidRegion = mDirtyRegion;
+        }
+    }
+
+    // compose all surfaces
+    composeSurfaces(mDirtyRegion);
+
+    // clear the dirty regions
+    mDirtyRegion.clear();
+}
+
+void SurfaceFlinger::composeSurfaces(const Region& dirty)
+{
+    if (UNLIKELY(!mWormholeRegion.isEmpty())) {
+        // should never happen unless the window manager has a bug
+        // draw something...
+        drawWormhole();
+    }
+    const SurfaceFlinger& flinger(*this);
+    const LayerVector& drawingLayers(mDrawingState.layersSortedByZ);
+    const size_t count = drawingLayers.size();
+    LayerBase const* const* const layers = drawingLayers.array();
+    for (size_t i=0 ; i<count ; ++i) {
+        LayerBase const * const layer = layers[i];
+        const Region& visibleRegion(layer->visibleRegionScreen);
+        if (!visibleRegion.isEmpty())  {
+            const Region clip(dirty.intersect(visibleRegion));
+            if (!clip.isEmpty()) {
+                layer->draw(clip);
+            }
+        }
+    }
+}
+
+void SurfaceFlinger::unlockClients()
+{
+    const LayerVector& drawingLayers(mDrawingState.layersSortedByZ);
+    const size_t count = drawingLayers.size();
+    LayerBase* const* const layers = drawingLayers.array();
+    for (size_t i=0 ; i<count ; ++i) {
+        LayerBase* const layer = layers[i];
+        layer->finishPageFlip();
+    }
+}
+
+void SurfaceFlinger::scheduleBroadcast(Client* client)
+{
+    if (mLastScheduledBroadcast != client) {
+        mLastScheduledBroadcast = client;
+        mScheduledBroadcasts.add(client);
+    }
+}
+
+void SurfaceFlinger::executeScheduledBroadcasts()
+{
+    SortedVector<Client*>& list = mScheduledBroadcasts;
+    size_t count = list.size();
+    while (count--) {
+        per_client_cblk_t* const cblk = list[count]->ctrlblk;
+        if (cblk->lock.tryLock() == NO_ERROR) {
+            cblk->cv.broadcast();
+            list.removeAt(count);
+            cblk->lock.unlock();
+        } else {
+            // schedule another round
+            LOGW("executeScheduledBroadcasts() skipped, "
+                "contention on the client. We'll try again later...");
+            signalDelayedEvent(ms2ns(4));
+        }
+    }
+    mLastScheduledBroadcast = 0;
+}
+
+void SurfaceFlinger::handleDebugCpu()
+{
+    Mutex::Autolock _l(mDebugLock);
+    if (mCpuGauge != 0)
+        mCpuGauge->sample();
+}
+
+void SurfaceFlinger::debugFlashRegions()
+{
+    if (UNLIKELY(!mDirtyRegion.isRect())) {
+        // TODO: do this only if we don't have preserving
+        // swapBuffer. If we don't have update-on-demand,
+        // redraw everything.
+        composeSurfaces(Region(mDirtyRegion.bounds()));
+    }
+
+    glDisable(GL_TEXTURE_2D);
+    glDisable(GL_BLEND);
+    glDisable(GL_DITHER);
+    glDisable(GL_SCISSOR_TEST);
+
+    glColor4x(0x10000, 0, 0x10000, 0x10000);
+
+    Rect r;
+    Region::iterator iterator(mDirtyRegion);
+    while (iterator.iterate(&r)) {
+        GLfloat vertices[][2] = {
+                { r.left,  r.top },
+                { r.left,  r.bottom },
+                { r.right, r.bottom },
+                { r.right, r.top }
+        };
+        glVertexPointer(2, GL_FLOAT, 0, vertices);
+        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+    }
+
+    const DisplayHardware& hw(graphicPlane(0).displayHardware());
+    hw.flip(mDirtyRegion.merge(mInvalidRegion));
+    mInvalidRegion.clear();
+
+    if (mDebugRegion > 1)
+       usleep(mDebugRegion * 1000);
+
+    glEnable(GL_SCISSOR_TEST);
+    //mDirtyRegion.dump("mDirtyRegion");
+}
+
+void SurfaceFlinger::drawWormhole() const
+{
+    const Region region(mWormholeRegion.intersect(mDirtyRegion));
+    if (region.isEmpty())
+        return;
+
+    const DisplayHardware& hw(graphicPlane(0).displayHardware());
+    const int32_t width = hw.getWidth();
+    const int32_t height = hw.getHeight();
+
+    glDisable(GL_BLEND);
+    glDisable(GL_DITHER);
+
+    if (LIKELY(!mDebugBackground)) {
+        glClearColorx(0,0,0,0);
+        Rect r;
+        Region::iterator iterator(region);
+        while (iterator.iterate(&r)) {
+            const GLint sy = height - (r.top + r.height());
+            glScissor(r.left, sy, r.width(), r.height());
+            glClear(GL_COLOR_BUFFER_BIT);
+        }
+    } else {
+        const GLshort vertices[][2] = { { 0, 0 }, { width, 0 },
+                { width, height }, { 0, height }  };
+        const GLshort tcoords[][2] = { { 0, 0 }, { 1, 0 },  { 1, 1 }, { 0, 1 } };
+        glVertexPointer(2, GL_SHORT, 0, vertices);
+        glTexCoordPointer(2, GL_SHORT, 0, tcoords);
+        glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+        glEnable(GL_TEXTURE_2D);
+        glBindTexture(GL_TEXTURE_2D, mWormholeTexName);
+        glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+        glMatrixMode(GL_TEXTURE);
+        glLoadIdentity();
+        glScalef(width*(1.0f/32.0f), height*(1.0f/32.0f), 1);
+        Rect r;
+        Region::iterator iterator(region);
+        while (iterator.iterate(&r)) {
+            const GLint sy = height - (r.top + r.height());
+            glScissor(r.left, sy, r.width(), r.height());
+            glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+        }
+        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+    }
+}
+
+void SurfaceFlinger::debugShowFPS() const
+{
+    static int mFrameCount;
+    static int mLastFrameCount = 0;
+    static nsecs_t mLastFpsTime = 0;
+    static float mFps = 0;
+    mFrameCount++;
+    nsecs_t now = systemTime();
+    nsecs_t diff = now - mLastFpsTime;
+    if (diff > ms2ns(250)) {
+        mFps =  ((mFrameCount - mLastFrameCount) * float(s2ns(1))) / diff;
+        mLastFpsTime = now;
+        mLastFrameCount = mFrameCount;
+    }
+    // XXX: mFPS has the value we want
+ }
+
+status_t SurfaceFlinger::addLayer_l(LayerBase* layer)
+{
+    ssize_t i = mCurrentState.layersSortedByZ.add(
+                layer, &LayerBase::compareCurrentStateZ);
+    LayerBaseClient* lbc = LayerBase::dynamicCast<LayerBaseClient*>(layer);
+    if (lbc) {
+        mLayerMap.add(lbc->serverIndex(), lbc);
+    }
+    mRemovedLayers.remove(layer);
+    return NO_ERROR;
+}
+
+status_t SurfaceFlinger::removeLayer_l(LayerBase* layerBase)
+{
+    ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase);
+    if (index >= 0) {
+        mRemovedLayers.add(layerBase);
+        LayerBaseClient* layer = LayerBase::dynamicCast<LayerBaseClient*>(layerBase);
+        if (layer) {
+            mLayerMap.removeItem(layer->serverIndex());
+        }
+        return NO_ERROR;
+    }
+    // it's possible that we don't find a layer, because it might
+    // have been destroyed already -- this is not technically an error
+    // from the user because there is a race between destroySurface,
+    // destroyclient and destroySurface-from-a-transaction.
+    return (index == NAME_NOT_FOUND) ? status_t(NO_ERROR) : index;
+}
+
+void SurfaceFlinger::free_resources_l()
+{
+    // Destroy layers that were removed
+    destroy_all_removed_layers_l();
+
+    // free resources associated with disconnected clients
+    SortedVector<Client*>& scheduledBroadcasts(mScheduledBroadcasts);
+    Vector<Client*>& disconnectedClients(mDisconnectedClients);
+    const size_t count = disconnectedClients.size();
+    for (size_t i=0 ; i<count ; i++) {
+        Client* client = disconnectedClients[i];
+        // if this client is the scheduled broadcast list,
+        // remove it from there (and we don't need to signal it
+        // since it is dead).
+        int32_t index = scheduledBroadcasts.indexOf(client);
+        if (index >= 0) {
+            scheduledBroadcasts.removeItemsAt(index);
+        }
+        mTokens.release(client->cid);
+        delete client;
+    }
+    disconnectedClients.clear();
+}
+
+void SurfaceFlinger::destroy_all_removed_layers_l()
+{
+    size_t c = mRemovedLayers.size();
+    while (c--) {
+        LayerBase* const removed_layer = mRemovedLayers[c];
+
+        LOGE_IF(mCurrentState.layersSortedByZ.indexOf(removed_layer) >= 0,
+            "layer %p removed but still in the current state list",
+            removed_layer);
+
+        delete removed_layer;
+    }
+    mRemovedLayers.clear();
+}
+
+
+uint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags)
+{
+    return android_atomic_and(~flags, &mTransactionFlags) & flags;
+}
+
+uint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags, nsecs_t delay)
+{
+    uint32_t old = android_atomic_or(flags, &mTransactionFlags);
+    if ((old & flags)==0) { // wake the server up
+        if (delay > 0) {
+            signalDelayedEvent(delay);
+        } else {
+            signalEvent();
+        }
+    }
+    return old;
+}
+
+void SurfaceFlinger::openGlobalTransaction()
+{
+    android_atomic_inc(&mTransactionCount);
+}
+
+void SurfaceFlinger::closeGlobalTransaction()
+{
+    if (android_atomic_dec(&mTransactionCount) == 1) {
+        signalEvent();
+    }
+}
+
+status_t SurfaceFlinger::freezeDisplay(DisplayID dpy, uint32_t flags)
+{
+    if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
+        return BAD_VALUE;
+
+    Mutex::Autolock _l(mStateLock);
+    mCurrentState.freezeDisplay = 1;
+    setTransactionFlags(eTransactionNeeded);
+
+    // flags is intended to communicate some sort of animation behavior
+    // (for instance fadding)
+    return NO_ERROR;
+}
+
+status_t SurfaceFlinger::unfreezeDisplay(DisplayID dpy, uint32_t flags)
+{
+    if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
+        return BAD_VALUE;
+
+    Mutex::Autolock _l(mStateLock);
+    mCurrentState.freezeDisplay = 0;
+    setTransactionFlags(eTransactionNeeded);
+
+    // flags is intended to communicate some sort of animation behavior
+    // (for instance fadding)
+    return NO_ERROR;
+}
+
+int SurfaceFlinger::setOrientation(DisplayID dpy, int orientation)
+{
+    if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
+        return BAD_VALUE;
+
+    Mutex::Autolock _l(mStateLock);
+    if (mCurrentState.orientation != orientation) {
+        if (uint32_t(orientation)<=eOrientation270 || orientation==42) {
+            mCurrentState.orientation = orientation;
+            setTransactionFlags(eTransactionNeeded);
+            mTransactionCV.wait(mStateLock);
+        } else {
+            orientation = BAD_VALUE;
+        }
+    }
+    return orientation;
+}
+
+sp<ISurface> SurfaceFlinger::createSurface(ClientID clientId, int pid,
+        ISurfaceFlingerClient::surface_data_t* params,
+        DisplayID d, uint32_t w, uint32_t h, PixelFormat format,
+        uint32_t flags)
+{
+    LayerBaseClient* layer = 0;
+    sp<LayerBaseClient::Surface> surfaceHandle;
+    Mutex::Autolock _l(mStateLock);
+    Client* const c = mClientsMap.valueFor(clientId);
+    if (UNLIKELY(!c)) {
+        LOGE("createSurface() failed, client not found (id=%d)", clientId);
+        return surfaceHandle;
+    }
+
+    //LOGD("createSurface for pid %d (%d x %d)", pid, w, h);
+    int32_t id = c->generateId(pid);
+    if (uint32_t(id) >= NUM_LAYERS_MAX) {
+        LOGE("createSurface() failed, generateId = %d", id);
+        return surfaceHandle;
+    }
+
+    switch (flags & eFXSurfaceMask) {
+        case eFXSurfaceNormal:
+            if (UNLIKELY(flags & ePushBuffers)) {
+                layer = createPushBuffersSurfaceLocked(c, d, id, w, h, flags);
+            } else {
+                layer = createNormalSurfaceLocked(c, d, id, w, h, format, flags);
+            }
+            break;
+        case eFXSurfaceBlur:
+            layer = createBlurSurfaceLocked(c, d, id, w, h, flags);
+            break;
+        case eFXSurfaceDim:
+            layer = createDimSurfaceLocked(c, d, id, w, h, flags);
+            break;
+    }
+
+    if (layer) {
+        setTransactionFlags(eTransactionNeeded);
+        surfaceHandle = layer->getSurface();
+        if (surfaceHandle != 0)
+            surfaceHandle->getSurfaceData(params);
+    }
+
+    return surfaceHandle;
+}
+
+LayerBaseClient* SurfaceFlinger::createNormalSurfaceLocked(
+        Client* client, DisplayID display,
+        int32_t id, uint32_t w, uint32_t h, PixelFormat format, uint32_t flags)
+{
+    // initialize the surfaces
+    switch (format) { // TODO: take h/w into account
+    case PIXEL_FORMAT_TRANSPARENT:
+    case PIXEL_FORMAT_TRANSLUCENT:
+        format = PIXEL_FORMAT_RGBA_8888;
+        break;
+    case PIXEL_FORMAT_OPAQUE:
+        format = PIXEL_FORMAT_RGB_565;
+        break;
+    }
+
+    Layer* layer = new Layer(this, display, client, id);
+    status_t err = layer->setBuffers(client, w, h, format, flags);
+    if (LIKELY(err == NO_ERROR)) {
+        layer->initStates(w, h, flags);
+        addLayer_l(layer);
+    } else {
+        LOGE("createNormalSurfaceLocked() failed (%s)", strerror(-err));
+        delete layer;
+        return 0;
+    }
+    return layer;
+}
+
+LayerBaseClient* SurfaceFlinger::createBlurSurfaceLocked(
+        Client* client, DisplayID display,
+        int32_t id, uint32_t w, uint32_t h, uint32_t flags)
+{
+    LayerBlur* layer = new LayerBlur(this, display, client, id);
+    layer->initStates(w, h, flags);
+    addLayer_l(layer);
+    return layer;
+}
+
+LayerBaseClient* SurfaceFlinger::createDimSurfaceLocked(
+        Client* client, DisplayID display,
+        int32_t id, uint32_t w, uint32_t h, uint32_t flags)
+{
+    LayerDim* layer = new LayerDim(this, display, client, id);
+    layer->initStates(w, h, flags);
+    addLayer_l(layer);
+    return layer;
+}
+
+LayerBaseClient* SurfaceFlinger::createPushBuffersSurfaceLocked(
+        Client* client, DisplayID display,
+        int32_t id, uint32_t w, uint32_t h, uint32_t flags)
+{
+    LayerBuffer* layer = new LayerBuffer(this, display, client, id);
+    layer->initStates(w, h, flags);
+    addLayer_l(layer);
+    return layer;
+}
+
+status_t SurfaceFlinger::destroySurface(SurfaceID index)
+{
+    Mutex::Autolock _l(mStateLock);
+    LayerBaseClient* const layer = getLayerUser_l(index);
+    status_t err = removeLayer_l(layer);
+    if (err < 0)
+        return err;
+    setTransactionFlags(eTransactionNeeded);
+    return NO_ERROR;
+}
+
+status_t SurfaceFlinger::setClientState(
+        ClientID cid,
+        int32_t count,
+        const layer_state_t* states)
+{
+    Mutex::Autolock _l(mStateLock);
+    uint32_t flags = 0;
+    cid <<= 16;
+    for (int i=0 ; i<count ; i++) {
+        const layer_state_t& s = states[i];
+        LayerBaseClient* layer = getLayerUser_l(s.surface | cid);
+        if (layer) {
+            const uint32_t what = s.what;
+            // check if it has been destroyed first
+            if (what & eDestroyed) {
+                if (removeLayer_l(layer) == NO_ERROR) {
+                    flags |= eTransactionNeeded;
+                    // we skip everything else... well, no, not really
+                    // we skip ONLY that transaction.
+                    continue;
+                }
+            }
+            if (what & ePositionChanged) {
+                if (layer->setPosition(s.x, s.y))
+                    flags |= eTraversalNeeded;
+            }
+            if (what & eLayerChanged) {
+                if (layer->setLayer(s.z)) {
+                    mCurrentState.layersSortedByZ.reorder(
+                            layer, &Layer::compareCurrentStateZ);
+                    // we need traversal (state changed)
+                    // AND transaction (list changed)
+                    flags |= eTransactionNeeded|eTraversalNeeded;
+                }
+            }
+            if (what & eSizeChanged) {
+                if (layer->setSize(s.w, s.h))
+                    flags |= eTraversalNeeded;
+            }
+            if (what & eAlphaChanged) {
+                if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f)))
+                    flags |= eTraversalNeeded;
+            }
+            if (what & eMatrixChanged) {
+                if (layer->setMatrix(s.matrix))
+                    flags |= eTraversalNeeded;
+            }
+            if (what & eTransparentRegionChanged) {
+                if (layer->setTransparentRegionHint(s.transparentRegion))
+                    flags |= eTraversalNeeded;
+            }
+            if (what & eVisibilityChanged) {
+                if (layer->setFlags(s.flags, s.mask))
+                    flags |= eTraversalNeeded;
+            }
+        }
+    }
+    if (flags) {
+        setTransactionFlags(flags);
+    }
+    return NO_ERROR;
+}
+
+LayerBaseClient* SurfaceFlinger::getLayerUser_l(SurfaceID s) const
+{
+    return mLayerMap.valueFor(s);
+}
+
+void SurfaceFlinger::screenReleased(int dpy)
+{
+    // this may be called by a signal handler, we can't do too much in here
+    android_atomic_or(eConsoleReleased, &mConsoleSignals);
+    signalEvent();
+}
+
+void SurfaceFlinger::screenAcquired(int dpy)
+{
+    // this may be called by a signal handler, we can't do too much in here
+    android_atomic_or(eConsoleAcquired, &mConsoleSignals);
+    signalEvent();
+}
+
+status_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
+{
+    const size_t SIZE = 1024;
+    char buffer[SIZE];
+    String8 result;
+    if (checkCallingPermission(
+            String16("android.permission.DUMP")) == false)
+    { // not allowed
+        snprintf(buffer, SIZE, "Permission Denial: "
+                "can't dump SurfaceFlinger from pid=%d, uid=%d\n",
+                IPCThreadState::self()->getCallingPid(),
+                IPCThreadState::self()->getCallingUid());
+        result.append(buffer);
+    } else {
+        Mutex::Autolock _l(mStateLock);
+        size_t s = mClientsMap.size();
+        char name[64];
+        for (size_t i=0 ; i<s ; i++) {
+            Client* client = mClientsMap.valueAt(i);
+            sprintf(name, "  Client (id=0x%08x)", client->cid);
+            client->dump(name);
+        }
+        const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
+        const size_t count = currentLayers.size();
+        for (size_t i=0 ; i<count ; i++) {
+            /*** LayerBase ***/
+            LayerBase const * const layer = currentLayers[i];
+            const Layer::State& s = layer->drawingState();
+            snprintf(buffer, SIZE,
+                    "+ %s %p\n"
+                    "      "
+                    "z=%9d, pos=(%4d,%4d), size=(%4d,%4d), "
+                    "needsBlending=%1d, invalidate=%1d, "
+                    "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n",
+                    layer->getTypeID(), layer,
+                    s.z, layer->tx(), layer->ty(), s.w, s.h,
+                    layer->needsBlending(), layer->invalidate,
+                    s.alpha, s.flags,
+                    s.transform[0], s.transform[1],
+                    s.transform[2], s.transform[3]);
+            result.append(buffer);
+            buffer[0] = 0;
+            /*** LayerBaseClient ***/
+            LayerBaseClient* const lbc =
+                LayerBase::dynamicCast<LayerBaseClient*>((LayerBase*)layer);
+            if (lbc) {
+                snprintf(buffer, SIZE,
+                        "      "
+                        "id=0x%08x, client=0x%08x, identity=%u\n",
+                        lbc->clientIndex(), lbc->client ? lbc->client->cid : 0,
+                        lbc->getIdentity());
+            }
+            result.append(buffer);
+            buffer[0] = 0;
+            /*** LayerBuffer ***/
+            LayerBuffer* const lbuf =
+                LayerBase::dynamicCast<LayerBuffer*>((LayerBase*)layer);
+            if (lbuf) {
+                sp<LayerBuffer::Buffer> lbb(lbuf->getBuffer());
+                if (lbb != 0) {
+                    const LayerBuffer::NativeBuffer& nbuf(lbb->getBuffer());
+                    snprintf(buffer, SIZE,
+                            "      "
+                            "mBuffer={w=%u, h=%u, f=%d, offset=%u, base=%p, fd=%d }\n",
+                            nbuf.img.w, nbuf.img.h, nbuf.img.format, nbuf.img.offset,
+                            nbuf.img.base, nbuf.img.fd);
+                }
+            }
+            result.append(buffer);
+            buffer[0] = 0;
+            /*** Layer ***/
+            Layer* const l = LayerBase::dynamicCast<Layer*>((LayerBase*)layer);
+            if (l) {
+                const LayerBitmap& buf0(l->getBuffer(0));
+                const LayerBitmap& buf1(l->getBuffer(1));
+                snprintf(buffer, SIZE,
+                        "      "
+                        "format=%2d, [%3ux%3u:%3u] [%3ux%3u:%3u], mTextureName=%d,"
+                        " freezeLock=%p, swapState=0x%08x\n",
+                        l->pixelFormat(),
+                        buf0.width(), buf0.height(), buf0.stride(),
+                        buf1.width(), buf1.height(), buf1.stride(),
+                        l->getTextureName(), l->getFreezeLock().get(),
+                        l->lcblk->swapState);
+            }
+            result.append(buffer);
+            buffer[0] = 0;
+            s.transparentRegion.dump(result, "transparentRegion");
+            layer->transparentRegionScreen.dump(result, "transparentRegionScreen");
+            layer->visibleRegionScreen.dump(result, "visibleRegionScreen");
+        }
+        mWormholeRegion.dump(result, "WormholeRegion");
+        const DisplayHardware& hw(graphicPlane(0).displayHardware());
+        snprintf(buffer, SIZE,
+                "  display frozen: %s, freezeCount=%d, orientation=%d, canDraw=%d\n",
+                mFreezeDisplay?"yes":"no", mFreezeCount,
+                mCurrentState.orientation, hw.canDraw());
+        result.append(buffer);
+
+        sp<AllocatorInterface> allocator;
+        if (mGPU != 0) {
+            snprintf(buffer, SIZE, "  GPU owner: %d\n", mGPU->getOwner());
+            result.append(buffer);
+            allocator = mGPU->getAllocator();
+            if (allocator != 0) {
+                allocator->dump(result, "GPU Allocator");
+            }
+        }
+        allocator = mSurfaceHeapManager->getAllocator(NATIVE_MEMORY_TYPE_PMEM);
+        if (allocator != 0) {
+            allocator->dump(result, "PMEM Allocator");
+        }
+    }
+    write(fd, result.string(), result.size());
+    return NO_ERROR;
+}
+
+status_t SurfaceFlinger::onTransact(
+    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    switch (code) {
+        case CREATE_CONNECTION:
+        case OPEN_GLOBAL_TRANSACTION:
+        case CLOSE_GLOBAL_TRANSACTION:
+        case SET_ORIENTATION:
+        case FREEZE_DISPLAY:
+        case UNFREEZE_DISPLAY:
+        case BOOT_FINISHED:
+        case REVOKE_GPU:
+        {
+            // codes that require permission check
+            IPCThreadState* ipc = IPCThreadState::self();
+            const int pid = ipc->getCallingPid();
+            const int self_pid = getpid();
+            if (UNLIKELY(pid != self_pid)) {
+                // we're called from a different process, do the real check
+                if (!checkCallingPermission(
+                        String16("android.permission.ACCESS_SURFACE_FLINGER")))
+                {
+                    const int uid = ipc->getCallingUid();
+                    LOGE("Permission Denial: "
+                            "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
+                    return PERMISSION_DENIED;
+                }
+            }
+        }
+    }
+
+    status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags);
+    if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) {
+        if (code == 1012) {
+            // take screen-shot of the front buffer
+            if (UNLIKELY(checkCallingPermission(
+                    String16("android.permission.READ_FRAME_BUFFER")) == false))
+            { // not allowed
+                LOGE("Permission Denial: "
+                        "can't take screenshots from pid=%d, uid=%d\n",
+                        IPCThreadState::self()->getCallingPid(),
+                        IPCThreadState::self()->getCallingUid());
+                return PERMISSION_DENIED;
+            }
+
+            if (UNLIKELY(mSecureFrameBuffer)) {
+                LOGE("A secure window is on screen: "
+                        "can't take screenshots from pid=%d, uid=%d\n",
+                        IPCThreadState::self()->getCallingPid(),
+                        IPCThreadState::self()->getCallingUid());
+                return PERMISSION_DENIED;
+            }
+
+            LOGI("Taking a screenshot...");
+
+            LayerScreenshot* l = new LayerScreenshot(this, 0);
+
+            Mutex::Autolock _l(mStateLock);
+            const DisplayHardware& hw(graphicPlane(0).displayHardware());
+            l->initStates(hw.getWidth(), hw.getHeight(), 0);
+            l->setLayer(INT_MAX);
+
+            addLayer_l(l);
+            setTransactionFlags(eTransactionNeeded|eTraversalNeeded);
+
+            l->takeScreenshot(mStateLock, reply);
+
+            removeLayer_l(l);
+            setTransactionFlags(eTransactionNeeded);
+            return NO_ERROR;
+        } else {
+            // HARDWARE_TEST stuff...
+            if (UNLIKELY(checkCallingPermission(
+                    String16("android.permission.HARDWARE_TEST")) == false))
+            { // not allowed
+                LOGE("Permission Denial: pid=%d, uid=%d\n",
+                        IPCThreadState::self()->getCallingPid(),
+                        IPCThreadState::self()->getCallingUid());
+                return PERMISSION_DENIED;
+            }
+            int n;
+            switch (code) {
+            case 1000: // SHOW_CPU
+                n = data.readInt32();
+                mDebugCpu = n ? 1 : 0;
+                if (mDebugCpu) {
+                    if (mCpuGauge == 0) {
+                        mCpuGauge = new CPUGauge(this, ms2ns(500));
+                    }
+                } else {
+                    if (mCpuGauge != 0) {
+                        mCpuGauge->requestExitAndWait();
+                        Mutex::Autolock _l(mDebugLock);
+                        mCpuGauge.clear();
+                    }
+                }
+                return NO_ERROR;
+            case 1001:  // SHOW_FPS
+                n = data.readInt32();
+                mDebugFps = n ? 1 : 0;
+                return NO_ERROR;
+            case 1002:  // SHOW_UPDATES
+                n = data.readInt32();
+                mDebugRegion = n ? n : (mDebugRegion ? 0 : 1);
+                return NO_ERROR;
+            case 1003:  // SHOW_BACKGROUND
+                n = data.readInt32();
+                mDebugBackground = n ? 1 : 0;
+                return NO_ERROR;
+            case 1004:{ // repaint everything
+                Mutex::Autolock _l(mStateLock);
+                const DisplayHardware& hw(graphicPlane(0).displayHardware());
+                mDirtyRegion.set(hw.bounds()); // careful that's not thread-safe
+                signalEvent();
+                }
+                return NO_ERROR;
+            case 1005: // ask GPU revoke
+                mGPU->friendlyRevoke();
+                return NO_ERROR;
+            case 1006: // revoke GPU
+                mGPU->unconditionalRevoke();
+                return NO_ERROR;
+            case 1007: // set mFreezeCount
+                mFreezeCount = data.readInt32();
+                return NO_ERROR;
+            case 1010:  // interrogate.
+                reply->writeInt32(mDebugCpu);
+                reply->writeInt32(0);
+                reply->writeInt32(mDebugRegion);
+                reply->writeInt32(mDebugBackground);
+                return NO_ERROR;
+            case 1013: { // screenshot
+                Mutex::Autolock _l(mStateLock);
+                const DisplayHardware& hw(graphicPlane(0).displayHardware());
+                reply->writeInt32(hw.getPageFlipCount());
+            }
+            return NO_ERROR;
+            }
+        }
+    }
+    return err;
+}
+
+// ---------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#endif
+
+Client::Client(ClientID clientID, const sp<SurfaceFlinger>& flinger)
+    : ctrlblk(0), cid(clientID), mPid(0), mBitmap(0), mFlinger(flinger)
+{
+    mSharedHeapAllocator = getSurfaceHeapManager()->createHeap(NATIVE_MEMORY_TYPE_HEAP);
+    const int pgsize = getpagesize();
+    const int cblksize=((sizeof(per_client_cblk_t)+(pgsize-1))&~(pgsize-1));
+    mCblkHeap = new MemoryDealer(cblksize);
+    mCblkMemory = mCblkHeap->allocate(cblksize);
+    if (mCblkMemory != 0) {
+        ctrlblk = static_cast<per_client_cblk_t *>(mCblkMemory->pointer());
+        if (ctrlblk) { // construct the shared structure in-place.
+            new(ctrlblk) per_client_cblk_t;
+        }
+    }
+}
+
+Client::~Client() {
+    if (ctrlblk) {
+        const int pgsize = getpagesize();
+        ctrlblk->~per_client_cblk_t();  // destroy our shared-structure.
+    }
+}
+
+const sp<SurfaceHeapManager>& Client::getSurfaceHeapManager() const {
+    return mFlinger->getSurfaceHeapManager();
+}
+
+const sp<GPUHardwareInterface>& Client::getGPU() const {
+    return mFlinger->getGPU();
+}
+
+int32_t Client::generateId(int pid)
+{
+    const uint32_t i = clz( ~mBitmap );
+    if (i >= NUM_LAYERS_MAX) {
+        return NO_MEMORY;
+    }
+    mPid = pid;
+    mInUse.add(uint8_t(i));
+    mBitmap |= 1<<(31-i);
+    return i;
+}
+status_t Client::bindLayer(LayerBaseClient* layer, int32_t id)
+{
+    ssize_t idx = mInUse.indexOf(id);
+    if (idx < 0)
+        return NAME_NOT_FOUND;
+    return mLayers.insertAt(layer, idx);
+}
+void Client::free(int32_t id)
+{
+    ssize_t idx = mInUse.remove(uint8_t(id));
+    if (idx >= 0) {
+        mBitmap &= ~(1<<(31-id));
+        mLayers.removeItemsAt(idx);
+    }
+}
+
+sp<MemoryDealer> Client::createAllocator(int memory_type)
+{
+    sp<MemoryDealer> allocator;
+    if (memory_type == NATIVE_MEMORY_TYPE_GPU) {
+        allocator = getGPU()->request(getClientPid());
+        if (allocator == 0)
+            memory_type = NATIVE_MEMORY_TYPE_PMEM;
+    }
+    if (memory_type == NATIVE_MEMORY_TYPE_PMEM) {
+        allocator = mPMemAllocator;
+        if (allocator == 0) {
+            allocator = getSurfaceHeapManager()->createHeap(
+                    NATIVE_MEMORY_TYPE_PMEM);
+            mPMemAllocator = allocator;
+        }
+    }
+    if (allocator == 0)
+        allocator = mSharedHeapAllocator;
+
+    return allocator;
+}
+
+bool Client::isValid(int32_t i) const {
+    return (uint32_t(i)<NUM_LAYERS_MAX) && (mBitmap & (1<<(31-i)));
+}
+const uint8_t* Client::inUseArray() const {
+    return mInUse.array();
+}
+size_t Client::numActiveLayers() const {
+    return mInUse.size();
+}
+LayerBaseClient* Client::getLayerUser(int32_t i) const {
+    ssize_t idx = mInUse.indexOf(uint8_t(i));
+    if (idx<0) return 0;
+    return mLayers[idx];
+}
+
+void Client::dump(const char* what)
+{
+}
+
+// ---------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#endif
+
+BClient::BClient(SurfaceFlinger *flinger, ClientID cid, const sp<IMemory>& cblk)
+    : mId(cid), mFlinger(flinger), mCblk(cblk)
+{
+}
+
+BClient::~BClient() {
+    // destroy all resources attached to this client
+    mFlinger->destroyConnection(mId);
+}
+
+void BClient::getControlBlocks(sp<IMemory>* ctrl) const {
+    *ctrl = mCblk;
+}
+
+sp<ISurface> BClient::createSurface(
+        ISurfaceFlingerClient::surface_data_t* params, int pid,
+        DisplayID display, uint32_t w, uint32_t h, PixelFormat format,
+        uint32_t flags)
+{
+    return mFlinger->createSurface(mId, pid, params, display, w, h, format, flags);
+}
+
+status_t BClient::destroySurface(SurfaceID sid)
+{
+    sid |= (mId << 16); // add the client-part to id
+    return mFlinger->destroySurface(sid);
+}
+
+status_t BClient::setState(int32_t count, const layer_state_t* states)
+{
+    return mFlinger->setClientState(mId, count, states);
+}
+
+// ---------------------------------------------------------------------------
+
+GraphicPlane::GraphicPlane()
+    : mHw(0)
+{
+}
+
+GraphicPlane::~GraphicPlane() {
+    delete mHw;
+}
+
+bool GraphicPlane::initialized() const {
+    return mHw ? true : false;
+}
+
+void GraphicPlane::setDisplayHardware(DisplayHardware *hw) {
+    mHw = hw;
+}
+
+void GraphicPlane::setTransform(const Transform& tr) {
+    mTransform = tr;
+    mGlobalTransform = mOrientationTransform * mTransform;
+}
+
+status_t GraphicPlane::setOrientation(int orientation)
+{
+    float a, b, c, d, x, y;
+
+    const DisplayHardware& hw(displayHardware());
+    const float w = hw.getWidth();
+    const float h = hw.getHeight();
+
+    if (orientation == ISurfaceComposer::eOrientationDefault) {
+        // make sure the default orientation is optimal
+        mOrientationTransform.reset();
+        mGlobalTransform = mTransform;
+        return NO_ERROR;
+    }
+
+    // If the rotation can be handled in hardware, this is where
+    // the magic should happen.
+
+    switch (orientation) {
+    case ISurfaceComposer::eOrientation90:
+        a=0; b=-1; c=1; d=0; x=w; y=0;
+        break;
+    case ISurfaceComposer::eOrientation180:
+        a=-1; b=0; c=0; d=-1; x=w; y=h;
+        break;
+    case ISurfaceComposer::eOrientation270:
+        a=0; b=1; c=-1; d=0; x=0; y=h;
+        break;
+    case 42: {
+        const float r = (3.14159265f / 180.0f) * 42.0f;
+        const float si = sinf(r);
+        const float co = cosf(r);
+        a=co; b=-si; c=si; d=co;
+        x = si*(h*0.5f) + (1-co)*(w*0.5f);
+        y =-si*(w*0.5f) + (1-co)*(h*0.5f);
+    } break;
+    default:
+        return BAD_VALUE;
+    }
+    mOrientationTransform.set(a, b, c, d);
+    mOrientationTransform.set(x, y);
+    mGlobalTransform = mOrientationTransform * mTransform;
+    return NO_ERROR;
+}
+
+const DisplayHardware& GraphicPlane::displayHardware() const {
+    return *mHw;
+}
+
+const Transform& GraphicPlane::transform() const {
+    return mGlobalTransform;
+}
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
diff --git a/libs/surfaceflinger/SurfaceFlinger.h b/libs/surfaceflinger/SurfaceFlinger.h
new file mode 100644
index 0000000..1581474
--- /dev/null
+++ b/libs/surfaceflinger/SurfaceFlinger.h
@@ -0,0 +1,433 @@
+/*
+ * 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_SURFACE_FLINGER_H
+#define ANDROID_SURFACE_FLINGER_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/SortedVector.h>
+#include <utils/KeyedVector.h>
+#include <utils/threads.h>
+#include <utils/Atomic.h>
+#include <utils/Errors.h>
+#include <utils/MemoryDealer.h>
+
+#include <ui/PixelFormat.h>
+#include <ui/ISurfaceComposer.h>
+#include <ui/ISurfaceFlingerClient.h>
+
+#include <private/ui/SharedState.h>
+#include <private/ui/LayerState.h>
+#include <private/ui/SurfaceFlingerSynchro.h>
+
+#include "Layer.h"
+#include "Tokenizer.h"
+#include "CPUGauge.h"
+#include "BootAnimation.h"
+#include "Barrier.h"
+
+struct copybit_t;
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+class BClient;
+class Client;
+class DisplayHardware;
+class GPUHardwareInterface;
+class IGPUCallback;
+class Layer;
+class LayerBuffer;
+class RFBServer;
+class SurfaceHeapManager;
+class FreezeLock;
+
+typedef int32_t ClientID;
+
+#define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
+#define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))
+
+// ---------------------------------------------------------------------------
+
+class Client
+{
+public:
+            Client(ClientID cid, const sp<SurfaceFlinger>& flinger);
+            ~Client();
+
+            int32_t                 generateId(int pid);
+            void                    free(int32_t id);
+            status_t                bindLayer(LayerBaseClient* layer, int32_t id);
+            sp<MemoryDealer>        createAllocator(int memory_type);
+
+    inline  bool                    isValid(int32_t i) const;
+    inline  const uint8_t*          inUseArray() const;
+    inline  size_t                  numActiveLayers() const;
+    LayerBaseClient*                getLayerUser(int32_t i) const;
+    const Vector<LayerBaseClient*>& getLayers() const { return mLayers; }
+    const sp<IMemory>&              controlBlockMemory() const { return mCblkMemory; }
+    void                            dump(const char* what);
+    const sp<SurfaceHeapManager>&   getSurfaceHeapManager() const;
+    
+    // pointer to this client's control block
+    per_client_cblk_t*      ctrlblk;
+    ClientID                cid;
+
+    
+private:
+    int                     getClientPid() const { return mPid; }
+    const sp<GPUHardwareInterface>&  getGPU() const;
+        
+    int                         mPid;
+    uint32_t                    mBitmap;
+    SortedVector<uint8_t>       mInUse;
+    Vector<LayerBaseClient*>    mLayers;
+    sp<MemoryDealer>            mCblkHeap;
+    sp<SurfaceFlinger>          mFlinger;
+    sp<MemoryDealer>            mSharedHeapAllocator;
+    sp<MemoryDealer>            mPMemAllocator;
+    sp<IMemory>                 mCblkMemory;
+};
+
+// ---------------------------------------------------------------------------
+
+class GraphicPlane
+{
+public:
+
+                                GraphicPlane();
+                                ~GraphicPlane();
+
+        bool                    initialized() const;
+
+        void                    setDisplayHardware(DisplayHardware *);
+        void                    setTransform(const Transform& tr);
+        status_t                setOrientation(int orientation);
+
+        const DisplayHardware&  displayHardware() const;
+        const Transform&        transform() const;
+private:
+                                GraphicPlane(const GraphicPlane&);
+        GraphicPlane            operator = (const GraphicPlane&);
+
+        DisplayHardware*        mHw;
+        Transform               mTransform;
+        Transform               mOrientationTransform;
+        Transform               mGlobalTransform;
+};
+
+// ---------------------------------------------------------------------------
+
+enum {
+    eTransactionNeeded      = 0x01,
+    eTraversalNeeded        = 0x02
+};
+
+class SurfaceFlinger : public BnSurfaceComposer, protected Thread
+{
+public:
+    static void instantiate();
+    static void shutdown();
+
+                    SurfaceFlinger();
+    virtual         ~SurfaceFlinger();
+            void    init();
+
+    virtual status_t onTransact(
+        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags);
+
+    virtual status_t dump(int fd, const Vector<String16>& args);
+
+    // ISurfaceComposer interface
+    virtual sp<ISurfaceFlingerClient>   createConnection();
+    virtual sp<IMemory>                 getCblk() const;
+    virtual void                        bootFinished();
+    virtual void                        openGlobalTransaction();
+    virtual void                        closeGlobalTransaction();
+    virtual status_t                    freezeDisplay(DisplayID dpy, uint32_t flags);
+    virtual status_t                    unfreezeDisplay(DisplayID dpy, uint32_t flags);
+    virtual int                         setOrientation(DisplayID dpy, int orientation);
+    virtual void                        signal() const;
+    virtual status_t requestGPU(const sp<IGPUCallback>& callback, 
+            gpu_info_t* gpu);
+    virtual status_t revokeGPU();
+
+            void                        screenReleased(DisplayID dpy);
+            void                        screenAcquired(DisplayID dpy);
+
+            const sp<SurfaceHeapManager>& getSurfaceHeapManager() const { 
+                return mSurfaceHeapManager; 
+            }
+
+            const sp<GPUHardwareInterface>& getGPU() const {
+                return mGPU; 
+            }
+
+            copybit_t* getBlitEngine() const;
+            
+private:
+    friend class BClient;
+    friend class LayerBase;
+    friend class LayerBuffer;
+    friend class LayerBaseClient;
+    friend class Layer;
+    friend class LayerBlur;
+
+    sp<ISurface> createSurface(ClientID client, int pid, 
+            ISurfaceFlingerClient::surface_data_t* params,
+            DisplayID display, uint32_t w, uint32_t h, PixelFormat format,
+            uint32_t flags);
+
+    LayerBaseClient* createNormalSurfaceLocked(Client* client, DisplayID display,
+            int32_t id, uint32_t w, uint32_t h, PixelFormat format, uint32_t flags);
+
+    LayerBaseClient* createBlurSurfaceLocked(Client* client, DisplayID display,
+            int32_t id, uint32_t w, uint32_t h, uint32_t flags);
+
+    LayerBaseClient* createDimSurfaceLocked(Client* client, DisplayID display,
+            int32_t id, uint32_t w, uint32_t h, uint32_t flags);
+
+    LayerBaseClient* createPushBuffersSurfaceLocked(Client* client, DisplayID display,
+            int32_t id, uint32_t w, uint32_t h, uint32_t flags);
+
+    status_t    destroySurface(SurfaceID surface_id);
+    status_t    setClientState(ClientID cid, int32_t count, const layer_state_t* states);
+
+
+    class LayerVector {
+    public:
+        inline              LayerVector() { }
+                            LayerVector(const LayerVector&);
+        inline size_t       size() const { return layers.size(); }
+        inline LayerBase*const* array() const { return layers.array(); }
+        ssize_t             add(LayerBase*, Vector<LayerBase*>::compar_t);
+        ssize_t             remove(LayerBase*);
+        ssize_t             reorder(LayerBase*, Vector<LayerBase*>::compar_t);
+        ssize_t             indexOf(LayerBase* key, size_t guess=0) const;
+        inline LayerBase*   operator [] (size_t i) const { return layers[i]; }
+    private:
+        KeyedVector<LayerBase*, size_t> lookup;
+        Vector<LayerBase*>              layers;
+    };
+
+    struct State {
+        State() {
+            orientation = ISurfaceComposer::eOrientationDefault;
+            freezeDisplay = 0;
+        }
+        LayerVector     layersSortedByZ;
+        uint8_t         orientation;
+        uint8_t         freezeDisplay;
+    };
+
+    class DelayedTransaction : public Thread
+    {
+        friend class SurfaceFlinger;
+        sp<SurfaceFlinger>  mFlinger;
+        nsecs_t             mDelay;
+    public:
+        DelayedTransaction(const sp<SurfaceFlinger>& flinger, nsecs_t delay)
+            : Thread(false), mFlinger(flinger), mDelay(delay) {
+        }
+        virtual bool threadLoop() {
+            usleep(mDelay / 1000);
+            if (android_atomic_and(~1,
+                    &mFlinger->mDeplayedTransactionPending) == 1) {
+                mFlinger->signalEvent();
+            }
+            return false;
+        }
+    };
+
+    virtual bool        threadLoop();
+    virtual status_t    readyToRun();
+    virtual void        onFirstRef();
+
+    const GraphicPlane&     graphicPlane(int dpy) const;
+          GraphicPlane&     graphicPlane(int dpy);
+
+            void        waitForEvent();
+            void        signalEvent();
+            void        signalDelayedEvent(nsecs_t delay);
+
+            void        handleConsoleEvents();
+            void        handleTransaction(uint32_t transactionFlags);
+
+            void        computeVisibleRegions(
+                            LayerVector& currentLayers,
+                            Region& dirtyRegion,
+                            Region& wormholeRegion);
+
+            void        handlePageFlip();
+            bool        lockPageFlip(const LayerVector& currentLayers);
+            void        unlockPageFlip(const LayerVector& currentLayers);
+            void        handleRepaint();
+            void        handleDebugCpu();
+            void        scheduleBroadcast(Client* client);
+            void        executeScheduledBroadcasts();
+            void        postFramebuffer();
+            void        composeSurfaces(const Region& dirty);
+            void        unlockClients();
+
+
+            void        destroyConnection(ClientID cid);
+            LayerBaseClient* getLayerUser_l(SurfaceID index) const;
+            status_t    addLayer_l(LayerBase* layer);
+            status_t    removeLayer_l(LayerBase* layer);
+            void        destroy_all_removed_layers_l();
+            void        free_resources_l();
+
+            uint32_t    getTransactionFlags(uint32_t flags);
+            uint32_t    setTransactionFlags(uint32_t flags, nsecs_t delay = 0);
+            void        commitTransaction();
+
+
+            friend class FreezeLock;
+            sp<FreezeLock> getFreezeLock() const;
+            inline void incFreezeCount() { mFreezeCount++; }
+            inline void decFreezeCount() { if (mFreezeCount > 0) mFreezeCount--; }
+            inline bool hasFreezeRequest() const { return mFreezeDisplay; }
+            inline bool isFrozen() const { 
+                return mFreezeDisplay || mFreezeCount>0;
+            }
+
+            
+            void        debugFlashRegions();
+            void        debugShowFPS() const;
+            void        drawWormhole() const;
+           
+                // access must be protected by mStateLock
+    mutable     Mutex                   mStateLock;
+                State                   mCurrentState;
+                State                   mDrawingState;
+    volatile    int32_t                 mTransactionFlags;
+    volatile    int32_t                 mTransactionCount;
+                Condition               mTransactionCV;
+
+                // protected by mStateLock (but we could use another lock)
+                Tokenizer                               mTokens;
+                DefaultKeyedVector<ClientID, Client*>   mClientsMap;
+                DefaultKeyedVector<SurfaceID, LayerBaseClient*>   mLayerMap;
+                GraphicPlane                            mGraphicPlanes[1];
+                SortedVector<LayerBase*>                mRemovedLayers;
+                Vector<Client*>                         mDisconnectedClients;
+
+                // constant members (no synchronization needed for access)
+                sp<MemoryDealer>            mServerHeap;
+                sp<IMemory>                 mServerCblkMemory;
+                surface_flinger_cblk_t*     mServerCblk;
+                sp<SurfaceHeapManager>      mSurfaceHeapManager;
+                sp<GPUHardwareInterface>    mGPU;
+                GLuint                      mWormholeTexName;
+                sp<BootAnimation>           mBootAnimation;
+                sp<RFBServer>               mRFBServer;
+                nsecs_t                     mBootTime;
+                
+                // Can only accessed from the main thread, these members
+                // don't need synchronization
+                Region                      mDirtyRegion;
+                Region                      mInvalidRegion;
+                Region                      mWormholeRegion;
+                Client*                     mLastScheduledBroadcast;
+                SortedVector<Client*>       mScheduledBroadcasts;
+                bool                        mVisibleRegionsDirty;
+                bool                        mDeferReleaseConsole;
+                bool                        mFreezeDisplay;
+                int32_t                     mFreezeCount;
+                nsecs_t                     mFreezeDisplayTime;
+
+                // access protected by mDebugLock
+    mutable     Mutex                       mDebugLock;
+                sp<CPUGauge>                mCpuGauge;
+
+                // don't use a lock for these, we don't care
+                int                         mDebugRegion;
+                int                         mDebugCpu;
+                int                         mDebugFps;
+                int                         mDebugBackground;
+                int                         mDebugNoBootAnimation;
+
+                // these are thread safe
+    mutable     Barrier                     mReadyToRunBarrier;
+    mutable     SurfaceFlingerSynchro       mSyncObject;
+    volatile    int32_t                     mDeplayedTransactionPending;
+
+                // atomic variables
+                enum {
+                    eConsoleReleased = 1,
+                    eConsoleAcquired = 2
+                };
+   volatile     int32_t                     mConsoleSignals;
+
+   // only written in the main thread, only read in other threads
+   volatile     int32_t                     mSecureFrameBuffer;
+};
+
+// ---------------------------------------------------------------------------
+
+class FreezeLock {
+    SurfaceFlinger* mFlinger;
+    mutable volatile int32_t mCount;
+public:
+    FreezeLock(SurfaceFlinger* flinger)
+        : mFlinger(flinger), mCount(0) {
+        mFlinger->incFreezeCount();
+    }
+    ~FreezeLock() {
+        mFlinger->decFreezeCount();
+    }
+    inline void incStrong(void*) const {
+        android_atomic_inc(&mCount);
+    }
+    inline void decStrong(void*) const {
+        if (android_atomic_dec(&mCount) == 1)
+             delete this;
+    }
+};
+
+// ---------------------------------------------------------------------------
+
+class BClient : public BnSurfaceFlingerClient
+{
+public:
+    BClient(SurfaceFlinger *flinger, ClientID cid,
+            const sp<IMemory>& cblk);
+    ~BClient();
+
+    // ISurfaceFlingerClient interface
+    virtual void getControlBlocks(sp<IMemory>* ctrl) const;
+
+    virtual sp<ISurface> createSurface(
+            surface_data_t* params, int pid,
+            DisplayID display, uint32_t w, uint32_t h,PixelFormat format,
+            uint32_t flags);
+
+    virtual status_t destroySurface(SurfaceID surfaceId);
+    virtual status_t setState(int32_t count, const layer_state_t* states);
+
+private:
+    ClientID            mId;
+    SurfaceFlinger*     mFlinger;
+    sp<IMemory>         mCblk;
+};
+
+// ---------------------------------------------------------------------------
+}; // namespace android
+
+#endif // ANDROID_SURFACE_FLINGER_H
diff --git a/libs/surfaceflinger/Tokenizer.cpp b/libs/surfaceflinger/Tokenizer.cpp
new file mode 100644
index 0000000..ef51d6a
--- /dev/null
+++ b/libs/surfaceflinger/Tokenizer.cpp
@@ -0,0 +1,172 @@
+/*
+ * 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.
+ */
+
+#include <stdio.h>
+
+#include "Tokenizer.h"
+
+// ----------------------------------------------------------------------------
+
+namespace android {
+
+ANDROID_BASIC_TYPES_TRAITS(Tokenizer::run_t)
+
+Tokenizer::Tokenizer()
+{
+}
+
+Tokenizer::Tokenizer(const Tokenizer& other)
+    : mRanges(other.mRanges)
+{
+}
+
+Tokenizer::~Tokenizer()
+{
+}
+
+uint32_t Tokenizer::acquire()
+{
+    if (!mRanges.size() || mRanges[0].first) {
+        _insertTokenAt(0,0);
+        return 0;
+    }
+    
+    // just extend the first run
+    const run_t& run = mRanges[0];
+    uint32_t token = run.first + run.length;
+    _insertTokenAt(token, 1);
+    return token;
+}
+
+bool Tokenizer::isAcquired(uint32_t token) const
+{
+    return (_indexOrderOf(token) >= 0);
+}
+
+status_t Tokenizer::reserve(uint32_t token)
+{
+    size_t o;
+    const ssize_t i = _indexOrderOf(token, &o);
+    if (i >= 0) {
+        return BAD_VALUE; // this token is already taken
+    }
+    ssize_t err = _insertTokenAt(token, o);
+    return (err<0) ? err : status_t(NO_ERROR);
+}
+
+status_t Tokenizer::release(uint32_t token)
+{
+    const ssize_t i = _indexOrderOf(token);
+    if (i >= 0) {
+        const run_t& run = mRanges[i];
+        if ((token >= run.first) && (token < run.first+run.length)) {
+            // token in this range, we need to split
+            run_t& run = mRanges.editItemAt(i);
+            if ((token == run.first) || (token == run.first+run.length-1)) {
+                if (token == run.first) {
+                    run.first += 1;
+                }
+                run.length -= 1;
+                if (run.length == 0) {
+                    // XXX: should we systematically remove a run that's empty?
+                    mRanges.removeItemsAt(i);
+                }
+            } else {
+                // split the run
+                run_t new_run;
+                new_run.first = token+1;
+                new_run.length = run.first+run.length - new_run.first;
+                run.length = token - run.first;
+                mRanges.insertAt(new_run, i+1);
+            }
+            return NO_ERROR;
+        }
+    }
+    return NAME_NOT_FOUND;
+}
+
+ssize_t Tokenizer::_indexOrderOf(uint32_t token, size_t* order) const
+{
+    // binary search
+    ssize_t err = NAME_NOT_FOUND;
+    ssize_t l = 0;
+    ssize_t h = mRanges.size()-1;
+    ssize_t mid;
+    const run_t* a = mRanges.array();
+    while (l <= h) {
+        mid = l + (h - l)/2;
+        const run_t* const curr = a + mid;
+        int c = 0;
+        if (token < curr->first)                        c = 1;
+        else if (token >= curr->first+curr->length)     c = -1;
+        if (c == 0) {
+            err = l = mid;
+            break;
+        } else if (c < 0) {
+            l = mid + 1;
+        } else {
+            h = mid - 1;
+        }
+    }
+    if (order) *order = l;
+    return err;
+}
+
+ssize_t Tokenizer::_insertTokenAt(uint32_t token, size_t index)
+{
+    const size_t c = mRanges.size();
+
+    if (index >= 1) {
+        // do we need to merge with the previous run?
+        run_t& p = mRanges.editItemAt(index-1);
+        if (p.first+p.length == token) {
+            p.length += 1;
+            if (index < c) {
+                const run_t& n = mRanges[index];
+                if (token+1 == n.first) {
+                    p.length += n.length;
+                    mRanges.removeItemsAt(index);
+                }
+            }
+            return index;
+        }
+    }
+    
+    if (index < c) {
+        // do we need to merge with the next run?
+        run_t& n = mRanges.editItemAt(index);
+        if (token+1 == n.first) {
+            n.first -= 1;
+            n.length += 1;
+            return index;
+        }
+    }
+
+    return mRanges.insertAt(run_t(token,1), index);
+}
+
+void Tokenizer::dump() const
+{
+    const run_t* ranges = mRanges.array();
+    const size_t c = mRanges.size();
+    printf("Tokenizer (%p, size = %lu)\n", this, c);
+    for (size_t i=0 ; i<c ; i++) {
+        printf("%lu: (%u, %u)\n", i, ranges[i].first, ranges[i].length);
+    }
+}
+
+}; // namespace android
+
diff --git a/libs/surfaceflinger/Tokenizer.h b/libs/surfaceflinger/Tokenizer.h
new file mode 100644
index 0000000..6b3057d
--- /dev/null
+++ b/libs/surfaceflinger/Tokenizer.h
@@ -0,0 +1,57 @@
+/*
+ * 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_TOKENIZER_H
+#define ANDROID_TOKENIZER_H
+
+#include <utils/Vector.h>
+#include <utils/Errors.h>
+
+// ----------------------------------------------------------------------------
+
+namespace android {
+
+class Tokenizer
+{
+public:
+                Tokenizer();
+                Tokenizer(const Tokenizer& other);
+                ~Tokenizer();
+
+    uint32_t    acquire();
+    status_t    reserve(uint32_t token);
+    status_t    release(uint32_t token);
+    bool        isAcquired(uint32_t token) const;
+
+    void dump() const;
+
+    struct run_t {
+        run_t() {};
+        run_t(uint32_t f, uint32_t l) : first(f), length(l) {}
+        uint32_t    first;
+        uint32_t    length;
+    };
+private:
+    ssize_t _indexOrderOf(uint32_t token, size_t* order=0) const;
+    ssize_t _insertTokenAt(uint32_t token, size_t index);
+    Vector<run_t>   mRanges;
+};
+
+}; // namespace android
+
+// ----------------------------------------------------------------------------
+
+#endif // ANDROID_TOKENIZER_H
diff --git a/libs/surfaceflinger/Transform.cpp b/libs/surfaceflinger/Transform.cpp
new file mode 100644
index 0000000..bec7a64
--- /dev/null
+++ b/libs/surfaceflinger/Transform.cpp
@@ -0,0 +1,204 @@
+/*
+ * 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.
+ */
+
+#include <ui/Region.h>
+
+#include <private/pixelflinger/ggl_fixed.h>
+
+#include "Transform.h"
+
+// ---------------------------------------------------------------------------
+
+#define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
+#define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))
+
+// ---------------------------------------------------------------------------
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+Transform::Transform()
+    : mType(0)
+{
+    mTransform.reset();
+}
+
+Transform::Transform(const Transform&  other)
+    : mTransform(other.mTransform), mType(other.mType)
+{
+}
+
+Transform::~Transform() {
+}
+
+Transform Transform::operator * (const Transform& rhs) const
+{
+    if (LIKELY(mType == 0))
+        return rhs;
+
+    Transform r(*this);
+    r.mTransform.preConcat(rhs.mTransform);
+    r.mType |= rhs.mType;
+    return r;
+}
+
+float Transform::operator [] (int i) const
+{
+    float r = 0;
+    switch(i) {
+        case 0: r = SkScalarToFloat( mTransform[SkMatrix::kMScaleX] );  break;
+        case 1: r = SkScalarToFloat( mTransform[SkMatrix::kMSkewX] );   break;
+        case 2: r = SkScalarToFloat( mTransform[SkMatrix::kMSkewY] );   break;
+        case 3: r = SkScalarToFloat( mTransform[SkMatrix::kMScaleY] );  break;
+    }
+    return r;
+}
+
+uint8_t Transform::type() const
+{
+    if (UNLIKELY(mType & 0x80000000)) {
+        mType = mTransform.getType();
+    }
+    return uint8_t(mType & 0xFF);
+}
+
+bool Transform::transformed() const {
+    return type() > SkMatrix::kTranslate_Mask;
+}
+
+int Transform::tx() const {
+    return SkScalarRound( mTransform[SkMatrix::kMTransX] );
+}
+
+int Transform::ty() const {
+    return SkScalarRound( mTransform[SkMatrix::kMTransY] );
+}
+
+void Transform::reset() {
+    mTransform.reset();
+    mType = 0;
+}
+
+void Transform::set( float xx, float xy,
+                     float yx, float yy)
+{
+    mTransform.set(SkMatrix::kMScaleX, SkFloatToScalar(xx));
+    mTransform.set(SkMatrix::kMSkewX, SkFloatToScalar(xy));
+    mTransform.set(SkMatrix::kMSkewY, SkFloatToScalar(yx));
+    mTransform.set(SkMatrix::kMScaleY, SkFloatToScalar(yy));
+    mType |= 0x80000000;
+}
+
+void Transform::set(int tx, int ty)
+{
+    if (tx | ty) {
+        mTransform.set(SkMatrix::kMTransX, SkIntToScalar(tx));
+        mTransform.set(SkMatrix::kMTransY, SkIntToScalar(ty));
+        mType |= SkMatrix::kTranslate_Mask;
+    } else {
+        mTransform.set(SkMatrix::kMTransX, 0);
+        mTransform.set(SkMatrix::kMTransY, 0);
+        mType &= ~SkMatrix::kTranslate_Mask;
+    }
+}
+
+void Transform::transform(GLfixed* point, int x, int y) const
+{
+    SkPoint s;
+    mTransform.mapXY(SkIntToScalar(x), SkIntToScalar(y), &s);
+    point[0] = SkScalarToFixed(s.fX);
+    point[1] = SkScalarToFixed(s.fY);
+}
+
+Rect Transform::makeBounds(int w, int h) const
+{
+    Rect r;
+    SkRect d, s;
+    s.set(0, 0, SkIntToScalar(w), SkIntToScalar(h));
+    mTransform.mapRect(&d, s);
+    r.left   = SkScalarRound( d.fLeft );
+    r.top    = SkScalarRound( d.fTop );
+    r.right  = SkScalarRound( d.fRight );
+    r.bottom = SkScalarRound( d.fBottom );
+    return r;
+}
+
+Rect Transform::transform(const Rect& bounds) const
+{
+    Rect r;
+    SkRect d, s;
+    s.set(  SkIntToScalar( bounds.left ),
+            SkIntToScalar( bounds.top ),
+            SkIntToScalar( bounds.right ),
+            SkIntToScalar( bounds.bottom ));
+    mTransform.mapRect(&d, s);
+    r.left   = SkScalarRound( d.fLeft );
+    r.top    = SkScalarRound( d.fTop );
+    r.right  = SkScalarRound( d.fRight );
+    r.bottom = SkScalarRound( d.fBottom );
+    return r;
+}
+
+Region Transform::transform(const Region& reg) const
+{
+    Region out;
+    if (UNLIKELY(transformed())) {
+        if (LIKELY(preserveRects())) {
+            Rect r;
+            Region::iterator iterator(reg);
+            while (iterator.iterate(&r)) {
+                out.orSelf(transform(r));
+            }
+        } else {
+            out.set(transform(reg.bounds()));
+        }
+    } else {
+        out = reg.translate(tx(), ty());
+    }
+    return out;
+}
+
+int32_t Transform::getOrientation() const
+{
+    uint32_t flags = 0;
+    if (UNLIKELY(transformed())) {
+        SkScalar a = mTransform[SkMatrix::kMScaleX];
+        SkScalar b = mTransform[SkMatrix::kMSkewX];
+        SkScalar c = mTransform[SkMatrix::kMSkewY];
+        SkScalar d = mTransform[SkMatrix::kMScaleY];
+        if (b==0 && c==0 && a && d) {
+            if (a<0)    flags |= FLIP_H;
+            if (d<0)    flags |= FLIP_V;
+        } else if (b && c && a==0 && d==0) {
+            flags |= ROT_90;
+            if (b>0)    flags |= FLIP_H;
+            if (c<0)    flags |= FLIP_V;
+        } else {
+            flags = 0x80000000;
+        }
+    }
+    return flags;
+}
+
+bool Transform::preserveRects() const
+{
+    return mTransform.rectStaysRect();
+}
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
diff --git a/libs/surfaceflinger/Transform.h b/libs/surfaceflinger/Transform.h
new file mode 100644
index 0000000..2f617c4
--- /dev/null
+++ b/libs/surfaceflinger/Transform.h
@@ -0,0 +1,87 @@
+/*
+ * 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_TRANSFORM_H
+#define ANDROID_TRANSFORM_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <ui/Point.h>
+#include <ui/Rect.h>
+
+#include <GLES/gl.h>
+
+#include <corecg/SkMatrix.h>
+
+namespace android {
+
+class Region;
+
+// ---------------------------------------------------------------------------
+
+class Transform
+{
+public:
+                    Transform();
+                    Transform(const Transform&  other);
+                    ~Transform();
+
+            enum orientation_flags {
+                ROT_0   = 0x00000000,
+                FLIP_H  = 0x00000001,
+                FLIP_V  = 0x00000002,
+                ROT_90  = 0x00000004,
+                ROT_180 = FLIP_H|FLIP_V,
+                ROT_270 = ROT_180|ROT_90,
+                ROT_INVALID = 0x80000000
+            };
+
+            bool    transformed() const;
+            int32_t getOrientation() const;
+            bool    preserveRects() const;
+            
+            int     tx() const;
+            int     ty() const;
+        
+            void    reset();
+            void    set(float xx, float xy, float yx, float yy);
+            void    set(int tx, int ty);
+
+            Rect    makeBounds(int w, int h) const;
+            void    transform(GLfixed* point, int x, int y) const;
+            Region  transform(const Region& reg) const;
+            Rect    transform(const Rect& bounds) const;
+
+            Transform operator * (const Transform& rhs) const;
+            float operator [] (int i) const;
+
+    inline uint32_t getType() const { return type(); }
+            
+    inline Transform(bool) : mType(0xFF) { };
+
+private:
+    uint8_t     type() const;
+
+private:
+            SkMatrix    mTransform;
+    mutable uint32_t    mType;      
+};
+
+// ---------------------------------------------------------------------------
+}; // namespace android
+
+#endif /* ANDROID_TRANSFORM_H */
diff --git a/libs/surfaceflinger/VRamHeap.cpp b/libs/surfaceflinger/VRamHeap.cpp
new file mode 100644
index 0000000..3852d51
--- /dev/null
+++ b/libs/surfaceflinger/VRamHeap.cpp
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2008 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.
+ */
+
+#define LOG_TAG "SurfaceFlinger"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <math.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+
+#include <cutils/log.h>
+#include <cutils/properties.h>
+
+#include <utils/MemoryDealer.h>
+#include <utils/MemoryBase.h>
+#include <utils/MemoryHeapPmem.h>
+#include <utils/MemoryHeapBase.h>
+
+#include <GLES/eglnatives.h>
+
+#include "VRamHeap.h"
+
+#if HAVE_ANDROID_OS
+#include <linux/android_pmem.h>
+#endif
+
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+/*
+ * Amount of memory we reserve for surface, per client in PMEM
+ * (PMEM is used for 2D acceleration)
+ * 8 MB of address space per client should be enough.
+ */
+static const int PMEM_SIZE = int(8 * 1024 * 1024);
+
+int SurfaceHeapManager::global_pmem_heap = 0;
+
+// ---------------------------------------------------------------------------
+
+SurfaceHeapManager::SurfaceHeapManager(size_t clientHeapSize)
+    : mClientHeapSize(clientHeapSize)
+{
+    SurfaceHeapManager::global_pmem_heap = 1;
+}
+
+SurfaceHeapManager::~SurfaceHeapManager()
+{
+}
+
+void SurfaceHeapManager::onFirstRef()
+{
+    if (global_pmem_heap) {
+        const char* device = "/dev/pmem";
+        mPMemHeap = new PMemHeap(device, PMEM_SIZE);
+        if (mPMemHeap->base() == MAP_FAILED) {
+            mPMemHeap.clear();
+            global_pmem_heap = 0;
+        }
+    }
+}
+
+sp<MemoryDealer> SurfaceHeapManager::createHeap(int type)
+{
+    if (!global_pmem_heap && type==NATIVE_MEMORY_TYPE_PMEM)
+        type = NATIVE_MEMORY_TYPE_HEAP;
+
+    const sp<PMemHeap>& heap(mPMemHeap);
+    sp<MemoryDealer> dealer; 
+    switch (type) {
+    case NATIVE_MEMORY_TYPE_HEAP:
+        dealer = new MemoryDealer(mClientHeapSize, 0, "SFNativeHeap");
+        break;
+
+    case NATIVE_MEMORY_TYPE_PMEM:
+        if (heap != 0) {
+            dealer = new MemoryDealer( 
+                    heap->createClientHeap(),
+                    heap->getAllocator());
+        }
+        break;
+    }
+    return dealer;
+}
+
+sp<SimpleBestFitAllocator> SurfaceHeapManager::getAllocator(int type) const 
+{
+    Mutex::Autolock _l(mLock);
+    sp<SimpleBestFitAllocator> allocator;
+
+    // this is only used for debugging
+    switch (type) {
+        case NATIVE_MEMORY_TYPE_PMEM:
+            if (mPMemHeap != 0) {
+                allocator = mPMemHeap->getAllocator();
+            }
+            break;
+    }
+    return allocator;
+}
+
+// ---------------------------------------------------------------------------
+
+PMemHeapInterface::PMemHeapInterface(int fd, size_t size)
+    : MemoryHeapBase(fd, size) {
+}
+PMemHeapInterface::PMemHeapInterface(const char* device, size_t size)
+    : MemoryHeapBase(device, size) {
+}
+PMemHeapInterface::PMemHeapInterface(size_t size, uint32_t flags, char const * name)
+    : MemoryHeapBase(size, flags, name) {
+}
+PMemHeapInterface::~PMemHeapInterface() {
+}
+
+// ---------------------------------------------------------------------------
+
+PMemHeap::PMemHeap(const char* const device, size_t size, size_t reserved)
+    : PMemHeapInterface(device, size)
+{
+    //LOGD("%s, %p, mFD=%d", __PRETTY_FUNCTION__, this, heapID());
+    if (base() != MAP_FAILED) {
+        //LOGD("%s, %u bytes", device, virtualSize());
+        if (reserved == 0)
+            reserved = virtualSize();
+        mAllocator = new SimpleBestFitAllocator(reserved);
+    }
+}
+
+PMemHeap::~PMemHeap() {
+    //LOGD("%s, %p, mFD=%d", __PRETTY_FUNCTION__, this, heapID());
+}
+
+sp<MemoryHeapPmem> PMemHeap::createClientHeap() {
+    sp<MemoryHeapBase> parentHeap(this);
+    return new MemoryHeapPmem(parentHeap);
+}
+
+// ---------------------------------------------------------------------------
+}; // namespace android
diff --git a/libs/surfaceflinger/VRamHeap.h b/libs/surfaceflinger/VRamHeap.h
new file mode 100644
index 0000000..03e0336
--- /dev/null
+++ b/libs/surfaceflinger/VRamHeap.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2008 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_VRAM_HEAP_H
+#define ANDROID_VRAM_HEAP_H
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <utils/MemoryDealer.h>
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+class PMemHeap;
+class MemoryHeapPmem;
+
+// ---------------------------------------------------------------------------
+
+class SurfaceHeapManager  : public RefBase
+{
+public:
+    SurfaceHeapManager(size_t clientHeapSize);
+    virtual ~SurfaceHeapManager();
+    virtual void onFirstRef();
+    sp<MemoryDealer> createHeap(int type);
+    
+    // used for debugging only...
+    sp<SimpleBestFitAllocator> getAllocator(int type) const;
+
+private:
+    sp<PMemHeap> getHeap(int type) const;
+
+    mutable Mutex   mLock;
+    size_t          mClientHeapSize;
+    sp<PMemHeap>    mPMemHeap;
+    static int global_pmem_heap;
+};
+
+// ---------------------------------------------------------------------------
+
+class PMemHeapInterface : public MemoryHeapBase
+{
+public:
+    PMemHeapInterface(int fd, size_t size);
+    PMemHeapInterface(const char* device, size_t size = 0);
+    PMemHeapInterface(size_t size, uint32_t flags = 0, char const * name = NULL);
+    virtual ~PMemHeapInterface();
+    virtual sp<MemoryHeapPmem> createClientHeap() = 0;
+};
+
+// ---------------------------------------------------------------------------
+
+class PMemHeap : public PMemHeapInterface
+{
+public:
+                PMemHeap(const char* const vram,
+                        size_t size=0, size_t reserved=0);
+    virtual     ~PMemHeap();
+    
+    virtual const sp<SimpleBestFitAllocator>& getAllocator() const {
+        return mAllocator; 
+    }
+    virtual sp<MemoryHeapPmem> createClientHeap();
+    
+private:
+    sp<SimpleBestFitAllocator>  mAllocator;
+};
+
+// ---------------------------------------------------------------------------
+}; // namespace android
+
+#endif // ANDROID_VRAM_HEAP_H
diff --git a/libs/surfaceflinger/clz.cpp b/libs/surfaceflinger/clz.cpp
new file mode 100644
index 0000000..2456b86
--- /dev/null
+++ b/libs/surfaceflinger/clz.cpp
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+
+#include "clz.h"
+
+namespace android {
+
+int clz_impl(int32_t x)
+{
+#if defined(__arm__) && !defined(__thumb__)
+    return __builtin_clz(x);
+#else
+    if (!x) return 32;
+    int e = 31;
+    if (x&0xFFFF0000)   { e -=16; x >>=16; }
+    if (x&0x0000FF00)   { e -= 8; x >>= 8; }
+    if (x&0x000000F0)   { e -= 4; x >>= 4; }
+    if (x&0x0000000C)   { e -= 2; x >>= 2; }
+    if (x&0x00000002)   { e -= 1; }
+    return e;
+#endif
+}
+
+}; // namespace android
diff --git a/libs/surfaceflinger/clz.h b/libs/surfaceflinger/clz.h
new file mode 100644
index 0000000..0ddf986
--- /dev/null
+++ b/libs/surfaceflinger/clz.h
@@ -0,0 +1,37 @@
+/*
+ * 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_SURFACE_FLINGER_CLZ_H
+
+#include <stdint.h>
+
+namespace android {
+
+int clz_impl(int32_t x);
+
+int inline clz(int32_t x)
+{
+#if defined(__arm__) && !defined(__thumb__)
+    return __builtin_clz(x);
+#else
+    return clz_impl(x);
+#endif
+}
+
+
+}; // namespace android
+
+#endif /* ANDROID_SURFACE_FLINGER_CLZ_H */
