diff options
| author | 2014-04-11 17:57:11 +0000 | |
|---|---|---|
| committer | 2014-04-11 17:57:12 +0000 | |
| commit | fd34b65f717b84fa06d8c37f41b070f41d0ad3a3 (patch) | |
| tree | 80315086e606f5184add4bab55c28e7687ccc931 /libs | |
| parent | 88a34b2f4351fe58b042f11af08ffd967ef7ce4c (diff) | |
| parent | f0eaf25e9247edf4d124bedaeb863f7abdf35a3e (diff) | |
Merge "BufferQueue: Add producer buffer-released callback"
Diffstat (limited to 'libs')
| -rw-r--r-- | libs/gui/Android.mk | 1 | ||||
| -rw-r--r-- | libs/gui/BufferQueue.cpp | 4 | ||||
| -rw-r--r-- | libs/gui/BufferQueueCore.cpp | 3 | ||||
| -rw-r--r-- | libs/gui/BufferQueueProducer.cpp | 20 | ||||
| -rw-r--r-- | libs/gui/IGraphicBufferProducer.cpp | 17 | ||||
| -rw-r--r-- | libs/gui/IProducerListener.cpp | 53 | ||||
| -rw-r--r-- | libs/gui/Surface.cpp | 5 | ||||
| -rw-r--r-- | libs/gui/tests/BufferQueue_test.cpp | 27 | ||||
| -rw-r--r-- | libs/gui/tests/IGraphicBufferProducer_test.cpp | 3 |
9 files changed, 102 insertions, 31 deletions
diff --git a/libs/gui/Android.mk b/libs/gui/Android.mk index 0a77317ea0..04a8a8d506 100644 --- a/libs/gui/Android.mk +++ b/libs/gui/Android.mk @@ -21,6 +21,7 @@ LOCAL_SRC_FILES:= \ IDisplayEventConnection.cpp \ IGraphicBufferAlloc.cpp \ IGraphicBufferProducer.cpp \ + IProducerListener.cpp \ ISensorEventConnection.cpp \ ISensorServer.cpp \ ISurfaceComposer.cpp \ diff --git a/libs/gui/BufferQueue.cpp b/libs/gui/BufferQueue.cpp index 782afcc9c8..d04b67d630 100644 --- a/libs/gui/BufferQueue.cpp +++ b/libs/gui/BufferQueue.cpp @@ -117,9 +117,9 @@ void BufferQueue::cancelBuffer(int buf, const sp<Fence>& fence) { mProducer->cancelBuffer(buf, fence); } -status_t BufferQueue::connect(const sp<IBinder>& token, +status_t BufferQueue::connect(const sp<IProducerListener>& listener, int api, bool producerControlledByApp, QueueBufferOutput* output) { - return mProducer->connect(token, api, producerControlledByApp, output); + return mProducer->connect(listener, api, producerControlledByApp, output); } status_t BufferQueue::disconnect(int api) { diff --git a/libs/gui/BufferQueueCore.cpp b/libs/gui/BufferQueueCore.cpp index 40a6cbb04d..71ba4e72de 100644 --- a/libs/gui/BufferQueueCore.cpp +++ b/libs/gui/BufferQueueCore.cpp @@ -26,6 +26,7 @@ #include <gui/BufferQueueCore.h> #include <gui/IConsumerListener.h> #include <gui/IGraphicBufferAlloc.h> +#include <gui/IProducerListener.h> #include <gui/ISurfaceComposer.h> #include <private/gui/ComposerService.h> @@ -49,7 +50,7 @@ BufferQueueCore::BufferQueueCore(const sp<IGraphicBufferAlloc>& allocator) : mConsumerListener(), mConsumerUsageBits(0), mConnectedApi(NO_CONNECTED_API), - mConnectedProducerToken(), + mConnectedProducerListener(), mSlots(), mQueue(), mOverrideMaxBufferCount(0), diff --git a/libs/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp index 249b7c7f55..ea37309fdb 100644 --- a/libs/gui/BufferQueueProducer.cpp +++ b/libs/gui/BufferQueueProducer.cpp @@ -25,6 +25,7 @@ #include <gui/BufferQueueProducer.h> #include <gui/IConsumerListener.h> #include <gui/IGraphicBufferAlloc.h> +#include <gui/IProducerListener.h> #include <utils/Log.h> #include <utils/Trace.h> @@ -654,7 +655,7 @@ int BufferQueueProducer::query(int what, int *outValue) { return NO_ERROR; } -status_t BufferQueueProducer::connect(const sp<android::IBinder> &token, +status_t BufferQueueProducer::connect(const sp<IProducerListener>& listener, int api, bool producerControlledByApp, QueueBufferOutput *output) { ATRACE_CALL(); Mutex::Autolock lock(mCore->mMutex); @@ -711,16 +712,16 @@ status_t BufferQueueProducer::connect(const sp<android::IBinder> &token, // Set up a death notification so that we can disconnect // automatically if the remote producer dies - if (token != NULL && token->remoteBinder() != NULL) { - status = token->linkToDeath( + if (listener != NULL && + listener->asBinder()->remoteBinder() != NULL) { + status = listener->asBinder()->linkToDeath( static_cast<IBinder::DeathRecipient*>(this)); - if (status == NO_ERROR) { - mCore->mConnectedProducerToken = token; - } else { + if (status != NO_ERROR) { BQ_LOGE("connect(P): linkToDeath failed: %s (%d)", strerror(-status), status); } } + mCore->mConnectedProducerListener = listener; break; default: BQ_LOGE("connect(P): unknown API %d", api); @@ -759,14 +760,15 @@ status_t BufferQueueProducer::disconnect(int api) { mCore->freeAllBuffersLocked(); // Remove our death notification callback if we have one - sp<IBinder> token = mCore->mConnectedProducerToken; - if (token != NULL) { + if (mCore->mConnectedProducerListener != NULL) { + sp<IBinder> token = + mCore->mConnectedProducerListener->asBinder(); // This can fail if we're here because of the death // notification, but we just ignore it token->unlinkToDeath( static_cast<IBinder::DeathRecipient*>(this)); } - mCore->mConnectedProducerToken = NULL; + mCore->mConnectedProducerListener = NULL; mCore->mConnectedApi = BufferQueueCore::NO_CONNECTED_API; mCore->mSidebandStream.clear(); mCore->mDequeueCondition.broadcast(); diff --git a/libs/gui/IGraphicBufferProducer.cpp b/libs/gui/IGraphicBufferProducer.cpp index 7c503156b7..c0b08c1612 100644 --- a/libs/gui/IGraphicBufferProducer.cpp +++ b/libs/gui/IGraphicBufferProducer.cpp @@ -27,6 +27,7 @@ #include <binder/IInterface.h> #include <gui/IGraphicBufferProducer.h> +#include <gui/IProducerListener.h> namespace android { // ---------------------------------------------------------------------------- @@ -171,11 +172,16 @@ public: return result; } - virtual status_t connect(const sp<IBinder>& token, + virtual status_t connect(const sp<IProducerListener>& listener, int api, bool producerControlledByApp, QueueBufferOutput* output) { Parcel data, reply; data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); - data.writeStrongBinder(token); + if (listener != NULL) { + data.writeInt32(1); + data.writeStrongBinder(listener->asBinder()); + } else { + data.writeInt32(0); + } data.writeInt32(api); data.writeInt32(producerControlledByApp); status_t result = remote()->transact(CONNECT, data, &reply); @@ -308,13 +314,16 @@ status_t BnGraphicBufferProducer::onTransact( } break; case CONNECT: { CHECK_INTERFACE(IGraphicBufferProducer, data, reply); - sp<IBinder> token = data.readStrongBinder(); + sp<IProducerListener> listener; + if (data.readInt32() == 1) { + listener = IProducerListener::asInterface(data.readStrongBinder()); + } int api = data.readInt32(); bool producerControlledByApp = data.readInt32(); QueueBufferOutput* const output = reinterpret_cast<QueueBufferOutput *>( reply->writeInplace(sizeof(QueueBufferOutput))); - status_t res = connect(token, api, producerControlledByApp, output); + status_t res = connect(listener, api, producerControlledByApp, output); reply->writeInt32(res); return NO_ERROR; } break; diff --git a/libs/gui/IProducerListener.cpp b/libs/gui/IProducerListener.cpp new file mode 100644 index 0000000000..efe4069e28 --- /dev/null +++ b/libs/gui/IProducerListener.cpp @@ -0,0 +1,53 @@ +/* + * Copyright 2014 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 <binder/Parcel.h> + +#include <gui/IProducerListener.h> + +namespace android { + +enum { + ON_BUFFER_RELEASED = IBinder::FIRST_CALL_TRANSACTION, +}; + +class BpProducerListener : public BpInterface<IProducerListener> +{ +public: + BpProducerListener(const sp<IBinder>& impl) + : BpInterface<IProducerListener>(impl) {} + + virtual void onBufferReleased() { + Parcel data, reply; + data.writeInterfaceToken(IProducerListener::getInterfaceDescriptor()); + remote()->transact(ON_BUFFER_RELEASED, data, &reply, IBinder::FLAG_ONEWAY); + } +}; + +IMPLEMENT_META_INTERFACE(ProducerListener, "android.gui.IProducerListener") + +status_t BnProducerListener::onTransact(uint32_t code, const Parcel& data, + Parcel* reply, uint32_t flags) { + switch (code) { + case ON_BUFFER_RELEASED: + CHECK_INTERFACE(IProducerListener, data, reply); + onBufferReleased(); + return NO_ERROR; + } + return BBinder::onTransact(code, data, reply, flags); +} + +} // namespace android diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp index 95f4084260..d1ef503f83 100644 --- a/libs/gui/Surface.cpp +++ b/libs/gui/Surface.cpp @@ -27,6 +27,7 @@ #include <ui/Fence.h> +#include <gui/IProducerListener.h> #include <gui/ISurfaceComposer.h> #include <gui/SurfaceComposerClient.h> #include <gui/GLConsumer.h> @@ -513,10 +514,10 @@ int Surface::dispatchUnlockAndPost(va_list args __attribute__((unused))) { int Surface::connect(int api) { ATRACE_CALL(); ALOGV("Surface::connect"); - static sp<BBinder> sLife = new BBinder(); + static sp<IProducerListener> listener = new DummyProducerListener(); Mutex::Autolock lock(mMutex); IGraphicBufferProducer::QueueBufferOutput output; - int err = mGraphicBufferProducer->connect(sLife, api, mProducerControlledByApp, &output); + int err = mGraphicBufferProducer->connect(listener, api, mProducerControlledByApp, &output); if (err == NO_ERROR) { uint32_t numPendingBuffers = 0; output.deflate(&mDefaultWidth, &mDefaultHeight, &mTransformHint, diff --git a/libs/gui/tests/BufferQueue_test.cpp b/libs/gui/tests/BufferQueue_test.cpp index e02c7808fd..fe8f8b162a 100644 --- a/libs/gui/tests/BufferQueue_test.cpp +++ b/libs/gui/tests/BufferQueue_test.cpp @@ -17,17 +17,19 @@ #define LOG_TAG "BufferQueue_test" //#define LOG_NDEBUG 0 -#include <gtest/gtest.h> - -#include <utils/String8.h> -#include <utils/threads.h> +#include <gui/BufferQueue.h> +#include <gui/IProducerListener.h> #include <ui/GraphicBuffer.h> #include <binder/IPCThreadState.h> #include <binder/IServiceManager.h> #include <binder/ProcessState.h> -#include <gui/BufferQueue.h> + +#include <utils/String8.h> +#include <utils/threads.h> + +#include <gtest/gtest.h> namespace android { @@ -141,7 +143,8 @@ TEST_F(BufferQueueTest, AcquireBuffer_ExceedsMaxAcquireCount_Fails) { sp<DummyConsumer> dc(new DummyConsumer); mConsumer->consumerConnect(dc, false); IGraphicBufferProducer::QueueBufferOutput qbo; - mProducer->connect(NULL, NATIVE_WINDOW_API_CPU, false, &qbo); + mProducer->connect(new DummyProducerListener, NATIVE_WINDOW_API_CPU, false, + &qbo); mProducer->setBufferCount(4); int slot; @@ -207,8 +210,8 @@ TEST_F(BufferQueueTest, DetachAndReattachOnProducerSide) { sp<DummyConsumer> dc(new DummyConsumer); ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false)); IGraphicBufferProducer::QueueBufferOutput output; - ASSERT_EQ(OK, - mProducer->connect(NULL, NATIVE_WINDOW_API_CPU, false, &output)); + ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener, + NATIVE_WINDOW_API_CPU, false, &output)); ASSERT_EQ(BAD_VALUE, mProducer->detachBuffer(-1)); // Index too low ASSERT_EQ(BAD_VALUE, mProducer->detachBuffer( @@ -260,8 +263,8 @@ TEST_F(BufferQueueTest, DetachAndReattachOnConsumerSide) { sp<DummyConsumer> dc(new DummyConsumer); ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false)); IGraphicBufferProducer::QueueBufferOutput output; - ASSERT_EQ(OK, - mProducer->connect(NULL, NATIVE_WINDOW_API_CPU, false, &output)); + ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener, + NATIVE_WINDOW_API_CPU, false, &output)); int slot; sp<Fence> fence; @@ -318,8 +321,8 @@ TEST_F(BufferQueueTest, MoveFromConsumerToProducer) { sp<DummyConsumer> dc(new DummyConsumer); ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false)); IGraphicBufferProducer::QueueBufferOutput output; - ASSERT_EQ(OK, - mProducer->connect(NULL, NATIVE_WINDOW_API_CPU, false, &output)); + ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener, + NATIVE_WINDOW_API_CPU, false, &output)); int slot; sp<Fence> fence; diff --git a/libs/gui/tests/IGraphicBufferProducer_test.cpp b/libs/gui/tests/IGraphicBufferProducer_test.cpp index 9c06fae064..aadfe61770 100644 --- a/libs/gui/tests/IGraphicBufferProducer_test.cpp +++ b/libs/gui/tests/IGraphicBufferProducer_test.cpp @@ -25,13 +25,14 @@ #include <ui/GraphicBuffer.h> #include <gui/BufferQueue.h> +#include <gui/IProducerListener.h> #include <vector> #define ASSERT_OK(x) ASSERT_EQ(OK, (x)) #define EXPECT_OK(x) EXPECT_EQ(OK, (x)) -#define TEST_TOKEN ((IBinder*)(NULL)) +#define TEST_TOKEN ((IProducerListener*)(NULL)) #define TEST_API NATIVE_WINDOW_API_CPU #define TEST_API_OTHER NATIVE_WINDOW_API_EGL // valid API that's not TEST_API #define TEST_CONTROLLED_BY_APP false |