Merge "GUI: Move Surface.aidl here and implement for native" into nyc-dev
diff --git a/cmds/installd/commands.cpp b/cmds/installd/commands.cpp
index 589b9c7..c9de3b9 100644
--- a/cmds/installd/commands.cpp
+++ b/cmds/installd/commands.cpp
@@ -165,7 +165,9 @@
std::string reference_profile_dir = create_data_ref_profile_package_path(pkgname);
std::string reference_profile = create_primary_profile(reference_profile_dir);
if (unlink(reference_profile.c_str()) != 0) {
- PLOG(WARNING) << "Could not unlink " << reference_profile;
+ if (errno != ENOENT) {
+ PLOG(WARNING) << "Could not unlink " << reference_profile;
+ }
}
}
@@ -175,7 +177,9 @@
std::string profile_dir = create_data_user_profile_package_path(user, pkgname);
std::string profile = create_primary_profile(profile_dir);
if (unlink(profile.c_str()) != 0) {
- PLOG(WARNING) << "Could not unlink " << profile;
+ if (errno != ENOENT) {
+ PLOG(WARNING) << "Could not unlink " << profile;
+ }
}
}
}
diff --git a/include/gui/BufferQueueCore.h b/include/gui/BufferQueueCore.h
index 2645d09..acc8c4b 100644
--- a/include/gui/BufferQueueCore.h
+++ b/include/gui/BufferQueueCore.h
@@ -32,7 +32,6 @@
#include <list>
#include <set>
-#include <vector>
#define BQ_LOGV(x, ...) ALOGV("[%s] " x, mConsumerName.string(), ##__VA_ARGS__)
#define BQ_LOGD(x, ...) ALOGD("[%s] " x, mConsumerName.string(), ##__VA_ARGS__)
@@ -68,8 +67,13 @@
// consumer can run asynchronously.
enum { MAX_MAX_ACQUIRED_BUFFERS = BufferQueueDefs::NUM_BUFFER_SLOTS - 2 };
- // The default API number used to indicate that no producer is connected
- enum { NO_CONNECTED_API = 0 };
+ enum {
+ // The API number used to indicate the currently connected producer
+ CURRENTLY_CONNECTED_API = -1,
+
+ // The API number used to indicate that no producer is connected
+ NO_CONNECTED_API = 0,
+ };
typedef Vector<BufferItem> Fifo;
@@ -121,9 +125,8 @@
void freeAllBuffersLocked();
// If delta is positive, makes more slots available. If negative, takes
- // away slots. Returns false if the request can't be met. Any slots that
- // were freed will be appended to freedSlots.
- bool adjustAvailableSlotsLocked(int delta, std::vector<int>* freedSlots);
+ // away slots. Returns false if the request can't be met.
+ bool adjustAvailableSlotsLocked(int delta);
// waitWhileAllocatingLocked blocks until mIsAllocating is false.
void waitWhileAllocatingLocked() const;
diff --git a/include/gui/IProducerListener.h b/include/gui/IProducerListener.h
index 895da4b..3848a6c 100644
--- a/include/gui/IProducerListener.h
+++ b/include/gui/IProducerListener.h
@@ -41,9 +41,6 @@
// This is called without any lock held and can be called concurrently by
// multiple threads.
virtual void onBufferReleased() = 0; // Asynchronous
-
- // onSlotFreed is called when the BufferQueue frees a buffer in a slot.
- virtual void onSlotFreed(int /*slot*/) {}; // Asynchronous
};
class IProducerListener : public ProducerListener, public IInterface
diff --git a/include/gui/SurfaceControl.h b/include/gui/SurfaceControl.h
index 993a92f..76ce68d 100644
--- a/include/gui/SurfaceControl.h
+++ b/include/gui/SurfaceControl.h
@@ -57,6 +57,9 @@
// release surface data from java
void clear();
+ // disconnect any api that's connected
+ void disconnect();
+
status_t setLayerStack(uint32_t layerStack);
status_t setLayer(uint32_t layer);
status_t setPosition(float x, float y);
diff --git a/libs/gui/BufferQueueConsumer.cpp b/libs/gui/BufferQueueConsumer.cpp
index aacbed5..4029496 100644
--- a/libs/gui/BufferQueueConsumer.cpp
+++ b/libs/gui/BufferQueueConsumer.cpp
@@ -277,51 +277,35 @@
ATRACE_CALL();
ATRACE_BUFFER_INDEX(slot);
BQ_LOGV("detachBuffer: slot %d", slot);
+ Mutex::Autolock lock(mCore->mMutex);
- sp<IConsumerListener> consumerListener;
- sp<IProducerListener> producerListener;
- {
- Mutex::Autolock lock(mCore->mMutex);
-
- if (mCore->mIsAbandoned) {
- BQ_LOGE("detachBuffer: BufferQueue has been abandoned");
- return NO_INIT;
- }
-
- if (mCore->mSingleBufferMode || slot == mCore->mSingleBufferSlot) {
- BQ_LOGE("detachBuffer: detachBuffer not allowed in single buffer"
- "mode");
- return BAD_VALUE;
- }
-
- if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) {
- BQ_LOGE("detachBuffer: slot index %d out of range [0, %d)",
- slot, BufferQueueDefs::NUM_BUFFER_SLOTS);
- return BAD_VALUE;
- } else if (!mSlots[slot].mBufferState.isAcquired()) {
- BQ_LOGE("detachBuffer: slot %d is not owned by the consumer "
- "(state = %s)", slot, mSlots[slot].mBufferState.string());
- return BAD_VALUE;
- }
-
- mSlots[slot].mBufferState.detachConsumer();
- mCore->mActiveBuffers.erase(slot);
- mCore->mFreeSlots.insert(slot);
- mCore->clearBufferSlotLocked(slot);
- mCore->mDequeueCondition.broadcast();
- VALIDATE_CONSISTENCY();
- producerListener = mCore->mConnectedProducerListener;
- consumerListener = mCore->mConsumerListener;
+ if (mCore->mIsAbandoned) {
+ BQ_LOGE("detachBuffer: BufferQueue has been abandoned");
+ return NO_INIT;
}
- // Call back without lock held
- if (producerListener != NULL) {
- producerListener->onSlotFreed(slot);
- }
- if (consumerListener != NULL) {
- consumerListener->onBuffersReleased();
+ if (mCore->mSingleBufferMode || slot == mCore->mSingleBufferSlot) {
+ BQ_LOGE("detachBuffer: detachBuffer not allowed in single buffer"
+ "mode");
+ return BAD_VALUE;
}
+ if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) {
+ BQ_LOGE("detachBuffer: slot index %d out of range [0, %d)",
+ slot, BufferQueueDefs::NUM_BUFFER_SLOTS);
+ return BAD_VALUE;
+ } else if (!mSlots[slot].mBufferState.isAcquired()) {
+ BQ_LOGE("detachBuffer: slot %d is not owned by the consumer "
+ "(state = %s)", slot, mSlots[slot].mBufferState.string());
+ return BAD_VALUE;
+ }
+
+ mSlots[slot].mBufferState.detachConsumer();
+ mCore->mActiveBuffers.erase(slot);
+ mCore->mFreeSlots.insert(slot);
+ mCore->clearBufferSlotLocked(slot);
+ mCore->mDequeueCondition.broadcast();
+ VALIDATE_CONSISTENCY();
return NO_ERROR;
}
@@ -592,40 +576,30 @@
return BAD_VALUE;
}
- sp<IConsumerListener> listener;
- {
- Mutex::Autolock lock(mCore->mMutex);
- if (mCore->mConnectedApi != BufferQueueCore::NO_CONNECTED_API) {
- BQ_LOGE("setMaxBufferCount: producer is already connected");
- return INVALID_OPERATION;
- }
+ Mutex::Autolock lock(mCore->mMutex);
- if (bufferCount < mCore->mMaxAcquiredBufferCount) {
- BQ_LOGE("setMaxBufferCount: invalid buffer count (%d) less than"
- "mMaxAcquiredBufferCount (%d)", bufferCount,
- mCore->mMaxAcquiredBufferCount);
- return BAD_VALUE;
- }
-
- int delta = mCore->getMaxBufferCountLocked(mCore->mAsyncMode,
- mCore->mDequeueBufferCannotBlock, bufferCount) -
- mCore->getMaxBufferCountLocked();
- if (!mCore->adjustAvailableSlotsLocked(delta, nullptr)) {
- BQ_LOGE("setMaxBufferCount: BufferQueue failed to adjust the number"
- " of available slots. Delta = %d", delta);
- return BAD_VALUE;
- }
-
- mCore->mMaxBufferCount = bufferCount;
- if (delta < 0) {
- listener = mCore->mConsumerListener;
- }
+ if (mCore->mConnectedApi != BufferQueueCore::NO_CONNECTED_API) {
+ BQ_LOGE("setMaxBufferCount: producer is already connected");
+ return INVALID_OPERATION;
}
- // Call back without lock held
- if (listener != NULL) {
- listener->onBuffersReleased();
+ if (bufferCount < mCore->mMaxAcquiredBufferCount) {
+ BQ_LOGE("setMaxBufferCount: invalid buffer count (%d) less than"
+ "mMaxAcquiredBufferCount (%d)", bufferCount,
+ mCore->mMaxAcquiredBufferCount);
+ return BAD_VALUE;
}
+
+ int delta = mCore->getMaxBufferCountLocked(mCore->mAsyncMode,
+ mCore->mDequeueBufferCannotBlock, bufferCount) -
+ mCore->getMaxBufferCountLocked();
+ if (!mCore->adjustAvailableSlotsLocked(delta)) {
+ BQ_LOGE("setMaxBufferCount: BufferQueue failed to adjust the number of "
+ "available slots. Delta = %d", delta);
+ return BAD_VALUE;
+ }
+
+ mCore->mMaxBufferCount = bufferCount;
return NO_ERROR;
}
@@ -640,9 +614,7 @@
return BAD_VALUE;
}
- sp<IConsumerListener> consumerListener;
- sp<IProducerListener> producerListener;
- std::vector<int> freedSlots;
+ sp<IConsumerListener> listener;
{ // Autolock scope
Mutex::Autolock lock(mCore->mMutex);
mCore->waitWhileAllocatingLocked();
@@ -679,7 +651,7 @@
}
int delta = maxAcquiredBuffers - mCore->mMaxAcquiredBufferCount;
- if (!mCore->adjustAvailableSlotsLocked(delta, &freedSlots)) {
+ if (!mCore->adjustAvailableSlotsLocked(delta)) {
return BAD_VALUE;
}
@@ -687,19 +659,12 @@
mCore->mMaxAcquiredBufferCount = maxAcquiredBuffers;
VALIDATE_CONSISTENCY();
if (delta < 0) {
- consumerListener = mCore->mConsumerListener;
- producerListener = mCore->mConnectedProducerListener;
+ listener = mCore->mConsumerListener;
}
}
-
// Call back without lock held
- if (consumerListener != NULL) {
- consumerListener->onBuffersReleased();
- }
- if (producerListener != NULL) {
- for (int i : freedSlots) {
- producerListener->onSlotFreed(i);
- }
+ if (listener != NULL) {
+ listener->onBuffersReleased();
}
return NO_ERROR;
diff --git a/libs/gui/BufferQueueCore.cpp b/libs/gui/BufferQueueCore.cpp
index fc3ffed..ba07362 100644
--- a/libs/gui/BufferQueueCore.cpp
+++ b/libs/gui/BufferQueueCore.cpp
@@ -226,8 +226,7 @@
VALIDATE_CONSISTENCY();
}
-bool BufferQueueCore::adjustAvailableSlotsLocked(int delta,
- std::vector<int>* freedSlots) {
+bool BufferQueueCore::adjustAvailableSlotsLocked(int delta) {
if (delta >= 0) {
// If we're going to fail, do so before modifying anything
if (delta > static_cast<int>(mUnusedSlots.size())) {
@@ -254,17 +253,11 @@
clearBufferSlotLocked(*slot);
mUnusedSlots.push_back(*slot);
mFreeSlots.erase(slot);
- if (freedSlots) {
- freedSlots->push_back(*slot);
- }
} else if (!mFreeBuffers.empty()) {
int slot = mFreeBuffers.back();
clearBufferSlotLocked(slot);
mUnusedSlots.push_back(slot);
mFreeBuffers.pop_back();
- if (freedSlots) {
- freedSlots->push_back(slot);
- }
} else {
return false;
}
diff --git a/libs/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp
index cb5d773..818fac6 100644
--- a/libs/gui/BufferQueueProducer.cpp
+++ b/libs/gui/BufferQueueProducer.cpp
@@ -90,9 +90,7 @@
BQ_LOGV("setMaxDequeuedBufferCount: maxDequeuedBuffers = %d",
maxDequeuedBuffers);
- sp<IConsumerListener> consumerListener;
- sp<IProducerListener> producerListener;
- std::vector<int> freedSlots;
+ sp<IConsumerListener> listener;
{ // Autolock scope
Mutex::Autolock lock(mCore->mMutex);
mCore->waitWhileAllocatingLocked();
@@ -144,26 +142,20 @@
}
int delta = maxDequeuedBuffers - mCore->mMaxDequeuedBufferCount;
- if (!mCore->adjustAvailableSlotsLocked(delta, &freedSlots)) {
+ if (!mCore->adjustAvailableSlotsLocked(delta)) {
return BAD_VALUE;
}
mCore->mMaxDequeuedBufferCount = maxDequeuedBuffers;
VALIDATE_CONSISTENCY();
if (delta < 0) {
- consumerListener = mCore->mConsumerListener;
- producerListener = mCore->mConnectedProducerListener;
+ listener = mCore->mConsumerListener;
}
mCore->mDequeueCondition.broadcast();
} // Autolock scope
// Call back without lock held
- if (consumerListener != NULL) {
- consumerListener->onBuffersReleased();
- }
- if (producerListener != NULL) {
- for (int i : freedSlots) {
- producerListener->onSlotFreed(i);
- }
+ if (listener != NULL) {
+ listener->onBuffersReleased();
}
return NO_ERROR;
@@ -173,9 +165,7 @@
ATRACE_CALL();
BQ_LOGV("setAsyncMode: async = %d", async);
- sp<IConsumerListener> consumerListener;
- sp<IProducerListener> producerListener;
- std::vector<int> freedSlots;
+ sp<IConsumerListener> listener;
{ // Autolock scope
Mutex::Autolock lock(mCore->mMutex);
mCore->waitWhileAllocatingLocked();
@@ -201,7 +191,7 @@
mCore->mDequeueBufferCannotBlock, mCore->mMaxBufferCount)
- mCore->getMaxBufferCountLocked();
- if (!mCore->adjustAvailableSlotsLocked(delta, &freedSlots)) {
+ if (!mCore->adjustAvailableSlotsLocked(delta)) {
BQ_LOGE("setAsyncMode: BufferQueue failed to adjust the number of "
"available slots. Delta = %d", delta);
return BAD_VALUE;
@@ -209,20 +199,12 @@
mCore->mAsyncMode = async;
VALIDATE_CONSISTENCY();
mCore->mDequeueCondition.broadcast();
- if (delta < 0) {
- consumerListener = mCore->mConsumerListener;
- producerListener = mCore->mConnectedProducerListener;
- }
+ listener = mCore->mConsumerListener;
} // Autolock scope
// Call back without lock held
- if (consumerListener != NULL) {
- consumerListener->onBuffersReleased();
- }
- if (producerListener != NULL) {
- for (int i : freedSlots) {
- producerListener->onSlotFreed(i);
- }
+ if (listener != NULL) {
+ listener->onBuffersReleased();
}
return NO_ERROR;
}
@@ -379,9 +361,6 @@
EGLSyncKHR eglFence = EGL_NO_SYNC_KHR;
bool attachedByConsumer = false;
- sp<IConsumerListener> consumerListener;
- sp<IProducerListener> producerListener;
- int found = BufferItem::INVALID_BUFFER_SLOT;
{ // Autolock scope
Mutex::Autolock lock(mCore->mMutex);
mCore->waitWhileAllocatingLocked();
@@ -399,6 +378,7 @@
height = mCore->mDefaultHeight;
}
+ int found = BufferItem::INVALID_BUFFER_SLOT;
while (found == BufferItem::INVALID_BUFFER_SLOT) {
status_t status = waitForFreeSlotThenRelock(FreeSlotCaller::Dequeue,
&found);
@@ -428,8 +408,6 @@
mCore->mFreeSlots.insert(found);
mCore->clearBufferSlotLocked(found);
found = BufferItem::INVALID_BUFFER_SLOT;
- consumerListener = mCore->mConsumerListener;
- producerListener = mCore->mConnectedProducerListener;
continue;
}
}
@@ -466,10 +444,6 @@
if ((buffer == NULL) ||
buffer->needsReallocation(width, height, format, usage))
{
- if (buffer != NULL) {
- consumerListener = mCore->mConsumerListener;
- producerListener = mCore->mConnectedProducerListener;
- }
mSlots[found].mAcquireCalled = false;
mSlots[found].mGraphicBuffer = NULL;
mSlots[found].mRequestBufferCalled = false;
@@ -557,14 +531,6 @@
mSlots[*outSlot].mFrameNumber,
mSlots[*outSlot].mGraphicBuffer->handle, returnFlags);
- // Call back without lock held
- if (consumerListener != NULL) {
- consumerListener->onBuffersReleased();
- }
- if (producerListener != NULL) {
- producerListener->onSlotFreed(found);
- }
-
return returnFlags;
}
@@ -572,60 +538,44 @@
ATRACE_CALL();
ATRACE_BUFFER_INDEX(slot);
BQ_LOGV("detachBuffer: slot %d", slot);
+ Mutex::Autolock lock(mCore->mMutex);
- sp<IConsumerListener> consumerListener;
- sp<IProducerListener> producerListener;
- {
- Mutex::Autolock lock(mCore->mMutex);
-
- if (mCore->mIsAbandoned) {
- BQ_LOGE("detachBuffer: BufferQueue has been abandoned");
- return NO_INIT;
- }
-
- if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) {
- BQ_LOGE("detachBuffer: BufferQueue has no connected producer");
- return NO_INIT;
- }
-
- if (mCore->mSingleBufferMode || mCore->mSingleBufferSlot == slot) {
- BQ_LOGE("detachBuffer: cannot detach a buffer in single buffer "
- "mode");
- return BAD_VALUE;
- }
-
- if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) {
- BQ_LOGE("detachBuffer: slot index %d out of range [0, %d)",
- slot, BufferQueueDefs::NUM_BUFFER_SLOTS);
- return BAD_VALUE;
- } else if (!mSlots[slot].mBufferState.isDequeued()) {
- BQ_LOGE("detachBuffer: slot %d is not owned by the producer "
- "(state = %s)", slot, mSlots[slot].mBufferState.string());
- return BAD_VALUE;
- } else if (!mSlots[slot].mRequestBufferCalled) {
- BQ_LOGE("detachBuffer: buffer in slot %d has not been requested",
- slot);
- return BAD_VALUE;
- }
-
- mSlots[slot].mBufferState.detachProducer();
- mCore->mActiveBuffers.erase(slot);
- mCore->mFreeSlots.insert(slot);
- mCore->clearBufferSlotLocked(slot);
- mCore->mDequeueCondition.broadcast();
- VALIDATE_CONSISTENCY();
- producerListener = mCore->mConnectedProducerListener;
- consumerListener = mCore->mConsumerListener;
+ if (mCore->mIsAbandoned) {
+ BQ_LOGE("detachBuffer: BufferQueue has been abandoned");
+ return NO_INIT;
}
- // Call back without lock held
- if (consumerListener != NULL) {
- consumerListener->onBuffersReleased();
+ if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) {
+ BQ_LOGE("detachBuffer: BufferQueue has no connected producer");
+ return NO_INIT;
}
- if (producerListener != NULL) {
- producerListener->onSlotFreed(slot);
+
+ if (mCore->mSingleBufferMode || mCore->mSingleBufferSlot == slot) {
+ BQ_LOGE("detachBuffer: cannot detach a buffer in single buffer mode");
+ return BAD_VALUE;
}
+ if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) {
+ BQ_LOGE("detachBuffer: slot index %d out of range [0, %d)",
+ slot, BufferQueueDefs::NUM_BUFFER_SLOTS);
+ return BAD_VALUE;
+ } else if (!mSlots[slot].mBufferState.isDequeued()) {
+ BQ_LOGE("detachBuffer: slot %d is not owned by the producer "
+ "(state = %s)", slot, mSlots[slot].mBufferState.string());
+ return BAD_VALUE;
+ } else if (!mSlots[slot].mRequestBufferCalled) {
+ BQ_LOGE("detachBuffer: buffer in slot %d has not been requested",
+ slot);
+ return BAD_VALUE;
+ }
+
+ mSlots[slot].mBufferState.detachProducer();
+ mCore->mActiveBuffers.erase(slot);
+ mCore->mFreeSlots.insert(slot);
+ mCore->clearBufferSlotLocked(slot);
+ mCore->mDequeueCondition.broadcast();
+ VALIDATE_CONSISTENCY();
+
return NO_ERROR;
}
@@ -641,55 +591,41 @@
return BAD_VALUE;
}
- sp<IConsumerListener> consumerListener;
- sp<IProducerListener> producerListener;
- int found = BufferQueueCore::INVALID_BUFFER_SLOT;
- {
- Mutex::Autolock lock(mCore->mMutex);
- if (mCore->mIsAbandoned) {
- BQ_LOGE("detachNextBuffer: BufferQueue has been abandoned");
- return NO_INIT;
- }
+ Mutex::Autolock lock(mCore->mMutex);
- if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) {
- BQ_LOGE("detachNextBuffer: BufferQueue has no connected producer");
- return NO_INIT;
- }
-
- if (mCore->mSingleBufferMode) {
- BQ_LOGE("detachNextBuffer: cannot detach a buffer in single buffer"
- "mode");
- return BAD_VALUE;
- }
-
- mCore->waitWhileAllocatingLocked();
-
- if (mCore->mFreeBuffers.empty()) {
- return NO_MEMORY;
- }
-
- found = mCore->mFreeBuffers.front();
- mCore->mFreeBuffers.remove(found);
- mCore->mFreeSlots.insert(found);
-
- BQ_LOGV("detachNextBuffer detached slot %d", found);
-
- *outBuffer = mSlots[found].mGraphicBuffer;
- *outFence = mSlots[found].mFence;
- mCore->clearBufferSlotLocked(found);
- VALIDATE_CONSISTENCY();
- consumerListener = mCore->mConsumerListener;
- producerListener = mCore->mConnectedProducerListener;
+ if (mCore->mIsAbandoned) {
+ BQ_LOGE("detachNextBuffer: BufferQueue has been abandoned");
+ return NO_INIT;
}
- // Call back without lock held
- if (consumerListener != NULL) {
- consumerListener->onBuffersReleased();
+ if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) {
+ BQ_LOGE("detachNextBuffer: BufferQueue has no connected producer");
+ return NO_INIT;
}
- if (producerListener != NULL) {
- producerListener->onSlotFreed(found);
+
+ if (mCore->mSingleBufferMode) {
+ BQ_LOGE("detachNextBuffer: cannot detach a buffer in single buffer"
+ "mode");
+ return BAD_VALUE;
}
+ mCore->waitWhileAllocatingLocked();
+
+ if (mCore->mFreeBuffers.empty()) {
+ return NO_MEMORY;
+ }
+
+ int found = mCore->mFreeBuffers.front();
+ mCore->mFreeBuffers.remove(found);
+ mCore->mFreeSlots.insert(found);
+
+ BQ_LOGV("detachNextBuffer detached slot %d", found);
+
+ *outBuffer = mSlots[found].mGraphicBuffer;
+ *outFence = mSlots[found].mFence;
+ mCore->clearBufferSlotLocked(found);
+ VALIDATE_CONSISTENCY();
+
return NO_ERROR;
}
@@ -1084,102 +1020,82 @@
status_t BufferQueueProducer::connect(const sp<IProducerListener>& listener,
int api, bool producerControlledByApp, QueueBufferOutput *output) {
ATRACE_CALL();
+ Mutex::Autolock lock(mCore->mMutex);
+ mConsumerName = mCore->mConsumerName;
+ BQ_LOGV("connect: api=%d producerControlledByApp=%s", api,
+ producerControlledByApp ? "true" : "false");
+
+ if (mCore->mIsAbandoned) {
+ BQ_LOGE("connect: BufferQueue has been abandoned");
+ return NO_INIT;
+ }
+
+ if (mCore->mConsumerListener == NULL) {
+ BQ_LOGE("connect: BufferQueue has no consumer");
+ return NO_INIT;
+ }
+
+ if (output == NULL) {
+ BQ_LOGE("connect: output was NULL");
+ return BAD_VALUE;
+ }
+
+ if (mCore->mConnectedApi != BufferQueueCore::NO_CONNECTED_API) {
+ BQ_LOGE("connect: already connected (cur=%d req=%d)",
+ mCore->mConnectedApi, api);
+ return BAD_VALUE;
+ }
+
+ int delta = mCore->getMaxBufferCountLocked(mCore->mAsyncMode,
+ mDequeueTimeout < 0 ?
+ mCore->mConsumerControlledByApp && producerControlledByApp : false,
+ mCore->mMaxBufferCount) -
+ mCore->getMaxBufferCountLocked();
+ if (!mCore->adjustAvailableSlotsLocked(delta)) {
+ BQ_LOGE("connect: BufferQueue failed to adjust the number of available "
+ "slots. Delta = %d", delta);
+ return BAD_VALUE;
+ }
+
int status = NO_ERROR;
- sp<IConsumerListener> consumerListener;
- sp<IProducerListener> producerListener;
- std::vector<int> freedSlots;
- {
- Mutex::Autolock lock(mCore->mMutex);
- mConsumerName = mCore->mConsumerName;
- BQ_LOGV("connect: api=%d producerControlledByApp=%s", api,
- producerControlledByApp ? "true" : "false");
+ switch (api) {
+ case NATIVE_WINDOW_API_EGL:
+ case NATIVE_WINDOW_API_CPU:
+ case NATIVE_WINDOW_API_MEDIA:
+ case NATIVE_WINDOW_API_CAMERA:
+ mCore->mConnectedApi = api;
+ output->inflate(mCore->mDefaultWidth, mCore->mDefaultHeight,
+ mCore->mTransformHint,
+ static_cast<uint32_t>(mCore->mQueue.size()));
- if (mCore->mIsAbandoned) {
- BQ_LOGE("connect: BufferQueue has been abandoned");
- return NO_INIT;
- }
-
- if (mCore->mConsumerListener == NULL) {
- BQ_LOGE("connect: BufferQueue has no consumer");
- return NO_INIT;
- }
-
- if (output == NULL) {
- BQ_LOGE("connect: output was NULL");
- return BAD_VALUE;
- }
-
- if (mCore->mConnectedApi != BufferQueueCore::NO_CONNECTED_API) {
- BQ_LOGE("connect: already connected (cur=%d req=%d)",
- mCore->mConnectedApi, api);
- return BAD_VALUE;
- }
-
- bool dequeueBufferCannotBlock = mDequeueTimeout < 0 ?
- mCore->mConsumerControlledByApp && producerControlledByApp :
- false;
- int delta = mCore->getMaxBufferCountLocked(mCore->mAsyncMode,
- dequeueBufferCannotBlock, mCore->mMaxBufferCount) -
- mCore->getMaxBufferCountLocked();
-
- if (!mCore->adjustAvailableSlotsLocked(delta, &freedSlots)) {
- BQ_LOGE("connect: BufferQueue failed to adjust the number of "
- "available slots. Delta = %d", delta);
- return BAD_VALUE;
- }
-
- switch (api) {
- case NATIVE_WINDOW_API_EGL:
- case NATIVE_WINDOW_API_CPU:
- case NATIVE_WINDOW_API_MEDIA:
- case NATIVE_WINDOW_API_CAMERA:
- mCore->mConnectedApi = api;
- output->inflate(mCore->mDefaultWidth, mCore->mDefaultHeight,
- mCore->mTransformHint,
- static_cast<uint32_t>(mCore->mQueue.size()));
-
- // Set up a death notification so that we can disconnect
- // automatically if the remote producer dies
- if (listener != NULL &&
- IInterface::asBinder(listener)->remoteBinder() !=
- NULL) {
- status = IInterface::asBinder(listener)->linkToDeath(
- static_cast<IBinder::DeathRecipient*>(this));
- if (status != NO_ERROR) {
- BQ_LOGE("connect: linkToDeath failed: %s (%d)",
- strerror(-status), status);
- }
+ // Set up a death notification so that we can disconnect
+ // automatically if the remote producer dies
+ if (listener != NULL &&
+ IInterface::asBinder(listener)->remoteBinder() != NULL) {
+ status = IInterface::asBinder(listener)->linkToDeath(
+ static_cast<IBinder::DeathRecipient*>(this));
+ if (status != NO_ERROR) {
+ BQ_LOGE("connect: linkToDeath failed: %s (%d)",
+ strerror(-status), status);
}
- mCore->mConnectedProducerListener = listener;
- break;
- default:
- BQ_LOGE("connect: unknown API %d", api);
- status = BAD_VALUE;
- break;
- }
-
- mCore->mBufferHasBeenQueued = false;
- mCore->mDequeueBufferCannotBlock = dequeueBufferCannotBlock;
-
- mCore->mAllowAllocation = true;
- VALIDATE_CONSISTENCY();
-
- if (delta < 0) {
- consumerListener = mCore->mConsumerListener;
- producerListener = listener;
- }
+ }
+ mCore->mConnectedProducerListener = listener;
+ break;
+ default:
+ BQ_LOGE("connect: unknown API %d", api);
+ status = BAD_VALUE;
+ break;
}
- // Call back without lock held
- if (consumerListener != NULL) {
- consumerListener->onBuffersReleased();
- }
- if (producerListener != NULL) {
- for (int i : freedSlots) {
- producerListener->onSlotFreed(i);
- }
+ mCore->mBufferHasBeenQueued = false;
+ mCore->mDequeueBufferCannotBlock = false;
+ if (mDequeueTimeout < 0) {
+ mCore->mDequeueBufferCannotBlock =
+ mCore->mConsumerControlledByApp && producerControlledByApp;
}
+ mCore->mAllowAllocation = true;
+ VALIDATE_CONSISTENCY();
return status;
}
@@ -1199,6 +1115,10 @@
return NO_ERROR;
}
+ if (api == BufferQueueCore::CURRENTLY_CONNECTED_API) {
+ api = mCore->mConnectedApi;
+ }
+
switch (api) {
case NATIVE_WINDOW_API_EGL:
case NATIVE_WINDOW_API_CPU:
@@ -1407,40 +1327,19 @@
ATRACE_CALL();
BQ_LOGV("setDequeueTimeout: %" PRId64, timeout);
- sp<IConsumerListener> consumerListener;
- sp<IProducerListener> producerListener;
- std::vector<int> freedSlots;
- {
- Mutex::Autolock lock(mCore->mMutex);
- int delta = mCore->getMaxBufferCountLocked(mCore->mAsyncMode, false,
- mCore->mMaxBufferCount) - mCore->getMaxBufferCountLocked();
- if (!mCore->adjustAvailableSlotsLocked(delta, &freedSlots)) {
- BQ_LOGE("setDequeueTimeout: BufferQueue failed to adjust the number"
- " of available slots. Delta = %d", delta);
- return BAD_VALUE;
- }
-
- mDequeueTimeout = timeout;
- mCore->mDequeueBufferCannotBlock = false;
-
- VALIDATE_CONSISTENCY();
-
- if (delta < 0) {
- consumerListener = mCore->mConsumerListener;
- producerListener = mCore->mConnectedProducerListener;
- }
+ Mutex::Autolock lock(mCore->mMutex);
+ int delta = mCore->getMaxBufferCountLocked(mCore->mAsyncMode, false,
+ mCore->mMaxBufferCount) - mCore->getMaxBufferCountLocked();
+ if (!mCore->adjustAvailableSlotsLocked(delta)) {
+ BQ_LOGE("setDequeueTimeout: BufferQueue failed to adjust the number of "
+ "available slots. Delta = %d", delta);
+ return BAD_VALUE;
}
- // Call back without lock held
- if (consumerListener != NULL) {
- consumerListener->onBuffersReleased();
- }
- if (producerListener != NULL) {
- for (int i : freedSlots) {
- producerListener->onSlotFreed(i);
- }
- }
+ mDequeueTimeout = timeout;
+ mCore->mDequeueBufferCannotBlock = false;
+ VALIDATE_CONSISTENCY();
return NO_ERROR;
}
diff --git a/libs/gui/IProducerListener.cpp b/libs/gui/IProducerListener.cpp
index 39c1da8..81adc95 100644
--- a/libs/gui/IProducerListener.cpp
+++ b/libs/gui/IProducerListener.cpp
@@ -22,7 +22,6 @@
enum {
ON_BUFFER_RELEASED = IBinder::FIRST_CALL_TRANSACTION,
- ON_SLOT_FREED,
};
class BpProducerListener : public BpInterface<IProducerListener>
@@ -38,17 +37,6 @@
data.writeInterfaceToken(IProducerListener::getInterfaceDescriptor());
remote()->transact(ON_BUFFER_RELEASED, data, &reply, IBinder::FLAG_ONEWAY);
}
-
- virtual void onSlotFreed(int slot) {
- Parcel data, reply;
- data.writeInterfaceToken(IProducerListener::getInterfaceDescriptor());
- data.writeInt32(slot);
- status_t err = remote()->transact(ON_SLOT_FREED, data, &reply,
- IBinder::FLAG_ONEWAY);
- if (err != NO_ERROR) {
- ALOGE("onSlotFreed failed to transact %d", err);
- }
- }
};
// Out-of-line virtual method definition to trigger vtable emission in this
@@ -64,12 +52,6 @@
CHECK_INTERFACE(IProducerListener, data, reply);
onBufferReleased();
return NO_ERROR;
- case ON_SLOT_FREED: {
- CHECK_INTERFACE(IProducerListener, data, reply);
- int slot = data.readInt32();
- onSlotFreed(slot);
- return NO_ERROR;
- }
}
return BBinder::onTransact(code, data, reply, flags);
}
diff --git a/libs/gui/SurfaceControl.cpp b/libs/gui/SurfaceControl.cpp
index a945358..e1a951c 100644
--- a/libs/gui/SurfaceControl.cpp
+++ b/libs/gui/SurfaceControl.cpp
@@ -33,6 +33,7 @@
#include <ui/GraphicBuffer.h>
#include <ui/Rect.h>
+#include <gui/BufferQueueCore.h>
#include <gui/ISurfaceComposer.h>
#include <gui/Surface.h>
#include <gui/SurfaceComposerClient.h>
@@ -81,6 +82,13 @@
destroy();
}
+void SurfaceControl::disconnect() {
+ if (mGraphicBufferProducer != NULL) {
+ mGraphicBufferProducer->disconnect(
+ BufferQueueCore::CURRENTLY_CONNECTED_API);
+ }
+}
+
bool SurfaceControl::isSameSurface(
const sp<SurfaceControl>& lhs, const sp<SurfaceControl>& rhs)
{
diff --git a/libs/gui/tests/IGraphicBufferProducer_test.cpp b/libs/gui/tests/IGraphicBufferProducer_test.cpp
index fad0baa..45b6463 100644
--- a/libs/gui/tests/IGraphicBufferProducer_test.cpp
+++ b/libs/gui/tests/IGraphicBufferProducer_test.cpp
@@ -727,55 +727,4 @@
ASSERT_EQ(NO_INIT, mProducer->attachBuffer(&slot, buffer));
}
-struct TestListener : public BnProducerListener {
- virtual void onBufferReleased() {}
- virtual void onSlotFreed(int slot) {
- ASSERT_EQ(1, slot);
- }
-};
-
-TEST_F(IGraphicBufferProducerTest, SlotFreedListenerReturnsCorrectSlot) {
- const ::testing::TestInfo* const testInfo =
- ::testing::UnitTest::GetInstance()->current_test_info();
- ALOGV("Begin test: %s.%s", testInfo->test_case_name(),
- testInfo->name());
-
- BufferQueue::createBufferQueue(&mProducer, &mConsumer);
-
- sp<DummyConsumer> consumerListener = new DummyConsumer;
- ASSERT_OK(mConsumer->consumerConnect(consumerListener, false));
-
- sp<TestListener> producerListener = new TestListener;
- IGraphicBufferProducer::QueueBufferOutput output;
- ASSERT_OK(mProducer->connect(producerListener, TEST_API,
- TEST_CONTROLLED_BY_APP, &output));
-
- ASSERT_OK(mProducer->setMaxDequeuedBufferCount(2));
-
- DequeueBufferResult buffer0;
- sp<GraphicBuffer> buf;
- ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
- dequeueBuffer(DEFAULT_WIDTH, DEFAULT_HEIGHT, DEFAULT_FORMAT,
- TEST_PRODUCER_USAGE_BITS, &buffer0));
- ASSERT_OK(mProducer->requestBuffer(buffer0.slot, &buf));
-
- DequeueBufferResult buffer1;
- ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
- dequeueBuffer(DEFAULT_WIDTH, DEFAULT_HEIGHT, DEFAULT_FORMAT,
- TEST_PRODUCER_USAGE_BITS, &buffer1));
-
- IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput();
- ASSERT_OK(mProducer->queueBuffer(buffer0.slot, input, &output));
-
- DequeueBufferResult buffer2;
- ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
- dequeueBuffer(DEFAULT_WIDTH, DEFAULT_HEIGHT, DEFAULT_FORMAT,
- TEST_PRODUCER_USAGE_BITS, &buffer2));
-
- ASSERT_OK(mProducer->cancelBuffer(buffer1.slot, Fence::NO_FENCE));
-
- ASSERT_OK(mProducer->setMaxDequeuedBufferCount(1));
-}
-
-
} // namespace android