Loading libs/gui/Surface.cpp +83 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,11 @@ #include <gui/Surface.h> #include <condition_variable> #include <deque> #include <mutex> #include <thread> #include <inttypes.h> #include <android/native_window.h> Loading Loading @@ -450,6 +455,74 @@ int Surface::setSwapInterval(int interval) { return NO_ERROR; } class FenceMonitor { public: explicit FenceMonitor(const char* name) : mName(name), mFencesQueued(0), mFencesSignaled(0) { std::thread thread(&FenceMonitor::loop, this); pthread_setname_np(thread.native_handle(), mName); thread.detach(); } void queueFence(const sp<Fence>& fence) { char message[64]; std::lock_guard<std::mutex> lock(mMutex); snprintf(message, sizeof(message), "Trace fence %u", mFencesQueued); ATRACE_NAME(message); mQueue.push_back(fence); mCondition.notify_one(); mFencesQueued++; ATRACE_INT(mName, int32_t(mQueue.size())); } private: #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wmissing-noreturn" void loop() { while (true) { threadLoop(); } } #pragma clang diagnostic pop void threadLoop() { sp<Fence> fence; uint32_t fenceNum; { std::unique_lock<std::mutex> lock(mMutex); while (mQueue.empty()) { mCondition.wait(lock); } fence = mQueue[0]; fenceNum = mFencesSignaled; } { char message[64]; snprintf(message, sizeof(message), "waiting for %s %u", mName, fenceNum); ATRACE_NAME(message); status_t result = fence->waitForever(message); if (result != OK) { ALOGE("Error waiting for fence: %d", result); } } { std::lock_guard<std::mutex> lock(mMutex); mQueue.pop_front(); mFencesSignaled++; ATRACE_INT(mName, int32_t(mQueue.size())); } } const char* mName; uint32_t mFencesQueued; uint32_t mFencesSignaled; std::deque<sp<Fence>> mQueue; std::condition_variable mCondition; std::mutex mMutex; }; int Surface::dequeueBuffer(android_native_buffer_t** buffer, int* fenceFd) { ATRACE_CALL(); ALOGV("Surface::dequeueBuffer"); Loading Loading @@ -519,6 +592,11 @@ int Surface::dequeueBuffer(android_native_buffer_t** buffer, int* fenceFd) { // this should never happen ALOGE_IF(fence == nullptr, "Surface::dequeueBuffer: received null Fence! buf=%d", buf); if (CC_UNLIKELY(atrace_is_tag_enabled(ATRACE_TAG_GRAPHICS))) { static FenceMonitor hwcReleaseThread("HWC release"); hwcReleaseThread.queueFence(fence); } if (result & IGraphicBufferProducer::RELEASE_ALL_BUFFERS) { freeAllBuffers(); } Loading Loading @@ -761,6 +839,11 @@ int Surface::queueBuffer(android_native_buffer_t* buffer, int fenceFd) { mQueueBufferCondition.broadcast(); if (CC_UNLIKELY(atrace_is_tag_enabled(ATRACE_TAG_GRAPHICS))) { static FenceMonitor gpuCompletionThread("GPU completion"); gpuCompletionThread.queueFence(fence); } return err; } Loading Loading
libs/gui/Surface.cpp +83 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,11 @@ #include <gui/Surface.h> #include <condition_variable> #include <deque> #include <mutex> #include <thread> #include <inttypes.h> #include <android/native_window.h> Loading Loading @@ -450,6 +455,74 @@ int Surface::setSwapInterval(int interval) { return NO_ERROR; } class FenceMonitor { public: explicit FenceMonitor(const char* name) : mName(name), mFencesQueued(0), mFencesSignaled(0) { std::thread thread(&FenceMonitor::loop, this); pthread_setname_np(thread.native_handle(), mName); thread.detach(); } void queueFence(const sp<Fence>& fence) { char message[64]; std::lock_guard<std::mutex> lock(mMutex); snprintf(message, sizeof(message), "Trace fence %u", mFencesQueued); ATRACE_NAME(message); mQueue.push_back(fence); mCondition.notify_one(); mFencesQueued++; ATRACE_INT(mName, int32_t(mQueue.size())); } private: #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wmissing-noreturn" void loop() { while (true) { threadLoop(); } } #pragma clang diagnostic pop void threadLoop() { sp<Fence> fence; uint32_t fenceNum; { std::unique_lock<std::mutex> lock(mMutex); while (mQueue.empty()) { mCondition.wait(lock); } fence = mQueue[0]; fenceNum = mFencesSignaled; } { char message[64]; snprintf(message, sizeof(message), "waiting for %s %u", mName, fenceNum); ATRACE_NAME(message); status_t result = fence->waitForever(message); if (result != OK) { ALOGE("Error waiting for fence: %d", result); } } { std::lock_guard<std::mutex> lock(mMutex); mQueue.pop_front(); mFencesSignaled++; ATRACE_INT(mName, int32_t(mQueue.size())); } } const char* mName; uint32_t mFencesQueued; uint32_t mFencesSignaled; std::deque<sp<Fence>> mQueue; std::condition_variable mCondition; std::mutex mMutex; }; int Surface::dequeueBuffer(android_native_buffer_t** buffer, int* fenceFd) { ATRACE_CALL(); ALOGV("Surface::dequeueBuffer"); Loading Loading @@ -519,6 +592,11 @@ int Surface::dequeueBuffer(android_native_buffer_t** buffer, int* fenceFd) { // this should never happen ALOGE_IF(fence == nullptr, "Surface::dequeueBuffer: received null Fence! buf=%d", buf); if (CC_UNLIKELY(atrace_is_tag_enabled(ATRACE_TAG_GRAPHICS))) { static FenceMonitor hwcReleaseThread("HWC release"); hwcReleaseThread.queueFence(fence); } if (result & IGraphicBufferProducer::RELEASE_ALL_BUFFERS) { freeAllBuffers(); } Loading Loading @@ -761,6 +839,11 @@ int Surface::queueBuffer(android_native_buffer_t* buffer, int fenceFd) { mQueueBufferCondition.broadcast(); if (CC_UNLIKELY(atrace_is_tag_enabled(ATRACE_TAG_GRAPHICS))) { static FenceMonitor gpuCompletionThread("GPU completion"); gpuCompletionThread.queueFence(fence); } return err; } Loading