15888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik/* 25888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik * Copyright (C) 2011 The Android Open Source Project 35888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik * 45888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik * Licensed under the Apache License, Version 2.0 (the "License"); 55888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik * you may not use this file except in compliance with the License. 65888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik * You may obtain a copy of the License at 75888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik * 85888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik * http://www.apache.org/licenses/LICENSE-2.0 95888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik * 105888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik * Unless required by applicable law or agreed to in writing, software 115888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik * distributed under the License is distributed on an "AS IS" BASIS, 125888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik * See the License for the specific language governing permissions and 145888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik * limitations under the License. 155888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik */ 165888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik 175888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craikpackage com.test.tilebenchmark; 185888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik 195888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craikimport android.content.res.Resources; 205888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craikimport android.graphics.Canvas; 215888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craikimport android.graphics.Color; 225888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craikimport android.graphics.Paint; 235888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craikimport android.graphics.Rect; 245888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craikimport android.graphics.drawable.ShapeDrawable; 25555c55ed65056e2236430f92e81c1fb6acd05dcdChris Craik 26555c55ed65056e2236430f92e81c1fb6acd05dcdChris Craikimport com.test.tilebenchmark.RunData.TileData; 275888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik 285888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craikimport java.util.ArrayList; 295888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craikimport java.util.Arrays; 30555c55ed65056e2236430f92e81c1fb6acd05dcdChris Craikimport java.util.HashMap; 315888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik 325888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craikpublic class PlaybackGraphs { 3321555abad7ba5f5377052e2644974d3ce8c37869Chris Craik private static final int BAR_WIDTH = PlaybackView.TILE_SCALE * 3; 345888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik private static final float CANVAS_SCALE = 0.2f; 355888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik private static final double IDEAL_FRAMES = 60; 365888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik private static final int LABELOFFSET = 100; 375888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik private static Paint whiteLabels; 385888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik 3921555abad7ba5f5377052e2644974d3ce8c37869Chris Craik private static double viewportCoverage(TileData view, TileData tile) { 406f92c15180f66d0ec7c8b20ea47f479468255970Chris Craik if (tile.left < (view.right * view.scale) 416f92c15180f66d0ec7c8b20ea47f479468255970Chris Craik && tile.right >= (view.left * view.scale) 426f92c15180f66d0ec7c8b20ea47f479468255970Chris Craik && tile.top < (view.bottom * view.scale) 436f92c15180f66d0ec7c8b20ea47f479468255970Chris Craik && tile.bottom >= (view.top * view.scale)) { 445888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik return 1.0f; 455888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik } 465888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik return 0.0f; 475888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik } 485888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik 49555c55ed65056e2236430f92e81c1fb6acd05dcdChris Craik protected interface MetricGen { 505888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik public double getValue(TileData[] frame); 515888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik 525888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik public double getMax(); 535888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik 545888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik public int getLabelId(); 555888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik }; 565888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik 57555c55ed65056e2236430f92e81c1fb6acd05dcdChris Craik protected static MetricGen[] Metrics = new MetricGen[] { 585888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik new MetricGen() { 595888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik // framerate graph 605888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik @Override 615888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik public double getValue(TileData[] frame) { 625888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik int renderTimeUS = frame[0].level; 635888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik return 1.0e6f / renderTimeUS; 645888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik } 655888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik 665888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik @Override 675888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik public double getMax() { 685888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik return IDEAL_FRAMES; 695888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik } 705888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik 715888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik @Override 725888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik public int getLabelId() { 735888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik return R.string.frames_per_second; 745888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik } 755888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik }, new MetricGen() { 765888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik // coverage graph 775888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik @Override 785888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik public double getValue(TileData[] frame) { 795888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik double total = 0, totalCount = 0; 8021555abad7ba5f5377052e2644974d3ce8c37869Chris Craik for (int tileID = 1; tileID < frame.length; tileID++) { 815888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik TileData data = frame[tileID]; 8221555abad7ba5f5377052e2644974d3ce8c37869Chris Craik double coverage = viewportCoverage(frame[0], data); 83702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik total += coverage * (data.isReady ? 100 : 0); 845888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik totalCount += coverage; 855888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik } 865888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik if (totalCount == 0) { 875888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik return -1; 885888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik } 895888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik return total / totalCount; 905888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik } 915888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik 925888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik @Override 935888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik public double getMax() { 94702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik return 100; 955888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik } 965888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik 975888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik @Override 985888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik public int getLabelId() { 995888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik return R.string.viewport_coverage; 1005888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik } 1015888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik } 1025888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik }; 1035888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik 104555c55ed65056e2236430f92e81c1fb6acd05dcdChris Craik protected interface StatGen { 1055888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik public double getValue(double sortedValues[]); 1065888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik 1075888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik public int getLabelId(); 1085888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik } 1095888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik 1105888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik public static double getPercentile(double sortedValues[], double ratioAbove) { 111702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik if (sortedValues.length == 0) 112702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik return -1; 113702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik 1145888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik double index = ratioAbove * (sortedValues.length - 1); 1155888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik int intIndex = (int) Math.floor(index); 1165888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik if (index == intIndex) { 1175888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik return sortedValues[intIndex]; 1185888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik } 1195888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik double alpha = index - intIndex; 1205888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik return sortedValues[intIndex] * (1 - alpha) 1215888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik + sortedValues[intIndex + 1] * (alpha); 1225888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik } 1235888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik 124702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik public static double getMean(double sortedValues[]) { 125702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik if (sortedValues.length == 0) 126702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik return -1; 127702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik 128702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik double agg = 0; 129702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik for (double val : sortedValues) { 130702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik agg += val; 131702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik } 132702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik return agg / sortedValues.length; 133702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik } 134702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik 135702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik public static double getStdDev(double sortedValues[]) { 136702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik if (sortedValues.length == 0) 137702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik return -1; 138702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik 139702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik double agg = 0; 140702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik double sqrAgg = 0; 141702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik for (double val : sortedValues) { 142702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik agg += val; 143702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik sqrAgg += val*val; 144702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik } 145702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik double mean = agg / sortedValues.length; 146702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik return Math.sqrt((sqrAgg / sortedValues.length) - (mean * mean)); 147702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik } 148702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik 149555c55ed65056e2236430f92e81c1fb6acd05dcdChris Craik protected static StatGen[] Stats = new StatGen[] { 1505888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik new StatGen() { 1515888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik @Override 1525888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik public double getValue(double[] sortedValues) { 1535888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik return getPercentile(sortedValues, 0.25); 1545888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik } 1555888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik 1565888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik @Override 1575888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik public int getLabelId() { 1585888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik return R.string.percentile_25; 1595888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik } 1605888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik }, new StatGen() { 1615888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik @Override 1625888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik public double getValue(double[] sortedValues) { 1635888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik return getPercentile(sortedValues, 0.5); 1645888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik } 1655888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik 1665888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik @Override 1675888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik public int getLabelId() { 1685888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik return R.string.percentile_50; 1695888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik } 1705888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik }, new StatGen() { 1715888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik @Override 1725888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik public double getValue(double[] sortedValues) { 1735888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik return getPercentile(sortedValues, 0.75); 1745888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik } 1755888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik 1765888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik @Override 1775888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik public int getLabelId() { 1785888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik return R.string.percentile_75; 1795888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik } 180702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik }, new StatGen() { 181702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik @Override 182702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik public double getValue(double[] sortedValues) { 183702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik return getStdDev(sortedValues); 184702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik } 185702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik 186702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik @Override 187702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik public int getLabelId() { 188702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik return R.string.std_dev; 189702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik } 190702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik }, new StatGen() { 191702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik @Override 192702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik public double getValue(double[] sortedValues) { 193702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik return getMean(sortedValues); 194702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik } 195702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik 196702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik @Override 197702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik public int getLabelId() { 198702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik return R.string.mean; 199702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik } 2005888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik }, 2015888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik }; 2025888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik 2035888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik public PlaybackGraphs() { 2045888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik whiteLabels = new Paint(); 2055888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik whiteLabels.setColor(Color.WHITE); 20621555abad7ba5f5377052e2644974d3ce8c37869Chris Craik whiteLabels.setTextSize(PlaybackView.TILE_SCALE / 3); 2075888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik } 2085888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik 2095888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik private ArrayList<ShapeDrawable> mShapes = new ArrayList<ShapeDrawable>(); 210702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik protected final double[][] mStats = new double[Metrics.length][Stats.length]; 211555c55ed65056e2236430f92e81c1fb6acd05dcdChris Craik protected HashMap<String, Double> mSingleStats; 2125888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik 213702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik private void gatherFrameMetric(int metricIndex, double metricValues[], RunData data) { 214702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik // create graph out of rectangles, one per frame 215702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik int lastBar = 0; 216702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik for (int frameIndex = 0; frameIndex < data.frames.length; frameIndex++) { 217702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik TileData frame[] = data.frames[frameIndex]; 2186f92c15180f66d0ec7c8b20ea47f479468255970Chris Craik int newBar = (int)((frame[0].top + frame[0].bottom) * frame[0].scale / 2.0f); 219702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik 220702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik MetricGen s = Metrics[metricIndex]; 221702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik double absoluteValue = s.getValue(frame); 222702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik double relativeValue = absoluteValue / s.getMax(); 223702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik relativeValue = Math.min(1,relativeValue); 224702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik relativeValue = Math.max(0,relativeValue); 225702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik int rightPos = (int) (-BAR_WIDTH * metricIndex); 226702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik int leftPos = (int) (-BAR_WIDTH * (metricIndex + relativeValue)); 227702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik 228702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik ShapeDrawable graphBar = new ShapeDrawable(); 229702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik graphBar.getPaint().setColor(Color.BLUE); 230702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik graphBar.setBounds(leftPos, lastBar, rightPos, newBar); 231702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik 232702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik mShapes.add(graphBar); 233702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik metricValues[frameIndex] = absoluteValue; 234702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik lastBar = newBar; 235702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik } 236702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik } 237702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik 238555c55ed65056e2236430f92e81c1fb6acd05dcdChris Craik public void setData(RunData data) { 2395888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik mShapes.clear(); 240555c55ed65056e2236430f92e81c1fb6acd05dcdChris Craik double metricValues[] = new double[data.frames.length]; 2415888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik 242702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik mSingleStats = data.singleStats; 243702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik 244555c55ed65056e2236430f92e81c1fb6acd05dcdChris Craik if (data.frames.length == 0) { 2455888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik return; 2465888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik } 2475888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik 2485888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik for (int metricIndex = 0; metricIndex < Metrics.length; metricIndex++) { 249702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik // calculate metric based on list of frames 250702c6fdc4799593c16eb0051703e3bd62086ff42Chris Craik gatherFrameMetric(metricIndex, metricValues, data); 2515888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik 2525888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik // store aggregate statistics per metric (median, and similar) 2535888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik Arrays.sort(metricValues); 2545888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik for (int statIndex = 0; statIndex < Stats.length; statIndex++) { 255555c55ed65056e2236430f92e81c1fb6acd05dcdChris Craik mStats[metricIndex][statIndex] = 256555c55ed65056e2236430f92e81c1fb6acd05dcdChris Craik Stats[statIndex].getValue(metricValues); 2575888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik } 2585888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik } 2595888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik } 2605888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik 2615888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik public void drawVerticalShiftedShapes(Canvas canvas, 2625888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik ArrayList<ShapeDrawable> shapes) { 2635888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik // Shapes drawn here are drawn relative to the viewRect 2645888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik Rect viewRect = shapes.get(shapes.size() - 1).getBounds(); 26521555abad7ba5f5377052e2644974d3ce8c37869Chris Craik canvas.translate(0, 5 * PlaybackView.TILE_SCALE - viewRect.top); 2665888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik 2675888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik for (ShapeDrawable shape : mShapes) { 2685888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik shape.draw(canvas); 2695888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik } 2705888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik for (ShapeDrawable shape : shapes) { 2715888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik shape.draw(canvas); 2725888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik } 2735888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik } 2745888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik 2755888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik public void draw(Canvas canvas, ArrayList<ShapeDrawable> shapes, 276555c55ed65056e2236430f92e81c1fb6acd05dcdChris Craik ArrayList<String> strings, Resources resources) { 2775888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik canvas.scale(CANVAS_SCALE, CANVAS_SCALE); 2785888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik 2795888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik canvas.translate(BAR_WIDTH * Metrics.length, 0); 2805888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik 2815888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik canvas.save(); 2825888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik drawVerticalShiftedShapes(canvas, shapes); 2835888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik canvas.restore(); 2845888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik 2855888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik for (int metricIndex = 0; metricIndex < Metrics.length; metricIndex++) { 2865888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik String label = resources.getString( 2875888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik Metrics[metricIndex].getLabelId()); 2885888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik int xPos = (metricIndex + 1) * -BAR_WIDTH; 2895888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik int yPos = LABELOFFSET; 2905888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik canvas.drawText(label, xPos, yPos, whiteLabels); 2915888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik for (int statIndex = 0; statIndex < Stats.length; statIndex++) { 2921d36d0fc7f776016c0282ae7ad8e01af81de6bf6Chris Craik String statLabel = resources.getString( 2931d36d0fc7f776016c0282ae7ad8e01af81de6bf6Chris Craik Stats[statIndex].getLabelId()).substring(0,3); 2941d36d0fc7f776016c0282ae7ad8e01af81de6bf6Chris Craik label = statLabel + " " + resources.getString( 2951d36d0fc7f776016c0282ae7ad8e01af81de6bf6Chris Craik R.string.format_stat, mStats[metricIndex][statIndex]); 29621555abad7ba5f5377052e2644974d3ce8c37869Chris Craik yPos = LABELOFFSET + (1 + statIndex) * PlaybackView.TILE_SCALE 29721555abad7ba5f5377052e2644974d3ce8c37869Chris Craik / 2; 2985888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik canvas.drawText(label, xPos, yPos, whiteLabels); 2995888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik } 3005888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik } 301555c55ed65056e2236430f92e81c1fb6acd05dcdChris Craik for (int stringIndex = 0; stringIndex < strings.size(); stringIndex++) { 30221555abad7ba5f5377052e2644974d3ce8c37869Chris Craik int yPos = LABELOFFSET + stringIndex * PlaybackView.TILE_SCALE / 2; 303555c55ed65056e2236430f92e81c1fb6acd05dcdChris Craik canvas.drawText(strings.get(stringIndex), 0, yPos, whiteLabels); 3045888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik } 3055888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik } 3065888ec2b30d2c76de84e3b840bf286fa371ccb4fChris Craik} 307