Merge commit 'remotes/korg/cupcake' into merge

Conflicts:
	core/java/android/view/animation/TranslateAnimation.java
	core/jni/Android.mk
	core/res/res/values-en-rGB/strings.xml
	libs/audioflinger/AudioFlinger.cpp
	libs/surfaceflinger/LayerScreenshot.cpp
	packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
diff --git a/camera/libcameraservice/CameraHardwareStub.cpp b/camera/libcameraservice/CameraHardwareStub.cpp
index 3d6b0b1..0f1ae8e 100644
--- a/camera/libcameraservice/CameraHardwareStub.cpp
+++ b/camera/libcameraservice/CameraHardwareStub.cpp
@@ -29,7 +29,8 @@
 
 CameraHardwareStub::CameraHardwareStub()
                   : mParameters(),
-                    mHeap(0),
+                    mPreviewHeap(0),
+                    mRawHeap(0),
                     mFakeCamera(0),
                     mPreviewFrameSize(0),
                     mRawPictureCallback(0),
@@ -62,13 +63,17 @@
 
 void CameraHardwareStub::initHeapLocked()
 {
-    int width, height;
-    mParameters.getPreviewSize(&width, &height);
+    // Create raw heap.
+    int picture_width, picture_height;
+    mParameters.getPictureSize(&picture_width, &picture_height);
+    mRawHeap = new MemoryHeapBase(picture_width * 2 * picture_height);
 
-    LOGD("initHeapLocked: preview size=%dx%d", width, height);
+    int preview_width, preview_height;
+    mParameters.getPreviewSize(&preview_width, &preview_height);
+    LOGD("initHeapLocked: preview size=%dx%d", preview_width, preview_height);
 
     // Note that we enforce yuv422 in setParameters().
-    int how_big = width * height * 2;
+    int how_big = preview_width * preview_height * 2;
 
     // If we are being reinitialized to the same size as before, no
     // work needs to be done.
@@ -79,15 +84,15 @@
 
     // Make a new mmap'ed heap that can be shared across processes. 
     // use code below to test with pmem
-    mHeap = new MemoryHeapBase(mPreviewFrameSize * kBufferCount);
+    mPreviewHeap = new MemoryHeapBase(mPreviewFrameSize * kBufferCount);
     // Make an IMemory for each frame so that we can reuse them in callbacks.
     for (int i = 0; i < kBufferCount; i++) {
-        mBuffers[i] = new MemoryBase(mHeap, i * mPreviewFrameSize, mPreviewFrameSize);
+        mBuffers[i] = new MemoryBase(mPreviewHeap, i * mPreviewFrameSize, mPreviewFrameSize);
     }
-
+    
     // Recreate the fake camera to reflect the current size.
     delete mFakeCamera;
-    mFakeCamera = new FakeCamera(width, height);
+    mFakeCamera = new FakeCamera(preview_width, preview_height);
 }
 
 CameraHardwareStub::~CameraHardwareStub()
@@ -99,7 +104,12 @@
 
 sp<IMemoryHeap> CameraHardwareStub::getPreviewHeap() const
 {
-    return mHeap;
+    return mPreviewHeap;
+}
+
+sp<IMemoryHeap> CameraHardwareStub::getRawHeap() const
+{
+    return mRawHeap;
 }
 
 // ---------------------------------------------------------------------------
@@ -114,7 +124,7 @@
         // Find the offset within the heap of the current buffer.
         ssize_t offset = mCurrentPreviewFrame * mPreviewFrameSize;
 
-        sp<MemoryHeapBase> heap = mHeap;
+        sp<MemoryHeapBase> heap = mPreviewHeap;
     
         // this assumes the internal state of fake camera doesn't change
         // (or is thread safe)
@@ -187,6 +197,24 @@
     return mPreviewThread != 0;
 }
 
+status_t CameraHardwareStub::startRecording(recording_callback cb, void* user)
+{
+    return UNKNOWN_ERROR;
+}
+
+void CameraHardwareStub::stopRecording()
+{
+}
+
+bool CameraHardwareStub::recordingEnabled()
+{
+    return false;
+}
+
+void CameraHardwareStub::releaseRecordingFrame(const sp<IMemory>& mem)
+{
+}
+
 // ---------------------------------------------------------------------------
 
 int CameraHardwareStub::beginAutoFocusThread(void *cookie)
@@ -237,10 +265,9 @@
         // In the meantime just make another fake camera picture.
         int w, h;
         mParameters.getPictureSize(&w, &h);
-        sp<MemoryHeapBase> heap = new MemoryHeapBase(w * 2 * h);
-        sp<MemoryBase> mem = new MemoryBase(heap, 0, w * 2 * h);
+        sp<MemoryBase> mem = new MemoryBase(mRawHeap, 0, w * 2 * h);
         FakeCamera cam(w, h);
-        cam.getNextFrameAsYuv422((uint8_t *)heap->base());
+        cam.getNextFrameAsYuv422((uint8_t *)mRawHeap->base());
         if (mRawPictureCallback)
             mRawPictureCallback(mem, mPictureCallbackCookie);
     }
diff --git a/camera/libcameraservice/CameraHardwareStub.h b/camera/libcameraservice/CameraHardwareStub.h
index 9f5ddf1..0d26d47 100644
--- a/camera/libcameraservice/CameraHardwareStub.h
+++ b/camera/libcameraservice/CameraHardwareStub.h
@@ -30,10 +30,17 @@
 class CameraHardwareStub : public CameraHardwareInterface {
 public:
     virtual sp<IMemoryHeap> getPreviewHeap() const;
+    virtual sp<IMemoryHeap> getRawHeap() const;
 
     virtual status_t    startPreview(preview_callback cb, void* user);
     virtual void        stopPreview();
     virtual bool        previewEnabled();
+
+    virtual status_t    startRecording(recording_callback cb, void* user);
+    virtual void        stopRecording();
+    virtual bool        recordingEnabled();
+    virtual void        releaseRecordingFrame(const sp<IMemory>& mem);
+
     virtual status_t    autoFocus(autofocus_callback, void *user);
     virtual status_t    takePicture(shutter_callback,
                                     raw_callback,
@@ -87,7 +94,8 @@
 
     CameraParameters    mParameters;
 
-    sp<MemoryHeapBase>  mHeap;
+    sp<MemoryHeapBase>  mPreviewHeap;
+    sp<MemoryHeapBase>  mRawHeap;
     sp<MemoryBase>      mBuffers[kBufferCount];
 
     FakeCamera          *mFakeCamera;
diff --git a/camera/libcameraservice/CameraService.cpp b/camera/libcameraservice/CameraService.cpp
index 36c5ada..15e3b21 100644
--- a/camera/libcameraservice/CameraService.cpp
+++ b/camera/libcameraservice/CameraService.cpp
@@ -86,18 +86,19 @@
     LOGD("Connect E from ICameraClient %p", cameraClient->asBinder().get());
 
     Mutex::Autolock lock(mLock);
+    sp<Client> client;
     if (mClient != 0) {
         sp<Client> currentClient = mClient.promote();
         if (currentClient != 0) {
             sp<ICameraClient> currentCameraClient(currentClient->getCameraClient());
             if (cameraClient->asBinder() == currentCameraClient->asBinder()) {
                 // this is the same client reconnecting...
-                LOGD("Connect X same client is reconnecting...");
+                LOGD("Connect X same client (%p) is reconnecting...", cameraClient->asBinder().get());
                 return currentClient;
             } else {
-                // it's another client... boot the previous one...
-                LOGD("new client connecting, booting the old one...");
-                mClient.clear();
+                // it's another client... reject it
+                LOGD("new client (%p) attempting to connect - rejected", cameraClient->asBinder().get());
+                return client;
             }
         } else {
             // can't promote, the previous client has died...
@@ -107,7 +108,7 @@
     }
 
     // create a new Client object
-    sp<Client> client = new Client(this, cameraClient, IPCThreadState::self()->getCallingPid());
+    client = new Client(this, cameraClient, IPCThreadState::self()->getCallingPid());
     mClient = client;
 #if DEBUG_CLIENT_REFERENCES
     // Enable tracking for this object, and track increments and decrements of
@@ -151,28 +152,30 @@
 }
 
 CameraService::Client::Client(const sp<CameraService>& cameraService,
-        const sp<ICameraClient>& cameraClient, pid_t clientPid) 
+        const sp<ICameraClient>& cameraClient, pid_t clientPid)
 {
     LOGD("Client E constructor");
     mCameraService = cameraService;
     mCameraClient = cameraClient;
     mClientPid = clientPid;
     mHardware = openCameraHardware();
+    mUseOverlay = mHardware->useOverlay();
 
     // Callback is disabled by default
-    mFrameCallbackFlag = FRAME_CALLBACK_FLAG_NOOP;
+    mPreviewCallbackFlag = FRAME_CALLBACK_FLAG_NOOP;
     LOGD("Client X constructor");
 }
 
 status_t CameraService::Client::checkPid()
 {
     if (mClientPid == IPCThreadState::self()->getCallingPid()) return NO_ERROR;
-    LOGW("Attempt to use locked camera from different process");
+    LOGW("Attempt to use locked camera (%p) from different process", getCameraClient()->asBinder().get());
     return -EBUSY;
 }
 
 status_t CameraService::Client::lock()
 {
+    Mutex::Autolock _l(mLock);
     // lock camera to this client if the the camera is unlocked
     if (mClientPid == 0) {
         mClientPid = IPCThreadState::self()->getCallingPid();
@@ -184,8 +187,9 @@
 
 status_t CameraService::Client::unlock()
 {
+    Mutex::Autolock _l(mLock);
     // allow anyone to use camera
-    LOGV("unlock");
+    LOGV("unlock (%p)", getCameraClient()->asBinder().get());
     status_t result = checkPid();
     if (result == NO_ERROR) mClientPid = 0;
     return result;
@@ -194,27 +198,40 @@
 status_t CameraService::Client::connect(const sp<ICameraClient>& client)
 {
     // connect a new process to the camera
-    LOGV("connect");
+    LOGV("connect (%p)", client->asBinder().get());
 
-    // hold a reference to the old client or we will deadlock if the client is
-    // in the same process and we hold the lock when we remove the reference
-    sp<ICameraClient> oldClient;
+    // I hate this hack, but things get really ugly when the media recorder
+    // service is handing back the camera to the app. The ICameraClient
+    // destructor will be called during the same IPC, making it look like
+    // the remote client is trying to disconnect. This hack temporarily
+    // sets the mClientPid to an invalid pid to prevent the hardware from
+    //  being torn down.
     {
-        Mutex::Autolock _l(mLock);
-        if (mClientPid != 0) {
-            LOGW("Tried to connect to locked camera");
-            return -EBUSY;
+
+        // hold a reference to the old client or we will deadlock if the client is
+        // in the same process and we hold the lock when we remove the reference
+        sp<ICameraClient> oldClient;
+        {
+            Mutex::Autolock _l(mLock);
+            if (mClientPid != 0) {
+                LOGW("Tried to connect to locked camera");
+                return -EBUSY;
+            }
+            oldClient = mCameraClient;
+
+            // did the client actually change?
+            if (client->asBinder() == mCameraClient->asBinder()) return NO_ERROR;
+
+            mCameraClient = client;
+            mClientPid = -1;
+            mPreviewCallbackFlag = FRAME_CALLBACK_FLAG_NOOP;
+            LOGV("connect new process (%d) to existing camera client", mClientPid);
         }
-        oldClient = mCameraClient;
 
-        // did the client actually change?
-        if (client->asBinder() == mCameraClient->asBinder()) return NO_ERROR;
-
-        LOGV("connect new process to existing camera client");
-        mCameraClient = client;
-        mClientPid = IPCThreadState::self()->getCallingPid();
-        mFrameCallbackFlag = FRAME_CALLBACK_FLAG_NOOP;
     }
+    // the old client destructor is called when oldClient goes out of scope
+    // now we set the new PID to lock the interface again
+    mClientPid = IPCThreadState::self()->getCallingPid();
 
     return NO_ERROR;
 }
@@ -232,8 +249,8 @@
 CameraService::Client::~Client()
 {
     // tear down client
-    LOGD("Client E destructor");
-    if (mSurface != 0) {
+    LOGD("Client (%p)  E destructor", getCameraClient()->asBinder().get());
+    if (mSurface != 0 && !mUseOverlay) {
 #if HAVE_ANDROID_OS
         pthread_t thr;
         // We unregister the buffers in a different thread because binder does
@@ -244,7 +261,7 @@
                        mSurface.get());
         pthread_join(thr, NULL);
 #else
-    	mSurface->unregisterBuffers();
+        mSurface->unregisterBuffers();
 #endif
     }
 
@@ -256,16 +273,22 @@
 
 void CameraService::Client::disconnect()
 {
-    LOGD("Client E disconnect");
+    LOGD("Client (%p) E disconnect from (%d)",
+            getCameraClient()->asBinder().get(),
+            IPCThreadState::self()->getCallingPid());
     Mutex::Autolock lock(mLock);
-    if (mClientPid == 0) {
+    if (mClientPid <= 0) {
         LOGV("camera is unlocked, don't tear down hardware");
         return;
     }
-    if (checkPid() != NO_ERROR) return;
+    if (checkPid() != NO_ERROR) {
+        LOGV("Different client - don't disconnect");
+        return;
+    }
 
     mCameraService->removeClient(mCameraClient);
     if (mHardware != 0) {
+        LOGV("hardware teardown");
         // Before destroying mHardware, we must make sure it's in the
         // idle state.
         mHardware->stopPreview();
@@ -288,7 +311,7 @@
     Mutex::Autolock surfaceLock(mSurfaceLock);
     // asBinder() is safe on NULL (returns NULL)
     if (surface->asBinder() != mSurface->asBinder()) {
-        if (mSurface != 0) {
+        if (mSurface != 0 && !mUseOverlay) {
             LOGD("clearing old preview surface %p", mSurface.get());
             mSurface->unregisterBuffers();
         }
@@ -297,19 +320,20 @@
     return NO_ERROR;
 }
 
-// set the frame callback flag to affect how the received frames from
+// set the preview callback flag to affect how the received frames from
 // preview are handled.
-void CameraService::Client::setFrameCallbackFlag(int frame_callback_flag)
+void CameraService::Client::setPreviewCallbackFlag(int callback_flag)
 {
+    LOGV("setPreviewCallbackFlag");
     Mutex::Autolock lock(mLock);
     if (checkPid() != NO_ERROR) return;
-    mFrameCallbackFlag = frame_callback_flag;
+    mPreviewCallbackFlag = callback_flag;
 }
 
 // start preview mode, must call setPreviewDisplay first
-status_t CameraService::Client::startPreview()
+status_t CameraService::Client::startCameraMode(camera_mode mode)
 {
-    LOGD("startPreview()");
+    LOGD("startCameraMode(%d)", mode);
 
     /* we cannot call into mHardware with mLock held because
      * mHardware has callbacks onto us which acquire this lock
@@ -325,37 +349,124 @@
     }
 
     if (mSurface == 0) {
-        LOGE("setPreviewDisplay must be called before startPreview!");
+        LOGE("setPreviewDisplay must be called before startCameraMode!");
         return INVALID_OPERATION;
     }
 
-    // do nothing if preview is already started
-    if (mHardware->previewEnabled()) return NO_ERROR;
+    switch(mode) {
+    case CAMERA_RECORDING_MODE:
+        return startRecordingMode();
 
-    // XXX: This needs to be improved. remove all hardcoded stuff
+    default: // CAMERA_PREVIEW_MODE
+        return startPreviewMode();
+    }
+}
 
+status_t CameraService::Client::startRecordingMode()
+{
+    LOGV("startRecordingMode");
+
+    status_t ret = UNKNOWN_ERROR;
+
+    // if preview has not been started, start preview first
+    if (!mHardware->previewEnabled()) {
+        ret = startPreviewMode();
+        if (ret != NO_ERROR) {
+            return ret;
+        }
+    }
+
+    // if recording has been enabled, nothing needs to be done
+    if (mHardware->recordingEnabled()) {
+        return NO_ERROR;
+    }
+
+    // start recording mode
+    ret = mHardware->startRecording(recordingCallback,
+                                    mCameraService.get());
+    if (ret != NO_ERROR) {
+        LOGE("mHardware->startRecording() failed with status %d", ret);
+    }
+    return ret;
+}
+
+status_t CameraService::Client::startPreviewMode()
+{
+    LOGV("startPreviewMode");
+
+    // if preview has been enabled, nothing needs to be done
+    if (mHardware->previewEnabled()) {
+        return NO_ERROR;
+    }
+
+    // start preview mode
+#if DEBUG_DUMP_PREVIEW_FRAME_TO_FILE
+    debug_frame_cnt = 0;
+#endif
+    status_t ret = UNKNOWN_ERROR;
     int w, h;
     CameraParameters params(mHardware->getParameters());
     params.getPreviewSize(&w, &h);
 
-#if DEBUG_DUMP_PREVIEW_FRAME_TO_FILE
-    debug_frame_cnt = 0;
-#endif
+    if (mUseOverlay) {
+        const char *format = params.getPreviewFormat();
+        int fmt;
+        LOGD("Use Overlays");
+        if (!strcmp(format, "yuv422i"))
+            fmt = OVERLAY_FORMAT_YCbCr_422_I;
+        else if (!strcmp(format, "rgb565"))
+            fmt = OVERLAY_FORMAT_RGB_565;
+        else {
+            LOGE("Invalid preview format for overlays");
+            return -EINVAL;
+        }
+        sp<OverlayRef> ref = mSurface->createOverlay(w, h, fmt);
+        ret = mHardware->setOverlay(new Overlay(ref));
+        if (ret != NO_ERROR) {
+            LOGE("mHardware->setOverlay() failed with status %d\n", ret);
+            return ret;
+        }
+        ret = mHardware->startPreview(NULL, mCameraService.get());
+        if (ret != NO_ERROR)
+            LOGE("mHardware->startPreview() failed with status %d\n", ret);
 
-    status_t ret = mHardware->startPreview(previewCallback,
-                                           mCameraService.get());
-    if (ret == NO_ERROR) {
-        mSurface->unregisterBuffers();
-        mSurface->registerBuffers(w,h,w,h,
-                                  PIXEL_FORMAT_YCbCr_420_SP,
-                                  mHardware->getPreviewHeap());
+    } else {
+        ret = mHardware->startPreview(previewCallback,
+                                      mCameraService.get());
+        if (ret == NO_ERROR) {
+
+            mSurface->unregisterBuffers();
+
+            uint32_t transform = 0;
+            if (params.getOrientation() ==
+                CameraParameters::CAMERA_ORIENTATION_PORTRAIT) {
+              LOGV("portrait mode");
+              transform = ISurface::BufferHeap::ROT_90;
+            }
+            ISurface::BufferHeap buffers(w, h, w, h,
+                                         PIXEL_FORMAT_YCbCr_420_SP,
+                                         transform,
+                                         0,
+                                         mHardware->getPreviewHeap());
+
+            mSurface->registerBuffers(buffers);
+        } else {
+          LOGE("mHardware->startPreview() failed with status %d", ret);
+        }
     }
-    else LOGE("mHardware->startPreview() failed with status %d\n",
-              ret);
-
     return ret;
 }
 
+status_t CameraService::Client::startPreview()
+{
+    return startCameraMode(CAMERA_PREVIEW_MODE);
+}
+
+status_t CameraService::Client::startRecording()
+{
+    return startCameraMode(CAMERA_RECORDING_MODE);
+}
+
 // stop preview mode
 void CameraService::Client::stopPreview()
 {
@@ -372,12 +483,46 @@
     mHardware->stopPreview();
     LOGD("stopPreview(), hardware stopped OK");
 
-    if (mSurface != 0) {
+    if (mSurface != 0 && !mUseOverlay) {
         mSurface->unregisterBuffers();
     }
     mPreviewBuffer.clear();
 }
 
+// stop recording mode
+void CameraService::Client::stopRecording()
+{
+    LOGV("stopRecording()");
+
+    Mutex::Autolock lock(mLock);
+    if (checkPid() != NO_ERROR) return;
+
+    if (mHardware == 0) {
+        LOGE("mHardware is NULL, returning.");
+        return;
+    }
+
+    mHardware->stopRecording();
+    LOGV("stopRecording(), hardware stopped OK");
+    mPreviewBuffer.clear();
+}
+
+// release a recording frame
+void CameraService::Client::releaseRecordingFrame(const sp<IMemory>& mem)
+{
+    LOGV("releaseRecordingFrame()");
+
+    Mutex::Autolock lock(mLock);
+    if (checkPid() != NO_ERROR) return;
+
+    if (mHardware == 0) {
+        LOGE("mHardware is NULL, returning.");
+        return;
+    }
+
+    mHardware->releaseRecordingFrame(mem);
+}
+
 bool CameraService::Client::previewEnabled()
 {
     Mutex::Autolock lock(mLock);
@@ -385,6 +530,13 @@
     return mHardware->previewEnabled();
 }
 
+bool CameraService::Client::recordingEnabled()
+{
+    Mutex::Autolock lock(mLock);
+    if (mHardware == 0) return false;
+    return mHardware->recordingEnabled();
+}
+
 // Safely retrieves a strong pointer to the client during a hardware callback.
 sp<CameraService::Client> CameraService::Client::getClientFromCookie(void* user)
 {
@@ -476,7 +628,7 @@
 #endif
 
     // The strong pointer guarantees the client will exist, but no lock is held.
-    client->postFrame(mem);
+    client->postPreviewFrame(mem);
 
 #if DEBUG_CLIENT_REFERENCES
     //**** if the client's refcount is 1, then we are about to destroy it here,
@@ -488,6 +640,18 @@
 #endif
 }
 
+// recording callback
+void CameraService::Client::recordingCallback(const sp<IMemory>& mem, void* user)
+{
+    LOGV("recordingCallback");
+    sp<Client> client = getClientFromCookie(user);
+    if (client == 0) {
+        return;
+    }
+    // The strong pointer guarantees the client will exist, but no lock is held.
+    client->postRecordingFrame(mem);
+}
+
 // take a picture - image is returned in callback
 status_t CameraService::Client::autoFocus()
 {
@@ -520,9 +684,6 @@
         return INVALID_OPERATION;
     }
 
-    if (mSurface != NULL)
-        mSurface->unregisterBuffers();
-
     return mHardware->takePicture(shutterCallback,
                                   yuvPictureCallback,
                                   jpegPictureCallback,
@@ -537,7 +698,29 @@
         return;
     }
 
+    // Screen goes black after the buffer is unregistered.
+    if (client->mSurface != 0 && !client->mUseOverlay) {
+        client->mSurface->unregisterBuffers();
+    }
+
     client->postShutter();
+
+    // It takes some time before yuvPicture callback to be called.
+    // Register the buffer for raw image here to reduce latency.
+    if (client->mSurface != 0 && !client->mUseOverlay) {
+        int w, h;
+        CameraParameters params(client->mHardware->getParameters());
+        params.getPictureSize(&w, &h);
+        uint32_t transform = 0;
+        if (params.getOrientation() == CameraParameters::CAMERA_ORIENTATION_PORTRAIT) {
+            LOGV("portrait mode");
+            transform = ISurface::BufferHeap::ROT_90;
+        }
+        ISurface::BufferHeap buffers(w, h, w, h,
+            PIXEL_FORMAT_YCbCr_420_SP, transform, 0, client->mHardware->getRawHeap());
+
+        client->mSurface->registerBuffers(buffers);
+    }
 }
 
 // picture callback - raw image ready
@@ -568,15 +751,7 @@
 #endif
 
     // Put the YUV version of the snapshot in the preview display.
-    int w, h;
-    CameraParameters params(client->mHardware->getParameters());
-    params.getPictureSize(&w, &h);
-
-//  Mutex::Autolock clientLock(client->mLock);
-    if (client->mSurface != 0) {
-        client->mSurface->unregisterBuffers();
-        client->mSurface->registerBuffers(w,h,w,h,
-                                          PIXEL_FORMAT_YCbCr_420_SP, heap);
+    if (client->mSurface != 0 && !client->mUseOverlay) {
         client->mSurface->postBuffer(offset);
     }
 
@@ -730,12 +905,22 @@
         LOGE("failed to allocate space for frame callback");
         return;
     }
-    mCameraClient->frameCallback(frame);
+    mCameraClient->previewCallback(frame);
 }
 
-void CameraService::Client::postFrame(const sp<IMemory>& mem)
+void CameraService::Client::postRecordingFrame(const sp<IMemory>& frame)
 {
-    LOGV("postFrame");
+    LOGV("postRecordingFrame");
+    if (frame == 0) {
+        LOGW("frame is a null pointer");
+        return;
+    }
+    mCameraClient->recordingCallback(frame);
+}
+
+void CameraService::Client::postPreviewFrame(const sp<IMemory>& mem)
+{
+    LOGV("postPreviewFrame");
     if (mem == 0) {
         LOGW("mem is a null pointer");
         return;
@@ -752,31 +937,32 @@
     }
 
     // Is the callback enabled or not?
-    if (!(mFrameCallbackFlag & FRAME_CALLBACK_FLAG_ENABLE_MASK)) {
+    if (!(mPreviewCallbackFlag & FRAME_CALLBACK_FLAG_ENABLE_MASK)) {
         // If the enable bit is off, the copy-out and one-shot bits are ignored
         LOGV("frame callback is diabled");
         return;
     }
 
     // Is the received frame copied out or not?
-    if (mFrameCallbackFlag & FRAME_CALLBACK_FLAG_COPY_OUT_MASK) {
+    if (mPreviewCallbackFlag & FRAME_CALLBACK_FLAG_COPY_OUT_MASK) {
         LOGV("frame is copied out");
         copyFrameAndPostCopiedFrame(heap, offset, size);
     } else {
         LOGV("frame is directly sent out without copying");
-        mCameraClient->frameCallback(mem);
+        mCameraClient->previewCallback(mem);
     }
 
     // Is this is one-shot only?
-    if (mFrameCallbackFlag & FRAME_CALLBACK_FLAG_ONE_SHOT_MASK) {
+    if (mPreviewCallbackFlag & FRAME_CALLBACK_FLAG_ONE_SHOT_MASK) {
         LOGV("One-shot only, thus clear the bits and disable frame callback");
-        mFrameCallbackFlag &= ~(FRAME_CALLBACK_FLAG_ONE_SHOT_MASK |
+        mPreviewCallbackFlag &= ~(FRAME_CALLBACK_FLAG_ONE_SHOT_MASK |
                                 FRAME_CALLBACK_FLAG_COPY_OUT_MASK |
                                 FRAME_CALLBACK_FLAG_ENABLE_MASK);
     }
 }
 
-void CameraService::Client::postError(status_t error) {
+void CameraService::Client::postError(status_t error)
+{
     mCameraClient->errorCallback(error);
 }
 
@@ -796,6 +982,11 @@
         AutoMutex lock(&mLock);
         if (mClient != 0) {
             sp<Client> currentClient = mClient.promote();
+            sprintf(buffer, "Client (%p) PID: %d\n",
+                    currentClient->getCameraClient()->asBinder().get(),
+                    currentClient->mClientPid);
+            result.append(buffer);
+            write(fd, result.string(), result.size());
             currentClient->mHardware->dump(fd, args);
         } else {
             result.append("No camera client yet.\n");
@@ -880,5 +1071,3 @@
 #endif // DEBUG_HEAP_LEAKS
 
 }; // namespace android
-
-
diff --git a/camera/libcameraservice/CameraService.h b/camera/libcameraservice/CameraService.h
index cd8c1e9..d9b7927 100644
--- a/camera/libcameraservice/CameraService.h
+++ b/camera/libcameraservice/CameraService.h
@@ -82,9 +82,9 @@
         // pass the buffered ISurface to the camera service
         virtual status_t        setPreviewDisplay(const sp<ISurface>& surface);
 
-        // set the frame callback flag to affect how the received frames from
+        // set the preview callback flag to affect how the received frames from
         // preview are handled.
-        virtual void            setFrameCallbackFlag(int frame_callback_flag);
+        virtual void            setPreviewCallbackFlag(int callback_flag);
 
         // start preview mode, must call setPreviewDisplay first
         virtual status_t        startPreview();
@@ -95,6 +95,18 @@
         // get preview state
         virtual bool            previewEnabled();
 
+        // start recording mode
+        virtual status_t        startRecording();
+
+        // stop recording mode
+        virtual void            stopRecording();
+
+        // get recording state
+        virtual bool            recordingEnabled();
+
+        // release a recording frame
+        virtual void            releaseRecordingFrame(const sp<IMemory>& mem);
+
         // auto focus
         virtual status_t        autoFocus();
 
@@ -120,6 +132,7 @@
 
                     status_t    checkPid();
 
+        static      void        recordingCallback(const sp<IMemory>& mem, void* user);
         static      void        previewCallback(const sp<IMemory>& mem, void* user);
         static      void        shutterCallback(void *user);
         static      void        yuvPictureCallback(const sp<IMemory>& mem, void* user);
@@ -130,17 +143,28 @@
                     void        postShutter();
                     void        postRaw(const sp<IMemory>& mem);
                     void        postJpeg(const sp<IMemory>& mem);
-                    void        postFrame(const sp<IMemory>& mem);
+                    void        postPreviewFrame(const sp<IMemory>& mem);
+                    void        postRecordingFrame(const sp<IMemory>& frame);
                     void        copyFrameAndPostCopiedFrame(sp<IMemoryHeap> heap, size_t offset, size_t size);
                     void        postError(status_t error);
                     void        postAutoFocus(bool focused);
 
-                    // Ensures atomicity among the public methods
+        // camera operation mode
+        enum camera_mode {
+            CAMERA_PREVIEW_MODE   = 0,  // frame automatically released
+            CAMERA_RECORDING_MODE = 1,  // frame has to be explicitly released by releaseRecordingFrame()
+        };
+        status_t                startCameraMode(camera_mode mode);
+        status_t                startPreviewMode();
+        status_t                startRecordingMode();
+
+        // Ensures atomicity among the public methods
         mutable     Mutex                       mLock;
+
         // mSurfaceLock synchronizes access to mSurface between
-        // setPreviewSurface() and postFrame().  Note that among
+        // setPreviewSurface() and postPreviewFrame().  Note that among
         // the public methods, all accesses to mSurface are
-        // syncrhonized by mLock.  However, postFrame() is called
+        // syncrhonized by mLock.  However, postPreviewFrame() is called
         // by the CameraHardwareInterface callback, and needs to
         // access mSurface.  It cannot hold mLock, however, because
         // stopPreview() may be holding that lock while attempting
@@ -152,13 +176,14 @@
                     sp<CameraService>           mCameraService;
                     sp<ISurface>                mSurface;
                     sp<MemoryHeapBase>          mPreviewBuffer;
-                    int                         mFrameCallbackFlag;
+                    int                         mPreviewCallbackFlag;
 
                     // these are immutable once the object is created,
                     // they don't need to be protected by a lock
                     sp<ICameraClient>           mCameraClient;
                     sp<CameraHardwareInterface> mHardware;
                     pid_t                       mClientPid;
+                    bool                        mUseOverlay;
     };
 
 // ----------------------------------------------------------------------------
diff --git a/include/GLES/egl.h b/include/GLES/egl.h
deleted file mode 100644
index 08834ab..0000000
--- a/include/GLES/egl.h
+++ /dev/null
@@ -1,268 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef ANDROID_EGL_H
-#define ANDROID_EGL_H
-
-#include <GLES/gl.h>
-#include <GLES/egltypes.h>
-#include <GLES/eglnatives.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define EGL_VERSION_1_0         1
-#define EGL_VERSION_1_1         1
-#define EGL_VERSION_1_2         1
-
-#define EGL_FALSE               0
-#define EGL_TRUE                1
-
-/* Errors */
-#define EGL_SUCCESS                     0x3000
-#define EGL_NOT_INITIALIZED             0x3001
-#define EGL_BAD_ACCESS                  0x3002
-#define EGL_BAD_ALLOC                   0x3003
-#define EGL_BAD_ATTRIBUTE               0x3004
-#define EGL_BAD_CONFIG                  0x3005
-#define EGL_BAD_CONTEXT                 0x3006
-#define EGL_BAD_CURRENT_SURFACE         0x3007
-#define EGL_BAD_DISPLAY                 0x3008
-#define EGL_BAD_MATCH                   0x3009
-#define EGL_BAD_NATIVE_PIXMAP           0x300A
-#define EGL_BAD_NATIVE_WINDOW           0x300B
-#define EGL_BAD_PARAMETER               0x300C
-#define EGL_BAD_SURFACE                 0x300D
-#define EGL_CONTEXT_LOST                0x300E
-
-/* Config attributes */
-#define EGL_BUFFER_SIZE                 0x3020
-#define EGL_ALPHA_SIZE                  0x3021
-#define EGL_BLUE_SIZE                   0x3022
-#define EGL_GREEN_SIZE                  0x3023
-#define EGL_RED_SIZE                    0x3024
-#define EGL_DEPTH_SIZE                  0x3025
-#define EGL_STENCIL_SIZE                0x3026
-#define EGL_CONFIG_CAVEAT               0x3027
-#define EGL_CONFIG_ID                   0x3028
-#define EGL_LEVEL                       0x3029
-#define EGL_MAX_PBUFFER_HEIGHT          0x302A
-#define EGL_MAX_PBUFFER_PIXELS          0x302B
-#define EGL_MAX_PBUFFER_WIDTH           0x302C
-#define EGL_NATIVE_RENDERABLE           0x302D
-#define EGL_NATIVE_VISUAL_ID            0x302E
-#define EGL_NATIVE_VISUAL_TYPE          0x302F
-#define EGL_SAMPLES                     0x3031
-#define EGL_SAMPLE_BUFFERS              0x3032
-#define EGL_SURFACE_TYPE                0x3033
-#define EGL_TRANSPARENT_TYPE            0x3034
-#define EGL_TRANSPARENT_BLUE_VALUE      0x3035
-#define EGL_TRANSPARENT_GREEN_VALUE     0x3036
-#define EGL_TRANSPARENT_RED_VALUE       0x3037
-#define EGL_NONE                        0x3038
-#define EGL_BIND_TO_TEXTURE_RGB         0x3039
-#define EGL_BIND_TO_TEXTURE_RGBA        0x303A
-#define EGL_MIN_SWAP_INTERVAL           0x303B
-#define EGL_MAX_SWAP_INTERVAL           0x303C
-#define EGL_LUMINANCE_SIZE              0x303D
-#define EGL_ALPHA_MASK_SIZE             0x303E
-#define EGL_COLOR_BUFFER_TYPE           0x303F
-#define EGL_RENDERABLE_TYPE             0x3040
-
-/* Config values */
-#define EGL_DONT_CARE                   ((EGLint)-1)
-
-#define EGL_SLOW_CONFIG                 0x3050
-#define EGL_NON_CONFORMANT_CONFIG       0x3051
-#define EGL_TRANSPARENT_RGB             0x3052
-#define EGL_NO_TEXTURE                  0x305C
-#define EGL_TEXTURE_RGB                 0x305D
-#define EGL_TEXTURE_RGBA                0x305E
-#define EGL_TEXTURE_2D                  0x305F
-#define EGL_RGB_BUFFER                  0x308E
-#define EGL_LUMINANCE_BUFFER            0x308F
-
-/* Config attribute mask bits */
-#define EGL_PBUFFER_BIT                 0x01
-#define EGL_PIXMAP_BIT                  0x02
-#define EGL_WINDOW_BIT                  0x04
-#define EGL_OPENGL_ES_BIT               0x01
-#define EGL_OPENVG_BIT                  0x02
-
-/* String names */
-#define EGL_VENDOR                      0x3053
-#define EGL_VERSION                     0x3054
-#define EGL_EXTENSIONS                  0x3055
-#define EGL_CLIENT_APIS                 0x308D
-
-/* Surface attributes */
-#define EGL_HEIGHT                      0x3056
-#define EGL_WIDTH                       0x3057
-#define EGL_LARGEST_PBUFFER             0x3058
-#define EGL_TEXTURE_FORMAT              0x3080
-#define EGL_TEXTURE_TARGET              0x3081
-#define EGL_MIPMAP_TEXTURE              0x3082
-#define EGL_MIPMAP_LEVEL                0x3083
-#define EGL_RENDER_BUFFER               0x3086
-#define EGL_COLORSPACE                  0x3087
-#define EGL_ALPHA_FORMAT                0x3088
-#define EGL_HORIZONTAL_RESOLUTION       0x3090
-#define EGL_VERTICAL_RESOLUTION         0x3091
-#define EGL_PIXEL_ASPECT_RATIO          0x3092
-#define EGL_SWAP_BEHAVIOR               0x3093
-
-#define EGL_BACK_BUFFER                 0x3084
-#define EGL_SINGLE_BUFFER               0x3085
-
-#define EGL_DISPLAY_SCALING             10000
-
-#define EGL_UNKNOWN                     ((EGLint)-1)
-
-/* Back buffer swap behaviors */
-#define EGL_BUFFER_PRESERVED            0x3094
-#define EGL_BUFFER_DESTROYED            0x3095
-
-/* CreatePbufferFromClientBuffer buffer types */
-#define EGL_OPENVG_IMAGE                0x3096
-
-/* QueryContext targets */
-#define EGL_CONTEXT_CLIENT_TYPE         0x3097
-
-/* BindAPI/QueryAPI targets */
-#define EGL_OPENGL_ES_API               0x30A0
-#define EGL_OPENVG_API                  0x30A1
-
-/* WaitNative engines */
-#define EGL_CORE_NATIVE_ENGINE          0x305B
-
-/* Current surfaces */
-#define EGL_DRAW                        0x3059
-#define EGL_READ                        0x305A
-
-
-EGLDisplay eglGetDisplay(NativeDisplayType display);
-EGLBoolean eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor);
-EGLBoolean eglTerminate(EGLDisplay dpy);
-
-EGLBoolean eglGetConfigs(   EGLDisplay dpy,
-                            EGLConfig *configs,
-                            EGLint config_size, EGLint *num_config);
-
-EGLBoolean eglChooseConfig( EGLDisplay dpy, const EGLint *attrib_list,
-                            EGLConfig *configs, EGLint config_size,
-                            EGLint *num_config);
-
-EGLBoolean eglGetConfigAttrib(  EGLDisplay dpy, EGLConfig config,
-                                EGLint attribute, EGLint *value);
-
-EGLSurface eglCreateWindowSurface(  EGLDisplay dpy, EGLConfig config,
-                                    NativeWindowType window,
-                                    const EGLint *attrib_list);
-
-EGLSurface eglCreatePixmapSurface(  EGLDisplay dpy, EGLConfig config,
-                                    NativePixmapType pixmap,
-                                    const EGLint *attrib_list);
-
-EGLSurface eglCreatePbufferSurface( EGLDisplay dpy, EGLConfig config,
-                                    const EGLint *attrib_list);
-                                    
-EGLBoolean eglDestroySurface(EGLDisplay dpy, EGLSurface surface);
-
-EGLBoolean eglQuerySurface( EGLDisplay dpy, EGLSurface surface,
-                            EGLint attribute, EGLint *value);
-
-EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config,
-                            EGLContext share_list, const EGLint *attrib_list);
-
-EGLBoolean eglDestroyContext(EGLDisplay dpy, EGLContext ctx);
-
-EGLBoolean eglMakeCurrent(  EGLDisplay dpy, EGLSurface draw,
-                            EGLSurface read, EGLContext ctx);
-
-EGLContext eglGetCurrentContext(void);
-EGLSurface eglGetCurrentSurface(EGLint readdraw);
-EGLDisplay eglGetCurrentDisplay(void);
-EGLBoolean eglQueryContext( EGLDisplay dpy, EGLContext ctx,
-                            EGLint attribute, EGLint *value);
-
-EGLBoolean eglWaitGL(void);
-EGLBoolean eglWaitNative(EGLint engine);
-EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface draw);
-EGLBoolean eglCopyBuffers(  EGLDisplay dpy, EGLSurface surface,
-                            NativePixmapType target);
-
-EGLint eglGetError(void);
-const char* eglQueryString(EGLDisplay dpy, EGLint name);
-void (*eglGetProcAddress (const char *procname))();
-
-/* ----------------------------------------------------------------------------
- * EGL 1.1
- * ----------------------------------------------------------------------------
- */
-
-EGLBoolean eglSurfaceAttrib(
-        EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value);
-EGLBoolean eglBindTexImage(
-        EGLDisplay dpy, EGLSurface surface, EGLint buffer);
-EGLBoolean eglReleaseTexImage(
-        EGLDisplay dpy, EGLSurface surface, EGLint buffer);
-
-EGLBoolean eglSwapInterval(EGLDisplay dpy, EGLint interval);
-
-/* ----------------------------------------------------------------------------
- * EGL 1.2
- * ----------------------------------------------------------------------------
- */
-
-EGLBoolean eglBindAPI(EGLenum api);
-EGLenum eglQueryAPI(void);
-EGLBoolean eglWaitClient(void);
-EGLBoolean eglReleaseThread(void);
-EGLSurface eglCreatePbufferFromClientBuffer(
-          EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer,
-          EGLConfig config, const EGLint *attrib_list);
-
-/* ----------------------------------------------------------------------------
- * Android extentions
- * ----------------------------------------------------------------------------
- */
-
-EGLBoolean eglSwapRectangleANDROID(EGLDisplay dpy, EGLSurface draw,
-        EGLint l, EGLint t, EGLint w, EGLint h);
-
-EGLBoolean eglCopyFrontToBackANDROID(EGLDisplay dpy,
-        EGLSurface surface,
-        EGLint l, EGLint t, EGLint w, EGLint h);
-
-const char* eglQueryStringConfigANDROID(
-        EGLDisplay dpy, EGLConfig config, EGLint name);
-
-void* eglGetRenderBufferAddressANDROID(EGLDisplay dpy, EGLSurface surface);
-
-EGLBoolean eglCopyBitsANDROID(EGLDisplay dpy,
-        NativeWindowType draw, EGLint x, EGLint y,
-        NativeWindowType read,
-        EGLint crop_x, EGLint crop_y, EGLint crop_w, EGLint crop_h,
-        EGLint flags);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-
-#endif /*ANDROID_EGL_H*/
diff --git a/include/GLES/egltypes.h b/include/GLES/egltypes.h
deleted file mode 100644
index 698239b..0000000
--- a/include/GLES/egltypes.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef ANDROID_EGL_TYPES_H
-#define ANDROID_EGL_TYPES_H
-
-#include <sys/types.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef unsigned int EGLBoolean;
-typedef int32_t EGLint;
-typedef int EGLenum;
-typedef void *EGLDisplay;
-typedef void *EGLConfig;
-typedef void *EGLSurface;
-typedef void *EGLContext;
-typedef void *EGLClientBuffer;
-
-#define EGL_DEFAULT_DISPLAY ((NativeDisplayType)0)
-
-#define EGL_NO_CONTEXT      ((EGLContext)0)
-#define EGL_NO_DISPLAY      ((EGLDisplay)0)
-#define EGL_NO_SURFACE      ((EGLSurface)0)
-
-
-#ifdef __cplusplus
-}
-#endif
-
-
-#endif /* ANDROID_EGL_TYPES_H */
diff --git a/include/GLES/gl.h b/include/GLES/gl.h
deleted file mode 100644
index 50b6ac4..0000000
--- a/include/GLES/gl.h
+++ /dev/null
@@ -1,639 +0,0 @@
-/*
- * Copyright (C) 2006 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.
- */
-
-#ifndef __gl_h_
-#define __gl_h_
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*****************************************************************************/
-
-typedef int8_t              GLbyte;         // b
-typedef int16_t             GLshort;        // s
-typedef int32_t             GLint;          // i
-typedef ssize_t             GLsizei;        // i
-typedef int32_t             GLfixed;        // x
-typedef int32_t             GLclampx;       // x
-typedef float               GLfloat;        // f
-typedef float               GLclampf;       // f
-typedef uint8_t             GLubyte;        // ub
-typedef uint8_t             GLboolean;      // ub
-typedef uint16_t            GLushort;       // us
-typedef uint32_t            GLuint;         // ui
-typedef unsigned int        GLenum;         // ui
-typedef unsigned int        GLbitfield;     // ui
-typedef void                GLvoid;
-typedef intptr_t            GLintptr; 
-typedef int                 GLsizeiptr; 
-typedef GLintptr            GLintptrARB; 
-typedef GLsizeiptr          GLsizeiptrARB; 
-
-/*****************************************************************************/
-
-#define GL_VERSION_ES_CM_1_0                1
-#define GL_VERSION_ES_CL_1_0                1
-#define GL_VERSION_ES_CM_1_1                1
-#define GL_VERSION_ES_CL_1_1                1
-
-#define GL_OES_byte_coordinates             1
-#define GL_OES_fixed_point                  1
-#define GL_OES_single_precision             1
-#define GL_OES_read_format                  1
-#define GL_OES_compressed_paletted_texture  1
-#define GL_OES_draw_texture                 1
-#define GL_OES_matrix_get                   1
-#define GL_OES_query_matrix                 1
-#define GL_OES_vertex_buffer_object         1
-#define GL_OES_point_size_array             1
-#define GL_OES_point_sprite                 1
-#define GL_ARB_texture_non_power_of_two     1
-
-/*****************************************************************************/
-/* OpenGL ES 1.0 names */
-
-#define GL_FALSE                            0
-#define GL_TRUE                             1
-
-/* begin mode */
-#define GL_POINTS                           0x0000
-#define GL_LINES                            0x0001
-#define GL_LINE_LOOP                        0x0002
-#define GL_LINE_STRIP                       0x0003
-#define GL_TRIANGLES                        0x0004
-#define GL_TRIANGLE_STRIP                   0x0005
-#define GL_TRIANGLE_FAN                     0x0006
-
-/* clear mask  */
-#define GL_DEPTH_BUFFER_BIT                 0x00000100
-#define GL_STENCIL_BUFFER_BIT               0x00000400
-#define GL_COLOR_BUFFER_BIT                 0x00004000
-
-/* enable/disable */
-#define GL_FOG                              0x0B60
-#define GL_LIGHTING                         0x0B50
-#define GL_TEXTURE_2D                       0x0DE1
-#define GL_CULL_FACE                        0x0B44
-#define GL_ALPHA_TEST                       0x0BC0
-#define GL_BLEND                            0x0BE2
-#define GL_COLOR_LOGIC_OP                   0x0BF2
-#define GL_DITHER                           0x0BD0
-#define GL_STENCIL_TEST                     0x0B90
-#define GL_DEPTH_TEST                       0x0B71
-#define GL_POINT_SMOOTH                     0x0B10
-#define GL_LINE_SMOOTH                      0x0B20
-#define GL_SCISSOR_TEST                     0x0C11
-#define GL_COLOR_MATERIAL                   0x0B57
-#define GL_NORMALIZE                        0x0BA1
-#define GL_RESCALE_NORMAL                   0x803A
-#define GL_POLYGON_OFFSET_FILL              0x8037
-#define GL_VERTEX_ARRAY                     0x8074
-#define GL_NORMAL_ARRAY                     0x8075
-#define GL_COLOR_ARRAY                      0x8076
-#define GL_TEXTURE_COORD_ARRAY              0x8078
-#define GL_MULTISAMPLE                      0x809D
-#define GL_SAMPLE_ALPHA_TO_COVERAGE         0x809E
-#define GL_SAMPLE_ALPHA_TO_ONE              0x809F
-#define GL_SAMPLE_COVERAGE                  0x80A0
-
-/* gets */
-#define GL_SMOOTH_POINT_SIZE_RANGE          0x0B12
-#define GL_SMOOTH_LINE_WIDTH_RANGE          0x0B22
-#define GL_ALIASED_POINT_SIZE_RANGE         0x846D
-#define GL_ALIASED_LINE_WIDTH_RANGE         0x846E
-#define GL_MAX_LIGHTS                       0x0D31
-#define GL_MAX_CLIP_PLANES                  0x0D32
-#define GL_MAX_TEXTURE_SIZE                 0x0D33
-#define GL_MAX_MODELVIEW_STACK_DEPTH        0x0D36
-#define GL_MAX_PROJECTION_STACK_DEPTH       0x0D38
-#define GL_MAX_TEXTURE_STACK_DEPTH          0x0D39
-#define GL_MAX_VIEWPORT_DIMS                0x0D3A
-#define GL_MAX_ELEMENTS_VERTICES            0x80E8
-#define GL_MAX_ELEMENTS_INDICES             0x80E9
-#define GL_MAX_TEXTURE_UNITS                0x84E2
-#define GL_NUM_COMPRESSED_TEXTURE_FORMATS   0x86A2
-#define GL_COMPRESSED_TEXTURE_FORMATS       0x86A3
-#define GL_SUBPIXEL_BITS                    0x0D50
-#define GL_RED_BITS                         0x0D52
-#define GL_GREEN_BITS                       0x0D53
-#define GL_BLUE_BITS                        0x0D54
-#define GL_ALPHA_BITS                       0x0D55
-#define GL_DEPTH_BITS                       0x0D56
-#define GL_STENCIL_BITS                     0x0D57
-
-/* clip planes */
-#define GL_CLIP_PLANE0                      0x3000
-#define GL_CLIP_PLANE1                      0x3001
-#define GL_CLIP_PLANE2                      0x3002
-#define GL_CLIP_PLANE3                      0x3003
-#define GL_CLIP_PLANE4                      0x3004
-#define GL_CLIP_PLANE5                      0x3005
-
-/* errors */
-#define GL_NO_ERROR                         0
-#define GL_INVALID_ENUM                     0x0500
-#define GL_INVALID_VALUE                    0x0501
-#define GL_INVALID_OPERATION                0x0502
-#define GL_STACK_OVERFLOW                   0x0503
-#define GL_STACK_UNDERFLOW                  0x0504
-#define GL_OUT_OF_MEMORY                    0x0505
-
-/* fog */
-#define GL_EXP                              0x0800
-#define GL_EXP2                             0x0801
-#define GL_FOG_DENSITY                      0x0B62
-#define GL_FOG_START                        0x0B63
-#define GL_FOG_END                          0x0B64
-#define GL_FOG_MODE                         0x0B65
-#define GL_FOG_COLOR                        0x0B66
-
-/* culling */
-#define GL_CW                               0x0900
-#define GL_CCW                              0x0901
-
-#define GL_FRONT                            0x0404
-#define GL_BACK                             0x0405
-#define GL_FRONT_AND_BACK                   0x0408
-
-/* hints */
-#define GL_DONT_CARE                        0x1100
-#define GL_FASTEST                          0x1101
-#define GL_NICEST                           0x1102
-
-#define GL_PERSPECTIVE_CORRECTION_HINT      0x0C50
-#define GL_POINT_SMOOTH_HINT                0x0C51
-#define GL_LINE_SMOOTH_HINT                 0x0C52
-#define GL_POLYGON_SMOOTH_HINT              0x0C53
-#define GL_FOG_HINT                         0x0C54
-#define GL_GENERATE_MIPMAP_HINT             0x8192
-
-/* lights */
-#define GL_LIGHT_MODEL_AMBIENT              0x0B53
-#define GL_LIGHT_MODEL_TWO_SIDE             0x0B52
-
-#define GL_AMBIENT                          0x1200
-#define GL_DIFFUSE                          0x1201
-#define GL_SPECULAR                         0x1202
-#define GL_POSITION                         0x1203
-#define GL_SPOT_DIRECTION                   0x1204
-#define GL_SPOT_EXPONENT                    0x1205
-#define GL_SPOT_CUTOFF                      0x1206
-#define GL_CONSTANT_ATTENUATION             0x1207
-#define GL_LINEAR_ATTENUATION               0x1208
-#define GL_QUADRATIC_ATTENUATION            0x1209
-
-#define GL_LIGHT0                           0x4000
-#define GL_LIGHT1                           0x4001
-#define GL_LIGHT2                           0x4002
-#define GL_LIGHT3                           0x4003
-#define GL_LIGHT4                           0x4004
-#define GL_LIGHT5                           0x4005
-#define GL_LIGHT6                           0x4006
-#define GL_LIGHT7                           0x4007
-
-/* material */
-#define GL_EMISSION                         0x1600
-#define GL_SHININESS                        0x1601
-#define GL_AMBIENT_AND_DIFFUSE              0x1602
-
-/* matrix */
-#define GL_MODELVIEW                        0x1700
-#define GL_PROJECTION                       0x1701
-#define GL_TEXTURE                          0x1702
-
-/* types */
-#define GL_BYTE                             0x1400
-#define GL_UNSIGNED_BYTE                    0x1401
-#define GL_SHORT                            0x1402
-#define GL_UNSIGNED_SHORT                   0x1403
-#define GL_FLOAT                            0x1406
-#define GL_FIXED                            0x140C
-
-/* pixel formats */
-#define GL_ALPHA                            0x1906
-#define GL_RGB                              0x1907
-#define GL_RGBA                             0x1908
-#define GL_LUMINANCE                        0x1909
-#define GL_LUMINANCE_ALPHA                  0x190A
-
-/* pixel store */
-#define GL_UNPACK_ALIGNMENT                 0x0CF5
-#define GL_PACK_ALIGNMENT                   0x0D05
-
-/* pixel types */
-#define GL_UNSIGNED_SHORT_4_4_4_4           0x8033
-#define GL_UNSIGNED_SHORT_5_5_5_1           0x8034
-#define GL_UNSIGNED_SHORT_5_6_5             0x8363
-
-/* logic op */
-#define GL_CLEAR                            0x1500   // 0
-#define GL_AND                              0x1501   // s & d
-#define GL_AND_REVERSE                      0x1502   // s & ~d
-#define GL_COPY                             0x1503   // s
-#define GL_AND_INVERTED                     0x1504   // ~s & d
-#define GL_NOOP                             0x1505   // d
-#define GL_XOR                              0x1506   // s ^ d
-#define GL_OR                               0x1507   // s | d
-#define GL_NOR                              0x1508   // ~(s | d)
-#define GL_EQUIV                            0x1509   // ~(s ^ d)
-#define GL_INVERT                           0x150A   // ~d
-#define GL_OR_REVERSE                       0x150B   // s | ~d
-#define GL_COPY_INVERTED                    0x150C   // ~s 
-#define GL_OR_INVERTED                      0x150D   // ~s | d
-#define GL_NAND                             0x150E   // ~(s & d)
-#define GL_SET                              0x150F   // 1
-
-/* shade model */
-#define GL_FLAT                             0x1D00
-#define GL_SMOOTH                           0x1D01
-
-/* strings */
-#define GL_VENDOR                           0x1F00
-#define GL_RENDERER                         0x1F01
-#define GL_VERSION                          0x1F02
-#define GL_EXTENSIONS                       0x1F03
-
-/* stencil */
-#define GL_KEEP                             0x1E00
-#define GL_REPLACE                          0x1E01
-#define GL_INCR                             0x1E02
-#define GL_DECR                             0x1E03
-
-/* alpha & stencil */
-#define GL_NEVER                            0x0200
-#define GL_LESS                             0x0201
-#define GL_EQUAL                            0x0202
-#define GL_LEQUAL                           0x0203
-#define GL_GREATER                          0x0204
-#define GL_NOTEQUAL                         0x0205
-#define GL_GEQUAL                           0x0206
-#define GL_ALWAYS                           0x0207
-
-/* blending equation & function */
-#define GL_ZERO                             0           // SD
-#define GL_ONE                              1           // SD
-#define GL_SRC_COLOR                        0x0300      //  D
-#define GL_ONE_MINUS_SRC_COLOR              0x0301      //  D
-#define GL_SRC_ALPHA                        0x0302      // SD
-#define GL_ONE_MINUS_SRC_ALPHA              0x0303      // SD
-#define GL_DST_ALPHA                        0x0304      // SD
-#define GL_ONE_MINUS_DST_ALPHA              0x0305      // SD
-#define GL_DST_COLOR                        0x0306      // S
-#define GL_ONE_MINUS_DST_COLOR              0x0307      // S
-#define GL_SRC_ALPHA_SATURATE               0x0308      // S
-    
-/* Texture parameter name */
-#define GL_TEXTURE_MIN_FILTER               0x2801
-#define GL_TEXTURE_MAG_FILTER               0x2800
-#define GL_TEXTURE_WRAP_S                   0x2802
-#define GL_TEXTURE_WRAP_T                   0x2803
-#define GL_GENERATE_MIPMAP                  0x8191
-#define GL_TEXTURE_CROP_RECT_OES            0x8B9D
-
-/* Texture Filter */
-#define GL_NEAREST                          0x2600
-#define GL_LINEAR                           0x2601
-#define GL_NEAREST_MIPMAP_NEAREST           0x2700
-#define GL_LINEAR_MIPMAP_NEAREST            0x2701
-#define GL_NEAREST_MIPMAP_LINEAR            0x2702
-#define GL_LINEAR_MIPMAP_LINEAR             0x2703
-
-/* Texture Wrap Mode */
-#define GL_CLAMP                            0x2900
-#define GL_REPEAT                           0x2901
-#define GL_CLAMP_TO_EDGE                    0x812F
-
-/* Texture Env Mode */
-#define GL_REPLACE                          0x1E01
-#define GL_MODULATE                         0x2100
-#define GL_DECAL                            0x2101
-#define GL_ADD                              0x0104
-
-/* Texture Env Parameter */
-#define GL_TEXTURE_ENV_MODE                 0x2200
-#define GL_TEXTURE_ENV_COLOR                0x2201
-
-/* Texture Env Target */
-#define GL_TEXTURE_ENV                      0x2300
-
-/* TMUs */
-#define GL_TEXTURE0                         0x84C0
-#define GL_TEXTURE1                         0x84C1
-#define GL_TEXTURE2                         0x84C2
-#define GL_TEXTURE3                         0x84C3
-#define GL_TEXTURE4                         0x84C4
-#define GL_TEXTURE5                         0x84C5
-#define GL_TEXTURE6                         0x84C6
-#define GL_TEXTURE7                         0x84C7
-#define GL_TEXTURE8                         0x84C8
-#define GL_TEXTURE9                         0x84C9
-#define GL_TEXTURE10                        0x84CA
-#define GL_TEXTURE11                        0x84CB
-#define GL_TEXTURE12                        0x84CC
-#define GL_TEXTURE13                        0x84CD
-#define GL_TEXTURE14                        0x84CE
-#define GL_TEXTURE15                        0x84CF
-#define GL_TEXTURE16                        0x84D0
-#define GL_TEXTURE17                        0x84D1
-#define GL_TEXTURE18                        0x84D2
-#define GL_TEXTURE19                        0x84D3
-#define GL_TEXTURE20                        0x84D4
-#define GL_TEXTURE21                        0x84D5
-#define GL_TEXTURE22                        0x84D6
-#define GL_TEXTURE23                        0x84D7
-#define GL_TEXTURE24                        0x84D8
-#define GL_TEXTURE25                        0x84D9
-#define GL_TEXTURE26                        0x84DA
-#define GL_TEXTURE27                        0x84DB
-#define GL_TEXTURE28                        0x84DC
-#define GL_TEXTURE29                        0x84DD
-#define GL_TEXTURE30                        0x84DE
-#define GL_TEXTURE31                        0x84DF
-
-/*****************************************************************************/
-/* OpenGL ES 1.1 additions */
-
-#define GL_ARRAY_BUFFER                         0x8892
-#define GL_ELEMENT_ARRAY_BUFFER                 0x8893
-
-#define GL_STATIC_DRAW                          0x88E4
-#define GL_DYNAMIC_DRAW                         0x88E8
-
-#define GL_BUFFER_SIZE                          0x8764
-#define GL_BUFFER_USAGE                         0x8765
-
-#define GL_ARRAY_BUFFER_BINDING                 0x8894
-#define GL_ELEMENT_ARRAY_BUFFER_BINDING         0x8895
-#define GL_VERTEX_ARRAY_BUFFER_BINDING          0x8896
-#define GL_NORMAL_ARRAY_BUFFER_BINDING          0x8897
-#define GL_COLOR_ARRAY_BUFFER_BINDING           0x8898
-#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING   0x889A
-
-/*****************************************************************************/
-/* Required extensions */
-
-#define GL_PALETTE4_RGB8_OES                        0x8B90
-#define GL_PALETTE4_RGBA8_OES                       0x8B91
-#define GL_PALETTE4_R5_G6_B5_OES                    0x8B92
-#define GL_PALETTE4_RGBA4_OES                       0x8B93
-#define GL_PALETTE4_RGB5_A1_OES                     0x8B94
-#define GL_PALETTE8_RGB8_OES                        0x8B95
-#define GL_PALETTE8_RGBA8_OES                       0x8B96
-#define GL_PALETTE8_R5_G6_B5_OES                    0x8B97
-#define GL_PALETTE8_RGBA4_OES                       0x8B98
-#define GL_PALETTE8_RGB5_A1_OES                     0x8B99
-
-#define GL_IMPLEMENTATION_COLOR_READ_TYPE_OES       0x8B9A
-#define GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES     0x8B9B
-
-#define GL_POINT_SPRITE_OES                         0x8861
-#define GL_COORD_REPLACE_OES                        0x8862
-
-#define GL_POINT_SIZE_ARRAY_OES                     0x8B9C
-#define GL_POINT_SIZE_ARRAY_TYPE_OES                0x898A
-#define GL_POINT_SIZE_ARRAY_STRIDE_OES              0x898B
-#define GL_POINT_SIZE_ARRAY_POINTER_OES             0x898C
-#define GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES      0x8B9F
-
-/*****************************************************************************/
-/* Extensions */
-
-#define GL_MODELVIEW_MATRIX_FLOAT_AS_INT_BITS_OES   0x898D
-#define GL_PROJECTION_MATRIX_FLOAT_AS_INT_BITS_OES  0x898E
-#define GL_TEXTURE_MATRIX_FLOAT_AS_INT_BITS_OES     0x898F
-
-#define GL_DIRECT_TEXTURE_2D_QUALCOMM               0x7E80
-
-
-
-
-/*****************************************************************************/
-/* OpenGL ES 1.0 functions */
-
-void glActiveTexture(GLenum texture);
-void glAlphaFunc(GLenum func, GLclampf ref);
-void glAlphaFuncx(GLenum func, GLclampx ref);
-void glBindTexture(GLenum target, GLuint texture);
-void glBlendFunc(GLenum sfactor, GLenum dfactor);
-void glClear(GLbitfield mask);
-void glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
-void glClearColorx(GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha);
-void glClearDepthf(GLclampf depth);
-void glClearDepthx(GLclampx depth);
-void glClearStencil(GLint s);
-void glClientActiveTexture(GLenum texture);
-void glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
-void glColor4x(GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha);
-void glColorMask(GLboolean r, GLboolean g, GLboolean b, GLboolean a);
-void glColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr);
-void glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat,
-        GLsizei width, GLsizei height, GLint border,
-        GLsizei imageSize, const GLvoid *data);
-void glCompressedTexSubImage2D( GLenum target, GLint level, GLint xoffset,
-        GLint yoffset, GLsizei width, GLsizei height,
-        GLenum format, GLsizei imageSize,
-        const GLvoid *data);
-void glCopyTexImage2D(  GLenum target, GLint level, GLenum internalformat,
-        GLint x, GLint y, GLsizei width, GLsizei height,
-        GLint border);
-void glCopyTexSubImage2D(   GLenum target, GLint level, GLint xoffset,
-        GLint yoffset, GLint x, GLint y, GLsizei width,
-        GLsizei height);
-void glCullFace(GLenum mode);
-void glDeleteTextures(GLsizei n, const GLuint *textures);
-void glDepthFunc(GLenum func);
-void glDepthMask(GLboolean flag);
-void glDepthRangef(GLclampf zNear, GLclampf zFar);
-void glDepthRangex(GLclampx zNear, GLclampx zFar);
-void glDisable(GLenum cap);
-void glDisableClientState(GLenum array);
-void glDrawArrays(GLenum mode, GLint first, GLsizei count);
-void glDrawElements(GLenum mode, GLsizei count,
-        GLenum type, const GLvoid *indices);
-void glEnable(GLenum cap);
-void glEnableClientState(GLenum array);
-void glFinish(void);
-void glFlush(void);
-void glFogf(GLenum pname, GLfloat param);
-void glFogfv(GLenum pname, const GLfloat *params);
-void glFogx(GLenum pname, GLfixed param);
-void glFogxv(GLenum pname, const GLfixed *params);
-void glFrontFace(GLenum mode);
-void glFrustumf(GLfloat left, GLfloat right,
-        GLfloat bottom, GLfloat top,
-        GLfloat zNear, GLfloat zFar);
-void glFrustumx(GLfixed left, GLfixed right,
-        GLfixed bottom, GLfixed top,
-        GLfixed zNear, GLfixed zFar);
-void glGenTextures(GLsizei n, GLuint *textures);
-GLenum glGetError(void);
-void glGetIntegerv(GLenum pname, GLint *params);
-const GLubyte * glGetString(GLenum name);
-void glHint(GLenum target, GLenum mode);
-void glLightModelf(GLenum pname, GLfloat param);
-void glLightModelfv(GLenum pname, const GLfloat *params);
-void glLightModelx(GLenum pname, GLfixed param);
-void glLightModelxv(GLenum pname, const GLfixed *params);
-void glLightf(GLenum light, GLenum pname, GLfloat param);
-void glLightfv(GLenum light, GLenum pname, const GLfloat *params);
-void glLightx(GLenum light, GLenum pname, GLfixed param);
-void glLightxv(GLenum light, GLenum pname, const GLfixed *params);
-void glLineWidth(GLfloat width);
-void glLineWidthx(GLfixed width);
-void glLoadIdentity(void);
-void glLoadMatrixf(const GLfloat *m);
-void glLoadMatrixx(const GLfixed *m);
-void glLogicOp(GLenum opcode);
-void glMaterialf(GLenum face, GLenum pname, GLfloat param);
-void glMaterialfv(GLenum face, GLenum pname, const GLfloat *params);
-void glMaterialx(GLenum face, GLenum pname, GLfixed param);
-void glMaterialxv(GLenum face, GLenum pname, const GLfixed *params);
-void glMatrixMode(GLenum mode);
-void glMultMatrixf(const GLfloat *m);
-void glMultMatrixx(const GLfixed *m);
-void glMultiTexCoord4f(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q);
-void glMultiTexCoord4x(GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q);
-void glNormal3f(GLfloat nx, GLfloat ny, GLfloat nz);
-void glNormal3x(GLfixed nx, GLfixed ny, GLfixed nz);
-void glNormalPointer(GLenum type, GLsizei stride, const GLvoid *pointer);
-void glOrthof(  GLfloat left, GLfloat right,
-        GLfloat bottom, GLfloat top,
-        GLfloat zNear, GLfloat zFar);
-void glOrthox(  GLfixed left, GLfixed right,
-        GLfixed bottom, GLfixed top,
-        GLfixed zNear, GLfixed zFar);
-void glPixelStorei(GLenum pname, GLint param);
-void glPointSize(GLfloat size);
-void glPointSizex(GLfixed size);
-void glPolygonOffset(GLfloat factor, GLfloat units);
-void glPolygonOffsetx(GLfixed factor, GLfixed units);
-void glPopMatrix(void);
-void glPushMatrix(void);
-void glReadPixels(  GLint x, GLint y, GLsizei width, GLsizei height,
-        GLenum format, GLenum type, GLvoid *pixels);
-void glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z);
-void glRotatex(GLfixed angle, GLfixed x, GLfixed y, GLfixed z);
-void glSampleCoverage(GLclampf value, GLboolean invert);
-void glSampleCoveragex(GLclampx value, GLboolean invert);
-void glScalef(GLfloat x, GLfloat y, GLfloat z);
-void glScalex(GLfixed x, GLfixed y, GLfixed z);
-void glScissor(GLint x, GLint y, GLsizei width, GLsizei height);
-void glShadeModel(GLenum mode);
-void glStencilFunc(GLenum func, GLint ref, GLuint mask);
-void glStencilMask(GLuint mask);
-void glStencilOp(GLenum fail, GLenum zfail, GLenum zpass);
-void glTexCoordPointer( GLint size, GLenum type,
-        GLsizei stride, const GLvoid *pointer);
-void glTexEnvf(GLenum target, GLenum pname, GLfloat param);
-void glTexEnvfv(GLenum target, GLenum pname, const GLfloat *params);
-void glTexEnvx(GLenum target, GLenum pname, GLfixed param);
-void glTexEnvxv(GLenum target, GLenum pname, const GLfixed *params);
-void glTexImage2D(  GLenum target, GLint level, GLenum internalformat,
-        GLsizei width, GLsizei height, GLint border, GLenum format,
-        GLenum type, const GLvoid *pixels);
-void glTexParameterf(GLenum target, GLenum pname, GLfloat param);
-void glTexParameterx(GLenum target, GLenum pname, GLfixed param);
-void glTexSubImage2D(   GLenum target, GLint level, GLint xoffset,
-        GLint yoffset, GLsizei width, GLsizei height,
-        GLenum format, GLenum type, const GLvoid *pixels);
-void glTranslatef(GLfloat x, GLfloat y, GLfloat z);
-void glTranslatex(GLfixed x, GLfixed y, GLfixed z);
-void glVertexPointer(   GLint size, GLenum type,
-        GLsizei stride, const GLvoid *pointer);
-void glViewport(GLint x, GLint y, GLsizei width, GLsizei height);
-
-/*****************************************************************************/
-/* OpenGL ES 1.1 functions */
-
-void glClipPlanef(GLenum plane, const GLfloat* equation);
-void glClipPlanex(GLenum plane, const GLfixed* equation);
-
-void glBindBuffer(GLenum target, GLuint buffer);
-void glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage);
-void glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data);
-void glDeleteBuffers(GLsizei n, const GLuint* buffers);
-void glGenBuffers(GLsizei n, GLuint* buffers);
-
-void glGetBooleanv(GLenum pname, GLboolean *params);
-void glGetFixedv(GLenum pname, GLfixed *params);
-void glGetFloatv(GLenum pname, GLfloat *params);
-void glGetPointerv(GLenum pname, void **params);
-void glGetBufferParameteriv(GLenum target, GLenum pname, GLint *params);
-void glGetClipPlanef(GLenum pname, GLfloat eqn[4]);
-void glGetClipPlanex(GLenum pname, GLfixed eqn[4]);
-void glGetLightxv(GLenum light, GLenum pname, GLfixed *params);
-void glGetLightfv(GLenum light, GLenum pname, GLfloat *params);
-void glGetMaterialxv(GLenum face, GLenum pname, GLfixed *params);
-void glGetMaterialfv(GLenum face, GLenum pname, GLfloat *params);
-void glGetTexEnvfv(GLenum env, GLenum pname, GLfloat *params);
-void glGetTexEnviv(GLenum env, GLenum pname, GLint *params);
-void glGetTexEnvxv(GLenum env, GLenum pname, GLfixed *params);
-void glGetTexParameterfv(GLenum target, GLenum pname, GLfloat *params);
-void glGetTexParameteriv(GLenum target, GLenum pname, GLint *params);
-void glGetTexParameterxv(GLenum target, GLenum pname, GLfixed *params);
-GLboolean glIsBuffer(GLuint buffer);
-GLboolean glIsEnabled(GLenum cap);
-GLboolean glIsTexture(GLuint texture);
-void glPointParameterf(GLenum pname, GLfloat param);
-void glPointParameterfv(GLenum pname, const GLfloat *params);
-void glPointParameterx(GLenum pname, GLfixed param);
-void glPointParameterxv(GLenum pname, const GLfixed *params);
-void glColor4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha);
-void glTexEnvi(GLenum target, GLenum pname, GLint param);
-void glTexEnviv(GLenum target, GLenum pname, const GLint *params);
-void glTexParameterfv(GLenum target, GLenum pname, const GLfloat *params);
-void glTexParameteriv(GLenum target, GLenum pname, const GLint *params);
-void glTexParameteri(GLenum target, GLenum pname, GLint param);
-void glTexParameterxv(GLenum target, GLenum pname, const GLfixed *params);
-
-/*****************************************************************************/
-/* Required extensions functions */
-
-void glPointSizePointerOES(GLenum type, GLsizei stride, const GLvoid *pointer);
-
-
-/*****************************************************************************/
-/* Extensions functions */
-
-void glDrawTexsOES(GLshort x , GLshort y, GLshort z, GLshort w, GLshort h);
-void glDrawTexiOES(GLint x, GLint y, GLint z, GLint w, GLint h);
-void glDrawTexfOES(GLfloat x, GLfloat y, GLfloat z, GLfloat w, GLfloat h);
-void glDrawTexxOES(GLfixed x, GLfixed y, GLfixed z, GLfixed w, GLfixed h);
-void glDrawTexsvOES(const GLshort* coords);
-void glDrawTexivOES(const GLint* coords);
-void glDrawTexfvOES(const GLfloat* coords);
-void glDrawTexxvOES(const GLfixed* coords);
-GLbitfield glQueryMatrixxOES(GLfixed* mantissa, GLint* exponent);
-
-/* called by dalvik */
-void glColorPointerBounds(GLint size, GLenum type, GLsizei stride,
-        const GLvoid *ptr, GLsizei count);
-void glNormalPointerBounds(GLenum type, GLsizei stride,
-        const GLvoid *pointer, GLsizei count);
-void glTexCoordPointerBounds(GLint size, GLenum type,
-        GLsizei stride, const GLvoid *pointer, GLsizei count);
-void glVertexPointerBounds(GLint size, GLenum type,
-        GLsizei stride, const GLvoid *pointer, GLsizei count);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __gl_h_ */
diff --git a/include/private/opengles/gl_context.h b/include/private/opengles/gl_context.h
index 3056139..0c7ad46 100644
--- a/include/private/opengles/gl_context.h
+++ b/include/private/opengles/gl_context.h
@@ -28,6 +28,7 @@
 #include <private/pixelflinger/ggl_context.h>
 
 #include <GLES/gl.h>
+#include <GLES/glext.h>
 
 namespace android {
 
diff --git a/include/ui/Camera.h b/include/ui/Camera.h
index 44acce5..e593fea 100644
--- a/include/ui/Camera.h
+++ b/include/ui/Camera.h
@@ -23,8 +23,8 @@
 namespace android {
 
 /*
- * A set of bit masks for specifying how the received frames from preview are
- * handled before the frame callback call.
+ * A set of bit masks for specifying how the received preview frames are
+ * handled before the previewCallback() call.
  *
  * The least significant 3 bits of an "int" value are used for this purpose:
  *
@@ -34,10 +34,18 @@
  *       | |-----------> determine whether the callback is one-shot or not
  *       |-------------> determine whether the frame is copied out or not
  *
+ * WARNING:
+ * When a frame is sent directly without copying, it is the frame receiver's
+ * responsiblity to make sure that the frame data won't get corrupted by
+ * subsequent preview frames filled by the camera. This flag is recommended
+ * only when copying out data brings significant performance price and the
+ * handling/processing of the received frame data is always faster than
+ * the preview frame rate so that data corruption won't occur.
+ *
  * For instance,
  * 1. 0x00 disables the callback. In this case, copy out and one shot bits
  *    are ignored.
- * 2. 0x01 enables a callback without copying out the recievied frames. A
+ * 2. 0x01 enables a callback without copying out the received frames. A
  *    typical use case is the Camcorder application to avoid making costly
  *    frame copies.
  * 3. 0x05 is enabling a callback with frame copied out repeatedly. A typical
@@ -96,6 +104,18 @@
             // get preview state
             bool        previewEnabled();
 
+            // start recording mode, must call setPreviewDisplay first
+            status_t    startRecording();
+
+            // stop recording mode
+            void        stopRecording();
+
+            // get recording state
+            bool        recordingEnabled();
+
+            // release a recording frame
+            void        releaseRecordingFrame(const sp<IMemory>& mem);
+
             // autoFocus - status returned from callback
             status_t    autoFocus();
 
@@ -111,20 +131,19 @@
             void        setShutterCallback(shutter_callback cb, void *cookie);
             void        setRawCallback(frame_callback cb, void *cookie);
             void        setJpegCallback(frame_callback cb, void *cookie);
-
-            void        setFrameCallback(frame_callback cb,
-                            void *cookie,
-                            int frame_callback_flag = FRAME_CALLBACK_FLAG_NOOP);
-
+            void        setRecordingCallback(frame_callback cb, void *cookie);
+            void        setPreviewCallback(frame_callback cb, void *cookie, int preview_callback_flag = FRAME_CALLBACK_FLAG_NOOP);
             void        setErrorCallback(error_callback cb, void *cookie);
             void        setAutoFocusCallback(autofocus_callback cb, void *cookie);
+
     // ICameraClient interface
     virtual void        shutterCallback();
     virtual void        rawCallback(const sp<IMemory>& picture);
     virtual void        jpegCallback(const sp<IMemory>& picture);
-    virtual void        frameCallback(const sp<IMemory>& frame);
+    virtual void        previewCallback(const sp<IMemory>& frame);
     virtual void        errorCallback(status_t error);
     virtual void        autoFocusCallback(bool focused);
+    virtual void        recordingCallback(const sp<IMemory>& frame);
 
     sp<ICamera>         remote();
 
@@ -155,8 +174,10 @@
             void                *mRawCallbackCookie;
             frame_callback      mJpegCallback;
             void                *mJpegCallbackCookie;
-            frame_callback      mFrameCallback;
-            void                *mFrameCallbackCookie;
+            frame_callback      mPreviewCallback;
+            void                *mPreviewCallbackCookie;
+            frame_callback      mRecordingCallback;
+            void                *mRecordingCallbackCookie;
             error_callback      mErrorCallback;
             void                *mErrorCallbackCookie;
             autofocus_callback  mAutoFocusCallback;
diff --git a/include/ui/CameraHardwareInterface.h b/include/ui/CameraHardwareInterface.h
index 2bd53dd..73036f0 100644
--- a/include/ui/CameraHardwareInterface.h
+++ b/include/ui/CameraHardwareInterface.h
@@ -20,12 +20,16 @@
 #include <utils/IMemory.h>
 #include <utils/RefBase.h>
 #include <ui/CameraParameters.h>
+#include <ui/Overlay.h>
 
 namespace android {
 
 /** Callback for startPreview() */
 typedef void (*preview_callback)(const sp<IMemory>& mem, void* user);
 
+/** Callback for startRecord() */
+typedef void (*recording_callback)(const sp<IMemory>& mem, void* user);
+
 /** Callback for takePicture() */
 typedef void (*shutter_callback)(void* user);
 
@@ -83,12 +87,20 @@
     /** Return the IMemoryHeap for the preview image heap */
     virtual sp<IMemoryHeap>         getPreviewHeap() const = 0;
 
+    /** Return the IMemoryHeap for the raw image heap */
+    virtual sp<IMemoryHeap>         getRawHeap() const = 0;
+
     /**
      * Start preview mode. When a preview image is available
      * preview_callback is called with the user parameter. The
      * call back parameter may be null.
      */
     virtual status_t    startPreview(preview_callback cb, void* user) = 0;
+    /**
+     * Only used if overlays are used for camera preview.
+     */
+    virtual bool useOverlay() {return false;}
+    virtual status_t setOverlay(const sp<Overlay> &overlay) {return BAD_VALUE;}
 
     /**
      * Stop a previously started preview.
@@ -101,6 +113,29 @@
     virtual bool        previewEnabled() = 0;
 
     /**
+     * Start record mode. When a record image is available recording_callback()
+     * is called with the user parameter.  Every record frame must be released
+     * by calling releaseRecordingFrame().
+     */
+    virtual status_t    startRecording(recording_callback cb, void* user) = 0;
+
+    /**
+     * Stop a previously started recording.
+     */
+    virtual void        stopRecording() = 0;
+
+    /**
+     * Returns true if recording is enabled.
+     */
+    virtual bool        recordingEnabled() = 0;
+    
+    /**
+     * Release a record frame previously returned by the recording_callback()
+     * passed to startRecord().
+     */
+    virtual void        releaseRecordingFrame(const sp<IMemory>& mem) = 0;
+
+    /**
      * Start auto focus, the callback routine is called
      * once when focusing is complete. autoFocus() will
      * be called again if another auto focus is needed.
diff --git a/include/ui/CameraParameters.h b/include/ui/CameraParameters.h
index e35a054..9ca1806 100644
--- a/include/ui/CameraParameters.h
+++ b/include/ui/CameraParameters.h
@@ -29,6 +29,12 @@
     CameraParameters(const String8 &params) { unflatten(params); }
     ~CameraParameters();
 
+    enum {
+        CAMERA_ORIENTATION_UNKNOWN = 0,
+        CAMERA_ORIENTATION_PORTRAIT = 1,
+        CAMERA_ORIENTATION_LANDSCAPE = 2,
+    };
+
     String8 flatten() const;
     void unflatten(const String8 &params);
 
@@ -57,6 +63,9 @@
     void setPictureFormat(const char *format);
     const char *getPictureFormat() const;
 
+    int getOrientation() const;
+    void setOrientation(int orientation);
+
     void dump() const;
     status_t dump(int fd, const Vector<String16>& args) const;
 
diff --git a/include/ui/EGLDisplaySurface.h b/include/ui/EGLDisplaySurface.h
index 0190e09..a8b5853 100644
--- a/include/ui/EGLDisplaySurface.h
+++ b/include/ui/EGLDisplaySurface.h
@@ -27,7 +27,10 @@
 #include <pixelflinger/pixelflinger.h>
 #include <linux/fb.h>
 
+#include <EGL/egl.h>
+
 struct copybit_device_t;
+struct copybit_image_t;
 
 // ---------------------------------------------------------------------------
 namespace android {
@@ -44,17 +47,17 @@
     
     int32_t getPageFlipCount() const;
     void    copyFrontToBack(const Region& copyback);
+    void    copyFrontToImage(const copybit_image_t& dst);
+    void    copyBackToImage(const copybit_image_t& dst);
     
+    void        setSwapRectangle(int l, int t, int w, int h);
+
 private:
     static void         hook_incRef(NativeWindowType window);
     static void         hook_decRef(NativeWindowType window);
     static uint32_t     hook_swapBuffers(NativeWindowType window);
-    static void         hook_setSwapRectangle(NativeWindowType window, int l, int t, int w, int h);
-    static uint32_t     hook_nextBuffer(NativeWindowType window);
      
             uint32_t    swapBuffers();
-            uint32_t    nextBuffer();
-            void        setSwapRectangle(int l, int t, int w, int h);
 
             status_t    mapFrameBuffer();
 
diff --git a/include/ui/EGLNativeSurface.h b/include/ui/EGLNativeSurface.h
index c303cd8..7964e7c 100644
--- a/include/ui/EGLNativeSurface.h
+++ b/include/ui/EGLNativeSurface.h
@@ -23,7 +23,7 @@
 #include <cutils/atomic.h>
 #include <utils/RefBase.h>
 
-#include <GLES/eglnatives.h>
+#include <EGL/eglnatives.h>
 
 // ---------------------------------------------------------------------------
 namespace android {
diff --git a/include/ui/EGLNativeWindowSurface.h b/include/ui/EGLNativeWindowSurface.h
index 058479a..3494234 100644
--- a/include/ui/EGLNativeWindowSurface.h
+++ b/include/ui/EGLNativeWindowSurface.h
@@ -20,6 +20,7 @@
 #include <stdint.h>
 #include <sys/types.h>
 #include <ui/EGLNativeSurface.h>
+#include <EGL/egl.h>
 
 // ---------------------------------------------------------------------------
 namespace android {
@@ -33,18 +34,16 @@
     EGLNativeWindowSurface(const sp<Surface>& surface);
     ~EGLNativeWindowSurface();
 
+    void        setSwapRectangle(int l, int t, int w, int h);
+
 private:
     static void         hook_incRef(NativeWindowType window);
     static void         hook_decRef(NativeWindowType window);
     static uint32_t     hook_swapBuffers(NativeWindowType window);
-    static uint32_t     hook_nextBuffer(NativeWindowType window);
-    static void         hook_setSwapRectangle(NativeWindowType window, int l, int t, int w, int h);
     static void         hook_connect(NativeWindowType window);
     static void         hook_disconnect(NativeWindowType window);
 
             uint32_t    swapBuffers();
-            uint32_t    nextBuffer();
-            void        setSwapRectangle(int l, int t, int w, int h);
             void        connect();
             void        disconnect();
             
diff --git a/include/ui/EventHub.h b/include/ui/EventHub.h
index 017c145..3848d8c 100644
--- a/include/ui/EventHub.h
+++ b/include/ui/EventHub.h
@@ -76,6 +76,9 @@
         DEVICE_REMOVED = 0x20000000
     };
     
+    // examine key input devices for specific framework keycode support
+    bool hasKeys(size_t numCodes, int32_t* keyCodes, uint8_t* outFlags);
+
     virtual bool getEvent(int32_t* outDeviceId, int32_t* outType,
             int32_t* outScancode, int32_t* outKeycode, uint32_t *outFlags,
             int32_t* outValue, nsecs_t* outWhen);
@@ -100,6 +103,7 @@
         const String8   path;
         String8         name;
         uint32_t        classes;
+        uint8_t*        keyBitmask;
         KeyLayoutMap*   layoutMap;
         String8         keylayoutFilename;
         device_t*       next;
@@ -134,8 +138,6 @@
 #ifdef EV_SW
     int32_t         mSwitches[SW_MAX+1];
 #endif
-
-    KeyLayoutMap * mLayoutMap;
 };
 
 }; // namespace android
diff --git a/include/ui/ICamera.h b/include/ui/ICamera.h
index ea2fcee..241fb63 100644
--- a/include/ui/ICamera.h
+++ b/include/ui/ICamera.h
@@ -48,9 +48,9 @@
     // pass the buffered ISurface to the camera service
     virtual status_t        setPreviewDisplay(const sp<ISurface>& surface) = 0;
 
-    // set the frame callback flag to affect how the received frames from
+    // set the preview callback flag to affect how the received frames from
     // preview are handled.
-    virtual void            setFrameCallbackFlag(int frame_callback_flag) = 0;
+    virtual void            setPreviewCallbackFlag(int flag) = 0;
 
     // start preview mode, must call setPreviewDisplay first
     virtual status_t        startPreview() = 0;
@@ -61,6 +61,18 @@
     // get preview state
     virtual bool            previewEnabled() = 0;
 
+    // start recording mode
+    virtual status_t        startRecording() = 0;
+
+    // stop recording mode
+    virtual void            stopRecording() = 0;    
+
+    // get recording state
+    virtual bool            recordingEnabled() = 0;
+
+    // release a recording frame
+    virtual void            releaseRecordingFrame(const sp<IMemory>& mem) = 0;
+
     // auto focus
     virtual status_t        autoFocus() = 0;
 
diff --git a/include/ui/ICameraClient.h b/include/ui/ICameraClient.h
index a286b8e..73b951c 100644
--- a/include/ui/ICameraClient.h
+++ b/include/ui/ICameraClient.h
@@ -32,9 +32,10 @@
     virtual void            shutterCallback() = 0;
     virtual void            rawCallback(const sp<IMemory>& picture) = 0;
     virtual void            jpegCallback(const sp<IMemory>& picture) = 0;
-    virtual void            frameCallback(const sp<IMemory>& frame) = 0;
+    virtual void            previewCallback(const sp<IMemory>& frame) = 0;
     virtual void            errorCallback(status_t error) = 0;
     virtual void            autoFocusCallback(bool focused) = 0;
+    virtual void            recordingCallback(const sp<IMemory>& frame) = 0;
 
 };
 
diff --git a/include/ui/ICameraService.h b/include/ui/ICameraService.h
index dfd8923..c652c51 100644
--- a/include/ui/ICameraService.h
+++ b/include/ui/ICameraService.h
@@ -28,7 +28,7 @@
 
 class ICameraService : public IInterface
 {
-protected:
+public:
     enum {
         CONNECT = IBinder::FIRST_CALL_TRANSACTION,
     };
diff --git a/include/ui/ISurface.h b/include/ui/ISurface.h
index 9a7383c..87b320f 100644
--- a/include/ui/ISurface.h
+++ b/include/ui/ISurface.h
@@ -25,6 +25,8 @@
 #include <utils/RefBase.h>
 #include <ui/PixelFormat.h>
 
+#include <hardware/hardware.h>
+
 namespace android {
 
 typedef int32_t    SurfaceID;
@@ -34,11 +36,48 @@
 
 class ISurface : public IInterface
 {
+protected:
+    enum {
+        REGISTER_BUFFERS = IBinder::FIRST_CALL_TRANSACTION,
+        UNREGISTER_BUFFERS,
+        POST_BUFFER, // one-way transaction
+        CREATE_OVERLAY,
+    };
+
 public: 
     DECLARE_META_INTERFACE(Surface);
 
-    virtual status_t registerBuffers(int w, int h, int hstride, int vstride,
-            PixelFormat format, const sp<IMemoryHeap>& heap) = 0;
+    
+    class BufferHeap {
+    public:
+        enum {
+            /* rotate source image 90 degrees */
+            ROT_90    = HAL_TRANSFORM_ROT_90,
+        };
+        BufferHeap();
+        
+        BufferHeap(uint32_t w, uint32_t h,
+                int32_t hor_stride, int32_t ver_stride, 
+                PixelFormat format, const sp<IMemoryHeap>& heap);
+        
+        BufferHeap(uint32_t w, uint32_t h,
+                int32_t hor_stride, int32_t ver_stride, 
+                PixelFormat format, uint32_t transform, uint32_t flags,
+                const sp<IMemoryHeap>& heap);
+        
+        ~BufferHeap(); 
+        
+        uint32_t w;
+        uint32_t h;
+        int32_t hor_stride;
+        int32_t ver_stride;
+        PixelFormat format;
+        uint32_t transform;
+        uint32_t flags;
+        sp<IMemoryHeap> heap;
+    };
+    
+    virtual status_t registerBuffers(const BufferHeap& buffers) = 0;
 
     virtual void postBuffer(ssize_t offset) = 0; // one-way
 
diff --git a/include/ui/KeycodeLabels.h b/include/ui/KeycodeLabels.h
index 53c1188..efa6d2b 100644
--- a/include/ui/KeycodeLabels.h
+++ b/include/ui/KeycodeLabels.h
@@ -113,6 +113,7 @@
     { "PREVIOUSSONG", 88 },
     { "REWIND", 89 },
     { "FORWARD", 90 },
+    { "MUTE", 91 },
 
     // NOTE: If you add a new keycode here you must also add it to:
     //   (enum KeyCode, in this file)
@@ -216,7 +217,8 @@
     kKeyCodeNextSong = 87,
     kKeyCodePreviousSong = 88,
     kKeyCodeRewind = 89,
-    kKeyCodeForward = 90
+    kKeyCodeForward = 90,
+    kKeyCodeMute = 91
 } KeyCode;
 
 static const KeycodeLabel FLAGS[] = {
diff --git a/include/ui/PixelFormat.h b/include/ui/PixelFormat.h
index b65c959..14af823 100644
--- a/include/ui/PixelFormat.h
+++ b/include/ui/PixelFormat.h
@@ -71,6 +71,10 @@
 
     PIXEL_FORMAT_YCbCr_422_SP= GGL_PIXEL_FORMAT_YCbCr_422_SP,
     PIXEL_FORMAT_YCbCr_420_SP= GGL_PIXEL_FORMAT_YCbCr_420_SP,
+    PIXEL_FORMAT_YCbCr_422_P = GGL_PIXEL_FORMAT_YCbCr_422_P,
+    PIXEL_FORMAT_YCbCr_420_P = GGL_PIXEL_FORMAT_YCbCr_420_P,
+    PIXEL_FORMAT_YCbCr_422_I = GGL_PIXEL_FORMAT_YCbCr_422_I,
+    PIXEL_FORMAT_YCbCr_420_I = GGL_PIXEL_FORMAT_YCbCr_420_I,
 
     // New formats can be added if they're also defined in
     // pixelflinger/format.h
@@ -80,7 +84,19 @@
 
 struct PixelFormatInfo
 {
+    enum { // components
+        ALPHA               = 1,
+        RGB                 = 2,
+        RGBA                = 3,
+        LUMINANCE           = 4,
+        LUMINANCE_ALPHA     = 5,
+        Y_CB_CR_SP          = 6,
+        Y_CB_CR_P           = 7,
+        Y_CB_CR_I           = 8,
+    };
+
     inline PixelFormatInfo() : version(sizeof(PixelFormatInfo)) { }
+    size_t getScanlineSize(unsigned int width) const;
     size_t      version;
     PixelFormat format;
     size_t      bytesPerPixel;
@@ -93,7 +109,9 @@
     uint8_t     l_green;
     uint8_t     h_blue;
     uint8_t     l_blue;
-    uint32_t    reserved[2];
+    uint8_t     components;
+    uint8_t     reserved0[3];
+    uint32_t    reserved1;
 };
 
 // Consider caching the results of these functions are they're not
diff --git a/include/utils/ResourceTypes.h b/include/utils/ResourceTypes.h
index 2d56e3e..7d3fcf2 100644
--- a/include/utils/ResourceTypes.h
+++ b/include/utils/ResourceTypes.h
@@ -223,7 +223,7 @@
 {
     // Number of bytes in this structure.
     uint16_t size;
-    
+
     // Always set to 0.
     uint8_t res0;
         
@@ -1101,16 +1101,22 @@
         return false;
     }
     
-    // Return true if 'this' can be considered a match for the parameters in
+    // Return true if 'this' can be considered a match for the parameters in 
     // 'settings'.
+    // Note this is asymetric.  A default piece of data will match every request
+    // but a request for the default should not match odd specifics
+    // (ie, request with no mcc should not match a particular mcc's data)
+    // settings is the requested settings
     inline bool match(const ResTable_config& settings) const {
         if (imsi != 0) {
-            if (settings.mcc != 0 && mcc != 0
-                && mcc != settings.mcc) {
+            if ((settings.mcc != 0 && mcc != 0
+                 && mcc != settings.mcc) || 
+                (settings.mcc == 0 && mcc != 0)) {
                 return false;
             }
-            if (settings.mnc != 0 && mnc != 0
-                && mnc != settings.mnc) {
+            if ((settings.mnc != 0 && mnc != 0
+                 && mnc != settings.mnc) ||
+                (settings.mnc == 0 && mnc != 0)) {
                 return false;
             }
         }
@@ -1131,10 +1137,8 @@
                 && orientation != settings.orientation) {
                 return false;
             }
-            if (settings.density != 0 && density != 0
-                && density != settings.density) {
-                return false;
-            }
+            // Density not taken into account, always match, no matter what
+            // density is specified for the resource
             if (settings.touchscreen != 0 && touchscreen != 0
                 && touchscreen != settings.touchscreen) {
                 return false;
@@ -1464,11 +1468,11 @@
      * @return ssize_t Either a >= 0 table index or a negative error code.
      */
     ssize_t getResource(uint32_t resID, Res_value* outValue, bool mayBeBag=false,
-            uint32_t* outSpecFlags=NULL) const;
+            uint32_t* outSpecFlags=NULL, ResTable_config* outConfig=NULL) const;
 
     inline ssize_t getResource(const ResTable_ref& res, Res_value* outValue,
             uint32_t* outSpecFlags=NULL) const {
-        return getResource(res.ident, outValue, outSpecFlags);
+        return getResource(res.ident, outValue, false, outSpecFlags, NULL);
     }
 
     ssize_t resolveReference(Res_value* inOutValue,
diff --git a/include/utils/logger.h b/include/utils/logger.h
deleted file mode 100644
index 3a08019..0000000
--- a/include/utils/logger.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/* utils/logger.h
-** 
-** Copyright 2007, The Android Open Source Project
-**
-** This file is dual licensed.  It may be redistributed and/or modified
-** under the terms of the Apache 2.0 License OR version 2 of the GNU
-** General Public License.
-*/
-
-#ifndef _UTILS_LOGGER_H
-#define _UTILS_LOGGER_H
-
-#include <stdint.h>
-
-struct logger_entry {
-    uint16_t    len;    /* length of the payload */
-    uint16_t    __pad;  /* no matter what, we get 2 bytes of padding */
-    int32_t     pid;    /* generating process's pid */
-    int32_t     tid;    /* generating process's tid */
-    int32_t     sec;    /* seconds since Epoch */
-    int32_t     nsec;   /* nanoseconds */
-    char        msg[0]; /* the entry's payload */
-};
-
-#define LOGGER_LOG_MAIN		"log/main"
-#define LOGGER_LOG_RADIO	"log/radio"
-#define LOGGER_LOG_EVENTS	"log/events"
-
-#define LOGGER_ENTRY_MAX_LEN		(4*1024)
-#define LOGGER_ENTRY_MAX_PAYLOAD	\
-	(LOGGER_ENTRY_MAX_LEN - sizeof(struct logger_entry))
-
-#ifdef HAVE_IOCTL
-
-#include <sys/ioctl.h>
-
-#define __LOGGERIO	0xAE
-
-#define LOGGER_GET_LOG_BUF_SIZE		_IO(__LOGGERIO, 1) /* size of log */
-#define LOGGER_GET_LOG_LEN		_IO(__LOGGERIO, 2) /* used log len */
-#define LOGGER_GET_NEXT_ENTRY_LEN	_IO(__LOGGERIO, 3) /* next entry len */
-#define LOGGER_FLUSH_LOG		_IO(__LOGGERIO, 4) /* flush log */
-
-#endif // HAVE_IOCTL
-
-#endif /* _UTILS_LOGGER_H */
diff --git a/include/utils/threads.h b/include/utils/threads.h
index 7dca810..8d8d46a 100644
--- a/include/utils/threads.h
+++ b/include/utils/threads.h
@@ -249,41 +249,6 @@
 
 
 /*
- * Read/write lock.  The resource can have multiple readers or one writer,
- * but can't be read and written at the same time.
- *
- * The same thread should not call a lock function while it already has
- * a lock.  (Should be okay for multiple readers.)
- */
-class ReadWriteLock {
-public:
-    ReadWriteLock()
-        : mNumReaders(0), mNumWriters(0)
-        {}
-    ~ReadWriteLock() {}
-
-    void lockForRead();
-    bool tryLockForRead();
-    void unlockForRead();
-
-    void lockForWrite();
-    bool tryLockForWrite();
-    void unlockForWrite();
-
-private:
-    int         mNumReaders;
-    int         mNumWriters;
-
-    Mutex       mLock;
-    Condition   mReadWaiter;
-    Condition   mWriteWaiter;
-#if defined(PRINT_RENDER_TIMES)
-    DurationTimer mDebugTimer;
-#endif
-};
-
-
-/*
  * This is our spiffy thread object!
  */
 
diff --git a/libs/audioflinger/A2dpAudioInterface.cpp b/libs/audioflinger/A2dpAudioInterface.cpp
index c8c8431..2974e32 100644
--- a/libs/audioflinger/A2dpAudioInterface.cpp
+++ b/libs/audioflinger/A2dpAudioInterface.cpp
@@ -48,7 +48,6 @@
         int format, int channelCount, uint32_t sampleRate, status_t *status)
 {
     LOGD("A2dpAudioInterface::openOutputStream %d, %d, %d\n", format, channelCount, sampleRate);
-    Mutex::Autolock lock(mLock);
     status_t err = 0;
 
     // only one output stream allowed
@@ -72,7 +71,8 @@
 }
 
 AudioStreamIn* A2dpAudioInterface::openInputStream(
-        int format, int channelCount, uint32_t sampleRate, status_t *status)
+        int format, int channelCount, uint32_t sampleRate, status_t *status,
+        AudioSystem::audio_in_acoustics acoustics)
 {
     if (status)
         *status = -1;
@@ -99,6 +99,10 @@
     if (strcmp(key, "a2dp_sink_address") == 0) {        
         return mOutput->setAddress(value);
     }
+    if (strcmp(key, "bluetooth_enabled") == 0 &&
+        strcmp(value, "false") == 0) {
+        return mOutput->close();
+    }
 
     return 0;
 }
@@ -126,11 +130,11 @@
 // ----------------------------------------------------------------------------
 
 A2dpAudioInterface::A2dpAudioStreamOut::A2dpAudioStreamOut() :
-    mFd(-1), mStandby(true), mStartCount(0), mRetryCount(0), mData(NULL),
-    mInitialized(false)
+    mFd(-1), mStandby(true), mStartCount(0), mRetryCount(0), mData(NULL)
 {
     // use any address by default
-    strncpy(mA2dpAddress, "00:00:00:00:00:00", sizeof(mA2dpAddress));
+    strcpy(mA2dpAddress, "00:00:00:00:00:00");
+    init();
 }
 
 status_t A2dpAudioInterface::A2dpAudioStreamOut::set(
@@ -154,23 +158,17 @@
 
 A2dpAudioInterface::A2dpAudioStreamOut::~A2dpAudioStreamOut()
 {
-    if (mData)
-        a2dp_cleanup(mData);
+    close();
 }
 
 ssize_t A2dpAudioInterface::A2dpAudioStreamOut::write(const void* buffer, size_t bytes)
 {    
-    status_t status = NO_INIT;
-    size_t remaining = bytes;
+    Mutex::Autolock lock(mLock);
 
-    if (!mInitialized) {
-        status = a2dp_init(mA2dpAddress, 44100, 2, &mData);
-        if (status < 0) {
-            LOGE("a2dp_init failed err: %d\n", status);
-            goto Error;
-        }
-        mInitialized = true;
-    }
+    size_t remaining = bytes;
+    status_t status = init();
+    if (status < 0)
+        goto Error;
     
     while (remaining > 0) {
         status = a2dp_write(mData, buffer, remaining);
@@ -186,17 +184,34 @@
     
     return bytes;
 
-Error:   
+Error:
     // Simulate audio output timing in case of error
     usleep(bytes * 1000000 / frameSize() / sampleRate());
 
     return status;
 }
 
+status_t A2dpAudioInterface::A2dpAudioStreamOut::init()
+{
+    if (!mData) {
+        status_t status = a2dp_init(44100, 2, &mData);
+        if (status < 0) {
+            LOGE("a2dp_init failed err: %d\n", status);
+            mData = NULL;
+            return status;
+        }
+        a2dp_set_sink(mData, mA2dpAddress);
+    }
+
+    return 0;
+}
+
 status_t A2dpAudioInterface::A2dpAudioStreamOut::standby()
 {
     int result = 0;
 
+    Mutex::Autolock lock(mLock);
+
     if (!mStandby) {
         result = a2dp_stop(mData);
         if (result == 0)
@@ -208,19 +223,24 @@
 
 status_t A2dpAudioInterface::A2dpAudioStreamOut::setAddress(const char* address)
 {
-    if (strlen(address) < sizeof(mA2dpAddress))
+    Mutex::Autolock lock(mLock);
+
+    if (strlen(address) != strlen("00:00:00:00:00:00"))
         return -EINVAL;
 
-    if (strcmp(address, mA2dpAddress)) {
-        strcpy(mA2dpAddress, address);
-        
-        if (mInitialized) {
-            a2dp_cleanup(mData);
-            mData = NULL;
-            mInitialized = false;
-        }
+    strcpy(mA2dpAddress, address);
+    if (mData)
+        a2dp_set_sink(mData, mA2dpAddress);
+
+    return NO_ERROR;
+}
+
+status_t A2dpAudioInterface::A2dpAudioStreamOut::close()
+{
+    if (mData) {
+        a2dp_cleanup(mData);
+        mData = NULL;
     }
-    
     return NO_ERROR;
 }
 
diff --git a/libs/audioflinger/A2dpAudioInterface.h b/libs/audioflinger/A2dpAudioInterface.h
index 2197d0e..99614dc 100644
--- a/libs/audioflinger/A2dpAudioInterface.h
+++ b/libs/audioflinger/A2dpAudioInterface.h
@@ -58,7 +58,8 @@
                                 int format,
                                 int channelCount,
                                 uint32_t sampleRate,
-                                status_t *status);
+                                status_t *status,
+                                AudioSystem::audio_in_acoustics acoustics);
 
 protected:
     virtual status_t    doRouting();
@@ -77,7 +78,7 @@
         virtual size_t      bufferSize() const { return 512 * 20; }
         virtual int         channelCount() const { return 2; }
         virtual int         format() const { return AudioSystem::PCM_16_BIT; }
-        virtual uint32_t    latency() const { return ((1000*channelCount()*bufferSize())/frameSize())/sampleRate() + 200; }
+        virtual uint32_t    latency() const { return ((1000*bufferSize())/frameSize())/sampleRate() + 200; }
         virtual status_t    setVolume(float volume) { return INVALID_OPERATION; }
         virtual ssize_t     write(const void* buffer, size_t bytes);
                 status_t    standby();
@@ -85,6 +86,8 @@
 
     private:
         friend class A2dpAudioInterface;
+                status_t    init();
+                status_t    close();
         status_t            setAddress(const char* address);
 
     private:
@@ -94,10 +97,9 @@
                 int         mRetryCount;
                 char        mA2dpAddress[20];
                 void*       mData;
-                bool        mInitialized;
+                Mutex       mLock;
     };
 
-    Mutex                   mLock;
     A2dpAudioStreamOut*     mOutput;
 };
 
diff --git a/libs/audioflinger/AudioDumpInterface.h b/libs/audioflinger/AudioDumpInterface.h
index 42204d6..9a94102 100644
--- a/libs/audioflinger/AudioDumpInterface.h
+++ b/libs/audioflinger/AudioDumpInterface.h
@@ -78,8 +78,9 @@
     virtual status_t    setParameter(const char* key, const char* value)
                             {return mFinalInterface->setParameter(key, value);}
 
-    virtual AudioStreamIn* openInputStream( int format, int channelCount, uint32_t sampleRate, status_t *status)
-                            {return mFinalInterface->openInputStream( format, channelCount, sampleRate, status);}
+    virtual AudioStreamIn* openInputStream( int format, int channelCount, uint32_t sampleRate, status_t *status,
+                                            AudioSystem::audio_in_acoustics acoustics)
+                            {return mFinalInterface->openInputStream( format, channelCount, sampleRate, status, acoustics);}
 
     virtual status_t    dump(int fd, const Vector<String16>& args) { return mFinalInterface->dumpState(fd, args); }
 
diff --git a/libs/audioflinger/AudioFlinger.cpp b/libs/audioflinger/AudioFlinger.cpp
index 918b01f..3c81a47 100644
--- a/libs/audioflinger/AudioFlinger.cpp
+++ b/libs/audioflinger/AudioFlinger.cpp
@@ -47,6 +47,15 @@
 #include "A2dpAudioInterface.h"
 #endif
 
+// ----------------------------------------------------------------------------
+// the sim build doesn't have gettid
+
+#ifndef HAVE_GETTID
+# define gettid getpid
+#endif
+
+// ----------------------------------------------------------------------------
+
 namespace android {
 
 //static const nsecs_t kStandbyTimeInNsecs = seconds(3);
@@ -59,6 +68,16 @@
 static const int8_t kMaxTrackRetries = 50;
 static const int8_t kMaxTrackStartupRetries = 50;
 
+static const int kStartSleepTime = 30000;
+static const int kStopSleepTime = 30000;
+
+static const int kDumpLockRetries = 50;
+static const int kDumpLockSleep = 20000;
+
+// Maximum number of pending buffers allocated by OutputTrack::write()
+static const uint8_t kMaxOutputTrackBuffers = 5;
+
+
 #define AUDIOFLINGER_SECURITY_ENABLED 1
 
 // ----------------------------------------------------------------------------
@@ -98,13 +117,10 @@
 // ----------------------------------------------------------------------------
 
 AudioFlinger::AudioFlinger()
-    : BnAudioFlinger(), Thread(false),
-        mMasterVolume(0), mMasterMute(true), mHardwareAudioMixer(0), mA2dpAudioMixer(0),
-        mAudioMixer(0), mAudioHardware(0), mA2dpAudioInterface(0), mHardwareOutput(0),
-        mA2dpOutput(0), mOutput(0), mRequestedOutput(0), mAudioRecordThread(0),
-        mSampleRate(0), mFrameCount(0), mChannelCount(0), mFormat(0), mMixBuffer(0),
-        mLastWriteTime(0), mNumWrites(0), mNumDelayedWrites(0), mStandby(false),
-        mInWrite(false), mA2dpDisableCount(0), mA2dpSuppressed(false)
+    : BnAudioFlinger(),
+        mAudioHardware(0), mA2dpAudioInterface(0), mA2dpEnabled(false), mNotifyA2dpChange(false),
+        mForcedSpeakerCount(0), mA2dpDisableCount(0), mA2dpSuppressed(false), mForcedRoute(0),
+        mRouteRestoreTime(0), mMusicMuteSaved(false)
 {
     mHardwareStatus = AUDIO_HW_IDLE;
     mAudioHardware = AudioHardwareInterface::create();
@@ -113,57 +129,51 @@
         // open 16-bit output stream for s/w mixer
         mHardwareStatus = AUDIO_HW_OUTPUT_OPEN;
         status_t status;
-        mHardwareOutput = mAudioHardware->openOutputStream(AudioSystem::PCM_16_BIT, 0, 0, &status);
+        AudioStreamOut *hwOutput = mAudioHardware->openOutputStream(AudioSystem::PCM_16_BIT, 0, 0, &status);
         mHardwareStatus = AUDIO_HW_IDLE;
-        if (mHardwareOutput) {
-            mHardwareAudioMixer = new AudioMixer(getOutputFrameCount(mHardwareOutput), mHardwareOutput->sampleRate());
-            mRequestedOutput = mHardwareOutput;
-            doSetOutput(mHardwareOutput);
-
-            // FIXME - this should come from settings
-            setMasterVolume(1.0f);
-            setRouting(AudioSystem::MODE_NORMAL, AudioSystem::ROUTE_SPEAKER, AudioSystem::ROUTE_ALL);
-            setRouting(AudioSystem::MODE_RINGTONE, AudioSystem::ROUTE_SPEAKER, AudioSystem::ROUTE_ALL);
-            setRouting(AudioSystem::MODE_IN_CALL, AudioSystem::ROUTE_EARPIECE, AudioSystem::ROUTE_ALL);
-            setMode(AudioSystem::MODE_NORMAL);
-            mMasterMute = false;
+        if (hwOutput) {
+            mHardwareMixerThread = new MixerThread(this, hwOutput, AudioSystem::AUDIO_OUTPUT_HARDWARE);
         } else {
-            LOGE("Failed to initialize output stream, status: %d", status);
+            LOGE("Failed to initialize hardware output stream, status: %d", status);
         }
         
 #ifdef WITH_A2DP
         // Create A2DP interface
         mA2dpAudioInterface = new A2dpAudioInterface();
-        mA2dpOutput = mA2dpAudioInterface->openOutputStream(AudioSystem::PCM_16_BIT, 0, 0, &status);       
-        mA2dpAudioMixer = new AudioMixer(getOutputFrameCount(mA2dpOutput), mA2dpOutput->sampleRate());
-
-        // create a buffer big enough for both hardware and A2DP audio output.
-        size_t hwFrameCount = getOutputFrameCount(mHardwareOutput);
-        size_t a2dpFrameCount = getOutputFrameCount(mA2dpOutput);
-        size_t frameCount = (hwFrameCount > a2dpFrameCount ? hwFrameCount : a2dpFrameCount);
-#else
-        size_t frameCount = getOutputFrameCount(mHardwareOutput);
+        AudioStreamOut *a2dpOutput = mA2dpAudioInterface->openOutputStream(AudioSystem::PCM_16_BIT, 0, 0, &status);
+        if (a2dpOutput) {
+            mA2dpMixerThread = new MixerThread(this, a2dpOutput, AudioSystem::AUDIO_OUTPUT_A2DP);
+            if (hwOutput) {  
+                uint32_t frameCount = ((a2dpOutput->bufferSize()/a2dpOutput->frameSize()) * hwOutput->sampleRate()) / a2dpOutput->sampleRate();
+                MixerThread::OutputTrack *a2dpOutTrack = new MixerThread::OutputTrack(mA2dpMixerThread,
+                                                            hwOutput->sampleRate(),
+                                                            AudioSystem::PCM_16_BIT,
+                                                            hwOutput->channelCount(),
+                                                            frameCount);
+                mHardwareMixerThread->setOuputTrack(a2dpOutTrack);                
+            }
+        } else {
+            LOGE("Failed to initialize A2DP output stream, status: %d", status);
+        }
 #endif
-        // FIXME - Current mixer implementation only supports stereo output: Always
-        // Allocate a stereo buffer even if HW output is mono.
-        mMixBuffer = new int16_t[frameCount * 2];
-        memset(mMixBuffer, 0, frameCount * 2 * sizeof(int16_t));
-        
+ 
+        // FIXME - this should come from settings
+        setRouting(AudioSystem::MODE_NORMAL, AudioSystem::ROUTE_SPEAKER, AudioSystem::ROUTE_ALL);
+        setRouting(AudioSystem::MODE_RINGTONE, AudioSystem::ROUTE_SPEAKER, AudioSystem::ROUTE_ALL);
+        setRouting(AudioSystem::MODE_IN_CALL, AudioSystem::ROUTE_EARPIECE, AudioSystem::ROUTE_ALL);
+        setMode(AudioSystem::MODE_NORMAL);
+
+        setMasterVolume(1.0f);
+        setMasterMute(false);
+
         // Start record thread
-        mAudioRecordThread = new AudioRecordThread(mAudioHardware);
+        mAudioRecordThread = new AudioRecordThread(mAudioHardware, this);
         if (mAudioRecordThread != 0) {
             mAudioRecordThread->run("AudioRecordThread", PRIORITY_URGENT_AUDIO);            
         }
      } else {
         LOGE("Couldn't even initialize the stubbed audio hardware!");
     }
-
-    char value[PROPERTY_VALUE_MAX];
-    property_get("ro.audio.silent", value, "0");
-    if (atoi(value)) {
-        LOGD("Silence is golden");
-        mMasterMute = true;
-    }
 }
 
 AudioFlinger::~AudioFlinger()
@@ -172,60 +182,73 @@
         mAudioRecordThread->exit();
         mAudioRecordThread.clear();        
     }
+    mHardwareMixerThread.clear();
     delete mAudioHardware;
     // deleting mA2dpAudioInterface also deletes mA2dpOutput;
+#ifdef WITH_A2DP
+    mA2dpMixerThread.clear();
     delete mA2dpAudioInterface;
-    delete [] mMixBuffer;
-    delete mHardwareAudioMixer;
-    delete mA2dpAudioMixer;
-}
- 
-void AudioFlinger::setOutput(AudioStreamOut* output)
-{
-    mRequestedOutput = output;
+#endif
 }
 
-void AudioFlinger::doSetOutput(AudioStreamOut* output)
-{
-    mSampleRate = output->sampleRate();
-    mChannelCount = output->channelCount();
-
-    // FIXME - Current mixer implementation only supports stereo output
-    if (mChannelCount == 1) {
-        LOGE("Invalid audio hardware channel count");
-    }
-    mFormat = output->format();
-    mFrameCount = getOutputFrameCount(output);
-    mAudioMixer = (output == mA2dpOutput ? mA2dpAudioMixer : mHardwareAudioMixer);
-    mOutput = output;
-}
-
-size_t AudioFlinger::getOutputFrameCount(AudioStreamOut* output) 
-{
-    return output->bufferSize() / output->channelCount() / sizeof(int16_t);
-}
 
 #ifdef WITH_A2DP
-bool AudioFlinger::streamDisablesA2dp(int streamType)
+// setA2dpEnabled_l() must be called with AudioFlinger::mLock held
+void AudioFlinger::setA2dpEnabled_l(bool enable)
 {
-    return (streamType == AudioTrack::SYSTEM ||
-            streamType == AudioTrack::RING ||
-            streamType == AudioTrack::ALARM ||
-            streamType == AudioTrack::NOTIFICATION);
+    SortedVector < sp<MixerThread::Track> > tracks;
+    SortedVector < wp<MixerThread::Track> > activeTracks;
+    
+    LOGV_IF(enable, "set output to A2DP\n");
+    LOGV_IF(!enable, "set output to hardware audio\n");
+
+    // Transfer tracks playing on MUSIC stream from one mixer to the other
+    if (enable) {
+        mHardwareMixerThread->getTracks_l(tracks, activeTracks);
+        mA2dpMixerThread->putTracks_l(tracks, activeTracks);
+    } else {
+        mA2dpMixerThread->getTracks_l(tracks, activeTracks);
+        mHardwareMixerThread->putTracks_l(tracks, activeTracks);
+    }
+    mA2dpEnabled = enable;
+    mNotifyA2dpChange = true;
+    mWaitWorkCV.broadcast();
 }
 
-void AudioFlinger::setA2dpEnabled(bool enable)
+// checkA2dpEnabledChange_l() must be called with AudioFlinger::mLock held
+void AudioFlinger::checkA2dpEnabledChange_l()
 {
-    if (enable) {
-        LOGD("set output to A2DP\n");
-        setOutput(mA2dpOutput);
-    } else {
-        LOGD("set output to hardware audio\n");
-        setOutput(mHardwareOutput);
+    if (mNotifyA2dpChange) {
+        // Notify AudioSystem of the A2DP activation/deactivation
+        size_t size = mNotificationClients.size();
+        for (size_t i = 0; i < size; i++) {
+            sp<IBinder> binder = mNotificationClients.itemAt(i).promote();
+            if (binder != NULL) {
+                LOGV("Notifying output change to client %p", binder.get());
+                sp<IAudioFlingerClient> client = interface_cast<IAudioFlingerClient> (binder);
+                client->a2dpEnabledChanged(mA2dpEnabled);
+            }
+        }
+        mNotifyA2dpChange = false;
     }
 }
 #endif // WITH_A2DP
 
+bool AudioFlinger::streamForcedToSpeaker(int streamType)
+{
+    // NOTE that streams listed here must not be routed to A2DP by default:
+    // AudioSystem::routedToA2dpOutput(streamType) == false
+    return (streamType == AudioSystem::RING ||
+            streamType == AudioSystem::ALARM ||
+            streamType == AudioSystem::NOTIFICATION);
+}
+
+bool AudioFlinger::streamDisablesA2dp(int streamType)
+{
+    return (streamType == AudioSystem::VOICE_CALL ||
+            streamType == AudioSystem::BLUETOOTH_SCO);
+}
+
 status_t AudioFlinger::dumpClients(int fd, const Vector<String16>& args)
 {
     const size_t SIZE = 256;
@@ -247,60 +270,18 @@
     return NO_ERROR;
 }
 
-status_t AudioFlinger::dumpTracks(int fd, const Vector<String16>& args)
-{
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-
-    result.append("Tracks:\n");
-    result.append("   Name Clien Typ Fmt Chn Buf S M F SRate LeftV RighV Serv User\n");
-    for (size_t i = 0; i < mTracks.size(); ++i) {
-        wp<Track> wTrack = mTracks[i];
-        if (wTrack != 0) {
-            sp<Track> track = wTrack.promote();
-            if (track != 0) {
-                track->dump(buffer, SIZE);
-                result.append(buffer);
-            }
-        }
-    }
-
-    result.append("Active Tracks:\n");
-    result.append("   Name Clien Typ Fmt Chn Buf S M F SRate LeftV RighV Serv User\n");
-    for (size_t i = 0; i < mActiveTracks.size(); ++i) {
-        wp<Track> wTrack = mTracks[i];
-        if (wTrack != 0) {
-            sp<Track> track = wTrack.promote();
-            if (track != 0) {
-                track->dump(buffer, SIZE);
-                result.append(buffer);
-            }
-        }
-    }
-    write(fd, result.string(), result.size());
-    return NO_ERROR;
-}
 
 status_t AudioFlinger::dumpInternals(int fd, const Vector<String16>& args)
 {
     const size_t SIZE = 256;
     char buffer[SIZE];
     String8 result;
-
-    snprintf(buffer, SIZE, "AudioMixer tracks: %08x\n", audioMixer()->trackNames());
-    result.append(buffer);
-    snprintf(buffer, SIZE, "last write occurred (msecs): %llu\n", ns2ms(systemTime() - mLastWriteTime));
-    result.append(buffer);
-    snprintf(buffer, SIZE, "total writes: %d\n", mNumWrites);
-    result.append(buffer);
-    snprintf(buffer, SIZE, "delayed writes: %d\n", mNumDelayedWrites);
-    result.append(buffer);
-    snprintf(buffer, SIZE, "blocked in write: %d\n", mInWrite);
-    result.append(buffer);
-    snprintf(buffer, SIZE, "standby: %d\n", mStandby);
-    result.append(buffer);
-    snprintf(buffer, SIZE, "Hardware status: %d\n", mHardwareStatus);
+    int hardwareStatus = mHardwareStatus;
+    
+    if (hardwareStatus == AUDIO_HW_IDLE && mHardwareMixerThread->mStandby) {
+        hardwareStatus = AUDIO_HW_STANDBY;
+    }
+    snprintf(buffer, SIZE, "Hardware status: %d\n", hardwareStatus);
     result.append(buffer);
     write(fd, result.string(), result.size());
     return NO_ERROR;
@@ -325,225 +306,36 @@
     if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
         dumpPermissionDenial(fd, args);
     } else {
-        AutoMutex lock(&mLock);
+        bool locked = false;
+        for (int i = 0; i < kDumpLockRetries; ++i) {
+            if (mLock.tryLock() == NO_ERROR) {
+                locked = true;
+                break;
+            }
+            usleep(kDumpLockSleep);
+        }
 
         dumpClients(fd, args);
-        dumpTracks(fd, args);
         dumpInternals(fd, args);
+        mHardwareMixerThread->dump(fd, args);
+#ifdef WITH_A2DP
+        mA2dpMixerThread->dump(fd, args);
+#endif
+
+        // dump record client
+        if (mAudioRecordThread != 0) mAudioRecordThread->dump(fd, args);
+
         if (mAudioHardware) {
             mAudioHardware->dumpState(fd, args);
         }
+        if (locked) mLock.unlock();
     }
     return NO_ERROR;
 }
 
-// Thread virtuals
-bool AudioFlinger::threadLoop()
-{
-    unsigned long sleepTime = kBufferRecoveryInUsecs;
-    int16_t* curBuf = mMixBuffer;
-    Vector< sp<Track> > tracksToRemove;
-    size_t enabledTracks = 0;
-    nsecs_t standbyTime = systemTime();
-
-    do {
-        enabledTracks = 0;
-        { // scope for the mLock
-        
-            Mutex::Autolock _l(mLock);
-            const SortedVector< wp<Track> >& activeTracks = mActiveTracks;
-
-            // put audio hardware into standby after short delay
-            if UNLIKELY(!activeTracks.size() && systemTime() > standbyTime) {
-                // wait until we have something to do...
-                LOGV("Audio hardware entering standby\n");
-                mHardwareStatus = AUDIO_HW_STANDBY;
-                if (!mStandby) {
-                    mOutput->standby();
-                    mStandby = true;
-                }
-                mHardwareStatus = AUDIO_HW_IDLE;
-                // we're about to wait, flush the binder command buffer
-                IPCThreadState::self()->flushCommands();
-                mWaitWorkCV.wait(mLock);
-                LOGV("Audio hardware exiting standby\n");
-                standbyTime = systemTime() + kStandbyTimeInNsecs;
-                continue;
-            }
-
-            // check for change in output
-            if (mRequestedOutput != mOutput) {
-
-                // put current output into standby mode
-                if (mOutput) mOutput->standby();
-
-                // change output
-                doSetOutput(mRequestedOutput);
-            }
-
-            // find out which tracks need to be processed
-            size_t count = activeTracks.size();
-            for (size_t i=0 ; i<count ; i++) {
-                sp<Track> t = activeTracks[i].promote();
-                if (t == 0) continue;
-
-                Track* const track = t.get();
-                audio_track_cblk_t* cblk = track->cblk();
-
-                // The first time a track is added we wait
-                // for all its buffers to be filled before processing it
-                mAudioMixer->setActiveTrack(track->name());
-                if (cblk->framesReady() && (track->isReady() || track->isStopped()) &&
-                        !track->isPaused())
-                {
-                    //LOGD("u=%08x, s=%08x [OK]", u, s);
-
-                    // compute volume for this track
-                    int16_t left, right;
-                    if (track->isMuted() || mMasterMute || track->isPausing()) {
-                        left = right = 0;
-                        if (track->isPausing()) {
-                            LOGV("paused(%d)", track->name());
-                            track->setPaused();
-                        }
-                    } else {
-                        float typeVolume = mStreamTypes[track->type()].volume;
-                        float v = mMasterVolume * typeVolume;
-                        float v_clamped = v * cblk->volume[0];
-                        if (v_clamped > MAX_GAIN) v_clamped = MAX_GAIN;
-                        left = int16_t(v_clamped);
-                        v_clamped = v * cblk->volume[1];
-                        if (v_clamped > MAX_GAIN) v_clamped = MAX_GAIN;
-                        right = int16_t(v_clamped);
-                    }
-
-                    // XXX: these things DON'T need to be done each time
-                    mAudioMixer->setBufferProvider(track);
-                    mAudioMixer->enable(AudioMixer::MIXING);
-
-                    int param;
-                    if ( track->mFillingUpStatus == Track::FS_FILLED) {
-                        // no ramp for the first volume setting
-                        track->mFillingUpStatus = Track::FS_ACTIVE;
-                        if (track->mState == TrackBase::RESUMING) {
-                            track->mState = TrackBase::ACTIVE;
-                            param = AudioMixer::RAMP_VOLUME;
-                        } else {
-                            param = AudioMixer::VOLUME;
-                        }
-                    } else {
-                        param = AudioMixer::RAMP_VOLUME;
-                    }
-                    mAudioMixer->setParameter(param, AudioMixer::VOLUME0, left);
-                    mAudioMixer->setParameter(param, AudioMixer::VOLUME1, right);
-                    mAudioMixer->setParameter(
-                        AudioMixer::TRACK,
-                        AudioMixer::FORMAT, track->format());
-                    mAudioMixer->setParameter(
-                        AudioMixer::TRACK,
-                        AudioMixer::CHANNEL_COUNT, track->channelCount());
-                    mAudioMixer->setParameter(
-                        AudioMixer::RESAMPLE,
-                        AudioMixer::SAMPLE_RATE,
-                        int(cblk->sampleRate));
-
-                    // reset retry count
-                    track->mRetryCount = kMaxTrackRetries;
-                    enabledTracks++;
-                } else {
-                    //LOGD("u=%08x, s=%08x [NOT READY]", u, s);
-                    if (track->isStopped()) {
-                        track->reset();
-                    }
-                    if (track->isTerminated() || track->isStopped() || track->isPaused()) {
-                        // We have consumed all the buffers of this track.
-                        // Remove it from the list of active tracks.
-                        LOGV("remove(%d) from active list", track->name());
-                        tracksToRemove.add(track);
-                    } else {
-                        // No buffers for this track. Give it a few chances to
-                        // fill a buffer, then remove it from active list.
-                        if (--(track->mRetryCount) <= 0) {
-                            LOGV("BUFFER TIMEOUT: remove(%d) from active list", track->name());
-                            tracksToRemove.add(track);
-                        }
-                    }
-                    // LOGV("disable(%d)", track->name());
-                    mAudioMixer->disable(AudioMixer::MIXING);
-                }
-            }
-
-            // remove all the tracks that need to be...
-            count = tracksToRemove.size();
-            if (UNLIKELY(count)) {
-                for (size_t i=0 ; i<count ; i++) {
-                    const sp<Track>& track = tracksToRemove[i];
-                    removeActiveTrack(track);
-                    if (track->isTerminated()) {
-                        mTracks.remove(track);
-                        mAudioMixer->deleteTrackName(track->mName);
-                    }
-                }
-            }  
-       }
-        if (LIKELY(enabledTracks)) {
-            // mix buffers...
-            mAudioMixer->process(curBuf);
-
-            // output audio to hardware
-            mLastWriteTime = systemTime();
-            mInWrite = true;
-            size_t mixBufferSize = mFrameCount*mChannelCount*sizeof(int16_t);
-            mOutput->write(curBuf, mixBufferSize);
-            mNumWrites++;
-            mInWrite = false;
-            mStandby = false;
-            nsecs_t temp = systemTime();
-            standbyTime = temp + kStandbyTimeInNsecs;
-            nsecs_t delta = temp - mLastWriteTime;
-            nsecs_t maxPeriod = seconds(mFrameCount) / mSampleRate * 2;
-            if (delta > maxPeriod) {
-                LOGW("write blocked for %llu msecs", ns2ms(delta));
-                mNumDelayedWrites++;
-            }
-            sleepTime = kBufferRecoveryInUsecs;
-        } else {
-            // There was nothing to mix this round, which means all
-            // active tracks were late. Sleep a little bit to give
-            // them another chance. If we're too late, the audio
-            // hardware will zero-fill for us.
-            LOGV("no buffers - usleep(%lu)", sleepTime);
-            usleep(sleepTime);
-            if (sleepTime < kMaxBufferRecoveryInUsecs) {
-                sleepTime += kBufferRecoveryInUsecs;
-            }
-        }
-
-        // finally let go of all our tracks, without the lock held
-        // since we can't guarantee the destructors won't acquire that
-        // same lock.
-        tracksToRemove.clear();
-    } while (true);
-
-    return false;
-}
-
-status_t AudioFlinger::readyToRun()
-{
-    if (mSampleRate == 0) {
-        LOGE("No working audio driver found.");
-        return NO_INIT;
-    }
-    LOGI("AudioFlinger's main thread ready to run.");
-    return NO_ERROR;
-}
-
-void AudioFlinger::onFirstRef()
-{
-    run("AudioFlinger", ANDROID_PRIORITY_URGENT_AUDIO);
-}
-
 // IAudioFlinger interface
+
+
 sp<IAudioTrack> AudioFlinger::createTrack(
         pid_t pid,
         int streamType,
@@ -555,34 +347,21 @@
         const sp<IMemory>& sharedBuffer,
         status_t *status)
 {
-    sp<Track> track;
+    sp<MixerThread::Track> track;
     sp<TrackHandle> trackHandle;
     sp<Client> client;
     wp<Client> wclient;
     status_t lStatus;
 
-    if (streamType >= AudioTrack::NUM_STREAM_TYPES) {
+    if (streamType >= AudioSystem::NUM_STREAM_TYPES) {
         LOGE("invalid stream type");
         lStatus = BAD_VALUE;
         goto Exit;
     }
 
-    // Resampler implementation limits input sampling rate to 2 x output sampling rate.
-    if (sampleRate > MAX_SAMPLE_RATE || sampleRate > mSampleRate*2) {
-        LOGE("Sample rate out of range: %d", sampleRate);
-        lStatus = BAD_VALUE;
-        goto Exit;
-    }
-
     {
         Mutex::Autolock _l(mLock);
 
-        if (mSampleRate == 0) {
-            LOGE("Audio driver not initialized.");
-            lStatus = NO_INIT;
-            goto Exit;
-        }
-
         wclient = mClients.valueFor(pid);
 
         if (wclient != NULL) {
@@ -591,13 +370,21 @@
             client = new Client(this, pid);
             mClients.add(pid, client);
         }
-
-        track = new Track(this, client, streamType, sampleRate, format,
-                channelCount, frameCount, sharedBuffer);
-        mTracks.add(track);
+#ifdef WITH_A2DP
+        if (isA2dpEnabled() && AudioSystem::routedToA2dpOutput(streamType)) {
+            track = mA2dpMixerThread->createTrack_l(client, streamType, sampleRate, format,
+                    channelCount, frameCount, sharedBuffer, &lStatus);            
+        } else 
+#endif
+        {
+            track = mHardwareMixerThread->createTrack_l(client, streamType, sampleRate, format,
+                    channelCount, frameCount, sharedBuffer, &lStatus);            
+        }
+    }
+    if (lStatus == NO_ERROR) {
         trackHandle = new TrackHandle(track);
-
-        lStatus = NO_ERROR;
+    } else {
+        track.clear();
     }
 
 Exit:
@@ -607,34 +394,54 @@
     return trackHandle;
 }
 
-uint32_t AudioFlinger::sampleRate() const
+uint32_t AudioFlinger::sampleRate(int output) const
 {
-    return mSampleRate;
+#ifdef WITH_A2DP
+     if (output == AudioSystem::AUDIO_OUTPUT_A2DP) {
+         return mA2dpMixerThread->sampleRate();
+     }
+#endif
+     return mHardwareMixerThread->sampleRate();
 }
 
-int AudioFlinger::channelCount() const
+int AudioFlinger::channelCount(int output) const
 {
-    return mChannelCount;
+#ifdef WITH_A2DP
+     if (output == AudioSystem::AUDIO_OUTPUT_A2DP) {
+         return mA2dpMixerThread->channelCount();
+     }
+#endif
+     return mHardwareMixerThread->channelCount();
 }
 
-int AudioFlinger::format() const
+int AudioFlinger::format(int output) const
 {
-    return mFormat;
+#ifdef WITH_A2DP
+     if (output == AudioSystem::AUDIO_OUTPUT_A2DP) {
+         return mA2dpMixerThread->format();
+     }
+#endif
+     return mHardwareMixerThread->format();
 }
 
-size_t AudioFlinger::frameCount() const
+size_t AudioFlinger::frameCount(int output) const
 {
-    return mFrameCount;
+#ifdef WITH_A2DP
+     if (output == AudioSystem::AUDIO_OUTPUT_A2DP) {
+         return mA2dpMixerThread->frameCount();
+     }
+#endif
+     return mHardwareMixerThread->frameCount();
 }
 
-uint32_t AudioFlinger::latency() const
+uint32_t AudioFlinger::latency(int output) const
 {
-    if (mOutput) {
-        return mOutput->latency();
-    }
-    else {
-        return 0;
-    }
+#ifdef WITH_A2DP
+     if (output == AudioSystem::AUDIO_OUTPUT_A2DP) {
+         return mA2dpMixerThread->latency();
+     }
+#endif
+     return mHardwareMixerThread->latency();
 }
 
 status_t AudioFlinger::setMasterVolume(float value)
@@ -648,12 +455,14 @@
     AutoMutex lock(mHardwareLock);
     mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME;
     if (mAudioHardware->setMasterVolume(value) == NO_ERROR) {
-        mMasterVolume = 1.0f;
-    }
-    else {
-        mMasterVolume = value;
+        value = 1.0f;
     }
     mHardwareStatus = AUDIO_HW_IDLE;
+    mHardwareMixerThread->setMasterVolume(value);
+#ifdef WITH_A2DP
+    mA2dpMixerThread->setMasterVolume(value);
+#endif
+
     return NO_ERROR;
 }
 
@@ -671,20 +480,21 @@
     }
 
 #ifdef WITH_A2DP
-    LOGD("setRouting %d %d %d\n", mode, routes, mask);
+    LOGD("setRouting %d %d %d, tid %d, calling tid %d\n", mode, routes, mask, gettid(), IPCThreadState::self()->getCallingPid());
     if (mode == AudioSystem::MODE_NORMAL && 
             (mask & AudioSystem::ROUTE_BLUETOOTH_A2DP)) {
         AutoMutex lock(&mLock);
 
         bool enableA2dp = false;
         if (routes & AudioSystem::ROUTE_BLUETOOTH_A2DP) {
-            if (mA2dpDisableCount > 0)
-                mA2dpSuppressed = true;
-            else
-                enableA2dp = true;
+            enableA2dp = true;
         }
-        setA2dpEnabled(enableA2dp);
-        LOGD("setOutput done\n");
+        if (mA2dpDisableCount > 0) {
+            mA2dpSuppressed = enableA2dp;
+        } else {
+            setA2dpEnabled_l(enableA2dp);
+        }
+        LOGV("setOutput done\n");
     }
 #endif
 
@@ -697,6 +507,12 @@
         err = mAudioHardware->getRouting(mode, &r);
         if (err == NO_ERROR) {
             r = (r & ~mask) | (routes & mask);
+            if (mode == AudioSystem::MODE_NORMAL || 
+                (mode == AudioSystem::MODE_CURRENT && getMode() == AudioSystem::MODE_NORMAL)) {
+                mSavedRoute = r;
+                r |= mForcedRoute;
+                LOGV("setRouting mSavedRoute %08x mForcedRoute %08x\n", mSavedRoute, mForcedRoute);
+            }
             mHardwareStatus = AUDIO_HW_SET_ROUTING;
             err = mAudioHardware->setRouting(mode, r);
         }
@@ -709,9 +525,14 @@
 {
     uint32_t routes = 0;
     if ((mode >= AudioSystem::MODE_CURRENT) && (mode < AudioSystem::NUM_MODES)) {
-        mHardwareStatus = AUDIO_HW_GET_ROUTING;
-        mAudioHardware->getRouting(mode, &routes);
-        mHardwareStatus = AUDIO_HW_IDLE;
+        if (mode == AudioSystem::MODE_NORMAL || 
+            (mode == AudioSystem::MODE_CURRENT && getMode() == AudioSystem::MODE_NORMAL)) {
+            routes = mSavedRoute;                
+        } else {
+            mHardwareStatus = AUDIO_HW_GET_ROUTING;
+            mAudioHardware->getRouting(mode, &routes);
+            mHardwareStatus = AUDIO_HW_IDLE;
+        }
     } else {
         LOGW("Illegal value: getRouting(%d)", mode);
     }
@@ -774,19 +595,21 @@
     if (!settingsAllowed()) {
         return PERMISSION_DENIED;
     }
-
-    mMasterMute = muted;
+    mHardwareMixerThread->setMasterMute(muted);
+#ifdef WITH_A2DP
+    mA2dpMixerThread->setMasterMute(muted);
+#endif
     return NO_ERROR;
 }
 
 float AudioFlinger::masterVolume() const
 {
-    return mMasterVolume;
+    return mHardwareMixerThread->masterVolume();
 }
 
 bool AudioFlinger::masterMute() const
 {
-    return mMasterMute;
+    return mHardwareMixerThread->masterMute();
 }
 
 status_t AudioFlinger::setStreamVolume(int stream, float value)
@@ -796,26 +619,40 @@
         return PERMISSION_DENIED;
     }
 
-    if (uint32_t(stream) >= AudioTrack::NUM_STREAM_TYPES) {
+    if (uint32_t(stream) >= AudioSystem::NUM_STREAM_TYPES) {
         return BAD_VALUE;
     }
 
     status_t ret = NO_ERROR;
-    if (stream == AudioTrack::VOICE_CALL) {
+    
+    if (stream == AudioSystem::VOICE_CALL ||
+        stream == AudioSystem::BLUETOOTH_SCO) {
+        float hwValue = value;
+        if (stream == AudioSystem::VOICE_CALL) {
+            hwValue = (float)AudioSystem::logToLinear(value)/100.0f;
+            // FIXME: This is a temporary fix to re-base the internally
+            // generated in-call audio so that it is never muted, which is
+            // already the case for the hardware routed in-call audio.
+            // When audio stream handling is reworked, this should be
+            // addressed more cleanly.  Fixes #1324; see discussion at
+            // http://review.source.android.com/8224
+            value = value * 0.99 + 0.01;        
+        } else { // (type == AudioSystem::BLUETOOTH_SCO)
+            hwValue = 1.0f;
+        }
+
         AutoMutex lock(mHardwareLock);
         mHardwareStatus = AUDIO_SET_VOICE_VOLUME;
-        ret = mAudioHardware->setVoiceVolume(value);
+        ret = mAudioHardware->setVoiceVolume(hwValue);
         mHardwareStatus = AUDIO_HW_IDLE;
-        // FIXME: This is a temporary fix to re-base the internally
-        // generated in-call audio so that it is never muted, which is
-        // already the case for the hardware routed in-call audio.
-        // When audio stream handling is reworked, this should be
-        // addressed more cleanly.  Fixes #1324; see discussion at
-        // http://review.source.android.com/8224
-        mStreamTypes[stream].volume = value * (1.0 - 1.0 / 6.0) + (1.0 / 6.0);
-    } else {
-        mStreamTypes[stream].volume = value;
+        
     }
+    
+    mHardwareMixerThread->setStreamVolume(stream, value);
+#ifdef WITH_A2DP
+    mA2dpMixerThread->setStreamVolume(stream, value);
+#endif
+
     return ret;
 }
 
@@ -826,45 +663,66 @@
         return PERMISSION_DENIED;
     }
 
-    if (uint32_t(stream) >= AudioTrack::NUM_STREAM_TYPES) {
+    if (uint32_t(stream) >= AudioSystem::NUM_STREAM_TYPES) {
         return BAD_VALUE;
     }
-    mStreamTypes[stream].mute = muted;
+    
+#ifdef WITH_A2DP
+    mA2dpMixerThread->setStreamMute(stream, muted);
+#endif
+    if (stream == AudioSystem::MUSIC) 
+    {
+        AutoMutex lock(&mHardwareLock);
+        if (mForcedRoute != 0)
+            mMusicMuteSaved = muted;
+        else
+            mHardwareMixerThread->setStreamMute(stream, muted);
+    } else {
+        mHardwareMixerThread->setStreamMute(stream, muted);
+    }
+
+    
+
     return NO_ERROR;
 }
 
 float AudioFlinger::streamVolume(int stream) const
 {
-    if (uint32_t(stream) >= AudioTrack::NUM_STREAM_TYPES) {
+    if (uint32_t(stream) >= AudioSystem::NUM_STREAM_TYPES) {
         return 0.0f;
     }
-    if (stream == AudioTrack::VOICE_CALL) {
+    float value = mHardwareMixerThread->streamVolume(stream);
+    
+    if (stream == AudioSystem::VOICE_CALL) {
         // FIXME: Re-base internally generated in-call audio,
         // reverse of above in setStreamVolume.
-        return (mStreamTypes[stream].volume - (1.0 / 6.0)) / (1.0 - 1.0 / 6.0);
+        value = (value - 0.01) / 0.99;
     }
-    return mStreamTypes[stream].volume;
+    
+    return value;
 }
 
 bool AudioFlinger::streamMute(int stream) const
 {
-    if (uint32_t(stream) >= AudioTrack::NUM_STREAM_TYPES) {
+    if (uint32_t(stream) >= AudioSystem::NUM_STREAM_TYPES) {
         return true;
     }
-    return mStreamTypes[stream].mute;
+    
+    if (stream == AudioSystem::MUSIC && mForcedRoute != 0) 
+    {
+        return mMusicMuteSaved;
+    }
+    return mHardwareMixerThread->streamMute(stream);
 }
 
 bool AudioFlinger::isMusicActive() const
 {
-    size_t count = mActiveTracks.size();
-    for (size_t i = 0 ; i < count ; ++i) {
-        sp<Track> t = mActiveTracks[i].promote();
-        if (t == 0) continue;
-        Track* const track = t.get();
-        if (t->mStreamType == AudioTrack::MUSIC)
-            return true;
-    }
-    return false;
+ #ifdef WITH_A2DP
+     if (isA2dpEnabled()) {
+         return mA2dpMixerThread->isMusicActive();
+     }
+ #endif
+    return mHardwareMixerThread->isMusicActive();
 }
 
 status_t AudioFlinger::setParameter(const char* key, const char* value)
@@ -872,6 +730,8 @@
     status_t result, result2;
     AutoMutex lock(mHardwareLock);
     mHardwareStatus = AUDIO_SET_PARAMETER;
+    
+    LOGV("setParameter() key %s, value %s, tid %d, calling tid %d", key, value, gettid(), IPCThreadState::self()->getCallingPid());
     result = mAudioHardware->setParameter(key, value);
     if (mA2dpAudioInterface) {
         result2 = mA2dpAudioInterface->setParameter(key, value);
@@ -882,15 +742,716 @@
     return result;
 }
 
+size_t AudioFlinger::getInputBufferSize(uint32_t sampleRate, int format, int channelCount)
+{
+    return mAudioHardware->getInputBufferSize(sampleRate, format, channelCount);
+}
+
+void AudioFlinger::registerClient(const sp<IAudioFlingerClient>& client)
+{
+    
+    LOGV("registerClient() %p, tid %d, calling tid %d", client.get(), gettid(), IPCThreadState::self()->getCallingPid());
+    Mutex::Autolock _l(mLock);
+
+    sp<IBinder> binder = client->asBinder();
+    if (mNotificationClients.indexOf(binder) < 0) {
+        LOGV("Adding notification client %p", binder.get());
+        binder->linkToDeath(this);
+        mNotificationClients.add(binder);
+        client->a2dpEnabledChanged(isA2dpEnabled());
+    }
+}
+
+void AudioFlinger::binderDied(const wp<IBinder>& who) {
+    
+    LOGV("binderDied() %p, tid %d, calling tid %d", who.unsafe_get(), gettid(), IPCThreadState::self()->getCallingPid());
+    Mutex::Autolock _l(mLock);
+
+    IBinder *binder = who.unsafe_get();
+
+    if (binder != NULL) {
+        int index = mNotificationClients.indexOf(binder);
+        if (index >= 0) {
+            LOGV("Removing notification client %p", binder);
+            mNotificationClients.removeAt(index);
+        }
+    }
+}
+
 void AudioFlinger::removeClient(pid_t pid)
 {
+    LOGV("removeClient() pid %d, tid %d, calling tid %d", pid, gettid(), IPCThreadState::self()->getCallingPid());
     Mutex::Autolock _l(mLock);
     mClients.removeItem(pid);
 }
 
-status_t AudioFlinger::addTrack(const sp<Track>& track)
+bool AudioFlinger::isA2dpEnabled() const
 {
-    Mutex::Autolock _l(mLock);
+    return mA2dpEnabled;
+}
+
+void AudioFlinger::handleForcedSpeakerRoute(int command)
+{
+    switch(command) {
+    case ACTIVE_TRACK_ADDED:
+        {
+            AutoMutex lock(mHardwareLock);
+            if (mForcedSpeakerCount++ == 0) {
+                mRouteRestoreTime = 0;
+                mMusicMuteSaved = mHardwareMixerThread->streamMute(AudioSystem::MUSIC);
+                if (mForcedRoute == 0 && !(mSavedRoute & AudioSystem::ROUTE_SPEAKER)) {
+                    LOGV("Route forced to Speaker ON %08x", mSavedRoute | AudioSystem::ROUTE_SPEAKER);
+                    mHardwareMixerThread->setStreamMute(AudioSystem::MUSIC, true);
+                    mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME;
+                    mAudioHardware->setMasterVolume(0);
+                    usleep(mHardwareMixerThread->latency()*1000);
+                    mHardwareStatus = AUDIO_HW_SET_ROUTING;
+                    mAudioHardware->setRouting(AudioSystem::MODE_NORMAL, mSavedRoute | AudioSystem::ROUTE_SPEAKER);
+                    mHardwareStatus = AUDIO_HW_IDLE;
+                    // delay track start so that audio hardware has time to siwtch routes
+                    usleep(kStartSleepTime);
+                    mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME;
+                    mAudioHardware->setMasterVolume(mHardwareMixerThread->masterVolume());
+                    mHardwareStatus = AUDIO_HW_IDLE;
+                }
+                mForcedRoute = AudioSystem::ROUTE_SPEAKER;
+            }
+            LOGV("mForcedSpeakerCount incremented to %d", mForcedSpeakerCount);
+        }
+        break;
+    case ACTIVE_TRACK_REMOVED:
+        {
+            AutoMutex lock(mHardwareLock);
+            if (mForcedSpeakerCount > 0){
+                if (--mForcedSpeakerCount == 0) {
+                    mRouteRestoreTime = systemTime() + milliseconds(kStopSleepTime/1000);
+                }
+                LOGV("mForcedSpeakerCount decremented to %d", mForcedSpeakerCount);
+            } else {
+                LOGE("mForcedSpeakerCount is already zero");
+            }
+        }
+        break;
+    case CHECK_ROUTE_RESTORE_TIME:
+    case FORCE_ROUTE_RESTORE:
+        if (mRouteRestoreTime) {
+            AutoMutex lock(mHardwareLock);
+            if (mRouteRestoreTime && 
+               (systemTime() > mRouteRestoreTime || command == FORCE_ROUTE_RESTORE)) {
+                mHardwareMixerThread->setStreamMute(AudioSystem::MUSIC, mMusicMuteSaved);
+                mForcedRoute = 0;
+                if (!(mSavedRoute & AudioSystem::ROUTE_SPEAKER)) {
+                    mHardwareStatus = AUDIO_HW_SET_ROUTING;
+                    mAudioHardware->setRouting(AudioSystem::MODE_NORMAL, mSavedRoute);
+                    mHardwareStatus = AUDIO_HW_IDLE;
+                    LOGV("Route forced to Speaker OFF %08x", mSavedRoute);
+                }
+                mRouteRestoreTime = 0;
+            }
+        }
+        break;
+    }
+}
+
+#ifdef WITH_A2DP
+// handleStreamDisablesA2dp_l() must be called with AudioFlinger::mLock held
+void AudioFlinger::handleStreamDisablesA2dp_l(int command)
+{
+    switch(command) {
+    case ACTIVE_TRACK_ADDED:
+        {
+            if (mA2dpDisableCount++ == 0) {
+                if (mA2dpEnabled) {
+                    setA2dpEnabled_l(false);
+                    mA2dpSuppressed = true;
+                }
+            }
+            LOGV("mA2dpDisableCount incremented to %d", mA2dpDisableCount);
+        }
+        break;
+    case ACTIVE_TRACK_REMOVED:
+        {
+            if (mA2dpDisableCount > 0) {
+                if (--mA2dpDisableCount == 0) {
+                    if (mA2dpSuppressed) {
+                        setA2dpEnabled_l(true);
+                        mA2dpSuppressed = false;
+                    }
+                }
+                LOGV("mA2dpDisableCount decremented to %d", mA2dpDisableCount);
+            } else {
+                LOGE("mA2dpDisableCount is already zero");
+            }
+        }
+        break;
+    }
+}
+#endif
+
+// ----------------------------------------------------------------------------
+
+AudioFlinger::MixerThread::MixerThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, int outputType)
+    :   Thread(false),
+        mAudioFlinger(audioFlinger), mAudioMixer(0), mOutput(output), mOutputType(outputType), 
+        mSampleRate(0), mFrameCount(0), mChannelCount(0), mFormat(0), mMixBuffer(0),
+        mLastWriteTime(0), mNumWrites(0), mNumDelayedWrites(0), mStandby(false),
+        mInWrite(false)
+{
+    mSampleRate = output->sampleRate();
+    mChannelCount = output->channelCount();
+
+    // FIXME - Current mixer implementation only supports stereo output
+    if (mChannelCount == 1) {
+        LOGE("Invalid audio hardware channel count");
+    }
+
+    mFormat = output->format();
+    mFrameCount = output->bufferSize() / output->channelCount() / sizeof(int16_t);
+    mAudioMixer = new AudioMixer(mFrameCount, output->sampleRate());
+
+    // FIXME - Current mixer implementation only supports stereo output: Always
+    // Allocate a stereo buffer even if HW output is mono.
+    mMixBuffer = new int16_t[mFrameCount * 2];
+    memset(mMixBuffer, 0, mFrameCount * 2 * sizeof(int16_t));
+}
+
+AudioFlinger::MixerThread::~MixerThread()
+{
+    delete [] mMixBuffer;
+    delete mAudioMixer;
+}
+
+status_t AudioFlinger::MixerThread::dump(int fd, const Vector<String16>& args)
+{
+    dumpInternals(fd, args);
+    dumpTracks(fd, args);
+    return NO_ERROR;
+}
+
+status_t AudioFlinger::MixerThread::dumpTracks(int fd, const Vector<String16>& args)
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    String8 result;
+
+    snprintf(buffer, SIZE, "Output %d mixer thread tracks\n", mOutputType);
+    result.append(buffer);
+    result.append("   Name Clien Typ Fmt Chn Buf S M F SRate LeftV RighV Serv User\n");
+    for (size_t i = 0; i < mTracks.size(); ++i) {
+        wp<Track> wTrack = mTracks[i];
+        if (wTrack != 0) {
+            sp<Track> track = wTrack.promote();
+            if (track != 0) {
+                track->dump(buffer, SIZE);
+                result.append(buffer);
+            }
+        }
+    }
+
+    snprintf(buffer, SIZE, "Output %d mixer thread active tracks\n", mOutputType);
+    result.append(buffer);
+    result.append("   Name Clien Typ Fmt Chn Buf S M F SRate LeftV RighV Serv User\n");
+    for (size_t i = 0; i < mActiveTracks.size(); ++i) {
+        wp<Track> wTrack = mTracks[i];
+        if (wTrack != 0) {
+            sp<Track> track = wTrack.promote();
+            if (track != 0) {
+                track->dump(buffer, SIZE);
+                result.append(buffer);
+            }
+        }
+    }
+    write(fd, result.string(), result.size());
+    return NO_ERROR;
+}
+
+status_t AudioFlinger::MixerThread::dumpInternals(int fd, const Vector<String16>& args)
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    String8 result;
+
+    snprintf(buffer, SIZE, "Output %d mixer thread internals\n", mOutputType);
+    result.append(buffer);
+    snprintf(buffer, SIZE, "AudioMixer tracks: %08x\n", mAudioMixer->trackNames());
+    result.append(buffer);
+    snprintf(buffer, SIZE, "last write occurred (msecs): %llu\n", ns2ms(systemTime() - mLastWriteTime));
+    result.append(buffer);
+    snprintf(buffer, SIZE, "total writes: %d\n", mNumWrites);
+    result.append(buffer);
+    snprintf(buffer, SIZE, "delayed writes: %d\n", mNumDelayedWrites);
+    result.append(buffer);
+    snprintf(buffer, SIZE, "blocked in write: %d\n", mInWrite);
+    result.append(buffer);
+    snprintf(buffer, SIZE, "standby: %d\n", mStandby);
+    result.append(buffer);
+    write(fd, result.string(), result.size());
+    return NO_ERROR;
+}
+
+// Thread virtuals
+bool AudioFlinger::MixerThread::threadLoop()
+{
+    unsigned long sleepTime = kBufferRecoveryInUsecs;
+    int16_t* curBuf = mMixBuffer;
+    Vector< sp<Track> > tracksToRemove;
+    size_t enabledTracks = 0;
+    nsecs_t standbyTime = systemTime();   
+    size_t mixBufferSize = mFrameCount*mChannelCount*sizeof(int16_t);
+    nsecs_t maxPeriod = seconds(mFrameCount) / mSampleRate * 2;
+
+#ifdef WITH_A2DP
+    bool outputTrackActive = false;
+#endif
+
+    do {
+        enabledTracks = 0;
+        { // scope for the AudioFlinger::mLock
+        
+            Mutex::Autolock _l(mAudioFlinger->mLock);
+
+#ifdef WITH_A2DP
+            if (mOutputTrack != NULL && !mAudioFlinger->isA2dpEnabled()) {
+                if (outputTrackActive) {
+                    mAudioFlinger->mLock.unlock();
+                    mOutputTrack->stop();
+                    mAudioFlinger->mLock.lock();
+                    outputTrackActive = false;
+                }
+            }
+            mAudioFlinger->checkA2dpEnabledChange_l();
+#endif
+
+            const SortedVector< wp<Track> >& activeTracks = mActiveTracks;
+
+            // put audio hardware into standby after short delay
+            if UNLIKELY(!activeTracks.size() && systemTime() > standbyTime) {
+                // wait until we have something to do...
+                LOGV("Audio hardware entering standby, output %d\n", mOutputType);
+                if (!mStandby) {
+                    mOutput->standby();
+                    mStandby = true;
+                }
+                
+#ifdef WITH_A2DP
+                if (outputTrackActive) {
+                    mAudioFlinger->mLock.unlock();
+                    mOutputTrack->stop();
+                    mAudioFlinger->mLock.lock();
+                    outputTrackActive = false;
+                }
+#endif
+                if (mOutputType == AudioSystem::AUDIO_OUTPUT_HARDWARE) {
+                    mAudioFlinger->handleForcedSpeakerRoute(FORCE_ROUTE_RESTORE);
+                }                
+                // we're about to wait, flush the binder command buffer
+                IPCThreadState::self()->flushCommands();
+                mAudioFlinger->mWaitWorkCV.wait(mAudioFlinger->mLock);
+                LOGV("Audio hardware exiting standby, output %d\n", mOutputType);
+                
+                if (mMasterMute == false) {
+                    char value[PROPERTY_VALUE_MAX];
+                    property_get("ro.audio.silent", value, "0");
+                    if (atoi(value)) {
+                        LOGD("Silence is golden");
+                        setMasterMute(true);
+                    }                    
+                }
+                
+                standbyTime = systemTime() + kStandbyTimeInNsecs;
+                continue;
+            }
+
+            // Forced route to speaker is handled by hardware mixer thread
+            if (mOutputType == AudioSystem::AUDIO_OUTPUT_HARDWARE) {
+                mAudioFlinger->handleForcedSpeakerRoute(CHECK_ROUTE_RESTORE_TIME);
+            }
+
+            // find out which tracks need to be processed
+            size_t count = activeTracks.size();
+            for (size_t i=0 ; i<count ; i++) {
+                sp<Track> t = activeTracks[i].promote();
+                if (t == 0) continue;
+
+                Track* const track = t.get();
+                audio_track_cblk_t* cblk = track->cblk();
+
+                // The first time a track is added we wait
+                // for all its buffers to be filled before processing it
+                mAudioMixer->setActiveTrack(track->name());
+                if (cblk->framesReady() && (track->isReady() || track->isStopped()) &&
+                        !track->isPaused())
+                {
+                    //LOGV("track %d u=%08x, s=%08x [OK]", track->name(), cblk->user, cblk->server);
+
+                    // compute volume for this track
+                    int16_t left, right;
+                    if (track->isMuted() || mMasterMute || track->isPausing()) {
+                        left = right = 0;
+                        if (track->isPausing()) {
+                            LOGV("paused(%d)", track->name());
+                            track->setPaused();
+                        }
+                    } else {
+                        float typeVolume = mStreamTypes[track->type()].volume;
+                        float v = mMasterVolume * typeVolume;
+                        float v_clamped = v * cblk->volume[0];
+                        if (v_clamped > MAX_GAIN) v_clamped = MAX_GAIN;
+                        left = int16_t(v_clamped);
+                        v_clamped = v * cblk->volume[1];
+                        if (v_clamped > MAX_GAIN) v_clamped = MAX_GAIN;
+                        right = int16_t(v_clamped);
+                    }
+
+                    // XXX: these things DON'T need to be done each time
+                    mAudioMixer->setBufferProvider(track);
+                    mAudioMixer->enable(AudioMixer::MIXING);
+
+                    int param;
+                    if ( track->mFillingUpStatus == Track::FS_FILLED) {
+                        // no ramp for the first volume setting
+                        track->mFillingUpStatus = Track::FS_ACTIVE;
+                        if (track->mState == TrackBase::RESUMING) {
+                            track->mState = TrackBase::ACTIVE;
+                            param = AudioMixer::RAMP_VOLUME;
+                        } else {
+                            param = AudioMixer::VOLUME;
+                        }
+                    } else {
+                        param = AudioMixer::RAMP_VOLUME;
+                    }
+                    mAudioMixer->setParameter(param, AudioMixer::VOLUME0, left);
+                    mAudioMixer->setParameter(param, AudioMixer::VOLUME1, right);
+                    mAudioMixer->setParameter(
+                        AudioMixer::TRACK,
+                        AudioMixer::FORMAT, track->format());
+                    mAudioMixer->setParameter(
+                        AudioMixer::TRACK,
+                        AudioMixer::CHANNEL_COUNT, track->channelCount());
+                    mAudioMixer->setParameter(
+                        AudioMixer::RESAMPLE,
+                        AudioMixer::SAMPLE_RATE,
+                        int(cblk->sampleRate));
+
+                    // reset retry count
+                    track->mRetryCount = kMaxTrackRetries;
+                    enabledTracks++;
+                } else {
+                    //LOGV("track %d u=%08x, s=%08x [NOT READY]", track->name(), cblk->user, cblk->server);
+                    if (track->isStopped()) {
+                        track->reset();
+                    }
+                    if (track->isTerminated() || track->isStopped() || track->isPaused()) {
+                        // We have consumed all the buffers of this track.
+                        // Remove it from the list of active tracks.
+                        LOGV("remove(%d) from active list", track->name());
+                        tracksToRemove.add(track);
+                    } else {
+                        // No buffers for this track. Give it a few chances to
+                        // fill a buffer, then remove it from active list.
+                        if (--(track->mRetryCount) <= 0) {
+                            LOGV("BUFFER TIMEOUT: remove(%d) from active list", track->name());
+                            tracksToRemove.add(track);
+                        }
+                    }
+                    // LOGV("disable(%d)", track->name());
+                    mAudioMixer->disable(AudioMixer::MIXING);
+                }
+            }
+
+            // remove all the tracks that need to be...
+            count = tracksToRemove.size();
+            if (UNLIKELY(count)) {
+                for (size_t i=0 ; i<count ; i++) {
+                    const sp<Track>& track = tracksToRemove[i];
+                    removeActiveTrack_l(track);
+                    if (track->isTerminated()) {
+                        mTracks.remove(track);
+                        deleteTrackName_l(track->mName);
+                    }
+                }
+            }
+       }
+        
+        if (LIKELY(enabledTracks)) {
+            // mix buffers...
+            mAudioMixer->process(curBuf);
+
+#ifdef WITH_A2DP
+            if (mOutputTrack != NULL && mAudioFlinger->isA2dpEnabled()) {
+                if (!outputTrackActive) {
+                    LOGV("starting output track in mixer for output %d", mOutputType);
+                    mOutputTrack->start();
+                    outputTrackActive = true;
+                }
+                mOutputTrack->write(curBuf, mFrameCount);
+            }
+#endif
+
+            // output audio to hardware
+            mLastWriteTime = systemTime();
+            mInWrite = true;
+            mOutput->write(curBuf, mixBufferSize);
+            mNumWrites++;
+            mInWrite = false;
+            mStandby = false;
+            nsecs_t temp = systemTime();
+            standbyTime = temp + kStandbyTimeInNsecs;
+            nsecs_t delta = temp - mLastWriteTime;
+            if (delta > maxPeriod) {
+                LOGW("write blocked for %llu msecs", ns2ms(delta));
+                mNumDelayedWrites++;
+            }
+            sleepTime = kBufferRecoveryInUsecs;
+        } else {         
+#ifdef WITH_A2DP
+            if (mOutputTrack != NULL && mAudioFlinger->isA2dpEnabled()) {
+                if (outputTrackActive) {
+                    mOutputTrack->write(curBuf, 0);
+                    if (mOutputTrack->bufferQueueEmpty()) {
+                        mOutputTrack->stop();
+                        outputTrackActive = false;
+                    } else {
+                        standbyTime = systemTime() + kStandbyTimeInNsecs;
+                    }
+                }
+            }
+#endif
+            // There was nothing to mix this round, which means all
+            // active tracks were late. Sleep a little bit to give
+            // them another chance. If we're too late, the audio
+            // hardware will zero-fill for us.
+            //LOGV("no buffers - usleep(%lu)", sleepTime);
+            usleep(sleepTime);
+            if (sleepTime < kMaxBufferRecoveryInUsecs) {
+                sleepTime += kBufferRecoveryInUsecs;
+            }
+        }
+
+        // finally let go of all our tracks, without the lock held
+        // since we can't guarantee the destructors won't acquire that
+        // same lock.
+        tracksToRemove.clear();
+    } while (true);
+
+    return false;
+}
+
+status_t AudioFlinger::MixerThread::readyToRun()
+{
+    if (mSampleRate == 0) {
+        LOGE("No working audio driver found.");
+        return NO_INIT;
+    }
+    LOGI("AudioFlinger's thread ready to run for output %d", mOutputType);
+    return NO_ERROR;
+}
+
+void AudioFlinger::MixerThread::onFirstRef()
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+
+    snprintf(buffer, SIZE, "Mixer Thread for output %d", mOutputType);
+
+    run(buffer, ANDROID_PRIORITY_URGENT_AUDIO);
+}
+
+// MixerThread::createTrack_l() must be called with AudioFlinger::mLock held
+sp<AudioFlinger::MixerThread::Track>  AudioFlinger::MixerThread::createTrack_l(
+        const sp<AudioFlinger::Client>& client,
+        int streamType,
+        uint32_t sampleRate,
+        int format,
+        int channelCount,
+        int frameCount,
+        const sp<IMemory>& sharedBuffer,
+        status_t *status)
+{
+    sp<Track> track;
+    status_t lStatus;
+    
+    // Resampler implementation limits input sampling rate to 2 x output sampling rate.
+    if (sampleRate > MAX_SAMPLE_RATE || sampleRate > mSampleRate*2) {
+        LOGE("Sample rate out of range: %d mSampleRate %d", sampleRate, mSampleRate);
+        lStatus = BAD_VALUE;
+        goto Exit;
+    }
+
+
+    if (mSampleRate == 0) {
+        LOGE("Audio driver not initialized.");
+        lStatus = NO_INIT;
+        goto Exit;
+    }
+
+    track = new Track(this, client, streamType, sampleRate, format,
+            channelCount, frameCount, sharedBuffer);
+    if (track->getCblk() == NULL) {
+        lStatus = NO_MEMORY;
+        goto Exit;
+    }
+    mTracks.add(track);
+    lStatus = NO_ERROR;
+
+Exit:
+    if(status) {
+        *status = lStatus;
+    }
+    return track;
+}
+
+// getTracks_l() must be called with AudioFlinger::mLock held
+void AudioFlinger::MixerThread::getTracks_l(
+        SortedVector < sp<Track> >& tracks,
+        SortedVector < wp<Track> >& activeTracks)
+{
+    size_t size = mTracks.size();
+    LOGV ("MixerThread::getTracks_l() for output %d, mTracks.size %d, mActiveTracks.size %d", mOutputType,  mTracks.size(), mActiveTracks.size());
+    for (size_t i = 0; i < size; i++) {
+        sp<Track> t = mTracks[i];
+        if (AudioSystem::routedToA2dpOutput(t->mStreamType)) {
+            tracks.add(t);
+            int j = mActiveTracks.indexOf(t);
+            if (j >= 0) {
+                t = mActiveTracks[j].promote();
+                if (t != NULL) {
+                    activeTracks.add(t);                                    
+                }                            
+            }
+        }
+    }
+
+    size = activeTracks.size();
+    for (size_t i = 0; i < size; i++) {
+        removeActiveTrack_l(activeTracks[i]);
+    }
+    
+    size = tracks.size();
+    for (size_t i = 0; i < size; i++) {
+        sp<Track> t = tracks[i];
+        mTracks.remove(t);
+        deleteTrackName_l(t->name());
+    }
+}
+
+// putTracks_l() must be called with AudioFlinger::mLock held
+void AudioFlinger::MixerThread::putTracks_l(
+        SortedVector < sp<Track> >& tracks,
+        SortedVector < wp<Track> >& activeTracks)
+{
+
+    LOGV ("MixerThread::putTracks_l() for output %d, tracks.size %d, activeTracks.size %d", mOutputType,  tracks.size(), activeTracks.size());
+
+    size_t size = tracks.size();
+    for (size_t i = 0; i < size ; i++) {
+        sp<Track> t = tracks[i];
+        int name = getTrackName_l();
+
+        if (name < 0) return;
+        
+        t->mName = name;
+        t->mMixerThread = this;
+        mTracks.add(t);
+
+        int j = activeTracks.indexOf(t);
+        if (j >= 0) {
+            addActiveTrack_l(t);
+        }            
+    }
+}
+
+uint32_t AudioFlinger::MixerThread::sampleRate() const
+{
+    return mSampleRate;
+}
+
+int AudioFlinger::MixerThread::channelCount() const
+{
+    return mChannelCount;
+}
+
+int AudioFlinger::MixerThread::format() const
+{
+    return mFormat;
+}
+
+size_t AudioFlinger::MixerThread::frameCount() const
+{
+    return mFrameCount;
+}
+
+uint32_t AudioFlinger::MixerThread::latency() const
+{
+    if (mOutput) {
+        return mOutput->latency();
+    }
+    else {
+        return 0;
+    }
+}
+
+status_t AudioFlinger::MixerThread::setMasterVolume(float value)
+{
+    mMasterVolume = value;
+    return NO_ERROR;
+}
+
+status_t AudioFlinger::MixerThread::setMasterMute(bool muted)
+{
+    mMasterMute = muted;
+    return NO_ERROR;
+}
+
+float AudioFlinger::MixerThread::masterVolume() const
+{
+    return mMasterVolume;
+}
+
+bool AudioFlinger::MixerThread::masterMute() const
+{
+    return mMasterMute;
+}
+
+status_t AudioFlinger::MixerThread::setStreamVolume(int stream, float value)
+{
+    mStreamTypes[stream].volume = value;
+    return NO_ERROR;
+}
+
+status_t AudioFlinger::MixerThread::setStreamMute(int stream, bool muted)
+{
+    mStreamTypes[stream].mute = muted;
+    return NO_ERROR;
+}
+
+float AudioFlinger::MixerThread::streamVolume(int stream) const
+{
+    return mStreamTypes[stream].volume;
+}
+
+bool AudioFlinger::MixerThread::streamMute(int stream) const
+{
+    return mStreamTypes[stream].mute;
+}
+
+bool AudioFlinger::MixerThread::isMusicActive() const
+{
+    size_t count = mActiveTracks.size();
+    for (size_t i = 0 ; i < count ; ++i) {
+        sp<Track> t = mActiveTracks[i].promote();
+        if (t == 0) continue;
+        Track* const track = t.get();
+        if (t->mStreamType == AudioSystem::MUSIC)
+            return true;
+    }
+    return false;
+}
+
+// addTrack_l() must be called with AudioFlinger::mLock held
+status_t AudioFlinger::MixerThread::addTrack_l(const sp<Track>& track)
+{
+    status_t status = ALREADY_EXISTS;
 
     // here the track could be either new, or restarted
     // in both cases "unstop" the track
@@ -903,139 +1464,135 @@
     }
     // set retry count for buffer fill
     track->mRetryCount = kMaxTrackStartupRetries;
-    LOGV("mWaitWorkCV.broadcast");
-    mWaitWorkCV.broadcast();
-
     if (mActiveTracks.indexOf(track) < 0) {
         // the track is newly added, make sure it fills up all its
         // buffers before playing. This is to ensure the client will
         // effectively get the latency it requested.
         track->mFillingUpStatus = Track::FS_FILLING;
         track->mResetDone = false;
-        addActiveTrack(track);
-        return NO_ERROR;
+        addActiveTrack_l(track);
+        status = NO_ERROR;
     }
-    return ALREADY_EXISTS;
+    
+    LOGV("mWaitWorkCV.broadcast");
+    mAudioFlinger->mWaitWorkCV.broadcast();
+
+    return status;
 }
 
-void AudioFlinger::removeTrack(wp<Track> track, int name)
+// removeTrack_l() must be called with AudioFlinger::mLock held
+void AudioFlinger::MixerThread::removeTrack_l(wp<Track> track, int name)
 {
-    Mutex::Autolock _l(mLock);
     sp<Track> t = track.promote();
     if (t!=NULL && (t->mState <= TrackBase::STOPPED)) {
-        remove_track_l(track, name);
-    }
-}
-
-void AudioFlinger::remove_track_l(wp<Track> track, int name)
-{
-    sp<Track> t = track.promote();
-    if (t!=NULL) {
         t->reset();
+        deleteTrackName_l(name);
+        removeActiveTrack_l(track);
+        mAudioFlinger->mWaitWorkCV.broadcast();
     }
-    audioMixer()->deleteTrackName(name);
-    removeActiveTrack(track);
-    mWaitWorkCV.broadcast();
 }
 
-void AudioFlinger::destroyTrack(const sp<Track>& track)
+// destroyTrack_l() must be called with AudioFlinger::mLock held
+void AudioFlinger::MixerThread::destroyTrack_l(const sp<Track>& track)
 {
-    // NOTE: We're acquiring a strong reference on the track before
-    // acquiring the lock, this is to make sure removing it from
-    // mTracks won't cause the destructor to be called while the lock is
-    // held (note that technically, 'track' could be a reference to an item
-    // in mTracks, which is why we need to do this).
-    sp<Track> keep(track);
-    Mutex::Autolock _l(mLock);
     track->mState = TrackBase::TERMINATED;
     if (mActiveTracks.indexOf(track) < 0) {
         LOGV("remove track (%d) and delete from mixer", track->name());
         mTracks.remove(track);
-        audioMixer()->deleteTrackName(keep->name());
+        deleteTrackName_l(track->name());
     }
 }
 
-void AudioFlinger::addActiveTrack(const wp<Track>& t)
+// addActiveTrack_l() must be called with AudioFlinger::mLock held
+void AudioFlinger::MixerThread::addActiveTrack_l(const wp<Track>& t)
 {
     mActiveTracks.add(t);
 
+    // Force routing to speaker for certain stream types
+    // The forced routing to speaker is managed by hardware mixer
+    if (mOutputType == AudioSystem::AUDIO_OUTPUT_HARDWARE) {
+        sp<Track> track = t.promote();
+        if (track == NULL) return;
+   
+        if (streamForcedToSpeaker(track->type())) {
+            mAudioFlinger->handleForcedSpeakerRoute(ACTIVE_TRACK_ADDED);
+        }        
 #ifdef WITH_A2DP
-    // disable A2DP for certain stream types
-    sp<Track> track = t.promote();
-    if (streamDisablesA2dp(track->type())) {
-        if (mA2dpDisableCount++ == 0 && isA2dpEnabled()) {
-            setA2dpEnabled(false);
-            mA2dpSuppressed = true;
-            LOGD("mA2dpSuppressed = true\n");
+        // AudioFlinger::mLock must be locked before calling
+        // handleStreamDisablesA2dp_l because it calls setA2dpEnabled_l().
+        if (streamDisablesA2dp(track->type())) {
+            mAudioFlinger->handleStreamDisablesA2dp_l(ACTIVE_TRACK_ADDED);
         }
-        LOGD("mA2dpDisableCount incremented to %d\n", mA2dpDisableCount);
-    }
 #endif
+    }
 }
 
-void AudioFlinger::removeActiveTrack(const wp<Track>& t)
+// removeActiveTrack_l() must be called with AudioFlinger::mLock held
+void AudioFlinger::MixerThread::removeActiveTrack_l(const wp<Track>& t)
 {
     mActiveTracks.remove(t);
+
+    // Force routing to speaker for certain stream types
+    // The forced routing to speaker is managed by hardware mixer
+    if (mOutputType == AudioSystem::AUDIO_OUTPUT_HARDWARE) {
+        sp<Track> track = t.promote();
+        if (track == NULL) return;
+
+        if (streamForcedToSpeaker(track->type())) {
+            mAudioFlinger->handleForcedSpeakerRoute(ACTIVE_TRACK_REMOVED);
+        }
 #ifdef WITH_A2DP
-    // disable A2DP for certain stream types
-    sp<Track> track = t.promote();
-    if (streamDisablesA2dp(track->type())) {
-        if (mA2dpDisableCount > 0) {
-            mA2dpDisableCount--;
-            if (mA2dpDisableCount == 0 && mA2dpSuppressed) {
-                setA2dpEnabled(true);
-                mA2dpSuppressed = false;
-            }
-            LOGD("mA2dpDisableCount decremented to %d\n", mA2dpDisableCount);
-        } else
-            LOGE("mA2dpDisableCount is already zero");
-    }
+        // AudioFlinger::mLock must be locked before calling
+        // handleStreamDisablesA2dp_l because it calls setA2dpEnabled_l().
+        if (streamDisablesA2dp(track->type())) {
+            mAudioFlinger->handleStreamDisablesA2dp_l(ACTIVE_TRACK_REMOVED);
+        }
 #endif
+    }
+}
+
+// getTrackName_l() must be called with AudioFlinger::mLock held
+int AudioFlinger::MixerThread::getTrackName_l()
+{
+    return mAudioMixer->getTrackName();
+}
+
+// deleteTrackName_l() must be called with AudioFlinger::mLock held
+void AudioFlinger::MixerThread::deleteTrackName_l(int name)
+{
+    mAudioMixer->deleteTrackName(name);
+}
+
+size_t AudioFlinger::MixerThread::getOutputFrameCount() 
+{
+    return mOutput->bufferSize() / mOutput->channelCount() / sizeof(int16_t);
 }
 
 // ----------------------------------------------------------------------------
 
-AudioFlinger::Client::Client(const sp<AudioFlinger>& audioFlinger, pid_t pid)
-    :   RefBase(),
-        mAudioFlinger(audioFlinger),
-        mMemoryDealer(new MemoryDealer(1024*1024)),
-        mPid(pid)
-{
-    // 1 MB of address space is good for 32 tracks, 8 buffers each, 4 KB/buffer
-}
-
-AudioFlinger::Client::~Client()
-{
-    mAudioFlinger->removeClient(mPid);
-}
-
-const sp<MemoryDealer>& AudioFlinger::Client::heap() const
-{
-    return mMemoryDealer;
-}
-
-// ----------------------------------------------------------------------------
-
-AudioFlinger::TrackBase::TrackBase(
-            const sp<AudioFlinger>& audioFlinger,
+// TrackBase constructor must be called with AudioFlinger::mLock held
+AudioFlinger::MixerThread::TrackBase::TrackBase(
+            const sp<MixerThread>& mixerThread,
             const sp<Client>& client,
             int streamType,
             uint32_t sampleRate,
             int format,
             int channelCount,
             int frameCount,
+            uint32_t flags,
             const sp<IMemory>& sharedBuffer)
     :   RefBase(),
-        mAudioFlinger(audioFlinger),
+        mMixerThread(mixerThread),
         mClient(client),
         mStreamType(streamType),
         mFrameCount(0),
         mState(IDLE),
         mClientTid(-1),
         mFormat(format),
-        mFlags(0)
+        mFlags(flags & ~SYSTEM_FLAGS_MASK)
 {
-    mName = audioFlinger->audioMixer()->getTrackName();
+    mName = mixerThread->getTrackName_l();
+    LOGV("TrackBase contructor name %d, calling thread %d", mName, IPCThreadState::self()->getCallingPid());
     if (mName < 0) {
         LOGE("no more track names availlable");
         return;
@@ -1043,7 +1600,6 @@
 
     LOGV_IF(sharedBuffer != 0, "sharedBuffer: %p, size: %d", sharedBuffer->pointer(), sharedBuffer->size());
 
-
     // LOGD("Creating track with %d buffers @ %d bytes", bufferCount, bufferSize);
    size_t size = sizeof(audio_track_cblk_t);
    size_t bufferSize = frameCount*channelCount*sizeof(int16_t);
@@ -1051,41 +1607,60 @@
        size += bufferSize;
    }
 
-    mCblkMemory = client->heap()->allocate(size);
-    if (mCblkMemory != 0) {
-        mCblk = static_cast<audio_track_cblk_t *>(mCblkMemory->pointer());
-        if (mCblk) { // construct the shared structure in-place.
-            new(mCblk) audio_track_cblk_t();
-            // clear all buffers
-            mCblk->frameCount = frameCount;
-            mCblk->sampleRate = sampleRate;
-            mCblk->channels = channelCount;
-            if (sharedBuffer == 0) {
-                mBuffer = (char*)mCblk + sizeof(audio_track_cblk_t);
-                memset(mBuffer, 0, frameCount*channelCount*sizeof(int16_t));
-                // Force underrun condition to avoid false underrun callback until first data is
-                // written to buffer
-                mCblk->flowControlFlag = 1;
-            } else {
-                mBuffer = sharedBuffer->pointer();
+   if (client != NULL) {
+        mCblkMemory = client->heap()->allocate(size);
+        if (mCblkMemory != 0) {
+            mCblk = static_cast<audio_track_cblk_t *>(mCblkMemory->pointer());
+            if (mCblk) { // construct the shared structure in-place.
+                new(mCblk) audio_track_cblk_t();
+                // clear all buffers
+                mCblk->frameCount = frameCount;
+                mCblk->sampleRate = sampleRate;
+                mCblk->channels = channelCount;
+                if (sharedBuffer == 0) {
+                    mBuffer = (char*)mCblk + sizeof(audio_track_cblk_t);
+                    memset(mBuffer, 0, frameCount*channelCount*sizeof(int16_t));
+                    // Force underrun condition to avoid false underrun callback until first data is
+                    // written to buffer
+                    mCblk->flowControlFlag = 1;
+                } else {
+                    mBuffer = sharedBuffer->pointer();
+                }
+                mBufferEnd = (uint8_t *)mBuffer + bufferSize;
             }
-            mBufferEnd = (uint8_t *)mBuffer + bufferSize;
+        } else {
+            LOGE("not enough memory for AudioTrack size=%u", size);
+            client->heap()->dump("AudioTrack");
+            return;
         }
-    } else {
-        LOGE("not enough memory for AudioTrack size=%u", size);
-        client->heap()->dump("AudioTrack");
-        return;
-    }
+   } else {
+       mCblk = (audio_track_cblk_t *)(new uint8_t[size]);
+       if (mCblk) { // construct the shared structure in-place.
+           new(mCblk) audio_track_cblk_t();
+           // clear all buffers
+           mCblk->frameCount = frameCount;
+           mCblk->sampleRate = sampleRate;
+           mCblk->channels = channelCount;
+           mBuffer = (char*)mCblk + sizeof(audio_track_cblk_t);
+           memset(mBuffer, 0, frameCount*channelCount*sizeof(int16_t));
+           // Force underrun condition to avoid false underrun callback until first data is
+           // written to buffer
+           mCblk->flowControlFlag = 1;
+           mBufferEnd = (uint8_t *)mBuffer + bufferSize;
+       }
+   }
 }
 
-AudioFlinger::TrackBase::~TrackBase()
+AudioFlinger::MixerThread::TrackBase::~TrackBase()
 {
-    mCblk->~audio_track_cblk_t();   // destroy our shared-structure.
+    if (mCblk) {
+        mCblk->~audio_track_cblk_t();   // destroy our shared-structure.        
+    }
     mCblkMemory.clear();            // and free the shared memory
     mClient.clear();
 }
 
-void AudioFlinger::TrackBase::releaseBuffer(AudioBufferProvider::Buffer* buffer)
+void AudioFlinger::MixerThread::TrackBase::releaseBuffer(AudioBufferProvider::Buffer* buffer)
 {
     buffer->raw = 0;
     mFrameCount = buffer->frameCount;
@@ -1093,7 +1668,7 @@
     buffer->frameCount = 0;
 }
 
-bool AudioFlinger::TrackBase::step() {
+bool AudioFlinger::MixerThread::TrackBase::step() {
     bool result;
     audio_track_cblk_t* cblk = this->cblk();
 
@@ -1105,31 +1680,31 @@
     return result;
 }
 
-void AudioFlinger::TrackBase::reset() {
+void AudioFlinger::MixerThread::TrackBase::reset() {
     audio_track_cblk_t* cblk = this->cblk();
 
     cblk->user = 0;
     cblk->server = 0;
     cblk->userBase = 0;
     cblk->serverBase = 0;
-    mFlags = 0;
+    mFlags &= (uint32_t)(~SYSTEM_FLAGS_MASK);
     LOGV("TrackBase::reset");
 }
 
-sp<IMemory> AudioFlinger::TrackBase::getCblk() const
+sp<IMemory> AudioFlinger::MixerThread::TrackBase::getCblk() const
 {
     return mCblkMemory;
 }
 
-int AudioFlinger::TrackBase::sampleRate() const {
+int AudioFlinger::MixerThread::TrackBase::sampleRate() const {
     return mCblk->sampleRate;
 }
 
-int AudioFlinger::TrackBase::channelCount() const {
+int AudioFlinger::MixerThread::TrackBase::channelCount() const {
     return mCblk->channels;
 }
 
-void* AudioFlinger::TrackBase::getBuffer(uint32_t offset, uint32_t frames) const {
+void* AudioFlinger::MixerThread::TrackBase::getBuffer(uint32_t offset, uint32_t frames) const {
     audio_track_cblk_t* cblk = this->cblk();
     int16_t *bufferStart = (int16_t *)mBuffer + (offset-cblk->serverBase)*cblk->channels;
     int16_t *bufferEnd = bufferStart + frames * cblk->channels;
@@ -1148,8 +1723,9 @@
 
 // ----------------------------------------------------------------------------
 
-AudioFlinger::Track::Track(
-            const sp<AudioFlinger>& audioFlinger,
+// Track constructor must be called with AudioFlinger::mLock held
+AudioFlinger::MixerThread::Track::Track(
+            const sp<MixerThread>& mixerThread,
             const sp<Client>& client,
             int streamType,
             uint32_t sampleRate,
@@ -1157,7 +1733,7 @@
             int channelCount,
             int frameCount,
             const sp<IMemory>& sharedBuffer)
-    :   TrackBase(audioFlinger, client, streamType, sampleRate, format, channelCount, frameCount, sharedBuffer)
+    :   TrackBase(mixerThread, client, streamType, sampleRate, format, channelCount, frameCount, 0, sharedBuffer)
 {
     mVolume[0] = 1.0f;
     mVolume[1] = 1.0f;
@@ -1165,23 +1741,36 @@
     mSharedBuffer = sharedBuffer;
 }
 
-AudioFlinger::Track::~Track()
+AudioFlinger::MixerThread::Track::~Track()
 {
     wp<Track> weak(this); // never create a strong ref from the dtor
+    Mutex::Autolock _l(mMixerThread->mAudioFlinger->mLock);
     mState = TERMINATED;
-    mAudioFlinger->removeTrack(weak, mName);
+    mMixerThread->removeTrack_l(weak, mName);
 }
 
-void AudioFlinger::Track::destroy()
+void AudioFlinger::MixerThread::Track::destroy()
 {
-    mAudioFlinger->destroyTrack(this);
+    // NOTE: destroyTrack_l() can remove a strong reference to this Track 
+    // by removing it from mTracks vector, so there is a risk that this Tracks's
+    // desctructor is called. As the destructor needs to lock AudioFlinger::mLock,
+    // we must acquire a strong reference on this Track before locking AudioFlinger::mLock
+    // here so that the destructor is called only when exiting this function.
+    // On the other hand, as long as Track::destroy() is only called by 
+    // TrackHandle destructor, the TrackHandle still holds a strong ref on 
+    // this Track with its member mTrack.
+    sp<Track> keep(this);
+    { // scope for AudioFlinger::mLock
+        Mutex::Autolock _l(mMixerThread->mAudioFlinger->mLock);
+        mMixerThread->destroyTrack_l(this);
+    }
 }
 
-void AudioFlinger::Track::dump(char* buffer, size_t size)
+void AudioFlinger::MixerThread::Track::dump(char* buffer, size_t size)
 {
     snprintf(buffer, size, "  %5d %5d %3u %3u %3u %3u %1d %1d %1d %5u %5u %5u %04x %04x\n",
             mName - AudioMixer::TRACK0,
-            mClient->pid(),
+            (mClient == NULL) ? getpid() : mClient->pid(),
             mStreamType,
             mFormat,
             mCblk->channels,
@@ -1196,7 +1785,7 @@
             mCblk->user);
 }
 
-status_t AudioFlinger::Track::getNextBuffer(AudioBufferProvider::Buffer* buffer)
+status_t AudioFlinger::MixerThread::Track::getNextBuffer(AudioBufferProvider::Buffer* buffer)
 {
      audio_track_cblk_t* cblk = this->cblk();
      uint32_t framesReady;
@@ -1236,53 +1825,55 @@
      return NOT_ENOUGH_DATA;
 }
 
-bool AudioFlinger::Track::isReady() const {
+bool AudioFlinger::MixerThread::Track::isReady() const {
     if (mFillingUpStatus != FS_FILLING) return true;
 
     if (mCblk->framesReady() >= mCblk->frameCount ||
         mCblk->forceReady) {
         mFillingUpStatus = FS_FILLED;
         mCblk->forceReady = 0;
+        LOGV("Track::isReady() track %d for output %d", mName, mMixerThread->mOutputType);
         return true;
     }
     return false;
 }
 
-status_t AudioFlinger::Track::start()
+status_t AudioFlinger::MixerThread::Track::start()
 {
-    LOGV("start(%d)", mName);
-    mAudioFlinger->addTrack(this);
+    LOGV("start(%d), calling thread %d for output %d", mName, IPCThreadState::self()->getCallingPid(), mMixerThread->mOutputType);
+    Mutex::Autolock _l(mMixerThread->mAudioFlinger->mLock);
+    mMixerThread->addTrack_l(this);
     return NO_ERROR;
 }
 
-void AudioFlinger::Track::stop()
+void AudioFlinger::MixerThread::Track::stop()
 {
-    LOGV("stop(%d)", mName);
-    Mutex::Autolock _l(mAudioFlinger->mLock);
+    LOGV("stop(%d), calling thread %d for output %d", mName, IPCThreadState::self()->getCallingPid(), mMixerThread->mOutputType);
+    Mutex::Autolock _l(mMixerThread->mAudioFlinger->mLock);
     if (mState > STOPPED) {
         mState = STOPPED;
         // If the track is not active (PAUSED and buffers full), flush buffers
-        if (mAudioFlinger->mActiveTracks.indexOf(this) < 0) {
+        if (mMixerThread->mActiveTracks.indexOf(this) < 0) {
             reset();
         }
         LOGV("(> STOPPED) => STOPPED (%d)", mName);
     }
 }
 
-void AudioFlinger::Track::pause()
+void AudioFlinger::MixerThread::Track::pause()
 {
-    LOGV("pause(%d)", mName);
-    Mutex::Autolock _l(mAudioFlinger->mLock);
+    LOGV("pause(%d), calling thread %d", mName, IPCThreadState::self()->getCallingPid());
+    Mutex::Autolock _l(mMixerThread->mAudioFlinger->mLock);
     if (mState == ACTIVE || mState == RESUMING) {
         mState = PAUSING;
         LOGV("ACTIVE/RESUMING => PAUSING (%d)", mName);
     }
 }
 
-void AudioFlinger::Track::flush()
+void AudioFlinger::MixerThread::Track::flush()
 {
     LOGV("flush(%d)", mName);
-    Mutex::Autolock _l(mAudioFlinger->mLock);
+    Mutex::Autolock _l(mMixerThread->mAudioFlinger->mLock);
     if (mState != STOPPED && mState != PAUSED && mState != PAUSING) {
         return;
     }
@@ -1298,7 +1889,7 @@
     reset();
 }
 
-void AudioFlinger::Track::reset()
+void AudioFlinger::MixerThread::Track::reset()
 {
     // Do not reset twice to avoid discarding data written just after a flush and before
     // the audioflinger thread detects the track is stopped.
@@ -1313,12 +1904,12 @@
     }
 }
 
-void AudioFlinger::Track::mute(bool muted)
+void AudioFlinger::MixerThread::Track::mute(bool muted)
 {
     mMute = muted;
 }
 
-void AudioFlinger::Track::setVolume(float left, float right)
+void AudioFlinger::MixerThread::Track::setVolume(float left, float right)
 {
     mVolume[0] = left;
     mVolume[1] = right;
@@ -1326,7 +1917,292 @@
 
 // ----------------------------------------------------------------------------
 
-AudioFlinger::TrackHandle::TrackHandle(const sp<AudioFlinger::Track>& track)
+// RecordTrack constructor must be called with AudioFlinger::mLock held
+AudioFlinger::MixerThread::RecordTrack::RecordTrack(
+            const sp<MixerThread>& mixerThread,
+            const sp<Client>& client,
+            int streamType,
+            uint32_t sampleRate,
+            int format,
+            int channelCount,
+            int frameCount,
+            uint32_t flags)
+    :   TrackBase(mixerThread, client, streamType, sampleRate, format,
+                  channelCount, frameCount, flags, 0),
+        mOverflow(false)
+{
+}
+
+AudioFlinger::MixerThread::RecordTrack::~RecordTrack()
+{
+    Mutex::Autolock _l(mMixerThread->mAudioFlinger->mLock);
+    mMixerThread->deleteTrackName_l(mName);
+}
+
+status_t AudioFlinger::MixerThread::RecordTrack::getNextBuffer(AudioBufferProvider::Buffer* buffer)
+{
+    audio_track_cblk_t* cblk = this->cblk();
+    uint32_t framesAvail;
+    uint32_t framesReq = buffer->frameCount;
+
+     // Check if last stepServer failed, try to step now
+    if (mFlags & TrackBase::STEPSERVER_FAILED) {
+        if (!step()) goto getNextBuffer_exit;
+        LOGV("stepServer recovered");
+        mFlags &= ~TrackBase::STEPSERVER_FAILED;
+    }
+
+    framesAvail = cblk->framesAvailable_l();
+
+    if (LIKELY(framesAvail)) {
+        uint32_t s = cblk->server;
+        uint32_t bufferEnd = cblk->serverBase + cblk->frameCount;
+
+        if (framesReq > framesAvail) {
+            framesReq = framesAvail;
+        }
+        if (s + framesReq > bufferEnd) {
+            framesReq = bufferEnd - s;
+        }
+
+        buffer->raw = getBuffer(s, framesReq);
+        if (buffer->raw == 0) goto getNextBuffer_exit;
+
+        buffer->frameCount = framesReq;
+        return NO_ERROR;
+    }
+
+getNextBuffer_exit:
+    buffer->raw = 0;
+    buffer->frameCount = 0;
+    return NOT_ENOUGH_DATA;
+}
+
+status_t AudioFlinger::MixerThread::RecordTrack::start()
+{
+    return mMixerThread->mAudioFlinger->startRecord(this);
+}
+
+void AudioFlinger::MixerThread::RecordTrack::stop()
+{
+    mMixerThread->mAudioFlinger->stopRecord(this);
+    TrackBase::reset();
+    // Force overerrun condition to avoid false overrun callback until first data is
+    // read from buffer
+    mCblk->flowControlFlag = 1;
+}
+
+
+// ----------------------------------------------------------------------------
+
+AudioFlinger::MixerThread::OutputTrack::OutputTrack(
+            const sp<MixerThread>& mixerThread,
+            uint32_t sampleRate,
+            int format,
+            int channelCount,
+            int frameCount)
+    :   Track(mixerThread, NULL, AudioSystem::SYSTEM, sampleRate, format, channelCount, frameCount, NULL),
+    mOutputMixerThread(mixerThread)
+{
+                
+    mCblk->out = 1;
+    mCblk->buffers = (char*)mCblk + sizeof(audio_track_cblk_t);
+    mCblk->volume[0] = mCblk->volume[1] = 0x1000;
+    mOutBuffer.frameCount = 0;
+    mCblk->bufferTimeoutMs = 10;
+    
+    LOGV("OutputTrack constructor mCblk %p, mBuffer %p, mCblk->buffers %p, mCblk->frameCount %d, mCblk->sampleRate %d, mCblk->channels %d mBufferEnd %p", 
+            mCblk, mBuffer, mCblk->buffers, mCblk->frameCount, mCblk->sampleRate, mCblk->channels, mBufferEnd);
+    
+}
+
+AudioFlinger::MixerThread::OutputTrack::~OutputTrack()
+{
+    stop();
+}
+
+status_t AudioFlinger::MixerThread::OutputTrack::start()
+{
+    status_t status = Track::start();
+    
+    mRetryCount = 127;
+    return status;
+}
+
+void AudioFlinger::MixerThread::OutputTrack::stop()
+{
+    Track::stop();
+    clearBufferQueue();
+    mOutBuffer.frameCount = 0;
+}
+
+void AudioFlinger::MixerThread::OutputTrack::write(int16_t* data, uint32_t frames)
+{
+    Buffer *pInBuffer;
+    Buffer inBuffer;
+    uint32_t channels = mCblk->channels;
+        
+    inBuffer.frameCount = frames;
+    inBuffer.i16 = data;
+    
+    if (mCblk->user == 0) {
+        if (mOutputMixerThread->isMusicActive()) {
+            mCblk->forceReady = 1;
+            LOGV("OutputTrack::start() force ready");
+        } else if (mCblk->frameCount > frames){
+            if (mBufferQueue.size() < kMaxOutputTrackBuffers) {
+                uint32_t startFrames = (mCblk->frameCount - frames);
+                LOGV("OutputTrack::start() write %d frames", startFrames);
+                pInBuffer = new Buffer;
+                pInBuffer->mBuffer = new int16_t[startFrames * channels];
+                pInBuffer->frameCount = startFrames;
+                pInBuffer->i16 = pInBuffer->mBuffer;
+                memset(pInBuffer->raw, 0, startFrames * channels * sizeof(int16_t));
+                mBufferQueue.add(pInBuffer);                
+            } else {
+                LOGW ("OutputTrack::write() no more buffers");
+            }
+        }        
+    }
+
+    while (1) { 
+        // First write pending buffers, then new data
+        if (mBufferQueue.size()) {
+            pInBuffer = mBufferQueue.itemAt(0);
+        } else {
+            pInBuffer = &inBuffer;
+        }
+ 
+        if (pInBuffer->frameCount == 0) {
+            break;
+        }
+        
+        if (mOutBuffer.frameCount == 0) {
+            mOutBuffer.frameCount = pInBuffer->frameCount;
+            if (obtainBuffer(&mOutBuffer) == (status_t)AudioTrack::NO_MORE_BUFFERS) {
+                break;
+            }
+        }
+            
+        uint32_t outFrames = pInBuffer->frameCount > mOutBuffer.frameCount ? mOutBuffer.frameCount : pInBuffer->frameCount;
+        memcpy(mOutBuffer.raw, pInBuffer->raw, outFrames * channels * sizeof(int16_t));
+        mCblk->stepUser(outFrames);
+        pInBuffer->frameCount -= outFrames;
+        pInBuffer->i16 += outFrames * channels;
+        mOutBuffer.frameCount -= outFrames;
+        mOutBuffer.i16 += outFrames * channels;            
+        
+        if (pInBuffer->frameCount == 0) {
+            if (mBufferQueue.size()) {
+                mBufferQueue.removeAt(0);
+                delete [] pInBuffer->mBuffer;
+                delete pInBuffer;
+            } else {
+                break;
+            }
+        }
+    }
+ 
+    // If we could not write all frames, allocate a buffer and queue it for next time.
+    if (inBuffer.frameCount) {
+        if (mBufferQueue.size() < kMaxOutputTrackBuffers) {
+            pInBuffer = new Buffer;
+            pInBuffer->mBuffer = new int16_t[inBuffer.frameCount * channels];
+            pInBuffer->frameCount = inBuffer.frameCount;
+            pInBuffer->i16 = pInBuffer->mBuffer;
+            memcpy(pInBuffer->raw, inBuffer.raw, inBuffer.frameCount * channels * sizeof(int16_t));
+            mBufferQueue.add(pInBuffer);
+        } else {
+            LOGW("OutputTrack::write() no more buffers");
+        }
+    }
+    
+    // Calling write() with a 0 length buffer, means that no more data will be written:
+    // If no more buffers are pending, fill output track buffer to make sure it is started 
+    // by output mixer.
+    if (frames == 0 && mBufferQueue.size() == 0 && mCblk->user < mCblk->frameCount) {
+        frames = mCblk->frameCount - mCblk->user;
+        pInBuffer = new Buffer;
+        pInBuffer->mBuffer = new int16_t[frames * channels];
+        pInBuffer->frameCount = frames;
+        pInBuffer->i16 = pInBuffer->mBuffer;
+        memset(pInBuffer->raw, 0, frames * channels * sizeof(int16_t));
+        mBufferQueue.add(pInBuffer);
+    }
+
+}
+
+status_t AudioFlinger::MixerThread::OutputTrack::obtainBuffer(AudioBufferProvider::Buffer* buffer)
+{
+    int active;
+    int timeout = 0;
+    status_t result;
+    audio_track_cblk_t* cblk = mCblk;
+    uint32_t framesReq = buffer->frameCount;
+
+    LOGV("OutputTrack::obtainBuffer user %d, server %d", cblk->user, cblk->server);
+    buffer->frameCount  = 0;
+    
+    uint32_t framesAvail = cblk->framesAvailable();
+
+    if (framesAvail == 0) {
+        return AudioTrack::NO_MORE_BUFFERS;
+    }
+
+    if (framesReq > framesAvail) {
+        framesReq = framesAvail;
+    }
+
+    uint32_t u = cblk->user;
+    uint32_t bufferEnd = cblk->userBase + cblk->frameCount;
+
+    if (u + framesReq > bufferEnd) {
+        framesReq = bufferEnd - u;
+    }
+
+    buffer->frameCount  = framesReq;
+    buffer->raw         = (void *)cblk->buffer(u);
+    return NO_ERROR;
+}
+
+
+void AudioFlinger::MixerThread::OutputTrack::clearBufferQueue()
+{
+    size_t size = mBufferQueue.size();
+    Buffer *pBuffer;
+    
+    for (size_t i = 0; i < size; i++) {
+        pBuffer = mBufferQueue.itemAt(i);
+        delete [] pBuffer->mBuffer;
+        delete pBuffer;
+    }
+    mBufferQueue.clear();
+}
+
+// ----------------------------------------------------------------------------
+
+AudioFlinger::Client::Client(const sp<AudioFlinger>& audioFlinger, pid_t pid)
+    :   RefBase(),
+        mAudioFlinger(audioFlinger),
+        mMemoryDealer(new MemoryDealer(1024*1024)),
+        mPid(pid)
+{
+    // 1 MB of address space is good for 32 tracks, 8 buffers each, 4 KB/buffer
+}
+
+AudioFlinger::Client::~Client()
+{
+    mAudioFlinger->removeClient(mPid);
+}
+
+const sp<MemoryDealer>& AudioFlinger::Client::heap() const
+{
+    return mMemoryDealer;
+}
+
+// ----------------------------------------------------------------------------
+
+AudioFlinger::TrackHandle::TrackHandle(const sp<AudioFlinger::MixerThread::Track>& track)
     : BnAudioTrack(),
       mTrack(track)
 {
@@ -1386,8 +2262,7 @@
         uint32_t flags,
         status_t *status)
 {
-    sp<AudioRecordThread> thread;
-    sp<RecordTrack> recordTrack;
+    sp<MixerThread::RecordTrack> recordTrack;
     sp<RecordHandle> recordHandle;
     sp<Client> client;
     wp<Client> wclient;
@@ -1414,12 +2289,6 @@
         goto Exit;
     }
 
-    if (mSampleRate == 0) {
-        LOGE("Audio driver not initialized");
-        lStatus = NO_INIT;
-        goto Exit;
-    }
-
     if (mAudioRecordThread == 0) {
         LOGE("Audio record thread not started");
         lStatus = NO_INIT;
@@ -1436,7 +2305,7 @@
     }
 
     // add client to list
-    {
+    { // scope for mLock
         Mutex::Autolock _l(mLock);
         wclient = mClients.valueFor(pid);
         if (wclient != NULL) {
@@ -1445,15 +2314,20 @@
             client = new Client(this, pid);
             mClients.add(pid, client);
         }
+
+        // frameCount must be a multiple of input buffer size
+        inFrameCount = inputBufferSize/channelCount/sizeof(short);
+        frameCount = ((frameCount - 1)/inFrameCount + 1) * inFrameCount;
+    
+        // create new record track. The record track uses one track in mHardwareMixerThread by convention.
+        recordTrack = new MixerThread::RecordTrack(mHardwareMixerThread, client, streamType, sampleRate,
+                                                   format, channelCount, frameCount, flags);
     }
-
-    // frameCount must be a multiple of input buffer size
-    inFrameCount = inputBufferSize/channelCount/sizeof(short);
-    frameCount = ((frameCount - 1)/inFrameCount + 1) * inFrameCount;
-
-    // create new record track and pass to record thread
-    recordTrack = new RecordTrack(this, client, streamType, sampleRate,
-            format, channelCount, frameCount);
+    if (recordTrack->getCblk() == NULL) {
+        recordTrack.clear();
+        lStatus = NO_MEMORY;
+        goto Exit;
+    }
 
     // return to handle to client
     recordHandle = new RecordHandle(recordTrack);
@@ -1466,97 +2340,22 @@
     return recordHandle;
 }
 
-status_t AudioFlinger::startRecord(RecordTrack* recordTrack) {
+status_t AudioFlinger::startRecord(MixerThread::RecordTrack* recordTrack) {
     if (mAudioRecordThread != 0) {
         return mAudioRecordThread->start(recordTrack);        
     }
     return NO_INIT;
 }
 
-void AudioFlinger::stopRecord(RecordTrack* recordTrack) {
+void AudioFlinger::stopRecord(MixerThread::RecordTrack* recordTrack) {
     if (mAudioRecordThread != 0) {
         mAudioRecordThread->stop(recordTrack);
     }
 }
 
-
 // ----------------------------------------------------------------------------
 
-AudioFlinger::RecordTrack::RecordTrack(
-            const sp<AudioFlinger>& audioFlinger,
-            const sp<Client>& client,
-            int streamType,
-            uint32_t sampleRate,
-            int format,
-            int channelCount,
-            int frameCount)
-    :   TrackBase(audioFlinger, client, streamType, sampleRate, format,
-            channelCount, frameCount, 0),
-            mOverflow(false)
-{
-}
-
-AudioFlinger::RecordTrack::~RecordTrack()
-{
-    mAudioFlinger->audioMixer()->deleteTrackName(mName);
-}
-
-status_t AudioFlinger::RecordTrack::getNextBuffer(AudioBufferProvider::Buffer* buffer)
-{
-    audio_track_cblk_t* cblk = this->cblk();
-    uint32_t framesAvail;
-    uint32_t framesReq = buffer->frameCount;
-
-     // Check if last stepServer failed, try to step now
-    if (mFlags & TrackBase::STEPSERVER_FAILED) {
-        if (!step()) goto getNextBuffer_exit;
-        LOGV("stepServer recovered");
-        mFlags &= ~TrackBase::STEPSERVER_FAILED;
-    }
-
-    framesAvail = cblk->framesAvailable_l();
-
-    if (LIKELY(framesAvail)) {
-        uint32_t s = cblk->server;
-        uint32_t bufferEnd = cblk->serverBase + cblk->frameCount;
-
-        if (framesReq > framesAvail) {
-            framesReq = framesAvail;
-        }
-        if (s + framesReq > bufferEnd) {
-            framesReq = bufferEnd - s;
-        }
-
-        buffer->raw = getBuffer(s, framesReq);
-        if (buffer->raw == 0) goto getNextBuffer_exit;
-
-        buffer->frameCount = framesReq;
-        return NO_ERROR;
-    }
-
-getNextBuffer_exit:
-    buffer->raw = 0;
-    buffer->frameCount = 0;
-    return NOT_ENOUGH_DATA;
-}
-
-status_t AudioFlinger::RecordTrack::start()
-{
-    return mAudioFlinger->startRecord(this);
-}
-
-void AudioFlinger::RecordTrack::stop()
-{
-    mAudioFlinger->stopRecord(this);
-    TrackBase::reset();
-    // Force overerrun condition to avoid false overrun callback until first data is
-    // read from buffer
-    mCblk->flowControlFlag = 1;
-}
-
-// ----------------------------------------------------------------------------
-
-AudioFlinger::RecordHandle::RecordHandle(const sp<AudioFlinger::RecordTrack>& recordTrack)
+AudioFlinger::RecordHandle::RecordHandle(const sp<AudioFlinger::MixerThread::RecordTrack>& recordTrack)
     : BnAudioRecord(),
     mRecordTrack(recordTrack)
 {
@@ -1588,8 +2387,10 @@
 
 // ----------------------------------------------------------------------------
 
-AudioFlinger::AudioRecordThread::AudioRecordThread(AudioHardwareInterface* audioHardware) :
+AudioFlinger::AudioRecordThread::AudioRecordThread(AudioHardwareInterface* audioHardware,
+            const sp<AudioFlinger>& audioFlinger) :
     mAudioHardware(audioHardware),
+    mAudioFlinger(audioFlinger),
     mActive(false)
 {
 }
@@ -1619,15 +2420,17 @@
                     input = 0;
                 }
                 mRecordTrack.clear();
+                mStopped.signal();
 
                 mWaitWorkCV.wait(mLock);
                
                 LOGV("AudioRecordThread: loop starting");
                 if (mRecordTrack != 0) {
                     input = mAudioHardware->openInputStream(mRecordTrack->format(), 
-                                            mRecordTrack->channelCount(), 
-                                            mRecordTrack->sampleRate(), 
-                                            &mStartStatus);
+                                    mRecordTrack->channelCount(), 
+                                    mRecordTrack->sampleRate(), 
+                                    &mStartStatus,
+                                    (AudioSystem::audio_in_acoustics)(mRecordTrack->mFlags >> 16));
                     if (input != 0) {
                         inBufferSize = input->bufferSize();
                         inFrameCount = inBufferSize/input->frameSize();                        
@@ -1643,12 +2446,14 @@
                 mWaitWorkCV.signal();
             }
             mLock.unlock();
-        } else if (mRecordTrack != 0){
+        } else if (mRecordTrack != 0) {
 
             buffer.frameCount = inFrameCount;
-            if (LIKELY(mRecordTrack->getNextBuffer(&buffer) == NO_ERROR)) {
+            if (LIKELY(mRecordTrack->getNextBuffer(&buffer) == NO_ERROR &&
+                       (int)buffer.frameCount == inFrameCount)) {
                 LOGV("AudioRecordThread read: %d frames", buffer.frameCount);
-                if (input->read(buffer.raw, inBufferSize) < 0) {
+                ssize_t bytesRead = input->read(buffer.raw, inBufferSize);
+                if (bytesRead < 0) {
                     LOGE("Error reading audio input");
                     sleep(1);
                 }
@@ -1677,7 +2482,7 @@
     return false;
 }
 
-status_t AudioFlinger::AudioRecordThread::start(RecordTrack* recordTrack)
+status_t AudioFlinger::AudioRecordThread::start(MixerThread::RecordTrack* recordTrack)
 {
     LOGV("AudioRecordThread::start");
     AutoMutex lock(&mLock);
@@ -1690,6 +2495,19 @@
 
     mRecordTrack = recordTrack;
 
+#ifdef WITH_A2DP
+    { // scope for lock2
+
+        // AudioFlinger::mLock must be locked before calling
+        // handleStreamDisablesA2dp_l because it calls setA2dpEnabled_l().
+        AutoMutex lock2(&mAudioFlinger->mLock);
+
+        // Currently there is no way to detect if we are recording over SCO,
+        // so we disable A2DP during any recording.
+        mAudioFlinger->handleStreamDisablesA2dp_l(ACTIVE_TRACK_ADDED);
+    }
+#endif
+
     // signal thread to start
     LOGV("Signal record thread");
     mWaitWorkCV.signal();
@@ -1698,11 +2516,24 @@
     return mStartStatus;
 }
 
-void AudioFlinger::AudioRecordThread::stop(RecordTrack* recordTrack) {
+void AudioFlinger::AudioRecordThread::stop(MixerThread::RecordTrack* recordTrack) {
     LOGV("AudioRecordThread::stop");
     AutoMutex lock(&mLock);
     if (mActive && (recordTrack == mRecordTrack.get())) {
+#ifdef WITH_A2DP
+        { // scope for lock2
+    
+            // AudioFlinger::mLock must be locked before calling
+            // handleStreamDisablesA2dp_l because it calls setA2dpEnabled_l().
+            AutoMutex lock2(&mAudioFlinger->mLock);
+
+            // Currently there is no way to detect if we are recording over SCO,
+            // so we disable A2DP during any recording.
+            mAudioFlinger->handleStreamDisablesA2dp_l(ACTIVE_TRACK_REMOVED);
+        }
+#endif
         mActive = false;
+        mStopped.wait(mLock);
     }
 }
 
@@ -1717,6 +2548,22 @@
     requestExitAndWait();
 }
 
+status_t AudioFlinger::AudioRecordThread::dump(int fd, const Vector<String16>& args)
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    String8 result;
+    pid_t pid = 0;
+
+    if (mRecordTrack != 0 && mRecordTrack->mClient != 0) {
+        snprintf(buffer, SIZE, "Record client pid: %d\n", mRecordTrack->mClient->pid());
+        result.append(buffer);
+    } else {
+        result.append("No record client\n");
+    }
+    write(fd, result.string(), result.size());
+    return NO_ERROR;
+}
 
 status_t AudioFlinger::onTransact(
         uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
diff --git a/libs/audioflinger/AudioFlinger.h b/libs/audioflinger/AudioFlinger.h
index 9ab362a..ab15947 100644
--- a/libs/audioflinger/AudioFlinger.h
+++ b/libs/audioflinger/AudioFlinger.h
@@ -22,6 +22,7 @@
 #include <sys/types.h>
 
 #include <media/IAudioFlinger.h>
+#include <media/IAudioFlingerClient.h>
 #include <media/IAudioTrack.h>
 #include <media/IAudioRecord.h>
 #include <media/AudioTrack.h>
@@ -32,6 +33,7 @@
 #include <utils/MemoryDealer.h>
 #include <utils/KeyedVector.h>
 #include <utils/SortedVector.h>
+#include <utils/Vector.h>
 
 #include <hardware_legacy/AudioHardwareInterface.h>
 
@@ -54,18 +56,13 @@
 
 static const nsecs_t kStandbyTimeInNsecs = seconds(3);
 
-class AudioFlinger : public BnAudioFlinger, protected Thread
+class AudioFlinger : public BnAudioFlinger, public IBinder::DeathRecipient 
 {
 public:
     static void instantiate();
 
     virtual     status_t    dump(int fd, const Vector<String16>& args);
 
-    // Thread virtuals
-    virtual     bool        threadLoop();
-    virtual     status_t    readyToRun();
-    virtual     void        onFirstRef();
-
     // IAudioFlinger interface
     virtual sp<IAudioTrack> createTrack(
                                 pid_t pid,
@@ -78,11 +75,11 @@
                                 const sp<IMemory>& sharedBuffer,
                                 status_t *status);
 
-    virtual     uint32_t    sampleRate() const;
-    virtual     int         channelCount() const;
-    virtual     int         format() const;
-    virtual     size_t      frameCount() const;
-    virtual     size_t      latency() const;
+    virtual     uint32_t    sampleRate(int output) const;
+    virtual     int         channelCount(int output) const;
+    virtual     int         format(int output) const;
+    virtual     size_t      frameCount(int output) const;
+    virtual     uint32_t    latency(int output) const;
 
     virtual     status_t    setMasterVolume(float value);
     virtual     status_t    setMasterMute(bool muted);
@@ -107,8 +104,19 @@
 
     virtual     bool        isMusicActive() const;
 
+    virtual     bool        isA2dpEnabled() const;
+
     virtual     status_t    setParameter(const char* key, const char* value);
 
+    virtual     void        registerClient(const sp<IAudioFlingerClient>& client);
+    
+    virtual     size_t      getInputBufferSize(uint32_t sampleRate, int format, int channelCount);
+    
+    virtual     void        wakeUp()    { mWaitWorkCV.broadcast(); }
+    
+    // IBinder::DeathRecipient
+    virtual     void        binderDied(const wp<IBinder>& who);
+
     enum hardware_call_state {
         AUDIO_HW_IDLE = 0,
         AUDIO_HW_INIT,
@@ -149,23 +157,31 @@
                             AudioFlinger();
     virtual                 ~AudioFlinger();
     
-    void                    setOutput(AudioStreamOut* output);
-    void                    doSetOutput(AudioStreamOut* output);
-    size_t                  getOutputFrameCount(AudioStreamOut* output);
+    void                    setOutput(int outputType);
+    void                    doSetOutput(int outputType);
 
 #ifdef WITH_A2DP
+    void                    setA2dpEnabled_l(bool enable);
+    void                    checkA2dpEnabledChange_l();
+#endif
+    static bool             streamForcedToSpeaker(int streamType);
     static bool             streamDisablesA2dp(int streamType);
-    inline bool             isA2dpEnabled() const {
-                                return (mRequestedOutput == mA2dpOutput ||
-                                        (mOutput && mOutput == mA2dpOutput));
-                            }
-    void                    setA2dpEnabled(bool enable);
+    
+    // Management of forced route to speaker for certain track types.
+    enum force_speaker_command {
+        ACTIVE_TRACK_ADDED = 0,
+        ACTIVE_TRACK_REMOVED,
+        CHECK_ROUTE_RESTORE_TIME,
+        FORCE_ROUTE_RESTORE
+    };
+    void                    handleForcedSpeakerRoute(int command);
+#ifdef WITH_A2DP
+    void                    handleStreamDisablesA2dp_l(int command);
 #endif
 
     // Internal dump utilites.
     status_t dumpPermissionDenial(int fd, const Vector<String16>& args);
     status_t dumpClients(int fd, const Vector<String16>& args);
-    status_t dumpTracks(int fd, const Vector<String16>& args);
     status_t dumpInternals(int fd, const Vector<String16>& args);
 
     // --- Client ---
@@ -184,168 +200,347 @@
     };
 
 
-    // --- Track ---
     class TrackHandle;
     class RecordHandle;
     class AudioRecordThread;
 
-    // base for record and playback
-    class TrackBase : public AudioBufferProvider, public RefBase {
-
+    
+    // --- MixerThread ---
+    class MixerThread : public Thread {
     public:
-        enum track_state {
-            IDLE,
-            TERMINATED,
-            STOPPED,
-            RESUMING,
-            ACTIVE,
-            PAUSING,
-            PAUSED
+        
+        // --- Track ---
+
+        // base for record and playback
+        class TrackBase : public AudioBufferProvider, public RefBase {
+
+        public:
+            enum track_state {
+                IDLE,
+                TERMINATED,
+                STOPPED,
+                RESUMING,
+                ACTIVE,
+                PAUSING,
+                PAUSED
+            };
+
+            enum track_flags {
+                STEPSERVER_FAILED = 0x01, //  StepServer could not acquire cblk->lock mutex
+                SYSTEM_FLAGS_MASK = 0x0000ffffUL,
+                // The upper 16 bits are used for track-specific flags.
+            };
+
+                                TrackBase(const sp<MixerThread>& mixerThread,
+                                        const sp<Client>& client,
+                                        int streamType,
+                                        uint32_t sampleRate,
+                                        int format,
+                                        int channelCount,
+                                        int frameCount,
+                                        uint32_t flags,
+                                        const sp<IMemory>& sharedBuffer);
+                                ~TrackBase();
+
+            virtual status_t    start() = 0;
+            virtual void        stop() = 0;
+                    sp<IMemory> getCblk() const;
+
+        protected:
+            friend class MixerThread;
+            friend class RecordHandle;
+            friend class AudioRecordThread;
+
+                                TrackBase(const TrackBase&);
+                                TrackBase& operator = (const TrackBase&);
+
+            virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer) = 0;
+            virtual void releaseBuffer(AudioBufferProvider::Buffer* buffer);
+
+            audio_track_cblk_t* cblk() const {
+                return mCblk;
+            }
+
+            int type() const {
+                return mStreamType;
+            }
+
+            int format() const {
+                return mFormat;
+            }
+
+            int channelCount() const ;
+
+            int sampleRate() const;
+
+            void* getBuffer(uint32_t offset, uint32_t frames) const;
+
+            int name() const {
+                return mName;
+            }
+
+            bool isStopped() const {
+                return mState == STOPPED;
+            }
+
+            bool isTerminated() const {
+                return mState == TERMINATED;
+            }
+
+            bool step();
+            void reset();
+
+            sp<MixerThread>     mMixerThread;
+            sp<Client>          mClient;
+            sp<IMemory>         mCblkMemory;
+            audio_track_cblk_t* mCblk;
+            int                 mStreamType;
+            void*               mBuffer;
+            void*               mBufferEnd;
+            uint32_t            mFrameCount;
+            int                 mName;
+            // we don't really need a lock for these
+            int                 mState;
+            int                 mClientTid;
+            uint8_t             mFormat;
+            uint32_t            mFlags;
         };
 
-        enum track_flags {
-            STEPSERVER_FAILED = 0x01   //  StepServer could not acquire cblk->lock mutex
+        // playback track
+        class Track : public TrackBase {
+        public:
+                                Track(  const sp<MixerThread>& mixerThread,
+                                        const sp<Client>& client,
+                                        int streamType,
+                                        uint32_t sampleRate,
+                                        int format,
+                                        int channelCount,
+                                        int frameCount,
+                                        const sp<IMemory>& sharedBuffer);
+                                ~Track();
+
+                    void        dump(char* buffer, size_t size);
+            virtual status_t    start();
+            virtual void        stop();
+                    void        pause();
+
+                    void        flush();
+                    void        destroy();
+                    void        mute(bool);
+                    void        setVolume(float left, float right);
+
+        protected:
+            friend class MixerThread;
+            friend class AudioFlinger;
+            friend class AudioFlinger::TrackHandle;
+
+                                Track(const Track&);
+                                Track& operator = (const Track&);
+
+            virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer);
+
+            bool isMuted() const {
+                return (mMute || mMixerThread->mStreamTypes[mStreamType].mute);
+            }
+
+            bool isPausing() const {
+                return mState == PAUSING;
+            }
+
+            bool isPaused() const {
+                return mState == PAUSED;
+            }
+
+            bool isReady() const;
+
+            void setPaused() { mState = PAUSED; }
+            void reset();
+
+            // we don't really need a lock for these
+            float               mVolume[2];
+            volatile bool       mMute;
+            // FILLED state is used for suppressing volume ramp at begin of playing
+            enum {FS_FILLING, FS_FILLED, FS_ACTIVE};
+            mutable uint8_t     mFillingUpStatus;
+            int8_t              mRetryCount;
+            sp<IMemory>         mSharedBuffer;
+            bool                mResetDone;
+        };  // end of Track
+
+        // record track
+        class RecordTrack : public TrackBase {
+        public:
+                                RecordTrack(const sp<MixerThread>& mixerThread,
+                                        const sp<Client>& client,
+                                        int streamType,
+                                        uint32_t sampleRate,
+                                        int format,
+                                        int channelCount,
+                                        int frameCount,
+                                        uint32_t flags);
+                                ~RecordTrack();
+
+            virtual status_t    start();
+            virtual void        stop();
+
+                    bool        overflow() { bool tmp = mOverflow; mOverflow = false; return tmp; }
+                    bool        setOverflow() { bool tmp = mOverflow; mOverflow = true; return tmp; }
+
+        private:
+            friend class AudioFlinger;
+            friend class AudioFlinger::RecordHandle;
+            friend class AudioFlinger::AudioRecordThread;
+            friend class MixerThread;
+
+                                RecordTrack(const Track&);
+                                RecordTrack& operator = (const Track&);
+
+            virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer);
+
+            bool                mOverflow;
         };
 
-                            TrackBase(  const sp<AudioFlinger>& audioFlinger,
-                                    const sp<Client>& client,
+        // playback track
+        class OutputTrack : public Track {
+        public:
+            
+            class Buffer: public AudioBufferProvider::Buffer {
+            public:
+                int16_t *mBuffer;
+            };
+            
+                                OutputTrack(  const sp<MixerThread>& mixerThread,
+                                        uint32_t sampleRate,
+                                        int format,
+                                        int channelCount,
+                                        int frameCount);
+                                ~OutputTrack();
+
+            virtual status_t    start();
+            virtual void        stop();
+                    void        write(int16_t* data, uint32_t frames);
+                    bool        bufferQueueEmpty() { return (mBufferQueue.size() == 0) ? true : false; }
+
+        private:
+
+            status_t            obtainBuffer(AudioBufferProvider::Buffer* buffer);
+            void                clearBufferQueue();
+            
+            sp<MixerThread>             mOutputMixerThread;
+            Vector < Buffer* >          mBufferQueue;
+            AudioBufferProvider::Buffer mOutBuffer;
+            uint32_t                    mFramesWritten;
+            
+         };  // end of OutputTrack
+
+        MixerThread (const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, int outputType);
+        virtual             ~MixerThread();
+
+        virtual     status_t    dump(int fd, const Vector<String16>& args);
+
+        // Thread virtuals
+        virtual     bool        threadLoop();
+        virtual     status_t    readyToRun();
+        virtual     void        onFirstRef();
+
+        virtual     uint32_t    sampleRate() const;
+        virtual     int         channelCount() const;
+        virtual     int         format() const;
+        virtual     size_t      frameCount() const;
+        virtual     uint32_t    latency() const;
+
+        virtual     status_t    setMasterVolume(float value);
+        virtual     status_t    setMasterMute(bool muted);
+
+        virtual     float       masterVolume() const;
+        virtual     bool        masterMute() const;
+
+        virtual     status_t    setStreamVolume(int stream, float value);
+        virtual     status_t    setStreamMute(int stream, bool muted);
+
+        virtual     float       streamVolume(int stream) const;
+        virtual     bool        streamMute(int stream) const;
+
+                    bool        isMusicActive() const;
+        
+                    
+                    sp<Track>   createTrack_l(
+                                    const sp<AudioFlinger::Client>& client,
                                     int streamType,
                                     uint32_t sampleRate,
                                     int format,
                                     int channelCount,
                                     int frameCount,
-                                    const sp<IMemory>& sharedBuffer);
-                            ~TrackBase();
-
-        virtual status_t    start() = 0;
-        virtual void        stop() = 0;
-                sp<IMemory> getCblk() const;
-
-    protected:
-        friend class AudioFlinger;
-        friend class RecordHandle;
-        friend class AudioRecordThread;
-
-                            TrackBase(const TrackBase&);
-                            TrackBase& operator = (const TrackBase&);
-
-        virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer) = 0;
-        virtual void releaseBuffer(AudioBufferProvider::Buffer* buffer);
-
-        audio_track_cblk_t* cblk() const {
-            return mCblk;
-        }
-
-        int type() const {
-            return mStreamType;
-        }
-
-        int format() const {
-            return mFormat;
-        }
-
-        int channelCount() const ;
-
-        int sampleRate() const;
-
-        void* getBuffer(uint32_t offset, uint32_t frames) const;
-
-        int name() const {
-            return mName;
-        }
-
-        bool isStopped() const {
-            return mState == STOPPED;
-        }
-
-        bool isTerminated() const {
-            return mState == TERMINATED;
-        }
-
-        bool step();
-        void reset();
-
-        sp<AudioFlinger>    mAudioFlinger;
-        sp<Client>          mClient;
-        sp<IMemory>         mCblkMemory;
-        audio_track_cblk_t* mCblk;
-        int                 mStreamType;
-        void*               mBuffer;
-        void*               mBufferEnd;
-        uint32_t            mFrameCount;
-        int                 mName;
-        // we don't really need a lock for these
-        int                 mState;
-        int                 mClientTid;
-        uint8_t             mFormat;
-        uint8_t             mFlags;
-    };
-
-    // playback track
-    class Track : public TrackBase {
-    public:
-                            Track(  const sp<AudioFlinger>& audioFlinger,
-                                    const sp<Client>& client,
-                                    int streamType,
-                                    uint32_t sampleRate,
-                                    int format,
-                                    int channelCount,
-                                    int frameCount,
-                                    const sp<IMemory>& sharedBuffer);
-                            ~Track();
-
-                void        dump(char* buffer, size_t size);
-        virtual status_t    start();
-        virtual void        stop();
-                void        pause();
-
-                void        flush();
-                void        destroy();
-                void        mute(bool);
-                void        setVolume(float left, float right);
+                                    const sp<IMemory>& sharedBuffer,
+                                    status_t *status);
+                    
+                    void        getTracks_l(SortedVector < sp<Track> >& tracks,
+                                          SortedVector < wp<Track> >& activeTracks);
+                    void        putTracks_l(SortedVector < sp<Track> >& tracks,
+                                          SortedVector < wp<Track> >& activeTracks);
+                    void        setOuputTrack(OutputTrack *track) { mOutputTrack = track; }
+                    
+        struct  stream_type_t {
+            stream_type_t()
+                :   volume(1.0f),
+                    mute(false)
+            {
+            }
+            float       volume;
+            bool        mute;
+        };
 
     private:
+
+
         friend class AudioFlinger;
-        friend class TrackHandle;
+        friend class Track;
+        friend class TrackBase;
+        friend class RecordTrack;
+        
+        MixerThread(const Client&);
+        MixerThread& operator = (const MixerThread&);
+  
+        status_t    addTrack_l(const sp<Track>& track);
+        void        removeTrack_l(wp<Track> track, int name);
+        void        destroyTrack_l(const sp<Track>& track);
+        int         getTrackName_l();
+        void        deleteTrackName_l(int name);
+        void        addActiveTrack_l(const wp<Track>& t);
+        void        removeActiveTrack_l(const wp<Track>& t);
+        size_t      getOutputFrameCount();
 
-                            Track(const Track&);
-                            Track& operator = (const Track&);
+        status_t    dumpInternals(int fd, const Vector<String16>& args);
+        status_t    dumpTracks(int fd, const Vector<String16>& args);
+        
+        sp<AudioFlinger>                mAudioFlinger;       
+        SortedVector< wp<Track> >       mActiveTracks;
+        SortedVector< sp<Track> >       mTracks;
+        stream_type_t                   mStreamTypes[AudioSystem::NUM_STREAM_TYPES];
+        AudioMixer*                     mAudioMixer;
+        AudioStreamOut*                 mOutput;
+        int                             mOutputType;
+        uint32_t                        mSampleRate;
+        size_t                          mFrameCount;
+        int                             mChannelCount;
+        int                             mFormat;
+        int16_t*                        mMixBuffer;
+        float                           mMasterVolume;
+        bool                            mMasterMute;
+        nsecs_t                         mLastWriteTime;
+        int                             mNumWrites;
+        int                             mNumDelayedWrites;
+        bool                            mStandby;
+        bool                            mInWrite;
+        sp <OutputTrack>                mOutputTrack;
+    };
 
-        virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer);
-
-        bool isMuted() const {
-            return mMute;
-        }
-
-        bool isPausing() const {
-            return mState == PAUSING;
-        }
-
-        bool isPaused() const {
-            return mState == PAUSED;
-        }
-
-        bool isReady() const;
-
-        void setPaused() { mState = PAUSED; }
-        void reset();
-
-        // we don't really need a lock for these
-        float               mVolume[2];
-        volatile bool       mMute;
-        // FILLED state is used for suppressing volume ramp at begin of playing
-        enum {FS_FILLING, FS_FILLED, FS_ACTIVE};
-        mutable uint8_t     mFillingUpStatus;
-        int8_t              mRetryCount;
-        sp<IMemory>         mSharedBuffer;
-        bool                mResetDone;
-    };  // end of Track
-
+    
     friend class AudioBuffer;
 
     class TrackHandle : public android::BnAudioTrack {
     public:
-                            TrackHandle(const sp<Track>& track);
+                            TrackHandle(const sp<MixerThread::Track>& track);
         virtual             ~TrackHandle();
         virtual status_t    start();
         virtual void        stop();
@@ -357,70 +552,20 @@
         virtual status_t onTransact(
             uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags);
     private:
-        sp<Track> mTrack;
-    };
-
-    struct  stream_type_t {
-        stream_type_t()
-            :   volume(1.0f),
-                mute(false)
-        {
-        }
-        float       volume;
-        bool        mute;
+        sp<MixerThread::Track> mTrack;
     };
 
     friend class Client;
-    friend class Track;
+    friend class MixerThread::Track;
 
 
                 void        removeClient(pid_t pid);
 
-                status_t    addTrack(const sp<Track>& track);
-                void        removeTrack(wp<Track> track, int name);
-                void        remove_track_l(wp<Track> track, int name);
-                void        destroyTrack(const sp<Track>& track);
-                void        addActiveTrack(const wp<Track>& track);
-                void        removeActiveTrack(const wp<Track>& track);
 
-                AudioMixer* audioMixer() {
-                    return mAudioMixer;
-                }
-
-    // record track
-    class RecordTrack : public TrackBase {
-    public:
-                            RecordTrack(  const sp<AudioFlinger>& audioFlinger,
-                                    const sp<Client>& client,
-                                    int streamType,
-                                    uint32_t sampleRate,
-                                    int format,
-                                    int channelCount,
-                                    int frameCount);
-                            ~RecordTrack();
-
-        virtual status_t    start();
-        virtual void        stop();
-
-                bool        overflow() { bool tmp = mOverflow; mOverflow = false; return tmp; }
-                bool        setOverflow() { bool tmp = mOverflow; mOverflow = true; return tmp; }
-
-    private:
-        friend class AudioFlinger;
-        friend class RecordHandle;
-        friend class AudioRecordThread;
-
-                            RecordTrack(const Track&);
-                            RecordTrack& operator = (const Track&);
-
-        virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer);
-
-        bool                mOverflow;
-    };
 
     class RecordHandle : public android::BnAudioRecord {
     public:
-        RecordHandle(const sp<RecordTrack>& recordTrack);
+        RecordHandle(const sp<MixerThread::RecordTrack>& recordTrack);
         virtual             ~RecordHandle();
         virtual status_t    start();
         virtual void        stop();
@@ -428,72 +573,66 @@
         virtual status_t onTransact(
             uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags);
     private:
-        sp<RecordTrack> mRecordTrack;
+        sp<MixerThread::RecordTrack> mRecordTrack;
     };
 
     // record thread
     class AudioRecordThread : public Thread
     {
     public:
-        AudioRecordThread(AudioHardwareInterface* audioHardware);
+        AudioRecordThread(AudioHardwareInterface* audioHardware, const sp<AudioFlinger>& audioFlinger);
         virtual             ~AudioRecordThread();
         virtual bool        threadLoop();
         virtual status_t    readyToRun() { return NO_ERROR; }
         virtual void        onFirstRef() {}
 
-                status_t    start(RecordTrack* recordTrack);
-                void        stop(RecordTrack* recordTrack);
+                status_t    start(MixerThread::RecordTrack* recordTrack);
+                void        stop(MixerThread::RecordTrack* recordTrack);
                 void        exit();
+                status_t    dump(int fd, const Vector<String16>& args);
 
     private:
                 AudioRecordThread();
                 AudioHardwareInterface              *mAudioHardware;
-                sp<RecordTrack>                     mRecordTrack;
+                sp<AudioFlinger>                    mAudioFlinger;
+                sp<MixerThread::RecordTrack>        mRecordTrack;
                 Mutex                               mLock;
                 Condition                           mWaitWorkCV;
+                Condition                           mStopped;
                 volatile bool                       mActive;
                 status_t                            mStartStatus;
     };
 
     friend class AudioRecordThread;
+    friend class MixerThread;
 
-                status_t    startRecord(RecordTrack* recordTrack);
-                void        stopRecord(RecordTrack* recordTrack);
+                status_t    startRecord(MixerThread::RecordTrack* recordTrack);
+                void        stopRecord(MixerThread::RecordTrack* recordTrack);
 
-    mutable     Mutex                                       mHardwareLock;
-    mutable     Mutex                                       mLock;
-    mutable     Condition                                   mWaitWorkCV;
+    mutable     Mutex                               mHardwareLock;
+    mutable     Mutex                               mLock;
+    mutable     Condition                           mWaitWorkCV;
+
                 DefaultKeyedVector< pid_t, wp<Client> >     mClients;
-                SortedVector< wp<Track> >                   mActiveTracks;
-                SortedVector< sp<Track> >                   mTracks;
-                float                               mMasterVolume;
-                uint32_t                            mMasterRouting;
-                bool                                mMasterMute;
-                stream_type_t                       mStreamTypes[AudioTrack::NUM_STREAM_TYPES];
 
-                AudioMixer*                         mHardwareAudioMixer;
-                AudioMixer*                         mA2dpAudioMixer;
-                AudioMixer*                         mAudioMixer;
+                sp<MixerThread>                     mA2dpMixerThread;
+                sp<MixerThread>                     mHardwareMixerThread;
                 AudioHardwareInterface*             mAudioHardware;
                 AudioHardwareInterface*             mA2dpAudioInterface;
-                AudioStreamOut*                     mHardwareOutput;
-                AudioStreamOut*                     mA2dpOutput;
-                AudioStreamOut*                     mOutput;
-                AudioStreamOut*                     mRequestedOutput;
                 sp<AudioRecordThread>               mAudioRecordThread;
-                uint32_t                            mSampleRate;
-                size_t                              mFrameCount;
-                int                                 mChannelCount;
-                int                                 mFormat;
-                int16_t*                            mMixBuffer;
+                bool                                mA2dpEnabled;
+                bool                                mNotifyA2dpChange;
     mutable     int                                 mHardwareStatus;
-                nsecs_t                             mLastWriteTime;
-                int                                 mNumWrites;
-                int                                 mNumDelayedWrites;
-                bool                                mStandby;
-                bool                                mInWrite;
+                SortedVector< wp<IBinder> >         mNotificationClients;
+                int                                 mForcedSpeakerCount;
                 int                                 mA2dpDisableCount;
+
+                // true if A2DP should resume when mA2dpDisableCount returns to zero
                 bool                                mA2dpSuppressed;
+                uint32_t                            mSavedRoute;
+                uint32_t                            mForcedRoute;
+                nsecs_t                             mRouteRestoreTime;
+                bool                                mMusicMuteSaved;
 };
 
 // ----------------------------------------------------------------------------
diff --git a/libs/audioflinger/AudioHardwareGeneric.cpp b/libs/audioflinger/AudioHardwareGeneric.cpp
index e455186..62beada 100644
--- a/libs/audioflinger/AudioHardwareGeneric.cpp
+++ b/libs/audioflinger/AudioHardwareGeneric.cpp
@@ -93,7 +93,8 @@
 }
 
 AudioStreamIn* AudioHardwareGeneric::openInputStream(
-        int format, int channelCount, uint32_t sampleRate, status_t *status)
+        int format, int channelCount, uint32_t sampleRate, status_t *status,
+        AudioSystem::audio_in_acoustics acoustics)
 {
     AutoMutex lock(mLock);
 
@@ -107,7 +108,7 @@
 
     // create new output stream
     AudioStreamInGeneric* in = new AudioStreamInGeneric();
-    status_t lStatus = in->set(this, mFd, format, channelCount, sampleRate);
+    status_t lStatus = in->set(this, mFd, format, channelCount, sampleRate, acoustics);
     if (status) {
         *status = lStatus;
     }
@@ -246,7 +247,8 @@
         int fd,
         int format,
         int channels,
-        uint32_t rate)
+        uint32_t rate,
+        AudioSystem::audio_in_acoustics acoustics)
 {
     // FIXME: remove logging
     LOGD("AudioStreamInGeneric::set(%p, %d, %d, %d, %u)", hw, fd, format, channels, rate);
diff --git a/libs/audioflinger/AudioHardwareGeneric.h b/libs/audioflinger/AudioHardwareGeneric.h
index a7822e1..c949aa1 100644
--- a/libs/audioflinger/AudioHardwareGeneric.h
+++ b/libs/audioflinger/AudioHardwareGeneric.h
@@ -47,7 +47,7 @@
     virtual size_t      bufferSize() const { return 4096; }
     virtual int         channelCount() const { return 2; }
     virtual int         format() const { return AudioSystem::PCM_16_BIT; }
-    virtual uint32_t    latency() const { return 0; }
+    virtual uint32_t    latency() const { return 20; }
     virtual status_t    setVolume(float volume) { return INVALID_OPERATION; }
     virtual ssize_t     write(const void* buffer, size_t bytes);
     virtual status_t    standby();
@@ -69,7 +69,8 @@
             int mFd,
             int format,
             int channelCount,
-            uint32_t sampleRate);
+            uint32_t sampleRate,
+            AudioSystem::audio_in_acoustics acoustics);
 
     uint32_t    sampleRate() const { return 8000; }
     virtual size_t      bufferSize() const { return 320; }
@@ -114,7 +115,8 @@
             int format,
             int channelCount,
             uint32_t sampleRate,
-            status_t *status);
+            status_t *status,
+            AudioSystem::audio_in_acoustics acoustics);
 
             void            closeOutputStream(AudioStreamOutGeneric* out);
             void            closeInputStream(AudioStreamInGeneric* in);
diff --git a/libs/audioflinger/AudioHardwareStub.cpp b/libs/audioflinger/AudioHardwareStub.cpp
index e9f3d69..b13cb1c 100644
--- a/libs/audioflinger/AudioHardwareStub.cpp
+++ b/libs/audioflinger/AudioHardwareStub.cpp
@@ -56,10 +56,11 @@
 }
 
 AudioStreamIn* AudioHardwareStub::openInputStream(
-        int format, int channelCount, uint32_t sampleRate, status_t *status)
+        int format, int channelCount, uint32_t sampleRate,
+        status_t *status, AudioSystem::audio_in_acoustics acoustics)
 {
     AudioStreamInStub* in = new AudioStreamInStub();
-    status_t lStatus = in->set(format, channelCount, sampleRate);
+    status_t lStatus = in->set(format, channelCount, sampleRate, acoustics);
     if (status) {
         *status = lStatus;
     }
@@ -142,7 +143,8 @@
 
 // ----------------------------------------------------------------------------
 
-status_t AudioStreamInStub::set(int format, int channels, uint32_t rate)
+status_t AudioStreamInStub::set(int format, int channels, uint32_t rate,
+				AudioSystem::audio_in_acoustics acoustics)
 {
     if ((format == AudioSystem::PCM_16_BIT) &&
             (channels == channelCount()) &&
diff --git a/libs/audioflinger/AudioHardwareStub.h b/libs/audioflinger/AudioHardwareStub.h
index 24736ed..d406424 100644
--- a/libs/audioflinger/AudioHardwareStub.h
+++ b/libs/audioflinger/AudioHardwareStub.h
@@ -43,7 +43,7 @@
 
 class AudioStreamInStub : public AudioStreamIn {
 public:
-    virtual status_t    set(int format, int channelCount, uint32_t sampleRate);
+    virtual status_t    set(int format, int channelCount, uint32_t sampleRate, AudioSystem::audio_in_acoustics acoustics);
     virtual uint32_t    sampleRate() const { return 8000; }
     virtual size_t      bufferSize() const { return 320; }
     virtual int         channelCount() const { return 1; }
@@ -81,7 +81,8 @@
                                 int format,
                                 int channelCount,
                                 uint32_t sampleRate,
-                                status_t *status);
+                                status_t *status,
+				AudioSystem::audio_in_acoustics acoustics);
 
 protected:
     virtual status_t    doRouting() { return NO_ERROR; }
diff --git a/libs/surfaceflinger/Android.mk b/libs/surfaceflinger/Android.mk
index d14cebf..496e271 100644
--- a/libs/surfaceflinger/Android.mk
+++ b/libs/surfaceflinger/Android.mk
@@ -15,8 +15,8 @@
     LayerBlur.cpp \
     LayerBitmap.cpp \
     LayerDim.cpp \
-    LayerScreenshot.cpp \
-    RFBServer.cpp \
+    LayerOrientationAnim.cpp \
+    OrientationAnimation.cpp \
     SurfaceFlinger.cpp \
     Tokenizer.cpp \
     Transform.cpp \
@@ -38,7 +38,8 @@
 	libcorecg \
 	libsgl \
 	libpixelflinger \
-	libGLES_CM
+	libEGL \
+	libGLESv1_CM
 
 LOCAL_C_INCLUDES := \
 	$(call include-path-for, corecg graphics)
diff --git a/libs/surfaceflinger/BootAnimation.cpp b/libs/surfaceflinger/BootAnimation.cpp
index d18f59a..2b30336 100644
--- a/libs/surfaceflinger/BootAnimation.cpp
+++ b/libs/surfaceflinger/BootAnimation.cpp
@@ -39,7 +39,9 @@
 #include <core/SkBitmap.h>
 #include <images/SkImageDecoder.h>
 
-#include <GLES/egl.h>
+#include <GLES/gl.h>
+#include <GLES/glext.h>
+#include <EGL/eglext.h>
 
 #include "BootAnimation.h"
 
@@ -47,32 +49,28 @@
 
 // ---------------------------------------------------------------------------
 
-BootAnimation::BootAnimation(const sp<ISurfaceComposer>& composer)
-:   Thread(false)
-{
+BootAnimation::BootAnimation(const sp<ISurfaceComposer>& composer) :
+    Thread(false) {
     mSession = SurfaceComposerClient::clientForConnection(
             composer->createConnection()->asBinder());
 }
 
-BootAnimation::~BootAnimation()
-{
+BootAnimation::~BootAnimation() {
 }
 
-void BootAnimation::onFirstRef()
-{
+void BootAnimation::onFirstRef() {
     run("BootAnimation", PRIORITY_DISPLAY);
 }
 
-const sp<SurfaceComposerClient>& BootAnimation::session() const 
-{
+const sp<SurfaceComposerClient>& BootAnimation::session() const {
     return mSession;
 }
 
-status_t BootAnimation::initTexture(
-        Texture* texture, AssetManager& assets, const char* name)
-{
+status_t BootAnimation::initTexture(Texture* texture, AssetManager& assets,
+        const char* name) {
     Asset* asset = assets.open(name, Asset::ACCESS_BUFFER);
-    if (!asset) return NO_INIT;
+    if (!asset)
+        return NO_INIT;
     SkBitmap bitmap;
     SkImageDecoder::DecodeMemory(asset->getBuffer(false), asset->getLength(),
             &bitmap, SkBitmap::kNo_Config, SkImageDecoder::kDecodePixels_Mode);
@@ -84,32 +82,32 @@
     bitmap.lockPixels();
 
     const int w = bitmap.width();
-    const int h = bitmap.height();    
+    const int h = bitmap.height();
     const void* p = bitmap.getPixels();
-    
+
     GLint crop[4] = { 0, h, w, -h };
     texture->w = w;
     texture->h = h;
 
     glGenTextures(1, &texture->name);
     glBindTexture(GL_TEXTURE_2D, texture->name);
-    
-    switch(bitmap.getConfig()) {
+
+    switch (bitmap.getConfig()) {
         case SkBitmap::kA8_Config:
-            glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, w, h, 0,
-                    GL_ALPHA, GL_UNSIGNED_BYTE, p);
+            glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, w, h, 0, GL_ALPHA,
+                    GL_UNSIGNED_BYTE, p);
             break;
         case SkBitmap::kARGB_4444_Config:
-            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0,
-                    GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, p);
+            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA,
+                    GL_UNSIGNED_SHORT_4_4_4_4, p);
             break;
         case SkBitmap::kARGB_8888_Config:
-            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0,
-                    GL_RGBA, GL_UNSIGNED_BYTE, p);
+            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA,
+                    GL_UNSIGNED_BYTE, p);
             break;
         case SkBitmap::kRGB_565_Config:
-            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0,
-                    GL_RGB, GL_UNSIGNED_SHORT_5_6_5, p);
+            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGB,
+                    GL_UNSIGNED_SHORT_5_6_5, p);
             break;
         default:
             break;
@@ -123,8 +121,7 @@
     return NO_ERROR;
 }
 
-status_t BootAnimation::readyToRun()
-{
+status_t BootAnimation::readyToRun() {
     mAssets.addDefaultAssets();
 
     DisplayInfo dinfo;
@@ -133,32 +130,27 @@
         return -1;
 
     // create the native surface
-    sp<Surface> s = session()->createSurface(getpid(), 0, 
-            dinfo.w, dinfo.h, PIXEL_FORMAT_RGB_565);
+    sp<Surface> s = session()->createSurface(getpid(), 0, dinfo.w, dinfo.h,
+            PIXEL_FORMAT_RGB_565);
     session()->openTransaction();
     s->setLayer(0x40000000);
     session()->closeTransaction();
 
     // initialize opengl and egl
-    const EGLint attribs[] = {
-            EGL_RED_SIZE,       5,
-            EGL_GREEN_SIZE,     6,
-            EGL_BLUE_SIZE,      5,
-            EGL_DEPTH_SIZE,     0,
-            EGL_NONE
-    };
+    const EGLint attribs[] = { EGL_RED_SIZE, 5, EGL_GREEN_SIZE, 6,
+            EGL_BLUE_SIZE, 5, EGL_DEPTH_SIZE, 0, EGL_NONE };
     EGLint w, h, dummy;
     EGLint numConfigs;
     EGLConfig config;
     EGLSurface surface;
     EGLContext context;
     EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
-    eglInitialize(display, NULL, NULL);
     eglChooseConfig(display, attribs, &config, 1, &numConfigs);
 
-    surface = eglCreateWindowSurface(
-            display, config, new EGLNativeWindowSurface(s), NULL);
-    
+    mNativeWindowSurface = new EGLNativeWindowSurface(s);
+    surface = eglCreateWindowSurface(display, config, 
+            mNativeWindowSurface.get(), NULL);
+
     context = eglCreateContext(display, config, NULL, NULL);
     eglQuerySurface(display, surface, EGL_WIDTH, &w);
     eglQuerySurface(display, surface, EGL_HEIGHT, &h);
@@ -167,7 +159,7 @@
     mContext = context;
     mSurface = surface;
     mWidth = w;
-    mHeight= h;
+    mHeight = h;
     mFlingerSurface = s;
 
     // initialize GL
@@ -180,25 +172,21 @@
     return NO_ERROR;
 }
 
-void BootAnimation::requestExit()
-{
+void BootAnimation::requestExit() {
     mBarrier.open();
     Thread::requestExit();
 }
 
-bool BootAnimation::threadLoop()
-{
+bool BootAnimation::threadLoop() {
     bool r = android();
-    eglMakeCurrent(mDisplay, 0, 0, 0);
-    eglDestroyContext(mDisplay, mContext);    
+    eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+    eglDestroyContext(mDisplay, mContext);
     eglDestroySurface(mDisplay, mSurface);
-    eglTerminate(mDisplay);
+    mNativeWindowSurface.clear();
     return r;
 }
 
-
-bool BootAnimation::android()
-{
+bool BootAnimation::android() {
     initTexture(&mAndroid[0], mAssets, "images/android_320x480.png");
     initTexture(&mAndroid[1], mAssets, "images/boot_robot.png");
     initTexture(&mAndroid[2], mAssets, "images/boot_robot_glow.png");
@@ -219,9 +207,9 @@
     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
     glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
     const int steps = 8;
-    for (int i=1 ; i<steps ; i++) {
+    for (int i = 1; i < steps; i++) {
         float fade = i / float(steps);
-        glColor4f(1, 1, 1, fade*fade);
+        glColor4f(1, 1, 1, fade * fade);
         glClear(GL_COLOR_BUFFER_BIT);
         glDrawTexiOES(0, 0, 0, mAndroid[0].w, mAndroid[0].h);
         eglSwapBuffers(mDisplay, mSurface);
@@ -232,79 +220,73 @@
     glDisable(GL_BLEND);
     glDrawTexiOES(0, 0, 0, mAndroid[0].w, mAndroid[0].h);
     eglSwapBuffers(mDisplay, mSurface);
-    
-    
+
     // update rect for the robot
     const int x = mWidth - mAndroid[1].w - 33;
-    const int y = (mHeight - mAndroid[1].h)/2 - 1;
-    const Rect updateRect(x, y, x+mAndroid[1].w, y+mAndroid[1].h);
+    const int y = (mHeight - mAndroid[1].h) / 2 - 1;
+    const Rect updateRect(x, y, x + mAndroid[1].w, y + mAndroid[1].h);
 
     // draw and update only what we need
-    eglSwapRectangleANDROID(mDisplay, mSurface,
-            updateRect.left, updateRect.top, 
-            updateRect.width(), updateRect.height());
+    mNativeWindowSurface->setSwapRectangle(updateRect.left,
+            updateRect.top, updateRect.width(), updateRect.height());
 
     glEnable(GL_SCISSOR_TEST);
-    glScissor(updateRect.left, mHeight-updateRect.bottom,
-            updateRect.width(), updateRect.height()); 
+    glScissor(updateRect.left, mHeight - updateRect.bottom, updateRect.width(),
+            updateRect.height());
 
     const nsecs_t startTime = systemTime();
-    do
-    {
+    do {
         // glow speed and shape
         nsecs_t time = systemTime() - startTime;
-        float t = ((4.0f/(360.0f*us2ns(16667))) * time);
+        float t = ((4.0f / (360.0f * us2ns(16667))) * time);
         t = t - floorf(t);
-        const float fade = 0.5f + 0.5f*sinf(t * 2*M_PI);
+        const float fade = 0.5f + 0.5f * sinf(t * 2 * M_PI);
 
         // fade the glow in and out
         glDisable(GL_BLEND);
         glBindTexture(GL_TEXTURE_2D, mAndroid[2].name);
         glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
         glColor4f(fade, fade, fade, fade);
-        glDrawTexiOES(updateRect.left, mHeight-updateRect.bottom, 0,
+        glDrawTexiOES(updateRect.left, mHeight - updateRect.bottom, 0,
                 updateRect.width(), updateRect.height());
 
         // draw the robot
         glEnable(GL_BLEND);
         glBindTexture(GL_TEXTURE_2D, mAndroid[1].name);
         glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
-        glDrawTexiOES(updateRect.left, mHeight-updateRect.bottom, 0,
+        glDrawTexiOES(updateRect.left, mHeight - updateRect.bottom, 0,
                 updateRect.width(), updateRect.height());
 
         // make sure sleep a lot to not take too much CPU away from 
         // the boot process. With this "glow" animation there is no
         // visible difference. 
-        usleep(16667*4);
+        usleep(16667 * 4);
 
         eglSwapBuffers(mDisplay, mSurface);
     } while (!exitPending());
-    
-    
+
     glDeleteTextures(1, &mAndroid[0].name);
     glDeleteTextures(1, &mAndroid[1].name);
     glDeleteTextures(1, &mAndroid[2].name);
     return false;
 }
 
-
-bool BootAnimation::cylon()
-{
+bool BootAnimation::cylon() {
     // initialize the textures...
-    initTexture(&mLeftTrail,  mAssets, "images/cylon_left.png");
+    initTexture(&mLeftTrail, mAssets, "images/cylon_left.png");
     initTexture(&mRightTrail, mAssets, "images/cylon_right.png");
     initTexture(&mBrightSpot, mAssets, "images/cylon_dot.png");
 
     int w = mWidth;
     int h = mHeight;
 
-    const Point c(w/2 , h/2);
+    const Point c(w / 2, h / 2);
     const GLint amplitude = 60;
-    const int scx = c.x - amplitude - mBrightSpot.w/2;
-    const int scy = c.y - mBrightSpot.h/2;
-    const int scw = amplitude*2 + mBrightSpot.w;
+    const int scx = c.x - amplitude - mBrightSpot.w / 2;
+    const int scy = c.y - mBrightSpot.h / 2;
+    const int scw = amplitude * 2 + mBrightSpot.w;
     const int sch = mBrightSpot.h;
-    const Rect updateRect(scx, h-scy-sch, scx+scw, h-scy);
+    const Rect updateRect(scx, h - scy - sch, scx + scw, h - scy);
 
     // erase screen
     glDisable(GL_SCISSOR_TEST);
@@ -314,33 +296,29 @@
 
     glClear(GL_COLOR_BUFFER_BIT);
 
-    eglSwapRectangleANDROID(mDisplay, mSurface,
-            updateRect.left, updateRect.top, 
-            updateRect.width(), updateRect.height());
+    mNativeWindowSurface->setSwapRectangle(updateRect.left,
+            updateRect.top, updateRect.width(), updateRect.height());
 
     glEnable(GL_SCISSOR_TEST);
     glEnable(GL_BLEND);
     glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
 
-
     // clear the screen to white
     Point p;
     float t = 0;
     float alpha = 1.0f;
     const nsecs_t startTime = systemTime();
     nsecs_t fadeTime = 0;
-    
-    do
-    {
+
+    do {
         // Set scissor in interesting area
-        glScissor(scx, scy, scw, sch); 
+        glScissor(scx, scy, scw, sch);
 
         // erase screen
         glClear(GL_COLOR_BUFFER_BIT);
 
-
         // compute wave
-        const float a = (t * 2*M_PI) - M_PI/2;
+        const float a = (t * 2 * M_PI) - M_PI / 2;
         const float sn = sinf(a);
         const float cs = cosf(a);
         GLint x = GLint(amplitude * sn);
@@ -350,50 +328,50 @@
 
         if (derivative > 0) {
             // vanishing trail...
-            p.x = (-amplitude + c.x) - mBrightSpot.w/2;
-            p.y = c.y-mLeftTrail.h/2;
-            float fade = 2.0f*(0.5f-t);
+            p.x = (-amplitude + c.x) - mBrightSpot.w / 2;
+            p.y = c.y - mLeftTrail.h / 2;
+            float fade = 2.0f * (0.5f - t);
             //fade *= fade;
             glColor4f(fade, fade, fade, fade);
             glBindTexture(GL_TEXTURE_2D, mLeftTrail.name);
             glDrawTexiOES(p.x, p.y, 0, mLeftTrail.w, mLeftTrail.h);
 
             // trail...
-            p.x = (x + c.x) - (mRightTrail.w + mBrightSpot.w/2) + 16;
-            p.y = c.y-mRightTrail.h/2;
-            fade = t<0.25f ? t*4.0f : 1.0f;
+            p.x = (x + c.x) - (mRightTrail.w + mBrightSpot.w / 2) + 16;
+            p.y = c.y - mRightTrail.h / 2;
+            fade = t < 0.25f ? t * 4.0f : 1.0f;
             fade *= fade;
             glColor4f(fade, fade, fade, fade);
             glBindTexture(GL_TEXTURE_2D, mRightTrail.name);
             glDrawTexiOES(p.x, p.y, 0, mRightTrail.w, mRightTrail.h);
-        } else { 
+        } else {
             // vanishing trail..
-            p.x = (amplitude + c.x) - (mRightTrail.w + mBrightSpot.w/2) + 16;
-            p.y = c.y-mRightTrail.h/2;
-            float fade = 2.0f*(0.5f-(t-0.5f));
+            p.x = (amplitude + c.x) - (mRightTrail.w + mBrightSpot.w / 2) + 16;
+            p.y = c.y - mRightTrail.h / 2;
+            float fade = 2.0f * (0.5f - (t - 0.5f));
             //fade *= fade;
             glColor4f(fade, fade, fade, fade);
             glBindTexture(GL_TEXTURE_2D, mRightTrail.name);
             glDrawTexiOES(p.x, p.y, 0, mRightTrail.w, mRightTrail.h);
 
             // trail...
-            p.x = (x + c.x) - mBrightSpot.w/2;
-            p.y = c.y-mLeftTrail.h/2;
-            fade = t<0.5f+0.25f ? (t-0.5f)*4.0f : 1.0f;
+            p.x = (x + c.x) - mBrightSpot.w / 2;
+            p.y = c.y - mLeftTrail.h / 2;
+            fade = t < 0.5f + 0.25f ? (t - 0.5f) * 4.0f : 1.0f;
             fade *= fade;
             glColor4f(fade, fade, fade, fade);
             glBindTexture(GL_TEXTURE_2D, mLeftTrail.name);
             glDrawTexiOES(p.x, p.y, 0, mLeftTrail.w, mLeftTrail.h);
         }
 
-        const Point p( x + c.x-mBrightSpot.w/2, c.y-mBrightSpot.h/2 );
+        const Point p(x + c.x - mBrightSpot.w / 2, c.y - mBrightSpot.h / 2);
         glBindTexture(GL_TEXTURE_2D, mBrightSpot.name);
-        glColor4f(1,0.5,0.5,1);
+        glColor4f(1, 0.5, 0.5, 1);
         glDrawTexiOES(p.x, p.y, 0, mBrightSpot.w, mBrightSpot.h);
 
         // update animation
         nsecs_t time = systemTime() - startTime;
-        t = ((4.0f/(360.0f*us2ns(16667))) * time);
+        t = ((4.0f / (360.0f * us2ns(16667))) * time);
         t = t - floorf(t);
 
         eglSwapBuffers(mDisplay, mSurface);
@@ -406,7 +384,7 @@
             alpha = 1.0f - ((float(time) * 6.0f) / float(s2ns(1)));
 
             session()->openTransaction();
-            mFlingerSurface->setAlpha(alpha*alpha);
+            mFlingerSurface->setAlpha(alpha * alpha);
             session()->closeTransaction();
         }
     } while (alpha > 0);
@@ -421,4 +399,5 @@
 
 // ---------------------------------------------------------------------------
 
-}; // namespace android
+}
+; // namespace android
diff --git a/libs/surfaceflinger/BootAnimation.h b/libs/surfaceflinger/BootAnimation.h
index a4a6d49..b20cea0 100644
--- a/libs/surfaceflinger/BootAnimation.h
+++ b/libs/surfaceflinger/BootAnimation.h
@@ -26,7 +26,8 @@
 #include <ui/ISurfaceComposer.h>
 #include <ui/SurfaceComposerClient.h>
 
-#include <GLES/egl.h>
+#include <EGL/egl.h>
+#include <GLES/gl.h>
 
 #include "Barrier.h"
 
@@ -35,6 +36,7 @@
 namespace android {
 
 class AssetManager;
+class EGLNativeWindowSurface;
 
 // ---------------------------------------------------------------------------
 
@@ -74,6 +76,7 @@
     EGLDisplay  mContext;
     EGLDisplay  mSurface;
     sp<Surface> mFlingerSurface;
+    sp<EGLNativeWindowSurface> mNativeWindowSurface;
     Barrier mBarrier;
 };
 
diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
index 92588fa..f14d7e9 100644
--- a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
+++ b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
@@ -21,14 +21,16 @@
 #include <string.h>
 #include <math.h>
 
-#include <GLES/egl.h>
-
 #include <cutils/properties.h>
 
 #include <utils/Log.h>
 
 #include <ui/EGLDisplaySurface.h>
 
+#include <GLES/gl.h>
+#include <EGL/eglext.h>
+
+
 #include "DisplayHardware/DisplayHardware.h"
 
 #include <hardware/copybit.h>
@@ -136,26 +138,19 @@
     const char* const egl_extensions = eglQueryString(
             display, EGL_EXTENSIONS);
     
-    const char* egl_extensions_config = egl_extensions;
-    
-    if (strstr(egl_extensions, "EGL_ANDROID_query_string_config")) {
-        egl_extensions_config = eglQueryStringConfigANDROID(
-                display, config, EGL_EXTENSIONS);
-    }
-
     LOGI("EGL informations:");
     LOGI("# of configs : %d", numConfigs);
     LOGI("vendor    : %s", eglQueryString(display, EGL_VENDOR));
     LOGI("version   : %s", eglQueryString(display, EGL_VERSION));
     LOGI("extensions: %s", egl_extensions);
-    LOGI("ext/config: %s", egl_extensions_config);
     LOGI("Client API: %s", eglQueryString(display, EGL_CLIENT_APIS)?:"Not Supported");
 
-    if (strstr(egl_extensions_config, "EGL_ANDROID_swap_rectangle")) {
-        mFlags |= SWAP_RECTANGLE_EXTENSION;
-        // TODO: get the real "update_on_demand" behavior
-        mFlags |= UPDATE_ON_DEMAND;
-    }
+    // TODO: get this from the devfb driver (probably should be HAL module)
+    mFlags |= SWAP_RECTANGLE_EXTENSION;
+    
+    // TODO: get the real "update_on_demand" behavior (probably should be HAL module)
+    mFlags |= UPDATE_ON_DEMAND;
+
     if (eglGetConfigAttrib(display, config, EGL_CONFIG_CAVEAT, &dummy) == EGL_TRUE) {
         if (dummy == EGL_SLOW_CONFIG)
             mFlags |= SLOW_CONFIG;
@@ -173,9 +168,6 @@
     if (eglQuerySurface(display, surface, EGL_SWAP_BEHAVIOR, &dummy) == EGL_TRUE) {
         if (dummy == EGL_BUFFER_PRESERVED) {
             mFlags |= BUFFER_PRESERVED;
-            if (strstr(egl_extensions_config, "EGL_ANDROID_copy_front_to_back")) {
-                mFlags |= COPY_BACK_EXTENSION;
-            }
         }
     }
     
@@ -330,8 +322,7 @@
 
     if (mFlags & SWAP_RECTANGLE_EXTENSION) {
         const Rect& b(newDirty.bounds());
-        eglSwapRectangleANDROID(
-                dpy, surface,
+        mDisplaySurface->setSwapRectangle(
                 b.left, b.top, b.width(), b.height());
     }
 
@@ -352,3 +343,11 @@
 {
     eglMakeCurrent(mDisplay, mSurface, mSurface, mContext);
 }
+
+void DisplayHardware::copyFrontToImage(const copybit_image_t& front) const {
+    mDisplaySurface->copyFrontToImage(front);
+}
+
+void DisplayHardware::copyBackToImage(const copybit_image_t& front) const {
+    mDisplaySurface->copyBackToImage(front);
+}
diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardware.h b/libs/surfaceflinger/DisplayHardware/DisplayHardware.h
index df97b60..550a4d1 100644
--- a/libs/surfaceflinger/DisplayHardware/DisplayHardware.h
+++ b/libs/surfaceflinger/DisplayHardware/DisplayHardware.h
@@ -22,7 +22,7 @@
 #include <ui/PixelFormat.h>
 #include <ui/Region.h>
 
-#include <GLES/egl.h>
+#include <EGL/egl.h>
 
 #include "DisplayHardware/DisplayHardwareBase.h"
 
@@ -39,7 +39,6 @@
 {
 public:
     enum {
-        COPY_BACK_EXTENSION     = 0x00000001,
         DIRECT_TEXTURE          = 0x00000002,
         SWAP_RECTANGLE_EXTENSION= 0x00000004,
         COPY_BITS_EXTENSION     = 0x00000008,
@@ -80,6 +79,9 @@
     copybit_device_t* getBlitEngine() const { return mBlitEngine; }
     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);
     }
diff --git a/libs/surfaceflinger/LayerBase.cpp b/libs/surfaceflinger/LayerBase.cpp
index bdefba3..0cf53f7 100644
--- a/libs/surfaceflinger/LayerBase.cpp
+++ b/libs/surfaceflinger/LayerBase.cpp
@@ -23,6 +23,11 @@
 #include <utils/Errors.h>
 #include <utils/Log.h>
 
+#include <GLES/gl.h>
+#include <GLES/glext.h>
+
+#include <hardware/hardware.h>
+
 #include "clz.h"
 #include "LayerBase.h"
 #include "LayerBlur.h"
@@ -111,6 +116,12 @@
         mDrawingState.h = h;
     }
 }
+void LayerBase::forceVisibilityTransaction() {
+    // this can be called without SurfaceFlinger.mStateLock, but if we
+    // can atomically increment the sequence number, it doesn't matter.
+    android_atomic_inc(&mCurrentState.sequence);
+    requestTransaction();
+}
 bool LayerBase::requestTransaction() {
     int32_t old = setTransactionFlags(eTransactionNeeded);
     return ((old & eTransactionNeeded) == 0);
@@ -350,6 +361,10 @@
             return;
         }        
     }
+
+    // reset GL state
+    glEnable(GL_SCISSOR_TEST);
+
     onDraw(clip);
 
     /*
@@ -391,6 +406,7 @@
     Rect r;
     Region::iterator iterator(clip);
     if (iterator) {
+        glEnable(GL_SCISSOR_TEST);
         glVertexPointer(2, GL_FIXED, 0, mVertices);
         while (iterator.iterate(&r)) {
             const GLint sy = fbHeight - (r.top + r.height());
@@ -401,7 +417,7 @@
 }
 
 void LayerBase::drawWithOpenGL(const Region& clip,
-        GLint textureName, const GGLSurface& t) const
+        GLint textureName, const GGLSurface& t, int transform) const
 {
     const DisplayHardware& hw(graphicPlane(0).displayHardware());
     const uint32_t fbHeight = hw.getHeight();
@@ -473,6 +489,12 @@
 
             glMatrixMode(GL_TEXTURE);
             glLoadIdentity();
+            
+            if (transform == HAL_TRANSFORM_ROT_90) {
+                glTranslatef(0, 1, 0);
+                glRotatef(-90, 0, 0, 1);
+            }
+
             if (!(mFlags & DisplayHardware::NPOT_EXTENSION)) {
                 // find the smallest power-of-two that will accommodate our surface
                 GLuint tw = 1 << (31 - clz(t.width));
diff --git a/libs/surfaceflinger/LayerBase.h b/libs/surfaceflinger/LayerBase.h
index 5e14dc8..a020f44 100644
--- a/libs/surfaceflinger/LayerBase.h
+++ b/libs/surfaceflinger/LayerBase.h
@@ -86,8 +86,8 @@
                 uint32_t        z;
                 uint8_t         alpha;
                 uint8_t         flags;
-                uint8_t         sequence;   // changes when visible regions can change
-                uint8_t         reserved;
+                uint8_t         reserved[2];
+                int32_t         sequence;   // changes when visible regions can change
                 uint32_t        tint;
                 Transform       transform;
                 Region          transparentRegion;
@@ -104,11 +104,11 @@
             
             void commitTransaction(bool skipSize);
             bool requestTransaction();
-
+            void forceVisibilityTransaction();
+            
             uint32_t getTransactionFlags(uint32_t flags);
             uint32_t setTransactionFlags(uint32_t flags);
             
-            void validateVisibility(const Transform& globalTransform);
             Rect visibleBounds() const;
             void drawRegion(const Region& reg) const;
 
@@ -162,7 +162,12 @@
      * the bitmap (as opposed to the size of the drawing state).
      */
     virtual Point getPhysicalSize() const;
-    
+
+    /**
+     * validateVisibility - cache a bunch of things
+     */
+    virtual void validateVisibility(const Transform& globalTransform);
+
     /**
      * lockPageFlip - called each time the screen is redrawn and returns whether
      * the visible regions need to be recomputed (this is a fairly heavy
@@ -188,10 +193,15 @@
      * needsBlending - true if this surface needs blending
      */
     virtual bool needsBlending() const  { return false; }
-    
+
     /**
-     * isSecure - true if this surface is secure, that is if it prevents a
-     * screenshot to be taken,
+     * transformed -- true is this surface needs a to be transformed
+     */
+    virtual bool transformed() const    { return mTransformed; }
+
+    /**
+     * isSecure - true if this surface is secure, that is if it prevents
+     * screenshots or vns servers.
      */
     virtual bool isSecure() const       { return false; }
 
@@ -210,7 +220,6 @@
     }
 
     int32_t  getOrientation() const { return mOrientation; }
-    bool transformed() const    { return mTransformed; }
     int  tx() const             { return mLeft; }
     int  ty() const             { return mTop; }
     
@@ -221,7 +230,9 @@
           GLuint createTexture() const;
     
           void drawWithOpenGL(const Region& clip,
-                  GLint textureName, const GGLSurface& surface) const;
+                  GLint textureName,
+                  const GGLSurface& surface,
+                  int transform = 0) const;
 
           void clearWithOpenGL(const Region& clip) const;
 
@@ -320,8 +331,7 @@
             *params = mParams;
         }
 
-        virtual status_t registerBuffers(int w, int h, int hstride, int vstride,
-                PixelFormat format, const sp<IMemoryHeap>& heap) 
+        virtual status_t registerBuffers(const ISurface::BufferHeap& buffers) 
                 { return INVALID_OPERATION; }
         virtual void postBuffer(ssize_t offset) { }
         virtual void unregisterBuffers() { };
diff --git a/libs/surfaceflinger/LayerBitmap.cpp b/libs/surfaceflinger/LayerBitmap.cpp
index 7c98857..e844350 100644
--- a/libs/surfaceflinger/LayerBitmap.cpp
+++ b/libs/surfaceflinger/LayerBitmap.cpp
@@ -69,18 +69,15 @@
         return NO_ERROR;
     }
 
+    PixelFormatInfo info;
+    getPixelFormatInfo(format, &info);
+
     uint32_t allocFlags = MemoryDealer::PAGE_ALIGNED;
     const uint32_t align = 4; // must match GL_UNPACK_ALIGNMENT
-    const uint32_t Bpp = bytesPerPixel(format);
+    const uint32_t Bpp = info.bytesPerPixel;
     uint32_t stride = (w + (alignment-1)) & ~(alignment-1);
     stride = ((stride * Bpp + (align-1)) & ~(align-1)) / Bpp;
-    size_t size = stride * h * Bpp;
-    if (format == PIXEL_FORMAT_YCbCr_422_SP ||
-        format == PIXEL_FORMAT_YCbCr_420_SP) {
-        // in YUV planar, bitsPerPixel is for the Y plane
-        size = (size * bitsPerPixel(format)) / 8;
-    }
-
+    size_t size = info.getScanlineSize(stride) * h;
     if (allocFlags & MemoryDealer::PAGE_ALIGNED) {
         size_t pagesize = getpagesize();
         size = (size + (pagesize-1)) & ~(pagesize-1);
diff --git a/libs/surfaceflinger/LayerBitmap.h b/libs/surfaceflinger/LayerBitmap.h
index 4c2eb50..9ad64c4 100644
--- a/libs/surfaceflinger/LayerBitmap.h
+++ b/libs/surfaceflinger/LayerBitmap.h
@@ -70,9 +70,6 @@
     void getBitmapSurface(copybit_image_t* img) const;
 
 private:
-    LayerBitmap(const LayerBitmap& rhs);
-    LayerBitmap& operator = (const LayerBitmap& rhs);
-
     sp<MemoryDealer>        mAllocator;
     sp<IMemory>             mBitsMemory;
     uint32_t                mAllocFlags;
diff --git a/libs/surfaceflinger/LayerBlur.cpp b/libs/surfaceflinger/LayerBlur.cpp
index efadbcf..d3e456f 100644
--- a/libs/surfaceflinger/LayerBlur.cpp
+++ b/libs/surfaceflinger/LayerBlur.cpp
@@ -23,6 +23,9 @@
 #include <utils/Errors.h>
 #include <utils/Log.h>
 
+#include <GLES/gl.h>
+#include <GLES/glext.h>
+
 #include "BlurFilter.h"
 #include "LayerBlur.h"
 #include "SurfaceFlinger.h"
diff --git a/libs/surfaceflinger/LayerBuffer.cpp b/libs/surfaceflinger/LayerBuffer.cpp
index c9cebf4..00fab70 100644
--- a/libs/surfaceflinger/LayerBuffer.cpp
+++ b/libs/surfaceflinger/LayerBuffer.cpp
@@ -25,6 +25,9 @@
 #include <utils/Log.h>
 #include <utils/StopWatch.h>
 
+#include <utils/IPCThreadState.h>
+#include <utils/IServiceManager.h>
+
 #include <ui/PixelFormat.h>
 #include <ui/EGLDisplaySurface.h>
 
@@ -129,18 +132,24 @@
     }
 }
 
+bool LayerBuffer::transformed() const
+{
+    sp<Source> source(getSource());
+    if (LIKELY(source != 0))
+        return source->transformed();
+    return false;
+}
+
 /**
  * This creates a "buffer" source for this surface
  */
-status_t LayerBuffer::registerBuffers(int w, int h, int hstride, int vstride,
-        PixelFormat format, const sp<IMemoryHeap>& memoryHeap)
+status_t LayerBuffer::registerBuffers(const ISurface::BufferHeap& buffers)
 {
     Mutex::Autolock _l(mLock);
     if (mSource != 0)
         return INVALID_OPERATION;
 
-    sp<BufferSource> source = new BufferSource(*this, w, h,
-            hstride, vstride, format, memoryHeap);
+    sp<BufferSource> source = new BufferSource(*this, buffers);
 
     status_t result = source->getStatus();
     if (result == NO_ERROR) {
@@ -194,13 +203,39 @@
     mOwner = 0;
 }
 
-status_t LayerBuffer::SurfaceBuffer::registerBuffers(
-        int w, int h, int hs, int vs,
-        PixelFormat format, const sp<IMemoryHeap>& heap)
+status_t LayerBuffer::SurfaceBuffer::onTransact(
+    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    switch (code) {
+        case REGISTER_BUFFERS:
+        case UNREGISTER_BUFFERS:
+        case CREATE_OVERLAY:
+        {
+            // codes that require permission check
+            IPCThreadState* ipc = IPCThreadState::self();
+            const int pid = ipc->getCallingPid();
+            const int self_pid = getpid();
+            if (LIKELY(pid != self_pid)) {
+                // we're called from a different process, do the real check
+                if (!checkCallingPermission(
+                        String16("android.permission.ACCESS_SURFACE_FLINGER")))
+                {
+                    const int uid = ipc->getCallingUid();
+                    LOGE("Permission Denial: "
+                            "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
+                    return PERMISSION_DENIED;
+                }
+            }
+        }
+    }
+    return LayerBaseClient::Surface::onTransact(code, data, reply, flags);
+}
+
+status_t LayerBuffer::SurfaceBuffer::registerBuffers(const ISurface::BufferHeap& buffers)
 {
     LayerBuffer* owner(getOwner());
     if (owner)
-        return owner->registerBuffers(w, h, hs, vs, format, heap);
+        return owner->registerBuffers(buffers);
     return NO_INIT;
 }
 
@@ -237,23 +272,20 @@
 // LayerBuffer::Buffer
 // ============================================================================
 
-LayerBuffer::Buffer::Buffer(const sp<IMemoryHeap>& heap, ssize_t offset,
-        int w, int h, int hs, int vs, int f)
-: mHeap(heap)
+LayerBuffer::Buffer::Buffer(const ISurface::BufferHeap& buffers, ssize_t offset)
+    : mBufferHeap(buffers)
 {
     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.crop.r = buffers.w;
+    src.crop.b = buffers.h;
+    src.img.w = buffers.hor_stride ?: buffers.w;
+    src.img.h = buffers.ver_stride ?: buffers.h;
+    src.img.format = buffers.format;
     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
+    src.img.base   = buffers.heap->base();
+    src.img.fd     = buffers.heap->heapID();
 }
 
 LayerBuffer::Buffer::~Buffer()
@@ -283,41 +315,55 @@
 }
 void LayerBuffer::Source::unregisterBuffers() {
 }
+bool LayerBuffer::Source::transformed() const {
+    return mLayer.mTransformed; 
+}
 
 // ---------------------------------------------------------------------------
 
 LayerBuffer::BufferSource::BufferSource(LayerBuffer& layer,
-        int w, int h, int hstride, int vstride,
-        PixelFormat format, const sp<IMemoryHeap>& memoryHeap)
-    : Source(layer), mStatus(NO_ERROR), mTextureName(-1U)
+        const ISurface::BufferHeap& buffers)
+    : Source(layer), mStatus(NO_ERROR), 
+      mBufferSize(0), mTextureName(-1U)
 {
-    if (memoryHeap == NULL) {
+    if (buffers.heap == NULL) {
         // this is allowed, but in this case, it is illegal to receive
         // postBuffer(). The surface just erases the framebuffer with
         // fully transparent pixels.
-        mHeap.clear();
-        mWidth = w;
-        mHeight = h;
+        mBufferHeap = buffers;
         mLayer.setNeedsBlending(false);
         return;
     }
 
-    status_t err = (memoryHeap->heapID() >= 0) ? NO_ERROR : NO_INIT;
+    status_t err = (buffers.heap->heapID() >= 0) ? NO_ERROR : NO_INIT;
     if (err != NO_ERROR) {
+        LOGE("LayerBuffer::BufferSource: invalid heap (%s)", strerror(err));
+        mStatus = err;
+        return;
+    }
+    
+    PixelFormatInfo info;
+    err = getPixelFormatInfo(buffers.format, &info);
+    if (err != NO_ERROR) {
+        LOGE("LayerBuffer::BufferSource: invalid format %d (%s)",
+                buffers.format, strerror(err));
         mStatus = err;
         return;
     }
 
-    // TODO: validate format/parameters
-    mHeap = memoryHeap;
-    mWidth = w;
-    mHeight = h;
-    mHStride = hstride;
-    mVStride = vstride;
-    mFormat = format;
-    PixelFormatInfo info;
-    getPixelFormatInfo(format, &info);
-    mLayer.setNeedsBlending((info.h_alpha - info.l_alpha) > 0);
+    if (buffers.hor_stride<0 || buffers.ver_stride<0) {
+        LOGE("LayerBuffer::BufferSource: invalid parameters "
+             "(w=%d, h=%d, xs=%d, ys=%d)", 
+             buffers.w, buffers.h, buffers.hor_stride, buffers.ver_stride);
+        mStatus = BAD_VALUE;
+        return;
+    }
+
+    mBufferHeap = buffers;
+    mLayer.setNeedsBlending((info.h_alpha - info.l_alpha) > 0);    
+    mBufferSize = info.getScanlineSize(buffers.hor_stride)*buffers.ver_stride;
+    mLayer.forceVisibilityTransaction();
+    
 }
 
 LayerBuffer::BufferSource::~BufferSource()
@@ -329,21 +375,24 @@
 
 void LayerBuffer::BufferSource::postBuffer(ssize_t offset)
 {    
-    sp<IMemoryHeap> heap;
-    int w, h, hs, vs, f;
+    ISurface::BufferHeap buffers;
     { // scope for the lock
         Mutex::Autolock _l(mLock);
-        w = mWidth;
-        h = mHeight;
-        hs= mHStride;
-        vs= mVStride;
-        f = mFormat;
-        heap = mHeap;
+        buffers = mBufferHeap;
+        if (buffers.heap != 0) {
+            const size_t memorySize = buffers.heap->getSize();
+            if ((size_t(offset) + mBufferSize) > memorySize) {
+                LOGE("LayerBuffer::BufferSource::postBuffer() "
+                     "invalid buffer (offset=%d, size=%d, heap-size=%d",
+                     int(offset), int(mBufferSize), int(memorySize));
+                return;
+            }
+        }
     }
 
     sp<Buffer> buffer;
-    if (heap != 0) {
-        buffer = new LayerBuffer::Buffer(heap, offset, w, h, hs, vs, f);
+    if (buffers.heap != 0) {
+        buffer = new LayerBuffer::Buffer(buffers, offset);
         if (buffer->getStatus() != NO_ERROR)
             buffer.clear();
         setBuffer(buffer);
@@ -354,7 +403,7 @@
 void LayerBuffer::BufferSource::unregisterBuffers()
 {
     Mutex::Autolock _l(mLock);
-    mHeap.clear();
+    mBufferHeap.heap.clear();
     mBuffer.clear();
     mLayer.invalidate();
 }
@@ -371,6 +420,11 @@
     mBuffer = buffer;
 }
 
+bool LayerBuffer::BufferSource::transformed() const
+{
+    return mBufferHeap.transform ? true : Source::transformed(); 
+}
+
 void LayerBuffer::BufferSource::onDraw(const Region& clip) const 
 {
     sp<Buffer> buffer(getBuffer());
@@ -417,7 +471,7 @@
             if (UNLIKELY(mTemporaryDealer == 0)) {
                 // allocate a memory-dealer for this the first time
                 mTemporaryDealer = mLayer.mFlinger->getSurfaceHeapManager()
-                ->createHeap(ISurfaceComposer::eHardware);
+                    ->createHeap(ISurfaceComposer::eHardware);
                 mTempBitmap.init(mTemporaryDealer);
             }
 
@@ -447,16 +501,31 @@
         copybit_image_t dst;
         hw.getDisplaySurface(&dst);
         const copybit_rect_t& drect
-        = reinterpret_cast<const copybit_rect_t&>(transformedBounds);
+            = reinterpret_cast<const copybit_rect_t&>(transformedBounds);
         const State& s(mLayer.drawingState());
         region_iterator it(clip);
-        copybit->set_parameter(copybit, COPYBIT_TRANSFORM, mLayer.getOrientation());
+        
+        // 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,
-                s.flags & ISurfaceComposer::eLayerDither ?
-                        COPYBIT_ENABLE : COPYBIT_DISABLE);
+        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 (!can_use_copybit || err) {
@@ -475,10 +544,11 @@
         t.data = (GGLubyte*)(intptr_t(src.img.base) + src.img.offset);
         const Region dirty(Rect(t.width, t.height));
         mLayer.loadTexture(dirty, mTextureName, t, w, h);
-        mLayer.drawWithOpenGL(clip, mTextureName, t);
+        mLayer.drawWithOpenGL(clip, mTextureName, t, mBufferHeap.transform);
     }
 }
 
+
 // ---------------------------------------------------------------------------
 
 LayerBuffer::OverlaySource::OverlaySource(LayerBuffer& layer,
diff --git a/libs/surfaceflinger/LayerBuffer.h b/libs/surfaceflinger/LayerBuffer.h
index 6e3d49f..2dc77f1 100644
--- a/libs/surfaceflinger/LayerBuffer.h
+++ b/libs/surfaceflinger/LayerBuffer.h
@@ -22,7 +22,7 @@
 
 #include <utils/IMemory.h>
 #include <private/ui/LayerState.h>
-#include <GLES/eglnatives.h>
+#include <EGL/eglnatives.h>
 
 #include "LayerBase.h"
 #include "LayerBitmap.h"
@@ -46,6 +46,7 @@
         virtual void onVisibilityResolved(const Transform& planeTransform);
         virtual void postBuffer(ssize_t offset);
         virtual void unregisterBuffers();
+        virtual bool transformed() const;
     protected:
         LayerBuffer& mLayer;
     };
@@ -67,9 +68,9 @@
     virtual void onDraw(const Region& clip) const;
     virtual uint32_t doTransaction(uint32_t flags);
     virtual void unlockPageFlip(const Transform& planeTransform, Region& outDirtyRegion);
+    virtual bool transformed() const;
 
-    status_t registerBuffers(int w, int h, int hstride, int vstride,
-            PixelFormat format, const sp<IMemoryHeap>& heap);
+    status_t registerBuffers(const ISurface::BufferHeap& buffers);
     void postBuffer(ssize_t offset);
     void unregisterBuffers();
     sp<OverlayRef> createOverlay(uint32_t w, uint32_t h, int32_t format);
@@ -89,10 +90,9 @@
 
     class Buffer : public LightRefBase<Buffer> {
     public:
-        Buffer(const sp<IMemoryHeap>& heap, ssize_t offset,
-                int w, int h, int hs, int vs, int f);
+        Buffer(const ISurface::BufferHeap& buffers, ssize_t offset);
         inline status_t getStatus() const {
-            return mHeap!=0 ? NO_ERROR : NO_INIT;
+            return mBufferHeap.heap!=0 ? NO_ERROR : NO_INIT;
         }
         inline const NativeBuffer& getBuffer() const {
             return mNativeBuffer;
@@ -103,15 +103,13 @@
         Buffer(const Buffer& rhs);
         ~Buffer();
     private:
-        sp<IMemoryHeap>    mHeap;
-        NativeBuffer       mNativeBuffer;
+        ISurface::BufferHeap    mBufferHeap;
+        NativeBuffer            mNativeBuffer;
     };
 
     class BufferSource : public Source {
     public:
-        BufferSource(LayerBuffer& layer,
-                int w, int h, int hstride, int vstride,
-                PixelFormat format, const sp<IMemoryHeap>& heap);
+        BufferSource(LayerBuffer& layer, const ISurface::BufferHeap& buffers);
         virtual ~BufferSource();
 
         status_t getStatus() const { return mStatus; }
@@ -121,16 +119,13 @@
         virtual void onDraw(const Region& clip) const;
         virtual void postBuffer(ssize_t offset);
         virtual void unregisterBuffers();
+        virtual bool transformed() const;
     private:
         mutable Mutex   mLock;
-        sp<IMemoryHeap> mHeap;
         sp<Buffer>      mBuffer;
         status_t        mStatus;
-        int             mWidth;
-        int             mHeight;
-        int             mHStride;
-        int             mVStride;
-        int             mFormat;
+        ISurface::BufferHeap mBufferHeap;
+        size_t          mBufferSize;
         mutable sp<MemoryDealer> mTemporaryDealer;
         mutable LayerBitmap mTempBitmap;
         mutable GLuint  mTextureName;
@@ -186,8 +181,9 @@
     public:
                 SurfaceBuffer(SurfaceID id, LayerBuffer* owner);
         virtual ~SurfaceBuffer();
-        virtual status_t registerBuffers(int w, int h, int hstride, int vstride,
-                PixelFormat format, const sp<IMemoryHeap>& heap);
+        virtual status_t onTransact(
+            uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags);
+        virtual status_t registerBuffers(const ISurface::BufferHeap& buffers);
         virtual void postBuffer(ssize_t offset);
         virtual void unregisterBuffers();
         virtual sp<OverlayRef> createOverlay(
diff --git a/libs/surfaceflinger/LayerOrientationAnim.cpp b/libs/surfaceflinger/LayerOrientationAnim.cpp
new file mode 100644
index 0000000..2b72d7c
--- /dev/null
+++ b/libs/surfaceflinger/LayerOrientationAnim.cpp
@@ -0,0 +1,287 @@
+/*
+ * 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 <utils/Errors.h>
+#include <utils/Log.h>
+
+#include <core/SkBitmap.h>
+
+#include <ui/EGLDisplaySurface.h>
+
+#include "LayerBase.h"
+#include "LayerOrientationAnim.h"
+#include "SurfaceFlinger.h"
+#include "DisplayHardware/DisplayHardware.h"
+#include "OrientationAnimation.h"
+
+namespace android {
+// ---------------------------------------------------------------------------
+
+const uint32_t LayerOrientationAnim::typeInfo = LayerBase::typeInfo | 0x80;
+const char* const LayerOrientationAnim::typeID = "LayerOrientationAnim";
+
+// ---------------------------------------------------------------------------
+
+LayerOrientationAnim::LayerOrientationAnim(
+        SurfaceFlinger* flinger, DisplayID display, 
+        OrientationAnimation* anim, 
+        const LayerBitmap& bitmap,
+        const LayerBitmap& bitmapIn)
+    : LayerBase(flinger, display), mAnim(anim), 
+      mBitmap(bitmap), mBitmapIn(bitmapIn), 
+      mTextureName(-1), mTextureNameIn(-1)
+{
+    mStartTime = systemTime();
+    mFinishTime = 0;
+    mOrientationCompleted = false;
+    mFirstRedraw = false;
+    mLastNormalizedTime = 0;
+    mLastScale = 0;
+    mNeedsBlending = false;
+}
+
+LayerOrientationAnim::~LayerOrientationAnim()
+{
+    if (mTextureName != -1U) {
+        LayerBase::deletedTextures.add(mTextureName);
+    }
+    if (mTextureNameIn != -1U) {
+        LayerBase::deletedTextures.add(mTextureNameIn);
+    }
+}
+
+bool LayerOrientationAnim::needsBlending() const 
+{
+    return mNeedsBlending; 
+}
+
+Point LayerOrientationAnim::getPhysicalSize() const
+{
+    const GraphicPlane& plane(graphicPlane(0));
+    const DisplayHardware& hw(plane.displayHardware());
+    return Point(hw.getWidth(), hw.getHeight());
+}
+
+void LayerOrientationAnim::validateVisibility(const Transform&)
+{
+    const Layer::State& s(drawingState());
+    const Transform tr(s.transform);
+    const Point size(getPhysicalSize());
+    uint32_t w = size.x;
+    uint32_t h = size.y;
+    mTransformedBounds = tr.makeBounds(w, h);
+    mLeft = tr.tx();
+    mTop  = tr.ty();
+    transparentRegionScreen.clear();
+    mTransformed = true;
+    mCanUseCopyBit = false;
+    copybit_device_t* copybit = mFlinger->getBlitEngine();
+    if (copybit) { 
+        mCanUseCopyBit = true;
+    }
+}
+
+void LayerOrientationAnim::onOrientationCompleted()
+{
+    mFinishTime = systemTime();
+    mOrientationCompleted = true;
+    mFirstRedraw = true;
+    mNeedsBlending = true;
+    mFlinger->invalidateLayerVisibility(this);
+}
+
+void LayerOrientationAnim::onDraw(const Region& clip) const
+{
+    // Animation...
+    const float MIN_SCALE = 0.5f;
+    const float DURATION = ms2ns(200);
+    const float BOUNCES_PER_SECOND = 1.618f;
+    const float BOUNCES_AMPLITUDE = 1.0f/32.0f;
+
+    const nsecs_t now = systemTime();
+    float scale, alpha;
+    
+    if (mOrientationCompleted) {
+        if (mFirstRedraw) {
+            mFirstRedraw = false;
+            
+            // make a copy of what's on screen
+            copybit_image_t image;
+            mBitmapIn.getBitmapSurface(&image);
+            const DisplayHardware& hw(graphicPlane(0).displayHardware());
+            hw.copyBackToImage(image);
+
+            // and erase the screen for this round
+            glDisable(GL_BLEND);
+            glDisable(GL_DITHER);
+            glDisable(GL_SCISSOR_TEST);
+            glClearColor(0,0,0,0);
+            glClear(GL_COLOR_BUFFER_BIT);
+            
+            // FIXME: code below is gross
+            mNeedsBlending = false;
+            LayerOrientationAnim* self(const_cast<LayerOrientationAnim*>(this));
+            mFlinger->invalidateLayerVisibility(self);
+        }
+
+        // make sure pick-up where we left off
+        const float duration = DURATION * mLastNormalizedTime;
+        const float normalizedTime = (float(now - mFinishTime) / duration);
+        if (normalizedTime <= 1.0f) {
+            const float squaredTime = normalizedTime*normalizedTime;
+            scale = (1.0f - mLastScale)*squaredTime + mLastScale;
+            alpha = (1.0f - normalizedTime);
+            alpha *= alpha;
+            alpha *= alpha;
+        } else {
+            mAnim->onAnimationFinished();
+            scale = 1.0f;
+            alpha = 0.0f;
+        }
+    } else {
+        const float normalizedTime = float(now - mStartTime) / DURATION;
+        if (normalizedTime <= 1.0f) {
+            mLastNormalizedTime = normalizedTime;
+            const float squaredTime = normalizedTime*normalizedTime;
+            scale = (MIN_SCALE-1.0f)*squaredTime + 1.0f;
+            alpha = 1.0f;
+        } else {
+            mLastNormalizedTime = 1.0f;
+            const float to_seconds = DURATION / seconds(1);
+            const float phi = BOUNCES_PER_SECOND * 
+                    (((normalizedTime - 1.0f) * to_seconds)*M_PI*2);
+            scale = MIN_SCALE + BOUNCES_AMPLITUDE * (1.0f - cosf(phi));
+            alpha = 1.0f;
+        }
+        mLastScale = scale;
+    }
+    drawScaled(scale, alpha);
+}
+
+void LayerOrientationAnim::drawScaled(float f, float alpha) const
+{
+    copybit_image_t dst;
+    const GraphicPlane& plane(graphicPlane(0));
+    const DisplayHardware& hw(plane.displayHardware());
+    hw.getDisplaySurface(&dst);
+
+    // clear screen
+    // TODO: with update on demand, we may be able 
+    // to not erase the screen at all during the animation 
+    if (!mOrientationCompleted) {
+        glDisable(GL_BLEND);
+        glDisable(GL_DITHER);
+        glDisable(GL_SCISSOR_TEST);
+        glClearColor(0,0,0,0);
+        glClear(GL_COLOR_BUFFER_BIT);
+    }
+    
+    const int w = dst.w*f; 
+    const int h = dst.h*f; 
+    const int xc = uint32_t(dst.w-w)/2;
+    const int yc = uint32_t(dst.h-h)/2;
+    const copybit_rect_t drect = { xc, yc, xc+w, yc+h }; 
+
+    copybit_image_t src;
+    mBitmap.getBitmapSurface(&src);
+    const copybit_rect_t srect = { 0, 0, src.w, src.h };
+
+    int err = NO_ERROR;
+    const int can_use_copybit = canUseCopybit();
+    if (can_use_copybit)  {
+        copybit_device_t* copybit = mFlinger->getBlitEngine();
+        copybit->set_parameter(copybit, COPYBIT_TRANSFORM, 0);
+        copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_ENABLE);
+
+        if (alpha < 1.0f) {
+            copybit_image_t srcIn;
+            mBitmapIn.getBitmapSurface(&srcIn);
+            region_iterator it(Region(Rect( drect.l, drect.t, drect.r, drect.b )));
+            copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, 0xFF);
+            err = copybit->stretch(copybit, &dst, &srcIn, &drect, &srect, &it);
+        }
+
+        if (!err && alpha > 0.0f) {
+            region_iterator it(Region(Rect( drect.l, drect.t, drect.r, drect.b )));
+            copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, int(alpha*255));
+            err = copybit->stretch(copybit, &dst, &src, &drect, &srect, &it);
+        }
+        LOGE_IF(err != NO_ERROR, "copybit failed (%s)", strerror(err));
+    }
+    if (!can_use_copybit || err) {   
+        GGLSurface t;
+        t.version = sizeof(GGLSurface);
+        t.width  = src.w;
+        t.height = src.h;
+        t.stride = src.w;
+        t.vstride= src.h;
+        t.format = src.format;
+        t.data = (GGLubyte*)(intptr_t(src.base) + src.offset);
+
+        Transform tr;
+        tr.set(f,0,0,f);
+        tr.set(xc, yc);
+        
+        // FIXME: we should not access mVertices and mDrawingState like that,
+        // but since we control the animation, we know it's going to work okay.
+        // eventually we'd need a more formal way of doing things like this.
+        LayerOrientationAnim& self(const_cast<LayerOrientationAnim&>(*this));
+        tr.transform(self.mVertices[0], 0, 0);
+        tr.transform(self.mVertices[1], 0, src.h);
+        tr.transform(self.mVertices[2], src.w, src.h);
+        tr.transform(self.mVertices[3], src.w, 0);
+        if (!(mFlags & DisplayHardware::SLOW_CONFIG)) {
+            // Too slow to do this in software
+            self.mDrawingState.flags |= ISurfaceComposer::eLayerFilter;
+        }
+
+        if (alpha < 1.0f) {
+            copybit_image_t src;
+            mBitmapIn.getBitmapSurface(&src);
+            t.data = (GGLubyte*)(intptr_t(src.base) + src.offset);
+            if (UNLIKELY(mTextureNameIn == -1LU)) {
+                mTextureNameIn = createTexture();
+                GLuint w=0, h=0;
+                const Region dirty(Rect(t.width, t.height));
+                loadTexture(dirty, mTextureNameIn, t, w, h);
+            }
+            self.mDrawingState.alpha = 255;
+            const Region clip(Rect( drect.l, drect.t, drect.r, drect.b ));
+            drawWithOpenGL(clip, mTextureName, t);
+        }
+
+        t.data = (GGLubyte*)(intptr_t(src.base) + src.offset);
+        if (UNLIKELY(mTextureName == -1LU)) {
+            mTextureName = createTexture();
+            GLuint w=0, h=0;
+            const Region dirty(Rect(t.width, t.height));
+            loadTexture(dirty, mTextureName, t, w, h);
+        }
+        self.mDrawingState.alpha = int(alpha*255);
+        const Region clip(Rect( drect.l, drect.t, drect.r, drect.b ));
+        drawWithOpenGL(clip, mTextureName, t);
+    }
+}
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
diff --git a/libs/surfaceflinger/LayerOrientationAnim.h b/libs/surfaceflinger/LayerOrientationAnim.h
new file mode 100644
index 0000000..7367685
--- /dev/null
+++ b/libs/surfaceflinger/LayerOrientationAnim.h
@@ -0,0 +1,75 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_LAYER_ORIENTATION_ANIM_H
+#define ANDROID_LAYER_ORIENTATION_ANIM_H
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <utils/threads.h>
+#include <utils/Parcel.h>
+
+#include "LayerBase.h"
+#include "LayerBitmap.h"
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+class OrientationAnimation;
+
+class LayerOrientationAnim : public LayerBase
+{
+public:    
+    static const uint32_t typeInfo;
+    static const char* const typeID;
+    virtual char const* getTypeID() const { return typeID; }
+    virtual uint32_t getTypeInfo() const { return typeInfo; }
+    
+                LayerOrientationAnim(SurfaceFlinger* flinger, DisplayID display,
+                        OrientationAnimation* anim, 
+                        const LayerBitmap& zoomOut,
+                        const LayerBitmap& zoomIn);
+        virtual ~LayerOrientationAnim();
+
+            void onOrientationCompleted();
+
+    virtual void onDraw(const Region& clip) const;
+    virtual Point getPhysicalSize() const;
+    virtual void validateVisibility(const Transform& globalTransform);
+    virtual bool needsBlending() const;
+    virtual bool isSecure() const       { return false; }
+private:
+    void drawScaled(float scale, float alpha) const;
+
+    OrientationAnimation* mAnim;
+    LayerBitmap mBitmap;
+    LayerBitmap mBitmapIn;
+    nsecs_t mStartTime;
+    nsecs_t mFinishTime;
+    bool mOrientationCompleted;
+    mutable bool mFirstRedraw;
+    mutable float mLastNormalizedTime;
+    mutable float mLastScale;
+    mutable GLuint  mTextureName;
+    mutable GLuint  mTextureNameIn;
+    mutable bool mNeedsBlending;
+};
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // ANDROID_LAYER_ORIENTATION_ANIM_H
diff --git a/libs/surfaceflinger/LayerScreenshot.h b/libs/surfaceflinger/LayerScreenshot.h
deleted file mode 100644
index 2d9a8ec..0000000
--- a/libs/surfaceflinger/LayerScreenshot.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef ANDROID_LAYER_SCREENSHOT_H
-#define ANDROID_LAYER_SCREENSHOT_H
-
-#include <stdint.h>
-#include <sys/types.h>
-#include <utils/threads.h>
-#include <utils/Parcel.h>
-
-#include "LayerBase.h"
-
-namespace android {
-
-// ---------------------------------------------------------------------------
-
-class LayerScreenshot : public LayerBase
-{
-public:    
-    static const uint32_t typeInfo;
-    static const char* const typeID;
-    virtual char const* getTypeID() const { return typeID; }
-    virtual uint32_t getTypeInfo() const { return typeInfo; }
-    
-                LayerScreenshot(SurfaceFlinger* flinger, DisplayID display);
-        virtual ~LayerScreenshot();
-
-    virtual void onDraw(const Region& clip) const;
-    virtual bool needsBlending() const  { return true; }
-    virtual bool isSecure() const       { return false; }
-
-    void takeScreenshot(Mutex& lock, Parcel* reply);
-    
-private:
-    mutable Condition   mCV;
-    Parcel*             mReply;
-};
-
-// ---------------------------------------------------------------------------
-
-}; // namespace android
-
-#endif // ANDROID_LAYER_SCREENSHOT_H
diff --git a/libs/surfaceflinger/OrientationAnimation.cpp b/libs/surfaceflinger/OrientationAnimation.cpp
new file mode 100644
index 0000000..f6f1326
--- /dev/null
+++ b/libs/surfaceflinger/OrientationAnimation.cpp
@@ -0,0 +1,155 @@
+/*
+ * 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 <stdint.h>
+#include <sys/types.h>
+#include <limits.h>
+
+#include "LayerOrientationAnim.h"
+#include "OrientationAnimation.h"
+#include "SurfaceFlinger.h"
+#include "VRamHeap.h"
+
+#include "DisplayHardware/DisplayHardware.h"
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+OrientationAnimation::OrientationAnimation(const sp<SurfaceFlinger>& flinger)
+    : mFlinger(flinger), mLayerOrientationAnim(NULL), mState(DONE)
+{
+    // allocate a memory-dealer for this the first time
+    mTemporaryDealer = mFlinger->getSurfaceHeapManager()->createHeap(
+            ISurfaceComposer::eHardware);
+}
+
+OrientationAnimation::~OrientationAnimation()
+{
+}
+
+void OrientationAnimation::onOrientationChanged()
+{
+    if (mState == DONE)
+        mState = PREPARE;
+}
+
+void OrientationAnimation::onAnimationFinished()
+{
+    if (mState != DONE)
+        mState = FINISH;
+}
+
+bool OrientationAnimation::run_impl()
+{
+    bool skip_frame;
+    switch (mState) {
+        default:
+        case DONE:
+            skip_frame = done();
+            break;
+        case PREPARE:
+            skip_frame = prepare();
+            break;
+        case PHASE1:
+            skip_frame = phase1();
+            break;
+        case PHASE2:
+            skip_frame = phase2();
+            break;
+        case FINISH:
+            skip_frame = finished();
+            break;
+    }
+    return skip_frame;
+}
+
+bool OrientationAnimation::done()
+{
+    if (mFlinger->isFrozen()) {
+        // we are not allowed to draw, but pause a bit to make sure
+        // apps don't end up using the whole CPU, if they depend on
+        // surfaceflinger for synchronization.
+        usleep(8333); // 8.3ms ~ 120fps
+        return true;
+    }
+    return false;
+}
+
+bool OrientationAnimation::prepare()
+{
+    mState = PHASE1;
+    
+    const GraphicPlane& plane(mFlinger->graphicPlane(0));
+    const DisplayHardware& hw(plane.displayHardware());
+    const uint32_t w = hw.getWidth();
+    const uint32_t h = hw.getHeight();
+
+    LayerBitmap bitmap;
+    bitmap.init(mTemporaryDealer);
+    bitmap.setBits(w, h, 1, hw.getFormat());
+
+    LayerBitmap bitmapIn;
+    bitmapIn.init(mTemporaryDealer);
+    bitmapIn.setBits(w, h, 1, hw.getFormat());
+
+    copybit_image_t front;
+    bitmap.getBitmapSurface(&front);
+    hw.copyFrontToImage(front);
+
+    LayerOrientationAnim* l = new LayerOrientationAnim(
+            mFlinger.get(), 0, this, bitmap, bitmapIn);
+    l->initStates(w, h, 0);
+    l->setLayer(INT_MAX-1);
+    mFlinger->addLayer(l);
+    mLayerOrientationAnim = l;
+    return true;
+}
+
+bool OrientationAnimation::phase1()
+{
+    if (mFlinger->isFrozen() == false) {
+        // start phase 2
+        mState = PHASE2;
+        mLayerOrientationAnim->onOrientationCompleted();
+        mLayerOrientationAnim->invalidate();
+        return true;
+        
+    }
+    mLayerOrientationAnim->invalidate();
+    return false;
+}
+
+bool OrientationAnimation::phase2()
+{
+    // do the 2nd phase of the animation
+    mLayerOrientationAnim->invalidate();
+    return false;
+}
+
+bool OrientationAnimation::finished()
+{
+    mState = DONE;
+    mFlinger->removeLayer(mLayerOrientationAnim);
+    mLayerOrientationAnim = NULL;
+    return true;
+}
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
diff --git a/libs/surfaceflinger/OrientationAnimation.h b/libs/surfaceflinger/OrientationAnimation.h
new file mode 100644
index 0000000..ba33fce
--- /dev/null
+++ b/libs/surfaceflinger/OrientationAnimation.h
@@ -0,0 +1,73 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_ORIENTATION_ANIMATION_H
+#define ANDROID_ORIENTATION_ANIMATION_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include "SurfaceFlinger.h"
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+class SurfaceFlinger;
+class MemoryDealer;
+class LayerOrientationAnim;
+
+class OrientationAnimation
+{
+public:    
+                 OrientationAnimation(const sp<SurfaceFlinger>& flinger);
+        virtual ~OrientationAnimation();
+
+   void onOrientationChanged();
+   void onAnimationFinished();
+   inline bool run() {
+       if (LIKELY(mState == DONE))
+           return false;
+       return run_impl();
+   }
+
+private:
+    enum {
+        DONE = 0,
+        PREPARE,
+        PHASE1,
+        PHASE2,
+        FINISH
+    };
+
+    bool run_impl();
+    bool done();
+    bool prepare();
+    bool phase1();
+    bool phase2();
+    bool finished();
+
+    sp<SurfaceFlinger> mFlinger;
+    sp<MemoryDealer> mTemporaryDealer;
+    LayerOrientationAnim* mLayerOrientationAnim;
+    int mState;
+};
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // ANDROID_ORIENTATION_ANIMATION_H
diff --git a/libs/surfaceflinger/RFBServer.cpp b/libs/surfaceflinger/RFBServer.cpp
deleted file mode 100644
index c2c1989..0000000
--- a/libs/surfaceflinger/RFBServer.cpp
+++ /dev/null
@@ -1,722 +0,0 @@
-/*
- * 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 "RFBServer"
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdint.h>
-#include <errno.h>
-#include <fcntl.h>
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-
-#include <netinet/in.h>
-
-#include <cutils/sockets.h>
-
-#include <utils/Log.h>
-#include <ui/Rect.h>
-
-#ifdef HAVE_ANDROID_OS
-#include <linux/input.h>
-#endif
-
-#include "RFBServer.h"
-#include "SurfaceFlinger.h"
-
-/* BUG=773511: this is a temporary hack required while developing the new
-   set of "clean kernel headers" for the Bionic C library. */
-#ifndef KEY_STAR
-#define KEY_STAR    227
-#endif
-#ifndef KEY_SHARP
-#define KEY_SHARP   228
-#endif
-#ifndef KEY_SOFT1
-#define KEY_SOFT1   229
-#endif
-#ifndef KEY_SOFT2
-#define KEY_SOFT2   230
-#endif
-#ifndef KEY_CENTER
-#define KEY_CENTER  232
-#endif
-
-// ----------------------------------------------------------------------------
-
-#define DEBUG_MSG   0
-
-// ----------------------------------------------------------------------------
-
-namespace android {
-
-const int VNC_PORT = 5900;
-
-RFBServer::RFBServer(uint32_t w, uint32_t h, android::PixelFormat format)
-    : Thread(false), mFD(-1), mStatus(NO_INIT), mIoVec(0)
-{
-    mFrameBuffer.version = sizeof(mFrameBuffer);
-    mFrameBuffer.width = w;
-    mFrameBuffer.height = h;
-    mFrameBuffer.stride = w;
-    mFrameBuffer.format = format;
-    mFrameBuffer.data = 0;
-}
-
-RFBServer::~RFBServer()
-{
-    if (mRobinThread != 0) {
-        // ask the thread to exit first
-        mRobinThread->exitAndWait();
-    }
-
-    free(mFrameBuffer.data);
-
-    delete [] mIoVec;
-}
-
-void RFBServer::onFirstRef()
-{
-    run("Batman");
-}
-
-status_t RFBServer::readyToRun()
-{
-    LOGI("RFB server ready to run");
-    return NO_ERROR;
-}
-
-bool RFBServer::threadLoop()
-{
-    struct sockaddr addr;
-    socklen_t alen;
-    int serverfd = -1;
-    int port = VNC_PORT;
-
-    do {
-        retry:
-        if (serverfd < 0) {
-            serverfd = socket_loopback_server(port, SOCK_STREAM);
-            if (serverfd < 0) {
-                if ((errno == EADDRINUSE) && (port < (VNC_PORT+10))) {
-                    LOGW("port %d already in use, trying %d", port, port+1);
-                    port++;
-                    goto retry;
-                }
-                LOGE("couldn't create socket, port=%d, error %d (%s)",
-                        port, errno, strerror(errno));
-                sleep(1);
-                break;
-            }
-            fcntl(serverfd, F_SETFD, FD_CLOEXEC);
-        }
-
-        alen = sizeof(addr);
-        mFD = accept(serverfd, &addr, &alen);
-
-        if (mFD < 0) {
-            LOGE("couldn't accept(), error %d (%s)", errno, strerror(errno));
-            // we could have run out of file descriptors, wait a bit and
-            // try again.
-            sleep(1);
-            goto retry;
-        }
-        fcntl(mFD, F_SETFD, FD_CLOEXEC);
-
-        // send protocol version and Authentication method
-        mStatus = NO_ERROR;
-        handshake(3, 3, Authentication::None);
-
-        if (alive()) {
-            // create the thread we use to send data to the client
-            mRobinThread = new ServerThread(this);
-        }
-
-        while( alive() ) {
-            // client message must be destroyed at each iteration
-            // (most of the time this is a no-op)
-            ClientMessage msg;
-            waitForClientMessage(msg);
-            if (alive()) {
-                handleClientMessage(msg);
-            }
-        }
-
-    } while( alive() );
-
-    // free-up some resources
-    if (mRobinThread != 0) {
-        mRobinThread->exitAndWait();
-        mRobinThread.clear();
-    }
-
-    free(mFrameBuffer.data);
-    mFrameBuffer.data = 0;
-
-    close(mFD);
-    close(serverfd);
-    mFD = -1;
-
-    // we'll try again
-    return true;
-}
-
-// ----------------------------------------------------------------------------
-
-RFBServer::ServerThread::ServerThread(const sp<RFBServer>& receiver)
-            : Thread(false), mReceiver(receiver)
-{
-    LOGD("RFB Server Thread created");
-}
-
-RFBServer::ServerThread::~ServerThread()
-{
-    LOGD("RFB Server Thread destroyed");
-}
-
-void RFBServer::ServerThread::onFirstRef()
-{
-    mUpdateBarrier.close();
-    run("Robin");
-}
-
-status_t RFBServer::ServerThread::readyToRun()
-{
-    return NO_ERROR;
-}
-
-void RFBServer::ServerThread::wake()
-{
-    mUpdateBarrier.open();
-}
-
-void RFBServer::ServerThread::exitAndWait()
-{
-    requestExit();
-    mUpdateBarrier.open();
-    requestExitAndWait();
-}
-
-bool RFBServer::ServerThread::threadLoop()
-{
-    sp<RFBServer> receiver(mReceiver.promote());
-    if (receiver == 0)
-        return false;
-
-    // wait for something to do
-    mUpdateBarrier.wait();
-
-    // we're asked to quit, abort everything
-    if (exitPending())
-        return false;
-
-    mUpdateBarrier.close();
-
-    // process updates
-    receiver->sendFrameBufferUpdates();
-    return !exitPending();
-}
-
-// ----------------------------------------------------------------------------
-
-void RFBServer::handshake(uint8_t major, uint8_t minor, uint32_t auth)
-{
-    ProtocolVersion protocolVersion(major, minor);
-    if( !write(protocolVersion) )
-        return;
-
-    if ( !read(protocolVersion) )
-        return;
-
-    int maj, min;
-    if ( protocolVersion.decode(maj, min) != NO_ERROR ) {
-        mStatus = -1;
-        return;
-    }
-
-#if DEBUG_MSG
-    LOGD("client protocol string: <%s>", (char*)protocolVersion.payload());
-    LOGD("client wants protocol version %d.%d\n", maj, min);
-#endif
-
-    Authentication authentication(auth);
-    if( !write(authentication) )
-        return;
-
-    ClientInitialization clientInit;
-    if ( !read(clientInit) )
-        return;
-
-#if DEBUG_MSG
-    LOGD("client initialization: sharedFlags = %d\n", clientInit.sharedFlags());
-#endif
-
-    ServerInitialization serverInit("Android RFB");
-    ServerInitialization::Payload& message(serverInit.message());
-        message.framebufferWidth = htons(mFrameBuffer.width);
-        message.framebufferHeight = htons(mFrameBuffer.height);
-        message.serverPixelFormat.bitsPerPixel = 16;
-        message.serverPixelFormat.depth = 16;
-        message.serverPixelFormat.bigEndianFlag = 0;
-        message.serverPixelFormat.trueColorFlag = 1;
-        message.serverPixelFormat.redMax   = htons((1<<5)-1);
-        message.serverPixelFormat.greenMax = htons((1<<6)-1);
-        message.serverPixelFormat.blueMax  = htons((1<<5)-1);
-        message.serverPixelFormat.redShift     = 11;
-        message.serverPixelFormat.greenShift   = 5;
-        message.serverPixelFormat.blueShift    = 0;
-
-    mIoVec = new iovec[mFrameBuffer.height];
-
-    write(serverInit);
-}
-
-void RFBServer::handleClientMessage(const ClientMessage& msg)
-{
-    switch(msg.type()) {
-    case SET_PIXEL_FORMAT:
-        handleSetPixelFormat(msg.messages().setPixelFormat);
-        break;
-    case SET_ENCODINGS:
-        handleSetEncodings(msg.messages().setEncodings);
-        break;
-    case FRAME_BUFFER_UPDATE_REQ:
-        handleFrameBufferUpdateReq(msg.messages().frameBufferUpdateRequest);
-        break;
-    case KEY_EVENT:
-        handleKeyEvent(msg.messages().keyEvent);
-        break;
-    }
-}
-
-void RFBServer::handleSetPixelFormat(const SetPixelFormat& msg)
-{
-    if (!validatePixelFormat(msg.pixelFormat)) {
-        LOGE("The builtin VNC server only supports the RGB 565 pixel format");
-        LOGD("requested pixel format:");
-        LOGD("bitsPerPixel:     %d", msg.pixelFormat.bitsPerPixel);
-        LOGD("depth:            %d", msg.pixelFormat.depth);
-        LOGD("bigEndianFlag:    %d", msg.pixelFormat.bigEndianFlag);
-        LOGD("trueColorFlag:    %d", msg.pixelFormat.trueColorFlag);
-        LOGD("redmax:           %d", ntohs(msg.pixelFormat.redMax));
-        LOGD("bluemax:          %d", ntohs(msg.pixelFormat.greenMax));
-        LOGD("greenmax:         %d", ntohs(msg.pixelFormat.blueMax));
-        LOGD("redshift:         %d", msg.pixelFormat.redShift);
-        LOGD("greenshift:       %d", msg.pixelFormat.greenShift);
-        LOGD("blueshift:        %d", msg.pixelFormat.blueShift);
-        mStatus = -1;
-    }
-}
-
-bool RFBServer::validatePixelFormat(const PixelFormat& pf)
-{
-    if ((pf.bitsPerPixel != 16) || (pf.depth != 16))
-        return false;
-
-    if (pf.bigEndianFlag || !pf.trueColorFlag)
-        return false;
-
-    if (ntohs(pf.redMax)!=0x1F ||
-        ntohs(pf.greenMax)!=0x3F ||
-        ntohs(pf.blueMax)!=0x1F) {
-        return false;
-    }
-
-    if (pf.redShift!=11 || pf.greenShift!=5 || pf.blueShift!=0)
-        return false;
-
-    return true;
-}
-
-void RFBServer::handleSetEncodings(const SetEncodings& msg)
-{
-    /* From the RFB specification:
-        Sets the encoding types in which pixel data can be sent by the server.
-        The order of the encoding types given in this message is a hint by the
-        client as to its preference (the first encoding specified being most
-        preferred). The server may or may not choose to make use of this hint.
-        Pixel data may always be sent in raw encoding even if not specified
-        explicitly here.
-    */
-
-    LOGW("SetEncodings received. Only RAW is supported.");
-}
-
-void RFBServer::handleFrameBufferUpdateReq(const FrameBufferUpdateRequest& msg)
-{
-#if DEBUG_MSG
-    LOGD("handle FrameBufferUpdateRequest");
-#endif
-
-    Rect r;
-    r.left = ntohs(msg.x);
-    r.top = ntohs(msg.y);
-    r.right = r.left + ntohs(msg.width);
-    r.bottom = r.top + ntohs(msg.height);
-
-    Mutex::Autolock _l(mRegionLock);
-    mClientRegionRequest.set(r);
-    if (!msg.incremental)
-        mDirtyRegion.orSelf(r);
-
-    mRobinThread->wake();
-}
-
-void RFBServer::handleKeyEvent(const KeyEvent& msg)
-{
-#ifdef HAVE_ANDROID_OS
-
-    int scancode = 0;
-    int code = ntohl(msg.key);
-
-    if (code>='0' && code<='9') {
-        scancode = (code & 0xF) - 1;
-        if (scancode<0) scancode += 10;
-        scancode += KEY_1;
-    } else if (code>=0xFF50 && code<=0xFF58) {
-        static const uint16_t map[] =
-             {  KEY_HOME, KEY_LEFT, KEY_UP, KEY_RIGHT, KEY_DOWN,
-                KEY_SOFT1, KEY_SOFT2, KEY_END, 0 };
-        scancode = map[code & 0xF];
-    } else if (code>=0xFFE1 && code<=0xFFEE) {
-        static const uint16_t map[] =
-             {  KEY_LEFTSHIFT, KEY_LEFTSHIFT,
-                KEY_COMPOSE, KEY_COMPOSE,
-                KEY_LEFTSHIFT, KEY_LEFTSHIFT,
-                0,0,
-                KEY_LEFTALT, KEY_RIGHTALT,
-                0, 0, 0, 0 };
-        scancode = map[code & 0xF];
-    } else if ((code>='A' && code<='Z') || (code>='a' && code<='z')) {
-        static const uint16_t map[] = {
-                KEY_A, KEY_B, KEY_C, KEY_D, KEY_E,
-                KEY_F, KEY_G, KEY_H, KEY_I, KEY_J,
-                KEY_K, KEY_L, KEY_M, KEY_N, KEY_O,
-                KEY_P, KEY_Q, KEY_R, KEY_S, KEY_T,
-                KEY_U, KEY_V, KEY_W, KEY_X, KEY_Y, KEY_Z };
-        scancode = map[(code & 0x5F) - 'A'];
-    } else {
-        switch (code) {
-            case 0x0003:    scancode = KEY_CENTER;      break;
-            case 0x0020:    scancode = KEY_SPACE;       break;
-            case 0x0023:    scancode = KEY_SHARP;       break;
-            case 0x0033:    scancode = KEY_SHARP;       break;
-            case 0x002C:    scancode = KEY_COMMA;       break;
-            case 0x003C:    scancode = KEY_COMMA;       break;
-            case 0x002E:    scancode = KEY_DOT;         break;
-            case 0x003E:    scancode = KEY_DOT;         break;
-            case 0x002F:    scancode = KEY_SLASH;       break;
-            case 0x003F:    scancode = KEY_SLASH;       break;
-            case 0x0032:    scancode = KEY_EMAIL;       break;
-            case 0x0040:    scancode = KEY_EMAIL;       break;
-            case 0xFF08:    scancode = KEY_BACKSPACE;   break;
-            case 0xFF1B:    scancode = KEY_BACK;        break;
-            case 0xFF09:    scancode = KEY_TAB;         break;
-            case 0xFF0D:    scancode = KEY_ENTER;       break;
-            case 0x002A:    scancode = KEY_STAR;        break;
-            case 0xFFBE:    scancode = KEY_SEND;        break; // F1
-            case 0xFFBF:    scancode = KEY_END;         break; // F2
-            case 0xFFC0:    scancode = KEY_HOME;        break; // F3
-            case 0xFFC5:    scancode = KEY_POWER;       break; // F8
-        }
-    }
-
-#if DEBUG_MSG
-   LOGD("handle KeyEvent 0x%08x, %d, scancode=%d\n", code, msg.downFlag, scancode);
-#endif
-
-    if (scancode) {
-        mEventInjector.injectKey(uint16_t(scancode),
-             msg.downFlag ? EventInjector::DOWN : EventInjector::UP);
-    }
-#endif
-}
-
-void RFBServer::waitForClientMessage(ClientMessage& msg)
-{
-    if ( !read(msg.payload(), 1) )
-        return;
-
-    switch(msg.type()) {
-
-    case SET_PIXEL_FORMAT:
-        read(msg.payload(1), sizeof(SetPixelFormat)-1);
-        break;
-
-    case FIX_COLOUR_MAP_ENTRIES:
-        mStatus = UNKNOWN_ERROR;
-        return;
-
-    case SET_ENCODINGS:
-    {
-        if ( !read(msg.payload(1), sizeof(SetEncodings)-1) )
-            return;
-
-        size_t size = ntohs( msg.messages().setEncodings.numberOfEncodings ) * 4;
-        if (msg.resize(sizeof(SetEncodings) + size) != NO_ERROR) {
-            mStatus = NO_MEMORY;
-            return;
-        }
-
-        if ( !read(msg.payload(sizeof(SetEncodings)), size) )
-            return;
-
-        break;
-    }
-
-    case FRAME_BUFFER_UPDATE_REQ:
-        read(msg.payload(1), sizeof(FrameBufferUpdateRequest)-1);
-        break;
-
-    case KEY_EVENT:
-        read(msg.payload(1), sizeof(KeyEvent)-1);
-        break;
-
-    case POINTER_EVENT:
-        read(msg.payload(1), sizeof(PointerEvent)-1);
-        break;
-
-    case CLIENT_CUT_TEXT:
-    {
-        if ( !read(msg.payload(1), sizeof(ClientCutText)-1) )
-            return;
-
-        size_t size = ntohl( msg.messages().clientCutText.length );
-        if (msg.resize(sizeof(ClientCutText) + size) != NO_ERROR) {
-            mStatus = NO_MEMORY;
-            return;
-        }
-
-        if ( !read(msg.payload(sizeof(SetEncodings)), size) )
-            return;
-
-        break;
-    }
-
-    default:
-        LOGE("Unknown Message %d", msg.type());
-        mStatus = UNKNOWN_ERROR;
-        return;
-    }
-}
-
-// ----------------------------------------------------------------------------
-
-bool RFBServer::write(const Message& msg)
-{
-    write(msg.payload(), msg.size());
-    return alive();
-}
-
-bool RFBServer::read(Message& msg)
-{
-    read(msg.payload(), msg.size());
-    return alive();
-}
-
-bool RFBServer::write(const void* buffer, int size)
-{
-    int wr = ::write(mFD, buffer, size);
-    if (wr != size) {
-        //LOGE("write(%d) error %d (%s)", size, wr, strerror(errno));
-        mStatus = (wr == -1) ? errno : -1;
-    }
-    return alive();
-}
-
-bool RFBServer::read(void* buffer, int size)
-{
-    int rd = ::read(mFD, buffer, size);
-    if (rd != size) {
-        //LOGE("read(%d) error %d (%s)", size, rd, strerror(errno));
-        mStatus = (rd == -1) ? errno : -1;
-    }
-    return alive();
-}
-
-bool RFBServer::alive() const
-{
-    return  mStatus == 0;
-}
-
-bool RFBServer::isConnected() const
-{
-    return alive();
-}
-
-// ----------------------------------------------------------------------------
-
-void RFBServer::frameBufferUpdated(const GGLSurface& front, const Region& reg)
-{
-    Mutex::Autolock _l(mRegionLock);
-
-    // update dirty region
-    mDirtyRegion.orSelf(reg);
-
-    // remember the front-buffer
-    mFrontBuffer = front;
-
-    // The client has not requested anything, don't do anything more
-    if (mClientRegionRequest.isEmpty())
-        return;
-
-    // wake the sending thread up
-    mRobinThread->wake();
-}
-
-void RFBServer::sendFrameBufferUpdates()
-{
-    Vector<Rect> rects;
-    size_t countRects;
-    GGLSurface fb;
-
-    { // Scope for the lock
-        Mutex::Autolock _l(mRegionLock);
-        if (mFrontBuffer.data == 0)
-            return;
-
-        const Region reg( mDirtyRegion.intersect(mClientRegionRequest) );
-        if (reg.isEmpty())
-            return;
-
-        mDirtyRegion.subtractSelf(reg);
-        countRects = reg.rects(rects);
-
-        // copy the frame-buffer so we can stay responsive
-        size_t bytesPerPix = bytesPerPixel(mFrameBuffer.format);
-        size_t bpr = mFrameBuffer.stride * bytesPerPix;
-        if (mFrameBuffer.data == 0) {
-            mFrameBuffer.data = (GGLubyte*)malloc(bpr * mFrameBuffer.height);
-            if (mFrameBuffer.data == 0)
-            	return;
-        }
-
-        memcpy(mFrameBuffer.data, mFrontBuffer.data, bpr*mFrameBuffer.height);
-        fb = mFrameBuffer;
-    }
-
-    FrameBufferUpdate msgHeader;
-    msgHeader.type = 0;
-    msgHeader.numberOfRectangles = htons(countRects);
-    write(&msgHeader, sizeof(msgHeader));
-
-    Rectangle rectangle;
-    for (size_t i=0 ; i<countRects ; i++) {
-        const Rect& r = rects[i];
-        rectangle.x = htons( r.left );
-        rectangle.y = htons( r.top );
-        rectangle.w = htons( r.width() );
-        rectangle.h = htons( r.height() );
-        rectangle.encoding = htons( SetEncodings::Raw );
-        write(&rectangle, sizeof(rectangle));
-        size_t h = r.height();
-        size_t w = r.width();
-        size_t bytesPerPix = bytesPerPixel(fb.format);
-        size_t bpr = fb.stride * bytesPerPix;
-        size_t bytes = w * bytesPerPix;
-        size_t offset = (r.top * bpr) + (r.left * bytesPerPix);
-        uint8_t* src = static_cast<uint8_t*>(fb.data) + offset;
-        iovec* iov = mIoVec;
-        while (h--) {
-            iov->iov_base = src;
-            iov->iov_len = bytes;
-            src += bpr;
-            iov++;
-        }
-        size_t iovcnt = iov - mIoVec;
-        int wr = ::writev(mFD, mIoVec, iovcnt);
-        if (wr < 0) {
-            //LOGE("write(%d) error %d (%s)", size, wr, strerror(errno));
-            mStatus =  errno;
-        }
-    }
-}
-
-// ----------------------------------------------------------------------------
-
-RFBServer::Message::Message(size_t size)
-    : mSize(size), mAllocatedSize(size)
-{
-    mPayload = malloc(size);
-}
-
-RFBServer::Message::Message(void* payload, size_t size)
-    : mPayload(payload), mSize(size), mAllocatedSize(0)
-{
-}
-
-RFBServer::Message::~Message()
-{
-    if (mAllocatedSize)
-        free(mPayload);
-}
-
-status_t RFBServer::Message::resize(size_t size)
-{
-    if (size > mAllocatedSize) {
-        void* newp;
-        if (mAllocatedSize) {
-            newp = realloc(mPayload, size);
-            if (!newp) return NO_MEMORY;
-        } else {
-            newp = malloc(size);
-            if (!newp) return NO_MEMORY;
-            memcpy(newp, mPayload, mSize);
-            mAllocatedSize = size;
-        }
-        mPayload = newp;
-    }
-    mSize = size;
-    return NO_ERROR;
-}
-
-// ----------------------------------------------------------------------------
-
-RFBServer::EventInjector::EventInjector()
-    : mFD(-1)
-{
-}
-
-RFBServer::EventInjector::~EventInjector()
-{
-}
-
-void RFBServer::EventInjector::injectKey(uint16_t code, uint16_t value)
-{
-#ifdef HAVE_ANDROID_OS
-    // XXX: we need to open the right event device
-    int version;
-    mFD = open("/dev/input/event0", O_RDWR);
-    ioctl(mFD, EVIOCGVERSION, &version);
-
-    input_event ev;
-    memset(&ev, 0, sizeof(ev));
-    ev.type = EV_KEY;
-    ev.code = code;
-    ev.value = value;
-    ::write(mFD, &ev, sizeof(ev));
-
-    close(mFD);
-    mFD = -1;
-#endif
-}
-
-
-}; // namespace android
-
diff --git a/libs/surfaceflinger/RFBServer.h b/libs/surfaceflinger/RFBServer.h
deleted file mode 100644
index 420912e..0000000
--- a/libs/surfaceflinger/RFBServer.h
+++ /dev/null
@@ -1,316 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef ANDROID_RFB_SERVER_H
-#define ANDROID_RFB_SERVER_H
-
-#include <stdint.h>
-#include <sys/types.h>
-#include <sys/uio.h>
-#include <unistd.h>
-#include <arpa/inet.h>
-
-#include <utils/Errors.h>
-#include <utils/threads.h>
-#include <ui/Region.h>
-#include <ui/PixelFormat.h>
-
-#include <pixelflinger/pixelflinger.h>
-
-#include "Barrier.h"
-
-namespace android {
-
-class SurfaceFlinger;
-
-class RFBServer : public Thread
-{
-public:
-                        RFBServer(uint32_t w, uint32_t h, android::PixelFormat format);
-    virtual             ~RFBServer();
-
-    void    frameBufferUpdated(const GGLSurface& front, const Region& reg);
-    bool    isConnected() const;
-
-private:
-            typedef uint8_t     card8;
-            typedef uint16_t    card16;
-            typedef uint32_t    card32;
-
-            struct Message {
-                                Message(size_t size);
-                virtual         ~Message();
-                void*           payload(int offset=0) {
-                    return static_cast<char*>(mPayload)+offset;
-                }
-                void const *    payload(int offset=0) const {
-                    return static_cast<char const *>(mPayload)+offset;
-                }
-                size_t          size() const { return mSize; }
-            protected:
-                                Message(void* payload, size_t size);
-                status_t        resize(size_t size);
-            private:
-                void*       mPayload;
-                size_t      mSize;
-                size_t      mAllocatedSize;
-            };
-
-            struct ProtocolVersion : public Message {
-                ProtocolVersion(uint8_t major, uint8_t minor)
-                    : Message(&messageData, 12) {
-                    char* p = static_cast<char*>(payload());
-                    snprintf(p, 13, "RFB %03u.%03u%c", major, minor, 0xA);
-                }
-                status_t decode(int& maj, int& min) {
-                    char* p = static_cast<char*>(payload());
-                    int n = sscanf(p, "RFB %03u.%03u", &maj, &min);
-                    return (n == 2) ? NO_ERROR : NOT_ENOUGH_DATA;
-                }
-            private:
-                char messageData[12+1];
-            };
-            
-            struct Authentication : public Message {
-                enum { Failed=0, None=1, Vnc=2 };
-                Authentication(int auth) : Message(&messageData, 4) {
-                    *static_cast<card32*>(payload()) = htonl(auth);
-                }
-            private:
-                card32 messageData;
-            };
-            
-            struct ClientInitialization : public Message {
-                ClientInitialization() : Message(&messageData, 1) { }
-                int sharedFlags() {
-                    return messageData;
-                }
-            private:
-                card8 messageData;
-            };
-
-            struct PixelFormat {
-                card8   bitsPerPixel;
-                card8   depth;
-                card8   bigEndianFlag;
-                card8   trueColorFlag;
-                card16  redMax;
-                card16  greenMax;
-                card16  blueMax;
-                card8   redShift;
-                card8   greenShift;
-                card8   blueShift;
-                uint8_t padding[3];
-            } __attribute__((packed));
-            
-            struct ServerInitialization : public Message {
-                ServerInitialization(char const * name)
-                    : Message(sizeof(Payload) + strlen(name))
-                {
-                    const size_t nameLength = size() - sizeof(Payload);
-                    message().nameLength = htonl(nameLength); 
-                    memcpy((char*)message().nameString, name,nameLength);
-                }
-                struct Payload {
-                    card16      framebufferWidth;
-                    card16      framebufferHeight;
-                    PixelFormat serverPixelFormat;
-                    card32      nameLength;
-                    card8       nameString[0];
-                } __attribute__((packed));
-                Payload& message() {
-                    return *static_cast<Payload*>(payload());
-                }
-            };
-
-            // client messages...
-            
-            struct SetPixelFormat {
-                card8           type;
-                uint8_t         padding[3];
-                PixelFormat     pixelFormat;
-            } __attribute__((packed));
-
-            struct SetEncodings {
-                enum { Raw=0, CoR=1, RRE=2, CoRRE=4, Hextile=5 };
-                card8           type;
-                uint8_t         padding;
-                card16          numberOfEncodings;
-                card32          encodings[0];
-            } __attribute__((packed));
-
-            struct FrameBufferUpdateRequest {
-                card8           type;
-                card8           incremental;
-                card16          x;
-                card16          y;
-                card16          width;
-                card16          height;
-            } __attribute__((packed));
-            
-            struct KeyEvent {
-                card8           type;
-                card8           downFlag;
-                uint8_t         padding[2];
-                card32          key;
-            } __attribute__((packed));
-
-            struct PointerEvent {
-                card8           type;
-                card8           buttonMask;
-                card16          x;
-                card16          y;
-            } __attribute__((packed));
-
-            struct ClientCutText {
-                card8           type;
-                uint8_t         padding[3];
-                card32          length;
-                card8           text[0];
-            } __attribute__((packed));
-            
-            union ClientMessages {
-                card8                       type;
-                SetPixelFormat              setPixelFormat;
-                SetEncodings                setEncodings;
-                FrameBufferUpdateRequest    frameBufferUpdateRequest;
-                KeyEvent                    keyEvent;
-                PointerEvent                pointerEvent;
-                ClientCutText               clientCutText;
-            };
-
-            struct Rectangle {
-                card16      x;
-                card16      y;
-                card16      w;
-                card16      h;
-                card32      encoding;
-            } __attribute__((packed));
-
-            struct FrameBufferUpdate {
-                card8       type;
-                uint8_t     padding;
-                card16      numberOfRectangles;
-                Rectangle   rectangles[0];            
-            } __attribute__((packed));
-
-            enum {
-                SET_PIXEL_FORMAT        = 0,
-                FIX_COLOUR_MAP_ENTRIES  = 1,
-                SET_ENCODINGS           = 2,
-                FRAME_BUFFER_UPDATE_REQ = 3,
-                KEY_EVENT               = 4,
-                POINTER_EVENT           = 5,
-                CLIENT_CUT_TEXT         = 6,
-            };
-
-            struct ClientMessage : public Message {
-                ClientMessage()
-                    : Message(&messageData, sizeof(messageData)) {
-                }
-                const ClientMessages& messages() const {
-                    return *static_cast<ClientMessages const *>(payload());
-                }
-                const int type() const {
-                    return messages().type;
-                }
-                status_t resize(size_t size) {
-                    return Message::resize(size);
-                }
-
-                ClientMessages messageData;
-            };
-
-            
-            class ServerThread : public Thread
-            {
-                friend class RFBServer;
-            public:
-                        ServerThread(const sp<RFBServer>& receiver);
-                virtual ~ServerThread();
-                void wake();
-                void exitAndWait();
-            private:
-                virtual bool threadLoop();
-                virtual status_t readyToRun();
-                virtual void onFirstRef();
-                wp<RFBServer> mReceiver;
-                bool (RFBServer::*mAction)();
-                Barrier mUpdateBarrier;
-            };
-            
-            class EventInjector {
-            public:
-                enum { UP=0, DOWN=1 };
-                EventInjector();
-                ~EventInjector();
-                void injectKey(uint16_t code, uint16_t value);
-            private:
-                struct input_event {
-                    struct timeval time;
-                    uint16_t type;
-                    uint16_t code;
-                    uint32_t value;
-                };
-                int mFD;
-            };
-            
-            void        handshake(uint8_t major, uint8_t minor, uint32_t auth);
-            void        waitForClientMessage(ClientMessage& msg);
-            void        handleClientMessage(const ClientMessage& msg);
-            void        handleSetPixelFormat(const SetPixelFormat& msg);
-            void        handleSetEncodings(const SetEncodings& msg);
-            void        handleFrameBufferUpdateReq(const FrameBufferUpdateRequest& msg);
-            void        handleKeyEvent(const KeyEvent& msg);
-            void        sendFrameBufferUpdates();
-
-            bool        validatePixelFormat(const PixelFormat& pf);
-            bool        alive() const;
-            bool        write(const Message& msg);
-            bool        read(Message& msg);
-
-            bool        write(const void* buffer, int size);
-            bool        read(void* buffer, int size);
-
-    virtual bool        threadLoop();
-    virtual status_t    readyToRun();
-    virtual void        onFirstRef();
-
-            sp<ServerThread>    mRobinThread;
-
-            int         mFD;
-            int         mStatus;
-            iovec*      mIoVec;
-    
-            EventInjector   mEventInjector;
-
-            Mutex       mRegionLock;
-            // This is the region requested by the client since the last
-            // time we updated it
-            Region      mClientRegionRequest;
-            // This is the region of the screen that needs to be sent to the
-            // client since the last time we updated it.
-            // Typically this is the dirty region, but not necessarily, for
-            // instance if the client asked for a non incremental update.
-            Region      mDirtyRegion;
-            
-            GGLSurface  mFrameBuffer;
-            GGLSurface  mFrontBuffer;
-};
-
-}; // namespace android
-
-#endif // ANDROID_RFB_SERVER_H
diff --git a/libs/surfaceflinger/SurfaceFlinger.cpp b/libs/surfaceflinger/SurfaceFlinger.cpp
index 554e8e7..242d026 100644
--- a/libs/surfaceflinger/SurfaceFlinger.cpp
+++ b/libs/surfaceflinger/SurfaceFlinger.cpp
@@ -53,20 +53,15 @@
 #include "LayerBuffer.h"
 #include "LayerDim.h"
 #include "LayerBitmap.h"
-#include "LayerScreenshot.h"
+#include "LayerOrientationAnim.h"
+#include "OrientationAnimation.h"
 #include "SurfaceFlinger.h"
-#include "RFBServer.h"
 #include "VRamHeap.h"
 
 #include "DisplayHardware/DisplayHardware.h"
 #include "GPUHardware/GPUHardware.h"
 
 
-// the VNC server even on local ports presents a significant
-// thread as it can allow an application to control and "see" other
-// applications, de-facto bypassing security permissions.
-#define ENABLE_VNC_SERVER   0
-
 #define DISPLAY_COUNT       1
 
 namespace android {
@@ -185,6 +180,7 @@
         mDeferReleaseConsole(false),
         mFreezeDisplay(false),
         mFreezeCount(0),
+        mFreezeDisplayTime(0),
         mDebugRegion(0),
         mDebugCpu(0),
         mDebugFps(0),
@@ -225,6 +221,7 @@
 SurfaceFlinger::~SurfaceFlinger()
 {
     glDeleteTextures(1, &mWormholeTexName);
+    delete mOrientationAnimation;
 }
 
 copybit_device_t* SurfaceFlinger::getBlitEngine() const
@@ -448,6 +445,8 @@
      *  We're now ready to accept clients...
      */
 
+    mOrientationAnimation = new OrientationAnimation(this);
+    
     // start CPU gauge display
     if (mDebugCpu)
         mCpuGauge = new CPUGauge(this, ms2ns(500));
@@ -456,9 +455,6 @@
     if (mDebugNoBootAnimation == false)
         mBootAnimation = new BootAnimation(this);
 
-    if (ENABLE_VNC_SERVER)
-        mRFBServer = new RFBServer(w, h, f);
-
     return NO_ERROR;
 }
 
@@ -472,17 +468,25 @@
 {
     // wait for something to do
     if (UNLIKELY(isFrozen())) {
-        // wait 2 seconds
-        int err = mSyncObject.wait(ms2ns(3000));
+        // wait 5 seconds
+        const nsecs_t freezeDisplayTimeout = ms2ns(5000);
+        const nsecs_t now = systemTime();
+        if (mFreezeDisplayTime == 0) {
+            mFreezeDisplayTime = now;
+        }
+        nsecs_t waitTime = freezeDisplayTimeout - (now - mFreezeDisplayTime);
+        int err = (waitTime > 0) ? mSyncObject.wait(waitTime) : TIMED_OUT;
         if (err != NO_ERROR) {
             if (isFrozen()) {
                 // we timed out and are still frozen
                 LOGW("timeout expired mFreezeDisplay=%d, mFreezeCount=%d",
                         mFreezeDisplay, mFreezeCount);
                 mFreezeCount = 0;
+                mFreezeDisplay = false;
             }
         }
     } else {
+        mFreezeDisplayTime = 0;
         mSyncObject.wait();
     }
 }
@@ -556,11 +560,8 @@
 
 void SurfaceFlinger::postFramebuffer()
 {
-    if (UNLIKELY(isFrozen())) {
-        // we are not allowed to draw, but pause a bit to make sure
-        // apps don't end up using the whole CPU, if they depend on
-        // surfaceflinger for synchronization.
-        usleep(8333); // 8.3ms ~ 120fps
+    const bool skip = mOrientationAnimation->run();
+    if (UNLIKELY(skip)) {
         return;
     }
 
@@ -571,18 +572,6 @@
             debugShowFPS();
         }
 
-        if (UNLIKELY(ENABLE_VNC_SERVER &&
-                mRFBServer!=0 && mRFBServer->isConnected())) {
-            if (!mSecureFrameBuffer) {
-                GGLSurface fb;
-                // backbufer, is going to become the front buffer really soon
-                hw.getDisplaySurface(&fb);
-                if (LIKELY(fb.data != 0)) {
-                    mRFBServer->frameBufferUpdated(fb, mInvalidRegion);
-                }
-            }
-        }
-
         hw.flip(mInvalidRegion);
 
         mInvalidRegion.clear();
@@ -685,18 +674,13 @@
 
             mVisibleRegionsDirty = true;
             mDirtyRegion.set(hw.bounds());
+
+            mOrientationAnimation->onOrientationChanged();
         }
 
         if (mCurrentState.freezeDisplay != mDrawingState.freezeDisplay) {
             // freezing or unfreezing the display -> trigger animation if needed
             mFreezeDisplay = mCurrentState.freezeDisplay;
-            const nsecs_t now = systemTime();
-            if (mFreezeDisplay) {
-                mFreezeDisplayTime = now;
-            } else {
-                //LOGD("Screen was frozen for %llu us",
-                //        ns2us(now-mFreezeDisplayTime));
-            }
         }
 
         // some layers might have been removed, so
@@ -875,19 +859,9 @@
 
     uint32_t flags = hw.getFlags();
     if (flags & DisplayHardware::BUFFER_PRESERVED) {
-        if (flags & DisplayHardware::COPY_BACK_EXTENSION) {
-            // yay. nothing to do here.
-        } else {
-            if (flags & DisplayHardware::UPDATE_ON_DEMAND) {
-                // we need to fully redraw the part that will be updated
-                mDirtyRegion.set(mInvalidRegion.bounds());
-            } else {
-                // TODO: we only need te redraw the part that had been drawn
-                // the round before and is not drawn now
-            }
-        }
+        // here we assume DisplayHardware::flip()'s  implementation
+        // performs the copy-back optimization.
     } else {
-        // COPY_BACK_EXTENSION makes no sense here
         if (flags & DisplayHardware::UPDATE_ON_DEMAND) {
             // we need to fully redraw the part that will be updated
             mDirtyRegion.set(mInvalidRegion.bounds());
@@ -1077,6 +1051,29 @@
     // XXX: mFPS has the value we want
  }
 
+status_t SurfaceFlinger::addLayer(LayerBase* layer)
+{
+    Mutex::Autolock _l(mStateLock);
+    addLayer_l(layer);
+    setTransactionFlags(eTransactionNeeded|eTraversalNeeded);
+    return NO_ERROR;
+}
+
+status_t SurfaceFlinger::removeLayer(LayerBase* layer)
+{
+    Mutex::Autolock _l(mStateLock);
+    removeLayer_l(layer);
+    setTransactionFlags(eTransactionNeeded);
+    return NO_ERROR;
+}
+
+status_t SurfaceFlinger::invalidateLayerVisibility(LayerBase* layer)
+{
+    layer->forceVisibilityTransaction();
+    setTransactionFlags(eTraversalNeeded);
+    return NO_ERROR;
+}
+
 status_t SurfaceFlinger::addLayer_l(LayerBase* layer)
 {
     ssize_t i = mCurrentState.layersSortedByZ.add(
@@ -1555,55 +1552,17 @@
 
     status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags);
     if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) {
-        if (code == 1012) {
-            // take screen-shot of the front buffer
-            if (UNLIKELY(checkCallingPermission(
-                    String16("android.permission.READ_FRAME_BUFFER")) == false))
-            { // not allowed
-                LOGE("Permission Denial: "
-                        "can't take screenshots from pid=%d, uid=%d\n",
-                        IPCThreadState::self()->getCallingPid(),
-                        IPCThreadState::self()->getCallingUid());
-                return PERMISSION_DENIED;
-            }
-
-            if (UNLIKELY(mSecureFrameBuffer)) {
-                LOGE("A secure window is on screen: "
-                        "can't take screenshots from pid=%d, uid=%d\n",
-                        IPCThreadState::self()->getCallingPid(),
-                        IPCThreadState::self()->getCallingUid());
-                return PERMISSION_DENIED;
-            }
-
-            LOGI("Taking a screenshot...");
-
-            LayerScreenshot* l = new LayerScreenshot(this, 0);
-
-            Mutex::Autolock _l(mStateLock);
-            const DisplayHardware& hw(graphicPlane(0).displayHardware());
-            l->initStates(hw.getWidth(), hw.getHeight(), 0);
-            l->setLayer(INT_MAX);
-
-            addLayer_l(l);
-            setTransactionFlags(eTransactionNeeded|eTraversalNeeded);
-
-            l->takeScreenshot(mStateLock, reply);
-
-            removeLayer_l(l);
-            setTransactionFlags(eTransactionNeeded);
-            return NO_ERROR;
-        } else {
-            // HARDWARE_TEST stuff...
-            if (UNLIKELY(checkCallingPermission(
-                    String16("android.permission.HARDWARE_TEST")) == false))
-            { // not allowed
-                LOGE("Permission Denial: pid=%d, uid=%d\n",
-                        IPCThreadState::self()->getCallingPid(),
-                        IPCThreadState::self()->getCallingUid());
-                return PERMISSION_DENIED;
-            }
-            int n;
-            switch (code) {
+        // HARDWARE_TEST stuff...
+        if (UNLIKELY(checkCallingPermission(
+                String16("android.permission.HARDWARE_TEST")) == false))
+        { // not allowed
+            LOGE("Permission Denial: pid=%d, uid=%d\n",
+                    IPCThreadState::self()->getCallingPid(),
+                    IPCThreadState::self()->getCallingUid());
+            return PERMISSION_DENIED;
+        }
+        int n;
+        switch (code) {
             case 1000: // SHOW_CPU
                 n = data.readInt32();
                 mDebugCpu = n ? 1 : 0;
@@ -1636,8 +1595,8 @@
                 const DisplayHardware& hw(graphicPlane(0).displayHardware());
                 mDirtyRegion.set(hw.bounds()); // careful that's not thread-safe
                 signalEvent();
-                }
-                return NO_ERROR;
+            }
+            return NO_ERROR;
             case 1005: // ask GPU revoke
                 mGPU->friendlyRevoke();
                 return NO_ERROR;
@@ -1653,13 +1612,12 @@
                 reply->writeInt32(mDebugRegion);
                 reply->writeInt32(mDebugBackground);
                 return NO_ERROR;
-            case 1013: { // screenshot
+            case 1013: {
                 Mutex::Autolock _l(mStateLock);
                 const DisplayHardware& hw(graphicPlane(0).displayHardware());
                 reply->writeInt32(hw.getPageFlipCount());
             }
             return NO_ERROR;
-            }
         }
     }
     return err;
@@ -1813,10 +1771,33 @@
     mGlobalTransform = mOrientationTransform * mTransform;
 }
 
+status_t GraphicPlane::orientationToTransfrom(
+        int orientation, int w, int h, Transform* tr)
+{    
+    float a, b, c, d, x, y;
+    switch (orientation) {
+    case ISurfaceComposer::eOrientationDefault:
+        a=1; b=0; c=0; d=1; x=0; y=0;
+        break;
+    case ISurfaceComposer::eOrientation90:
+        a=0; b=-1; c=1; d=0; x=w; y=0;
+        break;
+    case ISurfaceComposer::eOrientation180:
+        a=-1; b=0; c=0; d=-1; x=w; y=h;
+        break;
+    case ISurfaceComposer::eOrientation270:
+        a=0; b=1; c=-1; d=0; x=0; y=h;
+        break;
+    default:
+        return BAD_VALUE;
+    }
+    tr->set(a, b, c, d);
+    tr->set(x, y);
+    return NO_ERROR;
+}
+
 status_t GraphicPlane::setOrientation(int orientation)
 {
-    float a, b, c, d, x, y;
-
     const DisplayHardware& hw(displayHardware());
     const float w = hw.getWidth();
     const float h = hw.getHeight();
@@ -1830,30 +1811,21 @@
 
     // If the rotation can be handled in hardware, this is where
     // the magic should happen.
-
-    switch (orientation) {
-    case ISurfaceComposer::eOrientation90:
-        a=0; b=-1; c=1; d=0; x=w; y=0;
-        break;
-    case ISurfaceComposer::eOrientation180:
-        a=-1; b=0; c=0; d=-1; x=w; y=h;
-        break;
-    case ISurfaceComposer::eOrientation270:
-        a=0; b=1; c=-1; d=0; x=0; y=h;
-        break;
-    case 42: {
+    if (UNLIKELY(orientation == 42)) {
+        float a, b, c, d, x, y;
         const float r = (3.14159265f / 180.0f) * 42.0f;
         const float si = sinf(r);
         const float co = cosf(r);
         a=co; b=-si; c=si; d=co;
         x = si*(h*0.5f) + (1-co)*(w*0.5f);
         y =-si*(w*0.5f) + (1-co)*(h*0.5f);
-    } break;
-    default:
-        return BAD_VALUE;
+        mOrientationTransform.set(a, b, c, d);
+        mOrientationTransform.set(x, y);
+    } else {
+        GraphicPlane::orientationToTransfrom(orientation, w, h,
+                &mOrientationTransform);
     }
-    mOrientationTransform.set(a, b, c, d);
-    mOrientationTransform.set(x, y);
+    
     mGlobalTransform = mOrientationTransform * mTransform;
     return NO_ERROR;
 }
diff --git a/libs/surfaceflinger/SurfaceFlinger.h b/libs/surfaceflinger/SurfaceFlinger.h
index a242f1a..f7d7764 100644
--- a/libs/surfaceflinger/SurfaceFlinger.h
+++ b/libs/surfaceflinger/SurfaceFlinger.h
@@ -35,11 +35,11 @@
 #include <private/ui/LayerState.h>
 #include <private/ui/SurfaceFlingerSynchro.h>
 
+#include "Barrier.h"
+#include "BootAnimation.h"
+#include "CPUGauge.h"
 #include "Layer.h"
 #include "Tokenizer.h"
-#include "CPUGauge.h"
-#include "BootAnimation.h"
-#include "Barrier.h"
 
 struct copybit_device_t;
 struct overlay_device_t;
@@ -48,16 +48,17 @@
 
 // ---------------------------------------------------------------------------
 
-class BClient;
 class Client;
+class BClient;
 class DisplayHardware;
+class FreezeLock;
 class GPUHardwareInterface;
 class IGPUCallback;
 class Layer;
 class LayerBuffer;
-class RFBServer;
+class LayerOrientationAnim;
+class OrientationAnimation;
 class SurfaceHeapManager;
-class FreezeLock;
 
 typedef int32_t ClientID;
 
@@ -110,6 +111,8 @@
 class GraphicPlane
 {
 public:
+    static status_t orientationToTransfrom(int orientation, int w, int h,
+            Transform* tr);
 
                                 GraphicPlane();
                                 ~GraphicPlane();
@@ -181,7 +184,12 @@
 
             copybit_device_t* getBlitEngine() const;
             overlay_control_device_t* getOverlayEngine() const;
+
             
+    status_t removeLayer(LayerBase* layer);
+    status_t addLayer(LayerBase* layer);
+    status_t invalidateLayerVisibility(LayerBase* layer);
+    
 private:
     friend class BClient;
     friend class LayerBase;
@@ -337,7 +345,6 @@
                 sp<GPUHardwareInterface>    mGPU;
                 GLuint                      mWormholeTexName;
                 sp<BootAnimation>           mBootAnimation;
-                sp<RFBServer>               mRFBServer;
                 nsecs_t                     mBootTime;
                 
                 // Can only accessed from the main thread, these members
@@ -352,6 +359,8 @@
                 bool                        mFreezeDisplay;
                 int32_t                     mFreezeCount;
                 nsecs_t                     mFreezeDisplayTime;
+                friend class OrientationAnimation;
+                OrientationAnimation*       mOrientationAnimation;
 
                 // access protected by mDebugLock
     mutable     Mutex                       mDebugLock;
diff --git a/libs/surfaceflinger/VRamHeap.cpp b/libs/surfaceflinger/VRamHeap.cpp
index 77bc576..0ccd71f 100644
--- a/libs/surfaceflinger/VRamHeap.cpp
+++ b/libs/surfaceflinger/VRamHeap.cpp
@@ -35,8 +35,6 @@
 #include <utils/MemoryHeapPmem.h>
 #include <utils/MemoryHeapBase.h>
 
-#include <GLES/eglnatives.h>
-
 #include "GPUHardware/GPUHardware.h"
 #include "SurfaceFlinger.h"
 #include "VRamHeap.h"
diff --git a/libs/ui/Camera.cpp b/libs/ui/Camera.cpp
index 50c6008..b3cbda1 100644
--- a/libs/ui/Camera.cpp
+++ b/libs/ui/Camera.cpp
@@ -84,8 +84,10 @@
     mRawCallbackCookie = 0;
     mJpegCallback = 0;
     mJpegCallbackCookie = 0;
-    mFrameCallback = 0;
-    mFrameCallbackCookie = 0;
+    mPreviewCallback = 0;
+    mPreviewCallbackCookie = 0;
+    mRecordingCallback = 0;
+    mRecordingCallbackCookie = 0;
     mErrorCallback = 0;
     mErrorCallbackCookie = 0;
     mAutoFocusCallback = 0;
@@ -108,6 +110,8 @@
     if (c->mCamera != 0) {
         c->mCamera->asBinder()->linkToDeath(c);
         c->mStatus = NO_ERROR;
+    } else {
+        c.clear();
     }
     return c;
 }
@@ -184,6 +188,15 @@
     return c->startPreview();
 }
 
+// start recording mode, must call setPreviewDisplay first
+status_t Camera::startRecording()
+{
+    LOGV("startRecording");
+    sp <ICamera> c = mCamera;
+    if (c == 0) return NO_INIT;
+    return c->startRecording();
+}
+
 // stop preview mode
 void Camera::stopPreview()
 {
@@ -193,6 +206,24 @@
     c->stopPreview();
 }
 
+// stop recording mode
+void Camera::stopRecording()
+{
+    LOGV("stopRecording");
+    sp <ICamera> c = mCamera;
+    if (c == 0) return;
+    c->stopRecording();
+}
+
+// release a recording frame
+void Camera::releaseRecordingFrame(const sp<IMemory>& mem)
+{
+    LOGV("releaseRecordingFrame");
+    sp <ICamera> c = mCamera;
+    if (c == 0) return;
+    c->releaseRecordingFrame(mem);
+}
+
 // get preview state
 bool Camera::previewEnabled()
 {
@@ -202,6 +233,15 @@
     return c->previewEnabled();
 }
 
+// get recording state
+bool Camera::recordingEnabled()
+{
+    LOGV("recordingEnabled");
+    sp <ICamera> c = mCamera;
+    if (c == 0) return false;
+    return c->recordingEnabled();
+}
+
 status_t Camera::autoFocus()
 {
     LOGV("autoFocus");
@@ -266,14 +306,21 @@
     mJpegCallbackCookie = cookie;
 }
 
-void Camera::setFrameCallback(frame_callback cb, void *cookie, int frame_callback_flag)
+void Camera::setPreviewCallback(frame_callback cb, void *cookie, int flag)
 {
-    LOGV("setFrameCallback");
-    mFrameCallback = cb;
-    mFrameCallbackCookie = cookie;
+    LOGV("setPreviewCallback");
+    mPreviewCallback = cb;
+    mPreviewCallbackCookie = cookie;
     sp <ICamera> c = mCamera;
     if (c == 0) return;
-    mCamera->setFrameCallbackFlag(frame_callback_flag);
+    mCamera->setPreviewCallbackFlag(flag);
+}
+
+void Camera::setRecordingCallback(frame_callback cb, void *cookie)
+{
+    LOGV("setRecordingCallback");
+    mRecordingCallback = cb;
+    mRecordingCallbackCookie = cookie;
 }
 
 void Camera::setErrorCallback(error_callback cb, void *cookie)
@@ -316,12 +363,21 @@
     }
 }
 
-// callback from camera service when video frame is ready
-void Camera::frameCallback(const sp<IMemory>& frame)
+// callback from camera service when preview frame is ready
+void Camera::previewCallback(const sp<IMemory>& frame)
 {
     LOGV("frameCallback");
-    if (mFrameCallback) {
-        mFrameCallback(frame, mFrameCallbackCookie);
+    if (mPreviewCallback) {
+        mPreviewCallback(frame, mPreviewCallbackCookie);
+    }
+}
+
+// callback from camera service when a recording frame is ready
+void Camera::recordingCallback(const sp<IMemory>& frame)
+{
+    LOGV("recordingCallback");
+    if (mRecordingCallback) {
+        mRecordingCallback(frame, mRecordingCallbackCookie);
     }
 }
 
diff --git a/libs/ui/CameraParameters.cpp b/libs/ui/CameraParameters.cpp
index 7ca77bb..6c25836 100644
--- a/libs/ui/CameraParameters.cpp
+++ b/libs/ui/CameraParameters.cpp
@@ -24,6 +24,9 @@
 
 namespace android {
 
+static const char* portrait = "portrait";
+static const char* landscape = "landscape";
+
 CameraParameters::CameraParameters()
                 : mMap()
 {
@@ -182,6 +185,23 @@
     set("preview-format", format);
 }
 
+int CameraParameters::getOrientation() const
+{
+    const char* orientation = get("orientation");
+    if (orientation && !strcmp(orientation, portrait))
+        return CAMERA_ORIENTATION_PORTRAIT;
+    return CAMERA_ORIENTATION_LANDSCAPE;
+}
+
+void CameraParameters::setOrientation(int orientation)
+{
+    if (orientation == CAMERA_ORIENTATION_PORTRAIT) {
+        set("preview-format", portrait);
+    } else {
+        set("preview-format", landscape);
+    }
+}
+
 const char *CameraParameters::getPreviewFormat() const
 {
     return get("preview-format");
diff --git a/libs/ui/EGLDisplaySurface.cpp b/libs/ui/EGLDisplaySurface.cpp
index 44258a8..d06c98b 100644
--- a/libs/ui/EGLDisplaySurface.cpp
+++ b/libs/ui/EGLDisplaySurface.cpp
@@ -42,7 +42,7 @@
 #include <linux/msm_mdp.h>
 #endif
 
-#include <GLES/egl.h>
+#include <EGL/egl.h>
 
 #include <pixelflinger/format.h>
 
@@ -71,8 +71,6 @@
     egl_native_window_t::incRef = &EGLDisplaySurface::hook_incRef;
     egl_native_window_t::decRef = &EGLDisplaySurface::hook_decRef;
     egl_native_window_t::swapBuffers = &EGLDisplaySurface::hook_swapBuffers;
-    egl_native_window_t::setSwapRectangle = &EGLDisplaySurface::hook_setSwapRectangle;
-    egl_native_window_t::nextBuffer = &EGLDisplaySurface::hook_nextBuffer;
     egl_native_window_t::connect = 0;
     egl_native_window_t::disconnect = 0;
 
@@ -136,15 +134,6 @@
     EGLDisplaySurface* that = static_cast<EGLDisplaySurface*>(window);
     return that->swapBuffers();
 }
-uint32_t EGLDisplaySurface::hook_nextBuffer(NativeWindowType window) {
-    EGLDisplaySurface* that = static_cast<EGLDisplaySurface*>(window);
-    return that->nextBuffer();
-}
-void EGLDisplaySurface::hook_setSwapRectangle(NativeWindowType window,
-        int l, int t, int w, int h) {
-    EGLDisplaySurface* that = static_cast<EGLDisplaySurface*>(window);
-    that->setSwapRectangle(l, t, w, h);
-}
 
 void EGLDisplaySurface::setSwapRectangle(int l, int t, int w, int h)
 {
@@ -249,15 +238,6 @@
     return mPageFlipCount;
 }
 
-uint32_t EGLDisplaySurface::nextBuffer()
-{
-    // update the address of the buffer to draw to next
-    const GGLSurface& buffer = mFb[mIndex];
-    egl_native_window_t::offset =
-        intptr_t(buffer.data) - egl_native_window_t::base;
-    return 0;
-}
-
 void EGLDisplaySurface::copyFrontToBack(const Region& copyback)
 {
 #if HAVE_ANDROID_OS
@@ -318,6 +298,59 @@
     }
 }
 
+void EGLDisplaySurface::copyFrontToImage(const copybit_image_t& dst)
+{
+#if HAVE_ANDROID_OS
+    if (mBlitEngine) {
+        copybit_image_t src = {
+                w:      egl_native_window_t::stride,
+                h:      egl_native_window_t::height,
+                format: egl_native_window_t::format,
+                offset: mFb[mIndex].data - mFb[0].data,
+                base:   (void*)egl_native_window_t::base,
+                fd:     egl_native_window_t::fd
+        };
+        region_iterator it(Region(Rect(
+                egl_native_window_t::width, egl_native_window_t::height)));
+        mBlitEngine->blit(mBlitEngine, &dst, &src, &it);
+    } else
+#endif
+    {
+        uint8_t* const screen_src = mFb[  mIndex].data;
+        const size_t bpp = bytesPerPixel(egl_native_window_t::format);
+        const size_t bpr = egl_native_window_t::stride * bpp;
+        memcpy((char*)dst.base + dst.offset, screen_src,
+                bpr*egl_native_window_t::height);
+    }
+}
+
+void EGLDisplaySurface::copyBackToImage(const copybit_image_t& dst)
+{
+#if HAVE_ANDROID_OS
+    if (mBlitEngine) {
+        copybit_image_t src = {
+                w:      egl_native_window_t::stride,
+                h:      egl_native_window_t::height,
+                format: egl_native_window_t::format,
+                offset: mFb[1-mIndex].data - mFb[0].data,
+                base:   (void*)egl_native_window_t::base,
+                fd:     egl_native_window_t::fd
+        };
+        region_iterator it(Region(Rect(
+                egl_native_window_t::width, egl_native_window_t::height)));
+        mBlitEngine->blit(mBlitEngine, &dst, &src, &it);
+    } else
+#endif
+    {
+        uint8_t* const screen_src = mFb[1-mIndex].data;
+        const size_t bpp = bytesPerPixel(egl_native_window_t::format);
+        const size_t bpr = egl_native_window_t::stride * bpp;
+        memcpy((char*)dst.base + dst.offset, screen_src,
+                bpr*egl_native_window_t::height);
+    }
+}
+
+
 status_t EGLDisplaySurface::mapFrameBuffer()
 {
     char const * const device_template[] = {
diff --git a/libs/ui/EGLNativeWindowSurface.cpp b/libs/ui/EGLNativeWindowSurface.cpp
index d55fb70..f1071cf 100644
--- a/libs/ui/EGLNativeWindowSurface.cpp
+++ b/libs/ui/EGLNativeWindowSurface.cpp
@@ -28,7 +28,7 @@
 #include <ui/DisplayInfo.h>
 #include <ui/Rect.h>
 
-#include <GLES/egl.h>
+#include <EGL/egl.h>
 
 #include <pixelflinger/format.h>
 
@@ -48,8 +48,6 @@
     egl_native_window_t::incRef = &EGLNativeWindowSurface::hook_incRef;
     egl_native_window_t::decRef = &EGLNativeWindowSurface::hook_decRef;
     egl_native_window_t::swapBuffers = &EGLNativeWindowSurface::hook_swapBuffers;
-    egl_native_window_t::nextBuffer = &EGLNativeWindowSurface::hook_nextBuffer;
-    egl_native_window_t::setSwapRectangle = &EGLNativeWindowSurface::hook_setSwapRectangle;
     egl_native_window_t::connect = &EGLNativeWindowSurface::hook_connect;
     egl_native_window_t::disconnect = &EGLNativeWindowSurface::hook_disconnect;
     
@@ -98,18 +96,6 @@
     return that->swapBuffers();
 }
 
-uint32_t EGLNativeWindowSurface::hook_nextBuffer(NativeWindowType window)
-{
-    EGLNativeWindowSurface* that = static_cast<EGLNativeWindowSurface*>(window);
-    return that->nextBuffer();
-}
-
-void EGLNativeWindowSurface::hook_setSwapRectangle(NativeWindowType window, int l, int t, int w, int h)
-{
-    EGLNativeWindowSurface* that = static_cast<EGLNativeWindowSurface*>(window);
-    that->setSwapRectangle(l, t, w, h);
-}
-
 void EGLNativeWindowSurface::setSwapRectangle(int l, int t, int w, int h)
 {
     mSurface->setSwapRectangle(Rect(l, t, l+w, t+h));
@@ -138,17 +124,6 @@
     return 0;
 }
 
-uint32_t EGLNativeWindowSurface::nextBuffer()
-{
-    const sp<Surface>& surface(mSurface);
-    Surface::SurfaceInfo info;
-    surface->nextBuffer(&info);
-    // update the address of the buffer to draw to next
-    egl_native_window_t::base   = intptr_t(info.base);
-    egl_native_window_t::offset = intptr_t(info.bits) - intptr_t(info.base);
-    return 0;
-}
-
 void EGLNativeWindowSurface::connect()
 {   
     if (!mConnected) {
diff --git a/libs/ui/EventHub.cpp b/libs/ui/EventHub.cpp
index 700aa3a..3b29b09 100644
--- a/libs/ui/EventHub.cpp
+++ b/libs/ui/EventHub.cpp
@@ -71,10 +71,11 @@
 
 EventHub::device_t::device_t(int32_t _id, const char* _path)
     : id(_id), path(_path), classes(0)
-    , layoutMap(new KeyLayoutMap()), next(NULL) {
+    , keyBitmask(NULL), layoutMap(new KeyLayoutMap()), next(NULL) {
 }
 
 EventHub::device_t::~device_t() {
+    delete [] keyBitmask;
     delete layoutMap;
 }
 
@@ -403,6 +404,36 @@
     return true;
 }
 
+/*
+ * Inspect the known devices to determine whether physical keys exist for the given
+ * framework-domain key codes.
+ */
+bool EventHub::hasKeys(size_t numCodes, int32_t* keyCodes, uint8_t* outFlags) {
+    for (size_t codeIndex = 0; codeIndex < numCodes; codeIndex++) {
+        outFlags[codeIndex] = 0;
+
+        // check each available hardware device for support for this keycode
+        Vector<int32_t> scanCodes;
+        for (int n = 0; (n < mFDCount) && (outFlags[codeIndex] == 0); n++) {
+            if (mDevices[n]) {
+                status_t err = mDevices[n]->layoutMap->findScancodes(keyCodes[codeIndex], &scanCodes);
+                if (!err) {
+                    // check the possible scan codes identified by the layout map against the
+                    // map of codes actually emitted by the driver
+                    for (size_t sc = 0; sc < scanCodes.size(); sc++) {
+                        if (test_bit(scanCodes[sc], mDevices[n]->keyBitmask)) {
+                            outFlags[codeIndex] = 1;
+                            break;
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    return true;
+}
+
 // ----------------------------------------------------------------------------
 
 int EventHub::open_device(const char *deviceName)
@@ -527,6 +558,16 @@
                 break;
             }
         }
+        if ((device->classes & CLASS_KEYBOARD) != 0) {
+            device->keyBitmask = new uint8_t[(KEY_MAX+1)/8];
+            if (device->keyBitmask != NULL) {
+                memcpy(device->keyBitmask, key_bitmask, sizeof(key_bitmask));
+            } else {
+                delete device;
+                LOGE("out of memory allocating key bitmask");
+                return -1;
+            }
+        }
     }
     if (test_bit(BTN_MOUSE, key_bitmask)) {
         uint8_t rel_bitmask[(REL_MAX+1)/8];
diff --git a/libs/ui/ICamera.cpp b/libs/ui/ICamera.cpp
index 7b0922e..ab0fef1 100644
--- a/libs/ui/ICamera.cpp
+++ b/libs/ui/ICamera.cpp
@@ -28,7 +28,7 @@
 enum {
     DISCONNECT = IBinder::FIRST_CALL_TRANSACTION,
     SET_PREVIEW_DISPLAY,
-    SET_FRAME_CALLBACK_FLAG,
+    SET_PREVIEW_CALLBACK_FLAG,
     START_PREVIEW,
     STOP_PREVIEW,
     AUTO_FOCUS,
@@ -38,7 +38,11 @@
     CONNECT,
     LOCK,
     UNLOCK,
-    PREVIEW_ENABLED
+    PREVIEW_ENABLED,
+    START_RECORDING,
+    STOP_RECORDING,
+    RECORDING_ENABLED,
+    RELEASE_RECORDING_FRAME,
 };
 
 class BpCamera: public BpInterface<ICamera>
@@ -69,15 +73,15 @@
         return reply.readInt32();
     }
 
-    // set the frame callback flag to affect how the received frames from
-    // preview are handled.
-    void setFrameCallbackFlag(int frame_callback_flag)
+    // set the preview callback flag to affect how the received frames from
+    // preview are handled. See Camera.h for details.
+    void setPreviewCallbackFlag(int flag)
     {
-        LOGV("setFrameCallbackFlag(%d)", frame_callback_flag);
+        LOGV("setPreviewCallbackFlag(%d)", flag);
         Parcel data, reply;
         data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
-        data.writeInt32(frame_callback_flag);
-        remote()->transact(SET_FRAME_CALLBACK_FLAG, data, &reply);
+        data.writeInt32(flag);
+        remote()->transact(SET_PREVIEW_CALLBACK_FLAG, data, &reply);
     }
 
     // start preview mode, must call setPreviewDisplay first
@@ -90,6 +94,16 @@
         return reply.readInt32();
     }
 
+    // start recording mode, must call setPreviewDisplay first
+    status_t startRecording()
+    {
+        LOGV("startRecording");
+        Parcel data, reply;
+        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
+        remote()->transact(START_RECORDING, data, &reply);
+        return reply.readInt32();
+    }
+
     // stop preview mode
     void stopPreview()
     {
@@ -99,6 +113,24 @@
         remote()->transact(STOP_PREVIEW, data, &reply);
     }
 
+    // stop recording mode
+    void stopRecording()
+    {
+        LOGV("stopRecording");
+        Parcel data, reply;
+        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
+        remote()->transact(STOP_RECORDING, data, &reply);
+    }
+
+    void releaseRecordingFrame(const sp<IMemory>& mem)
+    {
+        LOGV("releaseRecordingFrame");
+        Parcel data, reply;
+        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
+        data.writeStrongBinder(mem->asBinder());
+        remote()->transact(RELEASE_RECORDING_FRAME, data, &reply);
+    }
+
     // check preview state
     bool previewEnabled()
     {
@@ -109,6 +141,16 @@
         return reply.readInt32();
     }
 
+    // check recording state
+    bool recordingEnabled()
+    {
+        LOGV("recordingEnabled");
+        Parcel data, reply;
+        data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
+        remote()->transact(RECORDING_ENABLED, data, &reply);
+        return reply.readInt32();
+    }
+
     // auto focus
     status_t autoFocus()
     {
@@ -202,11 +244,11 @@
             reply->writeInt32(setPreviewDisplay(surface));
             return NO_ERROR;
         } break;
-        case SET_FRAME_CALLBACK_FLAG: {
-            LOGV("SET_FRAME_CALLBACK_TYPE");
+        case SET_PREVIEW_CALLBACK_FLAG: {
+            LOGV("SET_PREVIEW_CALLBACK_TYPE");
             CHECK_INTERFACE(ICamera, data, reply);
-            int frame_callback_flag = data.readInt32();
-            setFrameCallbackFlag(frame_callback_flag);
+            int callback_flag = data.readInt32();
+            setPreviewCallbackFlag(callback_flag);
             return NO_ERROR;
         } break;
         case START_PREVIEW: {
@@ -215,18 +257,43 @@
             reply->writeInt32(startPreview());
             return NO_ERROR;
         } break;
+        case START_RECORDING: {
+            LOGV("START_RECORDING");
+            CHECK_INTERFACE(ICamera, data, reply);
+            reply->writeInt32(startRecording());
+            return NO_ERROR;
+        } break;
         case STOP_PREVIEW: {
             LOGV("STOP_PREVIEW");
             CHECK_INTERFACE(ICamera, data, reply);
             stopPreview();
             return NO_ERROR;
         } break;
+        case STOP_RECORDING: {
+            LOGV("STOP_RECORDING");
+            CHECK_INTERFACE(ICamera, data, reply);
+            stopRecording();
+            return NO_ERROR;
+        } break;
+        case RELEASE_RECORDING_FRAME: {
+            LOGV("RELEASE_RECORDING_FRAME");
+            CHECK_INTERFACE(ICamera, data, reply);
+            sp<IMemory> mem = interface_cast<IMemory>(data.readStrongBinder());
+            releaseRecordingFrame(mem);
+            return NO_ERROR;
+        } break;
         case PREVIEW_ENABLED: {
             LOGV("PREVIEW_ENABLED");
             CHECK_INTERFACE(ICamera, data, reply);
             reply->writeInt32(previewEnabled());
             return NO_ERROR;
         } break;
+        case RECORDING_ENABLED: {
+            LOGV("RECORDING_ENABLED");
+            CHECK_INTERFACE(ICamera, data, reply);
+            reply->writeInt32(recordingEnabled());
+            return NO_ERROR;
+        } break;
         case AUTO_FOCUS: {
             LOGV("AUTO_FOCUS");
             CHECK_INTERFACE(ICamera, data, reply);
diff --git a/libs/ui/ICameraClient.cpp b/libs/ui/ICameraClient.cpp
index c5d6d52..4bec9d2 100644
--- a/libs/ui/ICameraClient.cpp
+++ b/libs/ui/ICameraClient.cpp
@@ -28,9 +28,10 @@
     SHUTTER_CALLBACK = IBinder::FIRST_CALL_TRANSACTION,
     RAW_CALLBACK,
     JPEG_CALLBACK,
-    FRAME_CALLBACK,
+    PREVIEW_CALLBACK,
     ERROR_CALLBACK,
-    AUTOFOCUS_CALLBACK
+    AUTOFOCUS_CALLBACK,
+    RECORDING_CALLBACK,
 };
 
 class BpCameraClient: public BpInterface<ICameraClient>
@@ -70,14 +71,24 @@
         remote()->transact(JPEG_CALLBACK, data, &reply, IBinder::FLAG_ONEWAY);
     }
 
-    // callback from camera service to app with video frame data
-    void frameCallback(const sp<IMemory>& frame)
+    // callback from camera service to app with preview frame data
+    void previewCallback(const sp<IMemory>& frame)
     {
-        LOGV("frameCallback");
+        LOGV("previewCallback");
         Parcel data, reply;
         data.writeInterfaceToken(ICameraClient::getInterfaceDescriptor());
         data.writeStrongBinder(frame->asBinder());
-        remote()->transact(FRAME_CALLBACK, data, &reply, IBinder::FLAG_ONEWAY);
+        remote()->transact(PREVIEW_CALLBACK, data, &reply, IBinder::FLAG_ONEWAY);
+    }
+
+    // callback from camera service to app with recording frame data
+    void recordingCallback(const sp<IMemory>& frame)
+    {
+        LOGV("recordingCallback");
+        Parcel data, reply;
+        data.writeInterfaceToken(ICameraClient::getInterfaceDescriptor());
+        data.writeStrongBinder(frame->asBinder());
+        remote()->transact(RECORDING_CALLBACK, data, &reply, IBinder::FLAG_ONEWAY);
     }
 
     // callback from camera service to app to report error
@@ -135,11 +146,18 @@
             jpegCallback(picture);
             return NO_ERROR;
         } break;
-        case FRAME_CALLBACK: {
-            LOGV("FRAME_CALLBACK");
+        case PREVIEW_CALLBACK: {
+            LOGV("PREVIEW_CALLBACK");
             CHECK_INTERFACE(ICameraClient, data, reply);
             sp<IMemory> frame = interface_cast<IMemory>(data.readStrongBinder());
-            frameCallback(frame);
+            previewCallback(frame);
+            return NO_ERROR;
+        } break;
+        case RECORDING_CALLBACK: {
+            LOGV("RECORDING_CALLBACK");
+            CHECK_INTERFACE(ICameraClient, data, reply);
+            sp<IMemory> frame = interface_cast<IMemory>(data.readStrongBinder());
+            recordingCallback(frame);
             return NO_ERROR;
         } break;
         case ERROR_CALLBACK: {
diff --git a/libs/ui/ISurface.cpp b/libs/ui/ISurface.cpp
index 6f3cd47..d5e9f81 100644
--- a/libs/ui/ISurface.cpp
+++ b/libs/ui/ISurface.cpp
@@ -27,12 +27,33 @@
 
 namespace android {
 
-enum {
-    REGISTER_BUFFERS = IBinder::FIRST_CALL_TRANSACTION,
-    UNREGISTER_BUFFERS,
-    POST_BUFFER, // one-way transaction
-    CREATE_OVERLAY,
-};
+ISurface::BufferHeap::BufferHeap() 
+    : w(0), h(0), hor_stride(0), ver_stride(0), format(0),
+    transform(0), flags(0) 
+{     
+}
+
+ISurface::BufferHeap::BufferHeap(uint32_t w, uint32_t h,
+        int32_t hor_stride, int32_t ver_stride,
+        PixelFormat format, const sp<IMemoryHeap>& heap)
+    : w(w), h(h), hor_stride(hor_stride), ver_stride(ver_stride),
+      format(format), transform(0), flags(0), heap(heap) 
+{
+}
+
+ISurface::BufferHeap::BufferHeap(uint32_t w, uint32_t h,
+        int32_t hor_stride, int32_t ver_stride,
+        PixelFormat format, uint32_t transform, uint32_t flags,
+        const sp<IMemoryHeap>& heap)
+        : w(w), h(h), hor_stride(hor_stride), ver_stride(ver_stride),
+          format(format), transform(transform), flags(flags), heap(heap) 
+{
+}
+
+
+ISurface::BufferHeap::~BufferHeap() 
+{     
+}
 
 class BpSurface : public BpInterface<ISurface>
 {
@@ -42,17 +63,18 @@
     {
     }
 
-    virtual status_t registerBuffers(int w, int h, int hstride, int vstride,
-            PixelFormat format, const sp<IMemoryHeap>& heap)
+    virtual status_t registerBuffers(const BufferHeap& buffers)
     {
         Parcel data, reply;
         data.writeInterfaceToken(ISurface::getInterfaceDescriptor());
-        data.writeInt32(w);
-        data.writeInt32(h);
-        data.writeInt32(hstride);
-        data.writeInt32(vstride);
-        data.writeInt32(format);
-        data.writeStrongBinder(heap->asBinder());
+        data.writeInt32(buffers.w);
+        data.writeInt32(buffers.h);
+        data.writeInt32(buffers.hor_stride);
+        data.writeInt32(buffers.ver_stride);
+        data.writeInt32(buffers.format);
+        data.writeInt32(buffers.transform);
+        data.writeInt32(buffers.flags);
+        data.writeStrongBinder(buffers.heap->asBinder());
         remote()->transact(REGISTER_BUFFERS, data, &reply);
         status_t result = reply.readInt32();
         return result;
@@ -102,13 +124,16 @@
     switch(code) {
         case REGISTER_BUFFERS: {
             CHECK_INTERFACE(ISurface, data, reply);
-            int w = data.readInt32();
-            int h = data.readInt32();
-            int hs= data.readInt32();
-            int vs= data.readInt32();
-            PixelFormat f = data.readInt32();
-            sp<IMemoryHeap> heap(interface_cast<IMemoryHeap>(data.readStrongBinder()));
-            status_t err = registerBuffers(w,h,hs,vs,f,heap);
+            BufferHeap buffer;
+            buffer.w = data.readInt32();
+            buffer.h = data.readInt32();
+            buffer.hor_stride = data.readInt32();
+            buffer.ver_stride= data.readInt32();
+            buffer.format = data.readInt32();
+            buffer.transform = data.readInt32();
+            buffer.flags = data.readInt32();
+            buffer.heap = interface_cast<IMemoryHeap>(data.readStrongBinder());
+            status_t err = registerBuffers(buffer);
             reply->writeInt32(err);
             return NO_ERROR;
         } break;
diff --git a/libs/ui/PixelFormat.cpp b/libs/ui/PixelFormat.cpp
index 605c8ae..b65ed97 100644
--- a/libs/ui/PixelFormat.cpp
+++ b/libs/ui/PixelFormat.cpp
@@ -19,6 +19,18 @@
 
 namespace android {
 
+size_t PixelFormatInfo::getScanlineSize(unsigned int width) const
+{
+    size_t size;
+    if ((components >= 6) && (components <= 8)) {
+        // YCbCr formats are differents.
+        size = (width * bitsPerPixel)>>3;
+    } else {
+        size = width * bytesPerPixel;
+    }
+    return size;
+}
+
 ssize_t bytesPerPixel(PixelFormat format)
 {
     PixelFormatInfo info;
@@ -47,7 +59,25 @@
     if (!valid) {
         return BAD_INDEX;
     }
-
+    
+    #define COMPONENT(name) \ 
+        case GGL_##name: info->components = PixelFormatInfo::name; break;
+    
+    switch (i->components) {
+        COMPONENT(ALPHA)
+        COMPONENT(RGB)
+        COMPONENT(RGBA)
+        COMPONENT(LUMINANCE)
+        COMPONENT(LUMINANCE_ALPHA)
+        COMPONENT(Y_CB_CR_SP)
+        COMPONENT(Y_CB_CR_P)
+        COMPONENT(Y_CB_CR_I)
+        default:
+            return BAD_INDEX;
+    }
+    
+    #undef COMPONENT
+    
     info->format = format;
     info->bytesPerPixel = i->size;
     info->bitsPerPixel  = i->bitsPerPixel;
@@ -59,6 +89,7 @@
     info->l_green       = i->gl;
     info->h_blue        = i->bh;
     info->l_blue        = i->bl;
+
     return NO_ERROR;
 }
 
diff --git a/libs/utils/CallStack.cpp b/libs/utils/CallStack.cpp
index 26fb22a..2fdaa71 100644
--- a/libs/utils/CallStack.cpp
+++ b/libs/utils/CallStack.cpp
@@ -120,13 +120,18 @@
         char name[];
     };
 
-    const char *map_to_name(uint64_t pc, const char* def) {
+    const char *map_to_name(uint64_t pc, const char* def, uint64_t* start) {
         mapinfo* mi = getMapInfoList();
         while(mi) {
-            if ((pc >= mi->start) && (pc < mi->end))
+            if ((pc >= mi->start) && (pc < mi->end)) {
+                if (start) 
+                    *start = mi->start;
                 return mi->name;
+            }
             mi = mi->next;
         }
+        if (start) 
+            *start = 0;
         return def;
     }
 
@@ -183,8 +188,15 @@
         }
     }
     
-    static const char *mapAddressToName(const void* pc, const char* def) {
-        return sMapInfo.map_to_name((uint64_t)pc, def);
+    static const char *mapAddressToName(const void* pc, const char* def,
+            void const** start) 
+    {
+        uint64_t s;
+        char const* name = sMapInfo.map_to_name(uint64_t(uintptr_t(pc)), def, &s);
+        if (start) {
+            *start = (void*)s;
+        }
+        return name;
     }
 
 };
@@ -297,8 +309,9 @@
         res.append(name);
         res.append(tmp2);
     } else { 
-        name = MapInfo::mapAddressToName(ip, "<unknown>");
-        snprintf(tmp, 256, "pc %p  %s", ip, name);
+        void const* start = 0;
+        name = MapInfo::mapAddressToName(ip, "<unknown>", &start);
+        snprintf(tmp, 256, "pc %08lx  %s", uintptr_t(ip)-uintptr_t(start), name);
         res.append(tmp);
     }
     res.append("\n");
diff --git a/libs/utils/Parcel.cpp b/libs/utils/Parcel.cpp
index 2962b25..4225e67 100644
--- a/libs/utils/Parcel.cpp
+++ b/libs/utils/Parcel.cpp
@@ -658,15 +658,20 @@
     status_t err;
     err = writeInt32(handle.numFds);
     if (err != NO_ERROR) return err;
-    
+
     err = writeInt32(handle.numInts);
     if (err != NO_ERROR) return err;
-    
+
     for (int i=0 ; err==NO_ERROR && i<handle.numFds ; i++)
         err = writeDupFileDescriptor(handle.data[i]);
-    
+
+    if (err != NO_ERROR) {
+        LOGD("write native handle, write dup fd failed");
+        return err;
+    }
+
     err = write(handle.data + handle.numFds, sizeof(int)*handle.numInts);
-    
+
     return err;
 }
 
diff --git a/libs/utils/ResourceTypes.cpp b/libs/utils/ResourceTypes.cpp
index 5a09fb4..2ad3bfe 100644
--- a/libs/utils/ResourceTypes.cpp
+++ b/libs/utils/ResourceTypes.cpp
@@ -176,7 +176,9 @@
 
 void* Res_png_9patch::serialize()
 {
-    void* newData = malloc(serializedSize());
+    // Use calloc since we're going to leave a few holes in the data
+    // and want this to run cleanly under valgrind
+    void* newData = calloc(1, serializedSize());
     serialize(newData);
     return newData;
 }
@@ -1736,7 +1738,7 @@
 }
 
 ssize_t ResTable::getResource(uint32_t resID, Res_value* outValue, bool mayBeBag,
-        uint32_t* outSpecFlags) const
+        uint32_t* outSpecFlags, ResTable_config* outConfig) const
 {
     if (mError != NO_ERROR) {
         return mError;
@@ -1809,7 +1811,7 @@
             (const Res_value*)(((const uint8_t*)type) + offset);
         ResTable_config thisConfig;
         thisConfig.copyFromDtoH(type->config);
-        
+
         if (outSpecFlags != NULL) {
             if (typeClass->typeSpecFlags != NULL) {
                 *outSpecFlags |= dtohl(typeClass->typeSpecFlags[e]);
@@ -1834,6 +1836,9 @@
         outValue->res0 = bestValue->res0;
         outValue->dataType = bestValue->dataType;
         outValue->data = dtohl(bestValue->data);
+        if (outConfig != NULL) {
+            *outConfig = bestItem;
+        }
         TABLE_NOISY(size_t len;
               printf("Found value: pkg=%d, type=%d, str=%s, int=%d\n",
                      bestPackage->header->index,
@@ -3147,13 +3152,13 @@
             const char16_t* pos = s;
             while (pos < end && !failed) {
                 const char16_t* start = pos;
-                end++;
+                pos++;
                 while (pos < end && *pos != '|') {
                     pos++;
                 }
-				//printf("Looking for: %s\n", String8(start, pos-start).string());
+                //printf("Looking for: %s\n", String8(start, pos-start).string());
                 const bag_entry* bagi = bag;
-				ssize_t i;
+                ssize_t i;
                 for (i=0; i<cnt; i++, bagi++) {
                     if (!Res_INTERNALID(bagi->map.name.ident)) {
                         //printf("Trying attr #%08x\n", bagi->map.name.ident);
@@ -3181,7 +3186,7 @@
             }
             unlockBag(bag);
             if (!failed) {
-				//printf("Final flag value: 0x%lx\n", outValue->data);
+                //printf("Final flag value: 0x%lx\n", outValue->data);
                 return true;
             }
         }
@@ -3189,7 +3194,7 @@
 
         if (fromAccessor) {
             if (accessor->getAttributeFlags(attrID, s, len, outValue)) {
-				//printf("Final flag value: 0x%lx\n", outValue->data);
+                //printf("Final flag value: 0x%lx\n", outValue->data);
                 return true;
             }
         }
@@ -3484,7 +3489,7 @@
         
         ResTable_config thisConfig;
         thisConfig.copyFromDtoH(thisType->config);
-        
+
         TABLE_GETENTRY(LOGI("Match entry 0x%x in type 0x%x (sz 0x%x): imsi:%d/%d=%d/%d lang:%c%c=%c%c cnt:%c%c=%c%c "
                             "orien:%d=%d touch:%d=%d density:%d=%d key:%d=%d inp:%d=%d nav:%d=%d w:%d=%d h:%d=%d\n",
                            entryIndex, typeIndex+1, dtohl(thisType->config.size),
diff --git a/libs/utils/String16.cpp b/libs/utils/String16.cpp
index 1f81cad..aef67f2 100644
--- a/libs/utils/String16.cpp
+++ b/libs/utils/String16.cpp
@@ -244,7 +244,6 @@
 
 // ---------------------------------------------------------------------------
 
-// Note: not dealing with generating surrogate pairs.
 static char16_t* allocFromUTF8(const char* in, size_t len)
 {
     if (len == 0) return getEmptyString();
@@ -255,7 +254,10 @@
     
     while (p < end) {
         chars++;
-        p += utf8_char_len(*p);
+        int utf8len = utf8_char_len(*p);
+        uint32_t codepoint = utf8_to_utf32((const uint8_t*)p, utf8len);
+        if (codepoint > 0xFFFF) chars++; // this will be a surrogate pair in utf16
+        p += utf8len;
     }
     
     SharedBuffer* buf = SharedBuffer::alloc((chars+1)*sizeof(char16_t));
@@ -265,7 +267,19 @@
         char16_t* d = str;
         while (p < end) {
             size_t len = utf8_char_len(*p);
-            *d++ = (char16_t)utf8_to_utf32((const uint8_t*)p, len);
+            uint32_t codepoint = utf8_to_utf32((const uint8_t*)p, len);
+
+            // Convert the UTF32 codepoint to one or more UTF16 codepoints
+            if (codepoint <= 0xFFFF) {
+                // Single UTF16 character
+                *d++ = (char16_t) codepoint;
+            } else {
+                // Multiple UTF16 characters with surrogates
+                codepoint = codepoint - 0x10000;
+                *d++ = (char16_t) ((codepoint >> 10) + 0xD800);
+                *d++ = (char16_t) ((codepoint & 0x3FF) + 0xDC00);
+            }
+
             p += len;
         }
         *d = 0;
@@ -388,7 +402,7 @@
         ->editResize((len+1)*sizeof(char16_t));
     if (buf) {
         char16_t* str = (char16_t*)buf->data();
-        memcpy(str, other, len*sizeof(char16_t));
+        memmove(str, other, len*sizeof(char16_t));
         str[len] = 0;
         mString = str;
         return NO_ERROR;
diff --git a/libs/utils/String8.cpp b/libs/utils/String8.cpp
index ab843f6..c50d343 100644
--- a/libs/utils/String8.cpp
+++ b/libs/utils/String8.cpp
@@ -317,8 +317,10 @@
         ->editResize(myLen+otherLen+1);
     if (buf) {
         char* str = (char*)buf->data();
-        memcpy(str+myLen, other, otherLen+1);
         mString = str;
+        str += myLen;
+        memcpy(str, other, otherLen);
+        str[otherLen] = '\0';
         return NO_ERROR;
     }
     return NO_MEMORY;
diff --git a/libs/utils/Threads.cpp b/libs/utils/Threads.cpp
index 74271ba..9287c0b 100644
--- a/libs/utils/Threads.cpp
+++ b/libs/utils/Threads.cpp
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
+// #define LOG_NDEBUG 0
 #define LOG_TAG "libutils.threads"
 
 #include <utils/threads.h>
@@ -838,146 +839,6 @@
 #error "condition variables not supported on this platform"
 #endif
 
-
-/*
- * ===========================================================================
- *      ReadWriteLock class
- * ===========================================================================
- */
-
-#if 0
-#pragma mark -
-#pragma mark ReadWriteLock
-#endif
-
-/*
- * Add a reader.  Readers are nice.  They share.
- */
-void ReadWriteLock::lockForRead()
-{
-    mLock.lock();
-    while (mNumWriters > 0) {
-        LOG(LOG_DEBUG, "thread", "+++ lockForRead: waiting\n");
-        mReadWaiter.wait(mLock);
-    }
-    assert(mNumWriters == 0);
-    mNumReaders++;
-#if defined(PRINT_RENDER_TIMES)
-    if (mNumReaders == 1)
-        mDebugTimer.start();
-#endif
-    mLock.unlock();
-}
-
-/*
- * Try to add a reader.  If it doesn't work right away, return "false".
- */
-bool ReadWriteLock::tryLockForRead()
-{
-    mLock.lock();
-    if (mNumWriters > 0) {
-        mLock.unlock();
-        return false;
-    }
-    assert(mNumWriters == 0);
-    mNumReaders++;
-#if defined(PRINT_RENDER_TIMES)
-    if (mNumReaders == 1)
-        mDebugTimer.start();
-#endif
-    mLock.unlock();
-    return true;
-}
-
-/*
- * Remove a reader.
- */
-void ReadWriteLock::unlockForRead()
-{
-    mLock.lock();
-    if (mNumReaders == 0) {
-        LOG(LOG_WARN, "thread",
-            "WARNING: unlockForRead requested, but not locked\n");
-        return;
-    }
-    assert(mNumReaders > 0);
-    assert(mNumWriters == 0);
-    mNumReaders--;
-    if (mNumReaders == 0) {           // last reader?
-#if defined(PRINT_RENDER_TIMES)
-        mDebugTimer.stop();
-        printf(" rdlk held %.3f msec\n",
-            (double) mDebugTimer.durationUsecs() / 1000.0);
-#endif
-        //printf("+++ signaling writers (if any)\n");
-        mWriteWaiter.signal();      // wake one writer (if any)
-    }
-    mLock.unlock();
-}
-
-/*
- * Add a writer.  This requires exclusive access to the object.
- */
-void ReadWriteLock::lockForWrite()
-{
-    mLock.lock();
-    while (mNumReaders > 0 || mNumWriters > 0) {
-        LOG(LOG_DEBUG, "thread", "+++ lockForWrite: waiting\n");
-        mWriteWaiter.wait(mLock);
-    }
-    assert(mNumReaders == 0);
-    assert(mNumWriters == 0);
-    mNumWriters++;
-#if defined(PRINT_RENDER_TIMES)
-    mDebugTimer.start();
-#endif
-    mLock.unlock();
-}
-
-/*
- * Try to add a writer.  If it doesn't work right away, return "false".
- */
-bool ReadWriteLock::tryLockForWrite()
-{
-    mLock.lock();
-    if (mNumReaders > 0 || mNumWriters > 0) {
-        mLock.unlock();
-        return false;
-    }
-    assert(mNumReaders == 0);
-    assert(mNumWriters == 0);
-    mNumWriters++;
-#if defined(PRINT_RENDER_TIMES)
-    mDebugTimer.start();
-#endif
-    mLock.unlock();
-    return true;
-}
-
-/*
- * Remove a writer.
- */
-void ReadWriteLock::unlockForWrite()
-{
-    mLock.lock();
-    if (mNumWriters == 0) {
-        LOG(LOG_WARN, "thread",
-            "WARNING: unlockForWrite requested, but not locked\n");
-        return;
-    }
-    assert(mNumWriters == 1);
-    mNumWriters--;
-#if defined(PRINT_RENDER_TIMES)
-    mDebugTimer.stop();
-    //printf(" wrlk held %.3f msec\n",
-    //    (double) mDebugTimer.durationUsecs() / 1000.0);
-#endif
-    // mWriteWaiter.signal();       // should other writers get first dibs?
-    //printf("+++ signaling readers (if any)\n");
-    mReadWaiter.broadcast();        // wake all readers (if any)
-    mLock.unlock();
-}
-
 // ----------------------------------------------------------------------------
 
 #if 0
@@ -1025,6 +886,8 @@
     // hold a strong reference on ourself
     mHoldSelf = this;
 
+    mRunning = true;
+
     bool res;
     if (mCanCallJava) {
         res = createThreadEtc(_threadLoop,
@@ -1038,14 +901,16 @@
         mStatus = UNKNOWN_ERROR;   // something happened!
         mRunning = false;
         mThread = thread_id_t(-1);
+        mHoldSelf.clear();  // "this" may have gone away after this.
+
+        return UNKNOWN_ERROR;
     }
     
-    if (mStatus < 0) {
-        // something happened, don't leak
-        mHoldSelf.clear();
-    }
-    
-    return mStatus;
+    // Do not refer to mStatus here: The thread is already running (may, in fact
+    // already have exited with a valid mStatus result). The NO_ERROR indication
+    // here merely indicates successfully starting the thread and does not
+    // imply successful termination/execution.
+    return NO_ERROR;
 }
 
 int Thread::_threadLoop(void* user)
@@ -1055,20 +920,32 @@
     wp<Thread> weak(strong);
     self->mHoldSelf.clear();
 
-    // we're about to run...
-    self->mStatus = self->readyToRun();
-    if (self->mStatus!=NO_ERROR || self->mExitPending) {
-        // pretend the thread never started...
-        self->mExitPending = false;
-        self->mRunning = false;
-        return 0;
-    }
-    
-    // thread is running now
-    self->mRunning = true;
+    bool first = true;
 
     do {
-        bool result = self->threadLoop();
+        bool result;
+        if (first) {
+            first = false;
+            self->mStatus = self->readyToRun();
+            result = (self->mStatus == NO_ERROR);
+
+            if (result && !self->mExitPending) {
+                // Binder threads (and maybe others) rely on threadLoop
+                // running at least once after a successful ::readyToRun()
+                // (unless, of course, the thread has already been asked to exit
+                // at that point).
+                // This is because threads are essentially used like this:
+                //   (new ThreadSubclass())->run();
+                // The caller therefore does not retain a strong reference to
+                // the thread and the thread would simply disappear after the
+                // successful ::readyToRun() call instead of entering the
+                // threadLoop at least once.
+                result = self->threadLoop();
+            }
+        } else {
+            result = self->threadLoop();
+        }
+
         if (result == false || self->mExitPending) {
             self->mExitPending = true;
             self->mLock.lock();
@@ -1095,24 +972,23 @@
 
 status_t Thread::requestExitAndWait()
 {
-    if (mStatus == OK) {
+    if (mThread == getThreadId()) {
+        LOGW(
+        "Thread (this=%p): don't call waitForExit() from this "
+        "Thread object's thread. It's a guaranteed deadlock!",
+        this);
 
-        if (mThread == getThreadId()) {
-            LOGW(
-            "Thread (this=%p): don't call waitForExit() from this "
-            "Thread object's thread. It's a guaranteed deadlock!",
-            this);
-            return WOULD_BLOCK;
-        }
-        
-        requestExit();
-
-        Mutex::Autolock _l(mLock);
-        while (mRunning == true) {
-            mThreadExitedCondition.wait(mLock);
-        }
-        mExitPending = false;
+        return WOULD_BLOCK;
     }
+    
+    requestExit();
+
+    Mutex::Autolock _l(mLock);
+    while (mRunning == true) {
+        mThreadExitedCondition.wait(mLock);
+    }
+    mExitPending = false;
+
     return mStatus;
 }
 
diff --git a/opengl/include/EGL/egl.h b/opengl/include/EGL/egl.h
new file mode 100644
index 0000000..c269976
--- /dev/null
+++ b/opengl/include/EGL/egl.h
@@ -0,0 +1,330 @@
+/* -*- mode: c; tab-width: 8; -*- */
+/* vi: set sw=4 ts=8: */
+/* Reference version of egl.h for EGL 1.4.
+ * $Revision: 7244 $ on $Date: 2009-01-20 17:06:59 -0800 (Tue, 20 Jan 2009) $
+ */
+
+/*
+** Copyright (c) 2007-2009 The Khronos Group Inc.
+**
+** Permission is hereby granted, free of charge, to any person obtaining a
+** copy of this software and/or associated documentation files (the
+** "Materials"), to deal in the Materials without restriction, including
+** without limitation the rights to use, copy, modify, merge, publish,
+** distribute, sublicense, and/or sell copies of the Materials, and to
+** permit persons to whom the Materials are furnished to do so, subject to
+** the following conditions:
+**
+** The above copyright notice and this permission notice shall be included
+** in all copies or substantial portions of the Materials.
+**
+** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+*/
+
+#ifndef __egl_h_
+#define __egl_h_
+
+/* All platform-dependent types and macro boilerplate (such as EGLAPI
+ * and EGLAPIENTRY) should go in eglplatform.h.
+ */
+#include <EGL/eglplatform.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* EGL Types */
+/* EGLint is defined in eglplatform.h */
+typedef unsigned int EGLBoolean;
+typedef unsigned int EGLenum;
+typedef void *EGLConfig;
+typedef void *EGLContext;
+typedef void *EGLDisplay;
+typedef void *EGLSurface;
+typedef void *EGLClientBuffer;
+
+/* EGL Versioning */
+#define EGL_VERSION_1_0			1
+#define EGL_VERSION_1_1			1
+#define EGL_VERSION_1_2			1
+#define EGL_VERSION_1_3			1
+#define EGL_VERSION_1_4			1
+
+/* EGL Enumerants. Bitmasks and other exceptional cases aside, most
+ * enums are assigned unique values starting at 0x3000.
+ */
+
+/* EGL aliases */
+#define EGL_FALSE			0
+#define EGL_TRUE			1
+
+/* Out-of-band handle values */
+#define EGL_DEFAULT_DISPLAY		((EGLNativeDisplayType)0)
+#define EGL_NO_CONTEXT			((EGLContext)0)
+#define EGL_NO_DISPLAY			((EGLDisplay)0)
+#define EGL_NO_SURFACE			((EGLSurface)0)
+
+/* Out-of-band attribute value */
+#define EGL_DONT_CARE			((EGLint)-1)
+
+/* Errors / GetError return values */
+#define EGL_SUCCESS			0x3000
+#define EGL_NOT_INITIALIZED		0x3001
+#define EGL_BAD_ACCESS			0x3002
+#define EGL_BAD_ALLOC			0x3003
+#define EGL_BAD_ATTRIBUTE		0x3004
+#define EGL_BAD_CONFIG			0x3005
+#define EGL_BAD_CONTEXT			0x3006
+#define EGL_BAD_CURRENT_SURFACE		0x3007
+#define EGL_BAD_DISPLAY			0x3008
+#define EGL_BAD_MATCH			0x3009
+#define EGL_BAD_NATIVE_PIXMAP		0x300A
+#define EGL_BAD_NATIVE_WINDOW		0x300B
+#define EGL_BAD_PARAMETER		0x300C
+#define EGL_BAD_SURFACE			0x300D
+#define EGL_CONTEXT_LOST		0x300E	/* EGL 1.1 - IMG_power_management */
+
+/* Reserved 0x300F-0x301F for additional errors */
+
+/* Config attributes */
+#define EGL_BUFFER_SIZE			0x3020
+#define EGL_ALPHA_SIZE			0x3021
+#define EGL_BLUE_SIZE			0x3022
+#define EGL_GREEN_SIZE			0x3023
+#define EGL_RED_SIZE			0x3024
+#define EGL_DEPTH_SIZE			0x3025
+#define EGL_STENCIL_SIZE		0x3026
+#define EGL_CONFIG_CAVEAT		0x3027
+#define EGL_CONFIG_ID			0x3028
+#define EGL_LEVEL			0x3029
+#define EGL_MAX_PBUFFER_HEIGHT		0x302A
+#define EGL_MAX_PBUFFER_PIXELS		0x302B
+#define EGL_MAX_PBUFFER_WIDTH		0x302C
+#define EGL_NATIVE_RENDERABLE		0x302D
+#define EGL_NATIVE_VISUAL_ID		0x302E
+#define EGL_NATIVE_VISUAL_TYPE		0x302F
+#define EGL_PRESERVED_RESOURCES		0x3030
+#define EGL_SAMPLES			0x3031
+#define EGL_SAMPLE_BUFFERS		0x3032
+#define EGL_SURFACE_TYPE		0x3033
+#define EGL_TRANSPARENT_TYPE		0x3034
+#define EGL_TRANSPARENT_BLUE_VALUE	0x3035
+#define EGL_TRANSPARENT_GREEN_VALUE	0x3036
+#define EGL_TRANSPARENT_RED_VALUE	0x3037
+#define EGL_NONE			0x3038	/* Attrib list terminator */
+#define EGL_BIND_TO_TEXTURE_RGB		0x3039
+#define EGL_BIND_TO_TEXTURE_RGBA	0x303A
+#define EGL_MIN_SWAP_INTERVAL		0x303B
+#define EGL_MAX_SWAP_INTERVAL		0x303C
+#define EGL_LUMINANCE_SIZE		0x303D
+#define EGL_ALPHA_MASK_SIZE		0x303E
+#define EGL_COLOR_BUFFER_TYPE		0x303F
+#define EGL_RENDERABLE_TYPE		0x3040
+#define EGL_MATCH_NATIVE_PIXMAP		0x3041	/* Pseudo-attribute (not queryable) */
+#define EGL_CONFORMANT			0x3042
+
+/* Reserved 0x3041-0x304F for additional config attributes */
+
+/* Config attribute values */
+#define EGL_SLOW_CONFIG			0x3050	/* EGL_CONFIG_CAVEAT value */
+#define EGL_NON_CONFORMANT_CONFIG	0x3051	/* EGL_CONFIG_CAVEAT value */
+#define EGL_TRANSPARENT_RGB		0x3052	/* EGL_TRANSPARENT_TYPE value */
+#define EGL_RGB_BUFFER			0x308E	/* EGL_COLOR_BUFFER_TYPE value */
+#define EGL_LUMINANCE_BUFFER		0x308F	/* EGL_COLOR_BUFFER_TYPE value */
+
+/* More config attribute values, for EGL_TEXTURE_FORMAT */
+#define EGL_NO_TEXTURE			0x305C
+#define EGL_TEXTURE_RGB			0x305D
+#define EGL_TEXTURE_RGBA		0x305E
+#define EGL_TEXTURE_2D			0x305F
+
+/* Config attribute mask bits */
+#define EGL_PBUFFER_BIT			0x0001	/* EGL_SURFACE_TYPE mask bits */
+#define EGL_PIXMAP_BIT			0x0002	/* EGL_SURFACE_TYPE mask bits */
+#define EGL_WINDOW_BIT			0x0004	/* EGL_SURFACE_TYPE mask bits */
+#define EGL_VG_COLORSPACE_LINEAR_BIT	0x0020	/* EGL_SURFACE_TYPE mask bits */
+#define EGL_VG_ALPHA_FORMAT_PRE_BIT	0x0040	/* EGL_SURFACE_TYPE mask bits */
+#define EGL_MULTISAMPLE_RESOLVE_BOX_BIT 0x0200	/* EGL_SURFACE_TYPE mask bits */
+#define EGL_SWAP_BEHAVIOR_PRESERVED_BIT 0x0400	/* EGL_SURFACE_TYPE mask bits */
+
+#define EGL_OPENGL_ES_BIT		0x0001	/* EGL_RENDERABLE_TYPE mask bits */
+#define EGL_OPENVG_BIT			0x0002	/* EGL_RENDERABLE_TYPE mask bits */
+#define EGL_OPENGL_ES2_BIT		0x0004	/* EGL_RENDERABLE_TYPE mask bits */
+#define EGL_OPENGL_BIT			0x0008	/* EGL_RENDERABLE_TYPE mask bits */
+
+/* QueryString targets */
+#define EGL_VENDOR			0x3053
+#define EGL_VERSION			0x3054
+#define EGL_EXTENSIONS			0x3055
+#define EGL_CLIENT_APIS			0x308D
+
+/* QuerySurface / SurfaceAttrib / CreatePbufferSurface targets */
+#define EGL_HEIGHT			0x3056
+#define EGL_WIDTH			0x3057
+#define EGL_LARGEST_PBUFFER		0x3058
+#define EGL_TEXTURE_FORMAT		0x3080
+#define EGL_TEXTURE_TARGET		0x3081
+#define EGL_MIPMAP_TEXTURE		0x3082
+#define EGL_MIPMAP_LEVEL		0x3083
+#define EGL_RENDER_BUFFER		0x3086
+#define EGL_VG_COLORSPACE		0x3087
+#define EGL_VG_ALPHA_FORMAT		0x3088
+#define EGL_HORIZONTAL_RESOLUTION	0x3090
+#define EGL_VERTICAL_RESOLUTION		0x3091
+#define EGL_PIXEL_ASPECT_RATIO		0x3092
+#define EGL_SWAP_BEHAVIOR		0x3093
+#define EGL_MULTISAMPLE_RESOLVE		0x3099
+
+/* EGL_RENDER_BUFFER values / BindTexImage / ReleaseTexImage buffer targets */
+#define EGL_BACK_BUFFER			0x3084
+#define EGL_SINGLE_BUFFER		0x3085
+
+/* OpenVG color spaces */
+#define EGL_VG_COLORSPACE_sRGB		0x3089	/* EGL_VG_COLORSPACE value */
+#define EGL_VG_COLORSPACE_LINEAR	0x308A	/* EGL_VG_COLORSPACE value */
+
+/* OpenVG alpha formats */
+#define EGL_VG_ALPHA_FORMAT_NONPRE	0x308B	/* EGL_ALPHA_FORMAT value */
+#define EGL_VG_ALPHA_FORMAT_PRE		0x308C	/* EGL_ALPHA_FORMAT value */
+
+/* Constant scale factor by which fractional display resolutions &
+ * aspect ratio are scaled when queried as integer values.
+ */
+#define EGL_DISPLAY_SCALING		10000
+
+/* Unknown display resolution/aspect ratio */
+#define EGL_UNKNOWN			((EGLint)-1)
+
+/* Back buffer swap behaviors */
+#define EGL_BUFFER_PRESERVED		0x3094	/* EGL_SWAP_BEHAVIOR value */
+#define EGL_BUFFER_DESTROYED		0x3095	/* EGL_SWAP_BEHAVIOR value */
+
+/* CreatePbufferFromClientBuffer buffer types */
+#define EGL_OPENVG_IMAGE		0x3096
+
+/* QueryContext targets */
+#define EGL_CONTEXT_CLIENT_TYPE		0x3097
+
+/* CreateContext attributes */
+#define EGL_CONTEXT_CLIENT_VERSION	0x3098
+
+/* Multisample resolution behaviors */
+#define EGL_MULTISAMPLE_RESOLVE_DEFAULT 0x309A	/* EGL_MULTISAMPLE_RESOLVE value */
+#define EGL_MULTISAMPLE_RESOLVE_BOX	0x309B	/* EGL_MULTISAMPLE_RESOLVE value */
+
+/* BindAPI/QueryAPI targets */
+#define EGL_OPENGL_ES_API		0x30A0
+#define EGL_OPENVG_API			0x30A1
+#define EGL_OPENGL_API			0x30A2
+
+/* GetCurrentSurface targets */
+#define EGL_DRAW			0x3059
+#define EGL_READ			0x305A
+
+/* WaitNative engines */
+#define EGL_CORE_NATIVE_ENGINE		0x305B
+
+/* EGL 1.2 tokens renamed for consistency in EGL 1.3 */
+#define EGL_COLORSPACE			EGL_VG_COLORSPACE
+#define EGL_ALPHA_FORMAT		EGL_VG_ALPHA_FORMAT
+#define EGL_COLORSPACE_sRGB		EGL_VG_COLORSPACE_sRGB
+#define EGL_COLORSPACE_LINEAR		EGL_VG_COLORSPACE_LINEAR
+#define EGL_ALPHA_FORMAT_NONPRE		EGL_VG_ALPHA_FORMAT_NONPRE
+#define EGL_ALPHA_FORMAT_PRE		EGL_VG_ALPHA_FORMAT_PRE
+
+/* EGL extensions must request enum blocks from the Khronos
+ * API Registrar, who maintains the enumerant registry. Submit
+ * a bug in Khronos Bugzilla against task "Registry".
+ */
+
+
+
+/* EGL Functions */
+
+EGLAPI EGLint EGLAPIENTRY eglGetError(void);
+
+EGLAPI EGLDisplay EGLAPIENTRY eglGetDisplay(EGLNativeDisplayType display_id);
+EGLAPI EGLBoolean EGLAPIENTRY eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor);
+EGLAPI EGLBoolean EGLAPIENTRY eglTerminate(EGLDisplay dpy);
+
+EGLAPI const char * EGLAPIENTRY eglQueryString(EGLDisplay dpy, EGLint name);
+
+EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigs(EGLDisplay dpy, EGLConfig *configs,
+			 EGLint config_size, EGLint *num_config);
+EGLAPI EGLBoolean EGLAPIENTRY eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list,
+			   EGLConfig *configs, EGLint config_size,
+			   EGLint *num_config);
+EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config,
+			      EGLint attribute, EGLint *value);
+
+EGLAPI EGLSurface EGLAPIENTRY eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config,
+				  EGLNativeWindowType win,
+				  const EGLint *attrib_list);
+EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config,
+				   const EGLint *attrib_list);
+EGLAPI EGLSurface EGLAPIENTRY eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config,
+				  EGLNativePixmapType pixmap,
+				  const EGLint *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglDestroySurface(EGLDisplay dpy, EGLSurface surface);
+EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurface(EGLDisplay dpy, EGLSurface surface,
+			   EGLint attribute, EGLint *value);
+
+EGLAPI EGLBoolean EGLAPIENTRY eglBindAPI(EGLenum api);
+EGLAPI EGLenum EGLAPIENTRY eglQueryAPI(void);
+
+EGLAPI EGLBoolean EGLAPIENTRY eglWaitClient(void);
+
+EGLAPI EGLBoolean EGLAPIENTRY eglReleaseThread(void);
+
+EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferFromClientBuffer(
+	      EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer,
+	      EGLConfig config, const EGLint *attrib_list);
+
+EGLAPI EGLBoolean EGLAPIENTRY eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface,
+			    EGLint attribute, EGLint value);
+EGLAPI EGLBoolean EGLAPIENTRY eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer);
+EGLAPI EGLBoolean EGLAPIENTRY eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer);
+
+
+EGLAPI EGLBoolean EGLAPIENTRY eglSwapInterval(EGLDisplay dpy, EGLint interval);
+
+
+EGLAPI EGLContext EGLAPIENTRY eglCreateContext(EGLDisplay dpy, EGLConfig config,
+			    EGLContext share_context,
+			    const EGLint *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglDestroyContext(EGLDisplay dpy, EGLContext ctx);
+EGLAPI EGLBoolean EGLAPIENTRY eglMakeCurrent(EGLDisplay dpy, EGLSurface draw,
+			  EGLSurface read, EGLContext ctx);
+
+EGLAPI EGLContext EGLAPIENTRY eglGetCurrentContext(void);
+EGLAPI EGLSurface EGLAPIENTRY eglGetCurrentSurface(EGLint readdraw);
+EGLAPI EGLDisplay EGLAPIENTRY eglGetCurrentDisplay(void);
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryContext(EGLDisplay dpy, EGLContext ctx,
+			   EGLint attribute, EGLint *value);
+
+EGLAPI EGLBoolean EGLAPIENTRY eglWaitGL(void);
+EGLAPI EGLBoolean EGLAPIENTRY eglWaitNative(EGLint engine);
+EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffers(EGLDisplay dpy, EGLSurface surface);
+EGLAPI EGLBoolean EGLAPIENTRY eglCopyBuffers(EGLDisplay dpy, EGLSurface surface,
+			  EGLNativePixmapType target);
+
+/* This is a generic function pointer type, whose name indicates it must
+ * be cast to the proper type *and calling convention* before use.
+ */
+typedef void (*__eglMustCastToProperFunctionPointerType)(void);
+
+/* Now, define eglGetProcAddress using the generic function ptr. type */
+EGLAPI __eglMustCastToProperFunctionPointerType EGLAPIENTRY
+       eglGetProcAddress(const char *procname);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __egl_h_ */
diff --git a/opengl/include/EGL/eglext.h b/opengl/include/EGL/eglext.h
new file mode 100644
index 0000000..25cfcb8
--- /dev/null
+++ b/opengl/include/EGL/eglext.h
@@ -0,0 +1,138 @@
+#ifndef __eglext_h_
+#define __eglext_h_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+** Copyright (c) 2007-2009 The Khronos Group Inc.
+**
+** Permission is hereby granted, free of charge, to any person obtaining a
+** copy of this software and/or associated documentation files (the
+** "Materials"), to deal in the Materials without restriction, including
+** without limitation the rights to use, copy, modify, merge, publish,
+** distribute, sublicense, and/or sell copies of the Materials, and to
+** permit persons to whom the Materials are furnished to do so, subject to
+** the following conditions:
+**
+** The above copyright notice and this permission notice shall be included
+** in all copies or substantial portions of the Materials.
+**
+** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+*/
+
+#include <EGL/eglplatform.h>
+
+/*************************************************************/
+
+/* Header file version number */
+/* Current version at http://www.khronos.org/registry/egl/ */
+/* $Revision: 7244 $ on $Date: 2009-01-20 17:06:59 -0800 (Tue, 20 Jan 2009) $ */
+#define EGL_EGLEXT_VERSION 3
+
+#ifndef EGL_KHR_config_attribs
+#define EGL_KHR_config_attribs 1
+#define EGL_CONFORMANT_KHR			0x3042	/* EGLConfig attribute */
+#define EGL_VG_COLORSPACE_LINEAR_BIT_KHR	0x0020	/* EGL_SURFACE_TYPE bitfield */
+#define EGL_VG_ALPHA_FORMAT_PRE_BIT_KHR		0x0040	/* EGL_SURFACE_TYPE bitfield */
+#endif
+
+#ifndef EGL_KHR_lock_surface
+#define EGL_KHR_lock_surface 1
+#define EGL_READ_SURFACE_BIT_KHR		0x0001	/* EGL_LOCK_USAGE_HINT_KHR bitfield */
+#define EGL_WRITE_SURFACE_BIT_KHR		0x0002	/* EGL_LOCK_USAGE_HINT_KHR bitfield */
+#define EGL_LOCK_SURFACE_BIT_KHR		0x0080	/* EGL_SURFACE_TYPE bitfield */
+#define EGL_OPTIMAL_FORMAT_BIT_KHR		0x0100	/* EGL_SURFACE_TYPE bitfield */
+#define EGL_MATCH_FORMAT_KHR			0x3043	/* EGLConfig attribute */
+#define EGL_FORMAT_RGB_565_EXACT_KHR		0x30C0	/* EGL_MATCH_FORMAT_KHR value */
+#define EGL_FORMAT_RGB_565_KHR			0x30C1	/* EGL_MATCH_FORMAT_KHR value */
+#define EGL_FORMAT_RGBA_8888_EXACT_KHR		0x30C2	/* EGL_MATCH_FORMAT_KHR value */
+#define EGL_FORMAT_RGBA_8888_KHR		0x30C3	/* EGL_MATCH_FORMAT_KHR value */
+#define EGL_MAP_PRESERVE_PIXELS_KHR		0x30C4	/* eglLockSurfaceKHR attribute */
+#define EGL_LOCK_USAGE_HINT_KHR			0x30C5	/* eglLockSurfaceKHR attribute */
+#define EGL_BITMAP_POINTER_KHR			0x30C6	/* eglQuerySurface attribute */
+#define EGL_BITMAP_PITCH_KHR			0x30C7	/* eglQuerySurface attribute */
+#define EGL_BITMAP_ORIGIN_KHR			0x30C8	/* eglQuerySurface attribute */
+#define EGL_BITMAP_PIXEL_RED_OFFSET_KHR		0x30C9	/* eglQuerySurface attribute */
+#define EGL_BITMAP_PIXEL_GREEN_OFFSET_KHR	0x30CA	/* eglQuerySurface attribute */
+#define EGL_BITMAP_PIXEL_BLUE_OFFSET_KHR	0x30CB	/* eglQuerySurface attribute */
+#define EGL_BITMAP_PIXEL_ALPHA_OFFSET_KHR	0x30CC	/* eglQuerySurface attribute */
+#define EGL_BITMAP_PIXEL_LUMINANCE_OFFSET_KHR	0x30CD	/* eglQuerySurface attribute */
+#define EGL_LOWER_LEFT_KHR			0x30CE	/* EGL_BITMAP_ORIGIN_KHR value */
+#define EGL_UPPER_LEFT_KHR			0x30CF	/* EGL_BITMAP_ORIGIN_KHR value */
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglLockSurfaceKHR (EGLDisplay display, EGLSurface surface, const EGLint *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglUnlockSurfaceKHR (EGLDisplay display, EGLSurface surface);
+#endif /* EGL_EGLEXT_PROTOTYPES */
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLLOCKSURFACEKHRPROC) (EGLDisplay display, EGLSurface surface, const EGLint *attrib_list);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLUNLOCKSURFACEKHRPROC) (EGLDisplay display, EGLSurface surface);
+#endif
+
+#ifndef EGL_KHR_image
+#define EGL_KHR_image 1
+#define EGL_NATIVE_PIXMAP_KHR			0x30B0	/* eglCreateImageKHR target */
+typedef void *EGLImageKHR;
+#define EGL_NO_IMAGE_KHR			((EGLImageKHR)0)
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLImageKHR EGLAPIENTRY eglCreateImageKHR (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglDestroyImageKHR (EGLDisplay dpy, EGLImageKHR image);
+#endif /* EGL_EGLEXT_PROTOTYPES */
+typedef EGLImageKHR (EGLAPIENTRYP PFNEGLCREATEIMAGEKHRPROC) (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYIMAGEKHRPROC) (EGLDisplay dpy, EGLImageKHR image);
+#endif
+
+#ifndef EGL_KHR_vg_parent_image
+#define EGL_KHR_vg_parent_image 1
+#define EGL_VG_PARENT_IMAGE_KHR			0x30BA	/* eglCreateImageKHR target */
+#endif
+
+#ifndef EGL_KHR_gl_texture_2D_image
+#define EGL_KHR_gl_texture_2D_image 1
+#define EGL_GL_TEXTURE_2D_KHR			0x30B1	/* eglCreateImageKHR target */
+#define EGL_GL_TEXTURE_LEVEL_KHR		0x30BC	/* eglCreateImageKHR attribute */
+#endif
+
+#ifndef EGL_KHR_gl_texture_cubemap_image
+#define EGL_KHR_gl_texture_cubemap_image 1
+#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR	0x30B3	/* eglCreateImageKHR target */
+#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR	0x30B4	/* eglCreateImageKHR target */
+#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR	0x30B5	/* eglCreateImageKHR target */
+#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR	0x30B6	/* eglCreateImageKHR target */
+#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR	0x30B7	/* eglCreateImageKHR target */
+#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR	0x30B8	/* eglCreateImageKHR target */
+#endif
+
+#ifndef EGL_KHR_gl_texture_3D_image
+#define EGL_KHR_gl_texture_3D_image 1
+#define EGL_GL_TEXTURE_3D_KHR			0x30B2	/* eglCreateImageKHR target */
+#define EGL_GL_TEXTURE_ZOFFSET_KHR		0x30BD	/* eglCreateImageKHR attribute */
+#endif
+
+#ifndef EGL_KHR_gl_renderbuffer_image
+#define EGL_KHR_gl_renderbuffer_image 1
+#define EGL_GL_RENDERBUFFER_KHR			0x30B9	/* eglCreateImageKHR target */
+#endif
+
+#ifndef EGL_KHR_image_base
+#define EGL_KHR_image_base 1
+/* Most interfaces defined by EGL_KHR_image_pixmap above */
+#define EGL_IMAGE_PRESERVED_KHR			0x30D2	/* eglCreateImageKHR attribute */
+#endif
+
+#ifndef EGL_KHR_image_pixmap
+#define EGL_KHR_image_pixmap 1
+/* Interfaces defined by EGL_KHR_image above */
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/GLES/eglnatives.h b/opengl/include/EGL/eglnatives.h
similarity index 86%
rename from include/GLES/eglnatives.h
rename to opengl/include/EGL/eglnatives.h
index 1cd57d0..21622dc 100644
--- a/include/GLES/eglnatives.h
+++ b/opengl/include/EGL/eglnatives.h
@@ -22,24 +22,9 @@
 #ifdef __cplusplus
 extern "C" {
 #endif
+
 /*****************************************************************************/
 
-struct egl_native_window_t;
-struct egl_native_pixmap_t;
-
-
-typedef struct egl_native_window_t*     NativeWindowType;
-typedef struct egl_native_pixmap_t*     NativePixmapType;
-typedef void*                           NativeDisplayType;
-
-/* 
- * This a convenience function to create a NativeWindowType surface
- * that maps to the whole screen
- * This function is actually implemented in libui.so
- */
-
-NativeWindowType android_createDisplaySurface();
-
 /* flags returned from swapBuffer */
 #define EGL_NATIVES_FLAG_SIZE_CHANGED       0x00000001
 
@@ -151,48 +136,46 @@
     /*
      * Hook called by EGL to hold a reference on this structure
      */
-    void        (*incRef)(NativeWindowType window);
+    void        (*incRef)(struct egl_native_window_t* window);
 
     /*
      * Hook called by EGL to release a reference on this structure
      */
-    void        (*decRef)(NativeWindowType window);
+    void        (*decRef)(struct egl_native_window_t* window);
 
     /*
      * Hook called by EGL to perform a page flip. This function
      * may update the size attributes above, in which case it returns
      * the EGL_NATIVES_FLAG_SIZE_CHANGED bit set.
      */
-    uint32_t    (*swapBuffers)(NativeWindowType window);
+    uint32_t    (*swapBuffers)(struct egl_native_window_t* window);
     
     /*
-     * Hook called by EGL to set the swap rectangle. this hook can be 
-     * null (operation not supported) 
-     */
-    void        (*setSwapRectangle)(NativeWindowType window, int l, int t, int w, int h);
-
-    /*
      * Reserved for future use. MUST BE ZERO.
      */
     void        (*reserved_proc_0)(void);
-    
+
+    /*
+     * Reserved for future use. MUST BE ZERO.
+     */
+    void        (*reserved_proc_1)(void);
     
     /*
-     * Hook called by EGL to retrieve the next buffer to render into. 
-     * This call updates this structure.
+     * Reserved for future use. MUST BE ZERO.
      */
-    uint32_t    (*nextBuffer)(NativeWindowType window);
+    void        (*reserved_proc_2)(void);
 
+    
     /*
      * Hook called by EGL when the native surface is associated to EGL
      * (eglCreateWindowSurface). Can be NULL.
      */
-    void        (*connect)(NativeWindowType window);
+    void        (*connect)(struct egl_native_window_t* window);
 
     /*
      * Hook called by EGL when eglDestroySurface is called.  Can be NULL.
      */
-    void        (*disconnect)(NativeWindowType window);
+    void        (*disconnect)(struct egl_native_window_t* window);
     
     /*
      * Reserved for future use. MUST BE ZERO.
@@ -224,6 +207,17 @@
 
 /*****************************************************************************/
 
+/* 
+ * This a convenience function to create a NativeWindowType surface
+ * that maps to the whole screen
+ * This function is actually implemented in libui.so
+ */
+
+struct egl_native_window_t* android_createDisplaySurface();
+
+/*****************************************************************************/
+
+
 /*
  * OEM's egl's library (libhgl.so) must imlement these hooks to allocate
  * the GPU memory they need  
diff --git a/opengl/include/EGL/eglplatform.h b/opengl/include/EGL/eglplatform.h
new file mode 100644
index 0000000..ac00901
--- /dev/null
+++ b/opengl/include/EGL/eglplatform.h
@@ -0,0 +1,117 @@
+#ifndef __eglplatform_h_
+#define __eglplatform_h_
+
+/*
+** Copyright (c) 2007-2009 The Khronos Group Inc.
+**
+** Permission is hereby granted, free of charge, to any person obtaining a
+** copy of this software and/or associated documentation files (the
+** "Materials"), to deal in the Materials without restriction, including
+** without limitation the rights to use, copy, modify, merge, publish,
+** distribute, sublicense, and/or sell copies of the Materials, and to
+** permit persons to whom the Materials are furnished to do so, subject to
+** the following conditions:
+**
+** The above copyright notice and this permission notice shall be included
+** in all copies or substantial portions of the Materials.
+**
+** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+*/
+
+/* Platform-specific types and definitions for egl.h
+ * $Revision: 7244 $ on $Date: 2009-01-20 17:06:59 -0800 (Tue, 20 Jan 2009) $
+ *
+ * Adopters may modify khrplatform.h and this file to suit their platform.
+ * You are encouraged to submit all modifications to the Khronos group so that
+ * they can be included in future versions of this file.  Please submit changes
+ * by sending them to the public Khronos Bugzilla (http://khronos.org/bugzilla)
+ * by filing a bug against product "EGL" component "Registry".
+ */
+
+#include <KHR/khrplatform.h>
+
+/* Macros used in EGL function prototype declarations.
+ *
+ * EGL functions should be prototyped as:
+ *
+ * EGLAPI return-type EGLAPIENTRY eglFunction(arguments);
+ * typedef return-type (EXPAPIENTRYP PFNEGLFUNCTIONPROC) (arguments);
+ *
+ * KHRONOS_APICALL and KHRONOS_APIENTRY are defined in KHR/khrplatform.h
+ */
+
+#ifndef EGLAPI
+#define EGLAPI KHRONOS_APICALL
+#endif
+
+#define EGLAPIENTRY  KHRONOS_APIENTRY
+#define EGLAPIENTRYP KHRONOS_APIENTRY*
+
+/* The types NativeDisplayType, NativeWindowType, and NativePixmapType
+ * are aliases of window-system-dependent types, such as X Display * or
+ * Windows Device Context. They must be defined in platform-specific
+ * code below. The EGL-prefixed versions of Native*Type are the same
+ * types, renamed in EGL 1.3 so all types in the API start with "EGL".
+ */
+
+#if defined(_WIN32) || defined(__VC32__) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) /* Win32 and WinCE */
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN 1
+#endif
+#include <windows.h>
+
+typedef HDC     EGLNativeDisplayType;
+typedef HBITMAP EGLNativePixmapType;
+typedef HWND    EGLNativeWindowType;
+
+#elif defined(__WINSCW__) || defined(__SYMBIAN32__)  /* Symbian */
+
+typedef int   EGLNativeDisplayType;
+typedef void *EGLNativeWindowType;
+typedef void *EGLNativePixmapType;
+
+#elif defined(__unix__) && !defined(ANDROID)
+
+/* X11 (tentative)  */
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+
+typedef Display *EGLNativeDisplayType;
+typedef Pixmap   EGLNativePixmapType;
+typedef Window   EGLNativeWindowType;
+
+
+#elif defined(ANDROID)
+
+#include <EGL/eglnatives.h>
+
+typedef struct egl_native_window_t*     EGLNativeWindowType;
+typedef struct egl_native_pixmap_t*     EGLNativePixmapType;
+typedef void*                           EGLNativeDisplayType;
+
+#else
+#error "Platform not recognized"
+#endif
+
+/* EGL 1.2 types, renamed for consistency in EGL 1.3 */
+typedef EGLNativeDisplayType NativeDisplayType;
+typedef EGLNativePixmapType  NativePixmapType;
+typedef EGLNativeWindowType  NativeWindowType;
+
+
+/* Define EGLint. This must be a signed integral type large enough to contain
+ * all legal attribute names and values passed into and out of EGL, whether
+ * their type is boolean, bitmask, enumerant (symbolic constant), integer,
+ * handle, or other.  While in general a 32-bit integer will suffice, if
+ * handles are 64 bit types, then EGLint should be defined as a signed 64-bit
+ * integer type.
+ */
+typedef khronos_int32_t EGLint;
+
+#endif /* __eglplatform_h */
diff --git a/opengl/include/GLES/egl.h b/opengl/include/GLES/egl.h
new file mode 100644
index 0000000..5778e00
--- /dev/null
+++ b/opengl/include/GLES/egl.h
@@ -0,0 +1,15 @@
+/*
+ * Skeleton egl.h to provide compatibility for early GLES 1.0
+ * applications. Several early implementations included gl.h
+ * in egl.h leading applications to include only egl.h
+ *
+ * $Revision: 6252 $ on $Date:: 2008-08-06 16:35:08 -0700 #$
+ */
+
+#ifndef __legacy_egl_h_
+#define __legacy_egl_h_
+
+#include <EGL/egl.h>
+#include <GLES/gl.h>
+
+#endif /* __legacy_egl_h_ */
diff --git a/opengl/include/GLES/gl.h b/opengl/include/GLES/gl.h
new file mode 100644
index 0000000..2e8b971
--- /dev/null
+++ b/opengl/include/GLES/gl.h
@@ -0,0 +1,769 @@
+#ifndef __gl_h_
+#define __gl_h_
+
+/* $Revision: 7172 $ on $Date:: 2009-01-09 11:17:41 -0800 #$ */
+
+#include <GLES/glplatform.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * This document is licensed under the SGI Free Software B License Version
+ * 2.0. For details, see http://oss.sgi.com/projects/FreeB/ .
+ */
+
+typedef void             GLvoid;
+typedef unsigned int     GLenum;
+typedef unsigned char    GLboolean;
+typedef unsigned int     GLbitfield;
+typedef khronos_int8_t   GLbyte;
+typedef short            GLshort;
+typedef int              GLint;
+typedef int              GLsizei;
+typedef khronos_uint8_t  GLubyte;
+typedef unsigned short   GLushort;
+typedef unsigned int     GLuint;
+typedef khronos_float_t  GLfloat;
+typedef khronos_float_t  GLclampf;
+typedef khronos_int32_t  GLfixed;
+typedef khronos_int32_t  GLclampx;
+
+typedef khronos_intptr_t GLintptr;
+typedef khronos_ssize_t  GLsizeiptr;
+
+
+/*************************************************************/
+
+/* OpenGL ES core versions */
+#define GL_VERSION_ES_CM_1_0          1
+#define GL_VERSION_ES_CL_1_0          1
+#define GL_VERSION_ES_CM_1_1          1
+#define GL_VERSION_ES_CL_1_1          1
+
+/* ClearBufferMask */
+#define GL_DEPTH_BUFFER_BIT               0x00000100
+#define GL_STENCIL_BUFFER_BIT             0x00000400
+#define GL_COLOR_BUFFER_BIT               0x00004000
+
+/* Boolean */
+#define GL_FALSE                          0
+#define GL_TRUE                           1
+
+/* BeginMode */
+#define GL_POINTS                         0x0000
+#define GL_LINES                          0x0001
+#define GL_LINE_LOOP                      0x0002
+#define GL_LINE_STRIP                     0x0003
+#define GL_TRIANGLES                      0x0004
+#define GL_TRIANGLE_STRIP                 0x0005
+#define GL_TRIANGLE_FAN                   0x0006
+
+/* AlphaFunction */
+#define GL_NEVER                          0x0200
+#define GL_LESS                           0x0201
+#define GL_EQUAL                          0x0202
+#define GL_LEQUAL                         0x0203
+#define GL_GREATER                        0x0204
+#define GL_NOTEQUAL                       0x0205
+#define GL_GEQUAL                         0x0206
+#define GL_ALWAYS                         0x0207
+
+/* BlendingFactorDest */
+#define GL_ZERO                           0
+#define GL_ONE                            1
+#define GL_SRC_COLOR                      0x0300
+#define GL_ONE_MINUS_SRC_COLOR            0x0301
+#define GL_SRC_ALPHA                      0x0302
+#define GL_ONE_MINUS_SRC_ALPHA            0x0303
+#define GL_DST_ALPHA                      0x0304
+#define GL_ONE_MINUS_DST_ALPHA            0x0305
+
+/* BlendingFactorSrc */
+/*      GL_ZERO */
+/*      GL_ONE */
+#define GL_DST_COLOR                      0x0306
+#define GL_ONE_MINUS_DST_COLOR            0x0307
+#define GL_SRC_ALPHA_SATURATE             0x0308
+/*      GL_SRC_ALPHA */
+/*      GL_ONE_MINUS_SRC_ALPHA */
+/*      GL_DST_ALPHA */
+/*      GL_ONE_MINUS_DST_ALPHA */
+
+/* ClipPlaneName */
+#define GL_CLIP_PLANE0                    0x3000
+#define GL_CLIP_PLANE1                    0x3001
+#define GL_CLIP_PLANE2                    0x3002
+#define GL_CLIP_PLANE3                    0x3003
+#define GL_CLIP_PLANE4                    0x3004
+#define GL_CLIP_PLANE5                    0x3005
+
+/* ColorMaterialFace */
+/*      GL_FRONT_AND_BACK */
+
+/* ColorMaterialParameter */
+/*      GL_AMBIENT_AND_DIFFUSE */
+
+/* ColorPointerType */
+/*      GL_UNSIGNED_BYTE */
+/*      GL_FLOAT */
+/*      GL_FIXED */
+
+/* CullFaceMode */
+#define GL_FRONT                          0x0404
+#define GL_BACK                           0x0405
+#define GL_FRONT_AND_BACK                 0x0408
+
+/* DepthFunction */
+/*      GL_NEVER */
+/*      GL_LESS */
+/*      GL_EQUAL */
+/*      GL_LEQUAL */
+/*      GL_GREATER */
+/*      GL_NOTEQUAL */
+/*      GL_GEQUAL */
+/*      GL_ALWAYS */
+
+/* EnableCap */
+#define GL_FOG                            0x0B60
+#define GL_LIGHTING                       0x0B50
+#define GL_TEXTURE_2D                     0x0DE1
+#define GL_CULL_FACE                      0x0B44
+#define GL_ALPHA_TEST                     0x0BC0
+#define GL_BLEND                          0x0BE2
+#define GL_COLOR_LOGIC_OP                 0x0BF2
+#define GL_DITHER                         0x0BD0
+#define GL_STENCIL_TEST                   0x0B90
+#define GL_DEPTH_TEST                     0x0B71
+/*      GL_LIGHT0 */
+/*      GL_LIGHT1 */
+/*      GL_LIGHT2 */
+/*      GL_LIGHT3 */
+/*      GL_LIGHT4 */
+/*      GL_LIGHT5 */
+/*      GL_LIGHT6 */
+/*      GL_LIGHT7 */
+#define GL_POINT_SMOOTH                   0x0B10
+#define GL_LINE_SMOOTH                    0x0B20
+#define GL_SCISSOR_TEST                   0x0C11
+#define GL_COLOR_MATERIAL                 0x0B57
+#define GL_NORMALIZE                      0x0BA1
+#define GL_RESCALE_NORMAL                 0x803A
+#define GL_POLYGON_OFFSET_FILL            0x8037
+#define GL_VERTEX_ARRAY                   0x8074
+#define GL_NORMAL_ARRAY                   0x8075
+#define GL_COLOR_ARRAY                    0x8076
+#define GL_TEXTURE_COORD_ARRAY            0x8078
+#define GL_MULTISAMPLE                    0x809D
+#define GL_SAMPLE_ALPHA_TO_COVERAGE       0x809E
+#define GL_SAMPLE_ALPHA_TO_ONE            0x809F
+#define GL_SAMPLE_COVERAGE                0x80A0
+
+/* ErrorCode */
+#define GL_NO_ERROR                       0
+#define GL_INVALID_ENUM                   0x0500
+#define GL_INVALID_VALUE                  0x0501
+#define GL_INVALID_OPERATION              0x0502
+#define GL_STACK_OVERFLOW                 0x0503
+#define GL_STACK_UNDERFLOW                0x0504
+#define GL_OUT_OF_MEMORY                  0x0505
+
+/* FogMode */
+/*      GL_LINEAR */
+#define GL_EXP                            0x0800
+#define GL_EXP2                           0x0801
+
+/* FogParameter */
+#define GL_FOG_DENSITY                    0x0B62
+#define GL_FOG_START                      0x0B63
+#define GL_FOG_END                        0x0B64
+#define GL_FOG_MODE                       0x0B65
+#define GL_FOG_COLOR                      0x0B66
+
+/* FrontFaceDirection */
+#define GL_CW                             0x0900
+#define GL_CCW                            0x0901
+
+/* GetPName */
+#define GL_CURRENT_COLOR                  0x0B00
+#define GL_CURRENT_NORMAL                 0x0B02
+#define GL_CURRENT_TEXTURE_COORDS         0x0B03
+#define GL_POINT_SIZE                     0x0B11
+#define GL_POINT_SIZE_MIN                 0x8126
+#define GL_POINT_SIZE_MAX                 0x8127
+#define GL_POINT_FADE_THRESHOLD_SIZE      0x8128
+#define GL_POINT_DISTANCE_ATTENUATION     0x8129
+#define GL_SMOOTH_POINT_SIZE_RANGE        0x0B12
+#define GL_LINE_WIDTH                     0x0B21
+#define GL_SMOOTH_LINE_WIDTH_RANGE        0x0B22
+#define GL_ALIASED_POINT_SIZE_RANGE       0x846D
+#define GL_ALIASED_LINE_WIDTH_RANGE       0x846E
+#define GL_CULL_FACE_MODE                 0x0B45
+#define GL_FRONT_FACE                     0x0B46
+#define GL_SHADE_MODEL                    0x0B54
+#define GL_DEPTH_RANGE                    0x0B70
+#define GL_DEPTH_WRITEMASK                0x0B72
+#define GL_DEPTH_CLEAR_VALUE              0x0B73
+#define GL_DEPTH_FUNC                     0x0B74
+#define GL_STENCIL_CLEAR_VALUE            0x0B91
+#define GL_STENCIL_FUNC                   0x0B92
+#define GL_STENCIL_VALUE_MASK             0x0B93
+#define GL_STENCIL_FAIL                   0x0B94
+#define GL_STENCIL_PASS_DEPTH_FAIL        0x0B95
+#define GL_STENCIL_PASS_DEPTH_PASS        0x0B96
+#define GL_STENCIL_REF                    0x0B97
+#define GL_STENCIL_WRITEMASK              0x0B98
+#define GL_MATRIX_MODE                    0x0BA0
+#define GL_VIEWPORT                       0x0BA2
+#define GL_MODELVIEW_STACK_DEPTH          0x0BA3
+#define GL_PROJECTION_STACK_DEPTH         0x0BA4
+#define GL_TEXTURE_STACK_DEPTH            0x0BA5
+#define GL_MODELVIEW_MATRIX               0x0BA6
+#define GL_PROJECTION_MATRIX              0x0BA7
+#define GL_TEXTURE_MATRIX                 0x0BA8
+#define GL_ALPHA_TEST_FUNC                0x0BC1
+#define GL_ALPHA_TEST_REF                 0x0BC2
+#define GL_BLEND_DST                      0x0BE0
+#define GL_BLEND_SRC                      0x0BE1
+#define GL_LOGIC_OP_MODE                  0x0BF0
+#define GL_SCISSOR_BOX                    0x0C10
+#define GL_SCISSOR_TEST                   0x0C11
+#define GL_COLOR_CLEAR_VALUE              0x0C22
+#define GL_COLOR_WRITEMASK                0x0C23
+#define GL_UNPACK_ALIGNMENT               0x0CF5
+#define GL_PACK_ALIGNMENT                 0x0D05
+#define GL_MAX_LIGHTS                     0x0D31
+#define GL_MAX_CLIP_PLANES                0x0D32
+#define GL_MAX_TEXTURE_SIZE               0x0D33
+#define GL_MAX_MODELVIEW_STACK_DEPTH      0x0D36
+#define GL_MAX_PROJECTION_STACK_DEPTH     0x0D38
+#define GL_MAX_TEXTURE_STACK_DEPTH        0x0D39
+#define GL_MAX_VIEWPORT_DIMS              0x0D3A
+#define GL_MAX_TEXTURE_UNITS              0x84E2
+#define GL_SUBPIXEL_BITS                  0x0D50
+#define GL_RED_BITS                       0x0D52
+#define GL_GREEN_BITS                     0x0D53
+#define GL_BLUE_BITS                      0x0D54
+#define GL_ALPHA_BITS                     0x0D55
+#define GL_DEPTH_BITS                     0x0D56
+#define GL_STENCIL_BITS                   0x0D57
+#define GL_POLYGON_OFFSET_UNITS           0x2A00
+#define GL_POLYGON_OFFSET_FILL            0x8037
+#define GL_POLYGON_OFFSET_FACTOR          0x8038
+#define GL_TEXTURE_BINDING_2D             0x8069
+#define GL_VERTEX_ARRAY_SIZE              0x807A
+#define GL_VERTEX_ARRAY_TYPE              0x807B
+#define GL_VERTEX_ARRAY_STRIDE            0x807C
+#define GL_NORMAL_ARRAY_TYPE              0x807E
+#define GL_NORMAL_ARRAY_STRIDE            0x807F
+#define GL_COLOR_ARRAY_SIZE               0x8081
+#define GL_COLOR_ARRAY_TYPE               0x8082
+#define GL_COLOR_ARRAY_STRIDE             0x8083
+#define GL_TEXTURE_COORD_ARRAY_SIZE       0x8088
+#define GL_TEXTURE_COORD_ARRAY_TYPE       0x8089
+#define GL_TEXTURE_COORD_ARRAY_STRIDE     0x808A
+#define GL_VERTEX_ARRAY_POINTER           0x808E
+#define GL_NORMAL_ARRAY_POINTER           0x808F
+#define GL_COLOR_ARRAY_POINTER            0x8090
+#define GL_TEXTURE_COORD_ARRAY_POINTER    0x8092
+#define GL_SAMPLE_BUFFERS                 0x80A8
+#define GL_SAMPLES                        0x80A9
+#define GL_SAMPLE_COVERAGE_VALUE          0x80AA
+#define GL_SAMPLE_COVERAGE_INVERT         0x80AB
+
+/* GetTextureParameter */
+/*      GL_TEXTURE_MAG_FILTER */
+/*      GL_TEXTURE_MIN_FILTER */
+/*      GL_TEXTURE_WRAP_S */
+/*      GL_TEXTURE_WRAP_T */
+
+#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2
+#define GL_COMPRESSED_TEXTURE_FORMATS     0x86A3
+
+/* HintMode */
+#define GL_DONT_CARE                      0x1100
+#define GL_FASTEST                        0x1101
+#define GL_NICEST                         0x1102
+
+/* HintTarget */
+#define GL_PERSPECTIVE_CORRECTION_HINT    0x0C50
+#define GL_POINT_SMOOTH_HINT              0x0C51
+#define GL_LINE_SMOOTH_HINT               0x0C52
+#define GL_FOG_HINT                       0x0C54
+#define GL_GENERATE_MIPMAP_HINT           0x8192
+
+/* LightModelParameter */
+#define GL_LIGHT_MODEL_AMBIENT            0x0B53
+#define GL_LIGHT_MODEL_TWO_SIDE           0x0B52
+
+/* LightParameter */
+#define GL_AMBIENT                        0x1200
+#define GL_DIFFUSE                        0x1201
+#define GL_SPECULAR                       0x1202
+#define GL_POSITION                       0x1203
+#define GL_SPOT_DIRECTION                 0x1204
+#define GL_SPOT_EXPONENT                  0x1205
+#define GL_SPOT_CUTOFF                    0x1206
+#define GL_CONSTANT_ATTENUATION           0x1207
+#define GL_LINEAR_ATTENUATION             0x1208
+#define GL_QUADRATIC_ATTENUATION          0x1209
+
+/* DataType */
+#define GL_BYTE                           0x1400
+#define GL_UNSIGNED_BYTE                  0x1401
+#define GL_SHORT                          0x1402
+#define GL_UNSIGNED_SHORT                 0x1403
+#define GL_FLOAT                          0x1406
+#define GL_FIXED                          0x140C
+
+/* LogicOp */
+#define GL_CLEAR                          0x1500
+#define GL_AND                            0x1501
+#define GL_AND_REVERSE                    0x1502
+#define GL_COPY                           0x1503
+#define GL_AND_INVERTED                   0x1504
+#define GL_NOOP                           0x1505
+#define GL_XOR                            0x1506
+#define GL_OR                             0x1507
+#define GL_NOR                            0x1508
+#define GL_EQUIV                          0x1509
+#define GL_INVERT                         0x150A
+#define GL_OR_REVERSE                     0x150B
+#define GL_COPY_INVERTED                  0x150C
+#define GL_OR_INVERTED                    0x150D
+#define GL_NAND                           0x150E
+#define GL_SET                            0x150F
+
+/* MaterialFace */
+/*      GL_FRONT_AND_BACK */
+
+/* MaterialParameter */
+#define GL_EMISSION                       0x1600
+#define GL_SHININESS                      0x1601
+#define GL_AMBIENT_AND_DIFFUSE            0x1602
+/*      GL_AMBIENT */
+/*      GL_DIFFUSE */
+/*      GL_SPECULAR */
+
+/* MatrixMode */
+#define GL_MODELVIEW                      0x1700
+#define GL_PROJECTION                     0x1701
+#define GL_TEXTURE                        0x1702
+
+/* NormalPointerType */
+/*      GL_BYTE */
+/*      GL_SHORT */
+/*      GL_FLOAT */
+/*      GL_FIXED */
+
+/* PixelFormat */
+#define GL_ALPHA                          0x1906
+#define GL_RGB                            0x1907
+#define GL_RGBA                           0x1908
+#define GL_LUMINANCE                      0x1909
+#define GL_LUMINANCE_ALPHA                0x190A
+
+/* PixelStoreParameter */
+#define GL_UNPACK_ALIGNMENT               0x0CF5
+#define GL_PACK_ALIGNMENT                 0x0D05
+
+/* PixelType */
+/*      GL_UNSIGNED_BYTE */
+#define GL_UNSIGNED_SHORT_4_4_4_4         0x8033
+#define GL_UNSIGNED_SHORT_5_5_5_1         0x8034
+#define GL_UNSIGNED_SHORT_5_6_5           0x8363
+
+/* ShadingModel */
+#define GL_FLAT                           0x1D00
+#define GL_SMOOTH                         0x1D01
+
+/* StencilFunction */
+/*      GL_NEVER */
+/*      GL_LESS */
+/*      GL_EQUAL */
+/*      GL_LEQUAL */
+/*      GL_GREATER */
+/*      GL_NOTEQUAL */
+/*      GL_GEQUAL */
+/*      GL_ALWAYS */
+
+/* StencilOp */
+/*      GL_ZERO */
+#define GL_KEEP                           0x1E00
+#define GL_REPLACE                        0x1E01
+#define GL_INCR                           0x1E02
+#define GL_DECR                           0x1E03
+/*      GL_INVERT */
+
+/* StringName */
+#define GL_VENDOR                         0x1F00
+#define GL_RENDERER                       0x1F01
+#define GL_VERSION                        0x1F02
+#define GL_EXTENSIONS                     0x1F03
+
+/* TexCoordPointerType */
+/*      GL_SHORT */
+/*      GL_FLOAT */
+/*      GL_FIXED */
+/*      GL_BYTE */
+
+/* TextureEnvMode */
+#define GL_MODULATE                       0x2100
+#define GL_DECAL                          0x2101
+/*      GL_BLEND */
+#define GL_ADD                            0x0104
+/*      GL_REPLACE */
+
+/* TextureEnvParameter */
+#define GL_TEXTURE_ENV_MODE               0x2200
+#define GL_TEXTURE_ENV_COLOR              0x2201
+
+/* TextureEnvTarget */
+#define GL_TEXTURE_ENV                    0x2300
+
+/* TextureMagFilter */
+#define GL_NEAREST                        0x2600
+#define GL_LINEAR                         0x2601
+
+/* TextureMinFilter */
+/*      GL_NEAREST */
+/*      GL_LINEAR */
+#define GL_NEAREST_MIPMAP_NEAREST         0x2700
+#define GL_LINEAR_MIPMAP_NEAREST          0x2701
+#define GL_NEAREST_MIPMAP_LINEAR          0x2702
+#define GL_LINEAR_MIPMAP_LINEAR           0x2703
+
+/* TextureParameterName */
+#define GL_TEXTURE_MAG_FILTER             0x2800
+#define GL_TEXTURE_MIN_FILTER             0x2801
+#define GL_TEXTURE_WRAP_S                 0x2802
+#define GL_TEXTURE_WRAP_T                 0x2803
+#define GL_GENERATE_MIPMAP                0x8191
+
+/* TextureTarget */
+/*      GL_TEXTURE_2D */
+
+/* TextureUnit */
+#define GL_TEXTURE0                       0x84C0
+#define GL_TEXTURE1                       0x84C1
+#define GL_TEXTURE2                       0x84C2
+#define GL_TEXTURE3                       0x84C3
+#define GL_TEXTURE4                       0x84C4
+#define GL_TEXTURE5                       0x84C5
+#define GL_TEXTURE6                       0x84C6
+#define GL_TEXTURE7                       0x84C7
+#define GL_TEXTURE8                       0x84C8
+#define GL_TEXTURE9                       0x84C9
+#define GL_TEXTURE10                      0x84CA
+#define GL_TEXTURE11                      0x84CB
+#define GL_TEXTURE12                      0x84CC
+#define GL_TEXTURE13                      0x84CD
+#define GL_TEXTURE14                      0x84CE
+#define GL_TEXTURE15                      0x84CF
+#define GL_TEXTURE16                      0x84D0
+#define GL_TEXTURE17                      0x84D1
+#define GL_TEXTURE18                      0x84D2
+#define GL_TEXTURE19                      0x84D3
+#define GL_TEXTURE20                      0x84D4
+#define GL_TEXTURE21                      0x84D5
+#define GL_TEXTURE22                      0x84D6
+#define GL_TEXTURE23                      0x84D7
+#define GL_TEXTURE24                      0x84D8
+#define GL_TEXTURE25                      0x84D9
+#define GL_TEXTURE26                      0x84DA
+#define GL_TEXTURE27                      0x84DB
+#define GL_TEXTURE28                      0x84DC
+#define GL_TEXTURE29                      0x84DD
+#define GL_TEXTURE30                      0x84DE
+#define GL_TEXTURE31                      0x84DF
+#define GL_ACTIVE_TEXTURE                 0x84E0
+#define GL_CLIENT_ACTIVE_TEXTURE          0x84E1
+
+/* TextureWrapMode */
+#define GL_REPEAT                         0x2901
+#define GL_CLAMP_TO_EDGE                  0x812F
+
+/* VertexPointerType */
+/*      GL_SHORT */
+/*      GL_FLOAT */
+/*      GL_FIXED */
+/*      GL_BYTE */
+
+/* LightName */
+#define GL_LIGHT0                         0x4000
+#define GL_LIGHT1                         0x4001
+#define GL_LIGHT2                         0x4002
+#define GL_LIGHT3                         0x4003
+#define GL_LIGHT4                         0x4004
+#define GL_LIGHT5                         0x4005
+#define GL_LIGHT6                         0x4006
+#define GL_LIGHT7                         0x4007
+
+/* Buffer Objects */
+#define GL_ARRAY_BUFFER                   0x8892
+#define GL_ELEMENT_ARRAY_BUFFER           0x8893
+
+#define GL_ARRAY_BUFFER_BINDING               0x8894
+#define GL_ELEMENT_ARRAY_BUFFER_BINDING       0x8895
+#define GL_VERTEX_ARRAY_BUFFER_BINDING        0x8896
+#define GL_NORMAL_ARRAY_BUFFER_BINDING        0x8897
+#define GL_COLOR_ARRAY_BUFFER_BINDING         0x8898
+#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING 0x889A
+
+#define GL_STATIC_DRAW                    0x88E4
+#define GL_DYNAMIC_DRAW                   0x88E8
+
+#define GL_BUFFER_SIZE                    0x8764
+#define GL_BUFFER_USAGE                   0x8765
+
+/* Texture combine + dot3 */
+#define GL_SUBTRACT                       0x84E7
+#define GL_COMBINE                        0x8570
+#define GL_COMBINE_RGB                    0x8571
+#define GL_COMBINE_ALPHA                  0x8572
+#define GL_RGB_SCALE                      0x8573
+#define GL_ADD_SIGNED                     0x8574
+#define GL_INTERPOLATE                    0x8575
+#define GL_CONSTANT                       0x8576
+#define GL_PRIMARY_COLOR                  0x8577
+#define GL_PREVIOUS                       0x8578
+#define GL_OPERAND0_RGB                   0x8590
+#define GL_OPERAND1_RGB                   0x8591
+#define GL_OPERAND2_RGB                   0x8592
+#define GL_OPERAND0_ALPHA                 0x8598
+#define GL_OPERAND1_ALPHA                 0x8599
+#define GL_OPERAND2_ALPHA                 0x859A
+
+#define GL_ALPHA_SCALE                    0x0D1C
+
+#define GL_SRC0_RGB                       0x8580
+#define GL_SRC1_RGB                       0x8581
+#define GL_SRC2_RGB                       0x8582
+#define GL_SRC0_ALPHA                     0x8588
+#define GL_SRC1_ALPHA                     0x8589
+#define GL_SRC2_ALPHA                     0x858A
+
+#define GL_DOT3_RGB                       0x86AE
+#define GL_DOT3_RGBA                      0x86AF
+
+/*------------------------------------------------------------------------*
+ * required OES extension tokens
+ *------------------------------------------------------------------------*/
+
+/* OES_read_format */
+#ifndef GL_OES_read_format
+#define GL_IMPLEMENTATION_COLOR_READ_TYPE_OES                   0x8B9A
+#define GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES                 0x8B9B
+#endif
+
+/* GL_OES_compressed_paletted_texture */
+#ifndef GL_OES_compressed_paletted_texture
+#define GL_PALETTE4_RGB8_OES                                    0x8B90
+#define GL_PALETTE4_RGBA8_OES                                   0x8B91
+#define GL_PALETTE4_R5_G6_B5_OES                                0x8B92
+#define GL_PALETTE4_RGBA4_OES                                   0x8B93
+#define GL_PALETTE4_RGB5_A1_OES                                 0x8B94
+#define GL_PALETTE8_RGB8_OES                                    0x8B95
+#define GL_PALETTE8_RGBA8_OES                                   0x8B96
+#define GL_PALETTE8_R5_G6_B5_OES                                0x8B97
+#define GL_PALETTE8_RGBA4_OES                                   0x8B98
+#define GL_PALETTE8_RGB5_A1_OES                                 0x8B99
+#endif
+
+/* OES_point_size_array */
+#ifndef GL_OES_point_size_array
+#define GL_POINT_SIZE_ARRAY_OES                                 0x8B9C
+#define GL_POINT_SIZE_ARRAY_TYPE_OES                            0x898A
+#define GL_POINT_SIZE_ARRAY_STRIDE_OES                          0x898B
+#define GL_POINT_SIZE_ARRAY_POINTER_OES                         0x898C
+#define GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES                  0x8B9F
+#endif
+
+/* GL_OES_point_sprite */
+#ifndef GL_OES_point_sprite
+#define GL_POINT_SPRITE_OES                                     0x8861
+#define GL_COORD_REPLACE_OES                                    0x8862
+#endif
+
+/*************************************************************/
+
+/* Available only in Common profile */
+GL_API void GL_APIENTRY glAlphaFunc (GLenum func, GLclampf ref);
+GL_API void GL_APIENTRY glClearColor (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+GL_API void GL_APIENTRY glClearDepthf (GLclampf depth);
+GL_API void GL_APIENTRY glClipPlanef (GLenum plane, const GLfloat *equation);
+GL_API void GL_APIENTRY glColor4f (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
+GL_API void GL_APIENTRY glDepthRangef (GLclampf zNear, GLclampf zFar);
+GL_API void GL_APIENTRY glFogf (GLenum pname, GLfloat param);
+GL_API void GL_APIENTRY glFogfv (GLenum pname, const GLfloat *params);
+GL_API void GL_APIENTRY glFrustumf (GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar);
+GL_API void GL_APIENTRY glGetClipPlanef (GLenum pname, GLfloat eqn[4]);
+GL_API void GL_APIENTRY glGetFloatv (GLenum pname, GLfloat *params);
+GL_API void GL_APIENTRY glGetLightfv (GLenum light, GLenum pname, GLfloat *params);
+GL_API void GL_APIENTRY glGetMaterialfv (GLenum face, GLenum pname, GLfloat *params);
+GL_API void GL_APIENTRY glGetTexEnvfv (GLenum env, GLenum pname, GLfloat *params);
+GL_API void GL_APIENTRY glGetTexParameterfv (GLenum target, GLenum pname, GLfloat *params);
+GL_API void GL_APIENTRY glLightModelf (GLenum pname, GLfloat param);
+GL_API void GL_APIENTRY glLightModelfv (GLenum pname, const GLfloat *params);
+GL_API void GL_APIENTRY glLightf (GLenum light, GLenum pname, GLfloat param);
+GL_API void GL_APIENTRY glLightfv (GLenum light, GLenum pname, const GLfloat *params);
+GL_API void GL_APIENTRY glLineWidth (GLfloat width);
+GL_API void GL_APIENTRY glLoadMatrixf (const GLfloat *m);
+GL_API void GL_APIENTRY glMaterialf (GLenum face, GLenum pname, GLfloat param);
+GL_API void GL_APIENTRY glMaterialfv (GLenum face, GLenum pname, const GLfloat *params);
+GL_API void GL_APIENTRY glMultMatrixf (const GLfloat *m);
+GL_API void GL_APIENTRY glMultiTexCoord4f (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q);
+GL_API void GL_APIENTRY glNormal3f (GLfloat nx, GLfloat ny, GLfloat nz);
+GL_API void GL_APIENTRY glOrthof (GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar);
+GL_API void GL_APIENTRY glPointParameterf (GLenum pname, GLfloat param);
+GL_API void GL_APIENTRY glPointParameterfv (GLenum pname, const GLfloat *params);
+GL_API void GL_APIENTRY glPointSize (GLfloat size);
+GL_API void GL_APIENTRY glPolygonOffset (GLfloat factor, GLfloat units);
+GL_API void GL_APIENTRY glRotatef (GLfloat angle, GLfloat x, GLfloat y, GLfloat z);
+GL_API void GL_APIENTRY glScalef (GLfloat x, GLfloat y, GLfloat z);
+GL_API void GL_APIENTRY glTexEnvf (GLenum target, GLenum pname, GLfloat param);
+GL_API void GL_APIENTRY glTexEnvfv (GLenum target, GLenum pname, const GLfloat *params);
+GL_API void GL_APIENTRY glTexParameterf (GLenum target, GLenum pname, GLfloat param);
+GL_API void GL_APIENTRY glTexParameterfv (GLenum target, GLenum pname, const GLfloat *params);
+GL_API void GL_APIENTRY glTranslatef (GLfloat x, GLfloat y, GLfloat z);
+
+/* Available in both Common and Common-Lite profiles */
+GL_API void GL_APIENTRY glActiveTexture (GLenum texture);
+GL_API void GL_APIENTRY glAlphaFuncx (GLenum func, GLclampx ref);
+GL_API void GL_APIENTRY glBindBuffer (GLenum target, GLuint buffer);
+GL_API void GL_APIENTRY glBindTexture (GLenum target, GLuint texture);
+GL_API void GL_APIENTRY glBlendFunc (GLenum sfactor, GLenum dfactor);
+GL_API void GL_APIENTRY glBufferData (GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage);
+GL_API void GL_APIENTRY glBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data);
+GL_API void GL_APIENTRY glClear (GLbitfield mask);
+GL_API void GL_APIENTRY glClearColorx (GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha);
+GL_API void GL_APIENTRY glClearDepthx (GLclampx depth);
+GL_API void GL_APIENTRY glClearStencil (GLint s);
+GL_API void GL_APIENTRY glClientActiveTexture (GLenum texture);
+GL_API void GL_APIENTRY glClipPlanex (GLenum plane, const GLfixed *equation);
+GL_API void GL_APIENTRY glColor4ub (GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha);
+GL_API void GL_APIENTRY glColor4x (GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha);
+GL_API void GL_APIENTRY glColorMask (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
+GL_API void GL_APIENTRY glColorPointer (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+GL_API void GL_APIENTRY glCompressedTexImage2D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data);
+GL_API void GL_APIENTRY glCompressedTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data);
+GL_API void GL_APIENTRY glCopyTexImage2D (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
+GL_API void GL_APIENTRY glCopyTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+GL_API void GL_APIENTRY glCullFace (GLenum mode);
+GL_API void GL_APIENTRY glDeleteBuffers (GLsizei n, const GLuint *buffers);
+GL_API void GL_APIENTRY glDeleteTextures (GLsizei n, const GLuint *textures);
+GL_API void GL_APIENTRY glDepthFunc (GLenum func);
+GL_API void GL_APIENTRY glDepthMask (GLboolean flag);
+GL_API void GL_APIENTRY glDepthRangex (GLclampx zNear, GLclampx zFar);
+GL_API void GL_APIENTRY glDisable (GLenum cap);
+GL_API void GL_APIENTRY glDisableClientState (GLenum array);
+GL_API void GL_APIENTRY glDrawArrays (GLenum mode, GLint first, GLsizei count);
+GL_API void GL_APIENTRY glDrawElements (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices);
+GL_API void GL_APIENTRY glEnable (GLenum cap);
+GL_API void GL_APIENTRY glEnableClientState (GLenum array);
+GL_API void GL_APIENTRY glFinish (void);
+GL_API void GL_APIENTRY glFlush (void);
+GL_API void GL_APIENTRY glFogx (GLenum pname, GLfixed param);
+GL_API void GL_APIENTRY glFogxv (GLenum pname, const GLfixed *params);
+GL_API void GL_APIENTRY glFrontFace (GLenum mode);
+GL_API void GL_APIENTRY glFrustumx (GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar);
+GL_API void GL_APIENTRY glGetBooleanv (GLenum pname, GLboolean *params);
+GL_API void GL_APIENTRY glGetBufferParameteriv (GLenum target, GLenum pname, GLint *params);
+GL_API void GL_APIENTRY glGetClipPlanex (GLenum pname, GLfixed eqn[4]);
+GL_API void GL_APIENTRY glGenBuffers (GLsizei n, GLuint *buffers);
+GL_API void GL_APIENTRY glGenTextures (GLsizei n, GLuint *textures);
+GL_API GLenum GL_APIENTRY glGetError (void);
+GL_API void GL_APIENTRY glGetFixedv (GLenum pname, GLfixed *params);
+GL_API void GL_APIENTRY glGetIntegerv (GLenum pname, GLint *params);
+GL_API void GL_APIENTRY glGetLightxv (GLenum light, GLenum pname, GLfixed *params);
+GL_API void GL_APIENTRY glGetMaterialxv (GLenum face, GLenum pname, GLfixed *params);
+GL_API void GL_APIENTRY glGetPointerv (GLenum pname, void **params);
+GL_API const GLubyte * GL_APIENTRY glGetString (GLenum name);
+GL_API void GL_APIENTRY glGetTexEnviv (GLenum env, GLenum pname, GLint *params);
+GL_API void GL_APIENTRY glGetTexEnvxv (GLenum env, GLenum pname, GLfixed *params);
+GL_API void GL_APIENTRY glGetTexParameteriv (GLenum target, GLenum pname, GLint *params);
+GL_API void GL_APIENTRY glGetTexParameterxv (GLenum target, GLenum pname, GLfixed *params);
+GL_API void GL_APIENTRY glHint (GLenum target, GLenum mode);
+GL_API GLboolean GL_APIENTRY glIsBuffer (GLuint buffer);
+GL_API GLboolean GL_APIENTRY glIsEnabled (GLenum cap);
+GL_API GLboolean GL_APIENTRY glIsTexture (GLuint texture);
+GL_API void GL_APIENTRY glLightModelx (GLenum pname, GLfixed param);
+GL_API void GL_APIENTRY glLightModelxv (GLenum pname, const GLfixed *params);
+GL_API void GL_APIENTRY glLightx (GLenum light, GLenum pname, GLfixed param);
+GL_API void GL_APIENTRY glLightxv (GLenum light, GLenum pname, const GLfixed *params);
+GL_API void GL_APIENTRY glLineWidthx (GLfixed width);
+GL_API void GL_APIENTRY glLoadIdentity (void);
+GL_API void GL_APIENTRY glLoadMatrixx (const GLfixed *m);
+GL_API void GL_APIENTRY glLogicOp (GLenum opcode);
+GL_API void GL_APIENTRY glMaterialx (GLenum face, GLenum pname, GLfixed param);
+GL_API void GL_APIENTRY glMaterialxv (GLenum face, GLenum pname, const GLfixed *params);
+GL_API void GL_APIENTRY glMatrixMode (GLenum mode);
+GL_API void GL_APIENTRY glMultMatrixx (const GLfixed *m);
+GL_API void GL_APIENTRY glMultiTexCoord4x (GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q);
+GL_API void GL_APIENTRY glNormal3x (GLfixed nx, GLfixed ny, GLfixed nz);
+GL_API void GL_APIENTRY glNormalPointer (GLenum type, GLsizei stride, const GLvoid *pointer);
+GL_API void GL_APIENTRY glOrthox (GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar);
+GL_API void GL_APIENTRY glPixelStorei (GLenum pname, GLint param);
+GL_API void GL_APIENTRY glPointParameterx (GLenum pname, GLfixed param);
+GL_API void GL_APIENTRY glPointParameterxv (GLenum pname, const GLfixed *params);
+GL_API void GL_APIENTRY glPointSizex (GLfixed size);
+GL_API void GL_APIENTRY glPolygonOffsetx (GLfixed factor, GLfixed units);
+GL_API void GL_APIENTRY glPopMatrix (void);
+GL_API void GL_APIENTRY glPushMatrix (void);
+GL_API void GL_APIENTRY glReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels);
+GL_API void GL_APIENTRY glRotatex (GLfixed angle, GLfixed x, GLfixed y, GLfixed z);
+GL_API void GL_APIENTRY glSampleCoverage (GLclampf value, GLboolean invert);
+GL_API void GL_APIENTRY glSampleCoveragex (GLclampx value, GLboolean invert);
+GL_API void GL_APIENTRY glScalex (GLfixed x, GLfixed y, GLfixed z);
+GL_API void GL_APIENTRY glScissor (GLint x, GLint y, GLsizei width, GLsizei height);
+GL_API void GL_APIENTRY glShadeModel (GLenum mode);
+GL_API void GL_APIENTRY glStencilFunc (GLenum func, GLint ref, GLuint mask);
+GL_API void GL_APIENTRY glStencilMask (GLuint mask);
+GL_API void GL_APIENTRY glStencilOp (GLenum fail, GLenum zfail, GLenum zpass);
+GL_API void GL_APIENTRY glTexCoordPointer (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+GL_API void GL_APIENTRY glTexEnvi (GLenum target, GLenum pname, GLint param);
+GL_API void GL_APIENTRY glTexEnvx (GLenum target, GLenum pname, GLfixed param);
+GL_API void GL_APIENTRY glTexEnviv (GLenum target, GLenum pname, const GLint *params);
+GL_API void GL_APIENTRY glTexEnvxv (GLenum target, GLenum pname, const GLfixed *params);
+GL_API void GL_APIENTRY glTexImage2D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+GL_API void GL_APIENTRY glTexParameteri (GLenum target, GLenum pname, GLint param);
+GL_API void GL_APIENTRY glTexParameterx (GLenum target, GLenum pname, GLfixed param);
+GL_API void GL_APIENTRY glTexParameteriv (GLenum target, GLenum pname, const GLint *params);
+GL_API void GL_APIENTRY glTexParameterxv (GLenum target, GLenum pname, const GLfixed *params);
+GL_API void GL_APIENTRY glTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
+GL_API void GL_APIENTRY glTranslatex (GLfixed x, GLfixed y, GLfixed z);
+GL_API void GL_APIENTRY glVertexPointer (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+GL_API void GL_APIENTRY glViewport (GLint x, GLint y, GLsizei width, GLsizei height);
+
+/*------------------------------------------------------------------------*
+ * Required OES extension functions
+ *------------------------------------------------------------------------*/
+
+/* GL_OES_read_format */
+#ifndef GL_OES_read_format
+#define GL_OES_read_format 1
+#endif
+
+/* GL_OES_compressed_paletted_texture */
+#ifndef GL_OES_compressed_paletted_texture
+#define GL_OES_compressed_paletted_texture 1
+#endif
+
+/* GL_OES_point_size_array */
+#ifndef GL_OES_point_size_array
+#define GL_OES_point_size_array 1
+GL_API void GL_APIENTRY glPointSizePointerOES (GLenum type, GLsizei stride, const GLvoid *pointer);
+#endif
+
+/* GL_OES_point_sprite */
+#ifndef GL_OES_point_sprite
+#define GL_OES_point_sprite 1
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __gl_h_ */
+
diff --git a/opengl/include/GLES/glext.h b/opengl/include/GLES/glext.h
new file mode 100644
index 0000000..4c01871
--- /dev/null
+++ b/opengl/include/GLES/glext.h
@@ -0,0 +1,622 @@
+#ifndef __glext_h_
+#define __glext_h_
+
+/* $Revision: 7172 $ on $Date:: 2009-01-09 11:17:41 -0800 #$ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * This document is licensed under the SGI Free Software B License Version
+ * 2.0. For details, see http://oss.sgi.com/projects/FreeB/ .
+ */
+
+#ifndef GL_APIENTRYP
+#   define GL_APIENTRYP GL_APIENTRY*
+#endif
+
+/*------------------------------------------------------------------------*
+ * OES extension tokens
+ *------------------------------------------------------------------------*/
+
+/* GL_OES_blend_equation_separate */
+#ifndef GL_OES_blend_equation_separate
+/* BLEND_EQUATION_RGB_OES same as BLEND_EQUATION_OES */
+#define GL_BLEND_EQUATION_RGB_OES                               0x8009
+#define GL_BLEND_EQUATION_ALPHA_OES                             0x883D
+#endif
+
+/* GL_OES_blend_func_separate */
+#ifndef GL_OES_blend_func_separate
+#define GL_BLEND_DST_RGB_OES                                    0x80C8
+#define GL_BLEND_SRC_RGB_OES                                    0x80C9
+#define GL_BLEND_DST_ALPHA_OES                                  0x80CA
+#define GL_BLEND_SRC_ALPHA_OES                                  0x80CB
+#endif
+
+/* GL_OES_blend_subtract */
+#ifndef GL_OES_blend_subtract
+#define GL_BLEND_EQUATION_OES                                   0x8009
+#define GL_FUNC_ADD_OES                                         0x8006
+#define GL_FUNC_SUBTRACT_OES                                    0x800A
+#define GL_FUNC_REVERSE_SUBTRACT_OES                            0x800B
+#endif
+
+/* GL_OES_compressed_ETC1_RGB8_texture */
+#ifndef GL_OES_compressed_ETC1_RGB8_texture
+#define GL_ETC1_RGB8_OES                                        0x8D64
+#endif
+
+/* GL_OES_depth24 */
+#ifndef GL_OES_depth24
+#define GL_DEPTH_COMPONENT24_OES                                0x81A6
+#endif
+
+/* GL_OES_depth32 */
+#ifndef GL_OES_depth32
+#define GL_DEPTH_COMPONENT32_OES                                0x81A7
+#endif
+
+/* GL_OES_draw_texture */
+#ifndef GL_OES_draw_texture
+#define GL_TEXTURE_CROP_RECT_OES                                0x8B9D
+#endif
+
+/* GL_OES_EGL_image */
+#ifndef GL_OES_EGL_image
+typedef void* GLeglImageOES;
+#endif
+
+/* GL_OES_fixed_point */
+#ifndef GL_OES_fixed_point
+#define GL_FIXED_OES                                            0x140C
+#endif
+
+/* GL_OES_framebuffer_object */
+#ifndef GL_OES_framebuffer_object
+#define GL_NONE_OES                                             0
+#define GL_FRAMEBUFFER_OES                                      0x8D40
+#define GL_RENDERBUFFER_OES                                     0x8D41
+#define GL_RGBA4_OES                                            0x8056
+#define GL_RGB5_A1_OES                                          0x8057
+#define GL_RGB565_OES                                           0x8D62
+#define GL_DEPTH_COMPONENT16_OES                                0x81A5
+#define GL_RENDERBUFFER_WIDTH_OES                               0x8D42
+#define GL_RENDERBUFFER_HEIGHT_OES                              0x8D43
+#define GL_RENDERBUFFER_INTERNAL_FORMAT_OES                     0x8D44
+#define GL_RENDERBUFFER_RED_SIZE_OES                            0x8D50
+#define GL_RENDERBUFFER_GREEN_SIZE_OES                          0x8D51
+#define GL_RENDERBUFFER_BLUE_SIZE_OES                           0x8D52
+#define GL_RENDERBUFFER_ALPHA_SIZE_OES                          0x8D53
+#define GL_RENDERBUFFER_DEPTH_SIZE_OES                          0x8D54
+#define GL_RENDERBUFFER_STENCIL_SIZE_OES                        0x8D55
+#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_OES               0x8CD0
+#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_OES               0x8CD1
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_OES             0x8CD2
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_OES     0x8CD3
+#define GL_COLOR_ATTACHMENT0_OES                                0x8CE0
+#define GL_DEPTH_ATTACHMENT_OES                                 0x8D00
+#define GL_STENCIL_ATTACHMENT_OES                               0x8D20
+#define GL_FRAMEBUFFER_COMPLETE_OES                             0x8CD5
+#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_OES                0x8CD6
+#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_OES        0x8CD7
+#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_OES                0x8CD9
+#define GL_FRAMEBUFFER_INCOMPLETE_FORMATS_OES                   0x8CDA
+#define GL_FRAMEBUFFER_UNSUPPORTED_OES                          0x8CDD
+#define GL_FRAMEBUFFER_BINDING_OES                              0x8CA6
+#define GL_RENDERBUFFER_BINDING_OES                             0x8CA7
+#define GL_MAX_RENDERBUFFER_SIZE_OES                            0x84E8
+#define GL_INVALID_FRAMEBUFFER_OPERATION_OES                    0x0506
+#endif
+
+/* GL_OES_mapbuffer */
+#ifndef GL_OES_mapbuffer
+#define GL_WRITE_ONLY_OES                                       0x88B9
+#define GL_BUFFER_ACCESS_OES                                    0x88BB
+#define GL_BUFFER_MAPPED_OES                                    0x88BC
+#define GL_BUFFER_MAP_POINTER_OES                               0x88BD
+#endif
+
+/* GL_OES_matrix_get */
+#ifndef GL_OES_matrix_get
+#define GL_MODELVIEW_MATRIX_FLOAT_AS_INT_BITS_OES               0x898D
+#define GL_PROJECTION_MATRIX_FLOAT_AS_INT_BITS_OES              0x898E
+#define GL_TEXTURE_MATRIX_FLOAT_AS_INT_BITS_OES                 0x898F
+#endif
+
+/* GL_OES_matrix_palette */
+#ifndef GL_OES_matrix_palette
+#define GL_MAX_VERTEX_UNITS_OES                                 0x86A4
+#define GL_MAX_PALETTE_MATRICES_OES                             0x8842
+#define GL_MATRIX_PALETTE_OES                                   0x8840
+#define GL_MATRIX_INDEX_ARRAY_OES                               0x8844
+#define GL_WEIGHT_ARRAY_OES                                     0x86AD
+#define GL_CURRENT_PALETTE_MATRIX_OES                           0x8843
+#define GL_MATRIX_INDEX_ARRAY_SIZE_OES                          0x8846
+#define GL_MATRIX_INDEX_ARRAY_TYPE_OES                          0x8847
+#define GL_MATRIX_INDEX_ARRAY_STRIDE_OES                        0x8848
+#define GL_MATRIX_INDEX_ARRAY_POINTER_OES                       0x8849
+#define GL_MATRIX_INDEX_ARRAY_BUFFER_BINDING_OES                0x8B9E
+#define GL_WEIGHT_ARRAY_SIZE_OES                                0x86AB
+#define GL_WEIGHT_ARRAY_TYPE_OES                                0x86A9
+#define GL_WEIGHT_ARRAY_STRIDE_OES                              0x86AA
+#define GL_WEIGHT_ARRAY_POINTER_OES                             0x86AC
+#define GL_WEIGHT_ARRAY_BUFFER_BINDING_OES                      0x889E
+#endif
+
+/* GL_OES_packed_depth_stencil */
+#ifndef GL_OES_packed_depth_stencil
+#define GL_DEPTH_STENCIL_OES                                    0x84F9
+#define GL_UNSIGNED_INT_24_8_OES                                0x84FA
+#define GL_DEPTH24_STENCIL8_OES                                 0x88F0
+#endif
+
+/* GL_OES_rgb8_rgba8 */
+#ifndef GL_OES_rgb8_rgba8
+#define GL_RGB8_OES                                             0x8051
+#define GL_RGBA8_OES                                            0x8058
+#endif
+
+/* GL_OES_stencil1 */
+#ifndef GL_OES_stencil1
+#define GL_STENCIL_INDEX1_OES                                   0x8D46
+#endif
+
+/* GL_OES_stencil4 */
+#ifndef GL_OES_stencil4
+#define GL_STENCIL_INDEX4_OES                                   0x8D47
+#endif
+
+/* GL_OES_stencil8 */
+#ifndef GL_OES_stencil8
+#define GL_STENCIL_INDEX8_OES                                   0x8D48
+#endif
+
+/* GL_OES_stencil_wrap */
+#ifndef GL_OES_stencil_wrap
+#define GL_INCR_WRAP_OES                                        0x8507
+#define GL_DECR_WRAP_OES                                        0x8508
+#endif
+
+/* GL_OES_texture_cube_map */
+#ifndef GL_OES_texture_cube_map
+#define GL_NORMAL_MAP_OES                                       0x8511
+#define GL_REFLECTION_MAP_OES                                   0x8512
+#define GL_TEXTURE_CUBE_MAP_OES                                 0x8513
+#define GL_TEXTURE_BINDING_CUBE_MAP_OES                         0x8514
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_OES                      0x8515
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_OES                      0x8516
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_OES                      0x8517
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_OES                      0x8518
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_OES                      0x8519
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_OES                      0x851A
+#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_OES                        0x851C
+#define GL_TEXTURE_GEN_MODE_OES                                 0x2500
+#define GL_TEXTURE_GEN_STR_OES                                  0x8D60
+#endif
+
+/* GL_OES_texture_mirrored_repeat */
+#ifndef GL_OES_texture_mirrored_repeat
+#define GL_MIRRORED_REPEAT_OES                                  0x8370
+#endif
+
+/*------------------------------------------------------------------------*
+ * AMD extension tokens
+ *------------------------------------------------------------------------*/
+
+/* GL_AMD_compressed_3DC_texture */
+#ifndef GL_AMD_compressed_3DC_texture
+#define GL_3DC_X_AMD                                            0x87F9
+#define GL_3DC_XY_AMD                                           0x87FA
+#endif
+
+/* GL_AMD_compressed_ATC_texture */
+#ifndef GL_AMD_compressed_ATC_texture
+#define GL_ATC_RGB_AMD                                          0x8C92
+#define GL_ATC_RGBA_EXPLICIT_ALPHA_AMD                          0x8C93
+#define GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD                      0x87EE
+#endif
+
+/*------------------------------------------------------------------------*
+ * EXT extension tokens
+ *------------------------------------------------------------------------*/
+
+/* GL_EXT_texture_filter_anisotropic */
+#ifndef GL_EXT_texture_filter_anisotropic
+#define GL_TEXTURE_MAX_ANISOTROPY_EXT                           0x84FE
+#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT                       0x84FF
+#endif
+
+/*------------------------------------------------------------------------*
+ * OES extension functions
+ *------------------------------------------------------------------------*/
+
+/* GL_OES_blend_equation_separate */
+#ifndef GL_OES_blend_equation_separate
+#define GL_OES_blend_equation_separate 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_API void GL_APIENTRY glBlendEquationSeparateOES (GLenum modeRGB, GLenum modeAlpha);
+#endif
+typedef void (GL_APIENTRYP PFNGLBLENDEQUATIONSEPARATEOESPROC) (GLenum modeRGB, GLenum modeAlpha);
+#endif
+
+/* GL_OES_blend_func_separate */
+#ifndef GL_OES_blend_func_separate
+#define GL_OES_blend_func_separate 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_API void GL_APIENTRY glBlendFuncSeparateOES (GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+#endif
+typedef void (GL_APIENTRYP PFNGLBLENDFUNCSEPARATEOESPROC) (GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+#endif
+
+/* GL_OES_blend_subtract */
+#ifndef GL_OES_blend_subtract
+#define GL_OES_blend_subtract 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_API void GL_APIENTRY glBlendEquationOES (GLenum mode);
+#endif
+typedef void (GL_APIENTRYP PFNGLBLENDEQUATIONOESPROC) (GLenum mode);
+#endif
+
+/* GL_OES_byte_coordinates */
+#ifndef GL_OES_byte_coordinates
+#define GL_OES_byte_coordinates 1
+#endif
+
+/* GL_OES_compressed_ETC1_RGB8_texture */
+#ifndef GL_OES_compressed_ETC1_RGB8_texture
+#define GL_OES_compressed_ETC1_RGB8_texture 1
+#endif
+
+/* GL_OES_depth24 */
+#ifndef GL_OES_depth24
+#define GL_OES_depth24 1
+#endif
+
+/* GL_OES_depth32 */
+#ifndef GL_OES_depth32
+#define GL_OES_depth32 1
+#endif
+
+/* GL_OES_draw_texture */
+#ifndef GL_OES_draw_texture
+#define GL_OES_draw_texture 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_API void GL_APIENTRY glDrawTexsOES (GLshort x, GLshort y, GLshort z, GLshort width, GLshort height);
+GL_API void GL_APIENTRY glDrawTexiOES (GLint x, GLint y, GLint z, GLint width, GLint height);
+GL_API void GL_APIENTRY glDrawTexxOES (GLfixed x, GLfixed y, GLfixed z, GLfixed width, GLfixed height);
+GL_API void GL_APIENTRY glDrawTexsvOES (const GLshort *coords);
+GL_API void GL_APIENTRY glDrawTexivOES (const GLint *coords);
+GL_API void GL_APIENTRY glDrawTexxvOES (const GLfixed *coords);
+GL_API void GL_APIENTRY glDrawTexfOES (GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height);
+GL_API void GL_APIENTRY glDrawTexfvOES (const GLfloat *coords);
+#endif
+typedef void (GL_APIENTRYP PFNGLDRAWTEXSOESPROC) (GLshort x, GLshort y, GLshort z, GLshort width, GLshort height);
+typedef void (GL_APIENTRYP PFNGLDRAWTEXIOESPROC) (GLint x, GLint y, GLint z, GLint width, GLint height);
+typedef void (GL_APIENTRYP PFNGLDRAWTEXXOESPROC) (GLfixed x, GLfixed y, GLfixed z, GLfixed width, GLfixed height);
+typedef void (GL_APIENTRYP PFNGLDRAWTEXSVOESPROC) (const GLshort *coords);
+typedef void (GL_APIENTRYP PFNGLDRAWTEXIVOESPROC) (const GLint *coords);
+typedef void (GL_APIENTRYP PFNGLDRAWTEXXVOESPROC) (const GLfixed *coords);
+typedef void (GL_APIENTRYP PFNGLDRAWTEXFOESPROC) (GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height);
+typedef void (GL_APIENTRYP PFNGLDRAWTEXFVOESPROC) (const GLfloat *coords);
+#endif
+
+/* GL_OES_EGL_image */
+#ifndef GL_OES_EGL_image
+#define GL_OES_EGL_image 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_API void GL_APIENTRY glEGLImageTargetTexture2DOES (GLenum target, GLeglImageOES image);
+GL_API void GL_APIENTRY glEGLImageTargetRenderbufferStorageOES (GLenum target, GLeglImageOES image);
+#endif
+typedef void (GL_APIENTRYP PFNGLEGLIMAGETARGETTEXTURE2DOESPROC) (GLenum target, GLeglImageOES image);
+typedef void (GL_APIENTRYP PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC) (GLenum target, GLeglImageOES image);
+#endif
+
+/* GL_OES_element_index_uint */
+#ifndef GL_OES_element_index_uint
+#define GL_OES_element_index_uint 1
+#endif
+
+/* GL_OES_extended_matrix_palette */
+#ifndef GL_OES_extended_matrix_palette
+#define GL_OES_extended_matrix_palette 1
+#endif
+
+/* GL_OES_fbo_render_mipmap */
+#ifndef GL_OES_fbo_render_mipmap
+#define GL_OES_fbo_render_mipmap 1
+#endif
+
+/* GL_OES_fixed_point */
+#ifndef GL_OES_fixed_point
+#define GL_OES_fixed_point 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_API void GL_APIENTRY glAlphaFuncxOES (GLenum func, GLclampx ref);
+GL_API void GL_APIENTRY glClearColorxOES (GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha);
+GL_API void GL_APIENTRY glClearDepthxOES (GLclampx depth);
+GL_API void GL_APIENTRY glClipPlanexOES (GLenum plane, const GLfixed *equation);
+GL_API void GL_APIENTRY glColor4xOES (GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha);
+GL_API void GL_APIENTRY glDepthRangexOES (GLclampx zNear, GLclampx zFar);
+GL_API void GL_APIENTRY glFogxOES (GLenum pname, GLfixed param);
+GL_API void GL_APIENTRY glFogxvOES (GLenum pname, const GLfixed *params);
+GL_API void GL_APIENTRY glFrustumxOES (GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar);
+GL_API void GL_APIENTRY glGetClipPlanexOES (GLenum pname, GLfixed eqn[4]);
+GL_API void GL_APIENTRY glGetFixedvOES (GLenum pname, GLfixed *params);
+GL_API void GL_APIENTRY glGetLightxvOES (GLenum light, GLenum pname, GLfixed *params);
+GL_API void GL_APIENTRY glGetMaterialxvOES (GLenum face, GLenum pname, GLfixed *params);
+GL_API void GL_APIENTRY glGetTexEnvxvOES (GLenum env, GLenum pname, GLfixed *params);
+GL_API void GL_APIENTRY glGetTexParameterxvOES (GLenum target, GLenum pname, GLfixed *params);
+GL_API void GL_APIENTRY glLightModelxOES (GLenum pname, GLfixed param);
+GL_API void GL_APIENTRY glLightModelxvOES (GLenum pname, const GLfixed *params);
+GL_API void GL_APIENTRY glLightxOES (GLenum light, GLenum pname, GLfixed param);
+GL_API void GL_APIENTRY glLightxvOES (GLenum light, GLenum pname, const GLfixed *params);
+GL_API void GL_APIENTRY glLineWidthxOES (GLfixed width);
+GL_API void GL_APIENTRY glLoadMatrixxOES (const GLfixed *m);
+GL_API void GL_APIENTRY glMaterialxOES (GLenum face, GLenum pname, GLfixed param);
+GL_API void GL_APIENTRY glMaterialxvOES (GLenum face, GLenum pname, const GLfixed *params);
+GL_API void GL_APIENTRY glMultMatrixxOES (const GLfixed *m);
+GL_API void GL_APIENTRY glMultiTexCoord4xOES (GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q);
+GL_API void GL_APIENTRY glNormal3xOES (GLfixed nx, GLfixed ny, GLfixed nz);
+GL_API void GL_APIENTRY glOrthoxOES (GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar);
+GL_API void GL_APIENTRY glPointParameterxOES (GLenum pname, GLfixed param);
+GL_API void GL_APIENTRY glPointParameterxvOES (GLenum pname, const GLfixed *params);
+GL_API void GL_APIENTRY glPointSizexOES (GLfixed size);
+GL_API void GL_APIENTRY glPolygonOffsetxOES (GLfixed factor, GLfixed units);
+GL_API void GL_APIENTRY glRotatexOES (GLfixed angle, GLfixed x, GLfixed y, GLfixed z);
+GL_API void GL_APIENTRY glSampleCoveragexOES (GLclampx value, GLboolean invert);
+GL_API void GL_APIENTRY glScalexOES (GLfixed x, GLfixed y, GLfixed z);
+GL_API void GL_APIENTRY glTexEnvxOES (GLenum target, GLenum pname, GLfixed param);
+GL_API void GL_APIENTRY glTexEnvxvOES (GLenum target, GLenum pname, const GLfixed *params);
+GL_API void GL_APIENTRY glTexParameterxOES (GLenum target, GLenum pname, GLfixed param);
+GL_API void GL_APIENTRY glTexParameterxvOES (GLenum target, GLenum pname, const GLfixed *params);
+GL_API void GL_APIENTRY glTranslatexOES (GLfixed x, GLfixed y, GLfixed z);
+#endif
+typedef void (GL_APIENTRYP PFNGLALPHAFUNCXOESPROC) (GLenum func, GLclampx ref);
+typedef void (GL_APIENTRYP PFNGLCLEARCOLORXOESPROC) (GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha);
+typedef void (GL_APIENTRYP PFNGLCLEARDEPTHXOESPROC) (GLclampx depth);
+typedef void (GL_APIENTRYP PFNGLCLIPPLANEXOESPROC) (GLenum plane, const GLfixed *equation);
+typedef void (GL_APIENTRYP PFNGLCOLOR4XOESPROC) (GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha);
+typedef void (GL_APIENTRYP PFNGLDEPTHRANGEXOESPROC) (GLclampx zNear, GLclampx zFar);
+typedef void (GL_APIENTRYP PFNGLFOGXOESPROC) (GLenum pname, GLfixed param);
+typedef void (GL_APIENTRYP PFNGLFOGXVOESPROC) (GLenum pname, const GLfixed *params);
+typedef void (GL_APIENTRYP PFNGLFRUSTUMXOESPROC) (GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar);
+typedef void (GL_APIENTRYP PFNGLGETCLIPPLANEXOESPROC) (GLenum pname, GLfixed eqn[4]);
+typedef void (GL_APIENTRYP PFNGLGETFIXEDVOESPROC) (GLenum pname, GLfixed *params);
+typedef void (GL_APIENTRYP PFNGLGETLIGHTXVOESPROC) (GLenum light, GLenum pname, GLfixed *params);
+typedef void (GL_APIENTRYP PFNGLGETMATERIALXVOESPROC) (GLenum face, GLenum pname, GLfixed *params);
+typedef void (GL_APIENTRYP PFNGLGETTEXENVXVOESPROC) (GLenum env, GLenum pname, GLfixed *params);
+typedef void (GL_APIENTRYP PFNGLGETTEXPARAMETERXVOESPROC) (GLenum target, GLenum pname, GLfixed *params);
+typedef void (GL_APIENTRYP PFNGLLIGHTMODELXOESPROC) (GLenum pname, GLfixed param);
+typedef void (GL_APIENTRYP PFNGLLIGHTMODELXVOESPROC) (GLenum pname, const GLfixed *params);
+typedef void (GL_APIENTRYP PFNGLLIGHTXOESPROC) (GLenum light, GLenum pname, GLfixed param);
+typedef void (GL_APIENTRYP PFNGLLIGHTXVOESPROC) (GLenum light, GLenum pname, const GLfixed *params);
+typedef void (GL_APIENTRYP PFNGLLINEWIDTHXOESPROC) (GLfixed width);
+typedef void (GL_APIENTRYP PFNGLLOADMATRIXXOESPROC) (const GLfixed *m);
+typedef void (GL_APIENTRYP PFNGLMATERIALXOESPROC) (GLenum face, GLenum pname, GLfixed param);
+typedef void (GL_APIENTRYP PFNGLMATERIALXVOESPROC) (GLenum face, GLenum pname, const GLfixed *params);
+typedef void (GL_APIENTRYP PFNGLMULTMATRIXXOESPROC) (const GLfixed *m);
+typedef void (GL_APIENTRYP PFNGLMULTITEXCOORD4XOESPROC) (GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q);
+typedef void (GL_APIENTRYP PFNGLNORMAL3XOESPROC) (GLfixed nx, GLfixed ny, GLfixed nz);
+typedef void (GL_APIENTRYP PFNGLORTHOXOESPROC) (GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar);
+typedef void (GL_APIENTRYP PFNGLPOINTPARAMETERXOESPROC) (GLenum pname, GLfixed param);
+typedef void (GL_APIENTRYP PFNGLPOINTPARAMETERXVOESPROC) (GLenum pname, const GLfixed *params);
+typedef void (GL_APIENTRYP PFNGLPOINTSIZEXOESPROC) (GLfixed size);
+typedef void (GL_APIENTRYP PFNGLPOLYGONOFFSETXOESPROC) (GLfixed factor, GLfixed units);
+typedef void (GL_APIENTRYP PFNGLROTATEXOESPROC) (GLfixed angle, GLfixed x, GLfixed y, GLfixed z);
+typedef void (GL_APIENTRYP PFNGLSAMPLECOVERAGEXOESPROC) (GLclampx value, GLboolean invert);
+typedef void (GL_APIENTRYP PFNGLSCALEXOESPROC) (GLfixed x, GLfixed y, GLfixed z);
+typedef void (GL_APIENTRYP PFNGLTEXENVXOESPROC) (GLenum target, GLenum pname, GLfixed param);
+typedef void (GL_APIENTRYP PFNGLTEXENVXVOESPROC) (GLenum target, GLenum pname, const GLfixed *params);
+typedef void (GL_APIENTRYP PFNGLTEXPARAMETERXOESPROC) (GLenum target, GLenum pname, GLfixed param);
+typedef void (GL_APIENTRYP PFNGLTEXPARAMETERXVOESPROC) (GLenum target, GLenum pname, const GLfixed *params);
+typedef void (GL_APIENTRYP PFNGLTRANSLATEXOESPROC) (GLfixed x, GLfixed y, GLfixed z);
+#endif
+
+/* GL_OES_framebuffer_object */
+#ifndef GL_OES_framebuffer_object
+#define GL_OES_framebuffer_object 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_API GLboolean GL_APIENTRY glIsRenderbufferOES (GLuint renderbuffer);
+GL_API void GL_APIENTRY glBindRenderbufferOES (GLenum target, GLuint renderbuffer);
+GL_API void GL_APIENTRY glDeleteRenderbuffersOES (GLsizei n, const GLuint* renderbuffers);
+GL_API void GL_APIENTRY glGenRenderbuffersOES (GLsizei n, GLuint* renderbuffers);
+GL_API void GL_APIENTRY glRenderbufferStorageOES (GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+GL_API void GL_APIENTRY glGetRenderbufferParameterivOES (GLenum target, GLenum pname, GLint* params);
+GL_API GLboolean GL_APIENTRY glIsFramebufferOES (GLuint framebuffer);
+GL_API void GL_APIENTRY glBindFramebufferOES (GLenum target, GLuint framebuffer);
+GL_API void GL_APIENTRY glDeleteFramebuffersOES (GLsizei n, const GLuint* framebuffers);
+GL_API void GL_APIENTRY glGenFramebuffersOES (GLsizei n, GLuint* framebuffers);
+GL_API GLenum GL_APIENTRY glCheckFramebufferStatusOES (GLenum target);
+GL_API void GL_APIENTRY glFramebufferRenderbufferOES (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+GL_API void GL_APIENTRY glFramebufferTexture2DOES (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+GL_API void GL_APIENTRY glGetFramebufferAttachmentParameterivOES (GLenum target, GLenum attachment, GLenum pname, GLint* params);
+GL_API void GL_APIENTRY glGenerateMipmapOES (GLenum target);
+#endif
+typedef GLboolean (GL_APIENTRYP PFNGLISRENDERBUFFEROESPROC) (GLuint renderbuffer);
+typedef void (GL_APIENTRYP PFNGLBINDRENDERBUFFEROESPROC) (GLenum target, GLuint renderbuffer);
+typedef void (GL_APIENTRYP PFNGLDELETERENDERBUFFERSOESPROC) (GLsizei n, const GLuint* renderbuffers);
+typedef void (GL_APIENTRYP PFNGLGENRENDERBUFFERSOESPROC) (GLsizei n, GLuint* renderbuffers);
+typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEOESPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (GL_APIENTRYP PFNGLGETRENDERBUFFERPARAMETERIVOESPROC) (GLenum target, GLenum pname, GLint* params);
+typedef GLboolean (GL_APIENTRYP PFNGLISFRAMEBUFFEROESPROC) (GLuint framebuffer);
+typedef void (GL_APIENTRYP PFNGLBINDFRAMEBUFFEROESPROC) (GLenum target, GLuint framebuffer);
+typedef void (GL_APIENTRYP PFNGLDELETEFRAMEBUFFERSOESPROC) (GLsizei n, const GLuint* framebuffers);
+typedef void (GL_APIENTRYP PFNGLGENFRAMEBUFFERSOESPROC) (GLsizei n, GLuint* framebuffers);
+typedef GLenum (GL_APIENTRYP PFNGLCHECKFRAMEBUFFERSTATUSOESPROC) (GLenum target);
+typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERRENDERBUFFEROESPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DOESPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+typedef void (GL_APIENTRYP PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVOESPROC) (GLenum target, GLenum attachment, GLenum pname, GLint* params);
+typedef void (GL_APIENTRYP PFNGLGENERATEMIPMAPOESPROC) (GLenum target);
+#endif
+
+/* GL_OES_mapbuffer */
+#ifndef GL_OES_mapbuffer
+#define GL_OES_mapbuffer 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_API void* GL_APIENTRY glMapBufferOES (GLenum target, GLenum access);
+GL_API GLboolean GL_APIENTRY glUnmapBufferOES (GLenum target);
+GL_API void GL_APIENTRY glGetBufferPointervOES (GLenum target, GLenum pname, void** params);
+#endif
+typedef void* (GL_APIENTRYP PFNGLMAPBUFFEROESPROC) (GLenum target, GLenum access);
+typedef GLboolean (GL_APIENTRYP PFNGLUNMAPBUFFEROESPROC) (GLenum target);
+typedef void (GL_APIENTRYP PFNGLGETBUFFERPOINTERVOESPROC) (GLenum target, GLenum pname, void** params);
+#endif
+
+/* GL_OES_matrix_get */
+#ifndef GL_OES_matrix_get
+#define GL_OES_matrix_get 1
+#endif
+
+/* GL_OES_matrix_palette */
+#ifndef GL_OES_matrix_palette
+#define GL_OES_matrix_palette 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_API void GL_APIENTRY glCurrentPaletteMatrixOES (GLuint matrixpaletteindex);
+GL_API void GL_APIENTRY glLoadPaletteFromModelViewMatrixOES (void);
+GL_API void GL_APIENTRY glMatrixIndexPointerOES (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+GL_API void GL_APIENTRY glWeightPointerOES (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+#endif
+typedef void (GL_APIENTRYP PFNGLCURRENTPALETTEMATRIXOESPROC) (GLuint matrixpaletteindex);
+typedef void (GL_APIENTRYP PFNGLLOADPALETTEFROMMODELVIEWMATRIXOESPROC) (void);
+typedef void (GL_APIENTRYP PFNGLMATRIXINDEXPOINTEROESPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+typedef void (GL_APIENTRYP PFNGLWEIGHTPOINTEROESPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+#endif
+
+/* GL_OES_packed_depth_stencil */
+#ifndef GL_OES_packed_depth_stencil
+#define GL_OES_packed_depth_stencil 1
+#endif
+
+/* GL_OES_query_matrix */
+#ifndef GL_OES_query_matrix
+#define GL_OES_query_matrix 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_API GLbitfield GL_APIENTRY glQueryMatrixxOES (GLfixed mantissa[16], GLint exponent[16]);
+#endif
+typedef GLbitfield (GL_APIENTRYP PFNGLQUERYMATRIXXOESPROC) (GLfixed mantissa[16], GLint exponent[16]);
+#endif
+
+/* GL_OES_rgb8_rgba8 */
+#ifndef GL_OES_rgb8_rgba8
+#define GL_OES_rgb8_rgba8 1
+#endif
+
+/* GL_OES_single_precision */
+#ifndef GL_OES_single_precision
+#define GL_OES_single_precision 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_API void GL_APIENTRY glDepthRangefOES (GLclampf zNear, GLclampf zFar);
+GL_API void GL_APIENTRY glFrustumfOES (GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar);
+GL_API void GL_APIENTRY glOrthofOES (GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar);
+GL_API void GL_APIENTRY glClipPlanefOES (GLenum plane, const GLfloat *equation);
+GL_API void GL_APIENTRY glGetClipPlanefOES (GLenum pname, GLfloat eqn[4]);
+GL_API void GL_APIENTRY glClearDepthfOES (GLclampf depth);
+#endif
+typedef void (GL_APIENTRYP PFNGLDEPTHRANGEFOESPROC) (GLclampf zNear, GLclampf zFar);
+typedef void (GL_APIENTRYP PFNGLFRUSTUMFOESPROC) (GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar);
+typedef void (GL_APIENTRYP PFNGLORTHOFOESPROC) (GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar);
+typedef void (GL_APIENTRYP PFNGLCLIPPLANEFOESPROC) (GLenum plane, const GLfloat *equation);
+typedef void (GL_APIENTRYP PFNGLGETCLIPPLANEFOESPROC) (GLenum pname, GLfloat eqn[4]);
+typedef void (GL_APIENTRYP PFNGLCLEARDEPTHFOESPROC) (GLclampf depth);
+#endif
+
+/* GL_OES_stencil1 */
+#ifndef GL_OES_stencil1
+#define GL_OES_stencil1 1
+#endif
+
+/* GL_OES_stencil4 */
+#ifndef GL_OES_stencil4
+#define GL_OES_stencil4 1
+#endif
+
+/* GL_OES_stencil8 */
+#ifndef GL_OES_stencil8
+#define GL_OES_stencil8 1
+#endif
+
+/* GL_OES_stencil_wrap */
+#ifndef GL_OES_stencil_wrap
+#define GL_OES_stencil_wrap 1
+#endif
+
+/* GL_OES_texture_cube_map */
+#ifndef GL_OES_texture_cube_map
+#define GL_OES_texture_cube_map 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_API void GL_APIENTRY glTexGenfOES (GLenum coord, GLenum pname, GLfloat param);
+GL_API void GL_APIENTRY glTexGenfvOES (GLenum coord, GLenum pname, const GLfloat *params);
+GL_API void GL_APIENTRY glTexGeniOES (GLenum coord, GLenum pname, GLint param);
+GL_API void GL_APIENTRY glTexGenivOES (GLenum coord, GLenum pname, const GLint *params);
+GL_API void GL_APIENTRY glTexGenxOES (GLenum coord, GLenum pname, GLfixed param);
+GL_API void GL_APIENTRY glTexGenxvOES (GLenum coord, GLenum pname, const GLfixed *params);
+GL_API void GL_APIENTRY glGetTexGenfvOES (GLenum coord, GLenum pname, GLfloat *params);
+GL_API void GL_APIENTRY glGetTexGenivOES (GLenum coord, GLenum pname, GLint *params);
+GL_API void GL_APIENTRY glGetTexGenxvOES (GLenum coord, GLenum pname, GLfixed *params);
+#endif
+typedef void (GL_APIENTRYP PFNGLTEXGENFOESPROC) (GLenum coord, GLenum pname, GLfloat param);
+typedef void (GL_APIENTRYP PFNGLTEXGENFVOESPROC) (GLenum coord, GLenum pname, const GLfloat *params);
+typedef void (GL_APIENTRYP PFNGLTEXGENIOESPROC) (GLenum coord, GLenum pname, GLint param);
+typedef void (GL_APIENTRYP PFNGLTEXGENIVOESPROC) (GLenum coord, GLenum pname, const GLint *params);
+typedef void (GL_APIENTRYP PFNGLTEXGENXOESPROC) (GLenum coord, GLenum pname, GLfixed param);
+typedef void (GL_APIENTRYP PFNGLTEXGENXVOESPROC) (GLenum coord, GLenum pname, const GLfixed *params);
+typedef void (GL_APIENTRYP PFNGLGETTEXGENFVOESPROC) (GLenum coord, GLenum pname, GLfloat *params);
+typedef void (GL_APIENTRYP PFNGLGETTEXGENIVOESPROC) (GLenum coord, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETTEXGENXVOESPROC) (GLenum coord, GLenum pname, GLfixed *params);
+#endif
+
+/* GL_OES_texture_env_crossbar */
+#ifndef GL_OES_texture_env_crossbar
+#define GL_OES_texture_env_crossbar 1
+#endif
+
+/* GL_OES_texture_mirrored_repeat */
+#ifndef GL_OES_texture_mirrored_repeat
+#define GL_OES_texture_mirrored_repeat 1
+#endif
+
+/*------------------------------------------------------------------------*
+ * AMD extension functions
+ *------------------------------------------------------------------------*/
+
+/* GL_AMD_compressed_3DC_texture */
+#ifndef GL_AMD_compressed_3DC_texture
+#define GL_AMD_compressed_3DC_texture 1
+#endif
+
+/* GL_AMD_compressed_ATC_texture */
+#ifndef GL_AMD_compressed_ATC_texture
+#define GL_AMD_compressed_ATC_texture 1
+#endif
+
+/*------------------------------------------------------------------------*
+ * EXT extension functions
+ *------------------------------------------------------------------------*/
+
+/* GL_EXT_texture_filter_anisotropic */
+#ifndef GL_EXT_texture_filter_anisotropic
+#define GL_EXT_texture_filter_anisotropic 1
+#endif
+
+/*------------------------------------------------------------------------*
+ * dalvik extension functions
+ *------------------------------------------------------------------------*/
+#ifdef ANDROID
+void glColorPointerBounds(GLint size, GLenum type, GLsizei stride,
+        const GLvoid *ptr, GLsizei count);
+void glNormalPointerBounds(GLenum type, GLsizei stride,
+        const GLvoid *pointer, GLsizei count);
+void glTexCoordPointerBounds(GLint size, GLenum type,
+        GLsizei stride, const GLvoid *pointer, GLsizei count);
+void glVertexPointerBounds(GLint size, GLenum type,
+        GLsizei stride, const GLvoid *pointer, GLsizei count);
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __glext_h_ */
+
diff --git a/opengl/include/GLES/glplatform.h b/opengl/include/GLES/glplatform.h
new file mode 100644
index 0000000..0924cae
--- /dev/null
+++ b/opengl/include/GLES/glplatform.h
@@ -0,0 +1,39 @@
+#ifndef __glplatform_h_
+#define __glplatform_h_
+
+/* $Revision: 7172 $ on $Date:: 2009-01-09 11:17:41 -0800 #$ */
+
+/*
+ * This document is licensed under the SGI Free Software B License Version
+ * 2.0. For details, see http://oss.sgi.com/projects/FreeB/ .
+ */
+
+/* Platform-specific types and definitions for OpenGL ES 1.X  gl.h
+ * Last modified on 2008/12/19
+ *
+ * Adopters may modify khrplatform.h and this file to suit their platform.
+ * You are encouraged to submit all modifications to the Khronos group so that
+ * they can be included in future versions of this file.  Please submit changes
+ * by sending them to the public Khronos Bugzilla (http://khronos.org/bugzilla)
+ * by filing a bug against product "OpenGL-ES" component "Registry".
+ */
+
+#include <KHR/khrplatform.h>
+
+#ifndef GL_API
+#define GL_API      KHRONOS_APICALL
+#endif
+
+#if defined(ANDROID)
+
+#define GL_APIENTRY KHRONOS_APIENTRY
+
+// XXX: this should probably not be here
+#define GL_DIRECT_TEXTURE_2D_QUALCOMM               0x7E80
+
+// XXX: not sure how this is intended to be used
+#define GL_GLEXT_PROTOTYPES
+
+#endif
+
+#endif /* __glplatform_h_ */
diff --git a/opengl/include/KHR/khrplatform.h b/opengl/include/KHR/khrplatform.h
new file mode 100644
index 0000000..4cc27c5
--- /dev/null
+++ b/opengl/include/KHR/khrplatform.h
@@ -0,0 +1,241 @@
+#ifndef __khrplatform_h_
+#define __khrplatform_h_
+
+/*
+** Copyright (c) 2008-2009 The Khronos Group Inc.
+**
+** Permission is hereby granted, free of charge, to any person obtaining a
+** copy of this software and/or associated documentation files (the
+** "Materials"), to deal in the Materials without restriction, including
+** without limitation the rights to use, copy, modify, merge, publish,
+** distribute, sublicense, and/or sell copies of the Materials, and to
+** permit persons to whom the Materials are furnished to do so, subject to
+** the following conditions:
+**
+** The above copyright notice and this permission notice shall be included
+** in all copies or substantial portions of the Materials.
+**
+** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+*/
+
+/* Platform-specific types and definitions.
+ * $Revision: 7244 $ on $Date: 2009-01-20 17:06:59 -0800 (Tue, 20 Jan 2009) $
+ * 
+ * Adopters may modify this file to suit their platform. Adopters are
+ * encouraged to submit platform specific modifications to the Khronos
+ * group so that they can be included in future versions of this file.
+ * Please submit changes by sending them to the public Khronos Bugzilla
+ * (http://khronos.org/bugzilla) by filing a bug against product
+ * "Khronos (general)" component "Registry".
+ *
+ * A predefined template which fills in some of the bug fields can be
+ * reached using http://tinyurl.com/khrplatform-h-bugreport, but you
+ * must create a Bugzilla login first.
+ * 
+ *
+ * See the Implementer's Guidelines for information about where this file
+ * should be located on your system.
+ *    http://www.khronos.org/registry/implementers_guide.pdf
+ *
+ * 
+ * This file should be included as
+ *        #include <KHR/khrplatform.h>
+ * by the Khronos API header file that uses its types and defines.
+ *
+ * The types in this file should only be used to define API-specific types.
+ * Types defined in this file:
+ *    khronos_int8_t              signed   8  bit
+ *    khronos_uint8_t             unsigned 8  bit
+ *    khronos_int16_t             signed   16 bit
+ *    khronos_uint16_t            unsigned 16 bit
+ *    khronos_int32_t             signed   32 bit
+ *    khronos_uint32_t            unsigned 32 bit
+ *    khronos_int64_t             signed   64 bit
+ *    khronos_uint64_t            unsigned 64 bit
+ *    khronos_intptr_t            signed   same number of bits as a pointer
+ *    khronos_uintptr_t           unsigned same number of bits as a pointer
+ *    khronos_ssize_t             signed   size
+ *    khronos_usize_t             unsigned size
+ *    khronos_float_t             signed   32 bit floating point
+ *    khronos_time_ns_t           unsigned 64 bit time in nanoseconds
+ *    khronos_utime_nanoseconds_t unsigned time interval or absolute time in
+ *                                         nanoseconds
+ *    khronos_stime_nanoseconds_t signed time interval in nanoseconds
+ *
+ * KHRONOS_SUPPORT_INT64 is 1 if 64 bit integers are supported; otherwise 0.
+ * KHRONOS_SUPPORT_FLOAT is 1 if floats are supported; otherwise 0.
+ * 
+ *
+ * Macros defined in this file:
+ *    KHRONOS_APICALL
+ *    KHRONOS_APIENTRY
+ *    KHRONOS_APIATTRIBUTES
+ * These may be used in function prototypes as:
+ *      KHRONOS_APICALL void KHRONOS_APIENTRY funcname(
+ *                                  int arg1,
+ *                                  int arg2) KHRONOS_APIATTRIBUTES;
+ */
+
+/*-------------------------------------------------------------------------
+ * Definition of KHRONOS_APICALL
+ *-------------------------------------------------------------------------
+ * This precedes the return type of the function in the function prototype.
+ */
+#if defined(_WIN32) && !defined(__SCITECH_SNAP__)
+#   define KHRONOS_APICALL __declspec(dllimport)
+#elif defined (__SYMBIAN32__)
+#   define KHRONOS_APICALL IMPORT_C
+#else
+#   define KHRONOS_APICALL
+#endif
+
+/*-------------------------------------------------------------------------
+ * Definition of KHRONOS_APIENTRY
+ *-------------------------------------------------------------------------
+ * This follows the return type of the function  and precedes the function
+ * name in the function prototype.
+ */
+#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__)
+    /* Win32 but not WinCE */
+#   define KHRONOS_APIENTRY __stdcall
+#else
+#   define KHRONOS_APIENTRY
+#endif
+
+/*-------------------------------------------------------------------------
+ * Definition of KHRONOS_APIATTRIBUTES
+ *-------------------------------------------------------------------------
+ * This follows the closing parenthesis of the function prototype arguments.
+ */
+#if defined (__ARMCC_2__)
+#define KHRONOS_APIATTRIBUTES __softfp
+#else
+#define KHRONOS_APIATTRIBUTES
+#endif
+
+/*-------------------------------------------------------------------------
+ * basic type definitions
+ *-----------------------------------------------------------------------*/
+#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__GNUC__) || defined(__SCO__) || defined(__USLC__)
+
+
+/*
+ * Using <stdint.h>
+ */
+#include <stdint.h>
+typedef int32_t                 khronos_int32_t;
+typedef uint32_t                khronos_uint32_t;
+typedef int64_t                 khronos_int64_t;
+typedef uint64_t                khronos_uint64_t;
+#define KHRONOS_SUPPORT_INT64   1
+#define KHRONOS_SUPPORT_FLOAT   1
+
+#elif defined(__VMS ) || defined(__sgi)
+
+/*
+ * Using <inttypes.h>
+ */
+#include <inttypes.h>
+typedef int32_t                 khronos_int32_t;
+typedef uint32_t                khronos_uint32_t;
+typedef int64_t                 khronos_int64_t;
+typedef uint64_t                khronos_uint64_t;
+#define KHRONOS_SUPPORT_INT64   1
+#define KHRONOS_SUPPORT_FLOAT   1
+
+#elif defined(_WIN32) && !defined(__SCITECH_SNAP__)
+
+/*
+ * Win32
+ */
+typedef __int32                 khronos_int32_t;
+typedef unsigned __int32        khronos_uint32_t;
+typedef __int64                 khronos_int64_t;
+typedef unsigned __int64        khronos_uint64_t;
+#define KHRONOS_SUPPORT_INT64   1
+#define KHRONOS_SUPPORT_FLOAT   1
+
+#elif defined(__sun__) || defined(__digital__)
+
+/*
+ * Sun or Digital
+ */
+typedef int                     khronos_int32_t;
+typedef unsigned int            khronos_uint32_t;
+#if defined(__arch64__) || defined(_LP64)
+typedef long int                khronos_int64_t;
+typedef unsigned long int       khronos_uint64_t;
+#else
+typedef long long int           khronos_int64_t;
+typedef unsigned long long int  khronos_uint64_t;
+#endif /* __arch64__ */
+#define KHRONOS_SUPPORT_INT64   1
+#define KHRONOS_SUPPORT_FLOAT   1
+
+#elif 0
+
+/*
+ * Hypothetical platform with no float or int64 support
+ */
+typedef int                     khronos_int32_t;
+typedef unsigned int            khronos_uint32_t;
+#define KHRONOS_SUPPORT_INT64   0
+#define KHRONOS_SUPPORT_FLOAT   0
+
+#else
+
+/*
+ * Generic fallback
+ */
+#include <stdint.h>
+typedef int32_t                 khronos_int32_t;
+typedef uint32_t                khronos_uint32_t;
+typedef int64_t                 khronos_int64_t;
+typedef uint64_t                khronos_uint64_t;
+#define KHRONOS_SUPPORT_INT64   1
+#define KHRONOS_SUPPORT_FLOAT   1
+
+#endif
+
+
+/*
+ * Types that are (so far) the same on all platforms
+ */
+typedef signed   char          khronos_int8_t;
+typedef unsigned char          khronos_uint8_t;
+typedef signed   short int     khronos_int16_t;
+typedef unsigned short int     khronos_uint16_t;
+typedef signed   long  int     khronos_intptr_t;
+typedef unsigned long  int     khronos_uintptr_t;
+typedef signed   long  int     khronos_ssize_t;
+typedef unsigned long  int     khronos_usize_t;
+
+#if KHRONOS_SUPPORT_FLOAT
+/*
+ * Float type
+ */
+typedef          float         khronos_float_t;
+#endif
+
+#if KHRONOS_SUPPORT_INT64
+/* Time types
+ *
+ * These types can be used to represent a time interval in nanoseconds or 
+ * an absolute Unadjusted System Time.  Unadjusted System Time is the number 
+ * of nanoseconds since some arbitrary system event (e.g. since the last 
+ * time the system booted).  The Unadjusted System Time is an unsigned 
+ * 64 bit value that wraps back to 0 every 584 years.  Time intervals 
+ * may be either signed or unsigned.
+ */
+typedef khronos_uint64_t       khronos_utime_nanoseconds_t;
+typedef khronos_int64_t        khronos_stime_nanoseconds_t;
+#endif
+
+
+#endif /* __khrplatform_h_ */
diff --git a/opengl/libGLES_CM/Android.mk b/opengl/libGLES_CM/Android.mk
deleted file mode 100644
index e350e02..0000000
--- a/opengl/libGLES_CM/Android.mk
+++ /dev/null
@@ -1,24 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-
-#
-# Build the wrapper OpenGL ES library
-#
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= gl_wrapper.cpp.arm gl_logger.cpp
-
-LOCAL_SHARED_LIBRARIES += libcutils libutils libui
-LOCAL_LDLIBS := -lpthread -ldl
-LOCAL_MODULE:= libGLES_CM
-
-# needed on sim build because of weird logging issues
-ifeq ($(TARGET_SIMULATOR),true)
-else
-    LOCAL_SHARED_LIBRARIES += libdl
-    # we need to access the Bionic private header <bionic_tls.h>
-    LOCAL_CFLAGS += -I$(LOCAL_PATH)/../../../../bionic/libc/private
-endif
-
-include $(BUILD_SHARED_LIBRARY)
-
diff --git a/opengl/libagl/egl.cpp b/opengl/libagl/egl.cpp
index 3e8dca9..5b90bf0 100644
--- a/opengl/libagl/egl.cpp
+++ b/opengl/libagl/egl.cpp
@@ -33,7 +33,10 @@
 
 #include <utils/threads.h>
 
-#include <GLES/egl.h>
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include <GLES/gl.h>
+#include <GLES/glext.h>
 
 #include <pixelflinger/format.h>
 #include <pixelflinger/pixelflinger.h>
@@ -149,7 +152,6 @@
     virtual     EGLint      getRefreshRate() const;
     virtual     EGLint      getSwapBehavior() const;
     virtual     EGLBoolean  swapBuffers();
-    virtual     EGLBoolean  swapRectangle(EGLint l, EGLint t, EGLint w, EGLint h);
 protected:
     GGLSurface              depth;
 };
@@ -171,10 +173,6 @@
 EGLBoolean egl_surface_t::swapBuffers() {
     return EGL_FALSE;
 }
-EGLBoolean egl_surface_t::swapRectangle(
-        EGLint l, EGLint t, EGLint w, EGLint h) {
-    return EGL_FALSE;
-}
 EGLint egl_surface_t::getHorizontalResolution() const {
     return (0 * EGL_DISPLAY_SCALING) * (1.0f / 25.4f);
 }
@@ -201,7 +199,6 @@
 
     virtual     bool        isValid() const { return nativeWindow->magic == 0x600913; }    
     virtual     EGLBoolean  swapBuffers();
-    virtual     EGLBoolean  swapRectangle(EGLint l, EGLint t, EGLint w, EGLint h);
     virtual     EGLBoolean  bindDrawSurface(ogles_context_t* gl);
     virtual     EGLBoolean  bindReadSurface(ogles_context_t* gl);
     virtual     EGLint      getWidth() const    { return nativeWindow->width;  }
@@ -243,7 +240,6 @@
     if (flags & EGL_NATIVES_FLAG_SIZE_CHANGED) {
         // TODO: we probably should reset the swap rect here
         // if the window size has changed
-        //    window->setSwapRectangle(Rect(info.w, info.h));
         if (depth.data) {
             free(depth.data);
             depth.width   = nativeWindow->width;
@@ -259,12 +255,6 @@
     return EGL_TRUE;
 }
 
-EGLBoolean egl_window_surface_t::swapRectangle(
-        EGLint l, EGLint t, EGLint w, EGLint h)
-{
-    nativeWindow->setSwapRectangle(nativeWindow, l, t, w, h);
-    return EGL_TRUE;
-}
 EGLBoolean egl_window_surface_t::bindDrawSurface(ogles_context_t* gl)
 {
     GGLSurface buffer;
@@ -473,24 +463,21 @@
 
 // ----------------------------------------------------------------------------
 
+#define VERSION_MAJOR 1
+#define VERSION_MINOR 2
 static char const * const gVendorString     = "Google Inc.";
 static char const * const gVersionString    = "1.2 Android Driver";
 static char const * const gClientApiString  = "OpenGL ES";
-static char const * const gExtensionsString =
-    "EGL_ANDROID_swap_rectangle"                " "
-    "EGL_ANDROID_copy_front_to_back"            " "
-    "EGL_ANDROID_get_render_buffer_address"
-    ;
+static char const * const gExtensionsString = "";
 
 // ----------------------------------------------------------------------------
 
 struct extention_map_t {
     const char * const name;
-    void (*address)(void);
+    __eglMustCastToProperFunctionPointerType address;
 };
 
 static const extention_map_t gExtentionMap[] = {
-    { "eglSwapRectangleANDROID",    (void(*)())&eglSwapRectangleANDROID },
     { "glDrawTexsOES",              (void(*)())&glDrawTexsOES },
     { "glDrawTexiOES",              (void(*)())&glDrawTexiOES },
     { "glDrawTexfOES",              (void(*)())&glDrawTexfOES },
@@ -1017,8 +1004,8 @@
     }
 
     if (res == EGL_TRUE) {
-        if (major != NULL) *major = 1;
-        if (minor != NULL) *minor = 2;
+        if (major != NULL) *major = VERSION_MAJOR;
+        if (minor != NULL) *minor = VERSION_MINOR;
     }
     return res;
 }
@@ -1554,15 +1541,3 @@
     }
     return NULL;
 }
-
-EGLBoolean eglSwapRectangleANDROID(
-        EGLDisplay dpy, EGLSurface draw,
-        EGLint l, EGLint t, EGLint w, EGLint h)
-{    
-    if (egl_display_t::is_valid(dpy) == EGL_FALSE)
-        return setError(EGL_BAD_DISPLAY, EGL_FALSE);
-    egl_surface_t* surface = (egl_surface_t*)draw;
-    if (surface->dpy != dpy)
-        return setError(EGL_BAD_DISPLAY, EGL_FALSE);
-    return surface->swapRectangle(l, t, w, h);
-}
diff --git a/opengl/libagl/state.cpp b/opengl/libagl/state.cpp
index c2f9f12..5cbabea 100644
--- a/opengl/libagl/state.cpp
+++ b/opengl/libagl/state.cpp
@@ -403,12 +403,6 @@
     case GL_IMPLEMENTATION_COLOR_READ_TYPE_OES:
         params[0] = GL_UNSIGNED_SHORT_5_6_5;
         break;
-    case GL_MAX_ELEMENTS_INDICES:
-        params[0] = 65536;
-        break;
-    case GL_MAX_ELEMENTS_VERTICES:
-        params[0] = 0x7FFFFFFF;
-        break;
     case GL_MAX_LIGHTS:
         params[0] = OGLES_MAX_LIGHTS;
         break;
diff --git a/opengl/libagl/texture.cpp b/opengl/libagl/texture.cpp
index 6b2640a..b6f534b 100644
--- a/opengl/libagl/texture.cpp
+++ b/opengl/libagl/texture.cpp
@@ -526,7 +526,7 @@
 static void texParameterx(
         GLenum target, GLenum pname, GLfixed param, ogles_context_t* c)
 {
-    if (target != GGL_TEXTURE_2D) {
+    if (target != GL_TEXTURE_2D) {
         ogles_error(c, GL_INVALID_ENUM);
         return;
     }
@@ -534,8 +534,7 @@
     EGLTextureObject* textureObject = c->textures.tmu[c->textures.active].texture;    
     switch (pname) {
     case GL_TEXTURE_WRAP_S:
-        if ((param == GL_CLAMP) ||
-            (param == GL_REPEAT) ||
+        if ((param == GL_REPEAT) ||
             (param == GL_CLAMP_TO_EDGE)) {
             textureObject->wraps = param;
         } else {
@@ -543,9 +542,8 @@
         }
         break;
     case GL_TEXTURE_WRAP_T:
-        if ((param == GGL_CLAMP) ||
-            (param == GGL_REPEAT) ||
-            (param == GGL_CLAMP_TO_EDGE)) {
+        if ((param == GL_REPEAT) ||
+            (param == GL_CLAMP_TO_EDGE)) {
             textureObject->wrapt = param;
         } else {
             goto invalid_enum;
@@ -1006,7 +1004,7 @@
 
 
 void glTexImage2D(
-        GLenum target, GLint level, GLenum internalformat,
+        GLenum target, GLint level, GLint internalformat,
         GLsizei width, GLsizei height, GLint border,
         GLenum format, GLenum type, const GLvoid *pixels)
 {
diff --git a/opengl/libs/Android.mk b/opengl/libs/Android.mk
new file mode 100644
index 0000000..2ecc776
--- /dev/null
+++ b/opengl/libs/Android.mk
@@ -0,0 +1,53 @@
+LOCAL_PATH:= $(call my-dir)
+
+#
+# Build META EGL library
+#
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= 	\
+	EGL/egl.cpp 		\
+	EGL/gpu.cpp			\
+#
+
+LOCAL_SHARED_LIBRARIES += libcutils libutils libui
+LOCAL_LDLIBS := -lpthread -ldl
+LOCAL_MODULE:= libEGL
+
+# needed on sim build because of weird logging issues
+ifeq ($(TARGET_SIMULATOR),true)
+else
+    LOCAL_SHARED_LIBRARIES += libdl
+    # we need to access the Bionic private header <bionic_tls.h>
+    LOCAL_CFLAGS += -I$(LOCAL_PATH)/../../../../bionic/libc/private
+endif
+
+include $(BUILD_SHARED_LIBRARY)
+
+
+
+#
+# Build the wrapper OpenGL ES library
+#
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= 	\
+	GLES_CM/gl.cpp.arm 		\
+	GLES_CM/gl_logger.cpp 	\
+#
+
+LOCAL_SHARED_LIBRARIES += libcutils libutils libui libEGL
+LOCAL_LDLIBS := -lpthread -ldl
+LOCAL_MODULE:= libGLESv1_CM
+
+# needed on sim build because of weird logging issues
+ifeq ($(TARGET_SIMULATOR),true)
+else
+    LOCAL_SHARED_LIBRARIES += libdl
+    # we need to access the Bionic private header <bionic_tls.h>
+    LOCAL_CFLAGS += -I$(LOCAL_PATH)/../../../../bionic/libc/private
+endif
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/opengl/libGLES_CM/gl_wrapper.cpp b/opengl/libs/EGL/egl.cpp
similarity index 71%
rename from opengl/libGLES_CM/gl_wrapper.cpp
rename to opengl/libs/EGL/egl.cpp
index 3197535..687c8bc 100644
--- a/opengl/libGLES_CM/gl_wrapper.cpp
+++ b/opengl/libs/EGL/egl.cpp
@@ -27,31 +27,22 @@
 #include <linux/android_pmem.h>
 #endif
 
-#include <GLES/egl.h>
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include <GLES/gl.h>
+#include <GLES/glext.h>
 
 #include <cutils/log.h>
 #include <cutils/atomic.h>
 #include <cutils/properties.h>
 #include <cutils/memory.h>
 
-#include <utils/IMemory.h>
-#include <utils/KeyedVector.h>
-#include <utils/threads.h>
-#include <utils/IServiceManager.h>
-#include <utils/IPCThreadState.h>
-#include <utils/Parcel.h>
+#include <utils/RefBase.h>
 
-#include <ui/EGLDisplaySurface.h>
-#include <ui/ISurfaceComposer.h>
+#include "hooks.h"
+#include "egl_impl.h"
 
-#include "gl_logger.h"
 
-#undef NELEM
-
-#define GL_LOGGER                   0
-#define USE_SLOW_BINDING            0
-#define NELEM(x)                    (sizeof(x)/sizeof(*(x)))
-#define MAX_NUMBER_OF_GL_EXTENSIONS 32
 #define MAKE_CONFIG(_impl, _index)  ((EGLConfig)(((_impl)<<24) | (_index)))
 #define setError(_e, _r) setErrorEtc(__FUNCTION__, __LINE__, _e, _r)
 
@@ -59,26 +50,12 @@
 namespace android {
 // ----------------------------------------------------------------------------
 
-//  EGLDisplay are global, not attached to a given thread
-static const unsigned int NUM_DISPLAYS = 1;
-static const unsigned int IMPL_HARDWARE                 = 0;
-static const unsigned int IMPL_SOFTWARE                 = 1;
-static const unsigned int IMPL_HARDWARE_CONTEXT_LOST    = 2;
-static const unsigned int IMPL_SOFTWARE_CONTEXT_LOST    = 3;
-static const unsigned int IMPL_NO_CONTEXT               = 4;
-
-// ----------------------------------------------------------------------------
-
-struct gl_hooks_t;
-
-struct egl_connection_t
-{
-    void volatile *     dso;
-    gl_hooks_t *        hooks;
-    EGLint              major;
-    EGLint              minor;
-    int                 unavailable;
-};
+#define VERSION_MAJOR 1
+#define VERSION_MINOR 4
+static char const * const gVendorString     = "Android";
+static char const * const gVersionString    = "1.31 Android META-EGL";
+static char const * const gClientApiString  = "OpenGL ES";
+static char const * const gExtensionString  = "";
 
 template <int MAGIC>
 struct egl_object_t
@@ -103,7 +80,6 @@
         char const * version;
         char const * clientApi;
         char const * extensions;
-        char const * extensions_config;
     };
     strings_t   queryString[2];
 };
@@ -152,82 +128,45 @@
     EGLContext  ctx;
 };
 
-
-// GL / EGL hooks
-
-typedef void(*proc_t)();
-
-struct gl_hooks_t {
-    struct gl_t {
-        #define GL_ENTRY(_r, _api, ...) _r (*_api)(__VA_ARGS__);
-        #include "gl_entries.cpp"
-        #undef GL_ENTRY
-    } gl;
-    struct egl_t {
-        #define EGL_ENTRY(_r, _api, ...) _r (*_api)(__VA_ARGS__);
-        #include "egl_entries.cpp"
-        #undef EGL_ENTRY
-    } egl;
-    struct gl_ext_t {
-        void (*extensions[MAX_NUMBER_OF_GL_EXTENSIONS])(void);
-    } ext;
-};
-
-static char const * const gl_names[] = {
-    #define GL_ENTRY(_r, _api, ...) #_api,
-    #include "gl_entries.cpp"
-    #undef GL_ENTRY
-    NULL
-};
-
-static char const * const egl_names[] = {
-    #define EGL_ENTRY(_r, _api, ...) #_api,
-    #include "egl_entries.cpp"
-    #undef EGL_ENTRY
-    NULL
-};
-
 static void gl_unimplemented() {
     LOGE("called unimplemented OpenGL ES API");
 }
 
 // ----------------------------------------------------------------------------
+// GL / EGL hooks
+// ----------------------------------------------------------------------------
 
-static egl_connection_t gEGLImpl[2];
+#undef GL_ENTRY
+#undef EGL_ENTRY
+#define GL_ENTRY(_r, _api, ...) #_api,
+#define EGL_ENTRY(_r, _api, ...) #_api,
+
+static char const * const gl_names[] = {
+    #include "gl_entries.in"
+    NULL
+};
+
+static char const * const egl_names[] = {
+    #include "egl_entries.in"
+    NULL
+};
+
+#undef GL_ENTRY
+#undef EGL_ENTRY
+
+// ----------------------------------------------------------------------------
+
+egl_connection_t gEGLImpl[2];
 static egl_display_t gDisplay[NUM_DISPLAYS];
-static gl_hooks_t gHooks[5];
 static pthread_mutex_t gThreadLocalStorageKeyMutex = PTHREAD_MUTEX_INITIALIZER;
 static pthread_key_t gEGLThreadLocalStorageKey = -1;
 
 // ----------------------------------------------------------------------------
 
-#if defined(HAVE_ANDROID_OS) && !USE_SLOW_BINDING && !GL_LOGGER
+gl_hooks_t gHooks[IMPL_NUM_IMPLEMENTATIONS];
+pthread_key_t gGLWrapperKey = -1;
 
-/* special private C library header */
-#include <bionic_tls.h>
-// We have a dedicated TLS slot in bionic
-static inline void setGlThreadSpecific(gl_hooks_t const *value) {
-    ((uint32_t *)__get_tls())[TLS_SLOT_OPENGL_API] = (uint32_t)value;
-}
-static gl_hooks_t const* getGlThreadSpecific() {
-    gl_hooks_t const* hooks = (gl_hooks_t const *)(((unsigned const *)__get_tls())[TLS_SLOT_OPENGL_API]);
-    if (hooks) return hooks;
-    return &gHooks[IMPL_NO_CONTEXT];
-}
-
-#else
-
-static pthread_key_t gGLWrapperKey = -1;
-static inline void setGlThreadSpecific(gl_hooks_t const *value) {
-    pthread_setspecific(gGLWrapperKey, value);
-}
-static gl_hooks_t const* getGlThreadSpecific() {
-    gl_hooks_t const* hooks =  static_cast<gl_hooks_t*>(pthread_getspecific(gGLWrapperKey));
-    if (hooks) return hooks;
-    return &gHooks[IMPL_NO_CONTEXT];
-}
-
-#endif
+// ----------------------------------------------------------------------------
 
 static __attribute__((noinline))
 const char *egl_strerror(EGLint err)
@@ -322,170 +261,14 @@
     return tls->ctx;
 }
 
-/*****************************************************************************/
-
-/*
- * we provide our own allocators for the GPU regions, these
- * allocators go through surfaceflinger 
- */
-
-static Mutex                            gRegionsLock;
-static request_gpu_t                    gRegions;
-static sp<ISurfaceComposer>             gSurfaceManager;
-ISurfaceComposer*                       GLES_localSurfaceManager = 0;
-
-const sp<ISurfaceComposer>& getSurfaceFlinger()
-{
-    Mutex::Autolock _l(gRegionsLock);
-
-    /*
-     * There is a little bit of voodoo magic here. We want to access
-     * surfaceflinger for allocating GPU regions, however, when we are
-     * running as part of surfaceflinger, we want to bypass the
-     * service manager because surfaceflinger might not be registered yet.
-     * SurfaceFlinger will populate "GLES_localSurfaceManager" with its
-     * own address, so we can just use that.
-     */
-    if (gSurfaceManager == 0) {
-        if (GLES_localSurfaceManager) {
-            // we're running in SurfaceFlinger's context
-            gSurfaceManager =  GLES_localSurfaceManager;
-        } else {
-            // we're a remote process or not part of surfaceflinger,
-            // go through the service manager
-            sp<IServiceManager> sm = defaultServiceManager();
-            if (sm != NULL) {
-                sp<IBinder> binder = sm->getService(String16("SurfaceFlinger"));
-                gSurfaceManager = interface_cast<ISurfaceComposer>(binder);
-            }
-        }
-    }
-    return gSurfaceManager;
-}
-
-class GPURevokeRequester : public BnGPUCallback
-{
-public:
-    virtual void gpuLost() {
-        LOGD("CONTEXT_LOST: Releasing GPU upon request from SurfaceFlinger.");
-        gEGLImpl[IMPL_HARDWARE].hooks = &gHooks[IMPL_HARDWARE_CONTEXT_LOST];
-    }
-};
-
-static sp<GPURevokeRequester> gRevokerCallback;
-
-
-static request_gpu_t* gpu_acquire(void* user)
-{
-    sp<ISurfaceComposer> server( getSurfaceFlinger() );
-
-    Mutex::Autolock _l(gRegionsLock);
-    if (server == NULL) {
-        return 0;
-    }
-    
-    ISurfaceComposer::gpu_info_t info;
-    
-    if (gRevokerCallback == 0)
-        gRevokerCallback = new GPURevokeRequester();
-
-    status_t err = server->requestGPU(gRevokerCallback, &info);
-    if (err != NO_ERROR) {
-        LOGD("requestGPU returned %d", err);
-        return 0;
-    }
-
-    bool failed = false;
-    request_gpu_t* gpu = &gRegions;
-    memset(gpu, 0, sizeof(*gpu));
-    
-    if (info.regs != 0) {
-        sp<IMemoryHeap> heap(info.regs->getMemory());
-        if (heap != 0) {
-            int fd = heap->heapID();
-            gpu->regs.fd = fd;
-            gpu->regs.base = info.regs->pointer(); 
-            gpu->regs.size = info.regs->size(); 
-            gpu->regs.user = info.regs.get();
-#if HAVE_ANDROID_OS
-            struct pmem_region region;
-            if (ioctl(fd, PMEM_GET_PHYS, &region) >= 0)
-                gpu->regs.phys = (void*)region.offset;
-#endif
-            info.regs->incStrong(gpu);
-        } else {
-            LOGE("GPU register handle %p is invalid!", info.regs.get());
-            failed = true;
-        }
-    }
-
-    for (size_t i=0 ; i<info.count && !failed ; i++) {
-        sp<IMemory>& region(info.regions[i].region);
-        if (region != 0) {
-            sp<IMemoryHeap> heap(region->getMemory());
-            if (heap != 0) {
-                const int fd = heap->heapID();
-                gpu->gpu[i].fd = fd;
-                gpu->gpu[i].base = region->pointer(); 
-                gpu->gpu[i].size = region->size(); 
-                gpu->gpu[i].user = region.get();
-                gpu->gpu[i].offset = info.regions[i].reserved;
-#if HAVE_ANDROID_OS
-                struct pmem_region reg;
-                if (ioctl(fd, PMEM_GET_PHYS, &reg) >= 0)
-                    gpu->gpu[i].phys = (void*)reg.offset;
-#endif
-                region->incStrong(gpu);
-            } else {
-                LOGE("GPU region handle [%d, %p] is invalid!", i, region.get());
-                failed = true;
-            }
-        }
-    }
-    
-    if (failed) {
-        // something went wrong, clean up everything!
-        if (gpu->regs.user) {
-            static_cast<IMemory*>(gpu->regs.user)->decStrong(gpu);
-            for (size_t i=0 ; i<info.count ; i++) {
-                if (gpu->gpu[i].user) {
-                    static_cast<IMemory*>(gpu->gpu[i].user)->decStrong(gpu);
-                }
-            }
-        }
-    }
-    
-    gpu->count = info.count;
-    return gpu;
-}
-
-static int gpu_release(void*, request_gpu_t* gpu)
-{
-    sp<IMemory> regs;
-
-    { // scope for lock
-        Mutex::Autolock _l(gRegionsLock);
-        regs = static_cast<IMemory*>(gpu->regs.user);   
-        gpu->regs.user = 0;
-        if (regs != 0) regs->decStrong(gpu);
-        
-        for (int i=0 ; i<gpu->count ; i++) {
-            sp<IMemory> r(static_cast<IMemory*>(gpu->gpu[i].user));
-            gpu->gpu[i].user = 0;
-            if (r != 0) r->decStrong(gpu);
-        }
-    }
-    
-    // there is a special transaction to relinquish the GPU
-    // (it will happen automatically anyway if we don't do this)
-    Parcel data, reply;
-    // NOTE: this transaction does not require an interface token
-    regs->asBinder()->transact(1000, data, &reply);
-    return 1;
-}
 
 /*****************************************************************************/
 
+class ISurfaceComposer;
+const sp<ISurfaceComposer>& getSurfaceFlinger();
+request_gpu_t* gpu_acquire(void* user);
+int gpu_release(void*, request_gpu_t* gpu);
+
 static __attribute__((noinline))
 void *load_driver(const char* driver, gl_hooks_t* hooks)
 {
@@ -576,18 +359,12 @@
     return c0<c1 ? -1 : (c0>c1 ? 1 : 0);
 }
 
-static char const * const gVendorString     = "Android";
-static char const * const gVersionString    = "1.3 Android META-EGL";
-static char const * const gClientApiString  = "OpenGL ES";
-
 struct extention_map_t {
     const char* name;
-    void (*address)(void);
+    __eglMustCastToProperFunctionPointerType address;
 };
 
 static const extention_map_t gExtentionMap[] = {
-    { "eglSwapRectangleANDROID",         (void(*)())&eglSwapRectangleANDROID },
-    { "eglQueryStringConfigANDROID",     (void(*)())&eglQueryStringConfigANDROID },
 };
 
 static extention_map_t gGLExtentionMap[MAX_NUMBER_OF_GL_EXTENSIONS];
@@ -604,109 +381,18 @@
 }
 
 // ----------------------------------------------------------------------------
-}; // namespace android
-// ----------------------------------------------------------------------------
-
-using namespace android;
-
-
-// ----------------------------------------------------------------------------
-// extensions for the framework
-// ----------------------------------------------------------------------------
-
-void glColorPointerBounds(GLint size, GLenum type, GLsizei stride,
-        const GLvoid *ptr, GLsizei count) {
-    glColorPointer(size, type, stride, ptr);
-}
-void glNormalPointerBounds(GLenum type, GLsizei stride,
-        const GLvoid *pointer, GLsizei count) {
-    glNormalPointer(type, stride, pointer);
-}
-void glTexCoordPointerBounds(GLint size, GLenum type,
-        GLsizei stride, const GLvoid *pointer, GLsizei count) {
-    glTexCoordPointer(size, type, stride, pointer);
-}
-void glVertexPointerBounds(GLint size, GLenum type,
-        GLsizei stride, const GLvoid *pointer, GLsizei count) {
-    glVertexPointer(size, type, stride, pointer);
-}
-
-
-// ----------------------------------------------------------------------------
-// Actual GL wrappers
-// ----------------------------------------------------------------------------
-
-#if __OPTIMIZE__ && defined(__arm__) && !defined(__thumb__) && !USE_SLOW_BINDING && !GL_LOGGER
-
-    #define API_ENTRY(_api) __attribute__((naked)) _api
-    #define CALL_GL_API(_api, ...)                              \
-         asm volatile(                                          \
-            "mov   r12, #0xFFFF0FFF   \n"                       \
-            "ldr   r12, [r12, #-15]   \n"                       \
-            "ldr   r12, [r12, %[tls]] \n"                       \
-            "cmp   r12, #0            \n"                       \
-            "ldrne pc,  [r12, %[api]] \n"                       \
-            "bx    lr                 \n"                       \
-            :                                                   \
-            : [tls] "J"(TLS_SLOT_OPENGL_API*4),                 \
-              [api] "J"(__builtin_offsetof(gl_hooks_t, gl._api))    \
-            :                                                   \
-            );
-    
-    #define CALL_GL_API_RETURN(_api, ...) \
-        CALL_GL_API(_api, __VA_ARGS__) \
-        return 0; // placate gcc's warnings. never reached.
-
-#else
-
-    #define API_ENTRY(_api) _api
-    #if GL_LOGGER
-
-        #define CALL_GL_API(_api, ...)          \
-            gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl; \
-            log_##_api(__VA_ARGS__); \
-            _c->_api(__VA_ARGS__);
-        
-        #define CALL_GL_API_RETURN(_api, ...)   \
-            gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl; \
-            log_##_api(__VA_ARGS__); \
-            return _c->_api(__VA_ARGS__)
-
-    #else
-
-        #define CALL_GL_API(_api, ...)          \
-            gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl; \
-            _c->_api(__VA_ARGS__);
-        
-        #define CALL_GL_API_RETURN(_api, ...)   \
-            gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl; \
-            return _c->_api(__VA_ARGS__)
-
-    #endif
-
-#endif
-
-#include "gl_api.cpp"
-
-#undef API_ENTRY
-#undef CALL_GL_API
-#undef CALL_GL_API_RETURN
-
-// ----------------------------------------------------------------------------
-namespace android {
-// ----------------------------------------------------------------------------
 
 static int gl_context_lost() {
-    setGlThreadSpecific(&gHooks[IMPL_HARDWARE_CONTEXT_LOST]);
+    setGlThreadSpecific(&gHooks[IMPL_CONTEXT_LOST]);
     return 0;
 }
 static int egl_context_lost() {
-    setGlThreadSpecific(&gHooks[IMPL_HARDWARE_CONTEXT_LOST]);
+    setGlThreadSpecific(&gHooks[IMPL_CONTEXT_LOST]);
     return EGL_FALSE;
 }
 static EGLBoolean egl_context_lost_swap_buffers(void*, void*) {
     usleep(100000); // don't use all the CPU
-    setGlThreadSpecific(&gHooks[IMPL_HARDWARE_CONTEXT_LOST]);
+    setGlThreadSpecific(&gHooks[IMPL_CONTEXT_LOST]);
     return EGL_FALSE;
 }
 static GLint egl_context_lost_get_error() {
@@ -721,11 +407,14 @@
 }
 static void early_egl_init(void) 
 {
-#if !defined(HAVE_ANDROID_OS) || USE_SLOW_BINDING || GL_LOGGER
+#if !USE_FAST_TLS_KEY
     pthread_key_create(&gGLWrapperKey, NULL);
 #endif
     uint32_t addr = (uint32_t)((void*)gl_no_context);
-    android_memset32((uint32_t*)(void*)&gHooks[IMPL_NO_CONTEXT], addr, sizeof(gHooks[IMPL_NO_CONTEXT]));
+    android_memset32(
+            (uint32_t*)(void*)&gHooks[IMPL_NO_CONTEXT], 
+            addr, 
+            sizeof(gHooks[IMPL_NO_CONTEXT]));
     setGlThreadSpecific(&gHooks[IMPL_NO_CONTEXT]);
 }
 
@@ -802,25 +491,12 @@
     return EGL_TRUE;
 }
 
-static void add_extension(egl_display_t* dp, char const*& p, const char* ext)
-{
-    if (!strstr(p, ext)) {
-        p = (char const*)realloc((void*)p, strlen(p) + 1 + strlen(ext) + 1);
-        strcat((char*)p, " ");
-        strcat((char*)p, ext);
-    }
-    if (!strstr(dp->extensionsString, ext)) {
-        char const*& es = dp->extensionsString;
-        es = (char const*)realloc((void*)es, strlen(es) + 1 + strlen(ext) + 1);
-        strcat((char*)es, " ");
-        strcat((char*)es, ext);
-    }    
-}
-
 // ----------------------------------------------------------------------------
 }; // namespace android
 // ----------------------------------------------------------------------------
 
+using namespace android;
+
 EGLDisplay eglGetDisplay(NativeDisplayType display)
 {
     if (sEarlyInitState) {
@@ -854,38 +530,32 @@
         property_get("debug.egl.hw", value, "1");
         if (atoi(value) != 0) {
             cnx->hooks = &gHooks[IMPL_HARDWARE];
-            property_get("debug.egl.profiler", value, "0");
-            if (atoi(value) == 0) {
-                cnx->dso = load_driver("libhgl.so", cnx->hooks);
-            } else {
-                LOGW("Using instrumented h/w OpenGL ES library");
-                cnx->dso = load_driver("libhgld.so", cnx->hooks);
-            }
+            cnx->dso = load_driver("libhgl.so", cnx->hooks);
         } else {
             LOGD("3D hardware acceleration is disabled");
         }
     }
     if (cnx->dso && d->dpys[IMPL_HARDWARE]==EGL_NO_DISPLAY) {
         android_memset32(
-                (uint32_t*)(void*)&gHooks[IMPL_HARDWARE_CONTEXT_LOST].gl,
+                (uint32_t*)(void*)&gHooks[IMPL_CONTEXT_LOST].gl,
                 (uint32_t)((void*)gl_context_lost),
-                sizeof(gHooks[IMPL_HARDWARE_CONTEXT_LOST].gl));
+                sizeof(gHooks[IMPL_CONTEXT_LOST].gl));
         android_memset32(
-                (uint32_t*)(void*)&gHooks[IMPL_HARDWARE_CONTEXT_LOST].egl,
+                (uint32_t*)(void*)&gHooks[IMPL_CONTEXT_LOST].egl,
                 (uint32_t)((void*)egl_context_lost),
-                sizeof(gHooks[IMPL_HARDWARE_CONTEXT_LOST].egl));
+                sizeof(gHooks[IMPL_CONTEXT_LOST].egl));
         android_memset32(
-                (uint32_t*)(void*)&gHooks[IMPL_HARDWARE_CONTEXT_LOST].ext,
+                (uint32_t*)(void*)&gHooks[IMPL_CONTEXT_LOST].ext,
                 (uint32_t)((void*)ext_context_lost),
-                sizeof(gHooks[IMPL_HARDWARE_CONTEXT_LOST].ext));
+                sizeof(gHooks[IMPL_CONTEXT_LOST].ext));
 
-        gHooks[IMPL_HARDWARE_CONTEXT_LOST].egl.eglSwapBuffers =
+        gHooks[IMPL_CONTEXT_LOST].egl.eglSwapBuffers =
                 egl_context_lost_swap_buffers;
         
-        gHooks[IMPL_HARDWARE_CONTEXT_LOST].egl.eglGetError =
+        gHooks[IMPL_CONTEXT_LOST].egl.eglGetError =
                 egl_context_lost_get_error;
 
-        gHooks[IMPL_HARDWARE_CONTEXT_LOST].egl.eglTerminate =
+        gHooks[IMPL_CONTEXT_LOST].egl.eglTerminate =
                 gHooks[IMPL_HARDWARE].egl.eglTerminate;
         
         d->dpys[IMPL_HARDWARE] = cnx->hooks->egl.eglGetDisplay(display);
@@ -913,8 +583,8 @@
     if (!dp) return setError(EGL_BAD_DISPLAY, EGL_FALSE);
 
     if (android_atomic_inc(&dp->refs) > 0) {
-        if (major != NULL) *major = 1;
-        if (minor != NULL) *minor = 2;
+        if (major != NULL) *major = VERSION_MAJOR;
+        if (minor != NULL) *minor = VERSION_MINOR;
         return EGL_TRUE;
     }
     
@@ -923,7 +593,7 @@
     // initialize each EGL and
     // build our own extension string first, based on the extension we know
     // and the extension supported by our client implementation
-    dp->extensionsString = strdup("EGL_ANDROID_query_string_config");
+    dp->extensionsString = strdup(gExtensionString);
     for (int i=0 ; i<2 ; i++) {
         egl_connection_t* const cnx = &gEGLImpl[i];
         cnx->major = -1;
@@ -947,54 +617,16 @@
             dp->queryString[i].clientApi =
                 cnx->hooks->egl.eglQueryString(dp->dpys[i], EGL_CLIENT_APIS);
 
-            // Dynamically insert extensions we know about
-            if (cnx->hooks->egl.eglSwapRectangleANDROID)
-                add_extension(dp, dp->queryString[i].extensions,
-                        "EGL_ANDROID_swap_rectangle");
-
-            if (cnx->hooks->egl.eglQueryStringConfigANDROID)
-                add_extension(dp, dp->queryString[i].extensions,
-                        "EGL_ANDROID_query_string_config");
         } else {
             LOGD("%d: eglInitialize() failed (%s)", 
                     i, egl_strerror(cnx->hooks->egl.eglGetError()));
         }
     }
 
-    // Build the extension list that depends on the current config.
-    // It is the intersection of our extension list and the
-    // underlying EGL's extensions list
     EGLBoolean res = EGL_FALSE;
     for (int i=0 ; i<2 ; i++) {
         egl_connection_t* const cnx = &gEGLImpl[i];
         if (cnx->dso && cnx->major>=0 && cnx->minor>=0) {
-            char const* const their_extensions = dp->queryString[i].extensions;            
-            char* our_extensions = strdup(dp->extensionsString);
-            char* const our_extensions_org = our_extensions;
-            char* extensions_config = (char*)calloc(strlen(our_extensions)+2, 1);
-            char* p;
-            do {
-                p = strchr(our_extensions, ' ');
-                if (p)  *p++ = 0;
-                else    p = strchr(our_extensions, 0);
-                if (strstr(their_extensions, our_extensions)) {
-                    strcat(extensions_config, our_extensions);
-                    strcat(extensions_config, " ");
-                }
-                our_extensions = p;
-            } while (*p);
-            free((void*)our_extensions_org);
-
-            // remove the trailing white space
-            if (extensions_config[0] != 0) {
-                size_t l = strlen(extensions_config) - 1; // new size
-                extensions_config[l] = 0; // remove the trailing white space
-                extensions_config = (char*)realloc(extensions_config, l+1);
-            } else {
-                extensions_config = (char*)realloc(extensions_config, 1);
-            }
-            dp->queryString[i].extensions_config = extensions_config;
-
             EGLint n;
             if (cnx->hooks->egl.eglGetConfigs(dp->dpys[i], 0, 0, &n)) {
                 dp->configs[i] = (EGLConfig*)malloc(sizeof(EGLConfig)*n);
@@ -1016,8 +648,8 @@
     }
 
     if (res == EGL_TRUE) {
-        if (major != NULL) *major = 1;
-        if (minor != NULL) *minor = 2;
+        if (major != NULL) *major = VERSION_MAJOR;
+        if (minor != NULL) *minor = VERSION_MINOR;
         return EGL_TRUE;
     }
     return setError(EGL_NOT_INITIALIZED, EGL_FALSE);
@@ -1042,7 +674,6 @@
              * threads around). */
             
             free(dp->configs[i]);
-            free((void*)dp->queryString[i].extensions_config);
             free((void*)dp->queryString[i].extensions);
             dp->numConfigs[i] = 0;
             dp->dpys[i] = EGL_NO_DISPLAY;
@@ -1486,7 +1117,7 @@
 
 void (*eglGetProcAddress(const char *procname))()
 {
-    void (*addr)();
+    __eglMustCastToProperFunctionPointerType addr;
     addr = findProcAddress(procname, gExtentionMap, NELEM(gExtentionMap));
     if (addr) return addr;
 
@@ -1570,7 +1201,7 @@
         case EGL_VERSION:
             return gVersionString;
         case EGL_EXTENSIONS:
-            return dp->extensionsString;
+            return gExtensionString;
         case EGL_CLIENT_APIS:
             return gClientApiString;
     }
@@ -1730,34 +1361,3 @@
     }
     return setError(EGL_BAD_CONFIG, EGL_NO_SURFACE);
 }
-
-// ----------------------------------------------------------------------------
-// Android extentions
-// ----------------------------------------------------------------------------
-
-EGLBoolean eglSwapRectangleANDROID(
-        EGLDisplay dpy, EGLSurface draw,
-        EGLint l, EGLint t, EGLint w, EGLint h)
-{    
-    if (!validate_display_surface(dpy, draw))
-        return EGL_FALSE;    
-    egl_display_t const * const dp = get_display(dpy);
-    egl_surface_t const * const s = get_surface(draw);
-    if (s->cnx->hooks->egl.eglSwapRectangleANDROID) {
-        return s->cnx->hooks->egl.eglSwapRectangleANDROID(
-                dp->dpys[s->impl], s->surface, l, t, w, h);
-    }
-    return setError(EGL_BAD_SURFACE, EGL_FALSE);
-}
-
-const char* eglQueryStringConfigANDROID(
-        EGLDisplay dpy, EGLConfig config, EGLint name)
-{
-    egl_display_t const* dp = 0;
-    int i=0, index=0;
-    egl_connection_t* cnx = validate_display_config(dpy, config, dp, i, index);
-    if (cnx) {
-        return dp->queryString[i].extensions_config;
-    }
-    return setError(EGL_BAD_PARAMETER, (const char *)0);
-}
diff --git a/opengl/libs/EGL/gpu.cpp b/opengl/libs/EGL/gpu.cpp
new file mode 100644
index 0000000..3f9fd63
--- /dev/null
+++ b/opengl/libs/EGL/gpu.cpp
@@ -0,0 +1,212 @@
+/* 
+ ** Copyright 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 "EGL"
+
+#include <ctype.h>
+#include <string.h>
+#include <errno.h>
+
+#include <sys/ioctl.h>
+
+#if HAVE_ANDROID_OS
+#include <linux/android_pmem.h>
+#endif
+
+#include <cutils/log.h>
+#include <cutils/properties.h>
+
+#include <utils/IMemory.h>
+#include <utils/threads.h>
+#include <utils/IServiceManager.h>
+#include <utils/IPCThreadState.h>
+#include <utils/Parcel.h>
+
+#include <ui/EGLDisplaySurface.h>
+#include <ui/ISurfaceComposer.h>
+
+#include "hooks.h"
+#include "egl_impl.h"
+
+// ----------------------------------------------------------------------------
+namespace android {
+// ----------------------------------------------------------------------------
+
+/*
+ * we provide our own allocators for the GPU regions, these
+ * allocators go through surfaceflinger 
+ */
+
+static Mutex                            gRegionsLock;
+static request_gpu_t                    gRegions;
+static sp<ISurfaceComposer>             gSurfaceManager;
+ISurfaceComposer*                       GLES_localSurfaceManager = 0;
+
+extern egl_connection_t gEGLImpl[2];
+
+const sp<ISurfaceComposer>& getSurfaceFlinger()
+{
+    Mutex::Autolock _l(gRegionsLock);
+
+    /*
+     * There is a little bit of voodoo magic here. We want to access
+     * surfaceflinger for allocating GPU regions, however, when we are
+     * running as part of surfaceflinger, we want to bypass the
+     * service manager because surfaceflinger might not be registered yet.
+     * SurfaceFlinger will populate "GLES_localSurfaceManager" with its
+     * own address, so we can just use that.
+     */
+    if (gSurfaceManager == 0) {
+        if (GLES_localSurfaceManager) {
+            // we're running in SurfaceFlinger's context
+            gSurfaceManager =  GLES_localSurfaceManager;
+        } else {
+            // we're a remote process or not part of surfaceflinger,
+            // go through the service manager
+            sp<IServiceManager> sm = defaultServiceManager();
+            if (sm != NULL) {
+                sp<IBinder> binder = sm->getService(String16("SurfaceFlinger"));
+                gSurfaceManager = interface_cast<ISurfaceComposer>(binder);
+            }
+        }
+    }
+    return gSurfaceManager;
+}
+
+class GPURevokeRequester : public BnGPUCallback
+{
+public:
+    virtual void gpuLost() {
+        LOGD("CONTEXT_LOST: Releasing GPU upon request from SurfaceFlinger.");
+        gEGLImpl[IMPL_HARDWARE].hooks = &gHooks[IMPL_CONTEXT_LOST];
+    }
+};
+
+static sp<GPURevokeRequester> gRevokerCallback;
+
+
+request_gpu_t* gpu_acquire(void* user)
+{
+    sp<ISurfaceComposer> server( getSurfaceFlinger() );
+
+    Mutex::Autolock _l(gRegionsLock);
+    if (server == NULL) {
+        return 0;
+    }
+    
+    ISurfaceComposer::gpu_info_t info;
+    
+    if (gRevokerCallback == 0)
+        gRevokerCallback = new GPURevokeRequester();
+
+    status_t err = server->requestGPU(gRevokerCallback, &info);
+    if (err != NO_ERROR) {
+        LOGD("requestGPU returned %d", err);
+        return 0;
+    }
+
+    bool failed = false;
+    request_gpu_t* gpu = &gRegions;
+    memset(gpu, 0, sizeof(*gpu));
+    
+    if (info.regs != 0) {
+        sp<IMemoryHeap> heap(info.regs->getMemory());
+        if (heap != 0) {
+            int fd = heap->heapID();
+            gpu->regs.fd = fd;
+            gpu->regs.base = info.regs->pointer(); 
+            gpu->regs.size = info.regs->size(); 
+            gpu->regs.user = info.regs.get();
+#if HAVE_ANDROID_OS
+            struct pmem_region region;
+            if (ioctl(fd, PMEM_GET_PHYS, &region) >= 0)
+                gpu->regs.phys = (void*)region.offset;
+#endif
+            info.regs->incStrong(gpu);
+        } else {
+            LOGE("GPU register handle %p is invalid!", info.regs.get());
+            failed = true;
+        }
+    }
+
+    for (size_t i=0 ; i<info.count && !failed ; i++) {
+        sp<IMemory>& region(info.regions[i].region);
+        if (region != 0) {
+            sp<IMemoryHeap> heap(region->getMemory());
+            if (heap != 0) {
+                const int fd = heap->heapID();
+                gpu->gpu[i].fd = fd;
+                gpu->gpu[i].base = region->pointer(); 
+                gpu->gpu[i].size = region->size(); 
+                gpu->gpu[i].user = region.get();
+                gpu->gpu[i].offset = info.regions[i].reserved;
+#if HAVE_ANDROID_OS
+                struct pmem_region reg;
+                if (ioctl(fd, PMEM_GET_PHYS, &reg) >= 0)
+                    gpu->gpu[i].phys = (void*)reg.offset;
+#endif
+                region->incStrong(gpu);
+            } else {
+                LOGE("GPU region handle [%d, %p] is invalid!", i, region.get());
+                failed = true;
+            }
+        }
+    }
+    
+    if (failed) {
+        // something went wrong, clean up everything!
+        if (gpu->regs.user) {
+            static_cast<IMemory*>(gpu->regs.user)->decStrong(gpu);
+            for (size_t i=0 ; i<info.count ; i++) {
+                if (gpu->gpu[i].user) {
+                    static_cast<IMemory*>(gpu->gpu[i].user)->decStrong(gpu);
+                }
+            }
+        }
+    }
+    
+    gpu->count = info.count;
+    return gpu;
+}
+
+int gpu_release(void*, request_gpu_t* gpu)
+{
+    sp<IMemory> regs;
+
+    { // scope for lock
+        Mutex::Autolock _l(gRegionsLock);
+        regs = static_cast<IMemory*>(gpu->regs.user);   
+        gpu->regs.user = 0;
+        if (regs != 0) regs->decStrong(gpu);
+        
+        for (int i=0 ; i<gpu->count ; i++) {
+            sp<IMemory> r(static_cast<IMemory*>(gpu->gpu[i].user));
+            gpu->gpu[i].user = 0;
+            if (r != 0) r->decStrong(gpu);
+        }
+    }
+    
+    // there is a special transaction to relinquish the GPU
+    // (it will happen automatically anyway if we don't do this)
+    Parcel data, reply;
+    // NOTE: this transaction does not require an interface token
+    regs->asBinder()->transact(1000, data, &reply);
+    return 1;
+}
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+// ----------------------------------------------------------------------------
diff --git a/opengl/libs/GLES_CM/gl.cpp b/opengl/libs/GLES_CM/gl.cpp
new file mode 100644
index 0000000..865cf44
--- /dev/null
+++ b/opengl/libs/GLES_CM/gl.cpp
@@ -0,0 +1,116 @@
+/* 
+ ** Copyright 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 "GLES_CM"
+
+#include <ctype.h>
+#include <string.h>
+#include <errno.h>
+
+#include <sys/ioctl.h>
+
+#include <GLES/gl.h>
+#include <GLES/glext.h>
+
+#include <cutils/log.h>
+#include <cutils/properties.h>
+
+#include "hooks.h"
+
+using namespace android;
+
+// ----------------------------------------------------------------------------
+// extensions for the framework
+// ----------------------------------------------------------------------------
+
+void glColorPointerBounds(GLint size, GLenum type, GLsizei stride,
+        const GLvoid *ptr, GLsizei count) {
+    glColorPointer(size, type, stride, ptr);
+}
+void glNormalPointerBounds(GLenum type, GLsizei stride,
+        const GLvoid *pointer, GLsizei count) {
+    glNormalPointer(type, stride, pointer);
+}
+void glTexCoordPointerBounds(GLint size, GLenum type,
+        GLsizei stride, const GLvoid *pointer, GLsizei count) {
+    glTexCoordPointer(size, type, stride, pointer);
+}
+void glVertexPointerBounds(GLint size, GLenum type,
+        GLsizei stride, const GLvoid *pointer, GLsizei count) {
+    glVertexPointer(size, type, stride, pointer);
+}
+
+// ----------------------------------------------------------------------------
+// Actual GL entry-points
+// ----------------------------------------------------------------------------
+
+#if GL_LOGGER
+#   include "gl_logger.h"
+#   define GL_LOGGER_IMPL(_x) _x
+#else
+#   define GL_LOGGER_IMPL(_x)
+#endif
+
+#undef API_ENTRY
+#undef CALL_GL_API
+#undef CALL_GL_API_RETURN
+
+#if USE_FAST_TLS_KEY
+
+    #define API_ENTRY(_api) __attribute__((naked)) _api
+
+    #define CALL_GL_API(_api, ...)                              \
+         asm volatile(                                          \
+            "mov   r12, #0xFFFF0FFF   \n"                       \
+            "ldr   r12, [r12, #-15]   \n"                       \
+            "ldr   r12, [r12, %[tls]] \n"                       \
+            "cmp   r12, #0            \n"                       \
+            "ldrne pc,  [r12, %[api]] \n"                       \
+            "bx    lr                 \n"                       \
+            :                                                   \
+            : [tls] "J"(TLS_SLOT_OPENGL_API*4),                 \
+              [api] "J"(__builtin_offsetof(gl_hooks_t, gl._api))    \
+            :                                                   \
+            );
+    
+    #define CALL_GL_API_RETURN(_api, ...) \
+        CALL_GL_API(_api, __VA_ARGS__) \
+        return 0; // placate gcc's warnings. never reached.
+
+#else
+
+    #define API_ENTRY(_api) _api
+
+    #define CALL_GL_API(_api, ...)                                      \
+        gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl; \
+        GL_LOGGER_IMPL( log_##_api(__VA_ARGS__); )                      \
+        _c->_api(__VA_ARGS__)
+    
+    #define CALL_GL_API_RETURN(_api, ...)                               \
+        gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl; \
+        GL_LOGGER_IMPL( log_##_api(__VA_ARGS__); )                      \
+        return _c->_api(__VA_ARGS__)
+
+#endif
+
+extern "C" {
+#include "gl_api.in"
+}
+
+#undef API_ENTRY
+#undef CALL_GL_API
+#undef CALL_GL_API_RETURN
+
diff --git a/opengl/libGLES_CM/gl_api.cpp b/opengl/libs/GLES_CM/gl_api.in
similarity index 98%
rename from opengl/libGLES_CM/gl_api.cpp
rename to opengl/libs/GLES_CM/gl_api.in
index ed3bdaa..9234ef2 100644
--- a/opengl/libGLES_CM/gl_api.cpp
+++ b/opengl/libs/GLES_CM/gl_api.in
@@ -415,7 +415,7 @@
     CALL_GL_API(glTexEnvxv, target, pname, params);
 }
 
-void API_ENTRY(glTexImage2D)(  GLenum target, GLint level, GLenum internalformat,
+void API_ENTRY(glTexImage2D)(  GLenum target, GLint level, GLint internalformat,
                     GLsizei width, GLsizei height, GLint border, GLenum format,
                     GLenum type, const GLvoid *pixels) {
     CALL_GL_API(glTexImage2D, target, level, internalformat, width, height,
diff --git a/opengl/libGLES_CM/gl_logger.cpp b/opengl/libs/GLES_CM/gl_logger.cpp
similarity index 99%
rename from opengl/libGLES_CM/gl_logger.cpp
rename to opengl/libs/GLES_CM/gl_logger.cpp
index 14b5a39..27be5c9 100644
--- a/opengl/libGLES_CM/gl_logger.cpp
+++ b/opengl/libs/GLES_CM/gl_logger.cpp
@@ -23,7 +23,10 @@
 
 #include <sys/ioctl.h>
 
-#include <GLES/egl.h>
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include <GLES/gl.h>
+#include <GLES/glext.h>
 
 #include <cutils/log.h>
 #include <cutils/atomic.h>
@@ -33,13 +36,13 @@
 
 #include "gl_logger.h"
 
+#undef NELEM
+#define NELEM(x) (sizeof(x)/sizeof(*(x)))
+
 // ----------------------------------------------------------------------------
 namespace android {
 // ----------------------------------------------------------------------------
 
-#undef NELEM
-#define NELEM(x) (sizeof(x)/sizeof(*(x)))
-
 template<typename T>
 static int binarySearch(T const sortedArray[], int first, int last, EGLint key)
 {
@@ -226,12 +229,6 @@
     int mNumParams;
 };
 
-// ----------------------------------------------------------------------------
-}; // namespace android
-// ----------------------------------------------------------------------------
-
-using namespace android;
-
 #define API_ENTRY(api)                      log_##api
 #define CALL_GL_API(_x, ...)
 #define CALL_GL_API_RETURN(_x, ...)         return(0);
@@ -785,7 +782,7 @@
     GLLog("glTexEnvxv") << GLLogEnum(target) << GLLogEnum(pname) << GLLogBuffer<GLfixed>(params);
 }
 
-void API_ENTRY(glTexImage2D)(  GLenum target, GLint level, GLenum internalformat,
+void API_ENTRY(glTexImage2D)(  GLenum target, GLint level, GLint internalformat,
                     GLsizei width, GLsizei height, GLint border, GLenum format,
                     GLenum type, const GLvoid *pixels) {
     CALL_GL_API(glTexImage2D, target, level, internalformat, width, height,
@@ -1057,3 +1054,7 @@
     GLLog("glQueryMatrixxOES") << GLLogBuffer<GLfixed>(mantissa, 16) << GLLogBuffer<GLfixed>(exponent, 16);
     CALL_GL_API_RETURN(glQueryMatrixxOES, mantissa, exponent);
 }
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+// ----------------------------------------------------------------------------
diff --git a/opengl/libGLES_CM/egl_entries.cpp b/opengl/libs/egl_entries.in
similarity index 88%
rename from opengl/libGLES_CM/egl_entries.cpp
rename to opengl/libs/egl_entries.in
index ba46f40..33b4c65 100644
--- a/opengl/libGLES_CM/egl_entries.cpp
+++ b/opengl/libs/egl_entries.in
@@ -23,7 +23,7 @@
 EGL_ENTRY(EGLBoolean, eglCopyBuffers, EGLDisplay, EGLSurface, NativePixmapType)
 EGL_ENTRY(EGLint, eglGetError, void)
 EGL_ENTRY(const char*, eglQueryString, EGLDisplay, EGLint)
-EGL_ENTRY(proc_t, eglGetProcAddress, const char *)
+EGL_ENTRY(__eglMustCastToProperFunctionPointerType, eglGetProcAddress, const char *)
 
 /* EGL 1.1 */
 
@@ -40,7 +40,6 @@
 EGL_ENTRY(EGLBoolean, eglReleaseThread, void)
 EGL_ENTRY(EGLSurface, eglCreatePbufferFromClientBuffer, EGLDisplay, EGLenum, EGLClientBuffer, EGLConfig, const EGLint *)
 
-/* Android extentions */
+/* EGL 1.3 */
 
-EGL_ENTRY(EGLBoolean, eglSwapRectangleANDROID, EGLDisplay, EGLSurface , EGLint, EGLint, EGLint, EGLint)
-EGL_ENTRY(const char*, eglQueryStringConfigANDROID, EGLDisplay, EGLConfig, EGLint)
+/* EGL 1.4 */
diff --git a/opengl/libs/egl_impl.h b/opengl/libs/egl_impl.h
new file mode 100644
index 0000000..62ce3fc
--- /dev/null
+++ b/opengl/libs/egl_impl.h
@@ -0,0 +1,43 @@
+/* 
+ ** Copyright 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.
+ */
+
+#ifndef ANDROID_EGL_IMPL_H
+#define ANDROID_EGL_IMPL_H
+
+#include <ctype.h>
+
+#include <EGL/egl.h>
+
+// ----------------------------------------------------------------------------
+namespace android {
+// ----------------------------------------------------------------------------
+
+struct gl_hooks_t;
+
+struct egl_connection_t
+{
+    void volatile *     dso;
+    gl_hooks_t *        hooks;
+    EGLint              major;
+    EGLint              minor;
+    int                 unavailable;
+};
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+// ----------------------------------------------------------------------------
+
+#endif /* ANDROID_EGL_IMPL_H */
diff --git a/opengl/libGLES_CM/gl_entries.cpp b/opengl/libs/gl_entries.in
similarity index 97%
rename from opengl/libGLES_CM/gl_entries.cpp
rename to opengl/libs/gl_entries.in
index 3279322..b97e8fe 100644
--- a/opengl/libGLES_CM/gl_entries.cpp
+++ b/opengl/libs/gl_entries.in
@@ -101,7 +101,7 @@
 GL_ENTRY(void, glCompressedTexSubImage2D, GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid*)
 GL_ENTRY(void, glCopyTexImage2D, GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLsizei, GLint)
 GL_ENTRY(void, glCopyTexSubImage2D, GLenum, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei)
-GL_ENTRY(void, glTexImage2D, GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid*)
+GL_ENTRY(void, glTexImage2D, GLenum, GLint, GLint, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid*)
 GL_ENTRY(void, glTexSubImage2D, GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, const GLvoid*)
 GL_ENTRY(void, glReadPixels, GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, GLvoid *)
 
diff --git a/opengl/libGLES_CM/gl_enums.in b/opengl/libs/gl_enums.in
similarity index 100%
rename from opengl/libGLES_CM/gl_enums.in
rename to opengl/libs/gl_enums.in
diff --git a/opengl/libGLES_CM/gl_logger.h b/opengl/libs/gl_logger.h
similarity index 91%
rename from opengl/libGLES_CM/gl_logger.h
rename to opengl/libs/gl_logger.h
index 59e31c7..ce85dd1 100644
--- a/opengl/libGLES_CM/gl_logger.h
+++ b/opengl/libs/gl_logger.h
@@ -17,10 +17,10 @@
 #ifndef ANDROID_GL_LOGGER_H
 #define ANDROID_GL_LOGGER_H
 
-extern "C" {
+namespace android {
 #define GL_ENTRY(r, api, ...) r log_##api(__VA_ARGS__);
-#include "gl_entries.cpp"
+#include "gl_entries.in"
 #undef GL_ENTRY
-};
+}; // namespace android
 
 #endif /* ANDROID_GL_LOGGER_H */
diff --git a/opengl/libs/hooks.h b/opengl/libs/hooks.h
new file mode 100644
index 0000000..63fb017
--- /dev/null
+++ b/opengl/libs/hooks.h
@@ -0,0 +1,134 @@
+/* 
+ ** Copyright 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.
+ */
+
+#ifndef ANDROID_GLES_CM_HOOKS_H
+#define ANDROID_GLES_CM_HOOKS_H
+
+#include <ctype.h>
+#include <string.h>
+#include <errno.h>
+
+#include <EGL/egl.h>
+#include <GLES/gl.h>
+
+#define GL_LOGGER                   0
+#if !defined(__arm__)
+#define USE_SLOW_BINDING            1
+#else
+#define USE_SLOW_BINDING            0
+#endif
+#undef NELEM
+#define NELEM(x)                    (sizeof(x)/sizeof(*(x)))
+#define MAX_NUMBER_OF_GL_EXTENSIONS 32
+
+
+#if defined(HAVE_ANDROID_OS) && !USE_SLOW_BINDING && !GL_LOGGER && __OPTIMIZE__
+#define USE_FAST_TLS_KEY            1
+#else
+#define USE_FAST_TLS_KEY            0
+#endif
+
+#if USE_FAST_TLS_KEY
+#   include <bionic_tls.h>  /* special private C library header */
+#endif
+
+// ----------------------------------------------------------------------------
+namespace android {
+// ----------------------------------------------------------------------------
+
+//  EGLDisplay are global, not attached to a given thread
+const unsigned int NUM_DISPLAYS = 1;
+
+enum {
+    IMPL_HARDWARE = 0,
+    IMPL_SOFTWARE,
+    IMPL_CONTEXT_LOST,
+    IMPL_NO_CONTEXT,
+    
+    IMPL_NUM_IMPLEMENTATIONS
+};
+
+// ----------------------------------------------------------------------------
+
+// GL / EGL hooks
+
+#undef GL_ENTRY
+#undef EGL_ENTRY
+#define GL_ENTRY(_r, _api, ...) _r (*_api)(__VA_ARGS__);
+#define EGL_ENTRY(_r, _api, ...) _r (*_api)(__VA_ARGS__);
+
+struct gl_hooks_t {
+    struct gl_t {
+        #include "gl_entries.in"
+    } gl;
+    struct egl_t {
+        #include "egl_entries.in"
+    } egl;
+    struct gl_ext_t {
+        void (*extensions[MAX_NUMBER_OF_GL_EXTENSIONS])(void);
+    } ext;
+};
+#undef GL_ENTRY
+#undef EGL_ENTRY
+
+
+// ----------------------------------------------------------------------------
+
+extern gl_hooks_t gHooks[IMPL_NUM_IMPLEMENTATIONS];
+extern pthread_key_t gGLWrapperKey;
+
+#if USE_FAST_TLS_KEY
+
+// We have a dedicated TLS slot in bionic
+static inline gl_hooks_t const * volatile * get_tls_hooks() {
+    volatile void *tls_base = __get_tls();
+    gl_hooks_t const * volatile * tls_hooks = 
+            reinterpret_cast<gl_hooks_t const * volatile *>(tls_base);
+    return tls_hooks;
+}
+
+static inline void setGlThreadSpecific(gl_hooks_t const *value) {
+    gl_hooks_t const * volatile * tls_hooks = get_tls_hooks();
+    tls_hooks[TLS_SLOT_OPENGL_API] = value;
+}
+
+static gl_hooks_t const* getGlThreadSpecific() {
+    gl_hooks_t const * volatile * tls_hooks = get_tls_hooks();
+    gl_hooks_t const* hooks = tls_hooks[TLS_SLOT_OPENGL_API];
+    if (hooks) return hooks;
+    return &gHooks[IMPL_NO_CONTEXT];
+}
+
+#else
+
+static inline void setGlThreadSpecific(gl_hooks_t const *value) {
+    pthread_setspecific(gGLWrapperKey, value);
+}
+
+static gl_hooks_t const* getGlThreadSpecific() {
+    gl_hooks_t const* hooks =  static_cast<gl_hooks_t*>(pthread_getspecific(gGLWrapperKey));
+    if (hooks) return hooks;
+    return &gHooks[IMPL_NO_CONTEXT];
+}
+
+#endif
+
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+// ----------------------------------------------------------------------------
+
+#endif /* ANDROID_GLES_CM_HOOKS_H */
diff --git a/opengl/libGLES_CM/enumextract.sh b/opengl/libs/tools/enumextract.sh
similarity index 100%
rename from opengl/libGLES_CM/enumextract.sh
rename to opengl/libs/tools/enumextract.sh
diff --git a/opengl/tests/angeles/Android.mk b/opengl/tests/angeles/Android.mk
index 41673cb..46958d3 100644
--- a/opengl/tests/angeles/Android.mk
+++ b/opengl/tests/angeles/Android.mk
@@ -3,7 +3,7 @@
 LOCAL_PATH:= $(call my-dir)
 include $(CLEAR_VARS)
 LOCAL_SRC_FILES:= app-linux.c demo.c.arm
-LOCAL_SHARED_LIBRARIES := libGLES_CM libui
+LOCAL_SHARED_LIBRARIES := libEGL libGLESv1_CM libui
 LOCAL_MODULE:= angeles
 LOCAL_MODULE_TAGS := tests
 include $(BUILD_EXECUTABLE)
@@ -11,7 +11,7 @@
 
 include $(CLEAR_VARS)
 LOCAL_SRC_FILES:= gpustate.c
-LOCAL_SHARED_LIBRARIES := libGLES_CM
+LOCAL_SHARED_LIBRARIES := libEGL libGLESv1_CM
 LOCAL_MODULE:= gpustate
 LOCAL_MODULE_TAGS := tests
 include $(BUILD_EXECUTABLE)
diff --git a/opengl/tests/angeles/app-linux.c b/opengl/tests/angeles/app-linux.c
index d439eb2..7d0d320 100644
--- a/opengl/tests/angeles/app-linux.c
+++ b/opengl/tests/angeles/app-linux.c
@@ -49,7 +49,8 @@
 #include <stdio.h>
 #include <sys/time.h>
 
-#include <GLES/egl.h>
+#include <EGL/egl.h>
+#include <GLES/gl.h>
 
 #include "app.h"
 
diff --git a/opengl/tests/filter/Android.mk b/opengl/tests/filter/Android.mk
index 1c4253c..a448f0d 100644
--- a/opengl/tests/filter/Android.mk
+++ b/opengl/tests/filter/Android.mk
@@ -6,7 +6,8 @@
 
 LOCAL_SHARED_LIBRARIES := \
 	libcutils \
-    libGLES_CM \
+    libEGL \
+    libGLESv1_CM \
     libui
 
 LOCAL_MODULE:= test-opengl-filter
diff --git a/opengl/tests/filter/filter.c b/opengl/tests/filter/filter.c
index c8bac06..de97119 100644
--- a/opengl/tests/filter/filter.c
+++ b/opengl/tests/filter/filter.c
@@ -1,7 +1,9 @@
 #include <stdlib.h>
 #include <stdio.h>
 
-#include <GLES/egl.h>
+#include <EGL/egl.h>
+#include <GLES/gl.h>
+#include <GLES/glext.h>
 
 int main(int argc, char** argv)
 {
@@ -40,6 +42,9 @@
          printf("using pbuffer\n");
          EGLint attribs[] = { EGL_WIDTH, 320, EGL_HEIGHT, 480, EGL_NONE };
          surface = eglCreatePbufferSurface(dpy, config, attribs);
+         if (surface == EGL_NO_SURFACE) {
+             printf("eglCreatePbufferSurface error %x\n", eglGetError());
+         }
      }
      context = eglCreateContext(dpy, config, NULL, NULL);
      eglMakeCurrent(dpy, surface, surface, context);   
diff --git a/opengl/tests/finish/Android.mk b/opengl/tests/finish/Android.mk
index f7b95ed..26836c1 100644
--- a/opengl/tests/finish/Android.mk
+++ b/opengl/tests/finish/Android.mk
@@ -6,7 +6,8 @@
 
 LOCAL_SHARED_LIBRARIES := \
 	libcutils \
-    libGLES_CM \
+    libEGL \
+    libGLESv1_CM \
     libui
 
 LOCAL_MODULE:= test-opengl-finish
diff --git a/opengl/tests/finish/finish.c b/opengl/tests/finish/finish.c
index 3afe227..45fc758 100644
--- a/opengl/tests/finish/finish.c
+++ b/opengl/tests/finish/finish.c
@@ -20,7 +20,10 @@
 #include <sched.h>
 #include <sys/resource.h>
 
-#include <GLES/egl.h>
+#include <EGL/egl.h>
+#include <GLES/gl.h>
+#include <GLES/glext.h>
+
 
 long long systemTime()
 {
diff --git a/opengl/tests/sfsim/Android.mk b/opengl/tests/sfsim/Android.mk
deleted file mode 100644
index 8a1a03c..0000000
--- a/opengl/tests/sfsim/Android.mk
+++ /dev/null
@@ -1,15 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
-	egl_surface.cpp \
-	sfsim.c
-
-LOCAL_SHARED_LIBRARIES := \
-    libGLES_CM
-
-LOCAL_MODULE:= test-opengl-sfsim
-
-LOCAL_MODULE_TAGS := tests
-
-include $(BUILD_EXECUTABLE)
diff --git a/opengl/tests/sfsim/egl_surface.cpp b/opengl/tests/sfsim/egl_surface.cpp
deleted file mode 100644
index b0777f8..0000000
--- a/opengl/tests/sfsim/egl_surface.cpp
+++ /dev/null
@@ -1,346 +0,0 @@
-/* 
- **
- ** Copyright 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.
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <sys/ioctl.h>
-#include <sys/types.h>
-#include <sys/mman.h>
-
-#include <GLES/egl.h>
-
-#include "egl_surface.h"
-
-#define LOGI(x...) do { printf("INFO: " x); } while (0)
-#define LOGW(x...) do { printf("WARN: " x); } while (0)
-#define LOGE(x...) do { printf("ERR: " x); } while (0)
-
-// ----------------------------------------------------------------------------
-
-egl_native_window_t* android_createDisplaySurface()
-{
-    egl_native_window_t* s = new android::EGLDisplaySurface();
-    s->memory_type = NATIVE_MEMORY_TYPE_GPU;
-    return s;
-}
-
-#define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
-#define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))
-
-// ----------------------------------------------------------------------------
-namespace android {
-// ----------------------------------------------------------------------------
-
-EGLDisplaySurface::EGLDisplaySurface()
-    : EGLNativeSurface<EGLDisplaySurface>()
-{
-    egl_native_window_t::version = sizeof(egl_native_window_t);
-    egl_native_window_t::ident = 0;
-    egl_native_window_t::incRef = &EGLDisplaySurface::hook_incRef;
-    egl_native_window_t::decRef = &EGLDisplaySurface::hook_decRef;
-    egl_native_window_t::swapBuffers = &EGLDisplaySurface::hook_swapBuffers;
-    egl_native_window_t::setSwapRectangle = &EGLDisplaySurface::hook_setSwapRectangle;
-    egl_native_window_t::nextBuffer = &EGLDisplaySurface::hook_nextBuffer;
-    egl_native_window_t::connect = 0;
-    egl_native_window_t::disconnect = 0;
-
-    mFb[0].data = 0;
-    mFb[1].data = 0;
-    egl_native_window_t::fd = mapFrameBuffer();
-    if (egl_native_window_t::fd >= 0) {
-        const float in2mm = 25.4f;
-        float refreshRate = 1000000000000000LLU / (
-                float( mInfo.upper_margin + mInfo.lower_margin + mInfo.yres ) 
-                * ( mInfo.left_margin  + mInfo.right_margin + mInfo.xres )
-                * mInfo.pixclock);
-
-        const GGLSurface& buffer = mFb[1 - mIndex];
-        egl_native_window_t::width  = buffer.width;
-        egl_native_window_t::height = buffer.height;
-        egl_native_window_t::stride = buffer.stride;
-        egl_native_window_t::format = buffer.format;
-        egl_native_window_t::base   = intptr_t(mFb[0].data);
-        egl_native_window_t::offset =
-            intptr_t(buffer.data) - egl_native_window_t::base;
-        egl_native_window_t::flags  = 0;
-        egl_native_window_t::xdpi = (mInfo.xres * in2mm) / mInfo.width;
-        egl_native_window_t::ydpi = (mInfo.yres * in2mm) / mInfo.height;
-        egl_native_window_t::fps  = refreshRate;
-        egl_native_window_t::memory_type = NATIVE_MEMORY_TYPE_FB;
-        // no error, set the magic word
-        egl_native_window_t::magic = 0x600913;
-    }
-    mSwapCount = -1;
-    mPageFlipCount = 0;
-}
-
-EGLDisplaySurface::~EGLDisplaySurface()
-{
-    magic = 0;
-    close(egl_native_window_t::fd);
-    munmap(mFb[0].data, mSize);
-    if (!(mFlags & PAGE_FLIP))
-        free((void*)mFb[1].data);
-}
-
-void EGLDisplaySurface::hook_incRef(NativeWindowType window) {
-    EGLDisplaySurface* that = static_cast<EGLDisplaySurface*>(window);
-    that->incStrong(that);
-}
-void EGLDisplaySurface::hook_decRef(NativeWindowType window) {
-    EGLDisplaySurface* that = static_cast<EGLDisplaySurface*>(window);
-    that->decStrong(that);
-}
-uint32_t EGLDisplaySurface::hook_swapBuffers(NativeWindowType window) {
-    EGLDisplaySurface* that = static_cast<EGLDisplaySurface*>(window);
-    return that->swapBuffers();
-}
-uint32_t EGLDisplaySurface::hook_nextBuffer(NativeWindowType window) {
-    EGLDisplaySurface* that = static_cast<EGLDisplaySurface*>(window);
-    return that->nextBuffer();
-}
-void EGLDisplaySurface::hook_setSwapRectangle(NativeWindowType window,
-        int l, int t, int w, int h) {
-    EGLDisplaySurface* that = static_cast<EGLDisplaySurface*>(window);
-    that->setSwapRectangle(l, t, w, h);
-}
-
-void EGLDisplaySurface::setSwapRectangle(int l, int t, int w, int h)
-{
-    mInfo.reserved[0] = 0x54445055; // "UPDT";
-    mInfo.reserved[1] = (uint16_t)l | ((uint32_t)t << 16);
-    mInfo.reserved[2] = (uint16_t)(l+w) | ((uint32_t)(t+h) << 16);
-}
-
-uint32_t EGLDisplaySurface::swapBuffers()
-{
-    if (!(mFlags & PAGE_FLIP))
-        return 0;
-
-    // do the actual flip
-    mIndex = 1 - mIndex;
-    mInfo.activate = FB_ACTIVATE_VBL;
-    mInfo.yoffset = mIndex ? mInfo.yres : 0;
-    if (ioctl(egl_native_window_t::fd, FBIOPUT_VSCREENINFO, &mInfo) == -1) {
-        LOGE("FBIOPUT_VSCREENINFO failed");
-        return 0;
-    }
-
-    /*
-     * this is a monstruous hack: Because the h/w accelerator is not able
-     * to render directly into the framebuffer, we need to copy its
-     * internal framebuffer out to the fb. the base address of the internal fb
-     * is given in oem[0]. 
-     * All this is needed only in standalone mode, in SurfaceFlinger mode
-     * we control where the GPU renders.
-     */
-    if (egl_native_window_t::memory_type == NATIVE_MEMORY_TYPE_GPU && oem[0]) {
-        // could use MDP here, but that's tricky because we need
-        // /dev/pmem_gpu* filedescriptor
-        const GGLSurface& buffer = mFb[mIndex];
-        memcpy( buffer.data,
-                (void*)(oem[0] + egl_native_window_t::offset),
-                buffer.stride*buffer.height*2);
-    }
-
-    // update the address of the buffer to draw to next
-    const GGLSurface& buffer = mFb[1 - mIndex];
-    egl_native_window_t::offset =
-        intptr_t(buffer.data) - egl_native_window_t::base;
-
-    mPageFlipCount++;
-
-    // We don't support screen-size changes for now
-    return 0;
-}
-
-int32_t EGLDisplaySurface::getPageFlipCount() const
-{
-    return mPageFlipCount;
-}
-
-uint32_t EGLDisplaySurface::nextBuffer()
-{
-    // update the address of the buffer to draw to next
-    const GGLSurface& buffer = mFb[mIndex];
-    egl_native_window_t::offset =
-        intptr_t(buffer.data) - egl_native_window_t::base;
-    return 0;
-}
-
-int EGLDisplaySurface::mapFrameBuffer()
-{
-    char const * const device_template[] = {
-            "/dev/graphics/fb%u",
-            "/dev/fb%u",
-            0 };
-    int fd = -1;
-    int i=0;
-    char name[64];
-    while ((fd==-1) && device_template[i]) {
-        snprintf(name, 64, device_template[i], 0);
-        fd = open(name, O_RDWR, 0);
-        i++;
-    }
-    if (fd < 0)
-        return -errno;
-
-    struct fb_fix_screeninfo finfo;
-    if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) == -1)
-        return -errno;
-
-    struct fb_var_screeninfo info;
-    if (ioctl(fd, FBIOGET_VSCREENINFO, &info) == -1)
-        return -errno;
-
-    info.reserved[0] = 0;
-    info.reserved[1] = 0;
-    info.reserved[2] = 0;
-    info.xoffset = 0;
-    info.yoffset = 0;
-    info.yres_virtual = info.yres * 2;
-    info.bits_per_pixel = 16;
-    info.activate = FB_ACTIVATE_NOW;
-
-    uint32_t flags = PAGE_FLIP;
-    if (ioctl(fd, FBIOPUT_VSCREENINFO, &info) == -1) {
-        info.yres_virtual = info.yres;
-        flags &= ~PAGE_FLIP;
-        LOGW("FBIOPUT_VSCREENINFO failed, page flipping not supported");
-    }
-
-    if (info.yres_virtual < info.yres * 2) {
-        info.yres_virtual = info.yres;
-        flags &= ~PAGE_FLIP;
-        LOGW("page flipping not supported (yres_virtual=%d, requested=%d)",
-                info.yres_virtual, info.yres*2);
-    }
-
-    if (ioctl(fd, FBIOGET_VSCREENINFO, &info) == -1)
-        return -errno;    
-
-    int refreshRate = 1000000000000000LLU / 
-    (
-            uint64_t( info.upper_margin + info.lower_margin + info.yres ) 
-            * ( info.left_margin  + info.right_margin + info.xres )
-            * info.pixclock
-    );
-
-    if (refreshRate == 0) {
-        // bleagh, bad info from the driver
-        refreshRate = 60*1000;  // 60 Hz
-    }
-
-    if (int(info.width) <= 0 || int(info.height) <= 0) {
-        // stupid driver, doesn't return that information
-        // default to Sooner's screen size (160 dpi)
-        info.width  = 51;
-        info.height = 38;
-    }
-
-    float xdpi = (info.xres * 25.4f) / info.width; 
-    float ydpi = (info.yres * 25.4f) / info.height;
-    float fps  = refreshRate / 1000.0f; 
-
-    LOGI(   "using (fd=%d)\n"
-            "id           = %s\n"
-            "xres         = %d px\n"
-            "yres         = %d px\n"
-            "xres_virtual = %d px\n"
-            "yres_virtual = %d px\n"
-            "bpp          = %d\n"
-            "r            = %2u:%u\n"
-            "g            = %2u:%u\n"
-            "b            = %2u:%u\n",
-            fd,
-            finfo.id,
-            info.xres,
-            info.yres,
-            info.xres_virtual,
-            info.yres_virtual,
-            info.bits_per_pixel,
-            info.red.offset, info.red.length,
-            info.green.offset, info.green.length,
-            info.blue.offset, info.blue.length
-    );
-
-    LOGI(   "width        = %d mm (%f dpi)\n"
-            "height       = %d mm (%f dpi)\n"
-            "refresh rate = %.2f Hz\n",
-            info.width,  xdpi,
-            info.height, ydpi,
-            fps
-    );
-
-    
-    if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) == -1)
-        return -errno;
-
-    if (finfo.smem_len <= 0)
-        return -errno;
-
-    /*
-     * Open and map the display.
-     */
-
-    void* buffer  = (uint16_t*) mmap(
-            0, finfo.smem_len,
-            PROT_READ | PROT_WRITE,
-            MAP_SHARED,
-            fd, 0);
-
-    if (buffer == MAP_FAILED)
-        return -errno;
-
-    // at least for now, always clear the fb
-    memset(buffer, 0, finfo.smem_len);
-
-    uint8_t* offscreen[2];
-    offscreen[0] = (uint8_t*)buffer;
-    if (flags & PAGE_FLIP) {
-        offscreen[1] = (uint8_t*)buffer + finfo.line_length*info.yres;
-    } else {
-        offscreen[1] = (uint8_t*)malloc(finfo.smem_len);
-        if (offscreen[1] == 0) {
-            munmap(buffer, finfo.smem_len);
-            return -ENOMEM;
-        }
-    }
-
-    mFlags = flags;
-    mInfo = info;
-    mFinfo = finfo;
-    mSize = finfo.smem_len;
-    mIndex = 0;
-    for (int i=0 ; i<2 ; i++) {
-        mFb[i].version = sizeof(GGLSurface);
-        mFb[i].width   = info.xres;
-        mFb[i].height  = info.yres;
-        mFb[i].stride  = finfo.line_length / (info.bits_per_pixel >> 3);
-        mFb[i].data    = (uint8_t*)(offscreen[i]);
-        mFb[i].format  = NATIVE_PIXEL_FORMAT_RGB_565;
-    }
-    return fd;
-}
-
-// ----------------------------------------------------------------------------
-}; // namespace android
-// ----------------------------------------------------------------------------
diff --git a/opengl/tests/sfsim/egl_surface.h b/opengl/tests/sfsim/egl_surface.h
deleted file mode 100644
index 70a94fc..0000000
--- a/opengl/tests/sfsim/egl_surface.h
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef ANDROID_SIM_EGL_SURFACE_H
-#define ANDROID_SIM_EGL_SURFACE_H
-
-#include <stdint.h>
-#include <errno.h>
-#include <sys/types.h>
-
-#include <GLES/eglnatives.h>
-
-#include <linux/fb.h>
-
-typedef struct {
-    ssize_t    version;    // always set to sizeof(GGLSurface)
-    uint32_t   width;      // width in pixels
-    uint32_t   height;     // height in pixels
-    int32_t    stride;     // stride in pixels
-    uint8_t*   data;       // pointer to the bits
-    uint8_t    format;     // pixel format
-    uint8_t    rfu[3];     // must be zero
-    void*      reserved;
-} GGLSurface;
-
-// ---------------------------------------------------------------------------
-namespace android {
-// ---------------------------------------------------------------------------
-
-template <class TYPE>
-class EGLNativeSurface : public egl_native_window_t
-{
-public:
-    EGLNativeSurface() : mCount(0) { 
-        memset(egl_native_window_t::reserved, 0, 
-                sizeof(egl_native_window_t::reserved));
-        memset(egl_native_window_t::reserved_proc, 0, 
-                sizeof(egl_native_window_t::reserved_proc));
-        memset(egl_native_window_t::oem, 0, 
-                sizeof(egl_native_window_t::oem));
-    }
-    inline void incStrong(void*) const {
-        /* in a real implementation, the inc must be atomic */
-        mCount++;
-    }
-    inline void decStrong(void*) const {
-        /* in a real implementation, the dec must be atomic */
-        if (--mCount == 1) {
-             delete static_cast<const TYPE*>(this);
-         }
-    }
-protected:
-    EGLNativeSurface& operator = (const EGLNativeSurface& rhs);
-    EGLNativeSurface(const EGLNativeSurface& rhs);
-    inline ~EGLNativeSurface() { };
-    mutable volatile int32_t mCount;
-};
-
-
-class EGLDisplaySurface : public EGLNativeSurface<EGLDisplaySurface>
-{
-public:
-    EGLDisplaySurface();
-    ~EGLDisplaySurface();
-
-    int32_t getPageFlipCount() const;
-
-private:
-    static void         hook_incRef(NativeWindowType window);
-    static void         hook_decRef(NativeWindowType window);
-    static uint32_t     hook_swapBuffers(NativeWindowType window);
-    static void         hook_setSwapRectangle(NativeWindowType window, int l, int t, int w, int h);
-    static uint32_t     hook_nextBuffer(NativeWindowType window);
-
-    uint32_t    swapBuffers();
-    uint32_t    nextBuffer();
-    void        setSwapRectangle(int l, int t, int w, int h);
-
-    int    mapFrameBuffer();
-
-    enum {
-        PAGE_FLIP = 0x00000001
-    };
-    GGLSurface          mFb[2];
-    int                 mIndex;
-    uint32_t            mFlags;
-    size_t              mSize;
-    fb_var_screeninfo   mInfo;
-    fb_fix_screeninfo   mFinfo;
-    int32_t             mPageFlipCount;
-    int32_t             mSwapCount;
-    uint32_t            mFeatureFlags;
-};
-
-// ---------------------------------------------------------------------------
-}; // namespace android
-// ---------------------------------------------------------------------------
-
-#endif // ANDROID_SIM_EGL_SURFACE_H
-
diff --git a/opengl/tests/sfsim/sfsim.c b/opengl/tests/sfsim/sfsim.c
deleted file mode 100644
index 14ba490..0000000
--- a/opengl/tests/sfsim/sfsim.c
+++ /dev/null
@@ -1,112 +0,0 @@
-#include <stdlib.h>
-#include <stdio.h>
-
-#include <GLES/egl.h>
-
-int main(int argc, char** argv)
-{
-    if (argc != 2) {
-        printf("usage: %s <0-6>\n", argv[0]);
-        return 0;
-    }
-    
-    const int test = atoi(argv[1]);
-
-    EGLint s_configAttribs[] = {
-         EGL_RED_SIZE,       5,
-         EGL_GREEN_SIZE,     6,
-         EGL_BLUE_SIZE,      5,
-         EGL_NONE
-     };
-     
-     EGLint numConfigs = -1;
-     EGLint majorVersion;
-     EGLint minorVersion;
-     EGLConfig config;
-     EGLContext context;
-     EGLSurface surface;
-     EGLint w, h;
-     
-     EGLDisplay dpy;
-
-     dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
-     eglInitialize(dpy, &majorVersion, &minorVersion);
-     eglChooseConfig(dpy, s_configAttribs, &config, 1, &numConfigs);
-     surface = eglCreateWindowSurface(dpy, config,
-             android_createDisplaySurface(), NULL);
-     context = eglCreateContext(dpy, config, NULL, NULL);
-     eglMakeCurrent(dpy, surface, surface, context);   
-     eglQuerySurface(dpy, surface, EGL_WIDTH, &w);
-     eglQuerySurface(dpy, surface, EGL_HEIGHT, &h);
-     GLint dim = w<h ? w : h;
-
-     glClear(GL_COLOR_BUFFER_BIT);
-
-     GLint crop[4] = { 0, 4, 4, -4 };
-     glBindTexture(GL_TEXTURE_2D, 0);
-     glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, crop);
-     glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-     glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-     glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
-     glEnable(GL_TEXTURE_2D);
-     glColor4f(1,1,1,1);
-
-     // packing is always 4
-     uint8_t t8[]  = { 
-             0x00, 0x55, 0x00, 0x55, 
-             0xAA, 0xFF, 0xAA, 0xFF,
-             0x00, 0x55, 0x00, 0x55, 
-             0xAA, 0xFF, 0xAA, 0xFF  };
-
-     uint16_t t16[]  = { 
-             0x0000, 0x5555, 0x0000, 0x5555, 
-             0xAAAA, 0xFFFF, 0xAAAA, 0xFFFF,
-             0x0000, 0x5555, 0x0000, 0x5555, 
-             0xAAAA, 0xFFFF, 0xAAAA, 0xFFFF  };
-
-     uint16_t t5551[]  = { 
-             0x0000, 0xFFFF, 0x0000, 0xFFFF, 
-             0xFFFF, 0x0000, 0xFFFF, 0x0000,
-             0x0000, 0xFFFF, 0x0000, 0xFFFF, 
-             0xFFFF, 0x0000, 0xFFFF, 0x0000  };
-
-     uint32_t t32[]  = { 
-             0xFF000000, 0xFF0000FF, 0xFF00FF00, 0xFFFF0000, 
-             0xFF00FF00, 0xFFFF0000, 0xFF000000, 0xFF0000FF, 
-             0xFF00FFFF, 0xFF00FF00, 0x00FF00FF, 0xFFFFFF00, 
-             0xFF000000, 0xFFFF00FF, 0xFF00FFFF, 0xFFFFFFFF
-     };
-
-     switch(test) 
-     {
-     case 1:
-         glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE,
-                 4, 4, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, t8);
-         break;
-     case 2:
-         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
-                 4, 4, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, t16);
-         break;
-     case 3:
-         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
-                 4, 4, 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, t16);
-         break;
-     case 4:
-         glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA,
-                 4, 4, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, t16);
-         break;
-     case 5:
-         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
-                 4, 4, 0, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, t5551);
-         break;
-     case 6:
-         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
-                 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, t32);
-         break;
-     }
-
-     glDrawTexiOES(0, 0, 0, dim, dim);
-
-     eglSwapBuffers(dpy, surface);
-     return 0;
-}
diff --git a/opengl/tests/textures/Android.mk b/opengl/tests/textures/Android.mk
index b0c9021..a8c6220 100644
--- a/opengl/tests/textures/Android.mk
+++ b/opengl/tests/textures/Android.mk
@@ -6,7 +6,8 @@
 
 LOCAL_SHARED_LIBRARIES := \
 	libcutils \
-    libGLES_CM \
+    libEGL \
+    libGLESv1_CM \
     libui
 
 LOCAL_MODULE:= test-opengl-textures
diff --git a/opengl/tests/textures/textures.c b/opengl/tests/textures/textures.c
index 98e3be1..214291b 100644
--- a/opengl/tests/textures/textures.c
+++ b/opengl/tests/textures/textures.c
@@ -18,7 +18,9 @@
 #include <stdlib.h>
 #include <stdio.h>
 
-#include <GLES/egl.h>
+#include <EGL/egl.h>
+#include <GLES/gl.h>
+#include <GLES/glext.h>
 
 int main(int argc, char** argv)
 {
diff --git a/opengl/tests/tritex/Android.mk b/opengl/tests/tritex/Android.mk
index 4edac4c..5cd1f04 100644
--- a/opengl/tests/tritex/Android.mk
+++ b/opengl/tests/tritex/Android.mk
@@ -6,7 +6,8 @@
 
 LOCAL_SHARED_LIBRARIES := \
 	libcutils \
-    libGLES_CM \
+    libEGL \
+    libGLESv1_CM \
     libui
 
 LOCAL_MODULE:= test-opengl-tritex
diff --git a/opengl/tests/tritex/tritex.c b/opengl/tests/tritex/tritex.c
index 8ebe7d4..60a7feb 100644
--- a/opengl/tests/tritex/tritex.c
+++ b/opengl/tests/tritex/tritex.c
@@ -4,7 +4,9 @@
 //
 // Ported from a Java version by Google.
 
-#include <GLES/egl.h>

+#include <EGL/egl.h>

+#include <GLES/gl.h>
+
 #include <stdio.h>

 #include <stdlib.h>
 #include <math.h>
diff --git a/services/Android.mk b/services/Android.mk
deleted file mode 100644
index 5e912d6..0000000
--- a/services/Android.mk
+++ /dev/null
@@ -1,17 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-
-# the library
-# ============================================================
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := \
-            $(call all-subdir-java-files)
-
-LOCAL_MODULE:= services
-
-LOCAL_JAVA_LIBRARIES := android.policy
-
-include $(BUILD_JAVA_LIBRARY)
-
-include $(BUILD_DROIDDOC)
-