  // ---------------------------------------------------------------------------
  }; // namespace android
  
+diff --git a/frameworks/native/libs/binder/MemoryBase.cpp b/frameworks/native/libs/binder/MemoryBase.cpp
+index 5c82330..611cfa7 100644
+--- a/frameworks/native/libs/binder/MemoryBase.cpp
++++ b/frameworks/native/libs/binder/MemoryBase.cpp
+@@ -26,6 +26,10 @@ namespace android {
+ 
+ // ---------------------------------------------------------------------------
+ 
++#ifdef STE_HARDWARE  
++extern "C" void _ZN7android10MemoryBaseC2ERKNS_2spINS_11IMemoryHeapEEElj() __attribute__((alias("_ZN7android10MemoryBaseC1ERKNS_2spINS_11IMemoryHeapEEElj")));
++#endif
++
+ MemoryBase::MemoryBase(const sp<IMemoryHeap>& heap,
+         ssize_t offset, size_t size)
+     : mSize(size), mOffset(offset), mHeap(heap)
+@@ -43,6 +47,21 @@ MemoryBase::~MemoryBase()
+ {
+ }
+ 
++#ifdef STE_HARDWARE
++sp<IMemoryHeap> android::MemoryBase::getMemory(long* offset, unsigned int* size) const
++{
++    ssize_t offset_o;
++    size_t size_o;
++    sp<IMemoryHeap> res;
++
++    res = getMemory(&offset_o, & size_o);
++    *offset = offset_o;
++    *size = size_o;
++
++    return res;
++}
++#endif
++
+ // ---------------------------------------------------------------------------
+ }; // namespace android
+ 
+diff --git a/frameworks/native/libs/gui/Android.mk b/frameworks/native/libs/gui/Android.mk
+index 5bc759e..8c2cb51 100644
+--- a/frameworks/native/libs/gui/Android.mk
++++ b/frameworks/native/libs/gui/Android.mk
+@@ -38,6 +38,12 @@ LOCAL_SHARED_LIBRARIES := \
+ 	libutils \
+ 	liblog
+ 
++#ifdef STE_HARDWARE
++LOCAL_SHARED_LIBRARIES += \
++	libhardware \
++	libhardware_legacy
++#endif
++
+ # Executed only on QCOM BSPs
+ ifeq ($(TARGET_USES_QCOM_BSP),true)
+ ifneq ($(TARGET_QCOM_DISPLAY_VARIANT),)
 diff --git a/frameworks/native/libs/gui/GLConsumer.cpp b/frameworks/native/libs/gui/GLConsumer.cpp
-index bec0f90..7a7958c 100644
+index bec0f90..4510326 100644
 --- a/frameworks/native/libs/gui/GLConsumer.cpp
 +++ b/frameworks/native/libs/gui/GLConsumer.cpp
-@@ -552,8 +552,18 @@ bool GLConsumer::isExternalFormat(uint32_t format)
-     case HAL_PIXEL_FORMAT_YV12:
-     // Legacy/deprecated YUV formats
-     case HAL_PIXEL_FORMAT_YCbCr_422_SP:
--    case HAL_PIXEL_FORMAT_YCrCb_420_SP:
+@@ -94,13 +94,32 @@ GLConsumer::GLConsumer(GLuint tex, bool allowSynchronousMode,
+     mEglDisplay(EGL_NO_DISPLAY),
+     mEglContext(EGL_NO_CONTEXT),
+     mCurrentTexture(BufferQueue::INVALID_BUFFER_SLOT),
++#ifdef STE_HARDWARE
++    mNextBlitSlot(0),
++#endif
+     mAttached(true)
+ {
++#ifdef STE_HARDWARE
++    sp<ISurfaceComposer> composer(ComposerService::getComposerService());
++    mGraphicBufferAlloc = composer->createGraphicBufferAlloc();
++    if (mGraphicBufferAlloc == 0) {
++        ST_LOGE("createGraphicBufferAlloc() failed in SurfaceTexture()");
++    }
++#endif
+     ST_LOGV("GLConsumer");
+ 
+     memcpy(mCurrentTransformMatrix, mtxIdentity,
+             sizeof(mCurrentTransformMatrix));
+ 
++#ifdef STE_HARDWARE
++    hw_module_t const* module;
++    mBlitEngine = 0;
++    if (hw_get_module(COPYBIT_HARDWARE_MODULE_ID, &module) == 0) {
++        copybit_open(module, &mBlitEngine);
++    }
++    ALOGE_IF(!mBlitEngine, "\nCannot open copybit mBlitEngine=%p", mBlitEngine);
++#endif
++
+     mBufferQueue->setConsumerUsageBits(DEFAULT_USAGE_FLAGS);
+ }
+ 
+@@ -222,6 +241,59 @@ status_t GLConsumer::releaseAndUpdateLocked(const BufferQueue::BufferItem& item)
+     // means the buffer was previously acquired), if we destroyed the
+     // EGLImage when detaching from a context but the buffer has not been
+     // re-allocated.
++#ifdef STE_HARDWARE
++    sp<GraphicBuffer> textureBuffer;
++    if (conversionIsNeeded(mSlots[buf].mGraphicBuffer)) {
++        /* deallocate image each time .... */
++        if (mEglSlots[buf].mEglImage != EGL_NO_IMAGE_KHR) {
++            eglDestroyImageKHR(mEglDisplay, mEglSlots[buf].mEglImage);
++            mEglSlots[buf].mEglImage = EGL_NO_IMAGE_KHR;
++        }
++        /* test if source and convert buffer size are ok */
++        if (mSlots[buf].mGraphicBuffer != NULL && mBlitSlots[mNextBlitSlot] != NULL) {
++            sp<GraphicBuffer> &srcBuf = mSlots[buf].mGraphicBuffer;
++            sp<GraphicBuffer> &dstBuf = mBlitSlots[mNextBlitSlot];
++            if (srcBuf->getWidth() != dstBuf->getWidth() || srcBuf->getHeight() != dstBuf->getHeight()) {
++                mBlitSlots[mNextBlitSlot] = NULL;
++            }
++        }
++        /* allocate convert buffer if needed */
++        if (mBlitSlots[mNextBlitSlot] == NULL) {
++            sp<GraphicBuffer> &srcBuf = mSlots[buf].mGraphicBuffer;
++            status_t res = 0;
++            sp<GraphicBuffer> dstBuf(mGraphicBufferAlloc->createGraphicBuffer(srcBuf->getWidth(),
++                                                                              srcBuf->getHeight(),
++                                                                              PIXEL_FORMAT_RGBA_8888,
++                                                                              srcBuf->getUsage(),
++                                                                              &res));
++            if (dstBuf == 0) {
++                ST_LOGE("updateTexImage: SurfaceComposer::createGraphicBuffer failed");
++                return NO_MEMORY;
++            }
++            if (res != NO_ERROR) {
++                ST_LOGW("updateTexImage: SurfaceComposer::createGraphicBuffer error=%#04x", res);
++            }
++            mBlitSlots[mNextBlitSlot] = dstBuf;
++        }
++        /* allocate image */
++        EGLImageKHR image = createImage(mEglDisplay, mBlitSlots[mNextBlitSlot]);
++        if (image == EGL_NO_IMAGE_KHR) {
++            ST_LOGW("releaseAndUpdate: unable to createImage on display=%p slot=%d", mEglDisplay, buf);
++            return UNKNOWN_ERROR;
++        }
++        mEglSlots[buf].mEglImage = image;
++        /* convert buffer */
++        if (convert(mSlots[buf].mGraphicBuffer, mBlitSlots[mNextBlitSlot]) != OK) {
++            ALOGE("updateTexImage: convert failed");
++            return UNKNOWN_ERROR;
++        }
++        textureBuffer = mBlitSlots[mNextBlitSlot];
++        mNextBlitSlot = (mNextBlitSlot + 1) % NUM_BLIT_BUFFER_SLOTS;
++    } else {
++        textureBuffer = mSlots[buf].mGraphicBuffer;
++    }
++#endif
++
+     if (mEglSlots[buf].mEglImage == EGL_NO_IMAGE_KHR) {
+         EGLImageKHR image = createImage(mEglDisplay, mSlots[buf].mGraphicBuffer);
+         if (image == EGL_NO_IMAGE_KHR) {
+@@ -260,7 +332,11 @@ status_t GLConsumer::releaseAndUpdateLocked(const BufferQueue::BufferItem& item)
+ 
+     // Update the GLConsumer state.
+     mCurrentTexture = buf;
 +#ifndef STE_HARDWARE
-+     case HAL_PIXEL_FORMAT_YCrCb_420_SP:
+     mCurrentTextureBuf = mSlots[buf].mGraphicBuffer;
 +#else
-+    case HAL_PIXEL_FORMAT_YCbCr_420_SP:
-+#endif
-     case HAL_PIXEL_FORMAT_YCbCr_422_I:
-+#ifdef STE_HARDWARE
-+    case HAL_PIXEL_FORMAT_YCrCb_422_SP:
-+    case HAL_PIXEL_FORMAT_YCrCb_422_P:
-+    case HAL_PIXEL_FORMAT_YCrCb_420_SP:
-+    case HAL_PIXEL_FORMAT_YCrCb_420_P:
-+#endif
-         return true;
-     }
- 
++    mCurrentTextureBuf = textureBuffer;
++#endif
+     mCurrentCrop = item.mCrop;
+     mCurrentTransform = item.mTransform;
+     mCurrentScalingMode = item.mScalingMode;
+@@ -901,6 +977,54 @@ void GLConsumer::dumpLocked(String8& result, const char* prefix,
+     ConsumerBase::dumpLocked(result, prefix, buffer, size);
+ }
+ 
++#ifdef STE_HARDWARE
++bool GLConsumer::conversionIsNeeded(const sp<GraphicBuffer>& graphicBuffer) {
++    int fmt = graphicBuffer->getPixelFormat();
++    return (fmt == PIXEL_FORMAT_YCBCR42XMBN) || (fmt == PIXEL_FORMAT_YCbCr_420_P);
++}
++
++status_t GLConsumer::convert(sp<GraphicBuffer> &srcBuf, sp<GraphicBuffer> &dstBuf) {
++    copybit_image_t dstImg;
++    dstImg.w = dstBuf->getWidth();
++    dstImg.h = dstBuf->getHeight();
++    dstImg.format = dstBuf->getPixelFormat();
++    dstImg.handle = (native_handle_t*) dstBuf->getNativeBuffer()->handle;
++
++    copybit_image_t srcImg;
++    srcImg.w = srcBuf->getWidth();
++    srcImg.h = srcBuf->getHeight();
++    srcImg.format = srcBuf->getPixelFormat();
++    srcImg.base = NULL;
++    srcImg.handle = (native_handle_t*) srcBuf->getNativeBuffer()->handle;
++
++    copybit_rect_t dstCrop;
++    dstCrop.l = 0;
++    dstCrop.t = 0;
++    dstCrop.r = dstBuf->getWidth();
++    dstCrop.b = dstBuf->getHeight();
++
++    copybit_rect_t srcCrop;
++    srcCrop.l = 0;
++    srcCrop.t = 0;
++    srcCrop.r = srcBuf->getWidth();
++    srcCrop.b = srcBuf->getHeight();
++
++    region_iterator clip(Region(Rect(dstCrop.r, dstCrop.b)));
++    mBlitEngine->set_parameter(mBlitEngine, COPYBIT_TRANSFORM, 0);
++    mBlitEngine->set_parameter(mBlitEngine, COPYBIT_PLANE_ALPHA, 0xFF);
++    mBlitEngine->set_parameter(mBlitEngine, COPYBIT_DITHER, COPYBIT_ENABLE);
++
++    int err = mBlitEngine->stretch(
++            mBlitEngine, &dstImg, &srcImg, &dstCrop, &srcCrop, &clip);
++    if (err != 0) {
++        ALOGE("\nError: Blit stretch operation failed (err:%d)\n", err);
++        /* return ok to not block decoding. But why this error ? */
++        return OK;
++    }
++    return OK;
++}
++#endif
++
+ static void mtxMul(float out[16], const float a[16], const float b[16]) {
+     out[0] = a[0]*b[0] + a[4]*b[1] + a[8]*b[2] + a[12]*b[3];
+     out[1] = a[1]*b[0] + a[5]*b[1] + a[9]*b[2] + a[13]*b[3];
+@@ -924,3 +1048,4 @@ static void mtxMul(float out[16], const float a[16], const float b[16]) {
+ }
+ 
+ }; // namespace android
++
 diff --git a/frameworks/native/libs/ui/PixelFormat.cpp b/frameworks/native/libs/ui/PixelFormat.cpp
-index 3ced41d..e73dac8 100644
+index 3ced41d..e4d27f5 100644
 --- a/frameworks/native/libs/ui/PixelFormat.cpp
 +++ b/frameworks/native/libs/ui/PixelFormat.cpp
-@@ -100,11 +100,29 @@ status_t getPixelFormatInfo(PixelFormat format, PixelFormatInfo* info)
+@@ -100,11 +100,31 @@ status_t getPixelFormatInfo(PixelFormat format, PixelFormatInfo* info)
      // YUV format from the HAL are handled here
      switch (format) {
      case HAL_PIXEL_FORMAT_YCbCr_422_SP:
 +#ifdef STE_HARDWARE
 +    case HAL_PIXEL_FORMAT_YCrCb_422_SP:
 +    case HAL_PIXEL_FORMAT_YCbCr_422_P:
++    case HAL_PIXEL_FORMAT_YCrCb_422_P:
 +#endif
      case HAL_PIXEL_FORMAT_YCbCr_422_I:
 +#ifdef STE_HARDWARE

 /* IMG extensions */
 
 EGL_ENTRY(EGLBoolean, eglHibernateProcessIMG, void)

     OMX_QCOM_COLOR_FormatYVU420SemiPlanar = 0x7FA30C00,
     OMX_QCOM_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka = 0x7FA30C03,
     OMX_SEC_COLOR_FormatNV12Tiled = 0x7FC00002,
diff --git a/frameworks/native/include/ui/GraphicBuffer.h b/frameworks/native/include/ui/GraphicBuffer.h
index a4b9b99..2db7c8f 100644
--- a/frameworks/native/include/ui/GraphicBuffer.h
+++ b/frameworks/native/include/ui/GraphicBuffer.h
@@ -38,7 +38,12 @@ class GraphicBufferMapper;
 // ===========================================================================
 
 class GraphicBuffer
-    : public ANativeObjectBase< ANativeWindowBuffer, GraphicBuffer, RefBase >,
+    : public ANativeObjectBase< ANativeWindowBuffer, GraphicBuffer,
+#ifdef STE_HARDWARE
+    LightRefBase<GraphicBuffer> >,
+#else
+    RefBase >,
+#endif
       public Flattenable
 {
 public:
diff --git a/frameworks/native/include/ui/PixelFormat.h b/frameworks/native/include/ui/PixelFormat.h
index 9f3e267..d89790d 100644
--- a/frameworks/native/include/ui/PixelFormat.h
