diff options
| author | 2015-05-14 01:05:47 +0000 | |
|---|---|---|
| committer | 2015-05-14 01:05:47 +0000 | |
| commit | 951f23478d79fb232e93a750d9050adce7a67874 (patch) | |
| tree | 31808b394dfa8d25b385e296845beef215321781 /libs | |
| parent | e869835d6a884434842838fce6d17c770fa1ef8b (diff) | |
| parent | d955dceb4f38f214e62024e808b2b1a21be41940 (diff) | |
am d955dceb: am 862540cd: Merge "Revert "DO NOT MERGE Backport of limited jank-tracking metrics"" into lmp-mr1-dev
* commit 'd955dceb4f38f214e62024e808b2b1a21be41940':
Revert "DO NOT MERGE Backport of limited jank-tracking metrics"
Diffstat (limited to 'libs')
| -rw-r--r-- | libs/hwui/Android.mk | 2 | ||||
| -rw-r--r-- | libs/hwui/FrameInfo.cpp | 28 | ||||
| -rw-r--r-- | libs/hwui/FrameInfo.h | 116 | ||||
| -rw-r--r-- | libs/hwui/JankTracker.cpp | 159 | ||||
| -rw-r--r-- | libs/hwui/JankTracker.h | 71 | ||||
| -rw-r--r-- | libs/hwui/renderthread/CanvasContext.cpp | 46 | ||||
| -rw-r--r-- | libs/hwui/renderthread/CanvasContext.h | 26 | ||||
| -rw-r--r-- | libs/hwui/renderthread/DrawFrameTask.cpp | 16 | ||||
| -rw-r--r-- | libs/hwui/renderthread/DrawFrameTask.h | 9 | ||||
| -rw-r--r-- | libs/hwui/renderthread/RenderProxy.cpp | 52 | ||||
| -rw-r--r-- | libs/hwui/renderthread/RenderProxy.h | 8 | ||||
| -rw-r--r-- | libs/hwui/renderthread/RenderThread.cpp | 9 | ||||
| -rw-r--r-- | libs/hwui/renderthread/RenderThread.h | 12 | ||||
| -rw-r--r-- | libs/hwui/renderthread/TimeLord.cpp | 8 | ||||
| -rw-r--r-- | libs/hwui/renderthread/TimeLord.h | 4 | ||||
| -rw-r--r-- | libs/hwui/tests/main.cpp | 5 | ||||
| -rw-r--r-- | libs/hwui/utils/Macros.h | 8 | ||||
| -rw-r--r-- | libs/hwui/utils/RingBuffer.h | 71 |
18 files changed, 58 insertions, 592 deletions
diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk index 507472aa61a8..49560ffdd628 100644 --- a/libs/hwui/Android.mk +++ b/libs/hwui/Android.mk @@ -18,7 +18,6 @@ ifeq ($(USE_OPENGL_RENDERER),true) AssetAtlas.cpp \ DamageAccumulator.cpp \ FontRenderer.cpp \ - FrameInfo.cpp \ GammaFontRenderer.cpp \ Caches.cpp \ DisplayList.cpp \ @@ -33,7 +32,6 @@ ifeq ($(USE_OPENGL_RENDERER),true) GradientCache.cpp \ Image.cpp \ Interpolator.cpp \ - JankTracker.cpp \ Layer.cpp \ LayerCache.cpp \ LayerRenderer.cpp \ diff --git a/libs/hwui/FrameInfo.cpp b/libs/hwui/FrameInfo.cpp deleted file mode 100644 index 6da1fa808d0a..000000000000 --- a/libs/hwui/FrameInfo.cpp +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include "FrameInfo.h" - -#include <cstring> - -namespace android { -namespace uirenderer { - -void FrameInfo::importUiThreadInfo(int64_t* info) { - memcpy(mFrameInfo, info, UI_THREAD_FRAME_INFO_SIZE * sizeof(int64_t)); -} - -} /* namespace uirenderer */ -} /* namespace android */ diff --git a/libs/hwui/FrameInfo.h b/libs/hwui/FrameInfo.h deleted file mode 100644 index 3c3167721d2b..000000000000 --- a/libs/hwui/FrameInfo.h +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef FRAMEINFO_H_ -#define FRAMEINFO_H_ - -#include "utils/Macros.h" - -#include <cutils/compiler.h> -#include <utils/Timers.h> - -#include <memory.h> - -namespace android { -namespace uirenderer { - -#define UI_THREAD_FRAME_INFO_SIZE 9 - -HWUI_ENUM(FrameInfoIndex, - kFlags = 0, - kIntendedVsync, - kVsync, - kOldestInputEvent, - kNewestInputEvent, - kHandleInputStart, - kAnimationStart, - kPerformTraversalsStart, - kDrawStart, - // End of UI frame info - - kSyncStart, - kIssueDrawCommandsStart, - kSwapBuffers, - kFrameCompleted, - - // Must be the last value! - kNumIndexes -); - -HWUI_ENUM(FrameInfoFlags, - kWindowLayoutChanged = 1 << 0, - kRTAnimation = 1 << 1, - kSurfaceCanvas = 1 << 2, -); - -class ANDROID_API UiFrameInfoBuilder { -public: - UiFrameInfoBuilder(int64_t* buffer) : mBuffer(buffer) { - memset(mBuffer, 0, UI_THREAD_FRAME_INFO_SIZE * sizeof(int64_t)); - } - - UiFrameInfoBuilder& setVsync(nsecs_t vsyncTime, nsecs_t intendedVsync) { - mBuffer[FrameInfoIndex::kVsync] = vsyncTime; - mBuffer[FrameInfoIndex::kIntendedVsync] = intendedVsync; - return *this; - } - - UiFrameInfoBuilder& addFlag(FrameInfoFlagsEnum flag) { - mBuffer[FrameInfoIndex::kFlags] |= static_cast<uint64_t>(flag); - return *this; - } - -private: - int64_t* mBuffer; -}; - -class FrameInfo { -public: - void importUiThreadInfo(int64_t* info); - - void markSyncStart() { - mFrameInfo[FrameInfoIndex::kSyncStart] = systemTime(CLOCK_MONOTONIC); - } - - void markIssueDrawCommandsStart() { - mFrameInfo[FrameInfoIndex::kIssueDrawCommandsStart] = systemTime(CLOCK_MONOTONIC); - } - - void markSwapBuffers() { - mFrameInfo[FrameInfoIndex::kSwapBuffers] = systemTime(CLOCK_MONOTONIC); - } - - void markFrameCompleted() { - mFrameInfo[FrameInfoIndex::kFrameCompleted] = systemTime(CLOCK_MONOTONIC); - } - - int64_t operator[](FrameInfoIndexEnum index) const { - if (index == FrameInfoIndex::kNumIndexes) return 0; - return mFrameInfo[static_cast<int>(index)]; - } - - int64_t operator[](int index) const { - if (index < 0 || index >= FrameInfoIndex::kNumIndexes) return 0; - return mFrameInfo[static_cast<int>(index)]; - } - -private: - int64_t mFrameInfo[FrameInfoIndex::kNumIndexes]; -}; - -} /* namespace uirenderer */ -} /* namespace android */ - -#endif /* FRAMEINFO_H_ */ diff --git a/libs/hwui/JankTracker.cpp b/libs/hwui/JankTracker.cpp deleted file mode 100644 index f7c81953b67b..000000000000 --- a/libs/hwui/JankTracker.cpp +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include "JankTracker.h" - -#include <algorithm> -#include <cstdio> -#include <inttypes.h> - -namespace android { -namespace uirenderer { - -static const char* JANK_TYPE_NAMES[] = { - "Missed Vsync", - "High input latency", - "Slow UI thread", - "Slow bitmap uploads", - "Slow draw", -}; - -struct Comparison { - FrameInfoIndexEnum start; - FrameInfoIndexEnum end; -}; - -static const Comparison COMPARISONS[] = { - {FrameInfoIndex::kIntendedVsync, FrameInfoIndex::kVsync}, - {FrameInfoIndex::kOldestInputEvent, FrameInfoIndex::kVsync}, - {FrameInfoIndex::kVsync, FrameInfoIndex::kSyncStart}, - {FrameInfoIndex::kSyncStart, FrameInfoIndex::kIssueDrawCommandsStart}, - {FrameInfoIndex::kIssueDrawCommandsStart, FrameInfoIndex::kFrameCompleted}, -}; - -// If the event exceeds 10 seconds throw it away, this isn't a jank event -// it's an ANR and will be handled as such -static const int64_t IGNORE_EXCEEDING = seconds_to_nanoseconds(10); - -/* - * Frames that are exempt from jank metrics. - * First-draw frames, for example, are expected to - * be slow, this is hidden from the user with window animations and - * other tricks - * - * Similarly, we don't track direct-drawing via Surface:lockHardwareCanvas() - * for now - * - * TODO: kSurfaceCanvas can negatively impact other drawing by using up - * time on the RenderThread, figure out how to attribute that as a jank-causer - */ -static const int64_t EXEMPT_FRAMES_FLAGS - = FrameInfoFlags::kWindowLayoutChanged - | FrameInfoFlags::kSurfaceCanvas; - -JankTracker::JankTracker(nsecs_t frameIntervalNanos) { - reset(); - setFrameInterval(frameIntervalNanos); -} - -void JankTracker::setFrameInterval(nsecs_t frameInterval) { - mFrameInterval = frameInterval; - mThresholds[kMissedVsync] = 1; - /* - * Due to interpolation and sample rate differences between the touch - * panel and the display (example, 85hz touch panel driving a 60hz display) - * we call high latency 1.5 * frameinterval - * - * NOTE: Be careful when tuning this! A theoretical 1,000hz touch panel - * on a 60hz display will show kOldestInputEvent - kIntendedVsync of being 15ms - * Thus this must always be larger than frameInterval, or it will fail - */ - mThresholds[kHighInputLatency] = static_cast<int64_t>(1.5 * frameInterval); - - // Note that these do not add up to 1. This is intentional. It's to deal - // with variance in values, and should be sort of an upper-bound on what - // is reasonable to expect. - mThresholds[kSlowUI] = static_cast<int64_t>(.5 * frameInterval); - mThresholds[kSlowSync] = static_cast<int64_t>(.2 * frameInterval); - mThresholds[kSlowRT] = static_cast<int64_t>(.75 * frameInterval); - -} - -void JankTracker::addFrame(const FrameInfo& frame) { - using namespace FrameInfoIndex; - mTotalFrameCount++; - // Fast-path for jank-free frames - int64_t totalDuration = frame[kFrameCompleted] - frame[kIntendedVsync]; - uint32_t framebucket = std::min( - static_cast<typeof sizeof(mFrameCounts)>(ns2ms(totalDuration)), - sizeof(mFrameCounts) / sizeof(mFrameCounts[0])); - // Keep the fast path as fast as possible. - if (CC_LIKELY(totalDuration < mFrameInterval)) { - mFrameCounts[framebucket]++; - return; - } - - if (frame[kFlags] & EXEMPT_FRAMES_FLAGS) { - return; - } - - mFrameCounts[framebucket]++; - mJankFrameCount++; - - for (int i = 0; i < NUM_BUCKETS; i++) { - int64_t delta = frame[COMPARISONS[i].end] - frame[COMPARISONS[i].start]; - if (delta >= mThresholds[i] && delta < IGNORE_EXCEEDING) { - mBuckets[i].count++; - } - } -} - -void JankTracker::dump(int fd) { - FILE* file = fdopen(fd, "a"); - fprintf(file, "\nFrame stats:"); - fprintf(file, "\n Total frames rendered: %u", mTotalFrameCount); - fprintf(file, "\n Janky frames: %u (%.2f%%)", mJankFrameCount, - (float) mJankFrameCount / (float) mTotalFrameCount * 100.0f); - fprintf(file, "\n 90th percentile: %ums", findPercentile(90)); - fprintf(file, "\n 95th percentile: %ums", findPercentile(95)); - fprintf(file, "\n 99th percentile: %ums", findPercentile(99)); - for (int i = 0; i < NUM_BUCKETS; i++) { - fprintf(file, "\n Number %s: %u", JANK_TYPE_NAMES[i], mBuckets[i].count); - } - fprintf(file, "\n"); - fflush(file); -} - -void JankTracker::reset() { - memset(mBuckets, 0, sizeof(mBuckets)); - memset(mFrameCounts, 0, sizeof(mFrameCounts)); - mTotalFrameCount = 0; - mJankFrameCount = 0; -} - -uint32_t JankTracker::findPercentile(int percentile) { - int pos = percentile * mTotalFrameCount / 100; - int remaining = mTotalFrameCount - pos; - for (int i = sizeof(mFrameCounts) / sizeof(mFrameCounts[0]) - 1; i >= 0; i--) { - remaining -= mFrameCounts[i]; - if (remaining <= 0) { - return i; - } - } - return 0; -} - -} /* namespace uirenderer */ -} /* namespace android */ diff --git a/libs/hwui/JankTracker.h b/libs/hwui/JankTracker.h deleted file mode 100644 index 3d4929b215c6..000000000000 --- a/libs/hwui/JankTracker.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef JANKTRACKER_H_ -#define JANKTRACKER_H_ - -#include "FrameInfo.h" -#include "renderthread/TimeLord.h" -#include "utils/RingBuffer.h" - -#include <memory> - -namespace android { -namespace uirenderer { - -enum JankType { - kMissedVsync = 0, - kHighInputLatency, - kSlowUI, - kSlowSync, - kSlowRT, - - // must be last - NUM_BUCKETS, -}; - -struct JankBucket { - // Number of frames that hit this bucket - uint32_t count; -}; - -// TODO: Replace DrawProfiler with this -class JankTracker { -public: - JankTracker(nsecs_t frameIntervalNanos); - - void setFrameInterval(nsecs_t frameIntervalNanos); - - void addFrame(const FrameInfo& frame); - - void dump(int fd); - void reset(); - -private: - uint32_t findPercentile(int p); - - JankBucket mBuckets[NUM_BUCKETS]; - int64_t mThresholds[NUM_BUCKETS]; - uint32_t mFrameCounts[128]; - - int64_t mFrameInterval; - uint32_t mTotalFrameCount; - uint32_t mJankFrameCount; -}; - -} /* namespace uirenderer */ -} /* namespace android */ - -#endif /* JANKTRACKER_H_ */ diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp index 2eaa7719227c..75bd0676d70a 100644 --- a/libs/hwui/renderthread/CanvasContext.cpp +++ b/libs/hwui/renderthread/CanvasContext.cpp @@ -47,8 +47,7 @@ CanvasContext::CanvasContext(RenderThread& thread, bool translucent, , mOpaque(!translucent) , mCanvas(NULL) , mHaveNewSurface(false) - , mRootRenderNode(rootRenderNode) - , mCurrentFrameInfo(NULL) { + , mRootRenderNode(rootRenderNode) { mAnimationContext = contextFactory->createAnimationContext(mRenderThread.timeLord()); mRenderThread.renderState().registerCanvasContext(this); } @@ -153,13 +152,9 @@ void CanvasContext::processLayerUpdate(DeferredLayerUpdater* layerUpdater) { } } -void CanvasContext::prepareTree(TreeInfo& info, int64_t* uiFrameInfo) { +void CanvasContext::prepareTree(TreeInfo& info) { mRenderThread.removeFrameCallback(this); - mCurrentFrameInfo = &mFrames.next(); - mCurrentFrameInfo->importUiThreadInfo(uiFrameInfo); - mCurrentFrameInfo->markSyncStart(); - info.damageAccumulator = &mDamageAccumulator; info.renderer = mCanvas; if (mPrefetechedLayers.size() && info.mode == TreeInfo::MODE_FULL) { @@ -209,7 +204,6 @@ void CanvasContext::draw() { "drawRenderNode called on a context with no canvas or surface!"); profiler().markPlaybackStart(); - mCurrentFrameInfo->markIssueDrawCommandsStart(); SkRect dirty; mDamageAccumulator.finish(&dirty); @@ -247,19 +241,12 @@ void CanvasContext::draw() { profiler().markPlaybackEnd(); - // Even if we decided to cancel the frame, from the perspective of jank - // metrics the frame was swapped at this point - mCurrentFrameInfo->markSwapBuffers(); - if (status & DrawGlInfo::kStatusDrew) { swapBuffers(); } else { mEglManager.cancelFrame(); } - // TODO: Use a fence for real completion? - mCurrentFrameInfo->markFrameCompleted(); - mRenderThread.jankTracker().addFrame(*mCurrentFrameInfo); profiler().finishFrame(); } @@ -272,14 +259,9 @@ void CanvasContext::doFrame() { ATRACE_CALL(); profiler().startFrame(); - int64_t frameInfo[UI_THREAD_FRAME_INFO_SIZE]; - UiFrameInfoBuilder(frameInfo) - .addFlag(FrameInfoFlags::kRTAnimation) - .setVsync(mRenderThread.timeLord().computeFrameTimeNanos(), - mRenderThread.timeLord().latestVsync()); TreeInfo info(TreeInfo::MODE_RT_ONLY, mRenderThread.renderState()); - prepareTree(info, frameInfo); + prepareTree(info); if (info.out.canDrawThisFrame) { draw(); } @@ -392,28 +374,6 @@ void CanvasContext::setTextureAtlas(RenderThread& thread, thread.eglManager().setTextureAtlas(buffer, map, mapSize); } -void CanvasContext::dumpFrames(int fd) { - FILE* file = fdopen(fd, "a"); - fprintf(file, "\n\n---PROFILEDATA---"); - for (size_t i = 0; i < mFrames.size(); i++) { - FrameInfo& frame = mFrames[i]; - if (frame[FrameInfoIndex::kSyncStart] == 0) { - continue; - } - fprintf(file, "\n"); - for (int i = 0; i < FrameInfoIndex::kNumIndexes; i++) { - fprintf(file, "%" PRId64 ",", frame[i]); - } - } - fprintf(file, "\n---PROFILEDATA---\n\n"); - fflush(file); -} - -void CanvasContext::resetFrameStats() { - mFrames.clear(); - mRenderThread.jankTracker().reset(); -} - } /* namespace renderthread */ } /* namespace uirenderer */ } /* namespace android */ diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h index 0e8be9d9ed59..0cc2c7c2811a 100644 --- a/libs/hwui/renderthread/CanvasContext.h +++ b/libs/hwui/renderthread/CanvasContext.h @@ -17,14 +17,7 @@ #ifndef CANVASCONTEXT_H_ #define CANVASCONTEXT_H_ -#include "DamageAccumulator.h" -#include "DrawProfiler.h" -#include "IContextFactory.h" -#include "FrameInfo.h" -#include "RenderNode.h" -#include "utils/RingBuffer.h" -#include "renderthread/RenderTask.h" -#include "renderthread/RenderThread.h" +#include <set> #include <cutils/compiler.h> #include <EGL/egl.h> @@ -32,7 +25,14 @@ #include <utils/Functor.h> #include <utils/Vector.h> -#include <set> +#include "../DamageAccumulator.h" +#include "../DrawProfiler.h" +#include "../IContextFactory.h" +#include "../RenderNode.h" +#include "RenderTask.h" +#include "RenderThread.h" + +#define FUNCTOR_PROCESS_DELAY 4 namespace android { namespace uirenderer { @@ -75,7 +75,7 @@ public: void setOpaque(bool opaque); void makeCurrent(); void processLayerUpdate(DeferredLayerUpdater* layerUpdater); - void prepareTree(TreeInfo& info, int64_t* uiFrameInfo); + void prepareTree(TreeInfo& info); void draw(); void destroy(); @@ -103,9 +103,6 @@ public: DrawProfiler& profiler() { return mProfiler; } - void dumpFrames(int fd); - void resetFrameStats(); - private: friend class RegisterFrameCallbackTask; // TODO: Replace with something better for layer & other GL object @@ -136,9 +133,6 @@ private: const sp<RenderNode> mRootRenderNode; DrawProfiler mProfiler; - FrameInfo* mCurrentFrameInfo; - // Ring buffer large enough for 1 second worth of frames - RingBuffer<FrameInfo, 60> mFrames; std::set<RenderNode*> mPrefetechedLayers; }; diff --git a/libs/hwui/renderthread/DrawFrameTask.cpp b/libs/hwui/renderthread/DrawFrameTask.cpp index 23a020233f27..97b31a95f278 100644 --- a/libs/hwui/renderthread/DrawFrameTask.cpp +++ b/libs/hwui/renderthread/DrawFrameTask.cpp @@ -34,6 +34,8 @@ namespace renderthread { DrawFrameTask::DrawFrameTask() : mRenderThread(NULL) , mContext(NULL) + , mFrameTimeNanos(0) + , mRecordDurationNanos(0) , mDensity(1.0f) // safe enough default , mSyncResult(kSync_OK) { } @@ -66,12 +68,18 @@ void DrawFrameTask::removeLayerUpdate(DeferredLayerUpdater* layer) { } } -int DrawFrameTask::drawFrame() { +int DrawFrameTask::drawFrame(nsecs_t frameTimeNanos, nsecs_t recordDurationNanos) { LOG_ALWAYS_FATAL_IF(!mContext, "Cannot drawFrame with no CanvasContext!"); mSyncResult = kSync_OK; + mFrameTimeNanos = frameTimeNanos; + mRecordDurationNanos = recordDurationNanos; postAndWait(); + // Reset the single-frame data + mFrameTimeNanos = 0; + mRecordDurationNanos = 0; + return mSyncResult; } @@ -85,7 +93,7 @@ void DrawFrameTask::run() { ATRACE_NAME("DrawFrame"); mContext->profiler().setDensity(mDensity); - mContext->profiler().startFrame(); + mContext->profiler().startFrame(mRecordDurationNanos); bool canUnblockUiThread; bool canDrawThisFrame; @@ -114,7 +122,7 @@ void DrawFrameTask::run() { bool DrawFrameTask::syncFrameState(TreeInfo& info) { ATRACE_CALL(); - mRenderThread->timeLord().vsyncReceived(mFrameInfo[FrameInfoIndex::kVsync]); + mRenderThread->timeLord().vsyncReceived(mFrameTimeNanos); mContext->makeCurrent(); Caches::getInstance().textureCache.resetMarkInUse(); @@ -122,7 +130,7 @@ bool DrawFrameTask::syncFrameState(TreeInfo& info) { mContext->processLayerUpdate(mLayers[i].get()); } mLayers.clear(); - mContext->prepareTree(info, mFrameInfo); + mContext->prepareTree(info); // This is after the prepareTree so that any pending operations // (RenderNode tree state, prefetched layers, etc...) will be flushed. diff --git a/libs/hwui/renderthread/DrawFrameTask.h b/libs/hwui/renderthread/DrawFrameTask.h index eccb87f29383..28f6cb26fb57 100644 --- a/libs/hwui/renderthread/DrawFrameTask.h +++ b/libs/hwui/renderthread/DrawFrameTask.h @@ -25,7 +25,6 @@ #include "RenderTask.h" #include "../Rect.h" -#include "../FrameInfo.h" #include "../TreeInfo.h" namespace android { @@ -63,9 +62,7 @@ public: void removeLayerUpdate(DeferredLayerUpdater* layer); void setDensity(float density) { mDensity = density; } - int drawFrame(); - - int64_t* frameInfo() { return mFrameInfo; } + int drawFrame(nsecs_t frameTimeNanos, nsecs_t recordDurationNanos); virtual void run(); @@ -83,12 +80,12 @@ private: /********************************************* * Single frame data *********************************************/ + nsecs_t mFrameTimeNanos; + nsecs_t mRecordDurationNanos; float mDensity; std::vector< sp<DeferredLayerUpdater> > mLayers; int mSyncResult; - - int64_t mFrameInfo[UI_THREAD_FRAME_INFO_SIZE]; }; } /* namespace renderthread */ diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp index 088c65b939ef..6d063a4b0ce0 100644 --- a/libs/hwui/renderthread/RenderProxy.cpp +++ b/libs/hwui/renderthread/RenderProxy.cpp @@ -16,14 +16,14 @@ #include "RenderProxy.h" -#include "DeferredLayerUpdater.h" -#include "DisplayList.h" -#include "LayerRenderer.h" -#include "Rect.h" -#include "renderthread/CanvasContext.h" -#include "renderthread/RenderTask.h" -#include "renderthread/RenderThread.h" -#include "utils/Macros.h" +#include "CanvasContext.h" +#include "RenderTask.h" +#include "RenderThread.h" + +#include "../DeferredLayerUpdater.h" +#include "../DisplayList.h" +#include "../LayerRenderer.h" +#include "../Rect.h" namespace android { namespace uirenderer { @@ -52,11 +52,6 @@ namespace renderthread { MethodInvokeRenderTask* task = new MethodInvokeRenderTask((RunnableMethod) Bridge_ ## method); \ ARGS(method) *args = (ARGS(method) *) task->payload() -HWUI_ENUM(DumpFlags, - kFrameStats = 1 << 0, - kReset = 1 << 1, -); - CREATE_BRIDGE4(createContext, RenderThread* thread, bool translucent, RenderNode* rootRenderNode, IContextFactory* contextFactory) { return new CanvasContext(*args->thread, args->translucent, @@ -97,7 +92,7 @@ void RenderProxy::destroyContext() { } CREATE_BRIDGE2(setFrameInterval, RenderThread* thread, nsecs_t frameIntervalNanos) { - args->thread->setFrameInterval(args->frameIntervalNanos); + args->thread->timeLord().setFrameInterval(args->frameIntervalNanos); return NULL; } @@ -180,8 +175,7 @@ CREATE_BRIDGE7(setup, CanvasContext* context, int width, int height, } void RenderProxy::setup(int width, int height, const Vector3& lightCenter, float lightRadius, - uint8_t ambientShadowAlpha, uint8_t spotShadowAlpha, float density) { - mDrawFrameTask.setDensity(density); + uint8_t ambientShadowAlpha, uint8_t spotShadowAlpha) { SETUP_TASK(setup); args->context = mContext; args->width = width; @@ -205,12 +199,10 @@ void RenderProxy::setOpaque(bool opaque) { post(task); } -int64_t* RenderProxy::frameInfo() { - return mDrawFrameTask.frameInfo(); -} - -int RenderProxy::syncAndDrawFrame() { - return mDrawFrameTask.drawFrame(); +int RenderProxy::syncAndDrawFrame(nsecs_t frameTimeNanos, nsecs_t recordDurationNanos, + float density) { + mDrawFrameTask.setDensity(density); + return mDrawFrameTask.drawFrame(frameTimeNanos, recordDurationNanos); } CREATE_BRIDGE1(destroy, CanvasContext* context) { @@ -379,28 +371,19 @@ void RenderProxy::notifyFramePending() { mRenderThread.queueAtFront(task); } -CREATE_BRIDGE3(dumpProfileInfo, CanvasContext* context, int fd, int dumpFlags) { +CREATE_BRIDGE2(dumpProfileInfo, CanvasContext* context, int fd) { args->context->profiler().dumpData(args->fd); - - if (args->dumpFlags & DumpFlags::kFrameStats) { - args->context->dumpFrames(args->fd); - } - if (args->dumpFlags & DumpFlags::kReset) { - args->context->resetFrameStats(); - } return NULL; } -void RenderProxy::dumpProfileInfo(int fd, int dumpFlags) { +void RenderProxy::dumpProfileInfo(int fd) { SETUP_TASK(dumpProfileInfo); args->context = mContext; args->fd = fd; - args->dumpFlags = dumpFlags; postAndWait(task); } -CREATE_BRIDGE2(outputLogBuffer, int fd, RenderThread* thread) { - args->thread->jankTracker().dump(args->fd); +CREATE_BRIDGE1(outputLogBuffer, int fd) { RenderNode::outputLogBuffer(args->fd); return NULL; } @@ -408,7 +391,6 @@ CREATE_BRIDGE2(outputLogBuffer, int fd, RenderThread* thread) { void RenderProxy::outputLogBuffer(int fd) { SETUP_TASK(outputLogBuffer); args->fd = fd; - args->thread = &RenderThread::getInstance(); staticPostAndWait(task); } diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h index d86f1fca466f..fd1fe05ffbdb 100644 --- a/libs/hwui/renderthread/RenderProxy.h +++ b/libs/hwui/renderthread/RenderProxy.h @@ -71,10 +71,10 @@ public: ANDROID_API void updateSurface(const sp<ANativeWindow>& window); ANDROID_API bool pauseSurface(const sp<ANativeWindow>& window); ANDROID_API void setup(int width, int height, const Vector3& lightCenter, float lightRadius, - uint8_t ambientShadowAlpha, uint8_t spotShadowAlpha, float density); + uint8_t ambientShadowAlpha, uint8_t spotShadowAlpha); ANDROID_API void setOpaque(bool opaque); - ANDROID_API int64_t* frameInfo(); - ANDROID_API int syncAndDrawFrame(); + ANDROID_API int syncAndDrawFrame(nsecs_t frameTimeNanos, nsecs_t recordDurationNanos, + float density); ANDROID_API void destroy(); ANDROID_API static void invokeFunctor(Functor* functor, bool waitForCompletion); @@ -95,7 +95,7 @@ public: ANDROID_API void stopDrawing(); ANDROID_API void notifyFramePending(); - ANDROID_API void dumpProfileInfo(int fd, int dumpFlags); + ANDROID_API void dumpProfileInfo(int fd); ANDROID_API static void outputLogBuffer(int fd); ANDROID_API void setTextureAtlas(const sp<GraphicBuffer>& buffer, int64_t* map, size_t size); diff --git a/libs/hwui/renderthread/RenderThread.cpp b/libs/hwui/renderthread/RenderThread.cpp index 7a8c3cee088d..84826b7a3bff 100644 --- a/libs/hwui/renderthread/RenderThread.cpp +++ b/libs/hwui/renderthread/RenderThread.cpp @@ -143,8 +143,7 @@ RenderThread::RenderThread() : Thread(true), Singleton<RenderThread>() , mFrameCallbackTaskPending(false) , mFrameCallbackTask(0) , mRenderState(NULL) - , mEglManager(NULL) - , mJankTracker(NULL) { + , mEglManager(NULL) { mFrameCallbackTask = new DispatchFrameCallbacks(this); mLooper = new Looper(false); run("RenderThread"); @@ -154,11 +153,6 @@ RenderThread::~RenderThread() { LOG_ALWAYS_FATAL("Can't destroy the render thread"); } -void RenderThread::setFrameInterval(nsecs_t frameInterval) { - mTimeLord.setFrameInterval(frameInterval); - mJankTracker->setFrameInterval(frameInterval); -} - void RenderThread::initializeDisplayEventReceiver() { LOG_ALWAYS_FATAL_IF(mDisplayEventReceiver, "Initializing a second DisplayEventReceiver?"); mDisplayEventReceiver = new DisplayEventReceiver(); @@ -175,7 +169,6 @@ void RenderThread::initThreadLocals() { initializeDisplayEventReceiver(); mEglManager = new EglManager(*this); mRenderState = new RenderState(*this); - mJankTracker = new JankTracker(mTimeLord.frameIntervalNanos()); } int RenderThread::displayEventReceiverCallback(int fd, int events, void* data) { diff --git a/libs/hwui/renderthread/RenderThread.h b/libs/hwui/renderthread/RenderThread.h index 8a28a35aabc2..99c2e1527ea2 100644 --- a/libs/hwui/renderthread/RenderThread.h +++ b/libs/hwui/renderthread/RenderThread.h @@ -19,8 +19,8 @@ #include "RenderTask.h" -#include "../JankTracker.h" -#include "TimeLord.h" +#include <memory> +#include <set> #include <cutils/compiler.h> #include <utils/Looper.h> @@ -28,8 +28,7 @@ #include <utils/Singleton.h> #include <utils/Thread.h> -#include <memory> -#include <set> +#include "TimeLord.h" namespace android { @@ -86,12 +85,9 @@ public: // the next vsync. If it is not currently registered this does nothing. void pushBackFrameCallback(IFrameCallback* callback); - void setFrameInterval(nsecs_t frameInterval); - TimeLord& timeLord() { return mTimeLord; } RenderState& renderState() { return *mRenderState; } EglManager& eglManager() { return *mEglManager; } - JankTracker& jankTracker() { return *mJankTracker; } protected: virtual bool threadLoop(); @@ -136,8 +132,6 @@ private: TimeLord mTimeLord; RenderState* mRenderState; EglManager* mEglManager; - - JankTracker* mJankTracker; }; } /* namespace renderthread */ diff --git a/libs/hwui/renderthread/TimeLord.cpp b/libs/hwui/renderthread/TimeLord.cpp index f846d6a44473..f18749317ab6 100644 --- a/libs/hwui/renderthread/TimeLord.cpp +++ b/libs/hwui/renderthread/TimeLord.cpp @@ -32,7 +32,7 @@ bool TimeLord::vsyncReceived(nsecs_t vsync) { return false; } -nsecs_t TimeLord::computeFrameTimeNanos() { +nsecs_t TimeLord::computeFrameTimeMs() { // Logic copied from Choreographer.java nsecs_t now = systemTime(CLOCK_MONOTONIC); nsecs_t jitterNanos = now - mFrameTimeNanos; @@ -40,11 +40,7 @@ nsecs_t TimeLord::computeFrameTimeNanos() { nsecs_t lastFrameOffset = jitterNanos % mFrameIntervalNanos; mFrameTimeNanos = now - lastFrameOffset; } - return mFrameTimeNanos; -} - -nsecs_t TimeLord::computeFrameTimeMs() { - return nanoseconds_to_milliseconds(computeFrameTimeNanos()); + return nanoseconds_to_milliseconds(mFrameTimeNanos); } } /* namespace renderthread */ diff --git a/libs/hwui/renderthread/TimeLord.h b/libs/hwui/renderthread/TimeLord.h index 5464399234fb..7c155d28feef 100644 --- a/libs/hwui/renderthread/TimeLord.h +++ b/libs/hwui/renderthread/TimeLord.h @@ -29,13 +29,9 @@ class RenderThread; class TimeLord { public: void setFrameInterval(nsecs_t intervalNanos) { mFrameIntervalNanos = intervalNanos; } - nsecs_t frameIntervalNanos() const { return mFrameIntervalNanos; } - // returns true if the vsync is newer, false if it was rejected for staleness bool vsyncReceived(nsecs_t vsync); - nsecs_t latestVsync() { return mFrameTimeNanos; } nsecs_t computeFrameTimeMs(); - nsecs_t computeFrameTimeNanos(); private: friend class RenderThread; diff --git a/libs/hwui/tests/main.cpp b/libs/hwui/tests/main.cpp index 33b8103cdb84..2d99e9f7686c 100644 --- a/libs/hwui/tests/main.cpp +++ b/libs/hwui/tests/main.cpp @@ -88,7 +88,7 @@ int main(int argc, char* argv[]) { proxy->initialize(surface); float lightX = width / 2.0; proxy->setup(width, height, (Vector3){lightX, dp(-200.0f), dp(800.0f)}, - dp(800.0f), 255 * 0.075, 255 * 0.15, gDisplay.density); + dp(800.0f), 255 * 0.075, 255 * 0.15); android::uirenderer::Rect DUMMY; @@ -116,7 +116,8 @@ int main(int argc, char* argv[]) { cards[ci]->mutateStagingProperties().setTranslationY(i); cards[ci]->setPropertyFieldsDirty(RenderNode::X | RenderNode::Y); } - proxy->syncAndDrawFrame(); + nsecs_t frameTimeNs = systemTime(CLOCK_MONOTONIC); + proxy->syncAndDrawFrame(frameTimeNs, 0, gDisplay.density); usleep(12000); } diff --git a/libs/hwui/utils/Macros.h b/libs/hwui/utils/Macros.h index 068b32b3fe68..5b7c87ceef8f 100644 --- a/libs/hwui/utils/Macros.h +++ b/libs/hwui/utils/Macros.h @@ -29,12 +29,4 @@ friend inline int compare_type(const Type& lhs, const Type& rhs) { return lhs.compare(rhs); } \ friend inline hash_t hash_type(const Type& entry) { return entry.hash(); } -#define HWUI_ENUM(name, ...) \ - namespace name { \ - enum _##name { \ - __VA_ARGS__ \ - }; \ - } \ - typedef enum name::_##name name##Enum - #endif /* MACROS_H */ diff --git a/libs/hwui/utils/RingBuffer.h b/libs/hwui/utils/RingBuffer.h deleted file mode 100644 index 62b22fdcef42..000000000000 --- a/libs/hwui/utils/RingBuffer.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef RINGBUFFER_H_ -#define RINGBUFFER_H_ - -#include "utils/Macros.h" - -#include <stddef.h> - -namespace android { -namespace uirenderer { - -template<class T, size_t SIZE> -class RingBuffer { - PREVENT_COPY_AND_ASSIGN(RingBuffer); - -public: - RingBuffer() : mHead(-1), mCount(0) {} - ~RingBuffer() {} - - size_t capacity() { return SIZE; } - size_t size() { return mCount; } - - T& next() { - mHead = (mHead + 1) % SIZE; - if (mCount < SIZE) { - mCount++; - } - return mBuffer[mHead]; - } - - T& front() { - return this[0]; - } - - T& back() { - return this[size() - 1]; - } - - T& operator[](size_t index) { - return mBuffer[(mHead + index + 1) % mCount]; - } - - void clear() { - mCount = 0; - mHead = -1; - } - -private: - T mBuffer[SIZE]; - int mHead; - size_t mCount; -}; - -}; // namespace uirenderer -}; // namespace android - -#endif /* RINGBUFFER_H_ */ |