Merge "New secure setting for mobile download size limit." into gingerbread
diff --git a/include/ui/InputReader.h b/include/ui/InputReader.h
index d7ec8ea..6bf1bfa 100644
--- a/include/ui/InputReader.h
+++ b/include/ui/InputReader.h
@@ -210,7 +210,7 @@
  * IMPORTANT INVARIANT:
  *     Because the policy and dispatcher can potentially block or cause re-entrance into
  *     the input reader, the input reader never calls into other components while holding
- *     an exclusive internal lock.
+ *     an exclusive internal lock whenever re-entrance can happen.
  */
 class InputReader : public InputReaderInterface, private InputReaderContext {
 public:
@@ -414,6 +414,8 @@
     virtual int32_t getMetaState();
 
 private:
+    Mutex mLock;
+
     struct KeyDown {
         int32_t keyCode;
         int32_t scanCode;
@@ -423,17 +425,22 @@
     uint32_t mSources;
     int32_t mKeyboardType;
 
-    Vector<KeyDown> mKeyDowns; // keys that are down
-    int32_t mMetaState;
-    nsecs_t mDownTime; // time of most recent key down
+    struct LockedState {
+        Vector<KeyDown> keyDowns; // keys that are down
+        int32_t metaState;
+        nsecs_t downTime; // time of most recent key down
+    } mLocked;
 
-    void initialize();
+    void initializeLocked();
 
     bool isKeyboardOrGamepadKey(int32_t scanCode);
+
     void processKey(nsecs_t when, bool down, int32_t keyCode, int32_t scanCode,
             uint32_t policyFlags);
+    void applyPolicyAndDispatch(nsecs_t when, uint32_t policyFlags,
+            bool down, int32_t keyCode, int32_t scanCode, int32_t metaState, nsecs_t downTime);
 
-    ssize_t findKeyDown(int32_t scanCode);
+    ssize_t findKeyDownLocked(int32_t scanCode);
 };
 
 
@@ -451,6 +458,8 @@
     // Amount that trackball needs to move in order to generate a key event.
     static const int32_t TRACKBALL_MOVEMENT_THRESHOLD = 6;
 
+    Mutex mLock;
+
     int32_t mAssociatedDisplayId;
 
     struct Accumulator {
@@ -475,17 +484,21 @@
         }
     } mAccumulator;
 
-    bool mDown;
-    nsecs_t mDownTime;
-
     float mXScale;
     float mYScale;
     float mXPrecision;
     float mYPrecision;
 
-    void initialize();
+    struct LockedState {
+        bool down;
+        nsecs_t downTime;
+    } mLocked;
+
+    void initializeLocked();
 
     void sync(nsecs_t when);
+    void applyPolicyAndDispatch(nsecs_t when, int32_t motionEventAction,
+            PointerCoords* pointerCoords, nsecs_t downTime);
 };
 
 
@@ -509,6 +522,8 @@
      * (This is limited by our use of BitSet32 to track pointer assignments.) */
     static const uint32_t MAX_POINTER_ID = 31;
 
+    Mutex mLock;
+
     struct VirtualKey {
         int32_t keyCode;
         int32_t scanCode;
@@ -561,7 +576,6 @@
     };
 
     int32_t mAssociatedDisplayId;
-    Vector<VirtualKey> mVirtualKeys;
 
     // Immutable configuration parameters.
     struct Parameters {
@@ -583,67 +597,65 @@
         RawAbsoluteAxisInfo orientation;
     } mAxes;
 
-    // The surface orientation and width and height set by configureSurface().
-    int32_t mSurfaceOrientation;
-    int32_t mSurfaceWidth, mSurfaceHeight;
-
-    // Translation and scaling factors, orientation-independent.
-    int32_t mXOrigin;
-    float mXScale;
-    float mXPrecision;
-
-    int32_t mYOrigin;
-    float mYScale;
-    float mYPrecision;
-
-    int32_t mPressureOrigin;
-    float mPressureScale;
-
-    int32_t mSizeOrigin;
-    float mSizeScale;
-
-    float mOrientationScale;
-
-    // Oriented motion ranges for input device info.
-    struct OrientedRanges {
-        InputDeviceInfo::MotionRange x;
-        InputDeviceInfo::MotionRange y;
-        InputDeviceInfo::MotionRange pressure;
-        InputDeviceInfo::MotionRange size;
-        InputDeviceInfo::MotionRange touchMajor;
-        InputDeviceInfo::MotionRange touchMinor;
-        InputDeviceInfo::MotionRange toolMajor;
-        InputDeviceInfo::MotionRange toolMinor;
-        InputDeviceInfo::MotionRange orientation;
-    } mOrientedRanges;
-
-    // Oriented dimensions and precision.
-    float mOrientedSurfaceWidth, mOrientedSurfaceHeight;
-    float mOrientedXPrecision, mOrientedYPrecision;
-
-    // The touch data of the current sample being processed.
+    // Current and previous touch sample data.
     TouchData mCurrentTouch;
-
-    // The touch data of the previous sample that was processed.  This is updated
-    // incrementally while the current sample is being processed.
     TouchData mLastTouch;
 
     // The time the primary pointer last went down.
     nsecs_t mDownTime;
 
-    struct CurrentVirtualKeyState {
-        bool down;
-        nsecs_t downTime;
-        int32_t keyCode;
-        int32_t scanCode;
-    } mCurrentVirtualKey;
+    struct LockedState {
+        Vector<VirtualKey> virtualKeys;
 
-    // Lock for virtual key state.
-    Mutex mVirtualKeyLock; // methods use "Lvk" suffix
+        // The surface orientation and width and height set by configureSurfaceLocked().
+        int32_t surfaceOrientation;
+        int32_t surfaceWidth, surfaceHeight;
+
+        // Translation and scaling factors, orientation-independent.
+        int32_t xOrigin;
+        float xScale;
+        float xPrecision;
+
+        int32_t yOrigin;
+        float yScale;
+        float yPrecision;
+
+        int32_t pressureOrigin;
+        float pressureScale;
+
+        int32_t sizeOrigin;
+        float sizeScale;
+
+        float orientationScale;
+
+        // Oriented motion ranges for input device info.
+        struct OrientedRanges {
+            InputDeviceInfo::MotionRange x;
+            InputDeviceInfo::MotionRange y;
+            InputDeviceInfo::MotionRange pressure;
+            InputDeviceInfo::MotionRange size;
+            InputDeviceInfo::MotionRange touchMajor;
+            InputDeviceInfo::MotionRange touchMinor;
+            InputDeviceInfo::MotionRange toolMajor;
+            InputDeviceInfo::MotionRange toolMinor;
+            InputDeviceInfo::MotionRange orientation;
+        } orientedRanges;
+
+        // Oriented dimensions and precision.
+        float orientedSurfaceWidth, orientedSurfaceHeight;
+        float orientedXPrecision, orientedYPrecision;
+
+        struct CurrentVirtualKeyState {
+            bool down;
+            nsecs_t downTime;
+            int32_t keyCode;
+            int32_t scanCode;
+        } currentVirtualKey;
+    } mLocked;
 
     virtual void configureAxes();
-    virtual bool configureSurface();
-    virtual void configureVirtualKeys();
+    virtual bool configureSurfaceLocked();
+    virtual void configureVirtualKeysLocked();
 
     enum TouchResult {
         // Dispatch the touch normally.
@@ -696,15 +708,19 @@
         uint64_t distance : 48; // squared distance
     };
 
-    void initialize();
+    void initializeLocked();
 
     TouchResult consumeOffScreenTouches(nsecs_t when, uint32_t policyFlags);
     void dispatchTouches(nsecs_t when, uint32_t policyFlags);
     void dispatchTouch(nsecs_t when, uint32_t policyFlags, TouchData* touch,
             BitSet32 idBits, uint32_t changedId, int32_t motionEventAction);
 
-    bool isPointInsideSurface(int32_t x, int32_t y);
-    const VirtualKey* findVirtualKeyHitLvk(int32_t x, int32_t y);
+    void applyPolicyAndDispatchVirtualKey(nsecs_t when, uint32_t policyFlags,
+            int32_t keyEventAction, int32_t keyEventFlags,
+            int32_t keyCode, int32_t scanCode, nsecs_t downTime);
+
+    bool isPointInsideSurfaceLocked(int32_t x, int32_t y);
+    const VirtualKey* findVirtualKeyHitLocked(int32_t x, int32_t y);
 
     bool applyBadTouchFilter();
     bool applyJumpyTouchFilter();
diff --git a/libs/ui/InputReader.cpp b/libs/ui/InputReader.cpp
index 56e2977..6618702 100644
--- a/libs/ui/InputReader.cpp
+++ b/libs/ui/InputReader.cpp
@@ -713,15 +713,15 @@
         uint32_t sources, int32_t keyboardType) :
         InputMapper(device), mAssociatedDisplayId(associatedDisplayId), mSources(sources),
         mKeyboardType(keyboardType) {
-    initialize();
+    initializeLocked();
 }
 
 KeyboardInputMapper::~KeyboardInputMapper() {
 }
 
-void KeyboardInputMapper::initialize() {
-    mMetaState = AMETA_NONE;
-    mDownTime = 0;
+void KeyboardInputMapper::initializeLocked() {
+    mLocked.metaState = AMETA_NONE;
+    mLocked.downTime = 0;
 }
 
 uint32_t KeyboardInputMapper::getSources() {
@@ -735,17 +735,27 @@
 }
 
 void KeyboardInputMapper::reset() {
-    // Synthesize key up event on reset if keys are currently down.
-    while (! mKeyDowns.isEmpty()) {
-        const KeyDown& keyDown = mKeyDowns.top();
+    for (;;) {
+        int32_t keyCode, scanCode;
+        { // acquire lock
+            AutoMutex _l(mLock);
+
+            // Synthesize key up event on reset if keys are currently down.
+            if (mLocked.keyDowns.isEmpty()) {
+                initializeLocked();
+                break; // done
+            }
+
+            const KeyDown& keyDown = mLocked.keyDowns.top();
+            keyCode = keyDown.keyCode;
+            scanCode = keyDown.scanCode;
+        } // release lock
+
         nsecs_t when = systemTime(SYSTEM_TIME_MONOTONIC);
-        processKey(when, false, keyDown.keyCode, keyDown.scanCode, 0);
+        processKey(when, false, keyCode, scanCode, 0);
     }
 
     InputMapper::reset();
-
-    // Reinitialize.
-    initialize();
     getContext()->updateGlobalMetaState();
 }
 
@@ -768,56 +778,76 @@
         || (scanCode >= BTN_GAMEPAD && scanCode < BTN_DIGI);
 }
 
-void KeyboardInputMapper::processKey(nsecs_t when, bool down, int32_t keyCode, int32_t scanCode,
-        uint32_t policyFlags) {
-    if (down) {
-        // Rotate key codes according to orientation.
-        if (mAssociatedDisplayId >= 0) {
-            int32_t orientation;
-            if (! getPolicy()->getDisplayInfo(mAssociatedDisplayId, NULL, NULL, & orientation)) {
-                return;
+void KeyboardInputMapper::processKey(nsecs_t when, bool down, int32_t keyCode,
+        int32_t scanCode, uint32_t policyFlags) {
+    int32_t newMetaState;
+    nsecs_t downTime;
+    bool metaStateChanged = false;
+
+    { // acquire lock
+        AutoMutex _l(mLock);
+
+        if (down) {
+            // Rotate key codes according to orientation if needed.
+            // Note: getDisplayInfo is non-reentrant so we can continue holding the lock.
+            if (mAssociatedDisplayId >= 0) {
+                int32_t orientation;
+                if (! getPolicy()->getDisplayInfo(mAssociatedDisplayId, NULL, NULL, & orientation)) {
+                    return;
+                }
+
+                keyCode = rotateKeyCode(keyCode, orientation);
             }
 
-            keyCode = rotateKeyCode(keyCode, orientation);
+            // Add key down.
+            ssize_t keyDownIndex = findKeyDownLocked(scanCode);
+            if (keyDownIndex >= 0) {
+                // key repeat, be sure to use same keycode as before in case of rotation
+                keyCode = mLocked.keyDowns.top().keyCode;
+            } else {
+                // key down
+                mLocked.keyDowns.push();
+                KeyDown& keyDown = mLocked.keyDowns.editTop();
+                keyDown.keyCode = keyCode;
+                keyDown.scanCode = scanCode;
+            }
+
+            mLocked.downTime = when;
+        } else {
+            // Remove key down.
+            ssize_t keyDownIndex = findKeyDownLocked(scanCode);
+            if (keyDownIndex >= 0) {
+                // key up, be sure to use same keycode as before in case of rotation
+                keyCode = mLocked.keyDowns.top().keyCode;
+                mLocked.keyDowns.removeAt(size_t(keyDownIndex));
+            } else {
+                // key was not actually down
+                LOGI("Dropping key up from device %s because the key was not down.  "
+                        "keyCode=%d, scanCode=%d",
+                        getDeviceName().string(), keyCode, scanCode);
+                return;
+            }
         }
 
-        // Add key down.
-        ssize_t keyDownIndex = findKeyDown(scanCode);
-        if (keyDownIndex >= 0) {
-            // key repeat, be sure to use same keycode as before in case of rotation
-            keyCode = mKeyDowns.top().keyCode;
-        } else {
-            // key down
-            mKeyDowns.push();
-            KeyDown& keyDown = mKeyDowns.editTop();
-            keyDown.keyCode = keyCode;
-            keyDown.scanCode = scanCode;
+        int32_t oldMetaState = mLocked.metaState;
+        newMetaState = updateMetaState(keyCode, down, oldMetaState);
+        if (oldMetaState != newMetaState) {
+            mLocked.metaState = newMetaState;
+            metaStateChanged = true;
         }
-    } else {
-        // Remove key down.
-        ssize_t keyDownIndex = findKeyDown(scanCode);
-        if (keyDownIndex >= 0) {
-            // key up, be sure to use same keycode as before in case of rotation
-            keyCode = mKeyDowns.top().keyCode;
-            mKeyDowns.removeAt(size_t(keyDownIndex));
-        } else {
-            // key was not actually down
-            LOGI("Dropping key up from device %s because the key was not down.  "
-                    "keyCode=%d, scanCode=%d",
-                    getDeviceName().string(), keyCode, scanCode);
-            return;
-        }
-    }
 
-    int32_t oldMetaState = mMetaState;
-    int32_t newMetaState = updateMetaState(keyCode, down, oldMetaState);
-    if (oldMetaState != newMetaState) {
-        mMetaState = newMetaState;
+        downTime = mLocked.downTime;
+    } // release lock
+
+    if (metaStateChanged) {
         getContext()->updateGlobalMetaState();
     }
 
-    /* Apply policy. */
+    applyPolicyAndDispatch(when, policyFlags, down, keyCode, scanCode, newMetaState, downTime);
+}
 
+void KeyboardInputMapper::applyPolicyAndDispatch(nsecs_t when, uint32_t policyFlags, bool down,
+        int32_t keyCode, int32_t scanCode, int32_t metaState, nsecs_t downTime) {
     int32_t policyActions = getPolicy()->interceptKey(when,
             getDeviceId(), down, keyCode, scanCode, policyFlags);
 
@@ -825,30 +855,20 @@
         return; // event dropped
     }
 
-    /* Enqueue key event for dispatch. */
-
-    int32_t keyEventAction;
-    if (down) {
-        mDownTime = when;
-        keyEventAction = AKEY_EVENT_ACTION_DOWN;
-    } else {
-        keyEventAction = AKEY_EVENT_ACTION_UP;
-    }
-
+    int32_t keyEventAction = down ? AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP;
     int32_t keyEventFlags = AKEY_EVENT_FLAG_FROM_SYSTEM;
     if (policyFlags & POLICY_FLAG_WOKE_HERE) {
         keyEventFlags = keyEventFlags | AKEY_EVENT_FLAG_WOKE_HERE;
     }
 
     getDispatcher()->notifyKey(when, getDeviceId(), AINPUT_SOURCE_KEYBOARD, policyFlags,
-            keyEventAction, keyEventFlags, keyCode, scanCode,
-            mMetaState, mDownTime);
+            keyEventAction, keyEventFlags, keyCode, scanCode, metaState, downTime);
 }
 
-ssize_t KeyboardInputMapper::findKeyDown(int32_t scanCode) {
-    size_t n = mKeyDowns.size();
+ssize_t KeyboardInputMapper::findKeyDownLocked(int32_t scanCode) {
+    size_t n = mLocked.keyDowns.size();
     for (size_t i = 0; i < n; i++) {
-        if (mKeyDowns[i].scanCode == scanCode) {
+        if (mLocked.keyDowns[i].scanCode == scanCode) {
             return i;
         }
     }
@@ -869,7 +889,10 @@
 }
 
 int32_t KeyboardInputMapper::getMetaState() {
-    return mMetaState;
+    { // acquire lock
+        AutoMutex _l(mLock);
+        return mLocked.metaState;
+    } // release lock
 }
 
 
@@ -882,7 +905,7 @@
     mXScale = 1.0f / TRACKBALL_MOVEMENT_THRESHOLD;
     mYScale = 1.0f / TRACKBALL_MOVEMENT_THRESHOLD;
 
-    initialize();
+    initializeLocked();
 }
 
 TrackballInputMapper::~TrackballInputMapper() {
@@ -899,26 +922,33 @@
     info->addMotionRange(AINPUT_MOTION_RANGE_Y, -1.0f, 1.0f, 0.0f, mYScale);
 }
 
-void TrackballInputMapper::initialize() {
+void TrackballInputMapper::initializeLocked() {
     mAccumulator.clear();
 
-    mDown = false;
-    mDownTime = 0;
+    mLocked.down = false;
+    mLocked.downTime = 0;
 }
 
 void TrackballInputMapper::reset() {
-    // Synthesize trackball button up event on reset if trackball button is currently down.
-    if (mDown) {
+    for (;;) {
+        { // acquire lock
+            AutoMutex _l(mLock);
+
+            if (! mLocked.down) {
+                initializeLocked();
+                break; // done
+            }
+        } // release lock
+
+        // Synthesize trackball button up event on reset.
         nsecs_t when = systemTime(SYSTEM_TIME_MONOTONIC);
-        mAccumulator.fields |= Accumulator::FIELD_BTN_MOUSE;
+        mAccumulator.fields = Accumulator::FIELD_BTN_MOUSE;
         mAccumulator.btnMouse = false;
         sync(when);
+        mAccumulator.clear();
     }
 
     InputMapper::reset();
-
-    // Reinitialize.
-    initialize();
 }
 
 void TrackballInputMapper::process(const RawEvent* rawEvent) {
@@ -962,33 +992,79 @@
 }
 
 void TrackballInputMapper::sync(nsecs_t when) {
-    /* Get display properties so for rotation based on display orientation. */
+    int motionEventAction;
+    PointerCoords pointerCoords;
+    nsecs_t downTime;
+    { // acquire lock
+        AutoMutex _l(mLock);
 
-    int32_t orientation;
-    if (mAssociatedDisplayId >= 0) {
-        if (! getPolicy()->getDisplayInfo(mAssociatedDisplayId, NULL, NULL, & orientation)) {
-            return;
+        uint32_t fields = mAccumulator.fields;
+        bool downChanged = fields & Accumulator::FIELD_BTN_MOUSE;
+
+        if (downChanged) {
+            if (mAccumulator.btnMouse) {
+                mLocked.down = true;
+                mLocked.downTime = when;
+            } else {
+                mLocked.down = false;
+            }
         }
-    } else {
-        orientation = InputReaderPolicyInterface::ROTATION_0;
-    }
 
-    /* Update saved trackball state */
+        downTime = mLocked.downTime;
+        float x = fields & Accumulator::FIELD_REL_X ? mAccumulator.relX * mXScale : 0.0f;
+        float y = fields & Accumulator::FIELD_REL_Y ? mAccumulator.relY * mYScale : 0.0f;
 
-    uint32_t fields = mAccumulator.fields;
-    bool downChanged = fields & Accumulator::FIELD_BTN_MOUSE;
-
-    if (downChanged) {
-        if (mAccumulator.btnMouse) {
-            mDown = true;
-            mDownTime = when;
+        if (downChanged) {
+            motionEventAction = mLocked.down ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
         } else {
-            mDown = false;
+            motionEventAction = AMOTION_EVENT_ACTION_MOVE;
         }
-    }
 
-    /* Apply policy */
+        pointerCoords.x = x;
+        pointerCoords.y = y;
+        pointerCoords.pressure = mLocked.down ? 1.0f : 0.0f;
+        pointerCoords.size = 0;
+        pointerCoords.touchMajor = 0;
+        pointerCoords.touchMinor = 0;
+        pointerCoords.toolMajor = 0;
+        pointerCoords.toolMinor = 0;
+        pointerCoords.orientation = 0;
 
+        if (mAssociatedDisplayId >= 0 && (x != 0.0f || y != 0.0f)) {
+            // Rotate motion based on display orientation if needed.
+            // Note: getDisplayInfo is non-reentrant so we can continue holding the lock.
+            int32_t orientation;
+            if (! getPolicy()->getDisplayInfo(mAssociatedDisplayId, NULL, NULL, & orientation)) {
+                return;
+            }
+
+            float temp;
+            switch (orientation) {
+            case InputReaderPolicyInterface::ROTATION_90:
+                temp = pointerCoords.x;
+                pointerCoords.x = pointerCoords.y;
+                pointerCoords.y = - temp;
+                break;
+
+            case InputReaderPolicyInterface::ROTATION_180:
+                pointerCoords.x = - pointerCoords.x;
+                pointerCoords.y = - pointerCoords.y;
+                break;
+
+            case InputReaderPolicyInterface::ROTATION_270:
+                temp = pointerCoords.x;
+                pointerCoords.x = - pointerCoords.y;
+                pointerCoords.y = temp;
+                break;
+            }
+        }
+    } // release lock
+
+    applyPolicyAndDispatch(when, motionEventAction, & pointerCoords, downTime);
+}
+
+void TrackballInputMapper::applyPolicyAndDispatch(nsecs_t when, int32_t motionEventAction,
+        PointerCoords* pointerCoords, nsecs_t downTime) {
     uint32_t policyFlags = 0;
     int32_t policyActions = getPolicy()->interceptGeneric(when, policyFlags);
 
@@ -996,62 +1072,24 @@
         return; // event dropped
     }
 
-    /* Enqueue motion event for dispatch. */
-
-    int32_t motionEventAction;
-    if (downChanged) {
-        motionEventAction = mDown ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
-    } else {
-        motionEventAction = AMOTION_EVENT_ACTION_MOVE;
-    }
-
-    int32_t pointerId = 0;
-    PointerCoords pointerCoords;
-    pointerCoords.x = fields & Accumulator::FIELD_REL_X
-            ? mAccumulator.relX * mXScale : 0;
-    pointerCoords.y = fields & Accumulator::FIELD_REL_Y
-            ? mAccumulator.relY * mYScale : 0;
-    pointerCoords.pressure = 1.0f; // XXX Consider making this 1.0f if down, 0 otherwise.
-    pointerCoords.size = 0;
-    pointerCoords.touchMajor = 0;
-    pointerCoords.touchMinor = 0;
-    pointerCoords.toolMajor = 0;
-    pointerCoords.toolMinor = 0;
-    pointerCoords.orientation = 0;
-
-    float temp;
-    switch (orientation) {
-    case InputReaderPolicyInterface::ROTATION_90:
-        temp = pointerCoords.x;
-        pointerCoords.x = pointerCoords.y;
-        pointerCoords.y = - temp;
-        break;
-
-    case InputReaderPolicyInterface::ROTATION_180:
-        pointerCoords.x = - pointerCoords.x;
-        pointerCoords.y = - pointerCoords.y;
-        break;
-
-    case InputReaderPolicyInterface::ROTATION_270:
-        temp = pointerCoords.x;
-        pointerCoords.x = - pointerCoords.y;
-        pointerCoords.y = temp;
-        break;
-    }
-
     int32_t metaState = mContext->getGlobalMetaState();
+    int32_t pointerId = 0;
+
     getDispatcher()->notifyMotion(when, getDeviceId(), AINPUT_SOURCE_TRACKBALL, policyFlags,
             motionEventAction, metaState, AMOTION_EVENT_EDGE_FLAG_NONE,
-            1, & pointerId, & pointerCoords, mXPrecision, mYPrecision, mDownTime);
+            1, & pointerId, pointerCoords, mXPrecision, mYPrecision, downTime);
 }
 
 
 // --- TouchInputMapper ---
 
 TouchInputMapper::TouchInputMapper(InputDevice* device, int32_t associatedDisplayId) :
-        InputMapper(device), mAssociatedDisplayId(associatedDisplayId),
-        mSurfaceOrientation(-1), mSurfaceWidth(-1), mSurfaceHeight(-1) {
-    initialize();
+        InputMapper(device), mAssociatedDisplayId(associatedDisplayId) {
+    mLocked.surfaceOrientation = -1;
+    mLocked.surfaceWidth = -1;
+    mLocked.surfaceHeight = -1;
+
+    initializeLocked();
 }
 
 TouchInputMapper::~TouchInputMapper() {
@@ -1064,26 +1102,29 @@
 void TouchInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
     InputMapper::populateDeviceInfo(info);
 
-    // FIXME: Should ensure the surface information is up to date so that orientation changes
-    // are noticed immediately.  Unfortunately we will need to add some extra locks here
-    // to prevent race conditions.
-    // configureSurface();
+    { // acquire lock
+        AutoMutex _l(mLock);
 
-    info->addMotionRange(AINPUT_MOTION_RANGE_X, mOrientedRanges.x);
-    info->addMotionRange(AINPUT_MOTION_RANGE_Y, mOrientedRanges.y);
-    info->addMotionRange(AINPUT_MOTION_RANGE_PRESSURE, mOrientedRanges.pressure);
-    info->addMotionRange(AINPUT_MOTION_RANGE_SIZE, mOrientedRanges.size);
-    info->addMotionRange(AINPUT_MOTION_RANGE_TOUCH_MAJOR, mOrientedRanges.touchMajor);
-    info->addMotionRange(AINPUT_MOTION_RANGE_TOUCH_MINOR, mOrientedRanges.touchMinor);
-    info->addMotionRange(AINPUT_MOTION_RANGE_TOOL_MAJOR, mOrientedRanges.toolMajor);
-    info->addMotionRange(AINPUT_MOTION_RANGE_TOOL_MINOR, mOrientedRanges.toolMinor);
-    info->addMotionRange(AINPUT_MOTION_RANGE_ORIENTATION, mOrientedRanges.orientation);
+        // Ensure surface information is up to date so that orientation changes are
+        // noticed immediately.
+        configureSurfaceLocked();
+
+        info->addMotionRange(AINPUT_MOTION_RANGE_X, mLocked.orientedRanges.x);
+        info->addMotionRange(AINPUT_MOTION_RANGE_Y, mLocked.orientedRanges.y);
+        info->addMotionRange(AINPUT_MOTION_RANGE_PRESSURE, mLocked.orientedRanges.pressure);
+        info->addMotionRange(AINPUT_MOTION_RANGE_SIZE, mLocked.orientedRanges.size);
+        info->addMotionRange(AINPUT_MOTION_RANGE_TOUCH_MAJOR, mLocked.orientedRanges.touchMajor);
+        info->addMotionRange(AINPUT_MOTION_RANGE_TOUCH_MINOR, mLocked.orientedRanges.touchMinor);
+        info->addMotionRange(AINPUT_MOTION_RANGE_TOOL_MAJOR, mLocked.orientedRanges.toolMajor);
+        info->addMotionRange(AINPUT_MOTION_RANGE_TOOL_MINOR, mLocked.orientedRanges.toolMinor);
+        info->addMotionRange(AINPUT_MOTION_RANGE_ORIENTATION, mLocked.orientedRanges.orientation);
+    } // release lock
 }
 
-void TouchInputMapper::initialize() {
+void TouchInputMapper::initializeLocked() {
+    mCurrentTouch.clear();
     mLastTouch.clear();
     mDownTime = 0;
-    mCurrentVirtualKey.down = false;
 
     for (uint32_t i = 0; i < MAX_POINTERS; i++) {
         mAveragingTouchFilter.historyStart[i] = 0;
@@ -1091,6 +1132,8 @@
     }
 
     mJumpyTouchFilter.jumpyPointsDropped = 0;
+
+    mLocked.currentVirtualKey.down = false;
 }
 
 void TouchInputMapper::configure() {
@@ -1104,48 +1147,52 @@
     // Configure absolute axis information.
     configureAxes();
 
-    // Configure pressure factors.
-    if (mAxes.pressure.valid) {
-        mPressureOrigin = mAxes.pressure.minValue;
-        mPressureScale = 1.0f / mAxes.pressure.getRange();
-    } else {
-        mPressureOrigin = 0;
-        mPressureScale = 1.0f;
-    }
+    { // acquire lock
+        AutoMutex _l(mLock);
 
-    mOrientedRanges.pressure.min = 0.0f;
-    mOrientedRanges.pressure.max = 1.0f;
-    mOrientedRanges.pressure.flat = 0.0f;
-    mOrientedRanges.pressure.fuzz = mPressureScale;
+        // Configure pressure factors.
+        if (mAxes.pressure.valid) {
+            mLocked.pressureOrigin = mAxes.pressure.minValue;
+            mLocked.pressureScale = 1.0f / mAxes.pressure.getRange();
+        } else {
+            mLocked.pressureOrigin = 0;
+            mLocked.pressureScale = 1.0f;
+        }
 
-    // Configure size factors.
-    if (mAxes.size.valid) {
-        mSizeOrigin = mAxes.size.minValue;
-        mSizeScale = 1.0f / mAxes.size.getRange();
-    } else {
-        mSizeOrigin = 0;
-        mSizeScale = 1.0f;
-    }
+        mLocked.orientedRanges.pressure.min = 0.0f;
+        mLocked.orientedRanges.pressure.max = 1.0f;
+        mLocked.orientedRanges.pressure.flat = 0.0f;
+        mLocked.orientedRanges.pressure.fuzz = mLocked.pressureScale;
 
-    mOrientedRanges.size.min = 0.0f;
-    mOrientedRanges.size.max = 1.0f;
-    mOrientedRanges.size.flat = 0.0f;
-    mOrientedRanges.size.fuzz = mSizeScale;
+        // Configure size factors.
+        if (mAxes.size.valid) {
+            mLocked.sizeOrigin = mAxes.size.minValue;
+            mLocked.sizeScale = 1.0f / mAxes.size.getRange();
+        } else {
+            mLocked.sizeOrigin = 0;
+            mLocked.sizeScale = 1.0f;
+        }
 
-    // Configure orientation factors.
-    if (mAxes.orientation.valid && mAxes.orientation.maxValue > 0) {
-        mOrientationScale = float(M_PI_2) / mAxes.orientation.maxValue;
-    } else {
-        mOrientationScale = 0.0f;
-    }
+        mLocked.orientedRanges.size.min = 0.0f;
+        mLocked.orientedRanges.size.max = 1.0f;
+        mLocked.orientedRanges.size.flat = 0.0f;
+        mLocked.orientedRanges.size.fuzz = mLocked.sizeScale;
 
-    mOrientedRanges.orientation.min = - M_PI_2;
-    mOrientedRanges.orientation.max = M_PI_2;
-    mOrientedRanges.orientation.flat = 0;
-    mOrientedRanges.orientation.fuzz = mOrientationScale;
+        // Configure orientation factors.
+        if (mAxes.orientation.valid && mAxes.orientation.maxValue > 0) {
+            mLocked.orientationScale = float(M_PI_2) / mAxes.orientation.maxValue;
+        } else {
+            mLocked.orientationScale = 0.0f;
+        }
 
-    // Configure surface dimensions and orientation.
-    configureSurface();
+        mLocked.orientedRanges.orientation.min = - M_PI_2;
+        mLocked.orientedRanges.orientation.max = M_PI_2;
+        mLocked.orientedRanges.orientation.flat = 0;
+        mLocked.orientedRanges.orientation.fuzz = mLocked.orientationScale;
+
+        // Configure surface dimensions and orientation.
+        configureSurfaceLocked();
+    } // release lock
 }
 
 void TouchInputMapper::configureAxes() {
@@ -1160,11 +1207,12 @@
     mAxes.orientation.valid = false;
 }
 
-bool TouchInputMapper::configureSurface() {
+bool TouchInputMapper::configureSurfaceLocked() {
     // Update orientation and dimensions if needed.
     int32_t orientation;
     int32_t width, height;
     if (mAssociatedDisplayId >= 0) {
+        // Note: getDisplayInfo is non-reentrant so we can continue holding the lock.
         if (! getPolicy()->getDisplayInfo(mAssociatedDisplayId, & width, & height, & orientation)) {
             return false;
         }
@@ -1174,150 +1222,152 @@
         height = mAxes.y.getRange();
     }
 
-    bool orientationChanged = mSurfaceOrientation != orientation;
+    bool orientationChanged = mLocked.surfaceOrientation != orientation;
     if (orientationChanged) {
-        mSurfaceOrientation = orientation;
+        mLocked.surfaceOrientation = orientation;
     }
 
-    bool sizeChanged = mSurfaceWidth != width || mSurfaceHeight != height;
+    bool sizeChanged = mLocked.surfaceWidth != width || mLocked.surfaceHeight != height;
     if (sizeChanged) {
-        mSurfaceWidth = width;
-        mSurfaceHeight = height;
+        mLocked.surfaceWidth = width;
+        mLocked.surfaceHeight = height;
 
         // Compute size-dependent translation and scaling factors and place virtual keys.
         if (mAxes.x.valid && mAxes.y.valid) {
-            mXOrigin = mAxes.x.minValue;
-            mYOrigin = mAxes.y.minValue;
+            mLocked.xOrigin = mAxes.x.minValue;
+            mLocked.yOrigin = mAxes.y.minValue;
 
             LOGI("Device configured: id=0x%x, name=%s (display size was changed)",
                     getDeviceId(), getDeviceName().string());
 
-            mXScale = float(width) / mAxes.x.getRange();
-            mYScale = float(height) / mAxes.y.getRange();
-            mXPrecision = 1.0f / mXScale;
-            mYPrecision = 1.0f / mYScale;
+            mLocked.xScale = float(width) / mAxes.x.getRange();
+            mLocked.yScale = float(height) / mAxes.y.getRange();
+            mLocked.xPrecision = 1.0f / mLocked.xScale;
+            mLocked.yPrecision = 1.0f / mLocked.yScale;
 
-            configureVirtualKeys();
+            configureVirtualKeysLocked();
         } else {
-            mXOrigin = 0;
-            mYOrigin = 0;
-            mXScale = 1.0f;
-            mYScale = 1.0f;
-            mXPrecision = 1.0f;
-            mYPrecision = 1.0f;
+            mLocked.xOrigin = 0;
+            mLocked.yOrigin = 0;
+            mLocked.xScale = 1.0f;
+            mLocked.yScale = 1.0f;
+            mLocked.xPrecision = 1.0f;
+            mLocked.yPrecision = 1.0f;
         }
 
         // Configure touch and tool area ranges.
         float diagonal = sqrt(float(width * width + height * height));
-        float diagonalFuzz = sqrt(mXScale * mXScale + mYScale * mYScale);
+        float diagonalFuzz = sqrt(mLocked.xScale * mLocked.xScale
+                + mLocked.yScale * mLocked.yScale);
 
-        mOrientedRanges.touchMajor.min = 0.0f;
-        mOrientedRanges.touchMajor.max = diagonal;
-        mOrientedRanges.touchMajor.flat = 0.0f;
-        mOrientedRanges.touchMajor.fuzz = diagonalFuzz;
-        mOrientedRanges.touchMinor = mOrientedRanges.touchMajor;
+        InputDeviceInfo::MotionRange area;
+        area.min = 0.0f;
+        area.max = diagonal;
+        area.flat = 0.0f;
+        area.fuzz = diagonalFuzz;
 
-        mOrientedRanges.toolMinor = mOrientedRanges.toolMajor = mOrientedRanges.touchMajor;
+        mLocked.orientedRanges.touchMajor = area;
+        mLocked.orientedRanges.touchMinor = area;
+
+        mLocked.orientedRanges.toolMajor = area;
+        mLocked.orientedRanges.toolMinor = area;
     }
 
     if (orientationChanged || sizeChanged) {
         // Compute oriented surface dimensions, precision, and scales.
         float orientedXScale, orientedYScale;
-        switch (mSurfaceOrientation) {
+        switch (mLocked.surfaceOrientation) {
         case InputReaderPolicyInterface::ROTATION_90:
         case InputReaderPolicyInterface::ROTATION_270:
-            mOrientedSurfaceWidth = mSurfaceHeight;
-            mOrientedSurfaceHeight = mSurfaceWidth;
-            mOrientedXPrecision = mYPrecision;
-            mOrientedYPrecision = mXPrecision;
-            orientedXScale = mYScale;
-            orientedYScale = mXScale;
+            mLocked.orientedSurfaceWidth = mLocked.surfaceHeight;
+            mLocked.orientedSurfaceHeight = mLocked.surfaceWidth;
+            mLocked.orientedXPrecision = mLocked.yPrecision;
+            mLocked.orientedYPrecision = mLocked.xPrecision;
+            orientedXScale = mLocked.yScale;
+            orientedYScale = mLocked.xScale;
             break;
         default:
-            mOrientedSurfaceWidth = mSurfaceWidth;
-            mOrientedSurfaceHeight = mSurfaceHeight;
-            mOrientedXPrecision = mXPrecision;
-            mOrientedYPrecision = mYPrecision;
-            orientedXScale = mXScale;
-            orientedYScale = mYScale;
+            mLocked.orientedSurfaceWidth = mLocked.surfaceWidth;
+            mLocked.orientedSurfaceHeight = mLocked.surfaceHeight;
+            mLocked.orientedXPrecision = mLocked.xPrecision;
+            mLocked.orientedYPrecision = mLocked.yPrecision;
+            orientedXScale = mLocked.xScale;
+            orientedYScale = mLocked.yScale;
             break;
         }
 
         // Configure position ranges.
-        mOrientedRanges.x.min = 0;
-        mOrientedRanges.x.max = mOrientedSurfaceWidth;
-        mOrientedRanges.x.flat = 0;
-        mOrientedRanges.x.fuzz = orientedXScale;
+        mLocked.orientedRanges.x.min = 0;
+        mLocked.orientedRanges.x.max = mLocked.orientedSurfaceWidth;
+        mLocked.orientedRanges.x.flat = 0;
+        mLocked.orientedRanges.x.fuzz = orientedXScale;
 
-        mOrientedRanges.y.min = 0;
-        mOrientedRanges.y.max = mOrientedSurfaceHeight;
-        mOrientedRanges.y.flat = 0;
-        mOrientedRanges.y.fuzz = orientedYScale;
+        mLocked.orientedRanges.y.min = 0;
+        mLocked.orientedRanges.y.max = mLocked.orientedSurfaceHeight;
+        mLocked.orientedRanges.y.flat = 0;
+        mLocked.orientedRanges.y.fuzz = orientedYScale;
     }
 
     return true;
 }
 
-void TouchInputMapper::configureVirtualKeys() {
+void TouchInputMapper::configureVirtualKeysLocked() {
     assert(mAxes.x.valid && mAxes.y.valid);
 
+    // Note: getVirtualKeyDefinitions is non-reentrant so we can continue holding the lock.
     Vector<InputReaderPolicyInterface::VirtualKeyDefinition> virtualKeyDefinitions;
     getPolicy()->getVirtualKeyDefinitions(getDeviceName(), virtualKeyDefinitions);
 
-    { // acquire virtual key lock
-        AutoMutex _l(mVirtualKeyLock);
+    mLocked.virtualKeys.clear();
 
-        mVirtualKeys.clear();
+    if (virtualKeyDefinitions.size() == 0) {
+        return;
+    }
 
-        if (virtualKeyDefinitions.size() == 0) {
-            return;
+    mLocked.virtualKeys.setCapacity(virtualKeyDefinitions.size());
+
+    int32_t touchScreenLeft = mAxes.x.minValue;
+    int32_t touchScreenTop = mAxes.y.minValue;
+    int32_t touchScreenWidth = mAxes.x.getRange();
+    int32_t touchScreenHeight = mAxes.y.getRange();
+
+    for (size_t i = 0; i < virtualKeyDefinitions.size(); i++) {
+        const InputReaderPolicyInterface::VirtualKeyDefinition& virtualKeyDefinition =
+                virtualKeyDefinitions[i];
+
+        mLocked.virtualKeys.add();
+        VirtualKey& virtualKey = mLocked.virtualKeys.editTop();
+
+        virtualKey.scanCode = virtualKeyDefinition.scanCode;
+        int32_t keyCode;
+        uint32_t flags;
+        if (getEventHub()->scancodeToKeycode(getDeviceId(), virtualKey.scanCode,
+                & keyCode, & flags)) {
+            LOGW("  VirtualKey %d: could not obtain key code, ignoring", virtualKey.scanCode);
+            mLocked.virtualKeys.pop(); // drop the key
+            continue;
         }
 
-        mVirtualKeys.setCapacity(virtualKeyDefinitions.size());
+        virtualKey.keyCode = keyCode;
+        virtualKey.flags = flags;
 
-        int32_t touchScreenLeft = mAxes.x.minValue;
-        int32_t touchScreenTop = mAxes.y.minValue;
-        int32_t touchScreenWidth = mAxes.x.getRange();
-        int32_t touchScreenHeight = mAxes.y.getRange();
+        // convert the key definition's display coordinates into touch coordinates for a hit box
+        int32_t halfWidth = virtualKeyDefinition.width / 2;
+        int32_t halfHeight = virtualKeyDefinition.height / 2;
 
-        for (size_t i = 0; i < virtualKeyDefinitions.size(); i++) {
-            const InputReaderPolicyInterface::VirtualKeyDefinition& virtualKeyDefinition =
-                    virtualKeyDefinitions[i];
+        virtualKey.hitLeft = (virtualKeyDefinition.centerX - halfWidth)
+                * touchScreenWidth / mLocked.surfaceWidth + touchScreenLeft;
+        virtualKey.hitRight= (virtualKeyDefinition.centerX + halfWidth)
+                * touchScreenWidth / mLocked.surfaceWidth + touchScreenLeft;
+        virtualKey.hitTop = (virtualKeyDefinition.centerY - halfHeight)
+                * touchScreenHeight / mLocked.surfaceHeight + touchScreenTop;
+        virtualKey.hitBottom = (virtualKeyDefinition.centerY + halfHeight)
+                * touchScreenHeight / mLocked.surfaceHeight + touchScreenTop;
 
-            mVirtualKeys.add();
-            VirtualKey& virtualKey = mVirtualKeys.editTop();
-
-            virtualKey.scanCode = virtualKeyDefinition.scanCode;
-            int32_t keyCode;
-            uint32_t flags;
-            if (getEventHub()->scancodeToKeycode(getDeviceId(), virtualKey.scanCode,
-                    & keyCode, & flags)) {
-                LOGW("  VirtualKey %d: could not obtain key code, ignoring", virtualKey.scanCode);
-                mVirtualKeys.pop(); // drop the key
-                continue;
-            }
-
-            virtualKey.keyCode = keyCode;
-            virtualKey.flags = flags;
-
-            // convert the key definition's display coordinates into touch coordinates for a hit box
-            int32_t halfWidth = virtualKeyDefinition.width / 2;
-            int32_t halfHeight = virtualKeyDefinition.height / 2;
-
-            virtualKey.hitLeft = (virtualKeyDefinition.centerX - halfWidth)
-                    * touchScreenWidth / mSurfaceWidth + touchScreenLeft;
-            virtualKey.hitRight= (virtualKeyDefinition.centerX + halfWidth)
-                    * touchScreenWidth / mSurfaceWidth + touchScreenLeft;
-            virtualKey.hitTop = (virtualKeyDefinition.centerY - halfHeight)
-                    * touchScreenHeight / mSurfaceHeight + touchScreenTop;
-            virtualKey.hitBottom = (virtualKeyDefinition.centerY + halfHeight)
-                    * touchScreenHeight / mSurfaceHeight + touchScreenTop;
-
-            LOGI("  VirtualKey %d: keyCode=%d hitLeft=%d hitRight=%d hitTop=%d hitBottom=%d",
-                    virtualKey.scanCode, virtualKey.keyCode,
-                    virtualKey.hitLeft, virtualKey.hitRight, virtualKey.hitTop, virtualKey.hitBottom);
-        }
-    } // release virtual key lock
+        LOGI("  VirtualKey %d: keyCode=%d hitLeft=%d hitRight=%d hitTop=%d hitBottom=%d",
+                virtualKey.scanCode, virtualKey.keyCode,
+                virtualKey.hitLeft, virtualKey.hitRight, virtualKey.hitTop, virtualKey.hitBottom);
+    }
 }
 
 void TouchInputMapper::reset() {
@@ -1329,20 +1379,16 @@
         syncTouch(when, true);
     }
 
-    InputMapper::reset();
+    { // acquire lock
+        AutoMutex _l(mLock);
+        initializeLocked();
+    } // release lock
 
-    // Reinitialize.
-    initialize();
+    InputMapper::reset();
 }
 
 void TouchInputMapper::syncTouch(nsecs_t when, bool havePointerIds) {
-    /* Refresh associated display information and update our size configuration if needed. */
-
-    if (! configureSurface()) {
-        return;
-    }
-
-    /* Apply policy */
+    // Apply generic policy actions.
 
     uint32_t policyFlags = 0;
     int32_t policyActions = getPolicy()->interceptGeneric(when, policyFlags);
@@ -1352,7 +1398,7 @@
         return; // event dropped
     }
 
-    /* Preprocess pointer data */
+    // Preprocess pointer data.
 
     if (mParameters.useBadTouchFilter) {
         if (applyBadTouchFilter()) {
@@ -1381,14 +1427,14 @@
         savedTouch = & mCurrentTouch;
     }
 
-    /* Process touches and virtual keys */
+    // Process touches and virtual keys.
 
     TouchResult touchResult = consumeOffScreenTouches(when, policyFlags);
     if (touchResult == DISPATCH_TOUCH) {
         dispatchTouches(when, policyFlags);
     }
 
-    /* Copy current touch to last touch in preparation for the next cycle. */
+    // Copy current touch to last touch in preparation for the next cycle.
 
     if (touchResult == DROP_STROKE) {
         mLastTouch.clear();
@@ -1403,13 +1449,19 @@
     int32_t keyCode, scanCode, downTime;
     TouchResult touchResult;
 
-    { // acquire virtual key lock
-        AutoMutex _l(mVirtualKeyLock);
+    { // acquire lock
+        AutoMutex _l(mLock);
 
-        if (mCurrentVirtualKey.down) {
+        // Update surface size and orientation, including virtual key positions.
+        if (! configureSurfaceLocked()) {
+            return DROP_STROKE;
+        }
+
+        // Check for virtual key press.
+        if (mLocked.currentVirtualKey.down) {
             if (mCurrentTouch.pointerCount == 0) {
                 // Pointer went up while virtual key was down.
-                mCurrentVirtualKey.down = false;
+                mLocked.currentVirtualKey.down = false;
 #if DEBUG_VIRTUAL_KEYS
                 LOGD("VirtualKeys: Generating key up: keyCode=%d, scanCode=%d",
                         mCurrentVirtualKey.keyCode, mCurrentVirtualKey.scanCode);
@@ -1423,8 +1475,8 @@
             if (mCurrentTouch.pointerCount == 1) {
                 int32_t x = mCurrentTouch.pointers[0].x;
                 int32_t y = mCurrentTouch.pointers[0].y;
-                const VirtualKey* virtualKey = findVirtualKeyHitLvk(x, y);
-                if (virtualKey && virtualKey->keyCode == mCurrentVirtualKey.keyCode) {
+                const VirtualKey* virtualKey = findVirtualKeyHitLocked(x, y);
+                if (virtualKey && virtualKey->keyCode == mLocked.currentVirtualKey.keyCode) {
                     // Pointer is still within the space of the virtual key.
                     return SKIP_TOUCH;
                 }
@@ -1434,7 +1486,7 @@
             // Send key cancellation and drop the stroke so subsequent motions will be
             // considered fresh downs.  This is useful when the user swipes away from the
             // virtual key area into the main display surface.
-            mCurrentVirtualKey.down = false;
+            mLocked.currentVirtualKey.down = false;
 #if DEBUG_VIRTUAL_KEYS
             LOGD("VirtualKeys: Canceling key: keyCode=%d, scanCode=%d",
                     mCurrentVirtualKey.keyCode, mCurrentVirtualKey.scanCode);
@@ -1449,16 +1501,16 @@
                 // Pointer just went down.  Handle off-screen touches, if needed.
                 int32_t x = mCurrentTouch.pointers[0].x;
                 int32_t y = mCurrentTouch.pointers[0].y;
-                if (! isPointInsideSurface(x, y)) {
+                if (! isPointInsideSurfaceLocked(x, y)) {
                     // If exactly one pointer went down, check for virtual key hit.
                     // Otherwise we will drop the entire stroke.
                     if (mCurrentTouch.pointerCount == 1) {
-                        const VirtualKey* virtualKey = findVirtualKeyHitLvk(x, y);
+                        const VirtualKey* virtualKey = findVirtualKeyHitLocked(x, y);
                         if (virtualKey) {
-                            mCurrentVirtualKey.down = true;
-                            mCurrentVirtualKey.downTime = when;
-                            mCurrentVirtualKey.keyCode = virtualKey->keyCode;
-                            mCurrentVirtualKey.scanCode = virtualKey->scanCode;
+                            mLocked.currentVirtualKey.down = true;
+                            mLocked.currentVirtualKey.downTime = when;
+                            mLocked.currentVirtualKey.keyCode = virtualKey->keyCode;
+                            mLocked.currentVirtualKey.scanCode = virtualKey->scanCode;
 #if DEBUG_VIRTUAL_KEYS
                             LOGD("VirtualKeys: Generating key down: keyCode=%d, scanCode=%d",
                                     mCurrentVirtualKey.keyCode, mCurrentVirtualKey.scanCode);
@@ -1478,12 +1530,20 @@
 
     DispatchVirtualKey:
         // Collect remaining state needed to dispatch virtual key.
-        keyCode = mCurrentVirtualKey.keyCode;
-        scanCode = mCurrentVirtualKey.scanCode;
-        downTime = mCurrentVirtualKey.downTime;
-    } // release virtual key lock
+        keyCode = mLocked.currentVirtualKey.keyCode;
+        scanCode = mLocked.currentVirtualKey.scanCode;
+        downTime = mLocked.currentVirtualKey.downTime;
+    } // release lock
 
     // Dispatch virtual key.
+    applyPolicyAndDispatchVirtualKey(when, policyFlags, keyEventAction, keyEventFlags,
+            keyCode, scanCode, downTime);
+    return touchResult;
+}
+
+void TouchInputMapper::applyPolicyAndDispatchVirtualKey(nsecs_t when, uint32_t policyFlags,
+        int32_t keyEventAction, int32_t keyEventFlags,
+        int32_t keyCode, int32_t scanCode, nsecs_t downTime) {
     int32_t metaState = mContext->getGlobalMetaState();
 
     if (keyEventAction == AKEY_EVENT_ACTION_DOWN) {
@@ -1497,7 +1557,6 @@
         getDispatcher()->notifyKey(when, getDeviceId(), AINPUT_SOURCE_KEYBOARD, policyFlags,
                 keyEventAction, keyEventFlags, keyCode, scanCode, metaState, downTime);
     }
-    return touchResult;
 }
 
 void TouchInputMapper::dispatchTouches(nsecs_t when, uint32_t policyFlags) {
@@ -1566,107 +1625,118 @@
     uint32_t pointerCount = 0;
     int32_t pointerIds[MAX_POINTERS];
     PointerCoords pointerCoords[MAX_POINTERS];
-
-    // Walk through the the active pointers and map touch screen coordinates (TouchData) into
-    // display coordinates (PointerCoords) and adjust for display orientation.
-    while (! idBits.isEmpty()) {
-        uint32_t id = idBits.firstMarkedBit();
-        idBits.clearBit(id);
-        uint32_t index = touch->idToIndex[id];
-
-        float x = float(touch->pointers[index].x - mXOrigin) * mXScale;
-        float y = float(touch->pointers[index].y - mYOrigin) * mYScale;
-        float pressure = float(touch->pointers[index].pressure - mPressureOrigin) * mPressureScale;
-        float size = float(touch->pointers[index].size - mSizeOrigin) * mSizeScale;
-
-        float orientation = float(touch->pointers[index].orientation) * mOrientationScale;
-
-        float touchMajor, touchMinor, toolMajor, toolMinor;
-        if (abs(orientation) <= M_PI_4) {
-            // Nominally vertical orientation: scale major axis by Y, and scale minor axis by X.
-            touchMajor = float(touch->pointers[index].touchMajor) * mYScale;
-            touchMinor = float(touch->pointers[index].touchMinor) * mXScale;
-            toolMajor = float(touch->pointers[index].toolMajor) * mYScale;
-            toolMinor = float(touch->pointers[index].toolMinor) * mXScale;
-        } else {
-            // Nominally horizontal orientation: scale major axis by X, and scale minor axis by Y.
-            touchMajor = float(touch->pointers[index].touchMajor) * mXScale;
-            touchMinor = float(touch->pointers[index].touchMinor) * mYScale;
-            toolMajor = float(touch->pointers[index].toolMajor) * mXScale;
-            toolMinor = float(touch->pointers[index].toolMinor) * mYScale;
-        }
-
-        switch (mSurfaceOrientation) {
-        case InputReaderPolicyInterface::ROTATION_90: {
-            float xTemp = x;
-            x = y;
-            y = mSurfaceWidth - xTemp;
-            orientation -= M_PI_2;
-            if (orientation < - M_PI_2) {
-                orientation += M_PI;
-            }
-            break;
-        }
-        case InputReaderPolicyInterface::ROTATION_180: {
-            x = mSurfaceWidth - x;
-            y = mSurfaceHeight - y;
-            orientation = - orientation;
-            break;
-        }
-        case InputReaderPolicyInterface::ROTATION_270: {
-            float xTemp = x;
-            x = mSurfaceHeight - y;
-            y = xTemp;
-            orientation += M_PI_2;
-            if (orientation > M_PI_2) {
-                orientation -= M_PI;
-            }
-            break;
-        }
-        }
-
-        pointerIds[pointerCount] = int32_t(id);
-
-        pointerCoords[pointerCount].x = x;
-        pointerCoords[pointerCount].y = y;
-        pointerCoords[pointerCount].pressure = pressure;
-        pointerCoords[pointerCount].size = size;
-        pointerCoords[pointerCount].touchMajor = touchMajor;
-        pointerCoords[pointerCount].touchMinor = touchMinor;
-        pointerCoords[pointerCount].toolMajor = toolMajor;
-        pointerCoords[pointerCount].toolMinor = toolMinor;
-        pointerCoords[pointerCount].orientation = orientation;
-
-        if (id == changedId) {
-            motionEventAction |= pointerCount << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
-        }
-
-        pointerCount += 1;
-    }
-
-    // Check edge flags by looking only at the first pointer since the flags are
-    // global to the event.
     int32_t motionEventEdgeFlags = 0;
-    if (motionEventAction == AMOTION_EVENT_ACTION_DOWN) {
-        if (pointerCoords[0].x <= 0) {
-            motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_LEFT;
-        } else if (pointerCoords[0].x >= mOrientedSurfaceWidth) {
-            motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_RIGHT;
+    float xPrecision, yPrecision;
+
+    { // acquire lock
+        AutoMutex _l(mLock);
+
+        // Walk through the the active pointers and map touch screen coordinates (TouchData) into
+        // display coordinates (PointerCoords) and adjust for display orientation.
+        while (! idBits.isEmpty()) {
+            uint32_t id = idBits.firstMarkedBit();
+            idBits.clearBit(id);
+            uint32_t index = touch->idToIndex[id];
+
+            float x = float(touch->pointers[index].x - mLocked.xOrigin) * mLocked.xScale;
+            float y = float(touch->pointers[index].y - mLocked.yOrigin) * mLocked.yScale;
+            float pressure = float(touch->pointers[index].pressure - mLocked.pressureOrigin)
+                    * mLocked.pressureScale;
+            float size = float(touch->pointers[index].size - mLocked.sizeOrigin)
+                    * mLocked.sizeScale;
+
+            float orientation = float(touch->pointers[index].orientation)
+                    * mLocked.orientationScale;
+
+            float touchMajor, touchMinor, toolMajor, toolMinor;
+            if (abs(orientation) <= M_PI_4) {
+                // Nominally vertical orientation: scale major axis by Y, and scale minor axis by X.
+                touchMajor = float(touch->pointers[index].touchMajor) * mLocked.yScale;
+                touchMinor = float(touch->pointers[index].touchMinor) * mLocked.xScale;
+                toolMajor = float(touch->pointers[index].toolMajor) * mLocked.yScale;
+                toolMinor = float(touch->pointers[index].toolMinor) * mLocked.xScale;
+            } else {
+                // Nominally horizontal orientation: scale major axis by X, and scale minor axis by Y.
+                touchMajor = float(touch->pointers[index].touchMajor) * mLocked.xScale;
+                touchMinor = float(touch->pointers[index].touchMinor) * mLocked.yScale;
+                toolMajor = float(touch->pointers[index].toolMajor) * mLocked.xScale;
+                toolMinor = float(touch->pointers[index].toolMinor) * mLocked.yScale;
+            }
+
+            switch (mLocked.surfaceOrientation) {
+            case InputReaderPolicyInterface::ROTATION_90: {
+                float xTemp = x;
+                x = y;
+                y = mLocked.surfaceWidth - xTemp;
+                orientation -= M_PI_2;
+                if (orientation < - M_PI_2) {
+                    orientation += M_PI;
+                }
+                break;
+            }
+            case InputReaderPolicyInterface::ROTATION_180: {
+                x = mLocked.surfaceWidth - x;
+                y = mLocked.surfaceHeight - y;
+                orientation = - orientation;
+                break;
+            }
+            case InputReaderPolicyInterface::ROTATION_270: {
+                float xTemp = x;
+                x = mLocked.surfaceHeight - y;
+                y = xTemp;
+                orientation += M_PI_2;
+                if (orientation > M_PI_2) {
+                    orientation -= M_PI;
+                }
+                break;
+            }
+            }
+
+            pointerIds[pointerCount] = int32_t(id);
+
+            pointerCoords[pointerCount].x = x;
+            pointerCoords[pointerCount].y = y;
+            pointerCoords[pointerCount].pressure = pressure;
+            pointerCoords[pointerCount].size = size;
+            pointerCoords[pointerCount].touchMajor = touchMajor;
+            pointerCoords[pointerCount].touchMinor = touchMinor;
+            pointerCoords[pointerCount].toolMajor = toolMajor;
+            pointerCoords[pointerCount].toolMinor = toolMinor;
+            pointerCoords[pointerCount].orientation = orientation;
+
+            if (id == changedId) {
+                motionEventAction |= pointerCount << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
+            }
+
+            pointerCount += 1;
         }
-        if (pointerCoords[0].y <= 0) {
-            motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_TOP;
-        } else if (pointerCoords[0].y >= mOrientedSurfaceHeight) {
-            motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_BOTTOM;
+
+        // Check edge flags by looking only at the first pointer since the flags are
+        // global to the event.
+        if (motionEventAction == AMOTION_EVENT_ACTION_DOWN) {
+            if (pointerCoords[0].x <= 0) {
+                motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_LEFT;
+            } else if (pointerCoords[0].x >= mLocked.orientedSurfaceWidth) {
+                motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_RIGHT;
+            }
+            if (pointerCoords[0].y <= 0) {
+                motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_TOP;
+            } else if (pointerCoords[0].y >= mLocked.orientedSurfaceHeight) {
+                motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_BOTTOM;
+            }
         }
-    }
+
+        xPrecision = mLocked.orientedXPrecision;
+        yPrecision = mLocked.orientedYPrecision;
+    } // release lock
 
     getDispatcher()->notifyMotion(when, getDeviceId(), AINPUT_SOURCE_TOUCHSCREEN, policyFlags,
             motionEventAction, getContext()->getGlobalMetaState(), motionEventEdgeFlags,
             pointerCount, pointerIds, pointerCoords,
-            mOrientedXPrecision, mOrientedYPrecision, mDownTime);
+            xPrecision, yPrecision, mDownTime);
 }
 
-bool TouchInputMapper::isPointInsideSurface(int32_t x, int32_t y) {
+bool TouchInputMapper::isPointInsideSurfaceLocked(int32_t x, int32_t y) {
     if (mAxes.x.valid && mAxes.y.valid) {
         return x >= mAxes.x.minValue && x <= mAxes.x.maxValue
                 && y >= mAxes.y.minValue && y <= mAxes.y.maxValue;
@@ -1674,9 +1744,11 @@
     return true;
 }
 
-const TouchInputMapper::VirtualKey* TouchInputMapper::findVirtualKeyHitLvk(int32_t x, int32_t y) {
-    for (size_t i = 0; i < mVirtualKeys.size(); i++) {
-        const VirtualKey& virtualKey = mVirtualKeys[i];
+const TouchInputMapper::VirtualKey* TouchInputMapper::findVirtualKeyHitLocked(
+        int32_t x, int32_t y) {
+    size_t numVirtualKeys = mLocked.virtualKeys.size();
+    for (size_t i = 0; i < numVirtualKeys; i++) {
+        const VirtualKey& virtualKey = mLocked.virtualKeys[i];
 
 #if DEBUG_VIRTUAL_KEYS
         LOGD("VirtualKeys: Hit test (%d, %d): keyCode=%d, scanCode=%d, "
@@ -2224,50 +2296,53 @@
 }
 
 int32_t TouchInputMapper::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) {
-    { // acquire virtual key lock
-        AutoMutex _l(mVirtualKeyLock);
+    { // acquire lock
+        AutoMutex _l(mLock);
 
-        if (mCurrentVirtualKey.down && mCurrentVirtualKey.keyCode == keyCode) {
+        if (mLocked.currentVirtualKey.down && mLocked.currentVirtualKey.keyCode == keyCode) {
             return AKEY_STATE_VIRTUAL;
         }
 
-        for (size_t i = 0; i < mVirtualKeys.size(); i++) {
-            const VirtualKey& virtualKey = mVirtualKeys[i];
+        size_t numVirtualKeys = mLocked.virtualKeys.size();
+        for (size_t i = 0; i < numVirtualKeys; i++) {
+            const VirtualKey& virtualKey = mLocked.virtualKeys[i];
             if (virtualKey.keyCode == keyCode) {
                 return AKEY_STATE_UP;
             }
         }
-    } // release virtual key lock
+    } // release lock
 
     return AKEY_STATE_UNKNOWN;
 }
 
 int32_t TouchInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
-    { // acquire virtual key lock
-        AutoMutex _l(mVirtualKeyLock);
+    { // acquire lock
+        AutoMutex _l(mLock);
 
-        if (mCurrentVirtualKey.down && mCurrentVirtualKey.scanCode == scanCode) {
+        if (mLocked.currentVirtualKey.down && mLocked.currentVirtualKey.scanCode == scanCode) {
             return AKEY_STATE_VIRTUAL;
         }
 
-        for (size_t i = 0; i < mVirtualKeys.size(); i++) {
-            const VirtualKey& virtualKey = mVirtualKeys[i];
+        size_t numVirtualKeys = mLocked.virtualKeys.size();
+        for (size_t i = 0; i < numVirtualKeys; i++) {
+            const VirtualKey& virtualKey = mLocked.virtualKeys[i];
             if (virtualKey.scanCode == scanCode) {
                 return AKEY_STATE_UP;
             }
         }
-    } // release virtual key lock
+    } // release lock
 
     return AKEY_STATE_UNKNOWN;
 }
 
 bool TouchInputMapper::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
         const int32_t* keyCodes, uint8_t* outFlags) {
-    { // acquire virtual key lock
-        AutoMutex _l(mVirtualKeyLock);
+    { // acquire lock
+        AutoMutex _l(mLock);
 
-        for (size_t i = 0; i < mVirtualKeys.size(); i++) {
-            const VirtualKey& virtualKey = mVirtualKeys[i];
+        size_t numVirtualKeys = mLocked.virtualKeys.size();
+        for (size_t i = 0; i < numVirtualKeys; i++) {
+            const VirtualKey& virtualKey = mLocked.virtualKeys[i];
 
             for (size_t i = 0; i < numCodes; i++) {
                 if (virtualKey.keyCode == keyCodes[i]) {
@@ -2275,7 +2350,7 @@
                 }
             }
         }
-    } // release virtual key lock
+    } // release lock
 
     return true;
 }
@@ -2304,7 +2379,6 @@
 void SingleTouchInputMapper::reset() {
     TouchInputMapper::reset();
 
-    // Reinitialize.
     initialize();
  }
 
@@ -2436,7 +2510,6 @@
 void MultiTouchInputMapper::reset() {
     TouchInputMapper::reset();
 
-    // Reinitialize.
     initialize();
 }
 
diff --git a/opengl/libagl/Android.mk b/opengl/libagl/Android.mk
index 8abd649..b5c018f 100644
--- a/opengl/libagl/Android.mk
+++ b/opengl/libagl/Android.mk
@@ -6,9 +6,6 @@
 
 include $(CLEAR_VARS)
 
-# Set to 1 to use gralloc and copybits
-LIBAGL_USE_GRALLOC_COPYBITS := 1
-
 LOCAL_SRC_FILES:= \
 	egl.cpp                     \
 	state.cpp		            \
@@ -51,13 +48,6 @@
     LOCAL_C_INCLUDES += bionic/libc/private
 endif
 
-ifeq ($(LIBAGL_USE_GRALLOC_COPYBITS),1)
-    LOCAL_CFLAGS += -DLIBAGL_USE_GRALLOC_COPYBITS
-    LOCAL_SRC_FILES += copybit.cpp
-    LOCAL_SHARED_LIBRARIES += libui
-endif
-
-
 LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/egl
 LOCAL_MODULE:= libGLES_android
 
diff --git a/opengl/libagl/TextureObjectManager.cpp b/opengl/libagl/TextureObjectManager.cpp
index 255ccac..bbb82fc 100644
--- a/opengl/libagl/TextureObjectManager.cpp
+++ b/opengl/libagl/TextureObjectManager.cpp
@@ -55,9 +55,6 @@
     memset(crop_rect, 0, sizeof(crop_rect));
     generate_mipmap = GL_FALSE;
     direct = GL_FALSE;
-#ifdef LIBAGL_USE_GRALLOC_COPYBITS
-    try_copybit = false;
-#endif // LIBAGL_USE_GRALLOC_COPYBITS
     buffer = 0;
 }
 
diff --git a/opengl/libagl/TextureObjectManager.h b/opengl/libagl/TextureObjectManager.h
index 279e040..70e3bef 100644
--- a/opengl/libagl/TextureObjectManager.h
+++ b/opengl/libagl/TextureObjectManager.h
@@ -80,9 +80,6 @@
     GLint               crop_rect[4];
     GLint               generate_mipmap;
     GLint               direct;
-#ifdef LIBAGL_USE_GRALLOC_COPYBITS
-    bool                try_copybit;
-#endif // LIBAGL_USE_GRALLOC_COPYBITS
     android_native_buffer_t* buffer;
 };
 
diff --git a/opengl/libagl/array.cpp b/opengl/libagl/array.cpp
index 71825c5..4997dc8 100644
--- a/opengl/libagl/array.cpp
+++ b/opengl/libagl/array.cpp
@@ -26,9 +26,6 @@
 #include "primitives.h"
 #include "texture.h"
 #include "BufferObjectManager.h"
-#ifdef LIBAGL_USE_GRALLOC_COPYBITS
-#include "copybit.h"
-#endif // LIBAGL_USE_GRALLOC_COPYBITS
 
 // ----------------------------------------------------------------------------
 
@@ -707,12 +704,6 @@
 
 void drawPrimitivesTriangleFan(ogles_context_t* c,
         GLint first, GLsizei count) {
-#ifdef LIBAGL_USE_GRALLOC_COPYBITS
-    if (drawTriangleFanWithCopybit(c, first, count)) {
-        return;
-    }
-#endif // LIBAGL_USE_GRALLOC_COPYBITS
-
     drawPrimitivesTriangleFanOrStrip(c, first, count, 2);
 }
 
diff --git a/opengl/libagl/copybit.cpp b/opengl/libagl/copybit.cpp
deleted file mode 100644
index 67d1ce7..0000000
--- a/opengl/libagl/copybit.cpp
+++ /dev/null
@@ -1,618 +0,0 @@
-/*
-**
-** Copyright 2009, 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 "context.h"
-#include "fp.h"
-#include "state.h"
-#include "matrix.h"
-#include "vertex.h"
-#include "light.h"
-#include "primitives.h"
-#include "texture.h"
-#include "BufferObjectManager.h"
-#include "TextureObjectManager.h"
-
-#include <hardware/gralloc.h>
-#include <hardware/copybit.h>
-#include <private/ui/android_natives_priv.h>
-
-#include <ui/GraphicBuffer.h>
-#include <ui/Region.h>
-#include <ui/Rect.h>
-
-
-#define DEBUG_COPYBIT false
-
-// ----------------------------------------------------------------------------
-
-namespace android {
-
-static void textureToCopyBitImage(
-        const GGLSurface* surface, int32_t opFormat, 
-        android_native_buffer_t* buffer, copybit_image_t* img)
-{
-    img->w      = surface->stride;
-    img->h      = surface->height;
-    img->format = opFormat;
-    img->base   = surface->data;
-    img->handle = (native_handle_t *)buffer->handle;
-}
-
-struct clipRectRegion : public copybit_region_t {
-    clipRectRegion(ogles_context_t* c) 
-    {
-        scissor_t const* scissor = &c->rasterizer.state.scissor;
-        r.l = scissor->left;
-        r.t = scissor->top;
-        r.r = scissor->right;
-        r.b = scissor->bottom;
-        next = iterate; 
-    }
-private:
-    static int iterate(copybit_region_t const * self, copybit_rect_t* rect) {
-        *rect = static_cast<clipRectRegion const*>(self)->r;
-        const_cast<copybit_region_t *>(self)->next = iterate_done;
-        return 1;
-    }
-    static int iterate_done(copybit_region_t const *, copybit_rect_t*) {
-        return 0;
-    }
-public:
-    copybit_rect_t r;
-};
-
-static bool supportedCopybitsFormat(int format) {
-    switch (format) {
-    case COPYBIT_FORMAT_RGBA_8888:
-    case COPYBIT_FORMAT_RGBX_8888:
-    case COPYBIT_FORMAT_RGB_888:
-    case COPYBIT_FORMAT_RGB_565:
-    case COPYBIT_FORMAT_BGRA_8888:
-    case COPYBIT_FORMAT_RGBA_5551:
-    case COPYBIT_FORMAT_RGBA_4444:
-        return true;
-    default:
-        return false;
-    }
-}
-
-static bool hasAlpha(int format) {
-    switch (format) {
-    case COPYBIT_FORMAT_RGBA_8888:
-    case COPYBIT_FORMAT_BGRA_8888:
-    case COPYBIT_FORMAT_RGBA_5551:
-    case COPYBIT_FORMAT_RGBA_4444:
-        return true;
-    default:
-        return false;
-    }
-}
-
-static inline int fixedToByte(GGLfixed val) {
-    return (val - (val >> 8)) >> 8;
-}
-
-/**
- * Performs a quick check of the rendering state. If this function returns
- * false we cannot use the copybit driver.
- */
-
-static bool checkContext(ogles_context_t* c) {
-
-	// By convention copybitQuickCheckContext() has already returned true.
-	// avoid checking the same information again.
-	
-    if (c->copybits.blitEngine == NULL) {
-        LOGD_IF(DEBUG_COPYBIT, "no copybit hal");
-        return false;
-    }
-
-    if (c->rasterizer.state.enables
-                    & (GGL_ENABLE_DEPTH_TEST|GGL_ENABLE_FOG)) {
-        LOGD_IF(DEBUG_COPYBIT, "depth test and/or fog");
-        return false;
-    }
-
-    // Note: The drawSurfaceBuffer is only set for destination
-    // surfaces types that are supported by the hardware and
-    // do not have an alpha channel. So we don't have to re-check that here.
-
-    static const int tmu = 0;
-    texture_unit_t& u(c->textures.tmu[tmu]);
-    EGLTextureObject* textureObject = u.texture;
-
-    if (!supportedCopybitsFormat(textureObject->surface.format)) {
-        LOGD_IF(DEBUG_COPYBIT, "texture format not supported");
-        return false;
-    }
-    return true;
-}
-
-
-static bool copybit(GLint x, GLint y,
-        GLint w, GLint h,
-        EGLTextureObject* textureObject,
-        const GLint* crop_rect,
-        int transform,
-        ogles_context_t* c)
-{
-    status_t err = NO_ERROR;
-
-    // We assume checkContext has already been called and has already
-    // returned true.
-
-    const GGLSurface& cbSurface = c->rasterizer.state.buffers.color.s;
-
-    y = cbSurface.height - (y + h);
-
-    const GLint Ucr = crop_rect[0];
-    const GLint Vcr = crop_rect[1];
-    const GLint Wcr = crop_rect[2];
-    const GLint Hcr = crop_rect[3];
-
-    GLint screen_w = w;
-    GLint screen_h = h;
-    int32_t dsdx = Wcr << 16;   // dsdx =  ((Wcr/screen_w)/Wt)*Wt
-    int32_t dtdy = Hcr << 16;   // dtdy = -((Hcr/screen_h)/Ht)*Ht
-    if (transform & COPYBIT_TRANSFORM_ROT_90) {
-        swap(screen_w, screen_h);
-    }
-    if (dsdx!=screen_w || dtdy!=screen_h) {
-        // in most cases the divide is not needed
-        dsdx /= screen_w;
-        dtdy /= screen_h;
-    }
-    dtdy = -dtdy; // see equation of dtdy above
-
-    // copybit doesn't say anything about filtering, so we can't
-    // discriminate. On msm7k, copybit will always filter.
-    // the code below handles min/mag filters, we keep it as a reference.
-    
-#ifdef MIN_MAG_FILTER
-    int32_t texelArea = gglMulx(dtdy, dsdx);
-    if (texelArea < FIXED_ONE && textureObject->mag_filter != GL_LINEAR) {
-        // Non-linear filtering on a texture enlargement.
-        LOGD_IF(DEBUG_COPYBIT, "mag filter is not GL_LINEAR");
-        return false;
-    }
-    if (texelArea > FIXED_ONE && textureObject->min_filter != GL_LINEAR) {
-        // Non-linear filtering on an texture shrink.
-        LOGD_IF(DEBUG_COPYBIT, "min filter is not GL_LINEAR");
-        return false;
-    }
-#endif
-    
-    const uint32_t enables = c->rasterizer.state.enables;
-    int planeAlpha = 255;
-    bool alphaPlaneWorkaround = false;
-    static const int tmu = 0;
-    texture_t& tev(c->rasterizer.state.texture[tmu]);
-    int32_t opFormat = textureObject->surface.format;
-    const bool srcTextureHasAlpha = hasAlpha(opFormat);
-    if (!srcTextureHasAlpha) {
-        planeAlpha = fixedToByte(c->currentColorClamped.a);
-    }
-
-    const bool cbHasAlpha = hasAlpha(cbSurface.format);
-    bool blending = false;
-    if ((enables & GGL_ENABLE_BLENDING)
-            && !(c->rasterizer.state.blend.src == GL_ONE
-                    && c->rasterizer.state.blend.dst == GL_ZERO)) {
-        // Blending is OK if it is
-        // the exact kind of blending that the copybits hardware supports.
-        // Note: The hardware only supports
-        // GL_SRC_ALPHA / GL_ONE_MINUS_SRC_ALPHA,
-        // But the surface flinger uses GL_ONE / GL_ONE_MINUS_SRC_ALPHA.
-        // We substitute GL_SRC_ALPHA / GL_ONE_MINUS_SRC_ALPHA in that case,
-        // because the performance is worth it, even if the results are
-        // not correct.
-        if (!((c->rasterizer.state.blend.src == GL_SRC_ALPHA
-                || c->rasterizer.state.blend.src == GL_ONE)
-                && c->rasterizer.state.blend.dst == GL_ONE_MINUS_SRC_ALPHA
-                && c->rasterizer.state.blend.alpha_separate == 0)) {
-            // Incompatible blend mode.
-            LOGD_IF(DEBUG_COPYBIT, "incompatible blend mode");
-            return false;
-        }
-        blending = true;
-    } else {
-        if (cbHasAlpha) {
-            // NOTE: the result will be slightly wrong in this case because
-            // the destination alpha channel will be set to 1.0 instead of
-            // the iterated alpha value. *shrug*.
-        }
-        // disable plane blending and src blending for supported formats
-        planeAlpha = 255;
-        if (opFormat == COPYBIT_FORMAT_RGBA_8888) {
-            opFormat = COPYBIT_FORMAT_RGBX_8888;
-        } else {
-            if (srcTextureHasAlpha) {
-                LOGD_IF(DEBUG_COPYBIT, "texture format requires blending");
-                return false;
-            }
-        }
-    }
-
-    switch (tev.env) {
-    case GGL_REPLACE:
-        break;
-    case GGL_MODULATE:
-        // only cases allowed is:
-        // RGB  source, color={1,1,1,a} -> can be done with GL_REPLACE
-        // RGBA source, color={1,1,1,1} -> can be done with GL_REPLACE
-        if (blending) {
-            if (c->currentColorClamped.r == c->currentColorClamped.a &&
-                c->currentColorClamped.g == c->currentColorClamped.a &&
-                c->currentColorClamped.b == c->currentColorClamped.a) {
-                // TODO: RGBA source, color={1,1,1,a} / regular-blending
-                // is equivalent
-                alphaPlaneWorkaround = true;
-                break;
-            }
-        }
-        LOGD_IF(DEBUG_COPYBIT, "GGL_MODULATE");
-        return false;
-    default:
-        // Incompatible texture environment.
-        LOGD_IF(DEBUG_COPYBIT, "incompatible texture environment");
-        return false;
-    }
-
-    copybit_device_t* copybit = c->copybits.blitEngine;
-    copybit_image_t src;
-    textureToCopyBitImage(&textureObject->surface, opFormat,
-            textureObject->buffer, &src);
-    copybit_rect_t srect = { Ucr, Vcr + Hcr, Ucr + Wcr, Vcr };
-
-    /*
-     *  Below we perform extra passes needed to emulate things the h/w
-     * cannot do.
-     */
-
-    const GLfixed minScaleInv = gglDivQ(0x10000, c->copybits.minScale, 16);
-    const GLfixed maxScaleInv = gglDivQ(0x10000, c->copybits.maxScale, 16);
-
-    sp<GraphicBuffer> tempBitmap;
-
-    if (dsdx < maxScaleInv || dsdx > minScaleInv ||
-        dtdy < maxScaleInv || dtdy > minScaleInv)
-    {
-        // The requested scale is out of the range the hardware
-        // can support.
-        LOGD_IF(DEBUG_COPYBIT,
-                "scale out of range dsdx=%08x (Wcr=%d / w=%d), "
-                "dtdy=%08x (Hcr=%d / h=%d), Ucr=%d, Vcr=%d",
-                dsdx, Wcr, w, dtdy, Hcr, h, Ucr, Vcr);
-
-        int32_t xscale=0x10000, yscale=0x10000;
-        if (dsdx > minScaleInv)         xscale = c->copybits.minScale;
-        else if (dsdx < maxScaleInv)    xscale = c->copybits.maxScale;
-        if (dtdy > minScaleInv)         yscale = c->copybits.minScale;
-        else if (dtdy < maxScaleInv)    yscale = c->copybits.maxScale;
-        dsdx = gglMulx(dsdx, xscale);
-        dtdy = gglMulx(dtdy, yscale);
-
-        /* we handle only one step of resizing below. Handling an arbitrary
-         * number is relatively easy (replace "if" above by "while"), but requires
-         * two intermediate buffers and so far we never had the need.
-         */
-
-        if (dsdx < maxScaleInv || dsdx > minScaleInv ||
-            dtdy < maxScaleInv || dtdy > minScaleInv) {
-            LOGD_IF(DEBUG_COPYBIT,
-                    "scale out of range dsdx=%08x (Wcr=%d / w=%d), "
-                    "dtdy=%08x (Hcr=%d / h=%d), Ucr=%d, Vcr=%d",
-                    dsdx, Wcr, w, dtdy, Hcr, h, Ucr, Vcr);
-            return false;
-        }
-
-        const int tmp_w = gglMulx(srect.r - srect.l, xscale, 16);
-        const int tmp_h = gglMulx(srect.b - srect.t, yscale, 16);
-
-        LOGD_IF(DEBUG_COPYBIT,
-                "xscale=%08x, yscale=%08x, dsdx=%08x, dtdy=%08x, tmp_w=%d, tmp_h=%d",
-                xscale, yscale, dsdx, dtdy, tmp_w, tmp_h);
-
-        tempBitmap = new GraphicBuffer(
-                    tmp_w, tmp_h, src.format,
-                    GraphicBuffer::USAGE_HW_2D);
-
-        err = tempBitmap->initCheck();
-        if (err == NO_ERROR) {
-            copybit_image_t tmp_dst;
-            copybit_rect_t tmp_rect;
-            tmp_dst.w = tmp_w;
-            tmp_dst.h = tmp_h;
-            tmp_dst.format = tempBitmap->format;
-            tmp_dst.handle = (native_handle_t*)tempBitmap->getNativeBuffer()->handle;
-            tmp_rect.l = 0;
-            tmp_rect.t = 0;
-            tmp_rect.r = tmp_dst.w;
-            tmp_rect.b = tmp_dst.h;
-            region_iterator tmp_it(Region(Rect(tmp_rect.r, tmp_rect.b)));
-            copybit->set_parameter(copybit, COPYBIT_TRANSFORM, 0);
-            copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, 0xFF);
-            copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_DISABLE);
-            err = copybit->stretch(copybit,
-                    &tmp_dst, &src, &tmp_rect, &srect, &tmp_it);
-            src = tmp_dst;
-            srect = tmp_rect;
-        }
-    }
-
-    copybit_image_t dst;
-    textureToCopyBitImage(&cbSurface, cbSurface.format,
-            c->copybits.drawSurfaceBuffer, &dst);
-    copybit_rect_t drect = {x, y, x+w, y+h};
-
-
-    /* and now the alpha-plane hack. This handles the "Fade" case of a
-     * texture with an alpha channel.
-     */
-    if (alphaPlaneWorkaround) {
-        sp<GraphicBuffer> tempCb = new GraphicBuffer(
-                    w, h, COPYBIT_FORMAT_RGB_565,
-                    GraphicBuffer::USAGE_HW_2D);
-
-        err = tempCb->initCheck();
-
-        copybit_image_t tmpCbImg;
-        copybit_rect_t tmpCbRect;
-        copybit_rect_t tmpdrect = drect;
-        tmpCbImg.w = w;
-        tmpCbImg.h = h;
-        tmpCbImg.format = tempCb->format;
-        tmpCbImg.handle = (native_handle_t*)tempCb->getNativeBuffer()->handle;
-        tmpCbRect.l = 0;
-        tmpCbRect.t = 0;
-
-        if (drect.l < 0) {
-            tmpCbRect.l = -tmpdrect.l;
-            tmpdrect.l = 0;
-        }
-        if (drect.t < 0) {
-            tmpCbRect.t = -tmpdrect.t;
-            tmpdrect.t = 0;
-        }
-        if (drect.l + tmpCbImg.w > dst.w) {
-            tmpCbImg.w = dst.w - drect.l;
-            tmpdrect.r = dst.w;
-        }
-        if (drect.t + tmpCbImg.h > dst.h) {
-            tmpCbImg.h = dst.h - drect.t;
-            tmpdrect.b = dst.h;
-        }
-
-        tmpCbRect.r = tmpCbImg.w;
-        tmpCbRect.b = tmpCbImg.h;
-
-        if (!err) {
-            // first make a copy of the destination buffer
-            region_iterator tmp_it(Region(Rect(w, h)));
-            copybit->set_parameter(copybit, COPYBIT_TRANSFORM, 0);
-            copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, 0xFF);
-            copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_DISABLE);
-            err = copybit->stretch(copybit,
-                    &tmpCbImg, &dst, &tmpCbRect, &tmpdrect, &tmp_it);
-        }
-        if (!err) {
-            // then proceed as usual, but without the alpha plane
-            copybit->set_parameter(copybit, COPYBIT_TRANSFORM, transform);
-            copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, 0xFF);
-            copybit->set_parameter(copybit, COPYBIT_DITHER,
-                    (enables & GGL_ENABLE_DITHER) ?
-                            COPYBIT_ENABLE : COPYBIT_DISABLE);
-            clipRectRegion it(c);
-            err = copybit->stretch(copybit, &dst, &src, &drect, &srect, &it);
-        }
-        if (!err) {
-            // finally copy back the destination on top with 1-alphaplane
-            int invPlaneAlpha = 0xFF - fixedToByte(c->currentColorClamped.a);
-            clipRectRegion it(c);
-            copybit->set_parameter(copybit, COPYBIT_TRANSFORM, 0);
-            copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, invPlaneAlpha);
-            copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_ENABLE);
-            err = copybit->stretch(copybit,
-                    &dst, &tmpCbImg, &tmpdrect, &tmpCbRect, &it);
-        }
-    } else {
-        copybit->set_parameter(copybit, COPYBIT_TRANSFORM, transform);
-        copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, planeAlpha);
-        copybit->set_parameter(copybit, COPYBIT_DITHER,
-                (enables & GGL_ENABLE_DITHER) ?
-                        COPYBIT_ENABLE : COPYBIT_DISABLE);
-        clipRectRegion it(c);
-
-        LOGD_IF(0,
-             "dst={%d, %d, %d, %p, %p}, "
-             "src={%d, %d, %d, %p, %p}, "
-             "drect={%d,%d,%d,%d}, "
-             "srect={%d,%d,%d,%d}, "
-             "it={%d,%d,%d,%d}, " ,
-             dst.w, dst.h, dst.format, dst.base, dst.handle,
-             src.w, src.h, src.format, src.base, src.handle,
-             drect.l, drect.t, drect.r, drect.b,
-             srect.l, srect.t, srect.r, srect.b,
-             it.r.l, it.r.t, it.r.r, it.r.b
-        );
-
-        err = copybit->stretch(copybit, &dst, &src, &drect, &srect, &it);
-    }
-    if (err != NO_ERROR) {
-        c->textures.tmu[0].texture->try_copybit = false;
-    }
-    return err == NO_ERROR ? true : false;
-}
-
-/*
- * Try to draw a triangle fan with copybit, return false if we fail.
- */
-bool drawTriangleFanWithCopybit_impl(ogles_context_t* c, GLint first, GLsizei count)
-{
-    if (!checkContext(c)) {
-        return false;
-    }
-
-    // FIXME: we should handle culling  here
-    c->arrays.compileElements(c, c->vc.vBuffer, 0, 4);
-
-    // we detect if we're dealing with a rectangle, by comparing the
-    // rectangles {v0,v2} and {v1,v3} which should be identical.
-    
-    // NOTE: we should check that the rectangle is window aligned, however
-    // if we do that, the optimization won't be taken in a lot of cases.
-    // Since this code is intended to be used with SurfaceFlinger only,
-    // so it's okay...
-    
-    const vec4_t& v0 = c->vc.vBuffer[0].window;
-    const vec4_t& v1 = c->vc.vBuffer[1].window;
-    const vec4_t& v2 = c->vc.vBuffer[2].window;
-    const vec4_t& v3 = c->vc.vBuffer[3].window;
-    int l = min(v0.x, v2.x);
-    int b = min(v0.y, v2.y);
-    int r = max(v0.x, v2.x);
-    int t = max(v0.y, v2.y);
-    if ((l != min(v1.x, v3.x)) || (b != min(v1.y, v3.y)) ||
-        (r != max(v1.x, v3.x)) || (t != max(v1.y, v3.y))) {
-        LOGD_IF(DEBUG_COPYBIT, "geometry not a rectangle");
-        return false;
-    }
-
-    // fetch and transform texture coordinates
-    // NOTE: maybe it would be better to have a "compileElementsAll" method
-    // that would ensure all vertex data are fetched and transformed
-    const transform_t& tr = c->transforms.texture[0].transform; 
-    for (size_t i=0 ; i<4 ; i++) {
-        const GLubyte* tp = c->arrays.texture[0].element(i);
-        vertex_t* const v = &c->vc.vBuffer[i];
-        c->arrays.texture[0].fetch(c, v->texture[0].v, tp);
-        // FIXME: we should bail if q!=1
-        c->arrays.tex_transform[0](&tr, &v->texture[0], &v->texture[0]);
-    }
-    
-    const vec4_t& t0 = c->vc.vBuffer[0].texture[0];
-    const vec4_t& t1 = c->vc.vBuffer[1].texture[0];
-    const vec4_t& t2 = c->vc.vBuffer[2].texture[0];
-    const vec4_t& t3 = c->vc.vBuffer[3].texture[0];
-    int txl = min(t0.x, t2.x);
-    int txb = min(t0.y, t2.y);
-    int txr = max(t0.x, t2.x);
-    int txt = max(t0.y, t2.y);
-    if ((txl != min(t1.x, t3.x)) || (txb != min(t1.y, t3.y)) ||
-        (txr != max(t1.x, t3.x)) || (txt != max(t1.y, t3.y))) {
-        LOGD_IF(DEBUG_COPYBIT, "texcoord not a rectangle");
-        return false;
-    }
-    if ((txl != 0) || (txb != 0) ||
-        (txr != FIXED_ONE) || (txt != FIXED_ONE)) {
-        // we could probably handle this case, if we wanted to
-        LOGD_IF(DEBUG_COPYBIT, "texture is cropped: %08x,%08x,%08x,%08x",
-                txl, txb, txr, txt);
-        return false;
-    }
-
-    // at this point, we know we are dealing with a rectangle, so we 
-    // only need to consider 3 vertices for computing the jacobians
-    
-    const int dx01 = v1.x - v0.x;
-    const int dx02 = v2.x - v0.x;
-    const int dy01 = v1.y - v0.y;
-    const int dy02 = v2.y - v0.y;
-    const int ds01 = t1.S - t0.S;
-    const int ds02 = t2.S - t0.S;
-    const int dt01 = t1.T - t0.T;
-    const int dt02 = t2.T - t0.T;
-    const int area = dx01*dy02 - dy01*dx02;
-    int dsdx, dsdy, dtdx, dtdy;
-    if (area >= 0) {
-        dsdx = ds01*dy02 - ds02*dy01;
-        dtdx = dt01*dy02 - dt02*dy01;
-        dsdy = ds02*dx01 - ds01*dx02;
-        dtdy = dt02*dx01 - dt01*dx02;
-    } else {
-        dsdx = ds02*dy01 - ds01*dy02;
-        dtdx = dt02*dy01 - dt01*dy02;
-        dsdy = ds01*dx02 - ds02*dx01;
-        dtdy = dt01*dx02 - dt02*dx01;
-    }
-
-    // here we rely on the fact that we know the transform is
-    // a rigid-body transform AND that it can only rotate in 90 degrees
-    // increments
-
-    int transform = 0;
-    if (dsdx == 0) {
-        // 90 deg rotation case
-        // [ 0    dtdx  ]
-        // [ dsdx    0  ]
-        transform |= COPYBIT_TRANSFORM_ROT_90;
-        // FIXME: not sure if FLIP_H and FLIP_V shouldn't be inverted
-        if (dtdx > 0)
-            transform |= COPYBIT_TRANSFORM_FLIP_H;
-        if (dsdy < 0)
-            transform |= COPYBIT_TRANSFORM_FLIP_V;
-    } else {
-        // [ dsdx    0  ]
-        // [ 0     dtdy ]
-        if (dsdx < 0)
-            transform |= COPYBIT_TRANSFORM_FLIP_H;
-        if (dtdy < 0)
-            transform |= COPYBIT_TRANSFORM_FLIP_V;
-    }
-
-    //LOGD("l=%d, b=%d, w=%d, h=%d, tr=%d", x, y, w, h, transform);
-    //LOGD("A=%f\tB=%f\nC=%f\tD=%f",
-    //      dsdx/65536.0, dtdx/65536.0, dsdy/65536.0, dtdy/65536.0);
-
-    int x = l >> 4;
-    int y = b >> 4;
-    int w = (r-l) >> 4;
-    int h = (t-b) >> 4;
-    texture_unit_t& u(c->textures.tmu[0]);
-    EGLTextureObject* textureObject = u.texture;
-    GLint tWidth = textureObject->surface.width;
-    GLint tHeight = textureObject->surface.height;
-    GLint crop_rect[4] = {0, tHeight, tWidth, -tHeight};
-    const GGLSurface& cbSurface = c->rasterizer.state.buffers.color.s;
-    y = cbSurface.height - (y + h);
-    return copybit(x, y, w, h, textureObject, crop_rect, transform, c);
-}
-
-/*
- * Try to drawTexiOESWithCopybit, return false if we fail.
- */
-
-bool drawTexiOESWithCopybit_impl(GLint x, GLint y, GLint z,
-        GLint w, GLint h, ogles_context_t* c)
-{
-    // quickly process empty rects
-    if ((w|h) <= 0) {
-        return true;
-    }
-    if (!checkContext(c)) {
-        return false;
-    }
-    texture_unit_t& u(c->textures.tmu[0]);
-    EGLTextureObject* textureObject = u.texture;
-    return copybit(x, y, w, h, textureObject, textureObject->crop_rect, 0, c);
-}
-
-} // namespace android
-
diff --git a/opengl/libagl/copybit.h b/opengl/libagl/copybit.h
deleted file mode 100644
index b8b5afd..0000000
--- a/opengl/libagl/copybit.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
-**
-** Copyright 2009, 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_OPENGLES_COPYBIT_H
-#define ANDROID_OPENGLES_COPYBIT_H
-
-#include <stdlib.h>
-
-#include <GLES/gl.h>
-
-#include "TextureObjectManager.h"
-namespace android {
-#ifdef LIBAGL_USE_GRALLOC_COPYBITS
-
-bool drawTexiOESWithCopybit_impl(GLint x, GLint y, GLint z,
-        GLint w, GLint h, ogles_context_t* c);
-
-bool drawTriangleFanWithCopybit_impl(ogles_context_t* c, GLint first,
-        GLsizei count);
-
-inline bool copybitQuickCheckContext(ogles_context_t* c) {
-        return  c->copybits.drawSurfaceBuffer != 0
-            && c->rasterizer.state.enabled_tmu == 1
-            && c->textures.tmu[0].texture->try_copybit;
-}
-
-/*
- * Tries to draw a drawTexiOES using copybit hardware.
- * Returns true if successful.
- */
-inline bool drawTexiOESWithCopybit(GLint x, GLint y, GLint z,
-        GLint w, GLint h, ogles_context_t* c) {
-    if (!copybitQuickCheckContext(c)) {
-    	return false;
-   	}
-   	
-   	return drawTexiOESWithCopybit_impl(x, y, z, w, h, c);
-}
-
-/*
- * Tries to draw a triangle fan using copybit hardware.
- * Returns true if successful.
- */
-inline bool drawTriangleFanWithCopybit(ogles_context_t* c, GLint first,
-        GLsizei count) {
-    /*
-     * We are looking for the glDrawArrays call made by SurfaceFlinger.
-     */
-
-    if ((count!=4) || first || !copybitQuickCheckContext(c))
-        return false;
-    
-    return drawTriangleFanWithCopybit_impl(c, first, count);
-}
-
-
-#endif // LIBAGL_USE_GRALLOC_COPYBITS
-
-} // namespace android
-
-#endif // ANDROID_OPENGLES_COPYBIT_H
diff --git a/opengl/libagl/egl.cpp b/opengl/libagl/egl.cpp
index 54d7307..5bbe441 100644
--- a/opengl/libagl/egl.cpp
+++ b/opengl/libagl/egl.cpp
@@ -628,23 +628,6 @@
     return buffer;
 }
 
-#ifdef LIBAGL_USE_GRALLOC_COPYBITS
-
-static bool supportedCopybitsDestinationFormat(int format) {
-    // Hardware supported
-    switch (format) {
-    case HAL_PIXEL_FORMAT_RGB_565:
-    case HAL_PIXEL_FORMAT_RGBA_8888:
-    case HAL_PIXEL_FORMAT_RGBX_8888:
-    case HAL_PIXEL_FORMAT_RGBA_4444:
-    case HAL_PIXEL_FORMAT_RGBA_5551:
-    case HAL_PIXEL_FORMAT_BGRA_8888:
-        return true;
-    }
-    return false;
-}
-#endif
-
 EGLBoolean egl_window_surface_v2_t::bindDrawSurface(ogles_context_t* gl)
 {
     GGLSurface buffer;
@@ -658,18 +641,6 @@
     if (depth.data != gl->rasterizer.state.buffers.depth.data)
         gl->rasterizer.procs.depthBuffer(gl, &depth);
 
-#ifdef LIBAGL_USE_GRALLOC_COPYBITS
-    gl->copybits.drawSurfaceBuffer = 0;
-    if (gl->copybits.blitEngine != NULL) {
-        if (supportedCopybitsDestinationFormat(buffer.format)) {
-            buffer_handle_t handle = this->buffer->handle;
-            if (handle != NULL) {
-                gl->copybits.drawSurfaceBuffer = this->buffer;
-            }
-        }
-    }
-#endif // LIBAGL_USE_GRALLOC_COPYBITS
-
     return EGL_TRUE;
 }
 EGLBoolean egl_window_surface_v2_t::bindReadSurface(ogles_context_t* gl)
diff --git a/opengl/libagl/state.cpp b/opengl/libagl/state.cpp
index 27bb545..a0f720a 100644
--- a/opengl/libagl/state.cpp
+++ b/opengl/libagl/state.cpp
@@ -28,10 +28,6 @@
 #include "BufferObjectManager.h"
 #include "TextureObjectManager.h"
 
-#ifdef LIBAGL_USE_GRALLOC_COPYBITS
-#include <hardware/copybit.h>
-#endif // LIBAGL_USE_GRALLOC_COPYBITS
-
 namespace android {
 
 // ----------------------------------------------------------------------------
@@ -101,35 +97,6 @@
     // OpenGL enables dithering by default
     c->rasterizer.procs.enable(c, GL_DITHER);
 
-    c->copybits.blitEngine = NULL;
-    c->copybits.minScale = 0;
-    c->copybits.maxScale = 0;
-    c->copybits.drawSurfaceBuffer = 0;
-
-#ifdef LIBAGL_USE_GRALLOC_COPYBITS
-    hw_module_t const* module;
-    if (hw_get_module(COPYBIT_HARDWARE_MODULE_ID, &module) == 0) {
-        struct copybit_device_t* copyBits;
-        if (copybit_open(module, &copyBits) == 0) {
-            c->copybits.blitEngine = copyBits;
-            {
-                int minLim = copyBits->get(copyBits,
-                        COPYBIT_MINIFICATION_LIMIT);
-                if (minLim != -EINVAL && minLim > 0) {
-                    c->copybits.minScale = (1 << 16) / minLim;
-                }
-            }
-            {
-                int magLim = copyBits->get(copyBits,
-                        COPYBIT_MAGNIFICATION_LIMIT);
-                if (magLim != -EINVAL && magLim > 0) {
-                    c->copybits.maxScale = min(32*1024-1, magLim) << 16;
-                }
-            }
-        }
-    }
-#endif // LIBAGL_USE_GRALLOC_COPYBITS
-
     return c;
 }
 
@@ -144,11 +111,6 @@
     c->bufferObjectManager->decStrong(c);
     ggl_uninit_context(&(c->rasterizer));
     free(c->rasterizer.base);
-#ifdef LIBAGL_USE_GRALLOC_COPYBITS
-    if (c->copybits.blitEngine != NULL) {
-        copybit_close((struct copybit_device_t*) c->copybits.blitEngine);
-    }
-#endif // LIBAGL_USE_GRALLOC_COPYBITS
 }
 
 void _ogles_error(ogles_context_t* c, GLenum error)
diff --git a/opengl/libagl/texture.cpp b/opengl/libagl/texture.cpp
index d67612e..eb96895 100644
--- a/opengl/libagl/texture.cpp
+++ b/opengl/libagl/texture.cpp
@@ -26,10 +26,6 @@
 #include <private/ui/android_natives_priv.h>
 #include <ETC1/etc1.h>
 
-#ifdef LIBAGL_USE_GRALLOC_COPYBITS
-#include "copybit.h"
-#endif // LIBAGL_USE_GRALLOC_COPYBITS
-
 namespace android {
 
 // ----------------------------------------------------------------------------
@@ -763,17 +759,10 @@
 static void drawTexxOES(GLfixed x, GLfixed y, GLfixed z, GLfixed w, GLfixed h,
         ogles_context_t* c)
 {
-#ifdef LIBAGL_USE_GRALLOC_COPYBITS
-    if (drawTexiOESWithCopybit(gglFixedToIntRound(x),
-            gglFixedToIntRound(y), gglFixedToIntRound(z),
-            gglFixedToIntRound(w), gglFixedToIntRound(h), c)) {
-        return;
-    }
-#else
     // quickly reject empty rects
     if ((w|h) <= 0)
         return;
-#endif
+
     drawTexxOESImp(x, y, z, w, h, c);
 }
 
@@ -785,11 +774,6 @@
     // which is a lot faster.
 
     if (ggl_likely(c->rasterizer.state.enabled_tmu == 1)) {
-#ifdef LIBAGL_USE_GRALLOC_COPYBITS
-        if (drawTexiOESWithCopybit(x, y, z, w, h, c)) {
-            return;
-        }
-#endif
         const int tmu = 0;
         texture_unit_t& u(c->textures.tmu[tmu]);
         EGLTextureObject* textureObject = u.texture;
@@ -797,9 +781,7 @@
         const GLint Hcr = textureObject->crop_rect[3];
 
         if ((w == Wcr) && (h == -Hcr)) {
-#ifndef LIBAGL_USE_GRALLOC_COPYBITS
             if ((w|h) <= 0) return; // quickly reject empty rects
-#endif
 
             if (u.dirty) {
                 c->rasterizer.procs.activeTexture(c, tmu);
@@ -1646,13 +1628,6 @@
     // bind it to the texture unit
     sp<EGLTextureObject> tex = getAndBindActiveTextureObject(c);
     tex->setImage(native_buffer);
-
-#ifdef LIBAGL_USE_GRALLOC_COPYBITS
-    tex->try_copybit = false;
-    if (c->copybits.blitEngine != NULL) {
-        tex->try_copybit = true;
-    }
-#endif // LIBAGL_USE_GRALLOC_COPYBITS
 }
 
 void glEGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image)