| 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 |