Loading include/gui/BufferQueue.h +16 −2 Original line number Diff line number Diff line Loading @@ -20,6 +20,8 @@ #include <EGL/egl.h> #include <EGL/eglext.h> #include <binder/IBinder.h> #include <gui/IConsumerListener.h> #include <gui/IGraphicBufferAlloc.h> #include <gui/IGraphicBufferProducer.h> Loading @@ -35,7 +37,9 @@ namespace android { // ---------------------------------------------------------------------------- class BufferQueue : public BnGraphicBufferProducer, public BnGraphicBufferConsumer { class BufferQueue : public BnGraphicBufferProducer, public BnGraphicBufferConsumer, private IBinder::DeathRecipient { public: enum { MIN_UNDEQUEUED_BUFFERS = 2 }; enum { NUM_BUFFER_SLOTS = 32 }; Loading Loading @@ -78,6 +82,12 @@ public: BufferQueue(const sp<IGraphicBufferAlloc>& allocator = NULL); virtual ~BufferQueue(); /* * IBinder::DeathRecipient interface */ virtual void binderDied(const wp<IBinder>& who); /* * IGraphicBufferProducer interface */ Loading Loading @@ -184,7 +194,8 @@ public: // it's still connected to a producer). // // APIs are enumerated in window.h (e.g. NATIVE_WINDOW_API_CPU). virtual status_t connect(int api, bool producerControlledByApp, QueueBufferOutput* output); virtual status_t connect(const sp<IBinder>& token, int api, bool producerControlledByApp, QueueBufferOutput* output); // disconnect attempts to disconnect a producer API from the BufferQueue. // Calling this method will cause any subsequent calls to other Loading Loading @@ -552,6 +563,9 @@ private: // mTransformHint is used to optimize for screen rotations uint32_t mTransformHint; // mConnectedProducerToken is used to set a binder death notification on the producer sp<IBinder> mConnectedProducerToken; }; // ---------------------------------------------------------------------------- Loading include/gui/IGraphicBufferProducer.h +5 −2 Original line number Diff line number Diff line Loading @@ -189,8 +189,11 @@ public: // // outWidth, outHeight and outTransform are filled with the default width // and height of the window and current transform applied to buffers, // respectively. virtual status_t connect(int api, bool producerControlledByApp, QueueBufferOutput* output) = 0; // respectively. The token needs to be any binder object that lives in the // producer process -- it is solely used for obtaining a death notification // when the producer is killed. virtual status_t connect(const sp<IBinder>& token, int api, bool producerControlledByApp, QueueBufferOutput* output) = 0; // disconnect attempts to disconnect a client API from the // IGraphicBufferProducer. Calling this method will cause any subsequent Loading libs/gui/BufferQueue.cpp +29 −3 Original line number Diff line number Diff line Loading @@ -635,7 +635,9 @@ void BufferQueue::cancelBuffer(int buf, const sp<Fence>& fence) { mDequeueCondition.broadcast(); } status_t BufferQueue::connect(int api, bool producerControlledByApp, QueueBufferOutput* output) { status_t BufferQueue::connect(const sp<IBinder>& token, int api, bool producerControlledByApp, QueueBufferOutput* output) { ATRACE_CALL(); ST_LOGV("connect: api=%d producerControlledByApp=%s", api, producerControlledByApp ? "true" : "false"); Loading Loading @@ -663,8 +665,14 @@ status_t BufferQueue::connect(int api, bool producerControlledByApp, QueueBuffer err = -EINVAL; } else { mConnectedApi = api; output->inflate(mDefaultWidth, mDefaultHeight, mTransformHint, mQueue.size()); output->inflate(mDefaultWidth, mDefaultHeight, mTransformHint, mQueue.size()); // set-up a death notification so that we can disconnect automatically // when/if the remote producer dies. // This will fail with INVALID_OPERATION if the "token" is local to our process. if (token->linkToDeath(static_cast<IBinder::DeathRecipient*>(this)) == NO_ERROR) { mConnectedProducerToken = token; } } break; default: Loading @@ -678,6 +686,16 @@ status_t BufferQueue::connect(int api, bool producerControlledByApp, QueueBuffer return err; } void BufferQueue::binderDied(const wp<IBinder>& who) { // If we're here, it means that a producer we were connected to died. // We're GUARANTEED that we still are connected to it because it has no other way // to get disconnected -- or -- we wouldn't be here because we're removing this // callback upon disconnect. Therefore, it's okay to read mConnectedApi without // synchronization here. int api = mConnectedApi; this->disconnect(api); } status_t BufferQueue::disconnect(int api) { ATRACE_CALL(); ST_LOGV("disconnect: api=%d", api); Loading @@ -701,6 +719,14 @@ status_t BufferQueue::disconnect(int api) { case NATIVE_WINDOW_API_CAMERA: if (mConnectedApi == api) { freeAllBuffersLocked(); // remove our death notification callback if we have one sp<IBinder> token = mConnectedProducerToken; if (token != NULL) { // this can fail if we're here because of the death notification // either way, we just ignore. token->unlinkToDeath(static_cast<IBinder::DeathRecipient*>(this)); } mConnectedProducerToken = NULL; mConnectedApi = NO_CONNECTED_API; mDequeueCondition.broadcast(); listener = mConsumerListener; Loading libs/gui/IGraphicBufferProducer.cpp +5 −3 Original line number Diff line number Diff line Loading @@ -41,7 +41,6 @@ enum { DISCONNECT, }; class BpGraphicBufferProducer : public BpInterface<IGraphicBufferProducer> { public: Loading Loading @@ -139,9 +138,11 @@ public: return result; } virtual status_t connect(int api, bool producerControlledByApp, QueueBufferOutput* output) { virtual status_t connect(const sp<IBinder>& token, int api, bool producerControlledByApp, QueueBufferOutput* output) { Parcel data, reply; data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); data.writeStrongBinder(token); data.writeInt32(api); data.writeInt32(producerControlledByApp); status_t result = remote()->transact(CONNECT, data, &reply); Loading Loading @@ -241,12 +242,13 @@ status_t BnGraphicBufferProducer::onTransact( } break; case CONNECT: { CHECK_INTERFACE(IGraphicBufferProducer, data, reply); sp<IBinder> token = data.readStrongBinder(); int api = data.readInt32(); bool producerControlledByApp = data.readInt32(); QueueBufferOutput* const output = reinterpret_cast<QueueBufferOutput *>( reply->writeInplace(sizeof(QueueBufferOutput))); status_t res = connect(api, producerControlledByApp, output); status_t res = connect(token, api, producerControlledByApp, output); reply->writeInt32(res); return NO_ERROR; } break; Loading libs/gui/Surface.cpp +3 −1 Original line number Diff line number Diff line Loading @@ -490,9 +490,10 @@ int Surface::dispatchUnlockAndPost(va_list args) { int Surface::connect(int api) { ATRACE_CALL(); ALOGV("Surface::connect"); static sp<BBinder> sLife = new BBinder(); Mutex::Autolock lock(mMutex); IGraphicBufferProducer::QueueBufferOutput output; int err = mGraphicBufferProducer->connect(api, mProducerControlledByApp, &output); int err = mGraphicBufferProducer->connect(sLife, api, mProducerControlledByApp, &output); if (err == NO_ERROR) { uint32_t numPendingBuffers = 0; output.deflate(&mDefaultWidth, &mDefaultHeight, &mTransformHint, Loading @@ -505,6 +506,7 @@ int Surface::connect(int api) { return err; } int Surface::disconnect(int api) { ATRACE_CALL(); ALOGV("Surface::disconnect"); Loading Loading
include/gui/BufferQueue.h +16 −2 Original line number Diff line number Diff line Loading @@ -20,6 +20,8 @@ #include <EGL/egl.h> #include <EGL/eglext.h> #include <binder/IBinder.h> #include <gui/IConsumerListener.h> #include <gui/IGraphicBufferAlloc.h> #include <gui/IGraphicBufferProducer.h> Loading @@ -35,7 +37,9 @@ namespace android { // ---------------------------------------------------------------------------- class BufferQueue : public BnGraphicBufferProducer, public BnGraphicBufferConsumer { class BufferQueue : public BnGraphicBufferProducer, public BnGraphicBufferConsumer, private IBinder::DeathRecipient { public: enum { MIN_UNDEQUEUED_BUFFERS = 2 }; enum { NUM_BUFFER_SLOTS = 32 }; Loading Loading @@ -78,6 +82,12 @@ public: BufferQueue(const sp<IGraphicBufferAlloc>& allocator = NULL); virtual ~BufferQueue(); /* * IBinder::DeathRecipient interface */ virtual void binderDied(const wp<IBinder>& who); /* * IGraphicBufferProducer interface */ Loading Loading @@ -184,7 +194,8 @@ public: // it's still connected to a producer). // // APIs are enumerated in window.h (e.g. NATIVE_WINDOW_API_CPU). virtual status_t connect(int api, bool producerControlledByApp, QueueBufferOutput* output); virtual status_t connect(const sp<IBinder>& token, int api, bool producerControlledByApp, QueueBufferOutput* output); // disconnect attempts to disconnect a producer API from the BufferQueue. // Calling this method will cause any subsequent calls to other Loading Loading @@ -552,6 +563,9 @@ private: // mTransformHint is used to optimize for screen rotations uint32_t mTransformHint; // mConnectedProducerToken is used to set a binder death notification on the producer sp<IBinder> mConnectedProducerToken; }; // ---------------------------------------------------------------------------- Loading
include/gui/IGraphicBufferProducer.h +5 −2 Original line number Diff line number Diff line Loading @@ -189,8 +189,11 @@ public: // // outWidth, outHeight and outTransform are filled with the default width // and height of the window and current transform applied to buffers, // respectively. virtual status_t connect(int api, bool producerControlledByApp, QueueBufferOutput* output) = 0; // respectively. The token needs to be any binder object that lives in the // producer process -- it is solely used for obtaining a death notification // when the producer is killed. virtual status_t connect(const sp<IBinder>& token, int api, bool producerControlledByApp, QueueBufferOutput* output) = 0; // disconnect attempts to disconnect a client API from the // IGraphicBufferProducer. Calling this method will cause any subsequent Loading
libs/gui/BufferQueue.cpp +29 −3 Original line number Diff line number Diff line Loading @@ -635,7 +635,9 @@ void BufferQueue::cancelBuffer(int buf, const sp<Fence>& fence) { mDequeueCondition.broadcast(); } status_t BufferQueue::connect(int api, bool producerControlledByApp, QueueBufferOutput* output) { status_t BufferQueue::connect(const sp<IBinder>& token, int api, bool producerControlledByApp, QueueBufferOutput* output) { ATRACE_CALL(); ST_LOGV("connect: api=%d producerControlledByApp=%s", api, producerControlledByApp ? "true" : "false"); Loading Loading @@ -663,8 +665,14 @@ status_t BufferQueue::connect(int api, bool producerControlledByApp, QueueBuffer err = -EINVAL; } else { mConnectedApi = api; output->inflate(mDefaultWidth, mDefaultHeight, mTransformHint, mQueue.size()); output->inflate(mDefaultWidth, mDefaultHeight, mTransformHint, mQueue.size()); // set-up a death notification so that we can disconnect automatically // when/if the remote producer dies. // This will fail with INVALID_OPERATION if the "token" is local to our process. if (token->linkToDeath(static_cast<IBinder::DeathRecipient*>(this)) == NO_ERROR) { mConnectedProducerToken = token; } } break; default: Loading @@ -678,6 +686,16 @@ status_t BufferQueue::connect(int api, bool producerControlledByApp, QueueBuffer return err; } void BufferQueue::binderDied(const wp<IBinder>& who) { // If we're here, it means that a producer we were connected to died. // We're GUARANTEED that we still are connected to it because it has no other way // to get disconnected -- or -- we wouldn't be here because we're removing this // callback upon disconnect. Therefore, it's okay to read mConnectedApi without // synchronization here. int api = mConnectedApi; this->disconnect(api); } status_t BufferQueue::disconnect(int api) { ATRACE_CALL(); ST_LOGV("disconnect: api=%d", api); Loading @@ -701,6 +719,14 @@ status_t BufferQueue::disconnect(int api) { case NATIVE_WINDOW_API_CAMERA: if (mConnectedApi == api) { freeAllBuffersLocked(); // remove our death notification callback if we have one sp<IBinder> token = mConnectedProducerToken; if (token != NULL) { // this can fail if we're here because of the death notification // either way, we just ignore. token->unlinkToDeath(static_cast<IBinder::DeathRecipient*>(this)); } mConnectedProducerToken = NULL; mConnectedApi = NO_CONNECTED_API; mDequeueCondition.broadcast(); listener = mConsumerListener; Loading
libs/gui/IGraphicBufferProducer.cpp +5 −3 Original line number Diff line number Diff line Loading @@ -41,7 +41,6 @@ enum { DISCONNECT, }; class BpGraphicBufferProducer : public BpInterface<IGraphicBufferProducer> { public: Loading Loading @@ -139,9 +138,11 @@ public: return result; } virtual status_t connect(int api, bool producerControlledByApp, QueueBufferOutput* output) { virtual status_t connect(const sp<IBinder>& token, int api, bool producerControlledByApp, QueueBufferOutput* output) { Parcel data, reply; data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); data.writeStrongBinder(token); data.writeInt32(api); data.writeInt32(producerControlledByApp); status_t result = remote()->transact(CONNECT, data, &reply); Loading Loading @@ -241,12 +242,13 @@ status_t BnGraphicBufferProducer::onTransact( } break; case CONNECT: { CHECK_INTERFACE(IGraphicBufferProducer, data, reply); sp<IBinder> token = data.readStrongBinder(); int api = data.readInt32(); bool producerControlledByApp = data.readInt32(); QueueBufferOutput* const output = reinterpret_cast<QueueBufferOutput *>( reply->writeInplace(sizeof(QueueBufferOutput))); status_t res = connect(api, producerControlledByApp, output); status_t res = connect(token, api, producerControlledByApp, output); reply->writeInt32(res); return NO_ERROR; } break; Loading
libs/gui/Surface.cpp +3 −1 Original line number Diff line number Diff line Loading @@ -490,9 +490,10 @@ int Surface::dispatchUnlockAndPost(va_list args) { int Surface::connect(int api) { ATRACE_CALL(); ALOGV("Surface::connect"); static sp<BBinder> sLife = new BBinder(); Mutex::Autolock lock(mMutex); IGraphicBufferProducer::QueueBufferOutput output; int err = mGraphicBufferProducer->connect(api, mProducerControlledByApp, &output); int err = mGraphicBufferProducer->connect(sLife, api, mProducerControlledByApp, &output); if (err == NO_ERROR) { uint32_t numPendingBuffers = 0; output.deflate(&mDefaultWidth, &mDefaultHeight, &mTransformHint, Loading @@ -505,6 +506,7 @@ int Surface::connect(int api) { return err; } int Surface::disconnect(int api) { ATRACE_CALL(); ALOGV("Surface::disconnect"); Loading