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
