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 3 # found in the LICENSE file. 4 # pylint: disable=W0401,W0614 5 from telemetry.page.actions.all_page_actions import * 6 from telemetry.page import page as page_module 7 from telemetry.page import page_set as page_set_module 8 9 10 class ToughSchedulingCasesPage(page_module.Page): 11 12 def __init__(self, url, page_set): 13 super(ToughSchedulingCasesPage, self).__init__(url=url, page_set=page_set) 14 15 def RunSmoothness(self, action_runner): 16 action_runner.RunAction(ScrollAction()) 17 18 19 class Page1(ToughSchedulingCasesPage): 20 21 """ Why: Simulate oversubscribed main thread """ 22 23 def __init__(self, page_set): 24 super(Page1, self).__init__( 25 url='file://tough_scheduling_cases/simple_text_page.html?main_busy', 26 page_set=page_set) 27 28 self.synthetic_delays = {'cc.BeginMainFrame': {'target_duration': 0.008}} 29 30 31 class Page2(ToughSchedulingCasesPage): 32 33 """ Why: Simulate oversubscribed main thread """ 34 35 def __init__(self, page_set): 36 super(Page2, self).__init__( 37 # pylint: disable=C0301 38 url='file://tough_scheduling_cases/simple_text_page.html?main_very_busy', 39 page_set=page_set) 40 41 self.synthetic_delays = {'cc.BeginMainFrame': {'target_duration': 0.024}} 42 43 44 class Page3(ToughSchedulingCasesPage): 45 46 """ Why: Simulate a page with a a few graphics layers """ 47 48 def __init__(self, page_set): 49 super(Page3, self).__init__( 50 # pylint: disable=C0301 51 url='file://tough_scheduling_cases/simple_text_page.html?medium_layers', 52 page_set=page_set) 53 54 self.synthetic_delays = { 55 'cc.DrawAndSwap': {'target_duration': 0.004}, 56 'gpu.PresentingFrame': {'target_duration': 0.004}, 57 'cc.BeginMainFrame': {'target_duration': 0.004} 58 } 59 60 61 class Page4(ToughSchedulingCasesPage): 62 63 """ Why: Simulate a page with many graphics layers """ 64 65 def __init__(self, page_set): 66 super(Page4, self).__init__( 67 # pylint: disable=C0301 68 url='file://tough_scheduling_cases/simple_text_page.html?many_layers', 69 page_set=page_set) 70 71 self.synthetic_delays = { 72 'cc.DrawAndSwap': {'target_duration': 0.012}, 73 'gpu.PresentingFrame': {'target_duration': 0.012}, 74 'cc.BeginMainFrame': {'target_duration': 0.012} 75 } 76 77 78 class Page5(ToughSchedulingCasesPage): 79 80 """ Why: Simulate a page with expensive recording and rasterization """ 81 82 def __init__(self, page_set): 83 super(Page5, self).__init__( 84 # pylint: disable=C0301 85 url='file://tough_scheduling_cases/simple_text_page.html?medium_raster', 86 page_set=page_set) 87 88 self.synthetic_delays = { 89 'cc.RasterRequiredForActivation': {'target_duration': 0.004}, 90 'cc.BeginMainFrame': {'target_duration': 0.004}, 91 'gpu.AsyncTexImage': {'target_duration': 0.004} 92 } 93 94 95 class Page6(ToughSchedulingCasesPage): 96 97 """ Why: Simulate a page with expensive recording and rasterization """ 98 99 def __init__(self, page_set): 100 super(Page6, self).__init__( 101 # pylint: disable=C0301 102 url='file://tough_scheduling_cases/simple_text_page.html?heavy_raster', 103 page_set=page_set) 104 105 self.synthetic_delays = { 106 'cc.RasterRequiredForActivation': {'target_duration': 0.024}, 107 'cc.BeginMainFrame': {'target_duration': 0.024}, 108 'gpu.AsyncTexImage': {'target_duration': 0.024} 109 } 110 111 112 class Page7(ToughSchedulingCasesPage): 113 114 """ Why: Medium cost touch handler """ 115 116 def __init__(self, page_set): 117 super(Page7, self).__init__( 118 # pylint: disable=C0301 119 url='file://tough_scheduling_cases/touch_handler_scrolling.html?medium_handler', 120 page_set=page_set) 121 122 self.synthetic_delays = {'blink.HandleInputEvent': 123 {'target_duration': 0.008}} 124 125 126 class Page8(ToughSchedulingCasesPage): 127 128 """ Why: Slow touch handler """ 129 130 def __init__(self, page_set): 131 super(Page8, self).__init__( 132 # pylint: disable=C0301 133 url='file://tough_scheduling_cases/touch_handler_scrolling.html?slow_handler', 134 page_set=page_set) 135 136 self.synthetic_delays = {'blink.HandleInputEvent': 137 {'target_duration': 0.024}} 138 139 140 class Page9(ToughSchedulingCasesPage): 141 142 """ Why: Touch handler that often takes a long time """ 143 144 def __init__(self, page_set): 145 super(Page9, self).__init__( 146 # pylint: disable=C0301 147 url='file://tough_scheduling_cases/touch_handler_scrolling.html?janky_handler', 148 page_set=page_set) 149 150 self.synthetic_delays = {'blink.HandleInputEvent': 151 {'target_duration': 0.024, 'mode': 'alternating'} 152 } 153 154 155 class Page10(ToughSchedulingCasesPage): 156 157 """ Why: Touch handler that occasionally takes a long time """ 158 159 def __init__(self, page_set): 160 super(Page10, self).__init__( 161 # pylint: disable=C0301 162 url='file://tough_scheduling_cases/touch_handler_scrolling.html?occasionally_janky_handler', 163 page_set=page_set) 164 165 self.synthetic_delays = {'blink.HandleInputEvent': 166 {'target_duration': 0.024, 'mode': 'oneshot'}} 167 168 169 class Page11(ToughSchedulingCasesPage): 170 171 """ Why: Super expensive touch handler causes browser to scroll after a 172 timeout. 173 """ 174 175 def __init__(self, page_set): 176 super(Page11, self).__init__( 177 # pylint: disable=C0301 178 url='file://tough_scheduling_cases/touch_handler_scrolling.html?super_slow_handler', 179 page_set=page_set) 180 181 self.synthetic_delays = {'blink.HandleInputEvent': 182 {'target_duration': 0.2}} 183 184 185 class Page12(ToughSchedulingCasesPage): 186 187 """ Why: Super expensive touch handler that only occupies a part of the page. 188 """ 189 190 def __init__(self, page_set): 191 super(Page12, self).__init__( 192 url='file://tough_scheduling_cases/div_touch_handler.html', 193 page_set=page_set) 194 195 self.synthetic_delays = {'blink.HandleInputEvent': {'target_duration': 0.2}} 196 197 198 class Page13(ToughSchedulingCasesPage): 199 200 """ Why: Test a moderately heavy requestAnimationFrame handler """ 201 202 def __init__(self, page_set): 203 super(Page13, self).__init__( 204 url='file://tough_scheduling_cases/raf.html?medium_handler', 205 page_set=page_set) 206 207 self.synthetic_delays = { 208 'cc.RasterRequiredForActivation': {'target_duration': 0.004}, 209 'cc.BeginMainFrame': {'target_duration': 0.004}, 210 'gpu.AsyncTexImage': {'target_duration': 0.004} 211 } 212 213 214 class Page14(ToughSchedulingCasesPage): 215 216 """ Why: Test a moderately heavy requestAnimationFrame handler """ 217 218 def __init__(self, page_set): 219 super(Page14, self).__init__( 220 url='file://tough_scheduling_cases/raf.html?heavy_handler', 221 page_set=page_set) 222 223 self.synthetic_delays = { 224 'cc.RasterRequiredForActivation': {'target_duration': 0.024}, 225 'cc.BeginMainFrame': {'target_duration': 0.024}, 226 'gpu.AsyncTexImage': {'target_duration': 0.024} 227 } 228 229 230 class Page15(ToughSchedulingCasesPage): 231 232 """ Why: Simulate a heavily GPU bound page """ 233 234 def __init__(self, page_set): 235 super(Page15, self).__init__( 236 url='file://tough_scheduling_cases/raf.html?gpu_bound', 237 page_set=page_set) 238 239 self.synthetic_delays = {'gpu.PresentingFrame': {'target_duration': 0.1}} 240 241 242 class Page16(ToughSchedulingCasesPage): 243 244 """ Why: Test a requestAnimationFrame handler with a heavy first frame """ 245 246 def __init__(self, page_set): 247 super(Page16, self).__init__( 248 url='file://tough_scheduling_cases/raf.html?heavy_first_frame', 249 page_set=page_set) 250 251 self.synthetic_delays = {'cc.BeginMainFrame': {'target_duration': 0.15}} 252 253 254 class Page17(ToughSchedulingCasesPage): 255 256 """ Why: Medium stress test for the scheduler """ 257 258 def __init__(self, page_set): 259 super(Page17, self).__init__( 260 url='file://tough_scheduling_cases/raf_touch_animation.html?medium', 261 page_set=page_set) 262 263 self.synthetic_delays = { 264 'cc.DrawAndSwap': {'target_duration': 0.004}, 265 'cc.BeginMainFrame': {'target_duration': 0.004} 266 } 267 268 269 class Page18(ToughSchedulingCasesPage): 270 271 """ Why: Heavy stress test for the scheduler """ 272 273 def __init__(self, page_set): 274 super(Page18, self).__init__( 275 url='file://tough_scheduling_cases/raf_touch_animation.html?heavy', 276 page_set=page_set) 277 278 self.synthetic_delays = { 279 'cc.DrawAndSwap': {'target_duration': 0.012}, 280 'cc.BeginMainFrame': {'target_duration': 0.012} 281 } 282 283 284 class Page19(ToughSchedulingCasesPage): 285 286 """ Why: Both main and impl thread animating concurrently """ 287 288 def __init__(self, page_set): 289 super(Page19, self).__init__( 290 url='file://tough_scheduling_cases/split_animation.html', 291 page_set=page_set) 292 293 def RunSmoothness(self, action_runner): 294 action_runner.Wait(3) 295 296 class Page20(ToughSchedulingCasesPage): 297 298 """ Why: Simple JS touch dragging """ 299 300 def __init__(self, page_set): 301 super(Page20, self).__init__( 302 url='file://tough_scheduling_cases/simple_touch_drag.html', 303 page_set=page_set) 304 305 def RunSmoothness(self, action_runner): 306 action_runner.RunAction(ScrollAction( 307 { 308 'scrollable_element_function': ''' 309 function(callback) { 310 callback(document.getElementById('card')); 311 }''', 312 'scroll_requires_touch': True, 313 'direction': 'up', 314 'speed': 150, 315 'scroll_distance_function': 'function() { return 400; }' 316 })) 317 318 class EmptyTouchHandlerPage(ToughSchedulingCasesPage): 319 320 """ Why: Scrolling on a page with a touch handler that consumes no events but 321 may be slow """ 322 323 def __init__(self, name, desktop, slow_handler, bounce, page_set): 324 super(EmptyTouchHandlerPage, self).__init__( 325 url='file://tough_scheduling_cases/empty_touch_handler' + 326 ('_desktop' if desktop else '') + '.html?' + name, 327 page_set=page_set) 328 329 if slow_handler: 330 self.synthetic_delays = { 331 'blink.HandleInputEvent': {'target_duration': 0.2} 332 } 333 334 self.bounce = bounce 335 336 def RunSmoothness(self, action_runner): 337 if self.bounce: 338 action = ScrollBounceAction() 339 else: 340 action = ScrollAction( 341 { 342 'scroll_requires_touch': True, 343 """ Speed and distance are tuned to run exactly as long as a scroll 344 bounce """ 345 'speed': 400, 346 'scroll_distance_function': 'function() { return 2100; }' 347 }) 348 349 action_runner.RunAction(action) 350 351 class ToughSchedulingCasesPageSet(page_set_module.PageSet): 352 353 """ Tough scheduler latency test cases """ 354 355 def __init__(self): 356 super(ToughSchedulingCasesPageSet, self).__init__() 357 358 # Why: Simple scrolling baseline 359 self.AddPage(ToughSchedulingCasesPage( 360 'file://tough_scheduling_cases/simple_text_page.html', 361 self)) 362 self.AddPage(Page1(self)) 363 self.AddPage(Page2(self)) 364 self.AddPage(Page3(self)) 365 self.AddPage(Page4(self)) 366 self.AddPage(Page5(self)) 367 # self.AddPage(Page6(self)) Flaky crbug.com/368532 368 # Why: Touch handler scrolling baseline 369 self.AddPage(ToughSchedulingCasesPage( 370 'file://tough_scheduling_cases/touch_handler_scrolling.html', 371 self)) 372 self.AddPage(Page7(self)) 373 self.AddPage(Page8(self)) 374 self.AddPage(Page9(self)) 375 self.AddPage(Page10(self)) 376 self.AddPage(Page11(self)) 377 self.AddPage(Page12(self)) 378 # Why: requestAnimationFrame scrolling baseline 379 self.AddPage(ToughSchedulingCasesPage( 380 'file://tough_scheduling_cases/raf.html', 381 self)) 382 # Why: Test canvas blocking behavior 383 self.AddPage(ToughSchedulingCasesPage( 384 'file://tough_scheduling_cases/raf_canvas.html', 385 self)) 386 self.AddPage(Page13(self)) 387 # Disabled for flakiness. See 368532 388 # self.AddPage(Page14(self)) 389 self.AddPage(Page15(self)) 390 self.AddPage(Page16(self)) 391 # Why: Test a requestAnimationFrame handler with concurrent CSS animation 392 self.AddPage(ToughSchedulingCasesPage( 393 'file://tough_scheduling_cases/raf_animation.html', 394 self)) 395 # Why: Stress test for the scheduler 396 self.AddPage(ToughSchedulingCasesPage( 397 'file://tough_scheduling_cases/raf_touch_animation.html', 398 self)) 399 self.AddPage(Page17(self)) 400 self.AddPage(Page18(self)) 401 self.AddPage(Page19(self)) 402 self.AddPage(Page20(self)) 403 # Why: Baseline for scrolling in the presence of a no-op touch handler 404 self.AddPage(EmptyTouchHandlerPage( 405 name='baseline', 406 desktop=False, 407 slow_handler=False, 408 bounce=False, 409 page_set=self)) 410 # Why: Slow handler blocks scroll start 411 self.AddPage(EmptyTouchHandlerPage( 412 name='slow_handler', 413 desktop=False, 414 slow_handler=True, 415 bounce=False, 416 page_set=self)) 417 # Why: Slow handler blocks scroll start until touch ACK timeout 418 self.AddPage(EmptyTouchHandlerPage( 419 name='desktop_slow_handler', 420 desktop=True, 421 slow_handler=True, 422 bounce=False, 423 page_set=self)) 424 # Why: Scroll bounce showing repeated transitions between scrolling and 425 # sending synchronous touchmove events. Should be nearly as fast as 426 # scroll baseline. 427 self.AddPage(EmptyTouchHandlerPage( 428 name='bounce', 429 desktop=False, 430 slow_handler=False, 431 bounce=True, 432 page_set=self)) 433 # Why: Scroll bounce with slow handler, repeated blocking. 434 self.AddPage(EmptyTouchHandlerPage( 435 name='bounce_slow_handler', 436 desktop=False, 437 slow_handler=True, 438 bounce=True, 439 page_set=self)) 440 # Why: Scroll bounce with slow handler on desktop, blocks only once until 441 # ACK timeout. 442 self.AddPage(EmptyTouchHandlerPage( 443 name='bounce_desktop_slow_handler', 444 desktop=True, 445 slow_handler=True, 446 bounce=True, 447 page_set=self)) 448