Merge "Fix 5023708,4689527: Add popups and overlays to recents. Misc bug fixes."
diff --git a/include/gui/ISurfaceTexture.h b/include/gui/ISurfaceTexture.h
index e705c6f..5b5b731 100644
--- a/include/gui/ISurfaceTexture.h
+++ b/include/gui/ISurfaceTexture.h
@@ -104,6 +104,24 @@
// queued buffers will be retired in order.
// The default mode is asynchronous.
virtual status_t setSynchronousMode(bool enabled) = 0;
+
+ // connect attempts to connect a client API to the SurfaceTexture. This
+ // must be called before any other ISurfaceTexture methods are called except
+ // for getAllocator.
+ //
+ // This method will fail if the connect was previously called on the
+ // SurfaceTexture and no corresponding disconnect call was made.
+ virtual status_t connect(int api) = 0;
+
+ // disconnect attempts to disconnect a client API from the SurfaceTexture.
+ // Calling this method will cause any subsequent calls to other
+ // ISurfaceTexture methods to fail except for getAllocator and connect.
+ // Successfully calling connect after this will allow the other methods to
+ // succeed again.
+ //
+ // This method will fail if the the SurfaceTexture is not currently
+ // connected to the specified client API.
+ virtual status_t disconnect(int api) = 0;
};
// ----------------------------------------------------------------------------
diff --git a/include/gui/SurfaceTexture.h b/include/gui/SurfaceTexture.h
index e36360c..4080f27 100644
--- a/include/gui/SurfaceTexture.h
+++ b/include/gui/SurfaceTexture.h
@@ -44,6 +44,7 @@
MIN_SYNC_BUFFER_SLOTS = MIN_UNDEQUEUED_BUFFERS
};
enum { NUM_BUFFER_SLOTS = 32 };
+ enum { NO_CONNECTED_API = 0 };
struct FrameAvailableListener : public virtual RefBase {
// onFrameAvailable() is called from queueBuffer() each time an
@@ -97,6 +98,24 @@
// The default mode is asynchronous.
virtual status_t setSynchronousMode(bool enabled);
+ // connect attempts to connect a client API to the SurfaceTexture. This
+ // must be called before any other ISurfaceTexture methods are called except
+ // for getAllocator.
+ //
+ // This method will fail if the connect was previously called on the
+ // SurfaceTexture and no corresponding disconnect call was made.
+ virtual status_t connect(int api);
+
+ // disconnect attempts to disconnect a client API from the SurfaceTexture.
+ // Calling this method will cause any subsequent calls to other
+ // ISurfaceTexture methods to fail except for getAllocator and connect.
+ // Successfully calling connect after this will allow the other methods to
+ // succeed again.
+ //
+ // This method will fail if the the SurfaceTexture is not currently
+ // connected to the specified client API.
+ virtual status_t disconnect(int api);
+
// updateTexImage sets the image contents of the target texture to that of
// the most recently queued buffer.
//
@@ -362,6 +381,11 @@
// mAllowSynchronousMode whether we allow synchronous mode or not
const bool mAllowSynchronousMode;
+ // mConnectedApi indicates the API that is currently connected to this
+ // SurfaceTexture. It defaults to NO_CONNECTED_API (= 0), and gets updated
+ // by the connect and disconnect methods.
+ int mConnectedApi;
+
// mDequeueCondition condition used for dequeueBuffer in synchronous mode
mutable Condition mDequeueCondition;
diff --git a/include/gui/SurfaceTextureClient.h b/include/gui/SurfaceTextureClient.h
index 9db7364..5ec469e 100644
--- a/include/gui/SurfaceTextureClient.h
+++ b/include/gui/SurfaceTextureClient.h
@@ -129,9 +129,6 @@
// a timestamp is auto-generated when queueBuffer is called.
int64_t mTimestamp;
- // mConnectedApi holds the currently connected API to this surface
- int mConnectedApi;
-
// mQueryWidth is the width returned by query(). It is set to width
// of the last dequeued buffer or to mReqWidth if no buffer was dequeued.
uint32_t mQueryWidth;
diff --git a/libs/gui/ISurfaceTexture.cpp b/libs/gui/ISurfaceTexture.cpp
index 16e3780..41434a4 100644
--- a/libs/gui/ISurfaceTexture.cpp
+++ b/libs/gui/ISurfaceTexture.cpp
@@ -41,6 +41,8 @@
GET_ALLOCATOR,
QUERY,
SET_SYNCHRONOUS_MODE,
+ CONNECT,
+ DISCONNECT,
};
@@ -154,7 +156,23 @@
return result;
}
+ virtual status_t connect(int api) {
+ Parcel data, reply;
+ data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor());
+ data.writeInt32(api);
+ remote()->transact(CONNECT, data, &reply);
+ status_t result = reply.readInt32();
+ return result;
+ }
+ virtual status_t disconnect(int api) {
+ Parcel data, reply;
+ data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor());
+ data.writeInt32(api);
+ remote()->transact(DISCONNECT, data, &reply);
+ status_t result = reply.readInt32();
+ return result;
+ }
};
IMPLEMENT_META_INTERFACE(SurfaceTexture, "android.gui.SurfaceTexture");
@@ -248,6 +266,20 @@
reply->writeInt32(res);
return NO_ERROR;
} break;
+ case CONNECT: {
+ CHECK_INTERFACE(ISurfaceTexture, data, reply);
+ int api = data.readInt32();
+ status_t res = connect(api);
+ reply->writeInt32(res);
+ return NO_ERROR;
+ } break;
+ case DISCONNECT: {
+ CHECK_INTERFACE(ISurfaceTexture, data, reply);
+ int api = data.readInt32();
+ status_t res = disconnect(api);
+ reply->writeInt32(res);
+ return NO_ERROR;
+ } break;
}
return BBinder::onTransact(code, data, reply, flags);
}
diff --git a/libs/gui/SurfaceTexture.cpp b/libs/gui/SurfaceTexture.cpp
index 886a3fb..1410481 100644
--- a/libs/gui/SurfaceTexture.cpp
+++ b/libs/gui/SurfaceTexture.cpp
@@ -92,7 +92,8 @@
mNextTransform(0),
mTexName(tex),
mSynchronousMode(false),
- mAllowSynchronousMode(allowSynchronousMode) {
+ mAllowSynchronousMode(allowSynchronousMode),
+ mConnectedApi(NO_CONNECTED_API) {
LOGV("SurfaceTexture::SurfaceTexture");
sp<ISurfaceComposer> composer(ComposerService::getComposerService());
mGraphicBufferAlloc = composer->createGraphicBufferAlloc();
@@ -493,6 +494,50 @@
return OK;
}
+status_t SurfaceTexture::connect(int api) {
+ LOGV("SurfaceTexture::connect");
+ Mutex::Autolock lock(mMutex);
+ 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) {
+ err = -EINVAL;
+ } else {
+ mConnectedApi = api;
+ }
+ break;
+ default:
+ err = -EINVAL;
+ break;
+ }
+ return err;
+}
+
+status_t SurfaceTexture::disconnect(int api) {
+ LOGV("SurfaceTexture::disconnect");
+ Mutex::Autolock lock(mMutex);
+ 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 == api) {
+ mConnectedApi = NO_CONNECTED_API;
+ } else {
+ err = -EINVAL;
+ }
+ break;
+ default:
+ err = -EINVAL;
+ break;
+ }
+ return err;
+}
+
status_t SurfaceTexture::updateTexImage() {
LOGV("SurfaceTexture::updateTexImage");
Mutex::Autolock lock(mMutex);
diff --git a/libs/gui/SurfaceTextureClient.cpp b/libs/gui/SurfaceTextureClient.cpp
index e203035..f39cabf 100644
--- a/libs/gui/SurfaceTextureClient.cpp
+++ b/libs/gui/SurfaceTextureClient.cpp
@@ -27,7 +27,7 @@
const sp<ISurfaceTexture>& surfaceTexture):
mSurfaceTexture(surfaceTexture), mAllocator(0), mReqWidth(0),
mReqHeight(0), mReqFormat(0), mReqUsage(0),
- mTimestamp(NATIVE_WINDOW_TIMESTAMP_AUTO), mConnectedApi(0),
+ mTimestamp(NATIVE_WINDOW_TIMESTAMP_AUTO),
mQueryWidth(0), mQueryHeight(0), mQueryFormat(0),
mMutex() {
// Initialize the ANativeWindow function pointers.
@@ -327,45 +327,22 @@
int SurfaceTextureClient::connect(int api) {
LOGV("SurfaceTextureClient::connect");
Mutex::Autolock lock(mMutex);
- int err = NO_ERROR;
- switch (api) {
- case NATIVE_WINDOW_API_EGL:
- if (mConnectedApi) {
- err = -EINVAL;
- } else {
- mConnectedApi = api;
- }
- break;
- default:
- err = -EINVAL;
- break;
- }
- return err;
+ return mSurfaceTexture->connect(api);
}
int SurfaceTextureClient::disconnect(int api) {
LOGV("SurfaceTextureClient::disconnect");
Mutex::Autolock lock(mMutex);
- int err = NO_ERROR;
- switch (api) {
- case NATIVE_WINDOW_API_EGL:
- if (mConnectedApi == api) {
- mConnectedApi = 0;
- } else {
- err = -EINVAL;
- }
- break;
- default:
- err = -EINVAL;
- break;
- }
- return err;
+ return mSurfaceTexture->disconnect(api);
}
int SurfaceTextureClient::getConnectedApi() const
{
+ // XXX: This method will be going away shortly, and is currently bogus. It
+ // always returns "nothing is connected". It will go away once Surface gets
+ // updated to actually connect as the 'CPU' API when locking a buffer.
Mutex::Autolock lock(mMutex);
- return mConnectedApi;
+ return 0;
}
diff --git a/libs/gui/tests/SurfaceTexture_test.cpp b/libs/gui/tests/SurfaceTexture_test.cpp
index 88433fb..9abe89d 100644
--- a/libs/gui/tests/SurfaceTexture_test.cpp
+++ b/libs/gui/tests/SurfaceTexture_test.cpp
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+#define LOG_TAG "SurfaceTexture_test"
//#define LOG_NDEBUG 0
#include <gtest/gtest.h>
@@ -379,6 +380,13 @@
ASSERT_NE(-1, mTexMatrixHandle);
}
+ virtual void TearDown() {
+ mANW.clear();
+ mSTC.clear();
+ mST.clear();
+ GLTest::TearDown();
+ }
+
// drawTexture draws the SurfaceTexture over the entire GL viewport.
void drawTexture() {
const GLfloat triangleVertices[] = {
@@ -1089,13 +1097,21 @@
// synchronously from SurfaceTexture::queueBuffer.
class FrameCondition : public SurfaceTexture::FrameAvailableListener {
public:
+ FrameCondition():
+ mFrameAvailable(false),
+ mFrameFinished(false) {
+ }
+
// waitForFrame waits for the next frame to arrive. This should be
// called from the consumer thread once for every frame expected by the
// test.
void waitForFrame() {
- LOGV("+waitForFrame");
Mutex::Autolock lock(mMutex);
- status_t result = mFrameAvailableCondition.wait(mMutex);
+ LOGV("+waitForFrame");
+ while (!mFrameAvailable) {
+ mFrameAvailableCondition.wait(mMutex);
+ }
+ mFrameAvailable = false;
LOGV("-waitForFrame");
}
@@ -1103,22 +1119,30 @@
// on to produce the next frame. This should be called by the consumer
// thread once for every frame expected by the test.
void finishFrame() {
- LOGV("+finishFrame");
Mutex::Autolock lock(mMutex);
+ LOGV("+finishFrame");
+ mFrameFinished = true;
mFrameFinishCondition.signal();
LOGV("-finishFrame");
}
// This should be called by SurfaceTexture on the producer thread.
virtual void onFrameAvailable() {
- LOGV("+onFrameAvailable");
Mutex::Autolock lock(mMutex);
+ LOGV("+onFrameAvailable");
+ mFrameAvailable = true;
mFrameAvailableCondition.signal();
- mFrameFinishCondition.wait(mMutex);
+ while (!mFrameFinished) {
+ mFrameFinishCondition.wait(mMutex);
+ }
+ mFrameFinished = false;
LOGV("-onFrameAvailable");
}
protected:
+ bool mFrameAvailable;
+ bool mFrameFinished;
+
Mutex mMutex;
Condition mFrameAvailableCondition;
Condition mFrameFinishCondition;
@@ -1164,6 +1188,7 @@
}
mProducerThread.clear();
mFC.clear();
+ SurfaceTextureGLTest::TearDown();
}
void runProducerThread(const sp<ProducerThread> producerThread) {
diff --git a/libs/utils/Threads.cpp b/libs/utils/Threads.cpp
index 50312e7..d18c0a2 100644
--- a/libs/utils/Threads.cpp
+++ b/libs/utils/Threads.cpp
@@ -161,6 +161,7 @@
pthread_t thread;
int result = pthread_create(&thread, &attr,
(android_pthread_entry)entryFunction, userData);
+ pthread_attr_destroy(&attr);
if (result != 0) {
LOGE("androidCreateRawThreadEtc failed (entry=%p, res=%d, errno=%d)\n"
"(android threadPriority=%d)",
diff --git a/libs/utils/VectorImpl.cpp b/libs/utils/VectorImpl.cpp
index 87ae3d5..bfb37a6 100644
--- a/libs/utils/VectorImpl.cpp
+++ b/libs/utils/VectorImpl.cpp
@@ -252,13 +252,15 @@
"[%p] replace: index=%d, size=%d", this, (int)index, (int)size());
void* item = editItemLocation(index);
- if (item == 0)
- return NO_MEMORY;
- _do_destroy(item, 1);
- if (prototype == 0) {
- _do_construct(item, 1);
- } else {
- _do_copy(item, prototype, 1);
+ if (item != prototype) {
+ if (item == 0)
+ return NO_MEMORY;
+ _do_destroy(item, 1);
+ if (prototype == 0) {
+ _do_construct(item, 1);
+ } else {
+ _do_copy(item, prototype, 1);
+ }
}
return ssize_t(index);
}
@@ -347,9 +349,10 @@
// LOGV("_grow(this=%p, where=%d, amount=%d) count=%d, capacity=%d",
// this, (int)where, (int)amount, (int)mCount, (int)capacity());
- if (where > mCount)
- where = mCount;
-
+ LOG_ASSERT(where <= mCount,
+ "[%p] _grow: where=%d, amount=%d, count=%d",
+ this, (int)where, (int)amount, (int)mCount); // caller already checked
+
const size_t new_size = mCount + amount;
if (capacity() < new_size) {
const size_t new_capacity = max(kMinVectorCapacity, ((new_size*3)+1)/2);
@@ -366,10 +369,10 @@
SharedBuffer* sb = SharedBuffer::alloc(new_capacity * mItemSize);
if (sb) {
void* array = sb->data();
- if (where>0) {
+ if (where != 0) {
_do_copy(array, mStorage, where);
}
- if (mCount>where) {
+ if (where != mCount) {
const void* from = reinterpret_cast<const uint8_t *>(mStorage) + where*mItemSize;
void* dest = reinterpret_cast<uint8_t *>(array) + (where+amount)*mItemSize;
_do_copy(dest, from, mCount-where);
@@ -379,15 +382,14 @@
}
}
} else {
- ssize_t s = mCount-where;
- if (s>0) {
- void* array = editArrayImpl();
- void* to = reinterpret_cast<uint8_t *>(array) + (where+amount)*mItemSize;
+ if (where != mCount) {
+ void* array = editArrayImpl();
const void* from = reinterpret_cast<const uint8_t *>(array) + where*mItemSize;
- _do_move_forward(to, from, s);
+ void* to = reinterpret_cast<uint8_t *>(array) + (where+amount)*mItemSize;
+ _do_move_forward(to, from, mCount - where);
}
}
- mCount += amount;
+ mCount = new_size;
void* free_space = const_cast<void*>(itemLocation(where));
return free_space;
}
@@ -400,14 +402,15 @@
// LOGV("_shrink(this=%p, where=%d, amount=%d) count=%d, capacity=%d",
// this, (int)where, (int)amount, (int)mCount, (int)capacity());
- if (where >= mCount)
- where = mCount - amount;
+ LOG_ASSERT(where + amount <= mCount,
+ "[%p] _shrink: where=%d, amount=%d, count=%d",
+ this, (int)where, (int)amount, (int)mCount); // caller already checked
const size_t new_size = mCount - amount;
if (new_size*3 < capacity()) {
const size_t new_capacity = max(kMinVectorCapacity, new_size*2);
// LOGV("shrink vector %p, new_capacity=%d", this, (int)new_capacity);
- if ((where == mCount-amount) &&
+ if ((where == new_size) &&
(mFlags & HAS_TRIVIAL_COPY) &&
(mFlags & HAS_TRIVIAL_DTOR))
{
@@ -418,31 +421,28 @@
SharedBuffer* sb = SharedBuffer::alloc(new_capacity * mItemSize);
if (sb) {
void* array = sb->data();
- if (where>0) {
+ if (where != 0) {
_do_copy(array, mStorage, where);
}
- if (mCount > where+amount) {
+ if (where != new_size) {
const void* from = reinterpret_cast<const uint8_t *>(mStorage) + (where+amount)*mItemSize;
void* dest = reinterpret_cast<uint8_t *>(array) + where*mItemSize;
- _do_copy(dest, from, mCount-(where+amount));
+ _do_copy(dest, from, new_size - where);
}
release_storage();
mStorage = const_cast<void*>(array);
}
}
} else {
- void* array = editArrayImpl();
+ void* array = editArrayImpl();
void* to = reinterpret_cast<uint8_t *>(array) + where*mItemSize;
_do_destroy(to, amount);
- ssize_t s = mCount-(where+amount);
- if (s>0) {
+ if (where != new_size) {
const void* from = reinterpret_cast<uint8_t *>(array) + (where+amount)*mItemSize;
- _do_move_backward(to, from, s);
+ _do_move_backward(to, from, new_size - where);
}
}
-
- // adjust the number of items...
- mCount -= amount;
+ mCount = new_size;
}
size_t VectorImpl::itemSize() const {
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index b0881a4..680814c 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1551,8 +1551,18 @@
* Dump SurfaceFlinger global state
*/
- snprintf(buffer, SIZE, "SurfaceFlinger global state\n");
+ snprintf(buffer, SIZE, "SurfaceFlinger global state:\n");
result.append(buffer);
+
+ const GLExtensions& extensions(GLExtensions::getInstance());
+ snprintf(buffer, SIZE, "GLES: %s, %s, %s\n",
+ extensions.getVendor(),
+ extensions.getRenderer(),
+ extensions.getVersion());
+ result.append(buffer);
+ snprintf(buffer, SIZE, "EXTS: %s\n", extensions.getExtension());
+ result.append(buffer);
+
mWormholeRegion.dump(result, "WormholeRegion");
const DisplayHardware& hw(graphicPlane(0).displayHardware());
snprintf(buffer, SIZE,