• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.test.tilebenchmark;
18 
19 import android.animation.ArgbEvaluator;
20 import android.animation.ObjectAnimator;
21 import android.animation.ValueAnimator;
22 import android.content.Context;
23 import android.graphics.Canvas;
24 import android.graphics.Color;
25 import android.graphics.Paint;
26 import android.graphics.drawable.ShapeDrawable;
27 import android.util.AttributeSet;
28 import android.view.GestureDetector;
29 import android.view.GestureDetector.OnGestureListener;
30 import android.view.MotionEvent;
31 import android.view.View;
32 
33 import com.test.tilebenchmark.RunData.TileData;
34 
35 import java.util.ArrayList;
36 
37 public class PlaybackView extends View {
38     public static final int TILE_SCALE = 256;
39     private static final int INVAL_FLAG = -2;
40     private static final int INVAL_CYCLE = 250;
41 
42     private Paint levelPaint = null, coordPaint = null, goldPaint = null;
43     private PlaybackGraphs mGraphs;
44 
45     private ArrayList<ShapeDrawable> mTempShapes = new ArrayList<ShapeDrawable>();
46     private RunData mProfData = null;
47     private GestureDetector mGestureDetector = null;
48     private ArrayList<String> mRenderStrings = new ArrayList<String>();
49 
50     private class TileDrawable extends ShapeDrawable {
51         TileData tile;
52         String label;
53 
TileDrawable(TileData t, int colorId)54         public TileDrawable(TileData t, int colorId) {
55             this.tile = t;
56             getPaint().setColor(getResources().getColor(colorId));
57             if (colorId == R.color.ready_tile
58                     || colorId == R.color.unready_tile) {
59 
60                 label = (int) (t.left / TILE_SCALE) + ", "
61                         + (int) (t.top / TILE_SCALE);
62                 // ignore scale value for tiles
63                 setBounds(t.left, t.top,
64                         t.right, t.bottom);
65             } else {
66                 setBounds((int) (t.left * t.scale),
67                         (int) (t.top * t.scale),
68                         (int) (t.right * t.scale),
69                         (int) (t.bottom * t.scale));
70             }
71         }
72 
73         @SuppressWarnings("unused")
setColor(int color)74         public void setColor(int color) {
75             getPaint().setColor(color);
76         }
77 
78         @Override
draw(Canvas canvas)79         public void draw(Canvas canvas) {
80             super.draw(canvas);
81             if (label != null) {
82                 canvas.drawText(Integer.toString(tile.level), getBounds().left,
83                         getBounds().bottom, levelPaint);
84                 canvas.drawText(label, getBounds().left,
85                         ((getBounds().bottom + getBounds().top) / 2),
86                         coordPaint);
87             }
88         }
89     }
90 
PlaybackView(Context context)91     public PlaybackView(Context context) {
92         super(context);
93         init();
94     }
95 
PlaybackView(Context context, AttributeSet attrs)96     public PlaybackView(Context context, AttributeSet attrs) {
97         super(context, attrs);
98         init();
99     }
100 
PlaybackView(Context context, AttributeSet attrs, int defStyle)101     public PlaybackView(Context context, AttributeSet attrs, int defStyle) {
102         super(context, attrs, defStyle);
103         init();
104     }
105 
setOnGestureListener(OnGestureListener gl)106     public void setOnGestureListener(OnGestureListener gl) {
107         mGestureDetector = new GestureDetector(getContext(), gl);
108     }
109 
110     @Override
onTouchEvent(MotionEvent event)111     public boolean onTouchEvent(MotionEvent event) {
112         mGestureDetector.onTouchEvent(event);
113         return true;
114     }
115 
init()116     private void init() {
117         levelPaint = new Paint();
118         levelPaint.setColor(Color.WHITE);
119         levelPaint.setTextSize(TILE_SCALE / 2);
120         coordPaint = new Paint();
121         coordPaint.setColor(Color.BLACK);
122         coordPaint.setTextSize(TILE_SCALE / 3);
123         goldPaint = new Paint();
124         goldPaint.setColor(0xffa0e010);
125         mGraphs = new PlaybackGraphs();
126     }
127 
128     @Override
onDraw(Canvas canvas)129     protected void onDraw(Canvas canvas) {
130         super.onDraw(canvas);
131 
132         if (mTempShapes == null || mTempShapes.isEmpty()) {
133             return;
134         }
135 
136         mGraphs.draw(canvas, mTempShapes, mRenderStrings, getResources());
137         invalidate(); // may have animations, force redraw
138     }
139 
statString(int labelId, int value)140     private String statString(int labelId, int value) {
141         return getResources().getString(R.string.format_stat_name,
142                 getResources().getString(labelId), value);
143     }
tileString(int formatStringId, TileData t)144     private String tileString(int formatStringId, TileData t) {
145         return getResources().getString(formatStringId,
146                 t.left, t.top, t.right, t.bottom);
147     }
148 
setFrame(int frame)149     public int setFrame(int frame) {
150         if (mProfData == null || mProfData.frames.length == 0) {
151             return 0;
152         }
153 
154         int readyTiles = 0, unreadyTiles = 0, unplacedTiles = 0, numInvals = 0;
155         mTempShapes.clear();
156         mRenderStrings.clear();
157 
158         // create tile shapes (as they're drawn on bottom)
159         for (TileData t : mProfData.frames[frame]) {
160             if (t == mProfData.frames[frame][0]){
161                 // viewport 'tile', add coords to render strings
162                 mRenderStrings.add(tileString(R.string.format_view_pos, t));
163             } else  if (t.level != INVAL_FLAG) {
164                 int colorId;
165                 if (t.isReady) {
166                     readyTiles++;
167                     colorId = R.color.ready_tile;
168                 } else {
169                     unreadyTiles++;
170                     colorId = R.color.unready_tile;
171                 }
172                 if (t.left < 0 || t.top < 0) {
173                     unplacedTiles++;
174                 }
175                 mTempShapes.add(new TileDrawable(t, colorId));
176             } else {
177                 // inval 'tile', count and add coords to render strings
178                 numInvals++;
179                 mRenderStrings.add(tileString(R.string.format_inval_pos, t));
180             }
181         }
182 
183         // create invalidate shapes (drawn above tiles)
184         int invalId = 0;
185         for (TileData t : mProfData.frames[frame]) {
186             if (t.level == INVAL_FLAG && t != mProfData.frames[frame][0]) {
187                 TileDrawable invalShape = new TileDrawable(t,
188                         R.color.inval_region_start);
189                 ValueAnimator tileAnimator = ObjectAnimator.ofInt(invalShape,
190                         "color",
191                         getResources().getColor(R.color.inval_region_start),
192                         getResources().getColor(R.color.inval_region_stop));
193                 tileAnimator.setDuration(numInvals * INVAL_CYCLE);
194                 tileAnimator.setEvaluator(new ArgbEvaluator());
195                 tileAnimator.setRepeatCount(ValueAnimator.INFINITE);
196                 tileAnimator.setRepeatMode(ValueAnimator.RESTART);
197                 float delay = (float) (invalId) * INVAL_CYCLE;
198                 tileAnimator.setStartDelay((int) delay);
199                 invalId++;
200                 tileAnimator.start();
201 
202                 mTempShapes.add(invalShape);
203             }
204         }
205 
206         mRenderStrings.add(statString(R.string.ready_tiles, readyTiles));
207         mRenderStrings.add(statString(R.string.unready_tiles, unreadyTiles));
208         mRenderStrings.add(statString(R.string.unplaced_tiles, unplacedTiles));
209         mRenderStrings.add(statString(R.string.number_invalidates, numInvals));
210 
211         // draw view rect (using first TileData object, on top)
212         TileDrawable viewShape = new TileDrawable(mProfData.frames[frame][0],
213                 R.color.view);
214         mTempShapes.add(viewShape);
215         this.invalidate();
216         return frame;
217     }
218 
setData(RunData tileProfilingData)219     public void setData(RunData tileProfilingData) {
220         mProfData = tileProfilingData;
221 
222         mGraphs.setData(mProfData);
223     }
224 }
225