diff --git a/libs/ui/BlitHardware.cpp b/libs/ui/BlitHardware.cpp
new file mode 100644
index 0000000..90838b4
--- /dev/null
+++ b/libs/ui/BlitHardware.cpp
@@ -0,0 +1,446 @@
+/*
+ * 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 <stdint.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+
+#include <cutils/log.h>
+
+#include <utils/Errors.h>
+
+#if HAVE_ANDROID_OS
+#include <linux/fb.h>
+#include <linux/msm_mdp.h>
+#endif
+
+#include <ui/BlitHardware.h>
+
+/******************************************************************************/
+
+namespace android {
+class CopybitMSM7K : public copybit_t {
+public:
+    CopybitMSM7K();
+    ~CopybitMSM7K();
+    
+    status_t getStatus() const {
+        if (mFD<0) return mFD;
+        return NO_ERROR;
+    }
+
+    status_t setParameter(int name, int value);
+
+    status_t get(int name);
+
+    status_t blit( 
+            const copybit_image_t& dst,
+            const copybit_image_t& src,
+            copybit_region_t const* region);
+
+    status_t stretch( 
+            const copybit_image_t& dst,
+            const copybit_image_t& src, 
+            const copybit_rect_t& dst_rect,
+            const copybit_rect_t& src_rect,
+            copybit_region_t const* region);
+
+#if HAVE_ANDROID_OS
+private:
+    static int copybit_set_parameter(copybit_t* handle, int name, int value);
+    static int copybit_blit( copybit_t* handle, 
+            copybit_image_t const* dst, copybit_image_t const* src,
+            copybit_region_t const* region);
+    static int copybit_stretch(copybit_t* handle, 
+            copybit_image_t const* dst,  copybit_image_t const* src, 
+            copybit_rect_t const* dst_rect, copybit_rect_t const* src_rect,
+            copybit_region_t const* region);
+    static int copybit_get(copybit_t* handle, int name);
+
+    int getFormat(int format);
+    void setImage(mdp_img* img, const copybit_image_t& rhs);
+    void setRects(mdp_blit_req* req, const copybit_rect_t& dst,
+            const copybit_rect_t& src, const copybit_rect_t& scissor);
+    void setInfos(mdp_blit_req* req);
+    static void intersect(copybit_rect_t* out, 
+            const copybit_rect_t& lhs, const copybit_rect_t& rhs);
+    status_t msm_copybit(void const* list);
+#endif
+    int mFD;
+    uint8_t mAlpha;
+    uint8_t mFlags;
+};
+}; // namespace android
+
+using namespace android;
+
+/******************************************************************************/
+
+struct copybit_t* copybit_init()
+{
+    CopybitMSM7K* engine = new CopybitMSM7K();
+    if (engine->getStatus() != NO_ERROR) {
+        delete engine;
+        engine = 0;
+    }
+    return (struct copybit_t*)engine;
+        
+}
+
+int copybit_term(copybit_t* handle)
+{
+    delete static_cast<CopybitMSM7K*>(handle);
+    return NO_ERROR;
+}
+
+namespace android {
+/******************************************************************************/
+
+static inline
+int min(int a, int b) {
+    return (a<b) ? a : b;
+}
+
+static inline
+int max(int a, int b) {
+    return (a>b) ? a : b;
+}
+
+static inline
+void MULDIV(uint32_t& a, uint32_t& b, int mul, int div)
+{
+    if (mul != div) {
+        a = (mul * a) / div;
+        b = (mul * b) / div;
+    }
+}
+
+//-----------------------------------------------------------------------------
+
+#if HAVE_ANDROID_OS
+
+int CopybitMSM7K::copybit_set_parameter(copybit_t* handle, int name, int value)
+{
+    return static_cast<CopybitMSM7K*>(handle)->setParameter(name, value);
+}
+
+int CopybitMSM7K::copybit_get(copybit_t* handle, int name)
+{
+    return static_cast<CopybitMSM7K*>(handle)->get(name);
+}
+
+int CopybitMSM7K::copybit_blit(
+        copybit_t* handle, 
+        copybit_image_t const* dst, 
+        copybit_image_t const* src,
+        struct copybit_region_t const* region)
+{
+    return static_cast<CopybitMSM7K*>(handle)->blit(*dst, *src, region);
+}
+
+int CopybitMSM7K::copybit_stretch(
+        copybit_t* handle, 
+        copybit_image_t const* dst, 
+        copybit_image_t const* src, 
+        copybit_rect_t const* dst_rect,
+        copybit_rect_t const* src_rect,
+        struct copybit_region_t const* region)
+{
+    return static_cast<CopybitMSM7K*>(handle)->stretch(
+            *dst, *src, *dst_rect, *src_rect, region);
+}
+
+//-----------------------------------------------------------------------------
+
+CopybitMSM7K::CopybitMSM7K()
+    : mFD(-1), mAlpha(MDP_ALPHA_NOP), mFlags(0)
+{
+    int fd = open("/dev/graphics/fb0", O_RDWR, 0);
+    if (fd > 0) {
+        struct fb_fix_screeninfo finfo;
+        if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) == 0) {
+            if (!strcmp(finfo.id, "msmfb")) {
+                mFD = fd;
+                copybit_t::set_parameter = copybit_set_parameter;
+                copybit_t::get = copybit_get;
+                copybit_t::blit = copybit_blit;
+                copybit_t::stretch = copybit_stretch;
+            }
+        }
+    }
+    if (fd<0 || mFD<0) {
+        if (fd>0) { close(fd); }
+        mFD = -errno;
+    }
+}
+
+CopybitMSM7K::~CopybitMSM7K()
+{
+    if (mFD > 0){
+        close(mFD);
+    }
+}
+
+status_t CopybitMSM7K::setParameter(int name, int value)
+{
+    switch(name) {
+    case COPYBIT_ROTATION_DEG:
+        switch (value) {
+        case 0:
+            mFlags &= ~0x7;
+            break;
+        case 90:
+            mFlags &= ~0x7;
+            mFlags |= MDP_ROT_90;
+            break;
+        case 180:
+            mFlags &= ~0x7;
+            mFlags |= MDP_ROT_180;
+            break;
+        case 270:
+            mFlags &= ~0x7;
+            mFlags |= MDP_ROT_270;
+            break;
+        default:
+            return BAD_VALUE;
+        }
+        break;
+    case COPYBIT_PLANE_ALPHA:
+        if (value < 0)      value = 0;
+        if (value >= 256)   value = 255;
+        mAlpha = value;
+        break;
+    case COPYBIT_DITHER:
+        if (value == COPYBIT_ENABLE) {
+            mFlags |= MDP_DITHER;
+        } else if (value == COPYBIT_DISABLE) {
+            mFlags &= ~MDP_DITHER;
+        }
+        break;
+    case COPYBIT_TRANSFORM:
+        mFlags &= ~0x7;
+        mFlags |= value & 0x7;
+        break;
+    default:
+        return BAD_VALUE;
+    }
+    return NO_ERROR;
+}
+
+status_t CopybitMSM7K::get(int name)
+{
+    switch(name) {
+    case COPYBIT_MINIFICATION_LIMIT:
+        return 4;
+    case COPYBIT_MAGNIFICATION_LIMIT:
+        return 4;
+    case COPYBIT_SCALING_FRAC_BITS:
+        return 32;
+    case COPYBIT_ROTATION_STEP_DEG:
+        return 90;
+    }
+    return BAD_VALUE;
+}
+
+status_t CopybitMSM7K::blit( 
+        const copybit_image_t& dst,
+        const copybit_image_t& src,
+        copybit_region_t const* region)
+{
+    
+    copybit_rect_t dr = { 0, 0, dst.w, dst.h };
+    copybit_rect_t sr = { 0, 0, src.w, src.h };
+    return CopybitMSM7K::stretch(dst, src, dr, sr, region);
+}
+
+status_t CopybitMSM7K::stretch( 
+        const copybit_image_t& dst,
+        const copybit_image_t& src, 
+        const copybit_rect_t& dst_rect,
+        const copybit_rect_t& src_rect,
+        copybit_region_t const* region)
+{
+    struct {
+        uint32_t count;
+        struct mdp_blit_req req[12];
+    } list;
+    
+    if (mAlpha<255) {
+        switch (src.format) {
+            // we dont' support plane alpha with RGBA formats
+            case COPYBIT_RGBA_8888:
+            case COPYBIT_RGBA_5551:
+            case COPYBIT_RGBA_4444:
+                return INVALID_OPERATION;
+        }
+    }
+        
+    const uint32_t maxCount = sizeof(list.req)/sizeof(list.req[0]);
+    const copybit_rect_t bounds = { 0, 0, dst.w, dst.h };
+    copybit_rect_t clip;
+    list.count = 0;
+    int err = 0;
+    while (!err && region->next(region, &clip)) {
+        intersect(&clip, bounds, clip);
+        setInfos(&list.req[list.count]);
+        setImage(&list.req[list.count].dst, dst);
+        setImage(&list.req[list.count].src, src);
+        setRects(&list.req[list.count], dst_rect, src_rect, clip);
+        if (++list.count == maxCount) {
+            err = msm_copybit(&list);
+            list.count = 0;
+        }
+    }
+    if (!err && list.count) {
+        err = msm_copybit(&list);
+    }
+    return err;
+}
+
+status_t CopybitMSM7K::msm_copybit(void const* list)
+{
+    int err = ioctl(mFD, MSMFB_BLIT, static_cast<mdp_blit_req_list const*>(list));
+    LOGE_IF(err<0, "copyBits failed (%s)", strerror(errno));
+    if (err == 0)
+        return NO_ERROR;
+    return -errno;
+}
+
+int CopybitMSM7K::getFormat(int format)
+{
+    switch (format) {
+    case COPYBIT_RGBA_8888:     return MDP_RGBA_8888;
+    case COPYBIT_RGB_565:       return MDP_RGB_565;
+    case COPYBIT_YCbCr_422_SP:  return MDP_Y_CBCR_H2V1;
+    case COPYBIT_YCbCr_420_SP:  return MDP_Y_CBCR_H2V2;
+    }
+    return -1;
+}
+
+void CopybitMSM7K::setInfos(mdp_blit_req* req)
+{
+    req->alpha = mAlpha;
+    req->transp_mask = MDP_TRANSP_NOP;
+    req->flags = mFlags;
+}
+
+void CopybitMSM7K::setImage(mdp_img* img, const copybit_image_t& rhs)
+{
+    img->width      = rhs.w;
+    img->height     = rhs.h;
+    img->format     = getFormat(rhs.format);
+    img->offset     = rhs.offset;
+    img->memory_id  = rhs.fd;
+}
+    
+void CopybitMSM7K::setRects(mdp_blit_req* e, 
+        const copybit_rect_t& dst, const copybit_rect_t& src,
+        const copybit_rect_t& scissor)
+{
+    copybit_rect_t clip;
+    intersect(&clip, scissor, dst);
+
+    e->dst_rect.x  = clip.l;
+    e->dst_rect.y  = clip.t;
+    e->dst_rect.w  = clip.r - clip.l;
+    e->dst_rect.h  = clip.b - clip.t;
+
+    uint32_t W, H;
+    if (mFlags & COPYBIT_TRANSFORM_ROT_90) {
+        e->src_rect.x  = (clip.t - dst.t) + src.t;
+        e->src_rect.y  = (dst.r - clip.r) + src.l;
+        e->src_rect.w  = (clip.b - clip.t);
+        e->src_rect.h  = (clip.r - clip.l);
+        W = dst.b - dst.t;
+        H = dst.r - dst.l;
+    } else {
+        e->src_rect.x  = (clip.l - dst.l) + src.l;
+        e->src_rect.y  = (clip.t - dst.t) + src.t;
+        e->src_rect.w  = (clip.r - clip.l);
+        e->src_rect.h  = (clip.b - clip.t);
+        W = dst.r - dst.l;
+        H = dst.b - dst.t;
+    }
+    MULDIV(e->src_rect.x, e->src_rect.w, src.r - src.l, W);
+    MULDIV(e->src_rect.y, e->src_rect.h, src.b - src.t, H);
+    if (mFlags & COPYBIT_TRANSFORM_FLIP_V) {
+        e->src_rect.y = e->src.height - (e->src_rect.y + e->src_rect.h);
+    }
+    if (mFlags & COPYBIT_TRANSFORM_FLIP_H) {
+        e->src_rect.x = e->src.width  - (e->src_rect.x + e->src_rect.w);
+    }
+}
+
+void CopybitMSM7K::intersect(copybit_rect_t* out, 
+        const copybit_rect_t& lhs, const copybit_rect_t& rhs)
+{
+    out->l = max(lhs.l, rhs.l);
+    out->t = max(lhs.t, rhs.t);
+    out->r = min(lhs.r, rhs.r);
+    out->b = min(lhs.b, rhs.b);
+}
+
+/******************************************************************************/
+#else // HAVE_ANDROID_OS
+
+CopybitMSM7K::CopybitMSM7K()
+    : mFD(-1)
+{
+}
+
+CopybitMSM7K::~CopybitMSM7K()
+{
+}
+
+status_t CopybitMSM7K::setParameter(int name, int value)
+{
+    return NO_INIT;
+}
+
+status_t CopybitMSM7K::get(int name)
+{
+    return BAD_VALUE;
+}
+
+status_t CopybitMSM7K::blit( 
+        const copybit_image_t& dst,
+        const copybit_image_t& src,
+        copybit_region_t const* region)
+{
+    return NO_INIT;
+}
+
+status_t CopybitMSM7K::stretch( 
+        const copybit_image_t& dst,
+        const copybit_image_t& src, 
+        const copybit_rect_t& dst_rect,
+        const copybit_rect_t& src_rect,
+        copybit_region_t const* region)
+{
+    return NO_INIT;
+}
+
+#endif // HAVE_ANDROID_OS
+
+/******************************************************************************/
+}; // namespace android
