Merge "Add a boardconfig to force HWC composition of virtual displays" into klp-dev
diff --git a/libs/gui/BufferQueue.cpp b/libs/gui/BufferQueue.cpp
index c165a68..2aecb67 100644
--- a/libs/gui/BufferQueue.cpp
+++ b/libs/gui/BufferQueue.cpp
@@ -644,6 +644,7 @@
producerControlledByApp ? "true" : "false");
Mutex::Autolock lock(mMutex);
+retry:
if (mAbandoned) {
ST_LOGE("connect: BufferQueue has been abandoned!");
return NO_INIT;
@@ -654,29 +655,41 @@
return NO_INIT;
}
+ if (mConnectedApi != NO_CONNECTED_API) {
+ ST_LOGE("connect: already connected (cur=%d, req=%d)",
+ mConnectedApi, api);
+ return -EINVAL;
+ }
+
+ // If we disconnect and reconnect quickly, we can be in a state where our slots are
+ // empty but we have many buffers in the queue. This can cause us to run out of
+ // memory if we outrun the consumer. Wait here if it looks like we have too many
+ // buffers queued up.
+ int maxBufferCount = getMaxBufferCountLocked(false); // worst-case, i.e. largest value
+ if (mQueue.size() > (size_t) maxBufferCount) {
+ // TODO: make this bound tighter?
+ ST_LOGV("queue size is %d, waiting", mQueue.size());
+ mDequeueCondition.wait(mMutex);
+ goto retry;
+ }
+
int err = NO_ERROR;
switch (api) {
case NATIVE_WINDOW_API_EGL:
case NATIVE_WINDOW_API_CPU:
case NATIVE_WINDOW_API_MEDIA:
case NATIVE_WINDOW_API_CAMERA:
- if (mConnectedApi != NO_CONNECTED_API) {
- ST_LOGE("connect: already connected (cur=%d, req=%d)",
- mConnectedApi, api);
- err = -EINVAL;
- } else {
- mConnectedApi = api;
- output->inflate(mDefaultWidth, mDefaultHeight, mTransformHint, mQueue.size());
+ mConnectedApi = api;
+ output->inflate(mDefaultWidth, mDefaultHeight, mTransformHint, mQueue.size());
- // set-up a death notification so that we can disconnect
- // automatically when/if the remote producer dies.
- if (token != NULL && token->remoteBinder() != NULL) {
- status_t err = token->linkToDeath(static_cast<IBinder::DeathRecipient*>(this));
- if (err == NO_ERROR) {
- mConnectedProducerToken = token;
- } else {
- ALOGE("linkToDeath failed: %s (%d)", strerror(-err), err);
- }
+ // set-up a death notification so that we can disconnect
+ // automatically when/if the remote producer dies.
+ if (token != NULL && token->remoteBinder() != NULL) {
+ status_t err = token->linkToDeath(static_cast<IBinder::DeathRecipient*>(this));
+ if (err == NO_ERROR) {
+ mConnectedProducerToken = token;
+ } else {
+ ALOGE("linkToDeath failed: %s (%d)", strerror(-err), err);
}
}
break;
diff --git a/libs/input/InputTransport.cpp b/libs/input/InputTransport.cpp
index 9bd7fc6..09b2e7c 100644
--- a/libs/input/InputTransport.cpp
+++ b/libs/input/InputTransport.cpp
@@ -511,14 +511,17 @@
status_t result;
for (size_t i = mBatches.size(); i-- > 0; ) {
Batch& batch = mBatches.editItemAt(i);
- if (frameTime < 0 || !mResampleTouch) {
+ if (frameTime < 0) {
result = consumeSamples(factory, batch, batch.samples.size(),
outSeq, outEvent);
mBatches.removeAt(i);
return result;
}
- nsecs_t sampleTime = frameTime - RESAMPLE_LATENCY;
+ nsecs_t sampleTime = frameTime;
+ if (mResampleTouch) {
+ sampleTime -= RESAMPLE_LATENCY;
+ }
ssize_t split = findSampleNoLaterThan(batch, sampleTime);
if (split < 0) {
continue;
@@ -532,7 +535,7 @@
} else {
next = &batch.samples.itemAt(0);
}
- if (!result) {
+ if (!result && mResampleTouch) {
resampleTouchState(sampleTime, static_cast<MotionEvent*>(*outEvent), next);
}
return result;