hack copybit back in for video playback on msm7k. we have h/w accelerated video again
diff --git a/include/ui/FramebufferNativeWindow.h b/include/ui/FramebufferNativeWindow.h
index a7804728c..03d064c 100644
--- a/include/ui/FramebufferNativeWindow.h
+++ b/include/ui/FramebufferNativeWindow.h
@@ -55,6 +55,9 @@
     bool isUpdateOnDemand() const { return mUpdateOnDemand; }
     status_t setUpdateRectangle(const Rect& updateRect);
     
+    // FIXME: needed for copybit hack in LayerBuffer
+    android_native_buffer_t const* getBackbuffer() const;
+    
 private:
     friend class LightRefBase<FramebufferNativeWindow>;    
     ~FramebufferNativeWindow(); // this class cannot be overloaded
@@ -75,8 +78,11 @@
     int32_t mNumFreeBuffers;
     int32_t mBufferHead;
     bool mUpdateOnDemand;
-};
 
+    // FIXME: for getBackbuffer
+    int32_t mLastDequeued;
+};
+    
 // ---------------------------------------------------------------------------
 }; // namespace android
 // ---------------------------------------------------------------------------
diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
index 784dfa5..925f5cc 100644
--- a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
+++ b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
@@ -349,10 +349,7 @@
     eglMakeCurrent(mDisplay, mSurface, mSurface, mContext);
 }
 
-void DisplayHardware::copyFrontToImage(const copybit_image_t& front) const {
-    // FIXME: we need to get rid of this
+sp<FramebufferNativeWindow> DisplayHardware::getFb() const { 
+    return mNativeWindow; 
 }
 
-void DisplayHardware::copyBackToImage(const copybit_image_t& front) const {
-    // FIXME: we need to get rid of this
-}
diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardware.h b/libs/surfaceflinger/DisplayHardware/DisplayHardware.h
index c3dbff1..240c5d1 100644
--- a/libs/surfaceflinger/DisplayHardware/DisplayHardware.h
+++ b/libs/surfaceflinger/DisplayHardware/DisplayHardware.h
@@ -80,13 +80,13 @@
     EGLDisplay getEGLDisplay() const { return mDisplay; }
     overlay_control_device_t* getOverlayEngine() const { return mOverlayEngine; }
     
-    void copyFrontToImage(const copybit_image_t& front) const;
-    void copyBackToImage(const copybit_image_t& front) const;
-       
     Rect bounds() const {
         return Rect(mWidth, mHeight);
     }
 
+    // FIXME: needed in LayerBuffer for msm7k/copybit hack
+    sp<FramebufferNativeWindow> getFb() const;
+    
 private:
     void init(uint32_t displayIndex) __attribute__((noinline));
     void fini() __attribute__((noinline));
diff --git a/libs/surfaceflinger/LayerBuffer.cpp b/libs/surfaceflinger/LayerBuffer.cpp
index 22fd499..1baf720 100644
--- a/libs/surfaceflinger/LayerBuffer.cpp
+++ b/libs/surfaceflinger/LayerBuffer.cpp
@@ -24,6 +24,9 @@
 #include <utils/StopWatch.h>
 
 #include <ui/PixelFormat.h>
+#include <ui/FramebufferNativeWindow.h>
+
+#include <hardware/copybit.h>
 
 #include "LayerBuffer.h"
 #include "SurfaceFlinger.h"
@@ -316,7 +319,12 @@
     mLayer.setNeedsBlending((info.h_alpha - info.l_alpha) > 0);    
     mBufferSize = info.getScanlineSize(buffers.hor_stride)*buffers.ver_stride;
     mLayer.forceVisibilityTransaction();
-    
+
+    hw_module_t const* module;
+    mBlitEngine = NULL;
+    if (hw_get_module(COPYBIT_HARDWARE_MODULE_ID, &module) == 0) {
+        copybit_open(module, &mBlitEngine);
+    }
 }
 
 LayerBuffer::BufferSource::~BufferSource()
@@ -387,9 +395,119 @@
         return;
     }
 
-    const NativeBuffer& src( ourBuffer->getBuffer() );
+    status_t err = NO_ERROR;
+    NativeBuffer src(ourBuffer->getBuffer());
+    const Rect& transformedBounds = mLayer.getTransformedBounds();
+    copybit_device_t* copybit = mBlitEngine;
 
-    //if (!can_use_copybit || err) 
+    if (copybit)  {
+        const int src_width  = src.crop.r - src.crop.l;
+        const int src_height = src.crop.b - src.crop.t;
+        int W = transformedBounds.width();
+        int H = transformedBounds.height();
+        if (mLayer.getOrientation() & Transform::ROT_90) {
+            int t(W); W=H; H=t;
+        }
+
+#if 0
+        /* 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. */
+
+        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)) {
+            if (UNLIKELY(mTemporaryDealer == 0)) {
+                // allocate a memory-dealer for this the first time
+                mTemporaryDealer = mLayer.mFlinger->getSurfaceHeapManager()
+                    ->createHeap(ISurfaceComposer::eHardware);
+                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;
+            }
+        }
+#endif
+
+        copybit_image_t dst;
+        const DisplayHardware& hw(mLayer.graphicPlane(0).displayHardware());
+        sp<FramebufferNativeWindow> fbw = hw.getFb();
+        android_native_buffer_t const* nb = fbw->getBackbuffer();
+        native_handle_t const* hnd = nb->handle;
+
+        if (hnd->data[1] != 0x3141592) {
+            LOGE("buffer not compatible with copybit");
+            err = -1;
+        } else {
+
+            dst.w       = 320;
+            dst.h       = 480;
+            dst.format  = 4;
+            dst.offset  = hnd->data[4];
+            dst.base    = 0;
+            dst.fd      = hnd->data[0];
+
+            const Rect& transformedBounds = mLayer.getTransformedBounds();
+            const copybit_rect_t& drect
+                = reinterpret_cast<const copybit_rect_t&>(transformedBounds);
+            const State& s(mLayer.drawingState());
+            region_iterator it(clip);
+
+            // pick the right orientation for this buffer
+            int orientation = mLayer.getOrientation();
+            if (UNLIKELY(mBufferHeap.transform)) {
+                Transform rot90;
+                GraphicPlane::orientationToTransfrom(
+                        ISurfaceComposer::eOrientation90, 0, 0, &rot90);
+                const Transform& planeTransform(mLayer.graphicPlane(0).transform());
+                const Layer::State& s(mLayer.drawingState());
+                Transform tr(planeTransform * s.transform * rot90);
+                orientation = tr.getOrientation();
+            }
+
+            copybit->set_parameter(copybit, COPYBIT_TRANSFORM, orientation);
+            copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, s.alpha);
+            copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_ENABLE);
+
+            err = copybit->stretch(copybit,
+                    &dst, &src.img, &drect, &src.crop, &it);
+            if (err != NO_ERROR) {
+                LOGE("copybit failed (%s)", strerror(err));
+            }
+        }
+    }
+
+    if (!copybit || err) 
     {
         // OpenGL fall-back
         if (UNLIKELY(mTexture.name == -1LU)) {
diff --git a/libs/surfaceflinger/LayerBuffer.h b/libs/surfaceflinger/LayerBuffer.h
index e1b3cf8..cd541a5 100644
--- a/libs/surfaceflinger/LayerBuffer.h
+++ b/libs/surfaceflinger/LayerBuffer.h
@@ -26,6 +26,8 @@
 #include "LayerBase.h"
 #include "LayerBitmap.h"
 
+struct copybit_device_t;
+
 namespace android {
 
 // ---------------------------------------------------------------------------
@@ -128,6 +130,7 @@
         size_t                          mBufferSize;
         mutable sp<android::Buffer>     mTempBitmap;
         mutable LayerBase::Texture      mTexture;
+        copybit_device_t*               mBlitEngine;
     };
     
     class OverlaySource : public Source {
diff --git a/libs/ui/FramebufferNativeWindow.cpp b/libs/ui/FramebufferNativeWindow.cpp
index 8c8fd6b..406c072 100644
--- a/libs/ui/FramebufferNativeWindow.cpp
+++ b/libs/ui/FramebufferNativeWindow.cpp
@@ -63,6 +63,11 @@
 };
 
 
+android_native_buffer_t const* FramebufferNativeWindow::getBackbuffer() const {
+    return static_cast<android_native_buffer_t const*>(buffers[mLastDequeued].get());
+}
+
+
 /*
  * This implements the (main) framebuffer management. This class is used
  * mostly by SurfaceFlinger, but also by command line GL application.
@@ -165,6 +170,7 @@
     if (self->mBufferHead >= self->mNumBuffers)
         self->mBufferHead = 0;
 
+    self->mLastDequeued = index;
     *buffer = self->buffers[index].get();
 
     return 0;