diff options
author | 2016-07-29 10:08:16 -0700 | |
---|---|---|
committer | 2016-07-29 10:08:16 -0700 | |
commit | fb5c675b7e1fee074f19cf1866b5dda0785dbe64 (patch) | |
tree | 54c983e39ad8a3ee94062b8c509054ba87c9c81d /libs/hwui | |
parent | 942ad98481be73e1f4efe0e6837d8930ec4d9d6b (diff) | |
parent | 67daab6a1e0897cd0528a19071eeb9f4a2b00b49 (diff) |
resolve merge conflicts of 67daab6 to nyc-mr1-dev-plus-aosp
Change-Id: I35f867b8d6408a7eae9cf5643f0908259de90cb1
Diffstat (limited to 'libs/hwui')
-rw-r--r-- | libs/hwui/Android.mk | 4 | ||||
-rw-r--r-- | libs/hwui/FrameInfo.cpp | 6 | ||||
-rw-r--r-- | libs/hwui/FrameInfo.h | 3 | ||||
-rw-r--r-- | libs/hwui/JankTracker.cpp | 32 | ||||
-rw-r--r-- | libs/hwui/JankTracker.h | 11 | ||||
-rw-r--r-- | libs/hwui/renderthread/CanvasContext.cpp | 16 | ||||
-rw-r--r-- | libs/hwui/renderthread/RenderThread.cpp | 2 | ||||
-rw-r--r-- | libs/hwui/utils/TimeUtils.h | 8 |
8 files changed, 73 insertions, 9 deletions
diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk index 5dcfa4e102fd..50801a4702d9 100644 --- a/libs/hwui/Android.mk +++ b/libs/hwui/Android.mk @@ -113,6 +113,10 @@ hwui_cflags := \ -DATRACE_TAG=ATRACE_TAG_VIEW -DLOG_TAG=\"OpenGLRenderer\" \ -Wall -Wno-unused-parameter -Wunreachable-code -Werror +ifeq ($(TARGET_USES_HWC2),true) + hwui_cflags += -DUSE_HWC2 +endif + # GCC false-positives on this warning, and since we -Werror that's # a problem hwui_cflags += -Wno-free-nonheap-object diff --git a/libs/hwui/FrameInfo.cpp b/libs/hwui/FrameInfo.cpp index 41e22332d8ed..09b3945c7f55 100644 --- a/libs/hwui/FrameInfo.cpp +++ b/libs/hwui/FrameInfo.cpp @@ -35,8 +35,14 @@ const std::string FrameInfoNames[] = { "IssueDrawCommandsStart", "SwapBuffers", "FrameCompleted", + "DequeueBufferDuration", + "QueueBufferDuration", }; +static_assert((sizeof(FrameInfoNames)/sizeof(FrameInfoNames[0])) + == static_cast<int>(FrameInfoIndex::NumIndexes), + "size mismatch: FrameInfoNames doesn't match the enum!"); + void FrameInfo::importUiThreadInfo(int64_t* info) { memcpy(mFrameInfo, info, UI_THREAD_FRAME_INFO_SIZE * sizeof(int64_t)); } diff --git a/libs/hwui/FrameInfo.h b/libs/hwui/FrameInfo.h index afab84c3542c..993b158526b5 100644 --- a/libs/hwui/FrameInfo.h +++ b/libs/hwui/FrameInfo.h @@ -48,6 +48,9 @@ enum class FrameInfoIndex { SwapBuffers, FrameCompleted, + DequeueBufferDuration, + QueueBufferDuration, + // Must be the last value! NumIndexes }; diff --git a/libs/hwui/JankTracker.cpp b/libs/hwui/JankTracker.cpp index ebe9c4240221..ed6b211eef1b 100644 --- a/libs/hwui/JankTracker.cpp +++ b/libs/hwui/JankTracker.cpp @@ -16,6 +16,7 @@ #include "JankTracker.h" #include "Properties.h" +#include "utils/TimeUtils.h" #include <algorithm> #include <cutils/ashmem.h> @@ -119,11 +120,27 @@ static uint32_t frameTimeForFrameCountIndex(uint32_t index) { return index; } -JankTracker::JankTracker(nsecs_t frameIntervalNanos) { +JankTracker::JankTracker(const DisplayInfo& displayInfo) { // By default this will use malloc memory. It may be moved later to ashmem // if there is shared space for it and a request comes in to do that. mData = new ProfileData; reset(); + nsecs_t frameIntervalNanos = static_cast<nsecs_t>(1_s / displayInfo.fps); +#if USE_HWC2 + nsecs_t sfOffset = frameIntervalNanos - (displayInfo.presentationDeadline - 1_ms); + nsecs_t offsetDelta = sfOffset - displayInfo.appVsyncOffset; + // There are two different offset cases. If the offsetDelta is positive + // and small, then the intention is to give apps extra time by leveraging + // pipelining between the UI & RT threads. If the offsetDelta is large or + // negative, the intention is to subtract time from the total duration + // in which case we can't afford to wait for dequeueBuffer blockage. + if (offsetDelta <= 4_ms && offsetDelta >= 0) { + // SF will begin composition at VSYNC-app + offsetDelta. If we are triple + // buffered, this is the expected time at which dequeueBuffer will + // return due to the staggering of VSYNC-app & VSYNC-sf. + mDequeueTimeForgiveness = offsetDelta + 4_ms; + } +#endif setFrameInterval(frameIntervalNanos); } @@ -213,6 +230,19 @@ void JankTracker::addFrame(const FrameInfo& frame) { mData->totalFrameCount++; // Fast-path for jank-free frames int64_t totalDuration = frame.duration(sFrameStart, FrameInfoIndex::FrameCompleted); + if (mDequeueTimeForgiveness + && frame[FrameInfoIndex::DequeueBufferDuration] > 500_us) { + nsecs_t expectedDequeueDuration = + mDequeueTimeForgiveness + frame[FrameInfoIndex::Vsync] + - frame[FrameInfoIndex::IssueDrawCommandsStart]; + if (expectedDequeueDuration > 0) { + // Forgive only up to the expected amount, but not more than + // the actual time spent blocked. + nsecs_t forgiveAmount = std::min(expectedDequeueDuration, + frame[FrameInfoIndex::DequeueBufferDuration]); + totalDuration -= forgiveAmount; + } + } uint32_t framebucket = frameCountIndexForFrameTime(totalDuration); // Keep the fast path as fast as possible. if (CC_LIKELY(totalDuration < mFrameInterval)) { diff --git a/libs/hwui/JankTracker.h b/libs/hwui/JankTracker.h index a23dd7807169..8b482d5a804d 100644 --- a/libs/hwui/JankTracker.h +++ b/libs/hwui/JankTracker.h @@ -21,6 +21,7 @@ #include "utils/RingBuffer.h" #include <cutils/compiler.h> +#include <ui/DisplayInfo.h> #include <array> #include <memory> @@ -56,7 +57,7 @@ struct ProfileData { // TODO: Replace DrawProfiler with this class JankTracker { public: - explicit JankTracker(nsecs_t frameIntervalNanos); + explicit JankTracker(const DisplayInfo& displayInfo); ~JankTracker(); void addFrame(const FrameInfo& frame); @@ -79,6 +80,14 @@ private: std::array<int64_t, NUM_BUCKETS> mThresholds; int64_t mFrameInterval; + // The amount of time we will erase from the total duration to account + // for SF vsync offsets with HWC2 blocking dequeueBuffers. + // (Vsync + mDequeueBlockTolerance) is the point at which we expect + // SF to have released the buffer normally, so we will forgive up to that + // point in time by comparing to (IssueDrawCommandsStart + DequeueDuration) + // This is only used if we are in pipelined mode and are using HWC2, + // otherwise it's 0. + nsecs_t mDequeueTimeForgiveness = 0; ProfileData* mData; bool mIsMapped = false; }; diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp index 82684c5f86ff..d68f0e383152 100644 --- a/libs/hwui/renderthread/CanvasContext.cpp +++ b/libs/hwui/renderthread/CanvasContext.cpp @@ -67,7 +67,7 @@ CanvasContext::CanvasContext(RenderThread& thread, bool translucent, , mEglManager(thread.eglManager()) , mOpaque(!translucent) , mAnimationContext(contextFactory->createAnimationContext(mRenderThread.timeLord())) - , mJankTracker(thread.timeLord().frameIntervalNanos()) + , mJankTracker(thread.mainDisplayInfo()) , mProfiler(mFrames) , mContentDrawBounds(0, 0, 0, 0) { mRenderNodes.emplace_back(rootRenderNode); @@ -286,11 +286,6 @@ void CanvasContext::prepareTree(TreeInfo& info, int64_t* uiFrameInfo, if (CC_LIKELY(mSwapHistory.size())) { nsecs_t latestVsync = mRenderThread.timeLord().latestVsync(); SwapHistory& lastSwap = mSwapHistory.back(); - int durationUs; - mNativeSurface->query(NATIVE_WINDOW_LAST_DEQUEUE_DURATION, &durationUs); - lastSwap.dequeueDuration = us2ns(durationUs); - mNativeSurface->query(NATIVE_WINDOW_LAST_QUEUE_DURATION, &durationUs); - lastSwap.queueDuration = us2ns(durationUs); nsecs_t vsyncDelta = std::abs(lastSwap.vsyncTime - latestVsync); // The slight fudge-factor is to deal with cases where // the vsync was estimated due to being slow handling the signal. @@ -567,6 +562,15 @@ void CanvasContext::draw() { swap.damage = screenDirty; swap.swapCompletedTime = systemTime(CLOCK_MONOTONIC); swap.vsyncTime = mRenderThread.timeLord().latestVsync(); + int durationUs; + mNativeSurface->query(NATIVE_WINDOW_LAST_DEQUEUE_DURATION, &durationUs); + swap.dequeueDuration = us2ns(durationUs); + mNativeSurface->query(NATIVE_WINDOW_LAST_QUEUE_DURATION, &durationUs); + swap.queueDuration = us2ns(durationUs); + mCurrentFrameInfo->set(FrameInfoIndex::DequeueBufferDuration) + = swap.dequeueDuration; + mCurrentFrameInfo->set(FrameInfoIndex::QueueBufferDuration) + = swap.queueDuration; mHaveNewSurface = false; mFrameNumber = -1; } diff --git a/libs/hwui/renderthread/RenderThread.cpp b/libs/hwui/renderthread/RenderThread.cpp index 3c1c0bceba58..968834056ae1 100644 --- a/libs/hwui/renderthread/RenderThread.cpp +++ b/libs/hwui/renderthread/RenderThread.cpp @@ -190,7 +190,7 @@ void RenderThread::initThreadLocals() { initializeDisplayEventReceiver(); mEglManager = new EglManager(*this); mRenderState = new RenderState(*this); - mJankTracker = new JankTracker(frameIntervalNanos); + mJankTracker = new JankTracker(mDisplayInfo); } int RenderThread::displayEventReceiverCallback(int fd, int events, void* data) { diff --git a/libs/hwui/utils/TimeUtils.h b/libs/hwui/utils/TimeUtils.h index 8d42d7e55521..ce181b766841 100644 --- a/libs/hwui/utils/TimeUtils.h +++ b/libs/hwui/utils/TimeUtils.h @@ -21,10 +21,18 @@ namespace android { namespace uirenderer { +constexpr nsecs_t operator"" _s (unsigned long long s) { + return seconds_to_nanoseconds(s); +} + constexpr nsecs_t operator"" _ms (unsigned long long ms) { return milliseconds_to_nanoseconds(ms); } +constexpr nsecs_t operator"" _us (unsigned long long us) { + return microseconds_to_nanoseconds(us); +} + } /* namespace uirenderer */ } /* namespace android */ |