Merge "Avoid unnecessary SharedPrefences disk writes." into gingerbread
diff --git a/include/ui/EventHub.h b/include/ui/EventHub.h
index dab35b3..3d42856 100644
--- a/include/ui/EventHub.h
+++ b/include/ui/EventHub.h
@@ -224,6 +224,7 @@
uint8_t* keyBitmask;
KeyLayoutMap* layoutMap;
String8 keylayoutFilename;
+ int fd;
device_t* next;
device_t(int32_t _id, const char* _path, const char* name);
@@ -266,6 +267,12 @@
#ifdef EV_SW
int32_t mSwitches[SW_MAX + 1];
#endif
+
+ static const int INPUT_BUFFER_SIZE = 64;
+ struct input_event mInputBufferData[INPUT_BUFFER_SIZE];
+ int32_t mInputBufferIndex;
+ int32_t mInputBufferCount;
+ int32_t mInputDeviceIndex;
};
}; // namespace android
diff --git a/include/ui/InputDispatcher.h b/include/ui/InputDispatcher.h
index d3495fe..2505cb0 100644
--- a/include/ui/InputDispatcher.h
+++ b/include/ui/InputDispatcher.h
@@ -554,6 +554,8 @@
// All registered connections mapped by receive pipe file descriptor.
KeyedVector<int, sp<Connection> > mConnectionsByReceiveFd;
+ ssize_t getConnectionIndex(const sp<InputChannel>& inputChannel);
+
// Active connections are connections that have a non-empty outbound queue.
// We don't use a ref-counted pointer here because we explicitly abort connections
// during unregistration which causes the connection's outbound queue to be cleared
diff --git a/include/ui/InputReader.h b/include/ui/InputReader.h
index 71c6c51..56d2765 100644
--- a/include/ui/InputReader.h
+++ b/include/ui/InputReader.h
@@ -480,10 +480,6 @@
inline void clear() {
fields = 0;
}
-
- inline bool isDirty() {
- return fields != 0;
- }
} mAccumulator;
float mXScale;
@@ -702,7 +698,7 @@
} historyData[AVERAGING_HISTORY_SIZE];
} mAveragingTouchFilter;
- struct JumpTouchFilterState {
+ struct JumpyTouchFilterState {
uint32_t jumpyPointsDropped;
} mJumpyTouchFilter;
@@ -765,10 +761,6 @@
inline void clear() {
fields = 0;
}
-
- inline bool isDirty() {
- return fields != 0;
- }
} mAccumulator;
bool mDown;
@@ -804,7 +796,8 @@
FIELD_ABS_MT_WIDTH_MAJOR = 16,
FIELD_ABS_MT_WIDTH_MINOR = 32,
FIELD_ABS_MT_ORIENTATION = 64,
- FIELD_ABS_MT_TRACKING_ID = 128
+ FIELD_ABS_MT_TRACKING_ID = 128,
+ FIELD_ABS_MT_PRESSURE = 256,
};
uint32_t pointerCount;
@@ -819,6 +812,7 @@
int32_t absMTWidthMinor;
int32_t absMTOrientation;
int32_t absMTTrackingId;
+ int32_t absMTPressure;
inline void clear() {
fields = 0;
@@ -829,10 +823,6 @@
pointerCount = 0;
pointers[0].clear();
}
-
- inline bool isDirty() {
- return pointerCount != 0;
- }
} mAccumulator;
void initialize();
diff --git a/libs/ui/EventHub.cpp b/libs/ui/EventHub.cpp
index 124f7b3..891661d 100644
--- a/libs/ui/EventHub.cpp
+++ b/libs/ui/EventHub.cpp
@@ -60,7 +60,6 @@
#define ID_MASK 0x0000ffff
#define SEQ_MASK 0x7fff0000
#define SEQ_SHIFT 16
-#define id_to_index(id) ((id&ID_MASK)+1)
#ifndef ABS_MT_TOUCH_MAJOR
#define ABS_MT_TOUCH_MAJOR 0x30 /* Major axis of touching ellipse */
@@ -87,7 +86,7 @@
EventHub::device_t::device_t(int32_t _id, const char* _path, const char* name)
: id(_id), path(_path), name(name), classes(0)
- , keyBitmask(NULL), layoutMap(new KeyLayoutMap()), next(NULL) {
+ , keyBitmask(NULL), layoutMap(new KeyLayoutMap()), fd(-1), next(NULL) {
}
EventHub::device_t::~device_t() {
@@ -100,6 +99,7 @@
, mDevicesById(0), mNumDevicesById(0)
, mOpeningDevices(0), mClosingDevices(0)
, mDevices(0), mFDs(0), mFDCount(0), mOpened(false)
+ , mInputBufferIndex(0), mInputBufferCount(0), mInputDeviceIndex(0)
{
acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID);
#ifdef EV_SW
@@ -151,9 +151,9 @@
struct input_absinfo info;
- if(ioctl(mFDs[id_to_index(device->id)].fd, EVIOCGABS(axis), &info)) {
+ if(ioctl(device->fd, EVIOCGABS(axis), &info)) {
LOGW("Error reading absolute controller %d for device %s fd %d\n",
- axis, device->name.string(), mFDs[id_to_index(device->id)].fd);
+ axis, device->name.string(), device->fd);
return -errno;
}
@@ -182,7 +182,7 @@
int32_t EventHub::getScanCodeStateLocked(device_t* device, int32_t scanCode) const {
uint8_t key_bitmask[sizeof_bit_array(KEY_MAX + 1)];
memset(key_bitmask, 0, sizeof(key_bitmask));
- if (ioctl(mFDs[id_to_index(device->id)].fd,
+ if (ioctl(device->fd,
EVIOCGKEY(sizeof(key_bitmask)), key_bitmask) >= 0) {
return test_bit(scanCode, key_bitmask) ? AKEY_STATE_DOWN : AKEY_STATE_UP;
}
@@ -205,8 +205,7 @@
uint8_t key_bitmask[sizeof_bit_array(KEY_MAX + 1)];
memset(key_bitmask, 0, sizeof(key_bitmask));
- if (ioctl(mFDs[id_to_index(device->id)].fd,
- EVIOCGKEY(sizeof(key_bitmask)), key_bitmask) >= 0) {
+ if (ioctl(device->fd, EVIOCGKEY(sizeof(key_bitmask)), key_bitmask) >= 0) {
#if 0
for (size_t i=0; i<=KEY_MAX; i++) {
LOGI("(Scan code %d: down=%d)", i, test_bit(i, key_bitmask));
@@ -242,7 +241,7 @@
int32_t EventHub::getSwitchStateLocked(device_t* device, int32_t sw) const {
uint8_t sw_bitmask[sizeof_bit_array(SW_MAX + 1)];
memset(sw_bitmask, 0, sizeof(sw_bitmask));
- if (ioctl(mFDs[id_to_index(device->id)].fd,
+ if (ioctl(device->fd,
EVIOCGSW(sizeof(sw_bitmask)), sw_bitmask) >= 0) {
return test_bit(sw, sw_bitmask) ? AKEY_STATE_DOWN : AKEY_STATE_UP;
}
@@ -343,13 +342,6 @@
outEvent->value = 0;
outEvent->when = 0;
- status_t err;
-
- int i;
- int res;
- int pollres;
- struct input_event iev;
-
// Note that we only allow one caller to getEvent(), so don't need
// to do locking here... only when adding/removing devices.
@@ -358,9 +350,8 @@
mOpened = true;
}
- while(1) {
-
- // First, report any devices that had last been added/removed.
+ for (;;) {
+ // Report any devices that had last been added/removed.
if (mClosingDevices != NULL) {
device_t* device = mClosingDevices;
LOGV("Reporting device closed: id=0x%x, name=%s\n",
@@ -390,77 +381,96 @@
return true;
}
- release_wake_lock(WAKE_LOCK_ID);
+ // Grab the next input event.
+ for (;;) {
+ // Consume buffered input events, if any.
+ if (mInputBufferIndex < mInputBufferCount) {
+ const struct input_event& iev = mInputBufferData[mInputBufferIndex++];
+ const device_t* device = mDevices[mInputDeviceIndex];
- pollres = poll(mFDs, mFDCount, -1);
-
- acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID);
-
- if (pollres <= 0) {
- if (errno != EINTR) {
- LOGW("select failed (errno=%d)\n", errno);
- usleep(100000);
- }
- continue;
- }
-
- //printf("poll %d, returned %d\n", mFDCount, pollres);
-
- // mFDs[0] is used for inotify, so process regular events starting at mFDs[1]
- for(i = 1; i < mFDCount; i++) {
- if(mFDs[i].revents) {
- LOGV("revents for %d = 0x%08x", i, mFDs[i].revents);
- if(mFDs[i].revents & POLLIN) {
- res = read(mFDs[i].fd, &iev, sizeof(iev));
- if (res == sizeof(iev)) {
- device_t* device = mDevices[i];
- LOGV("%s got: t0=%d, t1=%d, type=%d, code=%d, v=%d",
- device->path.string(),
- (int) iev.time.tv_sec, (int) iev.time.tv_usec,
- iev.type, iev.code, iev.value);
- if (device->id == mFirstKeyboardId) {
- outEvent->deviceId = 0;
- } else {
- outEvent->deviceId = device->id;
- }
- outEvent->type = iev.type;
- outEvent->scanCode = iev.code;
- if (iev.type == EV_KEY) {
- err = device->layoutMap->map(iev.code,
- & outEvent->keyCode, & outEvent->flags);
- LOGV("iev.code=%d keyCode=%d flags=0x%08x err=%d\n",
- iev.code, outEvent->keyCode, outEvent->flags, err);
- if (err != 0) {
- outEvent->keyCode = AKEYCODE_UNKNOWN;
- outEvent->flags = 0;
- }
- } else {
- outEvent->keyCode = iev.code;
- }
- outEvent->value = iev.value;
-
- // Use an event timestamp in the same timebase as
- // java.lang.System.nanoTime() and android.os.SystemClock.uptimeMillis()
- // as expected by the rest of the system.
- outEvent->when = systemTime(SYSTEM_TIME_MONOTONIC);
- return true;
- } else {
- if (res<0) {
- LOGW("could not get event (errno=%d)", errno);
- } else {
- LOGE("could not get event (wrong size: %d)", res);
- }
- continue;
+ LOGV("%s got: t0=%d, t1=%d, type=%d, code=%d, v=%d", device->path.string(),
+ (int) iev.time.tv_sec, (int) iev.time.tv_usec, iev.type, iev.code, iev.value);
+ if (device->id == mFirstKeyboardId) {
+ outEvent->deviceId = 0;
+ } else {
+ outEvent->deviceId = device->id;
+ }
+ outEvent->type = iev.type;
+ outEvent->scanCode = iev.code;
+ if (iev.type == EV_KEY) {
+ status_t err = device->layoutMap->map(iev.code,
+ & outEvent->keyCode, & outEvent->flags);
+ LOGV("iev.code=%d keyCode=%d flags=0x%08x err=%d\n",
+ iev.code, outEvent->keyCode, outEvent->flags, err);
+ if (err != 0) {
+ outEvent->keyCode = AKEYCODE_UNKNOWN;
+ outEvent->flags = 0;
}
+ } else {
+ outEvent->keyCode = iev.code;
+ }
+ outEvent->value = iev.value;
+
+ // Use an event timestamp in the same timebase as
+ // java.lang.System.nanoTime() and android.os.SystemClock.uptimeMillis()
+ // as expected by the rest of the system.
+ outEvent->when = systemTime(SYSTEM_TIME_MONOTONIC);
+ return true;
+ }
+
+ // Finish reading all events from devices identified in previous poll().
+ // This code assumes that mInputDeviceIndex is initially 0 and that the
+ // revents member of pollfd is initialized to 0 when the device is first added.
+ // Since mFDs[0] is used for inotify, we process regular events starting at index 1.
+ mInputDeviceIndex += 1;
+ if (mInputDeviceIndex >= mFDCount) {
+ mInputDeviceIndex = 0;
+ break;
+ }
+
+ const struct pollfd &pfd = mFDs[mInputDeviceIndex];
+ if (pfd.revents & POLLIN) {
+ int32_t readSize = read(pfd.fd, mInputBufferData,
+ sizeof(struct input_event) * INPUT_BUFFER_SIZE);
+ if (readSize < 0) {
+ if (errno != EAGAIN && errno != EINTR) {
+ LOGW("could not get event (errno=%d)", errno);
+ }
+ } else if ((readSize % sizeof(struct input_event)) != 0) {
+ LOGE("could not get event (wrong size: %d)", readSize);
+ } else {
+ mInputBufferCount = readSize / sizeof(struct input_event);
+ mInputBufferIndex = 0;
}
}
}
-
+
// read_notify() will modify mFDs and mFDCount, so this must be done after
// processing all other events.
if(mFDs[0].revents & POLLIN) {
read_notify(mFDs[0].fd);
}
+
+ // Poll for events. Mind the wake lock dance!
+ // We hold a wake lock at all times except during poll(). This works due to some
+ // subtle choreography. When a device driver has pending (unread) events, it acquires
+ // a kernel wake lock. However, once the last pending event has been read, the device
+ // driver will release the kernel wake lock. To prevent the system from going to sleep
+ // when this happens, the EventHub holds onto its own user wake lock while the client
+ // is processing events. Thus the system can only sleep if there are no events
+ // pending or currently being processed.
+ release_wake_lock(WAKE_LOCK_ID);
+
+ int pollResult = poll(mFDs, mFDCount, -1);
+
+ acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID);
+
+ if (pollResult <= 0) {
+ if (errno != EINTR) {
+ LOGW("select failed (errno=%d)\n", errno);
+ usleep(100000);
+ }
+ }
}
}
@@ -478,6 +488,7 @@
mFDs = (pollfd *)calloc(1, sizeof(mFDs[0]));
mDevices = (device_t **)calloc(1, sizeof(mDevices[0]));
mFDs[0].events = POLLIN;
+ mFDs[0].revents = 0;
mDevices[0] = NULL;
#ifdef HAVE_INOTIFY
mFDs[0].fd = inotify_init();
@@ -570,7 +581,6 @@
if (strcmp(name, test) == 0) {
LOGI("ignoring event id %s driver %s\n", deviceName, test);
close(fd);
- fd = -1;
return -1;
}
}
@@ -584,6 +594,12 @@
idstr[0] = '\0';
}
+ if (fcntl(fd, F_SETFL, O_NONBLOCK)) {
+ LOGE("Error %d making device file descriptor non-blocking.", errno);
+ close(fd);
+ return -1;
+ }
+
int devid = 0;
while (devid < mNumDevicesById) {
if (mDevicesById[devid].device == NULL) {
@@ -638,8 +654,10 @@
return -1;
}
+ device->fd = fd;
mFDs[mFDCount].fd = fd;
mFDs[mFDCount].events = POLLIN;
+ mFDs[mFDCount].revents = 0;
// Figure out the kinds of events the device reports.
@@ -794,6 +812,14 @@
device->id, name, propName, keylayoutFilename);
}
+ // If the device isn't recognized as something we handle, don't monitor it.
+ if (device->classes == 0) {
+ LOGV("Dropping device %s %p, id = %d\n", deviceName, device, devid);
+ close(fd);
+ delete device;
+ return -1;
+ }
+
LOGI("New device: path=%s name=%s id=0x%x (of 0x%x) index=%d fd=%d classes=0x%x\n",
deviceName, name, device->id, mNumDevicesById, mFDCount, fd, device->classes);
diff --git a/libs/ui/InputDispatcher.cpp b/libs/ui/InputDispatcher.cpp
index b53f140..13030b5 100644
--- a/libs/ui/InputDispatcher.cpp
+++ b/libs/ui/InputDispatcher.cpp
@@ -433,8 +433,7 @@
for (size_t i = 0; i < mCurrentInputTargets.size(); i++) {
const InputTarget& inputTarget = mCurrentInputTargets.itemAt(i);
- ssize_t connectionIndex = mConnectionsByReceiveFd.indexOfKey(
- inputTarget.inputChannel->getReceivePipeFd());
+ ssize_t connectionIndex = getConnectionIndex(inputTarget.inputChannel);
if (connectionIndex >= 0) {
sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
prepareDispatchCycleLocked(currentTime, connection, eventEntry, & inputTarget,
@@ -1367,12 +1366,10 @@
LOGD("channel '%s' ~ registerInputChannel", inputChannel->getName().string());
#endif
- int receiveFd;
{ // acquire lock
AutoMutex _l(mLock);
- receiveFd = inputChannel->getReceivePipeFd();
- if (mConnectionsByReceiveFd.indexOfKey(receiveFd) >= 0) {
+ if (getConnectionIndex(inputChannel) >= 0) {
LOGW("Attempted to register already registered input channel '%s'",
inputChannel->getName().string());
return BAD_VALUE;
@@ -1386,12 +1383,13 @@
return status;
}
+ int32_t receiveFd = inputChannel->getReceivePipeFd();
mConnectionsByReceiveFd.add(receiveFd, connection);
+ mPollLoop->setCallback(receiveFd, POLLIN, handleReceiveCallback, this);
+
runCommandsLockedInterruptible();
} // release lock
-
- mPollLoop->setCallback(receiveFd, POLLIN, handleReceiveCallback, this);
return OK;
}
@@ -1400,12 +1398,10 @@
LOGD("channel '%s' ~ unregisterInputChannel", inputChannel->getName().string());
#endif
- int32_t receiveFd;
{ // acquire lock
AutoMutex _l(mLock);
- receiveFd = inputChannel->getReceivePipeFd();
- ssize_t connectionIndex = mConnectionsByReceiveFd.indexOfKey(receiveFd);
+ ssize_t connectionIndex = getConnectionIndex(inputChannel);
if (connectionIndex < 0) {
LOGW("Attempted to unregister already unregistered input channel '%s'",
inputChannel->getName().string());
@@ -1417,20 +1413,32 @@
connection->status = Connection::STATUS_ZOMBIE;
+ mPollLoop->removeCallback(inputChannel->getReceivePipeFd());
+
nsecs_t currentTime = now();
abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
runCommandsLockedInterruptible();
} // release lock
- mPollLoop->removeCallback(receiveFd);
-
// Wake the poll loop because removing the connection may have changed the current
// synchronization state.
mPollLoop->wake();
return OK;
}
+ssize_t InputDispatcher::getConnectionIndex(const sp<InputChannel>& inputChannel) {
+ ssize_t connectionIndex = mConnectionsByReceiveFd.indexOfKey(inputChannel->getReceivePipeFd());
+ if (connectionIndex >= 0) {
+ sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
+ if (connection->inputChannel.get() == inputChannel.get()) {
+ return connectionIndex;
+ }
+ }
+
+ return -1;
+}
+
void InputDispatcher::activateConnectionLocked(Connection* connection) {
for (size_t i = 0; i < mActiveConnections.size(); i++) {
if (mActiveConnections.itemAt(i) == connection) {
diff --git a/libs/ui/InputReader.cpp b/libs/ui/InputReader.cpp
index 5f5a4ac..6f042ec 100644
--- a/libs/ui/InputReader.cpp
+++ b/libs/ui/InputReader.cpp
@@ -945,7 +945,6 @@
mAccumulator.fields = Accumulator::FIELD_BTN_MOUSE;
mAccumulator.btnMouse = false;
sync(when);
- mAccumulator.clear();
}
InputMapper::reset();
@@ -958,9 +957,9 @@
case BTN_MOUSE:
mAccumulator.fields |= Accumulator::FIELD_BTN_MOUSE;
mAccumulator.btnMouse = rawEvent->value != 0;
-
+ // Sync now since BTN_MOUSE is not necessarily followed by SYN_REPORT and
+ // we need to ensure that we report the up/down promptly.
sync(rawEvent->when);
- mAccumulator.clear();
break;
}
break;
@@ -981,10 +980,7 @@
case EV_SYN:
switch (rawEvent->scanCode) {
case SYN_REPORT:
- if (mAccumulator.isDirty()) {
- sync(rawEvent->when);
- mAccumulator.clear();
- }
+ sync(rawEvent->when);
break;
}
break;
@@ -992,13 +988,17 @@
}
void TrackballInputMapper::sync(nsecs_t when) {
+ uint32_t fields = mAccumulator.fields;
+ if (fields == 0) {
+ return; // no new state changes, so nothing to do
+ }
+
int motionEventAction;
PointerCoords pointerCoords;
nsecs_t downTime;
{ // acquire lock
AutoMutex _l(mLock);
- uint32_t fields = mAccumulator.fields;
bool downChanged = fields & Accumulator::FIELD_BTN_MOUSE;
if (downChanged) {
@@ -1061,6 +1061,8 @@
} // release lock
applyPolicyAndDispatch(when, motionEventAction, & pointerCoords, downTime);
+
+ mAccumulator.clear();
}
void TrackballInputMapper::applyPolicyAndDispatch(nsecs_t when, int32_t motionEventAction,
@@ -2380,8 +2382,8 @@
mDown = false;
mX = 0;
mY = 0;
- mPressure = 0;
- mSize = 0;
+ mPressure = 1; // default to 1 for devices that don't report pressure
+ mSize = 0; // default to 0 for devices that don't report size
}
void SingleTouchInputMapper::reset() {
@@ -2397,9 +2399,9 @@
case BTN_TOUCH:
mAccumulator.fields |= Accumulator::FIELD_BTN_TOUCH;
mAccumulator.btnTouch = rawEvent->value != 0;
-
- sync(rawEvent->when);
- mAccumulator.clear();
+ // Don't sync immediately. Wait until the next SYN_REPORT since we might
+ // not have received valid position information yet. This logic assumes that
+ // BTN_TOUCH is always followed by SYN_REPORT as part of a complete packet.
break;
}
break;
@@ -2428,10 +2430,7 @@
case EV_SYN:
switch (rawEvent->scanCode) {
case SYN_REPORT:
- if (mAccumulator.isDirty()) {
- sync(rawEvent->when);
- mAccumulator.clear();
- }
+ sync(rawEvent->when);
break;
}
break;
@@ -2439,9 +2438,10 @@
}
void SingleTouchInputMapper::sync(nsecs_t when) {
- /* Update device state */
-
uint32_t fields = mAccumulator.fields;
+ if (fields == 0) {
+ return; // no new state changes, so nothing to do
+ }
if (fields & Accumulator::FIELD_BTN_TOUCH) {
mDown = mAccumulator.btnTouch;
@@ -2472,8 +2472,8 @@
mCurrentTouch.pointers[0].y = mY;
mCurrentTouch.pointers[0].pressure = mPressure;
mCurrentTouch.pointers[0].size = mSize;
- mCurrentTouch.pointers[0].touchMajor = mPressure;
- mCurrentTouch.pointers[0].touchMinor = mPressure;
+ mCurrentTouch.pointers[0].touchMajor = mSize;
+ mCurrentTouch.pointers[0].touchMinor = mSize;
mCurrentTouch.pointers[0].toolMajor = mSize;
mCurrentTouch.pointers[0].toolMinor = mSize;
mCurrentTouch.pointers[0].orientation = 0;
@@ -2482,6 +2482,8 @@
}
syncTouch(when, true);
+
+ mAccumulator.clear();
}
void SingleTouchInputMapper::configureAxes() {
@@ -2494,8 +2496,8 @@
getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_PRESSURE, & mAxes.pressure);
getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_TOOL_WIDTH, & mAxes.size);
- mAxes.touchMajor = mAxes.pressure;
- mAxes.touchMinor = mAxes.pressure;
+ mAxes.touchMajor = mAxes.size;
+ mAxes.touchMinor = mAxes.size;
mAxes.toolMajor = mAxes.size;
mAxes.toolMinor = mAxes.size;
}
@@ -2585,10 +2587,7 @@
}
case SYN_REPORT:
- if (mAccumulator.isDirty()) {
- sync(rawEvent->when);
- mAccumulator.clear();
- }
+ sync(rawEvent->when);
break;
}
break;
@@ -2598,11 +2597,7 @@
void MultiTouchInputMapper::sync(nsecs_t when) {
static const uint32_t REQUIRED_FIELDS =
Accumulator::FIELD_ABS_MT_POSITION_X
- | Accumulator::FIELD_ABS_MT_POSITION_Y
- | Accumulator::FIELD_ABS_MT_TOUCH_MAJOR
- | Accumulator::FIELD_ABS_MT_WIDTH_MAJOR;
-
- /* Update device state */
+ | Accumulator::FIELD_ABS_MT_POSITION_Y;
uint32_t inCount = mAccumulator.pointerCount;
uint32_t outCount = 0;
@@ -2611,53 +2606,76 @@
mCurrentTouch.clear();
for (uint32_t inIndex = 0; inIndex < inCount; inIndex++) {
- uint32_t fields = mAccumulator.pointers[inIndex].fields;
+ const Accumulator::Pointer& inPointer = mAccumulator.pointers[inIndex];
+ uint32_t fields = inPointer.fields;
if ((fields & REQUIRED_FIELDS) != REQUIRED_FIELDS) {
-#if DEBUG_POINTERS
- LOGD("Pointers: Missing required multitouch pointer fields: index=%d, fields=%d",
- inIndex, fields);
- continue;
-#endif
- }
-
- if (mAccumulator.pointers[inIndex].absMTTouchMajor <= 0) {
- // Pointer is not down. Drop it.
+ // Some drivers send empty MT sync packets without X / Y to indicate a pointer up.
+ // Drop this finger.
continue;
}
- mCurrentTouch.pointers[outCount].x = mAccumulator.pointers[inIndex].absMTPositionX;
- mCurrentTouch.pointers[outCount].y = mAccumulator.pointers[inIndex].absMTPositionY;
+ PointerData& outPointer = mCurrentTouch.pointers[outCount];
+ outPointer.x = inPointer.absMTPositionX;
+ outPointer.y = inPointer.absMTPositionY;
- mCurrentTouch.pointers[outCount].touchMajor =
- mAccumulator.pointers[inIndex].absMTTouchMajor;
- mCurrentTouch.pointers[outCount].touchMinor =
- (fields & Accumulator::FIELD_ABS_MT_TOUCH_MINOR) != 0
- ? mAccumulator.pointers[inIndex].absMTTouchMinor
- : mAccumulator.pointers[inIndex].absMTTouchMajor;
+ if (fields & Accumulator::FIELD_ABS_MT_TOUCH_MAJOR) {
+ int32_t value = inPointer.absMTTouchMajor;
+ if (value <= 0) {
+ // Some devices send sync packets with X / Y but with a 0 touch major to indicate
+ // a pointer up. Drop this finger.
+ continue;
+ }
+ outPointer.touchMajor = inPointer.absMTTouchMajor;
+ } else {
+ outPointer.touchMajor = 0;
+ }
- mCurrentTouch.pointers[outCount].toolMajor =
- mAccumulator.pointers[inIndex].absMTWidthMajor;
- mCurrentTouch.pointers[outCount].toolMinor =
- (fields & Accumulator::FIELD_ABS_MT_WIDTH_MINOR) != 0
- ? mAccumulator.pointers[inIndex].absMTWidthMinor
- : mAccumulator.pointers[inIndex].absMTWidthMajor;
+ if (fields & Accumulator::FIELD_ABS_MT_TOUCH_MINOR) {
+ outPointer.touchMinor = inPointer.absMTTouchMinor;
+ } else {
+ outPointer.touchMinor = outPointer.touchMajor;
+ }
- mCurrentTouch.pointers[outCount].orientation =
- (fields & Accumulator::FIELD_ABS_MT_ORIENTATION) != 0
- ? mAccumulator.pointers[inIndex].absMTOrientation : 0;
+ if (fields & Accumulator::FIELD_ABS_MT_WIDTH_MAJOR) {
+ outPointer.toolMajor = inPointer.absMTWidthMajor;
+ } else {
+ outPointer.toolMajor = outPointer.touchMajor;
+ }
- // Derive an approximation of pressure and size.
- // FIXME assignment of pressure may be incorrect, probably better to let
- // pressure = touch / width. Later on we pass width to MotionEvent as a size, which
- // isn't quite right either. Should be using touch for that.
- mCurrentTouch.pointers[outCount].pressure = mAccumulator.pointers[inIndex].absMTTouchMajor;
- mCurrentTouch.pointers[outCount].size = mAccumulator.pointers[inIndex].absMTWidthMajor;
+ if (fields & Accumulator::FIELD_ABS_MT_WIDTH_MINOR) {
+ outPointer.toolMinor = inPointer.absMTWidthMinor;
+ } else {
+ outPointer.toolMinor = outPointer.toolMajor;
+ }
+
+ if (fields & Accumulator::FIELD_ABS_MT_ORIENTATION) {
+ outPointer.orientation = inPointer.absMTOrientation;
+ } else {
+ outPointer.orientation = 0;
+ }
+
+ if (fields & Accumulator::FIELD_ABS_MT_PRESSURE) {
+ outPointer.pressure = inPointer.absMTPressure;
+ } else {
+ // Derive an approximation of pressure.
+ // FIXME Traditionally we have just passed a normalized value based on
+ // ABS_MT_TOUCH_MAJOR as an estimate of pressure but the result is not
+ // very meaningful, particularly on large displays. We should probably let
+ // pressure = touch_major / tool_major but it is unclear whether that will
+ // break applications.
+ outPointer.pressure = outPointer.touchMajor;
+ }
+
+ // Size is an alias for a normalized tool width.
+ // FIXME Normalized tool width doesn't actually make much sense since it literally
+ // means the approaching contact major axis is divided by its full range as
+ // reported by the driver. On a large display this could produce very small values.
+ outPointer.size = outPointer.toolMajor;
if (havePointerIds) {
- if (fields & Accumulator::
- FIELD_ABS_MT_TRACKING_ID) {
- uint32_t id = uint32_t(mAccumulator.pointers[inIndex].absMTTrackingId);
+ if (fields & Accumulator::FIELD_ABS_MT_TRACKING_ID) {
+ uint32_t id = uint32_t(inPointer.absMTTrackingId);
if (id > MAX_POINTER_ID) {
#if DEBUG_POINTERS
@@ -2668,7 +2686,7 @@
havePointerIds = false;
}
else {
- mCurrentTouch.pointers[outCount].id = id;
+ outPointer.id = id;
mCurrentTouch.idToIndex[id] = outCount;
mCurrentTouch.idBits.markBit(id);
}
@@ -2683,6 +2701,8 @@
mCurrentTouch.pointerCount = outCount;
syncTouch(when, havePointerIds);
+
+ mAccumulator.clear();
}
void MultiTouchInputMapper::configureAxes() {
@@ -2697,6 +2717,7 @@
getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_WIDTH_MAJOR, & mAxes.toolMajor);
getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_WIDTH_MINOR, & mAxes.toolMinor);
getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_ORIENTATION, & mAxes.orientation);
+ getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_PRESSURE, & mAxes.pressure);
if (! mAxes.touchMinor.valid) {
mAxes.touchMinor = mAxes.touchMajor;
@@ -2706,7 +2727,10 @@
mAxes.toolMinor = mAxes.toolMajor;
}
- mAxes.pressure = mAxes.touchMajor;
+ if (! mAxes.pressure.valid) {
+ mAxes.pressure = mAxes.touchMajor;
+ }
+
mAxes.size = mAxes.toolMajor;
}
diff --git a/services/surfaceflinger/Android.mk b/services/surfaceflinger/Android.mk
index 79772ed..a14bfb5 100644
--- a/services/surfaceflinger/Android.mk
+++ b/services/surfaceflinger/Android.mk
@@ -5,7 +5,6 @@
clz.cpp.arm \
DisplayHardware/DisplayHardware.cpp \
DisplayHardware/DisplayHardwareBase.cpp \
- DisplayHardware/HWComposer.cpp \
BlurFilter.cpp.arm \
GLExtensions.cpp \
Layer.cpp \
diff --git a/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp b/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp
index 166c528..2eac0a8 100644
--- a/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp
+++ b/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp
@@ -36,11 +36,11 @@
#include "DisplayHardware/DisplayHardware.h"
+#include <hardware/copybit.h>
#include <hardware/overlay.h>
#include <hardware/gralloc.h>
#include "GLExtensions.h"
-#include "HWComposer.h"
using namespace android;
@@ -76,7 +76,7 @@
const sp<SurfaceFlinger>& flinger,
uint32_t dpy)
: DisplayHardwareBase(flinger, dpy),
- mFlags(0), mHwc(0)
+ mFlags(0)
{
init(dpy);
}
@@ -262,17 +262,6 @@
// Unbind the context from this thread
eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
-
-
- // initialize the H/W composer
- mHwc = new HWComposer();
- if (mHwc->initCheck() == NO_ERROR) {
- mHwc->setFrameBuffer(mDisplay, mSurface);
- }
-}
-
-HWComposer& DisplayHardware::getHwComposer() const {
- return *mHwc;
}
/*
@@ -328,12 +317,7 @@
}
mPageFlipCount++;
-
- if (mHwc->initCheck() == NO_ERROR) {
- mHwc->commit();
- } else {
- eglSwapBuffers(dpy, surface);
- }
+ eglSwapBuffers(dpy, surface);
checkEGLErrors("eglSwapBuffers");
// for debugging
diff --git a/services/surfaceflinger/DisplayHardware/DisplayHardware.h b/services/surfaceflinger/DisplayHardware/DisplayHardware.h
index f2cfd2d..66bf521 100644
--- a/services/surfaceflinger/DisplayHardware/DisplayHardware.h
+++ b/services/surfaceflinger/DisplayHardware/DisplayHardware.h
@@ -34,11 +34,12 @@
#include "DisplayHardware/DisplayHardwareBase.h"
struct overlay_control_device_t;
+struct framebuffer_device_t;
+struct copybit_image_t;
namespace android {
class FramebufferNativeWindow;
-class HWComposer;
class DisplayHardware : public DisplayHardwareBase
{
@@ -79,9 +80,6 @@
uint32_t getPageFlipCount() const;
EGLDisplay getEGLDisplay() const { return mDisplay; }
overlay_control_device_t* getOverlayEngine() const { return mOverlayEngine; }
-
- // Hardware Composer
- HWComposer& getHwComposer() const;
status_t compositionComplete() const;
@@ -109,8 +107,6 @@
GLint mMaxViewportDims;
GLint mMaxTextureSize;
- HWComposer* mHwc;
-
sp<FramebufferNativeWindow> mNativeWindow;
overlay_control_device_t* mOverlayEngine;
};
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
deleted file mode 100644
index 0291d78..0000000
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (C) 2010 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 <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-
-#include <utils/Errors.h>
-
-#include <hardware/hardware.h>
-
-#include <cutils/log.h>
-
-#include <EGL/egl.h>
-
-#include "HWComposer.h"
-
-namespace android {
-// ---------------------------------------------------------------------------
-
-HWComposer::HWComposer()
- : mModule(0), mHwc(0), mList(0), mCapacity(0),
- mDpy(EGL_NO_DISPLAY), mSur(EGL_NO_SURFACE)
-{
- int err = hw_get_module(HWC_HARDWARE_MODULE_ID, &mModule);
- LOGW_IF(err, "%s module not found", HWC_HARDWARE_MODULE_ID);
- if (err == 0) {
- err = hwc_open(mModule, &mHwc);
- LOGE_IF(err, "%s device failed to initialize (%s)",
- HWC_HARDWARE_COMPOSER, strerror(-err));
- }
-}
-
-HWComposer::~HWComposer() {
- free(mList);
- if (mHwc) {
- hwc_close(mHwc);
- }
-}
-
-status_t HWComposer::initCheck() const {
- return mHwc ? NO_ERROR : NO_INIT;
-}
-
-void HWComposer::setFrameBuffer(EGLDisplay dpy, EGLSurface sur) {
- mDpy = (hwc_display_t)dpy;
- mSur = (hwc_surface_t)sur;
-}
-
-status_t HWComposer::createWorkList(size_t numLayers) {
- if (mHwc) {
- if (!mList || mCapacity < numLayers) {
- free(mList);
- size_t size = sizeof(hwc_layer_list) + numLayers*sizeof(hwc_layer_t);
- mList = (hwc_layer_list_t*)malloc(size);
- mCapacity = numLayers;
- }
- mList->flags = HWC_GEOMETRY_CHANGED;
- mList->numHwLayers = numLayers;
- }
- return NO_ERROR;
-}
-
-status_t HWComposer::prepare() const {
- int err = mHwc->prepare(mHwc, mList);
- return (status_t)err;
-}
-
-status_t HWComposer::commit() const {
- int err = mHwc->set(mHwc, mDpy, mSur, mList);
- mList->flags &= ~HWC_GEOMETRY_CHANGED;
- return (status_t)err;
-}
-
-size_t HWComposer::getNumLayers() const {
- return mList ? mList->numHwLayers : 0;
-}
-
-hwc_layer_t* HWComposer::getLayers() const {
- return mList ? mList->hwLayers : 0;
-}
-
-// ---------------------------------------------------------------------------
-}; // namespace android
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
deleted file mode 100644
index c5d5c2b..0000000
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2010 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_SF_HWCOMPOSER_H
-#define ANDROID_SF_HWCOMPOSER_H
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <EGL/egl.h>
-
-#include <hardware/hwcomposer.h>
-
-namespace android {
-// ---------------------------------------------------------------------------
-
-class HWComposer
-{
-public:
-
- HWComposer();
- ~HWComposer();
-
- status_t initCheck() const;
-
- // tells the HAL what the framebuffer is
- void setFrameBuffer(EGLDisplay dpy, EGLSurface sur);
-
- // create a work list for numLayers layer
- status_t createWorkList(size_t numLayers);
-
- // Asks the HAL what it can do
- status_t prepare() const;
-
- // commits the list
- status_t commit() const;
-
-
- size_t getNumLayers() const;
- hwc_layer_t* getLayers() const;
-
-private:
- hw_module_t const* mModule;
- hwc_composer_device_t* mHwc;
- hwc_layer_list_t* mList;
- size_t mCapacity;
- hwc_display_t mDpy;
- hwc_surface_t mSur;
-};
-
-
-// ---------------------------------------------------------------------------
-}; // namespace android
-
-#endif // ANDROID_SF_HWCOMPOSER_H
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 3720e16..629d993 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -35,7 +35,6 @@
#include "Layer.h"
#include "SurfaceFlinger.h"
#include "DisplayHardware/DisplayHardware.h"
-#include "DisplayHardware/HWComposer.h"
#define DEBUG_RESIZE 0
@@ -178,62 +177,6 @@
return NO_ERROR;
}
-void Layer::setGeometry(hwc_layer_t* hwcl)
-{
- hwcl->compositionType = HWC_FRAMEBUFFER;
- hwcl->hints = 0;
- hwcl->flags = 0;
- hwcl->transform = 0;
- hwcl->blending = HWC_BLENDING_NONE;
-
- // we can't do alpha-fade with the hwc HAL
- const State& s(drawingState());
- if (s.alpha < 0xFF) {
- hwcl->flags = HWC_SKIP_LAYER;
- return;
- }
-
- // we can only handle simple transformation
- if (mOrientation & Transform::ROT_INVALID) {
- hwcl->flags = HWC_SKIP_LAYER;
- return;
- }
-
- hwcl->transform = mOrientation;
-
- if (needsBlending()) {
- hwcl->blending = mPremultipliedAlpha ?
- HWC_BLENDING_PREMULT : HWC_BLENDING_COVERAGE;
- }
-
- hwcl->displayFrame.left = mTransformedBounds.left;
- hwcl->displayFrame.top = mTransformedBounds.top;
- hwcl->displayFrame.right = mTransformedBounds.right;
- hwcl->displayFrame.bottom = mTransformedBounds.bottom;
-
- hwcl->visibleRegionScreen.rects =
- reinterpret_cast<hwc_rect_t const *>(
- visibleRegionScreen.getArray(
- &hwcl->visibleRegionScreen.numRects));
-}
-
-void Layer::setPerFrameData(hwc_layer_t* hwcl) {
- sp<GraphicBuffer> buffer(mBufferManager.getActiveBuffer());
- if (buffer == NULL) {
- // this situation can happen if we ran out of memory for instance.
- // not much we can do. continue to use whatever texture was bound
- // to this context.
- hwcl->handle = NULL;
- return;
- }
- hwcl->handle = const_cast<native_handle_t*>(buffer->handle);
- // TODO: set the crop value properly
- hwcl->sourceCrop.left = 0;
- hwcl->sourceCrop.top = 0;
- hwcl->sourceCrop.right = buffer->width;
- hwcl->sourceCrop.bottom = buffer->height;
-}
-
void Layer::reloadTexture(const Region& dirty)
{
sp<GraphicBuffer> buffer(mBufferManager.getActiveBuffer());
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 188da6a..e1d283b 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -68,8 +68,6 @@
bool isFixedSize() const;
// LayerBase interface
- virtual void setGeometry(hwc_layer_t* hwcl);
- virtual void setPerFrameData(hwc_layer_t* hwcl);
virtual void onDraw(const Region& clip) const;
virtual uint32_t doTransaction(uint32_t transactionFlags);
virtual void lockPageFlip(bool& recomputeVisibleRegions);
diff --git a/services/surfaceflinger/LayerBase.cpp b/services/surfaceflinger/LayerBase.cpp
index 043d54d..91ac915 100644
--- a/services/surfaceflinger/LayerBase.cpp
+++ b/services/surfaceflinger/LayerBase.cpp
@@ -307,15 +307,6 @@
}
}
-void LayerBase::setGeometry(hwc_layer_t* hwcl) {
- hwcl->flags |= HWC_SKIP_LAYER;
-}
-
-void LayerBase::setPerFrameData(hwc_layer_t* hwcl) {
- hwcl->compositionType = HWC_FRAMEBUFFER;
- hwcl->handle = NULL;
-}
-
void LayerBase::draw(const Region& clip) const
{
// reset GL state
diff --git a/services/surfaceflinger/LayerBase.h b/services/surfaceflinger/LayerBase.h
index dd1cd05..22bf857 100644
--- a/services/surfaceflinger/LayerBase.h
+++ b/services/surfaceflinger/LayerBase.h
@@ -35,8 +35,6 @@
#include <pixelflinger/pixelflinger.h>
-#include <hardware/hwcomposer.h>
-
#include "Transform.h"
namespace android {
@@ -110,10 +108,6 @@
virtual const char* getTypeId() const { return "LayerBase"; }
- virtual void setGeometry(hwc_layer_t* hwcl);
-
- virtual void setPerFrameData(hwc_layer_t* hwcl);
-
/**
* draw - performs some global clipping optimizations
* and calls onDraw().
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index d257897..637ae48 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -52,7 +52,6 @@
#include "SurfaceFlinger.h"
#include "DisplayHardware/DisplayHardware.h"
-#include "DisplayHardware/HWComposer.h"
/* ideally AID_GRAPHICS would be in a semi-public header
* or there would be a way to map a user/group name to its id
@@ -77,7 +76,6 @@
mAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER"),
mDump("android.permission.DUMP"),
mVisibleRegionsDirty(false),
- mHwWorkListDirty(false),
mDeferReleaseConsole(false),
mFreezeDisplay(false),
mFreezeCount(0),
@@ -370,11 +368,6 @@
// post surfaces (if needed)
handlePageFlip();
- if (UNLIKELY(mHwWorkListDirty)) {
- // build the h/w work list
- handleWorkList();
- }
-
const DisplayHardware& hw(graphicPlane(0).displayHardware());
if (LIKELY(hw.canDraw() && !isFrozen())) {
// repaint the framebuffer (if needed)
@@ -450,7 +443,6 @@
handleTransactionLocked(transactionFlags, ditchedLayers);
mLastTransactionTime = systemTime() - now;
mDebugInTransaction = 0;
- mHwWorkListDirty = true;
// here the transaction has been committed
}
@@ -458,7 +450,6 @@
* Clean-up all layers that went away
* (do this without the lock held)
*/
-
const size_t count = ditchedLayers.size();
for (size_t i=0 ; i<count ; i++) {
if (ditchedLayers[i] != 0) {
@@ -692,8 +683,8 @@
void SurfaceFlinger::handlePageFlip()
{
bool visibleRegions = mVisibleRegionsDirty;
- LayerVector& currentLayers(
- const_cast<LayerVector&>(mDrawingState.layersSortedByZ));
+ LayerVector& currentLayers = const_cast<LayerVector&>(
+ mDrawingState.layersSortedByZ);
visibleRegions |= lockPageFlip(currentLayers);
const DisplayHardware& hw = graphicPlane(0).displayHardware();
@@ -716,7 +707,6 @@
mWormholeRegion = screenRegion.subtract(opaqueRegion);
mVisibleRegionsDirty = false;
- mHwWorkListDirty = true;
}
unlockPageFlip(currentLayers);
@@ -747,20 +737,6 @@
}
}
-void SurfaceFlinger::handleWorkList()
-{
- mHwWorkListDirty = false;
- HWComposer& hwc(graphicPlane(0).displayHardware().getHwComposer());
- if (hwc.initCheck() == NO_ERROR) {
- const Vector< sp<LayerBase> >& currentLayers(mVisibleLayersSortedByZ);
- const size_t count = currentLayers.size();
- hwc.createWorkList(count);
- hwc_layer_t* const cur(hwc.getLayers());
- for (size_t i=0 ; cur && i<count ; i++) {
- currentLayers[i]->setGeometry(&cur[i]);
- }
- }
-}
void SurfaceFlinger::handleRepaint()
{
@@ -825,72 +801,9 @@
// draw something...
drawWormhole();
}
-
- status_t err = NO_ERROR;
const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
- size_t count = layers.size();
-
- const DisplayHardware& hw(graphicPlane(0).displayHardware());
- HWComposer& hwc(hw.getHwComposer());
- hwc_layer_t* const cur(hwc.getLayers());
-
- LOGE_IF(cur && hwc.getNumLayers() != count,
- "HAL number of layers (%d) doesn't match surfaceflinger (%d)",
- hwc.getNumLayers(), count);
-
- // just to be extra-safe, use the smallest count
- if (hwc.initCheck() == NO_ERROR) {
- count = count < hwc.getNumLayers() ? count : hwc.getNumLayers();
- }
-
- /*
- * update the per-frame h/w composer data for each layer
- * and build the transparent region of the FB
- */
- Region transparent;
- if (cur) {
- for (size_t i=0 ; i<count ; i++) {
- const sp<LayerBase>& layer(layers[i]);
- layer->setPerFrameData(&cur[i]);
- if (cur[i].hints & HWC_HINT_CLEAR_FB) {
- if (!(layer->needsBlending())) {
- transparent.orSelf(layer->visibleRegionScreen);
- }
- }
- }
- err = hwc.prepare();
- LOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err));
- }
-
- /*
- * clear the area of the FB that need to be transparent
- */
- transparent.andSelf(dirty);
- if (!transparent.isEmpty()) {
- glClearColor(0,0,0,0);
- Region::const_iterator it = transparent.begin();
- Region::const_iterator const end = transparent.end();
- const int32_t height = hw.getHeight();
- while (it != end) {
- const Rect& r(*it++);
- const GLint sy = height - (r.top + r.height());
- glScissor(r.left, sy, r.width(), r.height());
- glClear(GL_COLOR_BUFFER_BIT);
- }
- }
-
-
- /*
- * and then, render the layers targeted at the framebuffer
- */
- for (size_t i=0 ; i<count ; i++) {
- if (cur) {
- if (!(cur[i].compositionType == HWC_FRAMEBUFFER) ||
- cur[i].flags & HWC_SKIP_LAYER) {
- // skip layers handled by the HAL
- continue;
- }
- }
+ const size_t count = layers.size();
+ for (size_t i=0 ; i<count ; ++i) {
const sp<LayerBase>& layer(layers[i]);
const Region clip(dirty.intersect(layer->visibleRegionScreen));
if (!clip.isEmpty()) {
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 8e286e5..8ecfc01 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -296,7 +296,6 @@
void handlePageFlip();
bool lockPageFlip(const LayerVector& currentLayers);
void unlockPageFlip(const LayerVector& currentLayers);
- void handleWorkList();
void handleRepaint();
void postFramebuffer();
void composeSurfaces(const Region& dirty);
@@ -371,7 +370,6 @@
Region mInvalidRegion;
Region mWormholeRegion;
bool mVisibleRegionsDirty;
- bool mHwWorkListDirty;
bool mDeferReleaseConsole;
bool mFreezeDisplay;
int32_t mFreezeCount;