<!DOCTYPE html> <script> 'use strict'; const RENDER_THREAD_NAME = "RenderThread"; const UI_THREAD_NAME = "UI Thread"; const DRAW_FRAME_SLICE_TITLE = "DrawFrame"; const BINDER_SLICE_TITLE = "binder transaction"; const RECORD_SLICE_TITLE = "Record View#draw()"; const DEQUEUE_BUFFER_SLICE_TITLE = "dequeueBuffer"; function getTimeInBinder(slice) { if (slice.title === BINDER_SLICE_TITLE) { return slice.duration; } let result = 0.0; for (let subslice of slice.subSlices) { result += getTimeInBinder(subslice); } return result; } function getTimeInDequeueBuffer(slice) { if (slice.title === DEQUEUE_BUFFER_SLICE_TITLE) { return slice.duration; } let result = 0.0; for (let subslice of slice.subSlices) { result += getTimeInDequeueBuffer(subslice); } return result; } tr.mre.FunctionRegistry.register( function AvgDrawFrame(result, model) { let canonicalUrl = model.canonicalUrl; for (let p of model.getAllProcesses()) { //calc stats for processes that have UI and render threads and at least 10 frames let renderThread = p.findAtMostOneThreadNamed(RENDER_THREAD_NAME); let UIThread = p.findAtMostOneThreadNamed(UI_THREAD_NAME); if (renderThread && UIThread) { let numDrawFrames = 0; let drawFramesWallDuration = 0.0; let binderDuration = 0.0; let dequeueBufferDuration = 0.0; let numRecordViewDraw = 0; let recordViewDrawWallDuration = 0.0; renderThread.sliceGroup.slices.forEach(function(slice) { if (slice.title === DRAW_FRAME_SLICE_TITLE) { drawFramesWallDuration += slice.duration; numDrawFrames++; binderDuration += getTimeInBinder(slice); dequeueBufferDuration += getTimeInDequeueBuffer(slice); } }); if (numDrawFrames < 10) continue; UIThread.sliceGroup.slices.forEach(function(slice) { if (slice.title === RECORD_SLICE_TITLE) { recordViewDrawWallDuration += slice.duration; numRecordViewDraw++; } }); let avgDrawFrameDuration = undefined; if (numDrawFrames > 0) { avgDrawFrameDuration = (drawFramesWallDuration-dequeueBufferDuration)/numDrawFrames; } let avgRecordViewDrawDuration = undefined; if (numRecordViewDraw > 0) { avgRecordViewDrawDuration = recordViewDrawWallDuration/numRecordViewDraw; } result.addPair('result', { canonicalUrl: canonicalUrl, processName: p.name, avgDrawFrameDuration: Number(avgDrawFrameDuration).toFixed(3), avgRecordViewDrawDuration: Number(avgRecordViewDrawDuration).toFixed(3), avgRecordAndPlay: Number(avgDrawFrameDuration+avgRecordViewDrawDuration).toFixed(3) }); } } }); </script>