Loading include/ui/GraphicBuffer.h +7 −0 Original line number Diff line number Diff line Loading @@ -72,6 +72,9 @@ public: GraphicBuffer(uint32_t w, uint32_t h, PixelFormat format, uint32_t usage, uint32_t stride, native_handle_t* handle, bool keepOwnership); // create a buffer from an existing android_native_buffer_t GraphicBuffer(android_native_buffer_t* buffer, bool keepOwnership); // return status status_t initCheck() const; Loading Loading @@ -137,6 +140,10 @@ private: GraphicBufferMapper& mBufferMapper; ssize_t mInitCheck; int mIndex; // If we're wrapping another buffer then this reference will make sure it // doesn't get freed. sp<android_native_buffer_t> mWrappedBuffer; }; }; // namespace android Loading include/utils/Looper.h +59 −3 Original line number Diff line number Diff line Loading @@ -20,9 +20,22 @@ #include <utils/threads.h> #include <utils/RefBase.h> #include <utils/KeyedVector.h> #include <utils/Timers.h> #include <android/looper.h> // Currently using poll() instead of epoll_wait() since it does a better job of meeting a // timeout deadline. epoll_wait() typically causes additional delays of up to 10ms // beyond the requested timeout. //#define LOOPER_USES_EPOLL //#define LOOPER_STATISTICS #ifdef LOOPER_USES_EPOLL #include <sys/epoll.h> #else #include <sys/poll.h> #endif /* * Declare a concrete type for the NDK's looper forward declaration. */ Loading Loading @@ -190,13 +203,54 @@ private: const bool mAllowNonCallbacks; // immutable int mEpollFd; // immutable int mWakeReadPipeFd; // immutable int mWakeWritePipeFd; // immutable Mutex mLock; #ifdef LOOPER_USES_EPOLL int mEpollFd; // immutable // Locked list of file descriptor monitoring requests. Mutex mLock; KeyedVector<int, Request> mRequests; KeyedVector<int, Request> mRequests; // guarded by mLock #else // The lock guards state used to track whether there is a poll() in progress and whether // there are any other threads waiting in wakeAndLock(). The condition variables // are used to transfer control among these threads such that all waiters are // serviced before a new poll can begin. // The wakeAndLock() method increments mWaiters, wakes the poll, blocks on mAwake // until mPolling becomes false, then decrements mWaiters again. // The poll() method blocks on mResume until mWaiters becomes 0, then sets // mPolling to true, blocks until the poll completes, then resets mPolling to false // and signals mResume if there are waiters. bool mPolling; // guarded by mLock uint32_t mWaiters; // guarded by mLock Condition mAwake; // guarded by mLock Condition mResume; // guarded by mLock Vector<struct pollfd> mRequestedFds; // must hold mLock and mPolling must be false to modify Vector<Request> mRequests; // must hold mLock and mPolling must be false to modify ssize_t getRequestIndexLocked(int fd); void wakeAndLock(); #endif #ifdef LOOPER_STATISTICS static const int SAMPLED_WAKE_CYCLES_TO_AGGREGATE = 100; static const int SAMPLED_POLLS_TO_AGGREGATE = 1000; nsecs_t mPendingWakeTime; int mPendingWakeCount; int mSampledWakeCycles; int mSampledWakeCountSum; nsecs_t mSampledWakeLatencySum; int mSampledPolls; int mSampledZeroPollCount; int mSampledZeroPollLatencySum; int mSampledTimeoutPollCount; int mSampledTimeoutPollLatencySum; #endif // This state is only used privately by pollOnce and does not require a lock since // it runs on a single thread. Loading @@ -204,6 +258,8 @@ private: size_t mResponseIndex; int pollInner(int timeoutMillis); void awoken(); void pushResponse(int events, const Request& request); static void initTLSKey(); static void threadDestructor(void *st); Loading libs/surfaceflinger_client/Surface.cpp +17 −19 Original line number Diff line number Diff line Loading @@ -454,15 +454,6 @@ void Surface::init() Surface::~Surface() { // this is a client-side operation, the surface is destroyed, unmap // its buffers in this process. size_t size = mBuffers.size(); for (size_t i=0 ; i<size ; i++) { if (mBuffers[i] != 0 && mBuffers[i]->handle != 0) { getBufferMapper().unregisterBuffer(mBuffers[i]->handle); } } // clear all references and trigger an IPC now, to make sure things // happen without delay, since these resources are quite heavy. mBuffers.clear(); Loading Loading @@ -1021,7 +1012,20 @@ void Surface::setSwapRectangle(const Rect& r) { int Surface::getBufferIndex(const sp<GraphicBuffer>& buffer) const { return buffer->getIndex(); int idx = buffer->getIndex(); if (idx < 0) { // The buffer doesn't have an index set. See if the handle the same as // one of the buffers for which we do know the index. This can happen // e.g. if GraphicBuffer is used to wrap an android_native_buffer_t that // was dequeued from an ANativeWindow. for (int i = 0; i < mBuffers.size(); i++) { if (buffer->handle == mBuffers[i]->handle) { idx = mBuffers[i]->getIndex(); break; } } } return idx; } status_t Surface::getBufferLocked(int index, Loading @@ -1035,7 +1039,6 @@ status_t Surface::getBufferLocked(int index, // free the current buffer sp<GraphicBuffer>& currentBuffer(mBuffers.editItemAt(index)); if (currentBuffer != 0) { getBufferMapper().unregisterBuffer(currentBuffer->handle); currentBuffer.clear(); } Loading @@ -1043,7 +1046,7 @@ status_t Surface::getBufferLocked(int index, LOGE_IF(buffer==0, "ISurface::getBuffer(%d, %08x) returned NULL", index, usage); if (buffer != 0) { // this should never happen by construction if (buffer != 0) { // this should always happen by construction LOGE_IF(buffer->handle == NULL, "Surface (identity=%d) requestBuffer(%d, %u, %u, %u, %08x) " "returned a buffer with a null handle", Loading @@ -1051,13 +1054,8 @@ status_t Surface::getBufferLocked(int index, err = mSharedBufferClient->getStatus(); LOGE_IF(err, "Surface (identity=%d) state = %d", mIdentity, err); if (!err && buffer->handle != NULL) { err = getBufferMapper().registerBuffer(buffer->handle); LOGW_IF(err, "registerBuffer(...) failed %d (%s)", err, strerror(-err)); if (err == NO_ERROR) { currentBuffer = buffer; currentBuffer->setIndex(index); } } else { err = err<0 ? err : status_t(NO_MEMORY); } Loading libs/ui/GraphicBuffer.cpp +20 −0 Original line number Diff line number Diff line Loading @@ -77,6 +77,19 @@ GraphicBuffer::GraphicBuffer(uint32_t w, uint32_t h, handle = inHandle; } GraphicBuffer::GraphicBuffer(android_native_buffer_t* buffer, bool keepOwnership) : BASE(), mOwner(keepOwnership ? ownHandle : ownNone), mBufferMapper(GraphicBufferMapper::get()), mInitCheck(NO_ERROR), mIndex(-1), mWrappedBuffer(buffer) { width = buffer->width; height = buffer->height; stride = buffer->stride; format = buffer->format; usage = buffer->usage; handle = buffer->handle; } GraphicBuffer::~GraphicBuffer() { if (handle) { Loading @@ -87,12 +100,14 @@ GraphicBuffer::~GraphicBuffer() void GraphicBuffer::free_handle() { if (mOwner == ownHandle) { mBufferMapper.unregisterBuffer(handle); native_handle_close(handle); native_handle_delete(const_cast<native_handle*>(handle)); } else if (mOwner == ownData) { GraphicBufferAllocator& allocator(GraphicBufferAllocator::get()); allocator.free(handle); } mWrappedBuffer = 0; } status_t GraphicBuffer::initCheck() const { Loading Loading @@ -253,6 +268,11 @@ status_t GraphicBuffer::unflatten(void const* buffer, size_t size, } mOwner = ownHandle; if (handle != 0) { mBufferMapper.registerBuffer(handle); } return NO_ERROR; } Loading libs/ui/InputReader.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -2447,7 +2447,7 @@ void TouchInputMapper::dispatchTouch(nsecs_t when, uint32_t policyFlags, yPrecision = mLocked.orientedYPrecision; } // release lock getDispatcher()->notifyMotion(when, getDeviceId(), AINPUT_SOURCE_TOUCHSCREEN, policyFlags, getDispatcher()->notifyMotion(when, getDeviceId(), getSources(), policyFlags, motionEventAction, 0, getContext()->getGlobalMetaState(), motionEventEdgeFlags, pointerCount, pointerIds, pointerCoords, xPrecision, yPrecision, mDownTime); Loading Loading
include/ui/GraphicBuffer.h +7 −0 Original line number Diff line number Diff line Loading @@ -72,6 +72,9 @@ public: GraphicBuffer(uint32_t w, uint32_t h, PixelFormat format, uint32_t usage, uint32_t stride, native_handle_t* handle, bool keepOwnership); // create a buffer from an existing android_native_buffer_t GraphicBuffer(android_native_buffer_t* buffer, bool keepOwnership); // return status status_t initCheck() const; Loading Loading @@ -137,6 +140,10 @@ private: GraphicBufferMapper& mBufferMapper; ssize_t mInitCheck; int mIndex; // If we're wrapping another buffer then this reference will make sure it // doesn't get freed. sp<android_native_buffer_t> mWrappedBuffer; }; }; // namespace android Loading
include/utils/Looper.h +59 −3 Original line number Diff line number Diff line Loading @@ -20,9 +20,22 @@ #include <utils/threads.h> #include <utils/RefBase.h> #include <utils/KeyedVector.h> #include <utils/Timers.h> #include <android/looper.h> // Currently using poll() instead of epoll_wait() since it does a better job of meeting a // timeout deadline. epoll_wait() typically causes additional delays of up to 10ms // beyond the requested timeout. //#define LOOPER_USES_EPOLL //#define LOOPER_STATISTICS #ifdef LOOPER_USES_EPOLL #include <sys/epoll.h> #else #include <sys/poll.h> #endif /* * Declare a concrete type for the NDK's looper forward declaration. */ Loading Loading @@ -190,13 +203,54 @@ private: const bool mAllowNonCallbacks; // immutable int mEpollFd; // immutable int mWakeReadPipeFd; // immutable int mWakeWritePipeFd; // immutable Mutex mLock; #ifdef LOOPER_USES_EPOLL int mEpollFd; // immutable // Locked list of file descriptor monitoring requests. Mutex mLock; KeyedVector<int, Request> mRequests; KeyedVector<int, Request> mRequests; // guarded by mLock #else // The lock guards state used to track whether there is a poll() in progress and whether // there are any other threads waiting in wakeAndLock(). The condition variables // are used to transfer control among these threads such that all waiters are // serviced before a new poll can begin. // The wakeAndLock() method increments mWaiters, wakes the poll, blocks on mAwake // until mPolling becomes false, then decrements mWaiters again. // The poll() method blocks on mResume until mWaiters becomes 0, then sets // mPolling to true, blocks until the poll completes, then resets mPolling to false // and signals mResume if there are waiters. bool mPolling; // guarded by mLock uint32_t mWaiters; // guarded by mLock Condition mAwake; // guarded by mLock Condition mResume; // guarded by mLock Vector<struct pollfd> mRequestedFds; // must hold mLock and mPolling must be false to modify Vector<Request> mRequests; // must hold mLock and mPolling must be false to modify ssize_t getRequestIndexLocked(int fd); void wakeAndLock(); #endif #ifdef LOOPER_STATISTICS static const int SAMPLED_WAKE_CYCLES_TO_AGGREGATE = 100; static const int SAMPLED_POLLS_TO_AGGREGATE = 1000; nsecs_t mPendingWakeTime; int mPendingWakeCount; int mSampledWakeCycles; int mSampledWakeCountSum; nsecs_t mSampledWakeLatencySum; int mSampledPolls; int mSampledZeroPollCount; int mSampledZeroPollLatencySum; int mSampledTimeoutPollCount; int mSampledTimeoutPollLatencySum; #endif // This state is only used privately by pollOnce and does not require a lock since // it runs on a single thread. Loading @@ -204,6 +258,8 @@ private: size_t mResponseIndex; int pollInner(int timeoutMillis); void awoken(); void pushResponse(int events, const Request& request); static void initTLSKey(); static void threadDestructor(void *st); Loading
libs/surfaceflinger_client/Surface.cpp +17 −19 Original line number Diff line number Diff line Loading @@ -454,15 +454,6 @@ void Surface::init() Surface::~Surface() { // this is a client-side operation, the surface is destroyed, unmap // its buffers in this process. size_t size = mBuffers.size(); for (size_t i=0 ; i<size ; i++) { if (mBuffers[i] != 0 && mBuffers[i]->handle != 0) { getBufferMapper().unregisterBuffer(mBuffers[i]->handle); } } // clear all references and trigger an IPC now, to make sure things // happen without delay, since these resources are quite heavy. mBuffers.clear(); Loading Loading @@ -1021,7 +1012,20 @@ void Surface::setSwapRectangle(const Rect& r) { int Surface::getBufferIndex(const sp<GraphicBuffer>& buffer) const { return buffer->getIndex(); int idx = buffer->getIndex(); if (idx < 0) { // The buffer doesn't have an index set. See if the handle the same as // one of the buffers for which we do know the index. This can happen // e.g. if GraphicBuffer is used to wrap an android_native_buffer_t that // was dequeued from an ANativeWindow. for (int i = 0; i < mBuffers.size(); i++) { if (buffer->handle == mBuffers[i]->handle) { idx = mBuffers[i]->getIndex(); break; } } } return idx; } status_t Surface::getBufferLocked(int index, Loading @@ -1035,7 +1039,6 @@ status_t Surface::getBufferLocked(int index, // free the current buffer sp<GraphicBuffer>& currentBuffer(mBuffers.editItemAt(index)); if (currentBuffer != 0) { getBufferMapper().unregisterBuffer(currentBuffer->handle); currentBuffer.clear(); } Loading @@ -1043,7 +1046,7 @@ status_t Surface::getBufferLocked(int index, LOGE_IF(buffer==0, "ISurface::getBuffer(%d, %08x) returned NULL", index, usage); if (buffer != 0) { // this should never happen by construction if (buffer != 0) { // this should always happen by construction LOGE_IF(buffer->handle == NULL, "Surface (identity=%d) requestBuffer(%d, %u, %u, %u, %08x) " "returned a buffer with a null handle", Loading @@ -1051,13 +1054,8 @@ status_t Surface::getBufferLocked(int index, err = mSharedBufferClient->getStatus(); LOGE_IF(err, "Surface (identity=%d) state = %d", mIdentity, err); if (!err && buffer->handle != NULL) { err = getBufferMapper().registerBuffer(buffer->handle); LOGW_IF(err, "registerBuffer(...) failed %d (%s)", err, strerror(-err)); if (err == NO_ERROR) { currentBuffer = buffer; currentBuffer->setIndex(index); } } else { err = err<0 ? err : status_t(NO_MEMORY); } Loading
libs/ui/GraphicBuffer.cpp +20 −0 Original line number Diff line number Diff line Loading @@ -77,6 +77,19 @@ GraphicBuffer::GraphicBuffer(uint32_t w, uint32_t h, handle = inHandle; } GraphicBuffer::GraphicBuffer(android_native_buffer_t* buffer, bool keepOwnership) : BASE(), mOwner(keepOwnership ? ownHandle : ownNone), mBufferMapper(GraphicBufferMapper::get()), mInitCheck(NO_ERROR), mIndex(-1), mWrappedBuffer(buffer) { width = buffer->width; height = buffer->height; stride = buffer->stride; format = buffer->format; usage = buffer->usage; handle = buffer->handle; } GraphicBuffer::~GraphicBuffer() { if (handle) { Loading @@ -87,12 +100,14 @@ GraphicBuffer::~GraphicBuffer() void GraphicBuffer::free_handle() { if (mOwner == ownHandle) { mBufferMapper.unregisterBuffer(handle); native_handle_close(handle); native_handle_delete(const_cast<native_handle*>(handle)); } else if (mOwner == ownData) { GraphicBufferAllocator& allocator(GraphicBufferAllocator::get()); allocator.free(handle); } mWrappedBuffer = 0; } status_t GraphicBuffer::initCheck() const { Loading Loading @@ -253,6 +268,11 @@ status_t GraphicBuffer::unflatten(void const* buffer, size_t size, } mOwner = ownHandle; if (handle != 0) { mBufferMapper.registerBuffer(handle); } return NO_ERROR; } Loading
libs/ui/InputReader.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -2447,7 +2447,7 @@ void TouchInputMapper::dispatchTouch(nsecs_t when, uint32_t policyFlags, yPrecision = mLocked.orientedYPrecision; } // release lock getDispatcher()->notifyMotion(when, getDeviceId(), AINPUT_SOURCE_TOUCHSCREEN, policyFlags, getDispatcher()->notifyMotion(when, getDeviceId(), getSources(), policyFlags, motionEventAction, 0, getContext()->getGlobalMetaState(), motionEventEdgeFlags, pointerCount, pointerIds, pointerCoords, xPrecision, yPrecision, mDownTime); Loading