12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright 2011 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/scheduler/scheduler_state_machine.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 78bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "base/debug/trace_event.h" 85f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/debug/trace_event_argument.h" 97d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/format_macros.h" 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/logging.h" 11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h" 123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "base/values.h" 131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "ui/gfx/frame_time.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace cc { 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SchedulerStateMachine::SchedulerStateMachine(const SchedulerSettings& settings) 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : settings_(settings), 19424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) output_surface_state_(OUTPUT_SURFACE_LOST), 208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) begin_impl_frame_state_(BEGIN_IMPL_FRAME_STATE_IDLE), 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) commit_state_(COMMIT_STATE_IDLE), 2258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) forced_redraw_state_(FORCED_REDRAW_STATE_IDLE), 237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) commit_count_(0), 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) current_frame_number_(0), 255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu last_frame_number_animate_performed_(-1), 2658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) last_frame_number_swap_performed_(-1), 27cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) last_frame_number_swap_requested_(-1), 288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) last_frame_number_begin_main_frame_sent_(-1), 2968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) last_frame_number_update_visible_tiles_was_called_(-1), 305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) manage_tiles_funnel_(0), 315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) consecutive_checkerboard_animations_(0), 320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch max_pending_swaps_(1), 330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch pending_swaps_(0), 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) needs_redraw_(false), 355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu needs_animate_(false), 36d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) needs_manage_tiles_(false), 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) swap_used_incomplete_tile_(false), 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) needs_commit_(false), 39d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) inside_poll_for_anticipated_draw_triggers_(false), 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) visible_(false), 41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) can_start_(false), 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) can_draw_(false), 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) has_pending_tree_(false), 44424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) pending_tree_is_ready_for_activation_(false), 4558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) active_tree_needs_first_draw_(false), 461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) did_create_and_initialize_first_output_surface_(false), 471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci impl_latency_takes_priority_(false), 48a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) skip_next_begin_main_frame_to_reduce_latency_(false), 49c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch skip_begin_main_frame_to_reduce_latency_(false), 50cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) continuous_painting_(false) { 515c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 53424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)const char* SchedulerStateMachine::OutputSurfaceStateToString( 54424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) OutputSurfaceState state) { 55424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) switch (state) { 56424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) case OUTPUT_SURFACE_ACTIVE: 57424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return "OUTPUT_SURFACE_ACTIVE"; 58424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) case OUTPUT_SURFACE_LOST: 59424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return "OUTPUT_SURFACE_LOST"; 60424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) case OUTPUT_SURFACE_CREATING: 61424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return "OUTPUT_SURFACE_CREATING"; 62424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) case OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT: 63424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return "OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT"; 64424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) case OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION: 65424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return "OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION"; 66424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 67424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) NOTREACHED(); 68424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return "???"; 69424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 70424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 718bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)const char* SchedulerStateMachine::BeginImplFrameStateToString( 728bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) BeginImplFrameState state) { 7368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) switch (state) { 748bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) case BEGIN_IMPL_FRAME_STATE_IDLE: 758bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return "BEGIN_IMPL_FRAME_STATE_IDLE"; 768bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) case BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING: 778bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return "BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING"; 788bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) case BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME: 798bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return "BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME"; 808bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) case BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE: 818bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return "BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE"; 8268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 8368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) NOTREACHED(); 8468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return "???"; 8568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 8668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)const char* SchedulerStateMachine::CommitStateToString(CommitState state) { 883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) switch (state) { 893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case COMMIT_STATE_IDLE: 903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return "COMMIT_STATE_IDLE"; 91a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) case COMMIT_STATE_BEGIN_MAIN_FRAME_SENT: 92a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return "COMMIT_STATE_BEGIN_MAIN_FRAME_SENT"; 93a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) case COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED: 94a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return "COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED"; 953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case COMMIT_STATE_READY_TO_COMMIT: 963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return "COMMIT_STATE_READY_TO_COMMIT"; 97a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) case COMMIT_STATE_WAITING_FOR_ACTIVATION: 98a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return "COMMIT_STATE_WAITING_FOR_ACTIVATION"; 993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case COMMIT_STATE_WAITING_FOR_FIRST_DRAW: 1003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return "COMMIT_STATE_WAITING_FOR_FIRST_DRAW"; 1013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 1023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) NOTREACHED(); 1033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return "???"; 1043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 1053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 10658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)const char* SchedulerStateMachine::ForcedRedrawOnTimeoutStateToString( 10758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ForcedRedrawOnTimeoutState state) { 10858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) switch (state) { 10958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) case FORCED_REDRAW_STATE_IDLE: 11058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return "FORCED_REDRAW_STATE_IDLE"; 11158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) case FORCED_REDRAW_STATE_WAITING_FOR_COMMIT: 11258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return "FORCED_REDRAW_STATE_WAITING_FOR_COMMIT"; 11358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) case FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION: 11458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return "FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION"; 11558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) case FORCED_REDRAW_STATE_WAITING_FOR_DRAW: 11658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return "FORCED_REDRAW_STATE_WAITING_FOR_DRAW"; 11758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 11858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) NOTREACHED(); 11958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return "???"; 12058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 12158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 1223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)const char* SchedulerStateMachine::ActionToString(Action action) { 1233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) switch (action) { 1243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case ACTION_NONE: 1253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return "ACTION_NONE"; 1265c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu case ACTION_ANIMATE: 1275c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return "ACTION_ANIMATE"; 1288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) case ACTION_SEND_BEGIN_MAIN_FRAME: 1298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return "ACTION_SEND_BEGIN_MAIN_FRAME"; 1303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case ACTION_COMMIT: 1313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return "ACTION_COMMIT"; 1323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case ACTION_UPDATE_VISIBLE_TILES: 1333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return "ACTION_UPDATE_VISIBLE_TILES"; 134116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch case ACTION_ACTIVATE_SYNC_TREE: 135116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return "ACTION_ACTIVATE_SYNC_TREE"; 13658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) case ACTION_DRAW_AND_SWAP_IF_POSSIBLE: 13758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return "ACTION_DRAW_AND_SWAP_IF_POSSIBLE"; 13858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) case ACTION_DRAW_AND_SWAP_FORCED: 13958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return "ACTION_DRAW_AND_SWAP_FORCED"; 1403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case ACTION_DRAW_AND_SWAP_ABORT: 1413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return "ACTION_DRAW_AND_SWAP_ABORT"; 1423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case ACTION_BEGIN_OUTPUT_SURFACE_CREATION: 1433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return "ACTION_BEGIN_OUTPUT_SURFACE_CREATION"; 144d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) case ACTION_MANAGE_TILES: 145d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return "ACTION_MANAGE_TILES"; 1463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 1473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) NOTREACHED(); 1483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return "???"; 1493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 1503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)scoped_refptr<base::debug::ConvertableToTraceFormat> 1525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)SchedulerStateMachine::AsValue() const { 1535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_refptr<base::debug::TracedValue> state = 1545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) new base::debug::TracedValue(); 1551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci AsValueInto(state.get(), gfx::FrameTime::Now()); 1565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return state; 1575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 1585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid SchedulerStateMachine::AsValueInto(base::debug::TracedValue* state, 1601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::TimeTicks now) const { 1615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) state->BeginDictionary("major_state"); 1625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) state->SetString("next_action", ActionToString(NextAction())); 1635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) state->SetString("begin_impl_frame_state", 1645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) BeginImplFrameStateToString(begin_impl_frame_state_)); 1655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) state->SetString("commit_state", CommitStateToString(commit_state_)); 1665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) state->SetString("output_surface_state_", 1675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) OutputSurfaceStateToString(output_surface_state_)); 1685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) state->SetString("forced_redraw_state", 1695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ForcedRedrawOnTimeoutStateToString(forced_redraw_state_)); 1705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) state->EndDictionary(); 1715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) state->BeginDictionary("major_timestamps_in_ms"); 1735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) state->SetDouble("0_interval", 1745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) begin_impl_frame_args_.interval.InMicroseconds() / 1000.0L); 1755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) state->SetDouble( 1763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) "1_now_to_deadline", 177a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch (begin_impl_frame_args_.deadline - now).InMicroseconds() / 1000.0L); 1785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) state->SetDouble( 1793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) "2_frame_time_to_now", 180a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch (now - begin_impl_frame_args_.frame_time).InMicroseconds() / 1000.0L); 1815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) state->SetDouble("3_frame_time_to_deadline", 1825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) (begin_impl_frame_args_.deadline - 1835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) begin_impl_frame_args_.frame_time).InMicroseconds() / 1845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1000.0L); 1855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) state->SetDouble("4_now", 1865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) (now - base::TimeTicks()).InMicroseconds() / 1000.0L); 1875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) state->SetDouble( 1883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) "5_frame_time", 189a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch (begin_impl_frame_args_.frame_time - base::TimeTicks()).InMicroseconds() / 1903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1000.0L); 1915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) state->SetDouble( 1923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) "6_deadline", 193a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch (begin_impl_frame_args_.deadline - base::TimeTicks()).InMicroseconds() / 1943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1000.0L); 1955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) state->EndDictionary(); 1965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) state->BeginDictionary("minor_state"); 1985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) state->SetInteger("commit_count", commit_count_); 1995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) state->SetInteger("current_frame_number", current_frame_number_); 2005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) state->SetInteger("last_frame_number_animate_performed", 2025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) last_frame_number_animate_performed_); 2035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) state->SetInteger("last_frame_number_swap_performed", 2045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) last_frame_number_swap_performed_); 2055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) state->SetInteger("last_frame_number_swap_requested", 2065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) last_frame_number_swap_requested_); 2075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) state->SetInteger("last_frame_number_begin_main_frame_sent", 2085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) last_frame_number_begin_main_frame_sent_); 2095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) state->SetInteger("last_frame_number_update_visible_tiles_was_called", 2105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) last_frame_number_update_visible_tiles_was_called_); 2115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) state->SetInteger("manage_tiles_funnel", manage_tiles_funnel_); 2135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) state->SetInteger("consecutive_checkerboard_animations", 2145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) consecutive_checkerboard_animations_); 2155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) state->SetInteger("max_pending_swaps_", max_pending_swaps_); 2165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) state->SetInteger("pending_swaps_", pending_swaps_); 2175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) state->SetBoolean("needs_redraw", needs_redraw_); 2185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) state->SetBoolean("needs_animate_", needs_animate_); 2195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) state->SetBoolean("needs_manage_tiles", needs_manage_tiles_); 2205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) state->SetBoolean("swap_used_incomplete_tile", swap_used_incomplete_tile_); 2215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) state->SetBoolean("needs_commit", needs_commit_); 2225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) state->SetBoolean("visible", visible_); 2235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) state->SetBoolean("can_start", can_start_); 2245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) state->SetBoolean("can_draw", can_draw_); 2255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) state->SetBoolean("has_pending_tree", has_pending_tree_); 2265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) state->SetBoolean("pending_tree_is_ready_for_activation", 2275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pending_tree_is_ready_for_activation_); 2285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) state->SetBoolean("active_tree_needs_first_draw", 2295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) active_tree_needs_first_draw_); 2305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) state->SetBoolean("did_create_and_initialize_first_output_surface", 2315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) did_create_and_initialize_first_output_surface_); 2321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci state->SetBoolean("impl_latency_takes_priority", 2331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci impl_latency_takes_priority_); 2345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) state->SetBoolean("main_thread_is_in_high_latency_mode", 2355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) MainThreadIsInHighLatencyMode()); 2365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) state->SetBoolean("skip_begin_main_frame_to_reduce_latency", 2375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) skip_begin_main_frame_to_reduce_latency_); 2385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) state->SetBoolean("skip_next_begin_main_frame_to_reduce_latency", 2395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) skip_next_begin_main_frame_to_reduce_latency_); 2405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) state->SetBoolean("continuous_painting", continuous_painting_); 2415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) state->EndDictionary(); 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void SchedulerStateMachine::AdvanceCurrentFrameNumber() { 2455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) current_frame_number_++; 2465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // "Drain" the ManageTiles funnel. 2485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (manage_tiles_funnel_ > 0) 2495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) manage_tiles_funnel_--; 250a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 251a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) skip_begin_main_frame_to_reduce_latency_ = 252a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) skip_next_begin_main_frame_to_reduce_latency_; 253a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) skip_next_begin_main_frame_to_reduce_latency_ = false; 2545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)bool SchedulerStateMachine::HasSentBeginMainFrameThisFrame() const { 25768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return current_frame_number_ == 2588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) last_frame_number_begin_main_frame_sent_; 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 261ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochbool SchedulerStateMachine::HasUpdatedVisibleTilesThisFrame() const { 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return current_frame_number_ == 26368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) last_frame_number_update_visible_tiles_was_called_; 2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 26668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)bool SchedulerStateMachine::HasSwappedThisFrame() const { 26768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return current_frame_number_ == last_frame_number_swap_performed_; 268558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch} 269558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 270cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool SchedulerStateMachine::HasRequestedSwapThisFrame() const { 271cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return current_frame_number_ == last_frame_number_swap_requested_; 272cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 273cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 2743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool SchedulerStateMachine::PendingDrawsShouldBeAborted() const { 275424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // These are all the cases where we normally cannot or do not want to draw 276424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // but, if needs_redraw_ is true and we do not draw to make forward progress, 277424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // we might deadlock with the main thread. 278424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // This should be a superset of PendingActivationsShouldBeForced() since 279424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // activation of the pending tree is blocked by drawing of the active tree and 280424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // the main thread might be blocked on activation of the most recent commit. 281424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (PendingActivationsShouldBeForced()) 282424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return true; 283424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 284424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Additional states where we should abort draws. 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!can_draw_) 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 287424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return false; 288424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 289424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 290424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)bool SchedulerStateMachine::PendingActivationsShouldBeForced() const { 29158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // There is no output surface to trigger our activations. 2921675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch // If we do not force activations to make forward progress, we might deadlock 2931675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch // with the main thread. 29458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (output_surface_state_ == OUTPUT_SURFACE_LOST) 295424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return true; 29658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 2971675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch // If we're not visible, we should force activation. 2981675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch // Since we set RequiresHighResToDraw when becoming visible, we ensure that we 2991675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch // don't checkerboard until all visible resources are done. Furthermore, if we 3001675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch // do keep the pending tree around, when becoming visible we might activate 3011675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch // prematurely causing RequiresHighResToDraw flag to be reset. In all cases, 3021675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch // we can simply activate on becoming invisible since we don't need to draw 3031675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch // the active tree when we're in this state. 3041675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch if (!visible_) 3051675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch return true; 3061675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch 3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 310424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)bool SchedulerStateMachine::ShouldBeginOutputSurfaceCreation() const { 311424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Don't try to initialize too early. 312424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (!can_start_) 313424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return false; 314424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 315424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // We only want to start output surface initialization after the 316424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // previous commit is complete. 317424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (commit_state_ != COMMIT_STATE_IDLE) 318424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return false; 319424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 3205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Make sure the BeginImplFrame from any previous OutputSurfaces 3215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // are complete before creating the new OutputSurface. 3225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_IDLE) 3235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 3245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 32558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // We want to clear the pipline of any pending draws and activations 32658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // before starting output surface initialization. This allows us to avoid 32758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // weird corner cases where we abort draws or force activation while we 328cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // are initializing the output surface. 32958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (active_tree_needs_first_draw_ || has_pending_tree_) 33058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return false; 33158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 332424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // We need to create the output surface if we don't have one and we haven't 333424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // started creating one yet. 334424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return output_surface_state_ == OUTPUT_SURFACE_LOST; 335424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 336424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool SchedulerStateMachine::ShouldDraw() const { 338424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // If we need to abort draws, we should do so ASAP since the draw could 339424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // be blocking other important actions (like output surface initialization), 340424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // from occuring. If we are waiting for the first draw, then perfom the 341424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // aborted draw to keep things moving. If we are not waiting for the first 342424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // draw however, we don't want to abort for no reason. 343424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (PendingDrawsShouldBeAborted()) 34458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return active_tree_needs_first_draw_; 3453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 346cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // After this line, we only want to send a swap request once per frame. 347cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (HasRequestedSwapThisFrame()) 3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 3493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // Do not queue too many swaps. 3510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (pending_swaps_ >= max_pending_swaps_) 3520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return false; 3530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 3548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Except for the cases above, do not draw outside of the BeginImplFrame 3558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // deadline. 3568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE) 3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 3583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 35958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Only handle forced redraws due to timeouts on the regular deadline. 360a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW) 36158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return true; 36258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 3633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return needs_redraw_; 3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 366424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)bool SchedulerStateMachine::ShouldActivatePendingTree() const { 367424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // There is nothing to activate. 368424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (!has_pending_tree_) 369424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return false; 370424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 37158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // We should not activate a second tree before drawing the first one. 37258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Even if we need to force activation of the pending tree, we should abort 37358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // drawing the active tree first. 37458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (active_tree_needs_first_draw_) 375424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return false; 376424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 377424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // If we want to force activation, do so ASAP. 378424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (PendingActivationsShouldBeForced()) 379424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return true; 380424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 381424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // At this point, only activate if we are ready to activate. 382424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return pending_tree_is_ready_for_activation_; 3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 385ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochbool SchedulerStateMachine::ShouldUpdateVisibleTiles() const { 3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!settings_.impl_side_painting) 3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 388ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (HasUpdatedVisibleTilesThisFrame()) 3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 391cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // We don't want to update visible tiles right after drawing. 392cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (HasRequestedSwapThisFrame()) 393cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return false; 394cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 395424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // There's no reason to check for tiles if we don't have an output surface. 396424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (!HasInitializedOutputSurface()) 397424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return false; 398424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 39968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // We should not check for visible tiles until we've entered the deadline so 40068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // we check as late as possible and give the tiles more time to initialize. 4018bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE) 40268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return false; 403424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 404424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // If the last swap drew with checkerboard or missing tiles, we should 405424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // poll for any new visible tiles so we can be notified to draw again 406424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // when there are. 407424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (swap_used_incomplete_tile_) 408424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return true; 409424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 410424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return false; 4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liubool SchedulerStateMachine::ShouldAnimate() const { 4145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (!can_draw_) 4155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return false; 4165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 4175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (last_frame_number_animate_performed_ == current_frame_number_) 4185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return false; 4195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 4205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING && 4215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE) 4225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return false; 4235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 4245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return needs_redraw_ || needs_animate_; 4255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 4265c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 4276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)bool SchedulerStateMachine::CouldSendBeginMainFrame() const { 428424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (!needs_commit_) 4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 430424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 4316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // We can not perform commits if we are not visible. 4326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (!visible_) 4336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return false; 4346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 4356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return true; 4366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} 4376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 4386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)bool SchedulerStateMachine::ShouldSendBeginMainFrame() const { 4396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (!CouldSendBeginMainFrame()) 4406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return false; 4416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 4428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Only send BeginMainFrame when there isn't another commit pending already. 443424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (commit_state_ != COMMIT_STATE_IDLE) 444424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return false; 445424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 446a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Don't send BeginMainFrame early if we are prioritizing the active tree 4471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // because of impl_latency_takes_priority_. 4481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (impl_latency_takes_priority_ && 449a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) (has_pending_tree_ || active_tree_needs_first_draw_)) { 450424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return false; 451a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 452424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 453424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // We want to start the first commit after we get a new output surface ASAP. 454424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (output_surface_state_ == OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT) 455424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return true; 456424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 457a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // We should not send BeginMainFrame while we are in 458a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // BEGIN_IMPL_FRAME_STATE_IDLE since we might have new 459a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // user input arriving soon. 4608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // TODO(brianderson): Allow sending BeginMainFrame while idle when the main 4618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // thread isn't consuming user input. 462a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_IDLE && 463a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch BeginFrameNeeded()) 46468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return false; 46568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 46658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // We need a new commit for the forced redraw. This honors the 46758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // single commit per interval because the result will be swapped to screen. 46858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_COMMIT) 46958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return true; 47058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 471424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // After this point, we only start a commit once per frame. 4728bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (HasSentBeginMainFrameThisFrame()) 473424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return false; 474424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 475424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // We shouldn't normally accept commits if there isn't an OutputSurface. 476424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (!HasInitializedOutputSurface()) 477424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return false; 478424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 479f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // SwapAck throttle the BeginMainFrames unless we just swapped. 4800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // TODO(brianderson): Remove this restriction to improve throughput. 481f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) bool just_swapped_in_deadline = 482f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE && 483f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) HasSwappedThisFrame(); 484f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (pending_swaps_ >= max_pending_swaps_ && !just_swapped_in_deadline) 4850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return false; 4860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 487f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (skip_begin_main_frame_to_reduce_latency_) 488f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return false; 489f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 490424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return true; 491424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 492424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 493424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)bool SchedulerStateMachine::ShouldCommit() const { 494a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (commit_state_ != COMMIT_STATE_READY_TO_COMMIT) 495a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return false; 496a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 497a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // We must not finish the commit until the pending tree is free. 498a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (has_pending_tree_) { 499a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(settings_.main_frame_before_activation_enabled); 500a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return false; 501a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 502a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 503a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Prioritize drawing the previous commit before finishing the next commit. 504a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (active_tree_needs_first_draw_) 505a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return false; 5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 507a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return true; 508f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 509f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 510d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)bool SchedulerStateMachine::ShouldManageTiles() const { 511f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // ManageTiles only really needs to be called immediately after commit 5125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // and then periodically after that. Use a funnel to make sure we average 5135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // one ManageTiles per BeginImplFrame in the long run. 5145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (manage_tiles_funnel_ > 0) 515f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return false; 516f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 517d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Limiting to once per-frame is not enough, since we only want to 518d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // manage tiles _after_ draws. Polling for draw triggers and 519d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // begin-frame are mutually exclusive, so we limit to these two cases. 5208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE && 52168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) !inside_poll_for_anticipated_draw_triggers_) 522d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return false; 523d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return needs_manage_tiles_; 524d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 525d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SchedulerStateMachine::Action SchedulerStateMachine::NextAction() const { 527424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (ShouldUpdateVisibleTiles()) 528424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return ACTION_UPDATE_VISIBLE_TILES; 529424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (ShouldActivatePendingTree()) 530116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return ACTION_ACTIVATE_SYNC_TREE; 531424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (ShouldCommit()) 532424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return ACTION_COMMIT; 5335c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (ShouldAnimate()) 5345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return ACTION_ANIMATE; 535424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (ShouldDraw()) { 536cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (PendingDrawsShouldBeAborted()) 537424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return ACTION_DRAW_AND_SWAP_ABORT; 53858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) else if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW) 53958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return ACTION_DRAW_AND_SWAP_FORCED; 540424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) else 54158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return ACTION_DRAW_AND_SWAP_IF_POSSIBLE; 5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 543d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (ShouldManageTiles()) 544d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return ACTION_MANAGE_TILES; 5458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (ShouldSendBeginMainFrame()) 5468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return ACTION_SEND_BEGIN_MAIN_FRAME; 547424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (ShouldBeginOutputSurfaceCreation()) 548424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return ACTION_BEGIN_OUTPUT_SURFACE_CREATION; 5492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return ACTION_NONE; 5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SchedulerStateMachine::UpdateState(Action action) { 5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch (action) { 5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case ACTION_NONE: 5552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 557ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch case ACTION_UPDATE_VISIBLE_TILES: 55868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) last_frame_number_update_visible_tiles_was_called_ = 5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) current_frame_number_; 5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 5612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 562116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch case ACTION_ACTIVATE_SYNC_TREE: 563424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) UpdateStateOnActivation(); 5642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 5652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5665c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu case ACTION_ANIMATE: 5675c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu last_frame_number_animate_performed_ = current_frame_number_; 5685c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu needs_animate_ = false; 5695c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // TODO(skyostil): Instead of assuming this, require the client to tell 5705c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // us. 5715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu SetNeedsRedraw(); 5725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return; 5735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 5748bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) case ACTION_SEND_BEGIN_MAIN_FRAME: 575a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(!has_pending_tree_ || 576a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) settings_.main_frame_before_activation_enabled); 577a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(!active_tree_needs_first_draw_ || 578a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) settings_.main_frame_before_draw_enabled); 579cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK(visible_); 580a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) commit_state_ = COMMIT_STATE_BEGIN_MAIN_FRAME_SENT; 5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) needs_commit_ = false; 5828bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) last_frame_number_begin_main_frame_sent_ = 583558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch current_frame_number_; 5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case ACTION_COMMIT: { 5873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) bool commit_was_aborted = false; 588424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) UpdateStateOnCommit(commit_was_aborted); 5892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 5903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 5912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 59258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) case ACTION_DRAW_AND_SWAP_FORCED: 59358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) case ACTION_DRAW_AND_SWAP_IF_POSSIBLE: { 5940529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch bool did_request_swap = true; 5950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch UpdateStateOnDraw(did_request_swap); 5962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 5973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 5983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 599cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case ACTION_DRAW_AND_SWAP_ABORT: { 6000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch bool did_request_swap = false; 6010529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch UpdateStateOnDraw(did_request_swap); 6023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return; 6033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 6042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 605c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case ACTION_BEGIN_OUTPUT_SURFACE_CREATION: 6062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_EQ(output_surface_state_, OUTPUT_SURFACE_LOST); 607c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) output_surface_state_ = OUTPUT_SURFACE_CREATING; 60858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 60958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // The following DCHECKs make sure we are in the proper quiescent state. 61058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // The pipeline should be flushed entirely before we start output 61158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // surface creation to avoid complicated corner cases. 61258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DCHECK_EQ(commit_state_, COMMIT_STATE_IDLE); 61358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DCHECK(!has_pending_tree_); 61458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DCHECK(!active_tree_needs_first_draw_); 6152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 6162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 617d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) case ACTION_MANAGE_TILES: 618d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) UpdateStateOnManageTiles(); 619d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return; 6202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 623424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void SchedulerStateMachine::UpdateStateOnCommit(bool commit_was_aborted) { 624424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) commit_count_++; 625424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 626a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (commit_was_aborted || settings_.main_frame_before_activation_enabled) { 627a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) commit_state_ = COMMIT_STATE_IDLE; 628a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } else if (settings_.main_frame_before_draw_enabled) { 629a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) commit_state_ = settings_.impl_side_painting 630a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ? COMMIT_STATE_WAITING_FOR_ACTIVATION 631a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) : COMMIT_STATE_IDLE; 632a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } else { 633a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) commit_state_ = COMMIT_STATE_WAITING_FOR_FIRST_DRAW; 634a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 635a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 636424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // If we are impl-side-painting but the commit was aborted, then we behave 637424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // mostly as if we are not impl-side-painting since there is no pending tree. 638424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) has_pending_tree_ = settings_.impl_side_painting && !commit_was_aborted; 639424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 640cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Update state related to forced draws. 641cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_COMMIT) { 642cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) forced_redraw_state_ = has_pending_tree_ 643cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ? FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION 644cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) : FORCED_REDRAW_STATE_WAITING_FOR_DRAW; 64558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 64658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 647cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Update the output surface state. 648cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK_NE(output_surface_state_, OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION); 649cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (output_surface_state_ == OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT) { 650cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (has_pending_tree_) { 651cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) output_surface_state_ = OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION; 652cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } else { 653cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) output_surface_state_ = OUTPUT_SURFACE_ACTIVE; 654cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) needs_redraw_ = true; 655424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 656424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 657424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 658424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Update state if we have a new active tree to draw, or if the active tree 659cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // was unchanged but we need to do a forced draw. 660424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (!has_pending_tree_ && 66158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) (!commit_was_aborted || 66258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW)) { 663424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) needs_redraw_ = true; 66458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) active_tree_needs_first_draw_ = true; 665424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 666424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 667424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // This post-commit work is common to both completed and aborted commits. 668424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) pending_tree_is_ready_for_activation_ = false; 669424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 670c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (continuous_painting_) 671c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch needs_commit_ = true; 672424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 673424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 674424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void SchedulerStateMachine::UpdateStateOnActivation() { 675a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (commit_state_ == COMMIT_STATE_WAITING_FOR_ACTIVATION) 676a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) commit_state_ = COMMIT_STATE_IDLE; 677a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 678424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (output_surface_state_ == OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION) 679424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) output_surface_state_ = OUTPUT_SURFACE_ACTIVE; 680424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 68158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION) 68258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) forced_redraw_state_ = FORCED_REDRAW_STATE_WAITING_FOR_DRAW; 68358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 684424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) has_pending_tree_ = false; 685424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) pending_tree_is_ready_for_activation_ = false; 68658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) active_tree_needs_first_draw_ = true; 687424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) needs_redraw_ = true; 688424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 689424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 6900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid SchedulerStateMachine::UpdateStateOnDraw(bool did_request_swap) { 691cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW) 69258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) forced_redraw_state_ = FORCED_REDRAW_STATE_IDLE; 69358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 694010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!has_pending_tree_ && 695010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) commit_state_ == COMMIT_STATE_WAITING_FOR_FIRST_DRAW) { 696a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) commit_state_ = COMMIT_STATE_IDLE; 697010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 698a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 6993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) needs_redraw_ = false; 70058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) active_tree_needs_first_draw_ = false; 7013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 7020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (did_request_swap) 703cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) last_frame_number_swap_requested_ = current_frame_number_; 7043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 7053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 706d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void SchedulerStateMachine::UpdateStateOnManageTiles() { 707d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) needs_manage_tiles_ = false; 708d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 709d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 710a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void SchedulerStateMachine::SetSkipNextBeginMainFrameToReduceLatency() { 711a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) skip_next_begin_main_frame_to_reduce_latency_ = true; 712f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 713f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 714a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochbool SchedulerStateMachine::BeginFrameNeeded() const { 715a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // Proactive BeginFrames are bad for the synchronous compositor because we 716a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // have to draw when we get the BeginFrame and could end up drawing many 71768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // duplicate frames if our new frame isn't ready in time. 71868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // To poll for state with the synchronous compositor without having to draw, 71968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // we rely on ShouldPollForAnticipatedDrawTriggers instead. 720a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (!SupportsProactiveBeginFrame()) 7215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return BeginFrameNeededToAnimateOrDraw(); 72268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 7235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return BeginFrameNeededToAnimateOrDraw() || ProactiveBeginFrameWanted(); 72468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 72568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 72668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)bool SchedulerStateMachine::ShouldPollForAnticipatedDrawTriggers() const { 72768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // ShouldPollForAnticipatedDrawTriggers is what we use in place of 728a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // ProactiveBeginFrameWanted when we are using the synchronous 72968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // compositor. 730a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (!SupportsProactiveBeginFrame()) { 7315c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return !BeginFrameNeededToAnimateOrDraw() && ProactiveBeginFrameWanted(); 73268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 73368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 73468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Non synchronous compositors should rely on 735a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // ProactiveBeginFrameWanted to poll for state instead. 73668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return false; 73768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 73868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 7395c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// Note: If SupportsProactiveBeginFrame is false, the scheduler should poll 7405c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// for changes in it's draw state so it can request a BeginFrame when it's 7415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// actually ready. 742a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochbool SchedulerStateMachine::SupportsProactiveBeginFrame() const { 7435c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // It is undesirable to proactively request BeginFrames if we are 7445c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // using a synchronous compositor because we *must* draw for every 7455c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // BeginFrame, which could cause duplicate draws. 7460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return !settings_.using_synchronous_renderer_compositor; 7474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 7484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 74958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// These are the cases where we definitely (or almost definitely) have a 7505c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// new frame to animate and/or draw and can draw. 7515c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liubool SchedulerStateMachine::BeginFrameNeededToAnimateOrDraw() const { 7528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // The output surface is the provider of BeginImplFrames, so we are not going 7538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // to get them even if we ask for them. 75458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (!HasInitializedOutputSurface()) 75558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return false; 75658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 7572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If we can't draw, don't tick until we are notified that we can draw again. 7582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!can_draw_) 7592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 7602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 76158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // The forced draw respects our normal draw scheduling, so we need to 7628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // request a BeginImplFrame for it. 76358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW) 7642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 7652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 76658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // There's no need to produce frames if we are not visible. 76758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (!visible_) 76858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return false; 76958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 7708bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // We need to draw a more complete frame than we did the last BeginImplFrame, 7718bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // so request another BeginImplFrame in anticipation that we will have 77258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // additional visible tiles. 77358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (swap_used_incomplete_tile_) 7742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 7752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7765c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (needs_animate_) 7775c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return true; 7785c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 77958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return needs_redraw_; 7802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 78258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// These are cases where we are very likely to draw soon, but might not 7838bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// actually have a new frame to draw when we receive the next BeginImplFrame. 7848bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// Proactively requesting the BeginImplFrame helps hide the round trip latency 785a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// of the SetNeedsBeginFrame request that has to go to the Browser. 786a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochbool SchedulerStateMachine::ProactiveBeginFrameWanted() const { 7878bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // The output surface is the provider of BeginImplFrames, 788424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // so we are not going to get them even if we ask for them. 789424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (!HasInitializedOutputSurface()) 790424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return false; 791424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 792eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Do not be proactive when invisible. 793424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (!visible_) 794eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return false; 7957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 7968bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // We should proactively request a BeginImplFrame if a commit is pending 79758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // because we will want to draw if the commit completes quickly. 79858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (needs_commit_ || commit_state_ != COMMIT_STATE_IDLE) 79958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return true; 80058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 8018bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // If the pending tree activates quickly, we'll want a BeginImplFrame soon 80258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // to draw the new active tree. 80358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (has_pending_tree_) 80458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return true; 80558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 806d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Changing priorities may allow us to activate (given the new priorities), 807d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // which may result in a new frame. 808d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (needs_manage_tiles_) 809d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return true; 810d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 811cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // If we just sent a swap request, it's likely that we are going to produce 812cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // another frame soon. This helps avoid negative glitches in our 813a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // SetNeedsBeginFrame requests, which may propagate to the BeginImplFrame 8141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // provider and get sampled at an inopportune time, delaying the next 8151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // BeginImplFrame. 816cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (HasRequestedSwapThisFrame()) 817d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return true; 818d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 81958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return false; 8207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 8217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 8228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void SchedulerStateMachine::OnBeginImplFrame(const BeginFrameArgs& args) { 8235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AdvanceCurrentFrameNumber(); 824a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch begin_impl_frame_args_ = args; 8255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK_EQ(begin_impl_frame_state_, BEGIN_IMPL_FRAME_STATE_IDLE) 8265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) << AsValue()->ToString(); 8278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING; 82890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 8292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void SchedulerStateMachine::OnBeginImplFrameDeadlinePending() { 8318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DCHECK_EQ(begin_impl_frame_state_, 8328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING) 8335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) << AsValue()->ToString(); 8348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME; 83568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 83668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 8378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void SchedulerStateMachine::OnBeginImplFrameDeadline() { 8388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DCHECK_EQ(begin_impl_frame_state_, BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME) 8395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) << AsValue()->ToString(); 8408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE; 84168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 84268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 8438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void SchedulerStateMachine::OnBeginImplFrameIdle() { 8448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DCHECK_EQ(begin_impl_frame_state_, BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE) 8455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) << AsValue()->ToString(); 8468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_IDLE; 84768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 84868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 8498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)bool SchedulerStateMachine::ShouldTriggerBeginImplFrameDeadlineEarly() const { 8508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // TODO(brianderson): This should take into account multiple commit sources. 8518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 8528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME) 8538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return false; 8548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 8555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // If we've lost the output surface, end the current BeginImplFrame ASAP 8565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // so we can start creating the next output surface. 8575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (output_surface_state_ == OUTPUT_SURFACE_LOST) 8585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return true; 8595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 8600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // SwapAck throttle the deadline since we wont draw and swap anyway. 8610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (pending_swaps_ >= max_pending_swaps_) 8620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return false; 8630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 8648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (active_tree_needs_first_draw_) 8658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return true; 8668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 8671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (!needs_redraw_) 8681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return false; 8691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 8708bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // This is used to prioritize impl-thread draws when the main thread isn't 8718bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // producing anything, e.g., after an aborted commit. We also check that we 8728bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // don't have a pending tree -- otherwise we should give it a chance to 8738bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // activate. 8748bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // TODO(skyostil): Revisit this when we have more accurate deadline estimates. 8751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (commit_state_ == COMMIT_STATE_IDLE && !has_pending_tree_) 8761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return true; 8771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 8781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Prioritize impl-thread draws in impl_latency_takes_priority_ mode. 8791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (impl_latency_takes_priority_) 8808bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return true; 8818bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 8828bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return false; 8832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 8842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 885f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool SchedulerStateMachine::MainThreadIsInHighLatencyMode() const { 886a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // If a commit is pending before the previous commit has been drawn, we 887a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // are definitely in a high latency mode. 888a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (CommitPending() && (active_tree_needs_first_draw_ || has_pending_tree_)) 889a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return true; 890a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 891f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // If we just sent a BeginMainFrame and haven't hit the deadline yet, the main 892f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // thread is in a low latency mode. 893cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (HasSentBeginMainFrameThisFrame() && 894f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) (begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING || 895f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME)) 896f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return false; 897f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 898f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // If there's a commit in progress it must either be from the previous frame 899f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // or it started after the impl thread's deadline. In either case the main 900f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // thread is in high latency mode. 901cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (CommitPending()) 902f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return true; 903f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 904f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Similarly, if there's a pending tree the main thread is in high latency 905f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // mode, because either 906f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // it's from the previous frame 907f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // or 908f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // we're currently drawing the active tree and the pending tree will thus 909f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // only be drawn in the next frame. 910f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (has_pending_tree_) 911f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return true; 912f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 913f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE) { 914f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Even if there's a new active tree to draw at the deadline or we've just 915cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // swapped it, it may have been triggered by a previous BeginImplFrame, in 916f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // which case the main thread is in a high latency mode. 917cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return (active_tree_needs_first_draw_ || HasSwappedThisFrame()) && 918cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) !HasSentBeginMainFrameThisFrame(); 919f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 920f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 921f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // If the active tree needs its first draw in any other state, we know the 922f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // main thread is in a high latency mode. 923f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return active_tree_needs_first_draw_; 924f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 925f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 926d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void SchedulerStateMachine::DidEnterPollForAnticipatedDrawTriggers() { 9275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AdvanceCurrentFrameNumber(); 928d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) inside_poll_for_anticipated_draw_triggers_ = true; 929d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 930d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 931d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void SchedulerStateMachine::DidLeavePollForAnticipatedDrawTriggers() { 932d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) inside_poll_for_anticipated_draw_triggers_ = false; 93358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 93458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 9352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SchedulerStateMachine::SetVisible(bool visible) { visible_ = visible; } 9362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 93768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void SchedulerStateMachine::SetCanDraw(bool can_draw) { can_draw_ = can_draw; } 93868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 9392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SchedulerStateMachine::SetNeedsRedraw() { needs_redraw_ = true; } 9402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid SchedulerStateMachine::SetNeedsAnimate() { 9425c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu needs_animate_ = true; 9435c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 9445c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 945d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void SchedulerStateMachine::SetNeedsManageTiles() { 9468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (!needs_manage_tiles_) { 9478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) TRACE_EVENT0("cc", 9488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) "SchedulerStateMachine::SetNeedsManageTiles"); 9498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) needs_manage_tiles_ = true; 9508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 951d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 952d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 9530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid SchedulerStateMachine::SetMaxSwapsPending(int max) { 9540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch max_pending_swaps_ = max; 9550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 9560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 9570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid SchedulerStateMachine::DidSwapBuffers() { 9580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch pending_swaps_++; 9590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch DCHECK_LE(pending_swaps_, max_pending_swaps_); 960cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 961cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) last_frame_number_swap_performed_ = current_frame_number_; 9620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 9630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 96458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void SchedulerStateMachine::SetSwapUsedIncompleteTile( 96558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) bool used_incomplete_tile) { 96658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) swap_used_incomplete_tile_ = used_incomplete_tile; 9672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 9682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid SchedulerStateMachine::DidSwapBuffersComplete() { 9700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch DCHECK_GT(pending_swaps_, 0); 9710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch pending_swaps_--; 9720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 9730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 9741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid SchedulerStateMachine::SetImplLatencyTakesPriority( 9751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bool impl_latency_takes_priority) { 9761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci impl_latency_takes_priority_ = impl_latency_takes_priority; 9771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 9781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 979cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void SchedulerStateMachine::DidDrawIfPossibleCompleted(DrawResult result) { 9805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) switch (result) { 981cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case INVALID_RESULT: 982cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) NOTREACHED() << "Uninitialized DrawResult."; 9835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) break; 984cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case DRAW_ABORTED_CANT_DRAW: 985cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case DRAW_ABORTED_CONTEXT_LOST: 9865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NOTREACHED() << "Invalid return value from DrawAndSwapIfPossible:" 9875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) << result; 9885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) break; 989cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case DRAW_SUCCESS: 9905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) consecutive_checkerboard_animations_ = 0; 9915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) forced_redraw_state_ = FORCED_REDRAW_STATE_IDLE; 9925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) break; 993cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case DRAW_ABORTED_CHECKERBOARD_ANIMATIONS: 9945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) needs_redraw_ = true; 9955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 9965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // If we're already in the middle of a redraw, we don't need to 9975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // restart it. 9985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (forced_redraw_state_ != FORCED_REDRAW_STATE_IDLE) 9995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 10005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 10015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) needs_commit_ = true; 10025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) consecutive_checkerboard_animations_++; 10035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (settings_.timeout_and_draw_when_animation_checkerboards && 10045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) consecutive_checkerboard_animations_ >= 10055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) settings_.maximum_number_of_failed_draws_before_draw_is_forced_) { 10065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) consecutive_checkerboard_animations_ = 0; 10075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // We need to force a draw, but it doesn't make sense to do this until 10085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // we've committed and have new textures. 10095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) forced_redraw_state_ = FORCED_REDRAW_STATE_WAITING_FOR_COMMIT; 10105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 10115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) break; 1012cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case DRAW_ABORTED_MISSING_HIGH_RES_CONTENT: 10135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // It's not clear whether this missing content is because of missing 10145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // pictures (which requires a commit) or because of memory pressure 10155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // removing textures (which might not). To be safe, request a commit 10165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // anyway. 10175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) needs_commit_ = true; 10185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) break; 10192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 10202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 10212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 10226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void SchedulerStateMachine::SetNeedsCommit() { 10236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) needs_commit_ = true; 10246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} 10252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1026a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void SchedulerStateMachine::NotifyReadyToCommit() { 10275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK(commit_state_ == COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED) 10285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) << AsValue()->ToString(); 10292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) commit_state_ = COMMIT_STATE_READY_TO_COMMIT; 10302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 10312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 10328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void SchedulerStateMachine::BeginMainFrameAborted(bool did_handle) { 1033a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK_EQ(commit_state_, COMMIT_STATE_BEGIN_MAIN_FRAME_SENT); 10343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (did_handle) { 10353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) bool commit_was_aborted = true; 1036424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) UpdateStateOnCommit(commit_was_aborted); 10372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 10382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) commit_state_ = COMMIT_STATE_IDLE; 10392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SetNeedsCommit(); 10402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 10412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 10422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1043f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void SchedulerStateMachine::DidManageTiles() { 1044f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) needs_manage_tiles_ = false; 10455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // "Fill" the ManageTiles funnel. 10465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) manage_tiles_funnel_++; 1047f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 1048f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 10492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SchedulerStateMachine::DidLoseOutputSurface() { 10502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (output_surface_state_ == OUTPUT_SURFACE_LOST || 1051c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) output_surface_state_ == OUTPUT_SURFACE_CREATING) 10522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 10532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) output_surface_state_ = OUTPUT_SURFACE_LOST; 1054424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) needs_redraw_ = false; 10552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 10562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1057424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void SchedulerStateMachine::NotifyReadyToActivate() { 1058424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (has_pending_tree_) 1059424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) pending_tree_is_ready_for_activation_ = true; 10602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 10612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1062c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void SchedulerStateMachine::DidCreateAndInitializeOutputSurface() { 1063c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK_EQ(output_surface_state_, OUTPUT_SURFACE_CREATING); 1064424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) output_surface_state_ = OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT; 1065c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1066c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (did_create_and_initialize_first_output_surface_) { 1067c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // TODO(boliu): See if we can remove this when impl-side painting is always 1068c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // on. Does anything on the main thread need to update after recreate? 1069a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) needs_commit_ = true; 1070c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1071c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) did_create_and_initialize_first_output_surface_ = true; 10720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch pending_swaps_ = 0; 1073c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 1074c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1075a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void SchedulerStateMachine::NotifyBeginMainFrameStarted() { 1076a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK_EQ(commit_state_, COMMIT_STATE_BEGIN_MAIN_FRAME_SENT); 1077a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) commit_state_ = COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED; 1078a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 1079a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 1080c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool SchedulerStateMachine::HasInitializedOutputSurface() const { 1081424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) switch (output_surface_state_) { 1082424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) case OUTPUT_SURFACE_LOST: 1083424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) case OUTPUT_SURFACE_CREATING: 1084424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return false; 1085424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 1086424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) case OUTPUT_SURFACE_ACTIVE: 1087424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) case OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT: 1088424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) case OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION: 1089424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return true; 1090424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 1091424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) NOTREACHED(); 1092424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return false; 10932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 10942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 10951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccistd::string SchedulerStateMachine::GetStatesForDebugging() const { 10961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return base::StringPrintf("%c %d %d %d %c %c %c %d %d", 10971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci needs_commit_ ? 'T' : 'F', 10981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci static_cast<int>(output_surface_state_), 10991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci static_cast<int>(begin_impl_frame_state_), 11001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci static_cast<int>(commit_state_), 11011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci has_pending_tree_ ? 'T' : 'F', 11021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci pending_tree_is_ready_for_activation_ ? 'T' : 'F', 11031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci active_tree_needs_first_draw_ ? 'T' : 'F', 11041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci max_pending_swaps_, 11051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci pending_swaps_); 11061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 11071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 11082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace cc 1109