| OLD | NEW |
| 1 # Copyright 2014 The Chromium Authors. All rights reserved. | 1 # Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
| 4 import collections | 4 import collections |
| 5 | 5 |
| 6 from metrics import Metric | 6 from metrics import Metric |
| 7 from telemetry.page import page_measurement | 7 from telemetry.page import page_measurement |
| 8 | 8 |
| 9 TRACING_MODE = 'tracing-mode' | 9 TRACING_MODE = 'tracing-mode' |
| 10 TIMELINE_MODE = 'timeline-mode' | 10 TIMELINE_MODE = 'timeline-mode' |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 142 "IO"] | 142 "IO"] |
| 143 | 143 |
| 144 AllThreads = TimelineThreadCategories.values() | 144 AllThreads = TimelineThreadCategories.values() |
| 145 NoThreads = [] | 145 NoThreads = [] |
| 146 MainThread = ["renderer_main"] | 146 MainThread = ["renderer_main"] |
| 147 FastPathResults = AllThreads | 147 FastPathResults = AllThreads |
| 148 FastPathDetails = NoThreads | 148 FastPathDetails = NoThreads |
| 149 SilkResults = ["renderer_main", "total_all"] | 149 SilkResults = ["renderer_main", "total_all"] |
| 150 SilkDetails = MainThread | 150 SilkDetails = MainThread |
| 151 | 151 |
| 152 # TODO(epenner): Thread names above are likely fairly stable but trace names |
| 153 # could change. We should formalize this trace to keep this robust. |
| 154 GpuFrameTraceName = ":RealSwapBuffers" |
| 155 # TODO(epenner): The decoder swap-buffers can be used by several producers. |
| 156 # we need to find the canonical swap buffers on Mac. |
| 157 GpuFrameTraceNameMac = "GLES2DecoderImpl::DoSwapBuffers" |
| 158 |
| 152 def ThreadCategoryName(thread_name): | 159 def ThreadCategoryName(thread_name): |
| 153 thread_category = "other" | 160 thread_category = "other" |
| 154 for substring, category in TimelineThreadCategories.iteritems(): | 161 for substring, category in TimelineThreadCategories.iteritems(): |
| 155 if substring in MatchBySubString and substring in thread_name: | 162 if substring in MatchBySubString and substring in thread_name: |
| 156 thread_category = category | 163 thread_category = category |
| 157 if thread_name in TimelineThreadCategories: | 164 if thread_name in TimelineThreadCategories: |
| 158 thread_category = TimelineThreadCategories[thread_name] | 165 thread_category = TimelineThreadCategories[thread_name] |
| 159 return thread_category | 166 return thread_category |
| 160 | 167 |
| 161 def ThreadTimeResultName(thread_category): | 168 def ThreadTimeResultName(thread_category): |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 219 idle_time_result = float(idle_time) / num_frames | 226 idle_time_result = float(idle_time) / num_frames |
| 220 results.Add(ThreadDetailResultName(self.name, "idle"), | 227 results.Add(ThreadDetailResultName(self.name, "idle"), |
| 221 'ms', idle_time_result) | 228 'ms', idle_time_result) |
| 222 | 229 |
| 223 class ThreadTimesTimelineMetric(TimelineMetric): | 230 class ThreadTimesTimelineMetric(TimelineMetric): |
| 224 def __init__(self): | 231 def __init__(self): |
| 225 super(ThreadTimesTimelineMetric, self).__init__(TRACING_MODE) | 232 super(ThreadTimesTimelineMetric, self).__init__(TRACING_MODE) |
| 226 self.results_to_report = AllThreads | 233 self.results_to_report = AllThreads |
| 227 self.details_to_report = NoThreads | 234 self.details_to_report = NoThreads |
| 228 | 235 |
| 229 def CalcFrameCount(self): | 236 def CountSlices(self, slices, substring): |
| 230 gpu_swaps = 0 | 237 count = 0 |
| 231 for thread in self._model.GetAllThreads(): | 238 for event in slices: |
| 232 if (ThreadCategoryName(thread.name) == "GPU"): | 239 if substring in event.name: |
| 233 for event in thread.IterAllSlices(): | 240 count += 1 |
| 234 if ":RealSwapBuffers" in event.name: | 241 return count |
| 235 gpu_swaps += 1 | |
| 236 return gpu_swaps | |
| 237 | 242 |
| 238 def AddResults(self, tab, results): | 243 def AddResults(self, tab, results): |
| 239 num_frames = self.CalcFrameCount() | |
| 240 if not num_frames: | |
| 241 raise MissingFramesError() | |
| 242 | |
| 243 # Set up each thread category for consistant results. | 244 # Set up each thread category for consistant results. |
| 244 thread_category_results = {} | 245 thread_category_results = {} |
| 245 for name in TimelineThreadCategories.values(): | 246 for name in TimelineThreadCategories.values(): |
| 246 thread_category_results[name] = ResultsForThread(self.model, name) | 247 thread_category_results[name] = ResultsForThread(self.model, name) |
| 247 | 248 |
| 248 # Group the slices by their thread category. | 249 # Group the slices by their thread category. |
| 249 for thread in self._model.GetAllThreads(): | 250 for thread in self._model.GetAllThreads(): |
| 250 thread_category = ThreadCategoryName(thread.name) | 251 thread_category = ThreadCategoryName(thread.name) |
| 251 thread_category_results[thread_category].AppendThreadSlices(thread) | 252 thread_category_results[thread_category].AppendThreadSlices(thread) |
| 252 | 253 |
| 253 # Group all threads. | 254 # Group all threads. |
| 254 for thread in self._model.GetAllThreads(): | 255 for thread in self._model.GetAllThreads(): |
| 255 thread_category_results['total_all'].AppendThreadSlices(thread) | 256 thread_category_results['total_all'].AppendThreadSlices(thread) |
| 256 | 257 |
| 257 # Also group fast-path threads. | 258 # Also group fast-path threads. |
| 258 for thread in self._model.GetAllThreads(): | 259 for thread in self._model.GetAllThreads(): |
| 259 if ThreadCategoryName(thread.name) in FastPath: | 260 if ThreadCategoryName(thread.name) in FastPath: |
| 260 thread_category_results['total_fast_path'].AppendThreadSlices(thread) | 261 thread_category_results['total_fast_path'].AppendThreadSlices(thread) |
| 261 | 262 |
| 263 # Calculate the number of frames from the GPU thread. |
| 264 gpu_slices = thread_category_results['GPU'].all_slices |
| 265 num_frames = self.CountSlices(gpu_slices, GpuFrameTraceName) |
| 266 if not num_frames: |
| 267 num_frames = self.CountSlices(gpu_slices, GpuFrameTraceNameMac) |
| 268 if not num_frames: |
| 269 raise MissingFramesError() |
| 270 |
| 262 # Report the desired results and details. | 271 # Report the desired results and details. |
| 263 for thread_results in thread_category_results.values(): | 272 for thread_results in thread_category_results.values(): |
| 264 if thread_results.name in self.results_to_report: | 273 if thread_results.name in self.results_to_report: |
| 265 thread_results.AddResults(num_frames, results) | 274 thread_results.AddResults(num_frames, results) |
| 266 # TOOD(nduca): When generic results objects are done, this special case | 275 # TOOD(nduca): When generic results objects are done, this special case |
| 267 # can be replaced with a generic UI feature. | 276 # can be replaced with a generic UI feature. |
| 268 if thread_results.name in self.details_to_report: | 277 if thread_results.name in self.details_to_report: |
| 269 thread_results.AddDetailedResults(num_frames, results) | 278 thread_results.AddDetailedResults(num_frames, results) |
| OLD | NEW |