OLD | NEW |
1 <!DOCTYPE html> | 1 <!DOCTYPE html> |
2 <!-- | 2 <!-- |
3 Copyright (c) 2015 The Chromium Authors. All rights reserved. | 3 Copyright (c) 2015 The Chromium Authors. All rights reserved. |
4 Use of this source code is governed by a BSD-style license that can be | 4 Use of this source code is governed by a BSD-style license that can be |
5 found in the LICENSE file. | 5 found in the LICENSE file. |
6 --> | 6 --> |
7 | 7 |
8 <link rel="import" href="/tracing/base/sorted_array_utils.html"> | 8 <link rel="import" href="/tracing/base/sorted_array_utils.html"> |
9 | 9 |
10 <script> | 10 <script> |
11 'use strict'; | 11 'use strict'; |
12 | 12 |
13 /** | 13 /** |
14 * @fileoverview Class for representing SurfaceFlinger process and its Vsyncs. | 14 * @fileoverview Class for representing SurfaceFlinger process and its Vsyncs. |
15 */ | 15 */ |
16 tr.exportTo('tr.model.helpers', function() { | 16 tr.exportTo('tr.model.helpers', function() { |
17 var findLowIndexInSortedArray = tr.b.findLowIndexInSortedArray; | 17 var findLowIndexInSortedArray = tr.b.findLowIndexInSortedArray; |
18 | 18 |
19 var VSYNC_SF_NAME = 'android.VSYNC-sf'; | 19 var VSYNC_SF_NAME = 'android.VSYNC-sf'; |
20 var VSYNC_APP_NAME = 'android.VSYNC-app'; | 20 var VSYNC_APP_NAME = 'android.VSYNC-app'; |
21 var VSYNC_FALLBACK_NAME = 'android.VSYNC'; | 21 var VSYNC_FALLBACK_NAME = 'android.VSYNC'; |
22 | 22 |
23 // when sampling vsync, push samples back by this much to ensure | 23 // when sampling vsync, push samples back by this much to ensure |
24 // frame start samples *between* vsyncs | 24 // frame start samples *between* vsyncs |
25 var TIMESTAMP_FUDGE_MS = 0.01; | 25 var TIMESTAMP_FUDGE_MS = 0.01; |
26 | 26 |
27 function getVsyncTimestamps(process, counterName) { | 27 function getVsyncTimestamps(process, counterName) { |
28 var vsync = process.counters[counterName]; | 28 var vsync = process.counters[counterName]; |
29 if (!vsync) | 29 if (!vsync) { |
30 vsync = process.counters[VSYNC_FALLBACK_NAME]; | 30 vsync = process.counters[VSYNC_FALLBACK_NAME]; |
| 31 } |
31 | 32 |
32 if (vsync && vsync.numSeries === 1 && vsync.numSamples > 1) | 33 if (vsync && vsync.numSeries === 1 && vsync.numSamples > 1) { |
33 return vsync.series[0].timestamps; | 34 return vsync.series[0].timestamps; |
| 35 } |
34 return undefined; | 36 return undefined; |
35 } | 37 } |
36 | 38 |
37 /** | 39 /** |
38 * Model for SurfaceFlinger specific data. | 40 * Model for SurfaceFlinger specific data. |
39 * @constructor | 41 * @constructor |
40 */ | 42 */ |
41 function AndroidSurfaceFlinger(process, thread) { | 43 function AndroidSurfaceFlinger(process, thread) { |
42 this.process = process; | 44 this.process = process; |
43 this.thread = thread; | 45 this.thread = thread; |
44 | 46 |
45 this.appVsync_ = undefined; | 47 this.appVsync_ = undefined; |
46 this.sfVsync_ = undefined; | 48 this.sfVsync_ = undefined; |
47 | 49 |
48 this.appVsyncTimestamps_ = getVsyncTimestamps(process, VSYNC_APP_NAME); | 50 this.appVsyncTimestamps_ = getVsyncTimestamps(process, VSYNC_APP_NAME); |
49 this.sfVsyncTimestamps_ = getVsyncTimestamps(process, VSYNC_SF_NAME); | 51 this.sfVsyncTimestamps_ = getVsyncTimestamps(process, VSYNC_SF_NAME); |
50 | 52 |
51 // separation of vsync of app vs sf - assume app has at least window of 5ms | 53 // separation of vsync of app vs sf - assume app has at least window of 5ms |
52 this.deadlineDelayMs_ = | 54 this.deadlineDelayMs_ = |
53 this.appVsyncTimestamps_ !== this.sfVsyncTimestamps_ ? | 55 this.appVsyncTimestamps_ !== this.sfVsyncTimestamps_ ? |
54 5 : TIMESTAMP_FUDGE_MS; | 56 5 : TIMESTAMP_FUDGE_MS; |
55 } | 57 } |
56 | 58 |
57 AndroidSurfaceFlinger.createForProcessIfPossible = function(process) { | 59 AndroidSurfaceFlinger.createForProcessIfPossible = function(process) { |
58 var mainThread = process.getThread(process.pid); | 60 var mainThread = process.getThread(process.pid); |
59 | 61 |
60 // newer versions - main thread, lowercase name, preceeding forward slash | 62 // newer versions - main thread, lowercase name, preceeding forward slash |
61 if (mainThread && mainThread.name && | 63 if (mainThread && mainThread.name && |
62 /surfaceflinger/.test(mainThread.name)) | 64 /surfaceflinger/.test(mainThread.name)) { |
63 return new AndroidSurfaceFlinger(process, mainThread); | 65 return new AndroidSurfaceFlinger(process, mainThread); |
| 66 } |
64 | 67 |
65 // older versions - another thread is named SurfaceFlinger | 68 // older versions - another thread is named SurfaceFlinger |
66 var primaryThreads = process.findAllThreadsNamed('SurfaceFlinger'); | 69 var primaryThreads = process.findAllThreadsNamed('SurfaceFlinger'); |
67 if (primaryThreads.length === 1) | 70 if (primaryThreads.length === 1) { |
68 return new AndroidSurfaceFlinger(process, primaryThreads[0]); | 71 return new AndroidSurfaceFlinger(process, primaryThreads[0]); |
| 72 } |
69 return undefined; | 73 return undefined; |
70 }; | 74 }; |
71 | 75 |
72 AndroidSurfaceFlinger.prototype = { | 76 AndroidSurfaceFlinger.prototype = { |
73 get hasVsyncs() { | 77 get hasVsyncs() { |
74 return !!this.appVsyncTimestamps_ && !!this.sfVsyncTimestamps_; | 78 return !!this.appVsyncTimestamps_ && !!this.sfVsyncTimestamps_; |
75 }, | 79 }, |
76 | 80 |
77 getFrameKickoff: function(timestamp) { | 81 getFrameKickoff: function(timestamp) { |
78 if (!this.hasVsyncs) | 82 if (!this.hasVsyncs) { |
79 throw new Error('cannot query vsync info without vsyncs'); | 83 throw new Error('cannot query vsync info without vsyncs'); |
| 84 } |
80 | 85 |
81 var firstGreaterIndex = | 86 var firstGreaterIndex = |
82 findLowIndexInSortedArray(this.appVsyncTimestamps_, | 87 findLowIndexInSortedArray(this.appVsyncTimestamps_, |
83 function(x) { return x; }, | 88 function(x) { return x; }, |
84 timestamp + TIMESTAMP_FUDGE_MS); | 89 timestamp + TIMESTAMP_FUDGE_MS); |
85 | 90 |
86 if (firstGreaterIndex < 1) | 91 if (firstGreaterIndex < 1) return undefined; |
87 return undefined; | |
88 return this.appVsyncTimestamps_[firstGreaterIndex - 1]; | 92 return this.appVsyncTimestamps_[firstGreaterIndex - 1]; |
89 }, | 93 }, |
90 | 94 |
91 getFrameDeadline: function(timestamp) { | 95 getFrameDeadline: function(timestamp) { |
92 if (!this.hasVsyncs) | 96 if (!this.hasVsyncs) { |
93 throw new Error('cannot query vsync info without vsyncs'); | 97 throw new Error('cannot query vsync info without vsyncs'); |
| 98 } |
94 | 99 |
95 var firstGreaterIndex = | 100 var firstGreaterIndex = |
96 findLowIndexInSortedArray(this.sfVsyncTimestamps_, | 101 findLowIndexInSortedArray(this.sfVsyncTimestamps_, |
97 function(x) { return x; }, | 102 function(x) { return x; }, |
98 timestamp + this.deadlineDelayMs_); | 103 timestamp + this.deadlineDelayMs_); |
99 if (firstGreaterIndex >= this.sfVsyncTimestamps_.length) | 104 if (firstGreaterIndex >= this.sfVsyncTimestamps_.length) { |
100 return undefined; | 105 return undefined; |
| 106 } |
101 return this.sfVsyncTimestamps_[firstGreaterIndex]; | 107 return this.sfVsyncTimestamps_[firstGreaterIndex]; |
102 } | 108 } |
103 }; | 109 }; |
104 | 110 |
105 return { | 111 return { |
106 AndroidSurfaceFlinger, | 112 AndroidSurfaceFlinger, |
107 }; | 113 }; |
108 }); | 114 }); |
109 </script> | 115 </script> |
OLD | NEW |