diff options
Diffstat (limited to 'libs')
-rw-r--r-- | libs/binder/Parcel.cpp | 101 | ||||
-rw-r--r-- | libs/binder/Static.cpp | 2 | ||||
-rw-r--r-- | libs/binder/TextOutput.cpp | 4 | ||||
-rw-r--r-- | libs/gui/BufferItem.cpp | 2 | ||||
-rw-r--r-- | libs/gui/BufferQueue.cpp | 5 | ||||
-rw-r--r-- | libs/gui/BufferQueueProducer.cpp | 61 | ||||
-rw-r--r-- | libs/gui/ConsumerBase.cpp | 4 | ||||
-rw-r--r-- | libs/gui/GLConsumer.cpp | 6 | ||||
-rw-r--r-- | libs/gui/IConsumerListener.cpp | 20 | ||||
-rw-r--r-- | libs/gui/ISurfaceComposer.cpp | 14 | ||||
-rw-r--r-- | libs/gui/LayerState.cpp | 8 | ||||
-rw-r--r-- | libs/gui/StreamSplitter.cpp | 2 | ||||
-rw-r--r-- | libs/gui/tests/BufferQueue_test.cpp | 2 | ||||
-rw-r--r-- | libs/gui/tests/DisconnectWaiter.h | 2 | ||||
-rw-r--r-- | libs/gui/tests/FrameWaiter.h | 2 | ||||
-rw-r--r-- | libs/gui/tests/IGraphicBufferProducer_test.cpp | 2 | ||||
-rw-r--r-- | libs/gui/tests/StreamSplitter_test.cpp | 2 | ||||
-rw-r--r-- | libs/gui/tests/SurfaceTextureGLThreadToGL.h | 2 | ||||
-rw-r--r-- | libs/ui/GraphicBuffer.cpp | 17 |
19 files changed, 175 insertions, 83 deletions
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp index 99e539c..c613fe7 100644 --- a/libs/binder/Parcel.cpp +++ b/libs/binder/Parcel.cpp @@ -26,7 +26,6 @@ #include <binder/TextOutput.h> #include <errno.h> -#include <utils/CallStack.h> #include <utils/Debug.h> #include <utils/Log.h> #include <utils/String8.h> @@ -36,8 +35,8 @@ #include <cutils/ashmem.h> #include <private/binder/binder_module.h> +#include <private/binder/Static.h> -#include <fcntl.h> #include <inttypes.h> #include <stdio.h> #include <stdlib.h> @@ -50,6 +49,8 @@ #define LOG_REFS(...) //#define LOG_REFS(...) ALOG(LOG_DEBUG, "Parcel", __VA_ARGS__) +#define LOG_ALLOC(...) +//#define LOG_ALLOC(...) ALOG(LOG_DEBUG, "Parcel", __VA_ARGS__) // --------------------------------------------------------------------------- @@ -74,6 +75,10 @@ struct small_flat_data namespace android { +static pthread_mutex_t gParcelGlobalAllocSizeLock = PTHREAD_MUTEX_INITIALIZER; +static size_t gParcelGlobalAllocSize = 0; +static size_t gParcelGlobalAllocCount = 0; + void acquire_object(const sp<ProcessState>& proc, const flat_binder_object& obj, const void* who) { @@ -293,12 +298,28 @@ status_t unflatten_binder(const sp<ProcessState>& proc, Parcel::Parcel() { + LOG_ALLOC("Parcel %p: constructing", this); initState(); } Parcel::~Parcel() { freeDataNoInit(); + LOG_ALLOC("Parcel %p: destroyed", this); +} + +size_t Parcel::getGlobalAllocSize() { + pthread_mutex_lock(&gParcelGlobalAllocSizeLock); + size_t size = gParcelGlobalAllocSize; + pthread_mutex_unlock(&gParcelGlobalAllocSizeLock); + return size; +} + +size_t Parcel::getGlobalAllocCount() { + pthread_mutex_lock(&gParcelGlobalAllocSizeLock); + size_t count = gParcelGlobalAllocCount; + pthread_mutex_unlock(&gParcelGlobalAllocSizeLock); + return count; } const uint8_t* Parcel::data() const @@ -768,29 +789,6 @@ status_t Parcel::writeFileDescriptor(int fd, bool takeOwnership) status_t Parcel::writeDupFileDescriptor(int fd) { int dupFd = dup(fd); - - { // Temporary extra debug validation for b/17477219: a Parcel recipient is - // getting a positive but invalid fd unexpectedly. Trying to track down - // where it's coming from. - int dupErrno = dupFd < 0 ? errno : 0; - int fdFlags = fcntl(fd, F_GETFD); - int fdFlagsErrno = fdFlags == -1 ? errno : 0; - int dupFlags = fcntl(dupFd, F_GETFD); - int dupFlagsErrno = dupFlags == -1 ? errno : 0; - if (dupFd < 0 || fdFlags == -1 || dupFlags == -1) { - ALOGE("Parcel::writeDupFileDescriptor failed:\n" - " fd=%d flags=%d err=%d(%s)\n" - " dupFd=%d dupErr=%d(%s) flags=%d err=%d(%s)", - fd, fdFlags, fdFlagsErrno, strerror(fdFlagsErrno), - dupFd, dupErrno, strerror(dupErrno), - dupFlags, dupFlagsErrno, strerror(dupFlagsErrno)); - if (fd < 0 || fdFlags == -1) { - CallStack(LOG_TAG); - } - return -errno; - } - } - if (dupFd < 0) { return -errno; } @@ -1305,23 +1303,11 @@ status_t Parcel::read(FlattenableHelperInterface& val) const status_t err = NO_ERROR; for (size_t i=0 ; i<fd_count && err==NO_ERROR ; i++) { - int oldfd = this->readFileDescriptor(); - fds[i] = dup(oldfd); + fds[i] = dup(this->readFileDescriptor()); if (fds[i] < 0) { - int dupErrno = errno; err = BAD_VALUE; - int flags = fcntl(oldfd, F_GETFD); - int fcntlErrno = errno; - const flat_binder_object* flat = readObject(true); - ALOGE("dup failed in Parcel::read, fd %zu of %zu\n" - " dup(%d) = %d [errno: %d (%s)]\n" - " fcntl(%d, F_GETFD) = %d [errno: %d (%s)]\n" - " flat %p type %d", - i, fd_count, - oldfd, fds[i], dupErrno, strerror(dupErrno), - oldfd, flags, fcntlErrno, strerror(fcntlErrno), - flat, flat ? flat->type : 0); - CallStack(LOG_TAG); + ALOGE("dup() failed in Parcel::read, i is %zu, fds[i] is %d, fd_count is %zu, error: %s", + i, fds[i], fd_count, strerror(errno)); } } @@ -1525,11 +1511,20 @@ void Parcel::freeData() void Parcel::freeDataNoInit() { if (mOwner) { + LOG_ALLOC("Parcel %p: freeing other owner data", this); //ALOGI("Freeing data ref of %p (pid=%d)", this, getpid()); mOwner(this, mData, mDataSize, mObjects, mObjectsSize, mOwnerCookie); } else { + LOG_ALLOC("Parcel %p: freeing allocated data", this); releaseObjects(); - if (mData) free(mData); + if (mData) { + LOG_ALLOC("Parcel %p: freeing with %zu capacity", this, mDataCapacity); + pthread_mutex_lock(&gParcelGlobalAllocSizeLock); + gParcelGlobalAllocSize -= mDataCapacity; + gParcelGlobalAllocCount--; + pthread_mutex_unlock(&gParcelGlobalAllocSizeLock); + free(mData); + } if (mObjects) free(mObjects); } } @@ -1558,6 +1553,11 @@ status_t Parcel::restartWrite(size_t desired) releaseObjects(); if (data) { + LOG_ALLOC("Parcel %p: restart from %zu to %zu capacity", this, mDataCapacity, desired); + pthread_mutex_lock(&gParcelGlobalAllocSizeLock); + gParcelGlobalAllocSize += desired; + gParcelGlobalAllocSize -= mDataCapacity; + pthread_mutex_unlock(&gParcelGlobalAllocSizeLock); mData = data; mDataCapacity = desired; } @@ -1637,6 +1637,12 @@ status_t Parcel::continueWrite(size_t desired) mOwner(this, mData, mDataSize, mObjects, mObjectsSize, mOwnerCookie); mOwner = NULL; + LOG_ALLOC("Parcel %p: taking ownership of %zu capacity", this, desired); + pthread_mutex_lock(&gParcelGlobalAllocSizeLock); + gParcelGlobalAllocSize += desired; + gParcelGlobalAllocCount++; + pthread_mutex_unlock(&gParcelGlobalAllocSizeLock); + mData = data; mObjects = objects; mDataSize = (mDataSize < desired) ? mDataSize : desired; @@ -1671,6 +1677,12 @@ status_t Parcel::continueWrite(size_t desired) if (desired > mDataCapacity) { uint8_t* data = (uint8_t*)realloc(mData, desired); if (data) { + LOG_ALLOC("Parcel %p: continue from %zu to %zu capacity", this, mDataCapacity, + desired); + pthread_mutex_lock(&gParcelGlobalAllocSizeLock); + gParcelGlobalAllocSize += desired; + gParcelGlobalAllocSize -= mDataCapacity; + pthread_mutex_unlock(&gParcelGlobalAllocSizeLock); mData = data; mDataCapacity = desired; } else if (desired > mDataCapacity) { @@ -1701,6 +1713,12 @@ status_t Parcel::continueWrite(size_t desired) ALOGE("continueWrite: %zu/%p/%zu/%zu", mDataCapacity, mObjects, mObjectsCapacity, desired); } + LOG_ALLOC("Parcel %p: allocating with %zu capacity", this, desired); + pthread_mutex_lock(&gParcelGlobalAllocSizeLock); + gParcelGlobalAllocSize += desired; + gParcelGlobalAllocCount++; + pthread_mutex_unlock(&gParcelGlobalAllocSizeLock); + mData = data; mDataSize = mDataPos = 0; ALOGV("continueWrite Setting data size of %p to %zu", this, mDataSize); @@ -1713,6 +1731,7 @@ status_t Parcel::continueWrite(size_t desired) void Parcel::initState() { + LOG_ALLOC("Parcel %p: initState", this); mError = NO_ERROR; mData = 0; mDataSize = 0; diff --git a/libs/binder/Static.cpp b/libs/binder/Static.cpp index 2062692..cd9509f 100644 --- a/libs/binder/Static.cpp +++ b/libs/binder/Static.cpp @@ -90,7 +90,7 @@ public: static LibBinderIPCtStatics gIPCStatics; -// ------------ ServiceManager.cpp +// ------------ IServiceManager.cpp Mutex gDefaultServiceManagerLock; sp<IServiceManager> gDefaultServiceManager; diff --git a/libs/binder/TextOutput.cpp b/libs/binder/TextOutput.cpp index db3e858..2ed5188 100644 --- a/libs/binder/TextOutput.cpp +++ b/libs/binder/TextOutput.cpp @@ -116,8 +116,8 @@ TextOutput& operator<<(TextOutput& to, double val) TextOutput& operator<<(TextOutput& to, const void* val) { - char buf[16]; - sprintf(buf, "%p", val); + char buf[32]; + snprintf(buf, sizeof(buf), "%p", val); to.print(buf, strlen(buf)); return to; } diff --git a/libs/gui/BufferItem.cpp b/libs/gui/BufferItem.cpp index d3fa43e..e6fc791 100644 --- a/libs/gui/BufferItem.cpp +++ b/libs/gui/BufferItem.cpp @@ -36,6 +36,8 @@ BufferItem::BufferItem() : mCrop.makeInvalid(); } +BufferItem::~BufferItem() {} + BufferItem::operator IGraphicBufferConsumer::BufferItem() const { IGraphicBufferConsumer::BufferItem bufferItem; bufferItem.mGraphicBuffer = mGraphicBuffer; diff --git a/libs/gui/BufferQueue.cpp b/libs/gui/BufferQueue.cpp index c49a886..61fd8c4 100644 --- a/libs/gui/BufferQueue.cpp +++ b/libs/gui/BufferQueue.cpp @@ -31,10 +31,11 @@ BufferQueue::ProxyConsumerListener::ProxyConsumerListener( BufferQueue::ProxyConsumerListener::~ProxyConsumerListener() {} -void BufferQueue::ProxyConsumerListener::onFrameAvailable() { +void BufferQueue::ProxyConsumerListener::onFrameAvailable( + const android::BufferItem& item) { sp<ConsumerListener> listener(mConsumerListener.promote()); if (listener != NULL) { - listener->onFrameAvailable(); + listener->onFrameAvailable(item); } } diff --git a/libs/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp index f9f4734..bf9c84d 100644 --- a/libs/gui/BufferQueueProducer.cpp +++ b/libs/gui/BufferQueueProducer.cpp @@ -38,7 +38,12 @@ BufferQueueProducer::BufferQueueProducer(const sp<BufferQueueCore>& core) : mCore(core), mSlots(core->mSlots), mConsumerName(), - mStickyTransform(0) {} + mStickyTransform(0), + mLastQueueBufferFence(Fence::NO_FENCE), + mCallbackMutex(), + mNextCallbackTicket(0), + mCurrentCallbackTicket(0), + mCallbackCondition() {} BufferQueueProducer::~BufferQueueProducer() {} @@ -522,12 +527,7 @@ status_t BufferQueueProducer::queueBuffer(int slot, if (fence == NULL) { BQ_LOGE("queueBuffer: fence is NULL"); - // Temporary workaround for b/17946343: soldier-on instead of returning an error. This - // prevents the client from dying, at the risk of visible corruption due to hwcomposer - // reading the buffer before the producer is done rendering it. Unless the buffer is the - // last frame of an animation, the corruption will be transient. - fence = Fence::NO_FENCE; - // return BAD_VALUE; + return BAD_VALUE; } switch (scalingMode) { @@ -541,7 +541,10 @@ status_t BufferQueueProducer::queueBuffer(int slot, return BAD_VALUE; } - sp<IConsumerListener> listener; + sp<IConsumerListener> frameAvailableListener; + sp<IConsumerListener> frameReplacedListener; + int callbackTicket = 0; + BufferItem item; { // Autolock scope Mutex::Autolock lock(mCore->mMutex); @@ -597,7 +600,6 @@ status_t BufferQueueProducer::queueBuffer(int slot, ++mCore->mFrameCounter; mSlots[slot].mFrameNumber = mCore->mFrameCounter; - BufferItem item; item.mAcquireCalled = mSlots[slot].mAcquireCalled; item.mGraphicBuffer = mSlots[slot].mGraphicBuffer; item.mCrop = crop; @@ -618,7 +620,7 @@ status_t BufferQueueProducer::queueBuffer(int slot, // When the queue is empty, we can ignore mDequeueBufferCannotBlock // and simply queue this buffer mCore->mQueue.push_back(item); - listener = mCore->mConsumerListener; + frameAvailableListener = mCore->mConsumerListener; } else { // When the queue is not empty, we need to look at the front buffer // state to see if we need to replace it @@ -634,9 +636,10 @@ status_t BufferQueueProducer::queueBuffer(int slot, } // Overwrite the droppable buffer with the incoming one *front = item; + frameReplacedListener = mCore->mConsumerListener; } else { mCore->mQueue.push_back(item); - listener = mCore->mConsumerListener; + frameAvailableListener = mCore->mConsumerListener; } } @@ -647,11 +650,41 @@ status_t BufferQueueProducer::queueBuffer(int slot, mCore->mTransformHint, mCore->mQueue.size()); ATRACE_INT(mCore->mConsumerName.string(), mCore->mQueue.size()); + + // Take a ticket for the callback functions + callbackTicket = mNextCallbackTicket++; } // Autolock scope - // Call back without lock held - if (listener != NULL) { - listener->onFrameAvailable(); + // Wait without lock held + if (mCore->mConnectedApi == NATIVE_WINDOW_API_EGL) { + // Waiting here allows for two full buffers to be queued but not a + // third. In the event that frames take varying time, this makes a + // small trade-off in favor of latency rather than throughput. + mLastQueueBufferFence->waitForever("Throttling EGL Production"); + mLastQueueBufferFence = fence; + } + + // Don't send the GraphicBuffer through the callback, and don't send + // the slot number, since the consumer shouldn't need it + item.mGraphicBuffer.clear(); + item.mSlot = BufferItem::INVALID_BUFFER_SLOT; + + // Call back without the main BufferQueue lock held, but with the callback + // lock held so we can ensure that callbacks occur in order + { + Mutex::Autolock lock(mCallbackMutex); + while (callbackTicket != mCurrentCallbackTicket) { + mCallbackCondition.wait(mCallbackMutex); + } + + if (frameAvailableListener != NULL) { + frameAvailableListener->onFrameAvailable(item); + } else if (frameReplacedListener != NULL) { + frameReplacedListener->onFrameReplaced(item); + } + + ++mCurrentCallbackTicket; + mCallbackCondition.broadcast(); } return NO_ERROR; diff --git a/libs/gui/ConsumerBase.cpp b/libs/gui/ConsumerBase.cpp index e476c9a..95f5507 100644 --- a/libs/gui/ConsumerBase.cpp +++ b/libs/gui/ConsumerBase.cpp @@ -98,7 +98,7 @@ void ConsumerBase::freeBufferLocked(int slotIndex) { mSlots[slotIndex].mFrameNumber = 0; } -void ConsumerBase::onFrameAvailable() { +void ConsumerBase::onFrameAvailable(const BufferItem& item) { CB_LOGV("onFrameAvailable"); sp<FrameAvailableListener> listener; @@ -109,7 +109,7 @@ void ConsumerBase::onFrameAvailable() { if (listener != NULL) { CB_LOGV("actually calling onFrameAvailable"); - listener->onFrameAvailable(); + listener->onFrameAvailable(item); } } diff --git a/libs/gui/GLConsumer.cpp b/libs/gui/GLConsumer.cpp index 6ba2ef8..b886c5b 100644 --- a/libs/gui/GLConsumer.cpp +++ b/libs/gui/GLConsumer.cpp @@ -505,7 +505,7 @@ status_t GLConsumer::checkAndUpdateEglStateLocked(bool contextCheck) { if (mEglDisplay == EGL_NO_DISPLAY) { mEglDisplay = dpy; } - if (mEglContext == EGL_NO_DISPLAY) { + if (mEglContext == EGL_NO_CONTEXT) { mEglContext = ctx; } } @@ -1065,6 +1065,7 @@ GLConsumer::EglImage::~EglImage() { if (!eglDestroyImageKHR(mEglDisplay, mEglImage)) { ALOGE("~EglImage: eglDestroyImageKHR failed"); } + eglTerminate(mEglDisplay); } } @@ -1079,6 +1080,7 @@ status_t GLConsumer::EglImage::createIfNeeded(EGLDisplay eglDisplay, if (!eglDestroyImageKHR(mEglDisplay, mEglImage)) { ALOGE("createIfNeeded: eglDestroyImageKHR failed"); } + eglTerminate(mEglDisplay); mEglImage = EGL_NO_IMAGE_KHR; mEglDisplay = EGL_NO_DISPLAY; } @@ -1129,11 +1131,13 @@ EGLImageKHR GLConsumer::EglImage::createImage(EGLDisplay dpy, // removes this restriction if there is hardware that can support it. attrs[2] = EGL_NONE; } + eglInitialize(dpy, 0, 0); EGLImageKHR image = eglCreateImageKHR(dpy, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID, cbuf, attrs); if (image == EGL_NO_IMAGE_KHR) { EGLint error = eglGetError(); ALOGE("error creating EGLImage: %#x", error); + eglTerminate(dpy); } return image; } diff --git a/libs/gui/IConsumerListener.cpp b/libs/gui/IConsumerListener.cpp index 4ccf0ac..409dfe4 100644 --- a/libs/gui/IConsumerListener.cpp +++ b/libs/gui/IConsumerListener.cpp @@ -21,6 +21,7 @@ #include <binder/Parcel.h> #include <gui/IConsumerListener.h> +#include <gui/BufferItem.h> // --------------------------------------------------------------------------- namespace android { @@ -39,9 +40,10 @@ public: : BpInterface<IConsumerListener>(impl) { } - virtual void onFrameAvailable() { + virtual void onFrameAvailable(const BufferItem& item) { Parcel data, reply; data.writeInterfaceToken(IConsumerListener::getInterfaceDescriptor()); + data.write(item); remote()->transact(ON_FRAME_AVAILABLE, data, &reply, IBinder::FLAG_ONEWAY); } @@ -66,18 +68,20 @@ status_t BnConsumerListener::onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { switch(code) { - case ON_FRAME_AVAILABLE: + case ON_FRAME_AVAILABLE: { CHECK_INTERFACE(IConsumerListener, data, reply); - onFrameAvailable(); - return NO_ERROR; - case ON_BUFFER_RELEASED: + BufferItem item; + data.read(item); + onFrameAvailable(item); + return NO_ERROR; } + case ON_BUFFER_RELEASED: { CHECK_INTERFACE(IConsumerListener, data, reply); onBuffersReleased(); - return NO_ERROR; - case ON_SIDEBAND_STREAM_CHANGED: + return NO_ERROR; } + case ON_SIDEBAND_STREAM_CHANGED: { CHECK_INTERFACE(IConsumerListener, data, reply); onSidebandStreamChanged(); - return NO_ERROR; + return NO_ERROR; } } return BBinder::onTransact(code, data, reply, flags); } diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp index 669755a..bc4baa3 100644 --- a/libs/gui/ISurfaceComposer.cpp +++ b/libs/gui/ISurfaceComposer.cpp @@ -312,19 +312,29 @@ status_t BnSurfaceComposer::onTransact( case SET_TRANSACTION_STATE: { CHECK_INTERFACE(ISurfaceComposer, data, reply); size_t count = data.readInt32(); + if (count > data.dataSize()) { + return BAD_VALUE; + } ComposerState s; Vector<ComposerState> state; state.setCapacity(count); for (size_t i=0 ; i<count ; i++) { - s.read(data); + if (s.read(data) == BAD_VALUE) { + return BAD_VALUE; + } state.add(s); } count = data.readInt32(); + if (count > data.dataSize()) { + return BAD_VALUE; + } DisplayState d; Vector<DisplayState> displays; displays.setCapacity(count); for (size_t i=0 ; i<count ; i++) { - d.read(data); + if (d.read(data) == BAD_VALUE) { + return BAD_VALUE; + } displays.add(d); } uint32_t flags = data.readInt32(); diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp index dcdcdf2..ccf8b78 100644 --- a/libs/gui/LayerState.cpp +++ b/libs/gui/LayerState.cpp @@ -55,8 +55,12 @@ status_t layer_state_t::read(const Parcel& input) alpha = input.readFloat(); flags = input.readInt32(); mask = input.readInt32(); - matrix = *reinterpret_cast<layer_state_t::matrix22_t const *>( - input.readInplace(sizeof(layer_state_t::matrix22_t))); + const void* matrix_data = input.readInplace(sizeof(layer_state_t::matrix22_t)); + if (matrix_data) { + matrix = *reinterpret_cast<layer_state_t::matrix22_t const *>(matrix_data); + } else { + return BAD_VALUE; + } input.read(crop); input.read(transparentRegion); return NO_ERROR; diff --git a/libs/gui/StreamSplitter.cpp b/libs/gui/StreamSplitter.cpp index 2fd09eb..25e6cab 100644 --- a/libs/gui/StreamSplitter.cpp +++ b/libs/gui/StreamSplitter.cpp @@ -98,7 +98,7 @@ void StreamSplitter::setName(const String8 &name) { mInput->setConsumerName(name); } -void StreamSplitter::onFrameAvailable() { +void StreamSplitter::onFrameAvailable(const BufferItem& /* item */) { ATRACE_CALL(); Mutex::Autolock lock(mMutex); diff --git a/libs/gui/tests/BufferQueue_test.cpp b/libs/gui/tests/BufferQueue_test.cpp index 5cccc9b..838ad90 100644 --- a/libs/gui/tests/BufferQueue_test.cpp +++ b/libs/gui/tests/BufferQueue_test.cpp @@ -67,7 +67,7 @@ protected: }; struct DummyConsumer : public BnConsumerListener { - virtual void onFrameAvailable() {} + virtual void onFrameAvailable(const BufferItem& /* item */) {} virtual void onBuffersReleased() {} virtual void onSidebandStreamChanged() {} }; diff --git a/libs/gui/tests/DisconnectWaiter.h b/libs/gui/tests/DisconnectWaiter.h index 56e96c2..6e6915b 100644 --- a/libs/gui/tests/DisconnectWaiter.h +++ b/libs/gui/tests/DisconnectWaiter.h @@ -44,7 +44,7 @@ public: mPendingFrames--; } - virtual void onFrameAvailable() { + virtual void onFrameAvailable(const BufferItem& /* item */) { Mutex::Autolock lock(mMutex); mPendingFrames++; mFrameCondition.signal(); diff --git a/libs/gui/tests/FrameWaiter.h b/libs/gui/tests/FrameWaiter.h index bdedba6..f78fa00 100644 --- a/libs/gui/tests/FrameWaiter.h +++ b/libs/gui/tests/FrameWaiter.h @@ -35,7 +35,7 @@ public: mPendingFrames--; } - virtual void onFrameAvailable() { + virtual void onFrameAvailable(const BufferItem& /* item */) { Mutex::Autolock lock(mMutex); mPendingFrames++; mCondition.signal(); diff --git a/libs/gui/tests/IGraphicBufferProducer_test.cpp b/libs/gui/tests/IGraphicBufferProducer_test.cpp index aadfe61..8d5fd8f 100644 --- a/libs/gui/tests/IGraphicBufferProducer_test.cpp +++ b/libs/gui/tests/IGraphicBufferProducer_test.cpp @@ -65,7 +65,7 @@ const sp<Fence> QUEUE_BUFFER_INPUT_FENCE = Fence::NO_FENCE; }; // namespace anonymous struct DummyConsumer : public BnConsumerListener { - virtual void onFrameAvailable() {} + virtual void onFrameAvailable(const BufferItem& /* item */) {} virtual void onBuffersReleased() {} virtual void onSidebandStreamChanged() {} }; diff --git a/libs/gui/tests/StreamSplitter_test.cpp b/libs/gui/tests/StreamSplitter_test.cpp index 32ec90d..4e63a6f 100644 --- a/libs/gui/tests/StreamSplitter_test.cpp +++ b/libs/gui/tests/StreamSplitter_test.cpp @@ -46,7 +46,7 @@ protected: }; struct DummyListener : public BnConsumerListener { - virtual void onFrameAvailable() {} + virtual void onFrameAvailable(const BufferItem& /* item */) {} virtual void onBuffersReleased() {} virtual void onSidebandStreamChanged() {} }; diff --git a/libs/gui/tests/SurfaceTextureGLThreadToGL.h b/libs/gui/tests/SurfaceTextureGLThreadToGL.h index 6410516..14e42ac 100644 --- a/libs/gui/tests/SurfaceTextureGLThreadToGL.h +++ b/libs/gui/tests/SurfaceTextureGLThreadToGL.h @@ -130,7 +130,7 @@ protected: } // This should be called by GLConsumer on the producer thread. - virtual void onFrameAvailable() { + virtual void onFrameAvailable(const BufferItem& /* item */) { Mutex::Autolock lock(mMutex); ALOGV("+onFrameAvailable"); mFrameAvailable = true; diff --git a/libs/ui/GraphicBuffer.cpp b/libs/ui/GraphicBuffer.cpp index 9b0bd60..e768f13 100644 --- a/libs/ui/GraphicBuffer.cpp +++ b/libs/ui/GraphicBuffer.cpp @@ -310,10 +310,19 @@ status_t GraphicBuffer::unflatten( const size_t numFds = buf[8]; const size_t numInts = buf[9]; + const size_t maxNumber = UINT_MAX / sizeof(int); + if (numFds >= maxNumber || numInts >= (maxNumber - 10)) { + width = height = stride = format = usage = 0; + handle = NULL; + ALOGE("unflatten: numFds or numInts is too large: %d, %d", + numFds, numInts); + return BAD_VALUE; + } + const size_t sizeNeeded = (10 + numInts) * sizeof(int); if (size < sizeNeeded) return NO_MEMORY; - size_t fdCountNeeded = 0; + size_t fdCountNeeded = numFds; if (count < fdCountNeeded) return NO_MEMORY; if (handle) { @@ -328,6 +337,12 @@ status_t GraphicBuffer::unflatten( format = buf[4]; usage = buf[5]; native_handle* h = native_handle_create(numFds, numInts); + if (!h) { + width = height = stride = format = usage = 0; + handle = NULL; + ALOGE("unflatten: native_handle_create failed"); + return NO_MEMORY; + } memcpy(h->data, fds, numFds*sizeof(int)); memcpy(h->data + numFds, &buf[10], numInts*sizeof(int)); handle = h; |