diff --git a/libs/surfaceflinger/Layer.cpp b/libs/surfaceflinger/Layer.cpp
new file mode 100644
index 0000000..f65d669
--- /dev/null
+++ b/libs/surfaceflinger/Layer.cpp
@@ -0,0 +1,568 @@
+/*
+ * 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 explicitly requested, we should fail
+    // on systems where we can't allocate memory that can be used with
+    // DMA engines for instance.
+    
+    // FIXME: we always ask for hardware for now (this should come from copybit)
+    flags |= ISurfaceComposer::eHardware;
+
+    const uint32_t memory_flags = flags & 
+            (ISurfaceComposer::eGPU | 
+             ISurfaceComposer::eHardware | 
+             ISurfaceComposer::eSecure);
+    
+    // pixel-alignment. the final alignment may be bigger because
+    // we always force a 4-byte aligned bpr.
+    uint32_t alignment = 1;
+
+    if (flags & ISurfaceComposer::eGPU) {
+        // FIXME: this value should come from the h/w
+        alignment = 8; 
+        // FIXME: this is msm7201A specific, as its GPU only supports
+        // BGRA_8888.
+        if (format == PIXEL_FORMAT_RGBA_8888) {
+            format = PIXEL_FORMAT_BGRA_8888;
+        }
+    }
+
+    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_flags);
+        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(),
+            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_device_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 available, 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;
+            this->contentDirty = 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
