analyzing display and performance with systrace
TRANSCRIPT
Analyzing Display and Performance with Systrace
Peter.Pan
What is Systrace
• The Systrace tool helps analyze the performance of your application by capturing and displaying execution times of your applications processes and other Android system processes.
Command Line Usage
• Android 4.3 and higher options$ cd $(project)/extenal/chromium-trace/$ python systrace.py --time=10 -o mynewtrace.html –b 2048 sched gfx view wm
ATRACE• Path
– frameworks/native/cmds/atrace/atrace.cpp• Define (form system/core/include/cutils/trace.h)
– #define ATRACE_TAG ATRACE_TAG_GRAPHICS• Function
– ATRACE_CALL()• Variables
– ATRACE_INT(“Name”, Value);– ATRACE_INT64(“Name”, Value64);
#define ATRACE_TAG ATRACE_TAG_GRAPHICS…Void Function(){ ATRACE_CALL(); int value = 0; value = Random();
ATRACE_INT(“RandomValue”, value);}…
GUI
FinderCPU infor.
Control bar
Surceflinger
Other processes
Detail
Timeline
Operation
Keyword
Shortcut:W: Zoom InS: Zoom OutA: Pan leftD: Pan right
CPU Scheduling• $ python systrace.py --time=10 -o mynewtrace.html sched gfx view wm freq
Process status
Status:*Uninterruptable sleep (usually IO)*Running or runnable (on run queue)*sleeping
Vsync_OnAdd/Remove a listener to DispVsyncSource.
[email protected]< sp<EventThread::Connection> EventThread::waitForEvent(…){ … if (timestamp && !waitForVSync) { disableVSyncLocked(); } else if (!timestamp && waitForVSync) { enableVSyncLocked(); }…}
@Sufaceflinger.cppvirtual void setVSyncEnabled(bool enable) { if (enable) { status_t err = mDispSync->addEventListener(mPhaseOffset, static_cast<DispSync::Callback*>(this)); … ATRACE_INT("VsyncOn", 1); } else { status_t err = mDispSync->removeEventListener(static_cast<DispSync::Callback*>(this)); … ATRACE_INT("VsyncOn", 0); }}
VSYNC
DispVsyncSource produces the Vsync signal.
[email protected] bool threadLoop() { while (true) { … if (callbackInvocations.size() > 0) { fireCallbackInvocations(callbackInvocations); }… }…}
@Surfacefliger.cpp virtual void onDispSyncEvent(nsecs_t when) { sp<VSyncSource::Callback> callback; { Mutex::Autolock lock(mMutex); callback = mCallback;
if (mTraceVsync) { mValue = (mValue + 1) % 2; ATRACE_INT("VSYNC", mValue); } }
if (callback != NULL) { callback->onVSyncEvent(when); } }
@DispSync.cppvoid fireCallbackInvocations(…) { for (size_t i = 0; i < callbacks.size(); i++) { callbacks[i].mCallback->onDispSyncEvent(callbacks[i].mEventTime); }}
HW_Vsync0Need HW Vsync
@HWComposer.cpp void vsync(int disp, int64_t timestamp) {… char tag[16]; snprintf(tag, sizeof(tag), "HW_VSYNC_%1u", disp); ATRACE_INT(tag, ++mVSyncCounts[disp] & 1); mEventHandler.onVSyncReceived(disp, timestamp);…}
[email protected] void surfaceflinger::onVSyncReceived(){ if (type == 0 && mPrimaryHWVsyncEnabled) { needsHwVsync = mPrimaryDispSync.addResyncSample(timestamp); } if (needsHwVsync) { enableHardwareVsync(); } else { disableHardwareVsync(false); }…}
@Surfaceflinger.cpp voidsurfaceflinger::onScreenAcquired(){ … mEventThread->onScreenAcquired(); resyncToHardwareVsync(true); …}
@Surfaceflinger.cpp void surfaceflinger:: onScreenReleased(){ …if (type== DisplayDevice::DISPLAY_PRIMARY) { disableHardwareVsync(true); } …}
Sufacefliger
QueueBuffer()
DequeueBuffer()/QueueBuffer()
DequeueBuffer() QueueBuffer()
QueueBuffer()/AcquirBuffer()
QueueBuffer()
AcquirBuffer()
+1 -1
QueueBuffer()/AcquirBuffer()
@BufferQueue.cppstatus_t BufferQueue::acquireBuffer(BufferItem *buffer, nsecs_t expectedPresent){ … ATRACE_INT(mConsumerName.string(), Queue.size()); …}
@BufferQueue.cppstatus_t BufferQueue::QueueuBuffer(BufferItem *buffer, nsecs_t expectedPresent){ … ATRACE_INT(mConsumerName.string(), Queue.size()); …}
FramebufferSurface
QueueBuffer() AcquirBuffer()
Case study(1)
DeliverInputEvent()
Status change
QueueBuffer()
Case Study(2)
Animator
Case Study(3)
Reference• http://developer.android.com/tools/debugging/systrace.html• http://www.curious-creature.org/2012/12/01/android-
performance-case-study/