scheduler_unittest.cc 156 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207
  1. // Copyright 2011 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "cc/scheduler/scheduler.h"
  5. #include <stddef.h>
  6. #include <memory>
  7. #include <string>
  8. #include <utility>
  9. #include <vector>
  10. #include "base/auto_reset.h"
  11. #include "base/bind.h"
  12. #include "base/check_op.h"
  13. #include "base/memory/ptr_util.h"
  14. #include "base/memory/raw_ptr.h"
  15. #include "base/notreached.h"
  16. #include "base/numerics/safe_conversions.h"
  17. #include "base/run_loop.h"
  18. #include "base/test/test_mock_time_task_runner.h"
  19. #include "base/time/time.h"
  20. #include "base/time/time_override.h"
  21. #include "base/trace_event/trace_event.h"
  22. #include "cc/metrics/begin_main_frame_metrics.h"
  23. #include "cc/metrics/event_metrics.h"
  24. #include "cc/test/fake_compositor_frame_reporting_controller.h"
  25. #include "cc/test/scheduler_test_common.h"
  26. #include "components/power_scheduler/power_mode_arbiter.h"
  27. #include "components/viz/common/frame_sinks/begin_frame_args.h"
  28. #include "components/viz/test/begin_frame_args_test.h"
  29. #include "components/viz/test/fake_delay_based_time_source.h"
  30. #include "components/viz/test/fake_external_begin_frame_source.h"
  31. #include "testing/gmock/include/gmock/gmock.h"
  32. #include "testing/gtest/include/gtest/gtest.h"
  33. #define EXPECT_ACTIONS(...) \
  34. EXPECT_THAT(client_->Actions(), ::testing::ElementsAre(__VA_ARGS__))
  35. #define EXPECT_NO_ACTION() EXPECT_THAT(client_->Actions(), ::testing::IsEmpty())
  36. #define EXPECT_SCOPED(statements) \
  37. { \
  38. SCOPED_TRACE(""); \
  39. statements; \
  40. }
  41. namespace cc {
  42. namespace {
  43. using power_scheduler::PowerMode;
  44. using power_scheduler::PowerModeArbiter;
  45. using power_scheduler::PowerModeVoter;
  46. base::TimeDelta kSlowDuration = base::Seconds(1);
  47. base::TimeDelta kFastDuration = base::Milliseconds(1);
  48. class FakeSchedulerClient : public SchedulerClient,
  49. public viz::FakeExternalBeginFrameSource::Client {
  50. public:
  51. FakeSchedulerClient() { Reset(); }
  52. void Reset() {
  53. actions_.clear();
  54. will_begin_impl_frame_causes_redraw_ = false;
  55. will_begin_impl_frame_requests_one_begin_impl_frame_ = false;
  56. invalidate_needs_redraw_ = true;
  57. draw_will_happen_ = true;
  58. swap_will_happen_if_draw_happens_ = true;
  59. num_draws_ = 0;
  60. last_begin_main_frame_args_ = viz::BeginFrameArgs();
  61. last_begin_frame_ack_ = viz::BeginFrameAck();
  62. last_frame_skipped_reason_.reset();
  63. }
  64. void set_scheduler(TestScheduler* scheduler) { scheduler_ = scheduler; }
  65. bool needs_begin_frames() { return scheduler_->begin_frames_expected(); }
  66. int num_draws() const { return num_draws_; }
  67. bool invalidate_needs_redraw() const { return invalidate_needs_redraw_; }
  68. const std::vector<std::string> Actions() const {
  69. return std::vector<std::string>(actions_.begin(), actions_.end());
  70. }
  71. base::TimeTicks posted_begin_impl_frame_deadline() const {
  72. return posted_begin_impl_frame_deadline_;
  73. }
  74. base::TimeDelta frame_interval() const { return frame_interval_; }
  75. int ActionIndex(const char* action) const {
  76. for (size_t i = 0; i < actions_.size(); i++)
  77. if (!strcmp(actions_[i], action))
  78. return base::checked_cast<int>(i);
  79. return -1;
  80. }
  81. bool HasAction(const char* action) const { return ActionIndex(action) >= 0; }
  82. void SetWillBeginImplFrameRequestsOneBeginImplFrame(bool request) {
  83. will_begin_impl_frame_requests_one_begin_impl_frame_ = request;
  84. }
  85. void SetWillBeginImplFrameCausesRedraw(bool causes_redraw) {
  86. will_begin_impl_frame_causes_redraw_ = causes_redraw;
  87. }
  88. void SetInvalidateNeedsRedraw(bool needs_redraw) {
  89. invalidate_needs_redraw_ = needs_redraw;
  90. }
  91. void SetDrawWillHappen(bool draw_will_happen) {
  92. draw_will_happen_ = draw_will_happen;
  93. }
  94. void SetSwapWillHappenIfDrawHappens(bool swap_will_happen_if_draw_happens) {
  95. swap_will_happen_if_draw_happens_ = swap_will_happen_if_draw_happens;
  96. }
  97. void SetAutomaticSubmitCompositorFrameAck(bool automatic_ack) {
  98. automatic_ack_ = automatic_ack;
  99. }
  100. void SetWillBeginImplFrameMightHaveDamage(bool might_have_damage) {
  101. will_begin_impl_frame_might_have_damage_ = might_have_damage;
  102. }
  103. // SchedulerClient implementation.
  104. bool WillBeginImplFrame(const viz::BeginFrameArgs& args) override {
  105. EXPECT_FALSE(inside_begin_impl_frame_);
  106. EXPECT_FALSE(inside_action_);
  107. base::AutoReset<bool> mark_inside(&inside_action_, true);
  108. inside_begin_impl_frame_ = true;
  109. PushAction("WillBeginImplFrame");
  110. if (will_begin_impl_frame_requests_one_begin_impl_frame_)
  111. scheduler_->SetNeedsOneBeginImplFrame();
  112. if (will_begin_impl_frame_causes_redraw_)
  113. scheduler_->SetNeedsRedraw();
  114. return will_begin_impl_frame_might_have_damage_;
  115. }
  116. void DidFinishImplFrame(
  117. const viz::BeginFrameArgs& last_activated_args) override {
  118. EXPECT_TRUE(inside_begin_impl_frame_);
  119. EXPECT_FALSE(inside_action_);
  120. base::AutoReset<bool> mark_inside(&inside_action_, true);
  121. inside_begin_impl_frame_ = false;
  122. }
  123. void DidNotProduceFrame(const viz::BeginFrameAck& ack,
  124. FrameSkippedReason reason) override {
  125. EXPECT_FALSE(inside_action_);
  126. base::AutoReset<bool> mark_inside(&inside_action_, true);
  127. last_begin_frame_ack_ = ack;
  128. last_frame_skipped_reason_ = reason;
  129. }
  130. void WillNotReceiveBeginFrame() override {}
  131. void ScheduledActionSendBeginMainFrame(
  132. const viz::BeginFrameArgs& args) override {
  133. EXPECT_FALSE(inside_action_);
  134. base::AutoReset<bool> mark_inside(&inside_action_, true);
  135. PushAction("ScheduledActionSendBeginMainFrame");
  136. last_begin_main_frame_args_ = args;
  137. }
  138. void FrameIntervalUpdated(base::TimeDelta interval) override {
  139. frame_interval_ = interval;
  140. }
  141. const viz::BeginFrameArgs& last_begin_main_frame_args() {
  142. return last_begin_main_frame_args_;
  143. }
  144. const viz::BeginFrameAck& last_begin_frame_ack() {
  145. return last_begin_frame_ack_;
  146. }
  147. FrameSkippedReason last_frame_skipped_reason() const {
  148. return last_frame_skipped_reason_.value();
  149. }
  150. DrawResult ScheduledActionDrawIfPossible() override {
  151. EXPECT_FALSE(inside_action_);
  152. base::AutoReset<bool> mark_inside(&inside_action_, true);
  153. PushAction("ScheduledActionDrawIfPossible");
  154. num_draws_++;
  155. if (!draw_will_happen_)
  156. return DRAW_ABORTED_CHECKERBOARD_ANIMATIONS;
  157. if (swap_will_happen_if_draw_happens_) {
  158. last_begin_frame_ack_ = scheduler_->CurrentBeginFrameAckForActiveTree();
  159. scheduler_->DidSubmitCompositorFrame(0, base::TimeTicks::Now(),
  160. EventMetricsSet(),
  161. /*has_missing_content=*/false);
  162. if (automatic_ack_)
  163. scheduler_->DidReceiveCompositorFrameAck();
  164. }
  165. return DRAW_SUCCESS;
  166. }
  167. DrawResult ScheduledActionDrawForced() override {
  168. EXPECT_FALSE(inside_action_);
  169. base::AutoReset<bool> mark_inside(&inside_action_, true);
  170. PushAction("ScheduledActionDrawForced");
  171. last_begin_frame_ack_ = scheduler_->CurrentBeginFrameAckForActiveTree();
  172. return DRAW_SUCCESS;
  173. }
  174. void ScheduledActionCommit() override {
  175. EXPECT_FALSE(inside_action_);
  176. base::AutoReset<bool> mark_inside(&inside_action_, true);
  177. PushAction("ScheduledActionCommit");
  178. }
  179. void ScheduledActionPostCommit() override {
  180. EXPECT_FALSE(inside_action_);
  181. base::AutoReset<bool> mark_inside(&inside_action_, true);
  182. PushAction("ScheduledActionPostCommit");
  183. }
  184. void ScheduledActionActivateSyncTree() override {
  185. EXPECT_FALSE(inside_action_);
  186. base::AutoReset<bool> mark_inside(&inside_action_, true);
  187. PushAction("ScheduledActionActivateSyncTree");
  188. }
  189. void ScheduledActionBeginLayerTreeFrameSinkCreation() override {
  190. EXPECT_FALSE(inside_action_);
  191. base::AutoReset<bool> mark_inside(&inside_action_, true);
  192. PushAction("ScheduledActionBeginLayerTreeFrameSinkCreation");
  193. }
  194. void ScheduledActionPrepareTiles() override {
  195. EXPECT_FALSE(inside_action_);
  196. base::AutoReset<bool> mark_inside(&inside_action_, true);
  197. PushAction("ScheduledActionPrepareTiles");
  198. scheduler_->WillPrepareTiles();
  199. scheduler_->DidPrepareTiles();
  200. }
  201. void ScheduledActionInvalidateLayerTreeFrameSink(bool needs_redraw) override {
  202. EXPECT_FALSE(inside_action_);
  203. base::AutoReset<bool> mark_inside(&inside_action_, true);
  204. invalidate_needs_redraw_ = needs_redraw;
  205. actions_.push_back("ScheduledActionInvalidateLayerTreeFrameSink");
  206. }
  207. void ScheduledActionPerformImplSideInvalidation() override {
  208. EXPECT_FALSE(inside_action_);
  209. base::AutoReset<bool> mark_inside(&inside_action_, true);
  210. PushAction("ScheduledActionPerformImplSideInvalidation");
  211. }
  212. void SendBeginMainFrameNotExpectedSoon() override {
  213. EXPECT_FALSE(inside_action_);
  214. base::AutoReset<bool> mark_inside(&inside_action_, true);
  215. PushAction("SendBeginMainFrameNotExpectedSoon");
  216. }
  217. void ScheduledActionBeginMainFrameNotExpectedUntil(
  218. base::TimeTicks time) override {
  219. EXPECT_FALSE(inside_action_);
  220. base::AutoReset<bool> mark_inside(&inside_action_, true);
  221. PushAction("ScheduledActionBeginMainFrameNotExpectedUntil");
  222. }
  223. bool IsInsideBeginImplFrame() const { return inside_begin_impl_frame_; }
  224. base::RepeatingCallback<bool(void)> InsideBeginImplFrame(bool state) {
  225. return base::BindRepeating(
  226. &FakeSchedulerClient::InsideBeginImplFrameCallback,
  227. base::Unretained(this), state);
  228. }
  229. bool IsCurrentFrame(int last_frame_number) const {
  230. return scheduler_->current_frame_number() == last_frame_number;
  231. }
  232. base::RepeatingCallback<bool(void)> FrameHasNotAdvancedCallback() {
  233. return base::BindRepeating(&FakeSchedulerClient::IsCurrentFrame,
  234. base::Unretained(this),
  235. scheduler_->current_frame_number());
  236. }
  237. void PushAction(const char* description) {
  238. actions_.push_back(description);
  239. }
  240. // FakeExternalBeginFrameSource::Client implementation.
  241. void OnAddObserver(viz::BeginFrameObserver* obs) override {
  242. PushAction("AddObserver(this)");
  243. }
  244. void OnRemoveObserver(viz::BeginFrameObserver* obs) override {
  245. PushAction("RemoveObserver(this)");
  246. }
  247. bool HasInvalidationAnimation() const override { return false; }
  248. protected:
  249. bool InsideBeginImplFrameCallback(bool state) {
  250. return inside_begin_impl_frame_ == state;
  251. }
  252. bool inside_action_ = false;
  253. bool inside_begin_impl_frame_ = false;
  254. bool will_begin_impl_frame_causes_redraw_;
  255. bool will_begin_impl_frame_requests_one_begin_impl_frame_;
  256. bool invalidate_needs_redraw_ = true;
  257. bool draw_will_happen_;
  258. bool swap_will_happen_if_draw_happens_;
  259. bool automatic_ack_ = true;
  260. bool will_begin_impl_frame_might_have_damage_ = true;
  261. int num_draws_;
  262. viz::BeginFrameArgs last_begin_main_frame_args_;
  263. viz::BeginFrameAck last_begin_frame_ack_;
  264. base::TimeTicks posted_begin_impl_frame_deadline_;
  265. std::vector<const char*> actions_;
  266. raw_ptr<TestScheduler> scheduler_ = nullptr;
  267. base::TimeDelta frame_interval_;
  268. absl::optional<FrameSkippedReason> last_frame_skipped_reason_;
  269. };
  270. enum BeginFrameSourceType {
  271. EXTERNAL_BFS,
  272. UNTHROTTLED_BFS,
  273. THROTTLED_BFS,
  274. };
  275. class SchedulerTestTaskRunner : public base::TestMockTimeTaskRunner {
  276. public:
  277. SchedulerTestTaskRunner()
  278. : base::TestMockTimeTaskRunner(
  279. base::TestMockTimeTaskRunner::Type::kStandalone) {
  280. AdvanceMockTickClock(base::Microseconds(110000));
  281. }
  282. void RunUntilTime(base::TimeTicks end_time) {
  283. FastForwardBy(end_time - NowTicks());
  284. }
  285. // Runs all tasks posted before this call.
  286. void RunPendingTasks() {
  287. base::circular_deque<base::TestPendingTask> tasks = TakePendingTasks();
  288. while (!tasks.empty()) {
  289. base::TestPendingTask task = std::move(tasks.front());
  290. tasks.pop_front();
  291. // Set clock to the beginning of task and run it.
  292. AdvanceMockTickClock(task.GetTimeToRun() - NowTicks());
  293. std::move(task.task).Run();
  294. }
  295. }
  296. // Runs tasks while condition is met.
  297. // Condition is being checked when task exists and before it gets selected.
  298. void RunTasksWhile(base::RepeatingCallback<bool()> condition) {
  299. run_condition_ = condition;
  300. FastForwardUntilNoTasksRemain();
  301. run_condition_ = absl::nullopt;
  302. // We've moved all the pending tasks away to break the execution loop,
  303. // now we should restore them.
  304. while (!tasks_to_requeue_.empty()) {
  305. base::TestPendingTask task = std::move(tasks_to_requeue_.front());
  306. tasks_to_requeue_.pop_front();
  307. PostDelayedTask(task.location, std::move(task.task),
  308. task.GetTimeToRun() - NowTicks());
  309. }
  310. }
  311. protected:
  312. void OnBeforeSelectingTask() override {
  313. // Avoid potential infinite loops.
  314. ASSERT_LT(++task_count_, 100u);
  315. if (run_condition_ && HasPendingTask() && !run_condition_->Run()) {
  316. // Execution will not continue because we move all the pending tasks away.
  317. tasks_to_requeue_ = TakePendingTasks();
  318. }
  319. }
  320. private:
  321. ~SchedulerTestTaskRunner() override = default; // Ref-counted.
  322. size_t task_count_ = 0u;
  323. absl::optional<base::RepeatingCallback<bool()>> run_condition_;
  324. base::circular_deque<base::TestPendingTask> tasks_to_requeue_;
  325. };
  326. class SchedulerTest : public testing::Test {
  327. public:
  328. SchedulerTest()
  329. : task_runner_(base::MakeRefCounted<SchedulerTestTaskRunner>()),
  330. fake_external_begin_frame_source_(nullptr) {}
  331. ~SchedulerTest() override = default;
  332. protected:
  333. TestScheduler* CreateScheduler(BeginFrameSourceType bfs_type) {
  334. viz::BeginFrameSource* frame_source = nullptr;
  335. unthrottled_frame_source_ =
  336. std::make_unique<viz::BackToBackBeginFrameSource>(
  337. std::make_unique<viz::FakeDelayBasedTimeSource>(
  338. task_runner_->GetMockTickClock(), task_runner_.get()));
  339. fake_external_begin_frame_source_ =
  340. std::make_unique<viz::FakeExternalBeginFrameSource>(1.0, false);
  341. fake_external_begin_frame_source_->SetClient(client_.get());
  342. synthetic_frame_source_ = std::make_unique<viz::DelayBasedBeginFrameSource>(
  343. std::make_unique<viz::FakeDelayBasedTimeSource>(
  344. task_runner_->GetMockTickClock(), task_runner_.get()),
  345. viz::BeginFrameSource::kNotRestartableId);
  346. switch (bfs_type) {
  347. case EXTERNAL_BFS:
  348. frame_source = fake_external_begin_frame_source_.get();
  349. break;
  350. case UNTHROTTLED_BFS:
  351. frame_source = unthrottled_frame_source_.get();
  352. break;
  353. case THROTTLED_BFS:
  354. frame_source = synthetic_frame_source_.get();
  355. break;
  356. }
  357. DCHECK(frame_source);
  358. std::unique_ptr<FakeCompositorTimingHistory>
  359. fake_compositor_timing_history = FakeCompositorTimingHistory::Create(
  360. scheduler_settings_.using_synchronous_renderer_compositor);
  361. fake_compositor_timing_history_ = fake_compositor_timing_history.get();
  362. reporting_controller =
  363. std::make_unique<FakeCompositorFrameReportingController>();
  364. reporting_controller->SetDroppedFrameCounter(&dropped_counter);
  365. scheduler_ = std::make_unique<TestScheduler>(
  366. task_runner_->GetMockTickClock(), client_.get(), scheduler_settings_, 0,
  367. task_runner_.get(), std::move(fake_compositor_timing_history),
  368. reporting_controller.get(), &power_mode_arbiter_);
  369. client_->set_scheduler(scheduler_.get());
  370. scheduler_->SetBeginFrameSource(frame_source);
  371. return scheduler_.get();
  372. }
  373. void SetUpScheduler(BeginFrameSourceType bfs_type,
  374. std::unique_ptr<FakeSchedulerClient> client) {
  375. client_ = std::move(client);
  376. CreateScheduler(bfs_type);
  377. EXPECT_SCOPED(InitializeLayerTreeFrameSinkAndFirstCommit());
  378. }
  379. void SetUpScheduler(BeginFrameSourceType bfs_type) {
  380. SetUpScheduler(bfs_type, std::make_unique<FakeSchedulerClient>());
  381. }
  382. void SetUpSchedulerWithNoLayerTreeFrameSink(BeginFrameSourceType bfs_type) {
  383. client_ = std::make_unique<FakeSchedulerClient>();
  384. CreateScheduler(bfs_type);
  385. }
  386. // As this function contains EXPECT macros, to allow debugging it should be
  387. // called inside EXPECT_SCOPED like so;
  388. // EXPECT_SCOPED(
  389. // client.InitializeLayerTreeFrameSinkAndFirstCommit(scheduler));
  390. void InitializeLayerTreeFrameSinkAndFirstCommit() {
  391. TRACE_EVENT0(
  392. "cc", "SchedulerUnitTest::InitializeLayerTreeFrameSinkAndFirstCommit");
  393. DCHECK(scheduler_);
  394. // Check the client doesn't have any actions queued when calling this
  395. // function.
  396. EXPECT_NO_ACTION();
  397. EXPECT_FALSE(scheduler_->begin_frames_expected());
  398. // Start the initial LayerTreeFrameSink creation.
  399. scheduler_->SetVisible(true);
  400. scheduler_->SetCanDraw(true);
  401. EXPECT_ACTIONS("ScheduledActionBeginLayerTreeFrameSinkCreation");
  402. client_->Reset();
  403. // We don't see anything happening until the first impl frame.
  404. scheduler_->DidCreateAndInitializeLayerTreeFrameSink();
  405. scheduler_->SetNeedsBeginMainFrame();
  406. EXPECT_TRUE(scheduler_->begin_frames_expected());
  407. EXPECT_FALSE(client_->IsInsideBeginImplFrame());
  408. client_->Reset();
  409. {
  410. SCOPED_TRACE("Do first frame to commit after initialize.");
  411. AdvanceFrame();
  412. task_runner_->AdvanceMockTickClock(base::Milliseconds(1));
  413. scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
  414. scheduler_->NotifyReadyToCommit(nullptr);
  415. scheduler_->NotifyReadyToActivate();
  416. scheduler_->NotifyReadyToDraw();
  417. EXPECT_FALSE(scheduler_->CommitPending());
  418. if (scheduler_settings_.using_synchronous_renderer_compositor) {
  419. scheduler_->SetNeedsRedraw();
  420. bool resourceless_software_draw = false;
  421. bool skip_draw = false;
  422. scheduler_->OnDrawForLayerTreeFrameSink(resourceless_software_draw,
  423. skip_draw);
  424. } else {
  425. // Run the posted deadline task.
  426. EXPECT_TRUE(client_->IsInsideBeginImplFrame());
  427. task_runner_->RunTasksWhile(client_->InsideBeginImplFrame(true));
  428. }
  429. EXPECT_FALSE(client_->IsInsideBeginImplFrame());
  430. }
  431. client_->Reset();
  432. {
  433. SCOPED_TRACE(
  434. "Run second frame so Scheduler calls SetNeedsBeginFrame(false).");
  435. AdvanceFrame();
  436. if (!scheduler_settings_.using_synchronous_renderer_compositor) {
  437. // Run the posted deadline task.
  438. EXPECT_TRUE(client_->IsInsideBeginImplFrame());
  439. task_runner_->RunTasksWhile(client_->InsideBeginImplFrame(true));
  440. }
  441. EXPECT_FALSE(client_->IsInsideBeginImplFrame());
  442. }
  443. EXPECT_FALSE(scheduler_->begin_frames_expected());
  444. if (scheduler_->begin_frame_source() ==
  445. fake_external_begin_frame_source_.get()) {
  446. // Expect the last viz::BeginFrameAck to be for last BeginFrame, which
  447. // didn't cause damage.
  448. uint64_t last_begin_frame_number =
  449. fake_external_begin_frame_source_->next_begin_frame_number() - 1;
  450. bool has_damage = false;
  451. EXPECT_EQ(
  452. viz::BeginFrameAck(fake_external_begin_frame_source_->source_id(),
  453. last_begin_frame_number, has_damage),
  454. client_->last_begin_frame_ack());
  455. }
  456. client_->Reset();
  457. }
  458. // As this function contains EXPECT macros, to allow debugging it should be
  459. // called inside EXPECT_SCOPED like so;
  460. // EXPECT_SCOPED(client.AdvanceFrame());
  461. void AdvanceFrame(bool animate_only = false) {
  462. TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler.frames"),
  463. "FakeSchedulerClient::AdvanceFrame");
  464. // Send the next BeginFrame message if using an external source, otherwise
  465. // it will be already in the task queue.
  466. if (scheduler_->begin_frame_source() ==
  467. fake_external_begin_frame_source_.get()) {
  468. EXPECT_TRUE(scheduler_->begin_frames_expected());
  469. // Run the deadline first if we're inside the previous frame.
  470. if (client_->IsInsideBeginImplFrame())
  471. task_runner_->RunPendingTasks();
  472. SendNextBeginFrame(animate_only);
  473. } else {
  474. task_runner_->RunTasksWhile(client_->FrameHasNotAdvancedCallback());
  475. }
  476. }
  477. viz::BeginFrameArgs SendNextBeginFrame(bool animate_only = false) {
  478. DCHECK_EQ(scheduler_->begin_frame_source(),
  479. fake_external_begin_frame_source_.get());
  480. // Creep the time forward so that any viz::BeginFrameArgs is not equal to
  481. // the last one otherwise we violate the viz::BeginFrameSource contract.
  482. task_runner_->AdvanceMockTickClock(viz::BeginFrameArgs::DefaultInterval());
  483. viz::BeginFrameArgs args =
  484. fake_external_begin_frame_source_->CreateBeginFrameArgs(
  485. BEGINFRAME_FROM_HERE, task_runner_->GetMockTickClock());
  486. args.animate_only = animate_only;
  487. fake_external_begin_frame_source_->TestOnBeginFrame(args);
  488. return args;
  489. }
  490. viz::FakeExternalBeginFrameSource* fake_external_begin_frame_source() const {
  491. return fake_external_begin_frame_source_.get();
  492. }
  493. void SetShouldDeferInvalidationForMainFrame(bool defer) {
  494. // Set the CompositorTimingHistory so that main thread is identified to be
  495. // fast or slow.
  496. base::TimeDelta delta;
  497. if (!defer)
  498. delta = base::Seconds(1);
  499. fake_compositor_timing_history_
  500. ->SetBeginMainFrameStartToReadyToCommitDurationEstimate(delta);
  501. fake_compositor_timing_history_
  502. ->SetBeginMainFrameQueueDurationCriticalEstimate(delta);
  503. fake_compositor_timing_history_
  504. ->SetBeginMainFrameQueueDurationNotCriticalEstimate(delta);
  505. fake_compositor_timing_history_->SetDrawDurationEstimate(base::TimeDelta());
  506. }
  507. void AdvanceAndMissOneFrame();
  508. void CheckMainFrameNotSkippedAfterLateCommit();
  509. void ImplFrameNotSkippedAfterLateAck();
  510. void BeginFramesNotFromClient(BeginFrameSourceType bfs_type);
  511. void BeginFramesNotFromClient_IsDrawThrottled(BeginFrameSourceType bfs_type);
  512. bool BeginMainFrameOnCriticalPath(TreePriority tree_priority,
  513. ScrollHandlerState scroll_handler_state,
  514. base::TimeDelta durations);
  515. scoped_refptr<SchedulerTestTaskRunner> task_runner_;
  516. std::unique_ptr<viz::FakeExternalBeginFrameSource>
  517. fake_external_begin_frame_source_;
  518. std::unique_ptr<viz::SyntheticBeginFrameSource> synthetic_frame_source_;
  519. std::unique_ptr<viz::SyntheticBeginFrameSource> unthrottled_frame_source_;
  520. SchedulerSettings scheduler_settings_;
  521. std::unique_ptr<FakeSchedulerClient> client_;
  522. PowerModeArbiter power_mode_arbiter_;
  523. std::unique_ptr<TestScheduler> scheduler_;
  524. raw_ptr<FakeCompositorTimingHistory> fake_compositor_timing_history_;
  525. DroppedFrameCounter dropped_counter;
  526. std::unique_ptr<CompositorFrameReportingController> reporting_controller;
  527. };
  528. TEST_F(SchedulerTest, InitializeLayerTreeFrameSinkDoesNotBeginImplFrame) {
  529. SetUpSchedulerWithNoLayerTreeFrameSink(EXTERNAL_BFS);
  530. scheduler_->SetVisible(true);
  531. scheduler_->SetCanDraw(true);
  532. EXPECT_ACTIONS("ScheduledActionBeginLayerTreeFrameSinkCreation");
  533. client_->Reset();
  534. scheduler_->DidCreateAndInitializeLayerTreeFrameSink();
  535. EXPECT_NO_ACTION();
  536. }
  537. TEST_F(SchedulerTest, Stop) {
  538. SetUpScheduler(EXTERNAL_BFS);
  539. scheduler_->SetNeedsBeginMainFrame();
  540. EXPECT_ACTIONS("AddObserver(this)");
  541. client_->Reset();
  542. // No scheduled actions are performed after Stop. WillBeginImplFrame is only
  543. // a notification and not an action performed by the scheduler.
  544. scheduler_->Stop();
  545. EXPECT_SCOPED(AdvanceFrame());
  546. EXPECT_ACTIONS("WillBeginImplFrame");
  547. client_->Reset();
  548. }
  549. TEST_F(SchedulerTest, VideoNeedsBeginFrames) {
  550. SetUpScheduler(EXTERNAL_BFS);
  551. scheduler_->SetVideoNeedsBeginFrames(true);
  552. EXPECT_ACTIONS("AddObserver(this)");
  553. EXPECT_TRUE(scheduler_->begin_frames_expected());
  554. client_->Reset();
  555. EXPECT_SCOPED(AdvanceFrame());
  556. EXPECT_TRUE(client_->IsInsideBeginImplFrame());
  557. // WillBeginImplFrame is responsible for sending BeginFrames to video.
  558. EXPECT_ACTIONS("WillBeginImplFrame");
  559. client_->Reset();
  560. EXPECT_SCOPED(AdvanceFrame());
  561. EXPECT_TRUE(client_->IsInsideBeginImplFrame());
  562. EXPECT_ACTIONS("WillBeginImplFrame");
  563. client_->Reset();
  564. scheduler_->SetVideoNeedsBeginFrames(false);
  565. EXPECT_NO_ACTION();
  566. client_->Reset();
  567. task_runner_->RunTasksWhile(client_->InsideBeginImplFrame(true));
  568. EXPECT_FALSE(client_->IsInsideBeginImplFrame());
  569. EXPECT_ACTIONS("RemoveObserver(this)");
  570. EXPECT_FALSE(scheduler_->begin_frames_expected());
  571. }
  572. TEST_F(SchedulerTest, RequestCommit) {
  573. SetUpScheduler(EXTERNAL_BFS);
  574. // SetNeedsBeginMainFrame should begin the frame on the next BeginImplFrame.
  575. scheduler_->SetNeedsBeginMainFrame();
  576. EXPECT_ACTIONS("AddObserver(this)");
  577. client_->Reset();
  578. EXPECT_SCOPED(AdvanceFrame());
  579. EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame");
  580. EXPECT_TRUE(client_->IsInsideBeginImplFrame());
  581. EXPECT_TRUE(scheduler_->begin_frames_expected());
  582. client_->Reset();
  583. // If we don't swap on the deadline, we wait for the next BeginFrame.
  584. task_runner_->RunPendingTasks(); // Run posted deadline.
  585. EXPECT_NO_ACTION();
  586. EXPECT_FALSE(client_->IsInsideBeginImplFrame());
  587. EXPECT_TRUE(scheduler_->begin_frames_expected());
  588. client_->Reset();
  589. // NotifyReadyToCommit should trigger the commit.
  590. scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
  591. scheduler_->NotifyReadyToCommit(nullptr);
  592. EXPECT_ACTIONS("ScheduledActionCommit", "ScheduledActionPostCommit");
  593. EXPECT_TRUE(scheduler_->begin_frames_expected());
  594. client_->Reset();
  595. // NotifyReadyToActivate should trigger the activation.
  596. scheduler_->NotifyReadyToActivate();
  597. EXPECT_ACTIONS("ScheduledActionActivateSyncTree");
  598. EXPECT_TRUE(scheduler_->begin_frames_expected());
  599. client_->Reset();
  600. // BeginImplFrame should prepare the draw.
  601. EXPECT_SCOPED(AdvanceFrame());
  602. EXPECT_ACTIONS("WillBeginImplFrame");
  603. EXPECT_TRUE(client_->IsInsideBeginImplFrame());
  604. EXPECT_TRUE(scheduler_->begin_frames_expected());
  605. client_->Reset();
  606. // BeginImplFrame deadline should draw.
  607. task_runner_->RunPendingTasks(); // Run posted deadline.
  608. EXPECT_ACTIONS("ScheduledActionDrawIfPossible");
  609. EXPECT_FALSE(client_->IsInsideBeginImplFrame());
  610. EXPECT_TRUE(scheduler_->begin_frames_expected());
  611. client_->Reset();
  612. // The following BeginImplFrame deadline should SetNeedsBeginFrame(false)
  613. // to avoid excessive toggles.
  614. EXPECT_SCOPED(AdvanceFrame());
  615. EXPECT_ACTIONS("WillBeginImplFrame");
  616. EXPECT_TRUE(client_->IsInsideBeginImplFrame());
  617. client_->Reset();
  618. task_runner_->RunPendingTasks(); // Run posted deadline.
  619. EXPECT_ACTIONS("RemoveObserver(this)");
  620. client_->Reset();
  621. }
  622. TEST_F(SchedulerTest, RequestCommitAfterSetDeferBeginMainFrame) {
  623. SetUpScheduler(EXTERNAL_BFS);
  624. scheduler_->SetDeferBeginMainFrame(true);
  625. scheduler_->SetNeedsBeginMainFrame();
  626. EXPECT_NO_ACTION();
  627. client_->Reset();
  628. task_runner_->RunPendingTasks();
  629. // There are no pending tasks or actions.
  630. EXPECT_NO_ACTION();
  631. EXPECT_FALSE(scheduler_->begin_frames_expected());
  632. client_->Reset();
  633. scheduler_->SetDeferBeginMainFrame(false);
  634. EXPECT_ACTIONS("AddObserver(this)");
  635. // Start new BeginMainFrame after defer commit is off.
  636. client_->Reset();
  637. EXPECT_SCOPED(AdvanceFrame());
  638. EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame");
  639. EXPECT_TRUE(client_->IsInsideBeginImplFrame());
  640. }
  641. TEST_F(SchedulerTest, DeferBeginMainFrameWithRedraw) {
  642. SetUpScheduler(EXTERNAL_BFS);
  643. scheduler_->SetDeferBeginMainFrame(true);
  644. scheduler_->SetNeedsBeginMainFrame();
  645. EXPECT_NO_ACTION();
  646. // The SetNeedsRedraw will override the SetDeferBeginMainFrame(true), to
  647. // allow a begin frame to be needed.
  648. client_->Reset();
  649. scheduler_->SetNeedsRedraw();
  650. EXPECT_ACTIONS("AddObserver(this)");
  651. client_->Reset();
  652. AdvanceFrame();
  653. // BeginMainFrame is not sent during the defer commit is on.
  654. EXPECT_ACTIONS("WillBeginImplFrame");
  655. client_->Reset();
  656. task_runner_->RunPendingTasks(); // Run posted deadline.
  657. EXPECT_ACTIONS("ScheduledActionDrawIfPossible");
  658. EXPECT_FALSE(client_->IsInsideBeginImplFrame());
  659. EXPECT_TRUE(scheduler_->begin_frames_expected());
  660. client_->Reset();
  661. AdvanceFrame();
  662. EXPECT_ACTIONS("WillBeginImplFrame");
  663. }
  664. TEST_F(SchedulerTest, RequestCommitAfterBeginMainFrameSent) {
  665. SetUpScheduler(EXTERNAL_BFS);
  666. // SetNeedsBeginMainFrame should begin the frame.
  667. scheduler_->SetNeedsBeginMainFrame();
  668. EXPECT_ACTIONS("AddObserver(this)");
  669. client_->Reset();
  670. EXPECT_SCOPED(AdvanceFrame());
  671. EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame");
  672. EXPECT_TRUE(client_->IsInsideBeginImplFrame());
  673. EXPECT_TRUE(scheduler_->begin_frames_expected());
  674. client_->Reset();
  675. // Now SetNeedsBeginMainFrame again. Calling here means we need a second
  676. // commit.
  677. scheduler_->SetNeedsBeginMainFrame();
  678. EXPECT_NO_ACTION();
  679. client_->Reset();
  680. // Finish the first commit.
  681. scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
  682. scheduler_->NotifyReadyToCommit(nullptr);
  683. EXPECT_ACTIONS("ScheduledActionCommit", "ScheduledActionPostCommit");
  684. EXPECT_TRUE(client_->IsInsideBeginImplFrame());
  685. client_->Reset();
  686. // Activate it.
  687. scheduler_->NotifyReadyToActivate();
  688. EXPECT_ACTIONS("ScheduledActionActivateSyncTree");
  689. EXPECT_TRUE(client_->IsInsideBeginImplFrame());
  690. client_->Reset();
  691. task_runner_->RunPendingTasks(); // Run posted deadline.
  692. EXPECT_ACTIONS("ScheduledActionDrawIfPossible");
  693. EXPECT_FALSE(client_->IsInsideBeginImplFrame());
  694. // Because we just swapped, the Scheduler should also request the next
  695. // BeginImplFrame from the LayerTreeFrameSink.
  696. EXPECT_TRUE(scheduler_->begin_frames_expected());
  697. client_->Reset();
  698. // Since another commit is needed, the next BeginImplFrame should initiate
  699. // the second commit.
  700. EXPECT_SCOPED(AdvanceFrame());
  701. EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame");
  702. EXPECT_TRUE(client_->IsInsideBeginImplFrame());
  703. client_->Reset();
  704. // Finishing the commit before the deadline should post a new deadline task
  705. // to trigger the deadline early.
  706. scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
  707. scheduler_->NotifyReadyToCommit(nullptr);
  708. EXPECT_ACTIONS("ScheduledActionCommit", "ScheduledActionPostCommit");
  709. EXPECT_TRUE(client_->IsInsideBeginImplFrame());
  710. client_->Reset();
  711. scheduler_->NotifyReadyToActivate();
  712. EXPECT_ACTIONS("ScheduledActionActivateSyncTree");
  713. EXPECT_TRUE(client_->IsInsideBeginImplFrame());
  714. client_->Reset();
  715. task_runner_->RunPendingTasks(); // Run posted deadline.
  716. EXPECT_ACTIONS("ScheduledActionDrawIfPossible");
  717. EXPECT_FALSE(client_->IsInsideBeginImplFrame());
  718. EXPECT_TRUE(scheduler_->begin_frames_expected());
  719. client_->Reset();
  720. // On the next BeginImplFrame, verify we go back to a quiescent state and
  721. // no longer request BeginImplFrames.
  722. EXPECT_SCOPED(AdvanceFrame());
  723. task_runner_->RunPendingTasks(); // Run posted deadline.
  724. EXPECT_FALSE(scheduler_->begin_frames_expected());
  725. client_->Reset();
  726. }
  727. class SchedulerClientThatsetNeedsDrawInsideDraw : public FakeSchedulerClient {
  728. public:
  729. SchedulerClientThatsetNeedsDrawInsideDraw()
  730. : FakeSchedulerClient(), request_redraws_(false) {}
  731. void SetRequestRedrawsInsideDraw(bool enable) { request_redraws_ = enable; }
  732. DrawResult ScheduledActionDrawIfPossible() override {
  733. // Only SetNeedsRedraw the first time this is called
  734. if (request_redraws_) {
  735. scheduler_->SetNeedsRedraw();
  736. }
  737. return FakeSchedulerClient::ScheduledActionDrawIfPossible();
  738. }
  739. DrawResult ScheduledActionDrawForced() override {
  740. NOTREACHED();
  741. return DRAW_SUCCESS;
  742. }
  743. private:
  744. bool request_redraws_;
  745. };
  746. // Tests for two different situations:
  747. // 1. the scheduler dropping SetNeedsRedraw requests that happen inside
  748. // a ScheduledActionDraw
  749. // 2. the scheduler drawing twice inside a single tick
  750. TEST_F(SchedulerTest, RequestRedrawInsideDraw) {
  751. SchedulerClientThatsetNeedsDrawInsideDraw* client =
  752. new SchedulerClientThatsetNeedsDrawInsideDraw;
  753. SetUpScheduler(EXTERNAL_BFS, base::WrapUnique(client));
  754. client->SetRequestRedrawsInsideDraw(true);
  755. scheduler_->SetNeedsRedraw();
  756. EXPECT_TRUE(scheduler_->RedrawPending());
  757. EXPECT_TRUE(client->needs_begin_frames());
  758. EXPECT_EQ(0, client->num_draws());
  759. EXPECT_SCOPED(AdvanceFrame());
  760. task_runner_->RunPendingTasks(); // Run posted deadline.
  761. EXPECT_EQ(1, client->num_draws());
  762. EXPECT_TRUE(scheduler_->RedrawPending());
  763. EXPECT_TRUE(client->needs_begin_frames());
  764. client->SetRequestRedrawsInsideDraw(false);
  765. EXPECT_SCOPED(AdvanceFrame());
  766. task_runner_->RunPendingTasks(); // Run posted deadline.
  767. EXPECT_EQ(2, client_->num_draws());
  768. EXPECT_FALSE(scheduler_->RedrawPending());
  769. EXPECT_TRUE(client->needs_begin_frames());
  770. // We stop requesting BeginImplFrames after a BeginImplFrame where we don't
  771. // swap.
  772. EXPECT_SCOPED(AdvanceFrame());
  773. task_runner_->RunPendingTasks(); // Run posted deadline.
  774. EXPECT_EQ(2, client->num_draws());
  775. EXPECT_FALSE(scheduler_->RedrawPending());
  776. EXPECT_FALSE(client->needs_begin_frames());
  777. }
  778. // Test that requesting redraw inside a failed draw doesn't lose the request.
  779. TEST_F(SchedulerTest, RequestRedrawInsideFailedDraw) {
  780. SchedulerClientThatsetNeedsDrawInsideDraw* client =
  781. new SchedulerClientThatsetNeedsDrawInsideDraw;
  782. SetUpScheduler(EXTERNAL_BFS, base::WrapUnique(client));
  783. client->SetRequestRedrawsInsideDraw(true);
  784. client->SetDrawWillHappen(false);
  785. scheduler_->SetNeedsRedraw();
  786. EXPECT_TRUE(scheduler_->RedrawPending());
  787. EXPECT_TRUE(client->needs_begin_frames());
  788. EXPECT_EQ(0, client->num_draws());
  789. // Fail the draw.
  790. EXPECT_SCOPED(AdvanceFrame());
  791. task_runner_->RunPendingTasks(); // Run posted deadline.
  792. EXPECT_EQ(1, client->num_draws());
  793. // We have a commit pending and the draw failed, and we didn't lose the redraw
  794. // request.
  795. EXPECT_TRUE(scheduler_->CommitPending());
  796. EXPECT_TRUE(scheduler_->RedrawPending());
  797. EXPECT_TRUE(client->needs_begin_frames());
  798. client->SetRequestRedrawsInsideDraw(false);
  799. // Fail the draw again.
  800. EXPECT_SCOPED(AdvanceFrame());
  801. task_runner_->RunPendingTasks(); // Run posted deadline.
  802. EXPECT_EQ(2, client->num_draws());
  803. EXPECT_TRUE(scheduler_->CommitPending());
  804. EXPECT_TRUE(scheduler_->RedrawPending());
  805. EXPECT_TRUE(client->needs_begin_frames());
  806. // Draw successfully.
  807. client->SetDrawWillHappen(true);
  808. EXPECT_SCOPED(AdvanceFrame());
  809. task_runner_->RunPendingTasks(); // Run posted deadline.
  810. EXPECT_EQ(3, client->num_draws());
  811. EXPECT_TRUE(scheduler_->CommitPending());
  812. EXPECT_FALSE(scheduler_->RedrawPending());
  813. EXPECT_TRUE(client->needs_begin_frames());
  814. }
  815. class SchedulerClientThatSetNeedsBeginMainFrameInsideDraw
  816. : public FakeSchedulerClient {
  817. public:
  818. SchedulerClientThatSetNeedsBeginMainFrameInsideDraw()
  819. : set_needs_commit_on_next_draw_(false) {}
  820. DrawResult ScheduledActionDrawIfPossible() override {
  821. // Only SetNeedsBeginMainFrame the first time this is called
  822. if (set_needs_commit_on_next_draw_) {
  823. scheduler_->SetNeedsBeginMainFrame();
  824. set_needs_commit_on_next_draw_ = false;
  825. }
  826. return FakeSchedulerClient::ScheduledActionDrawIfPossible();
  827. }
  828. DrawResult ScheduledActionDrawForced() override {
  829. NOTREACHED();
  830. return DRAW_SUCCESS;
  831. }
  832. void SetNeedsBeginMainFrameOnNextDraw() {
  833. set_needs_commit_on_next_draw_ = true;
  834. }
  835. private:
  836. bool set_needs_commit_on_next_draw_;
  837. };
  838. // Tests for the scheduler infinite-looping on SetNeedsBeginMainFrame requests
  839. // that happen inside a ScheduledActionDraw
  840. TEST_F(SchedulerTest, RequestCommitInsideDraw) {
  841. SchedulerClientThatSetNeedsBeginMainFrameInsideDraw* client =
  842. new SchedulerClientThatSetNeedsBeginMainFrameInsideDraw;
  843. SetUpScheduler(EXTERNAL_BFS, base::WrapUnique(client));
  844. EXPECT_FALSE(client->needs_begin_frames());
  845. scheduler_->SetNeedsRedraw();
  846. EXPECT_TRUE(scheduler_->RedrawPending());
  847. EXPECT_EQ(0, client->num_draws());
  848. EXPECT_TRUE(client->needs_begin_frames());
  849. client->SetNeedsBeginMainFrameOnNextDraw();
  850. EXPECT_SCOPED(AdvanceFrame());
  851. client->SetNeedsBeginMainFrameOnNextDraw();
  852. task_runner_->RunPendingTasks(); // Run posted deadline.
  853. EXPECT_EQ(1, client->num_draws());
  854. EXPECT_TRUE(scheduler_->CommitPending());
  855. EXPECT_TRUE(client->needs_begin_frames());
  856. scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
  857. scheduler_->NotifyReadyToCommit(nullptr);
  858. scheduler_->NotifyReadyToActivate();
  859. EXPECT_SCOPED(AdvanceFrame());
  860. task_runner_->RunPendingTasks(); // Run posted deadline.
  861. EXPECT_EQ(2, client->num_draws());
  862. EXPECT_FALSE(scheduler_->RedrawPending());
  863. EXPECT_FALSE(scheduler_->CommitPending());
  864. EXPECT_TRUE(client->needs_begin_frames());
  865. // We stop requesting BeginImplFrames after a BeginImplFrame where we don't
  866. // swap.
  867. EXPECT_SCOPED(AdvanceFrame());
  868. task_runner_->RunPendingTasks(); // Run posted deadline.
  869. EXPECT_EQ(2, client->num_draws());
  870. EXPECT_FALSE(scheduler_->RedrawPending());
  871. EXPECT_FALSE(scheduler_->CommitPending());
  872. EXPECT_FALSE(client->needs_begin_frames());
  873. }
  874. // Tests that when a draw fails then the pending commit should not be dropped.
  875. TEST_F(SchedulerTest, RequestCommitInsideFailedDraw) {
  876. SchedulerClientThatsetNeedsDrawInsideDraw* client =
  877. new SchedulerClientThatsetNeedsDrawInsideDraw;
  878. SetUpScheduler(EXTERNAL_BFS, base::WrapUnique(client));
  879. client->SetDrawWillHappen(false);
  880. scheduler_->SetNeedsRedraw();
  881. EXPECT_TRUE(scheduler_->RedrawPending());
  882. EXPECT_TRUE(client->needs_begin_frames());
  883. EXPECT_EQ(0, client->num_draws());
  884. // Fail the draw.
  885. EXPECT_SCOPED(AdvanceFrame());
  886. task_runner_->RunPendingTasks(); // Run posted deadline.
  887. EXPECT_EQ(1, client->num_draws());
  888. // We have a commit pending and the draw failed, and we didn't lose the commit
  889. // request.
  890. EXPECT_TRUE(scheduler_->CommitPending());
  891. EXPECT_TRUE(scheduler_->RedrawPending());
  892. EXPECT_TRUE(client->needs_begin_frames());
  893. // Fail the draw again.
  894. EXPECT_SCOPED(AdvanceFrame());
  895. task_runner_->RunPendingTasks(); // Run posted deadline.
  896. EXPECT_EQ(2, client->num_draws());
  897. EXPECT_TRUE(scheduler_->CommitPending());
  898. EXPECT_TRUE(scheduler_->RedrawPending());
  899. EXPECT_TRUE(client->needs_begin_frames());
  900. // Draw successfully.
  901. client->SetDrawWillHappen(true);
  902. EXPECT_SCOPED(AdvanceFrame());
  903. task_runner_->RunPendingTasks(); // Run posted deadline.
  904. EXPECT_EQ(3, client->num_draws());
  905. EXPECT_TRUE(scheduler_->CommitPending());
  906. EXPECT_FALSE(scheduler_->RedrawPending());
  907. EXPECT_TRUE(client->needs_begin_frames());
  908. }
  909. TEST_F(SchedulerTest, NoSwapWhenDrawFails) {
  910. SchedulerClientThatSetNeedsBeginMainFrameInsideDraw* client =
  911. new SchedulerClientThatSetNeedsBeginMainFrameInsideDraw;
  912. SetUpScheduler(EXTERNAL_BFS, base::WrapUnique(client));
  913. scheduler_->SetNeedsRedraw();
  914. EXPECT_TRUE(scheduler_->RedrawPending());
  915. EXPECT_TRUE(client->needs_begin_frames());
  916. EXPECT_EQ(0, client->num_draws());
  917. // Draw successfully, this starts a new frame.
  918. client->SetNeedsBeginMainFrameOnNextDraw();
  919. EXPECT_SCOPED(AdvanceFrame());
  920. task_runner_->RunPendingTasks(); // Run posted deadline.
  921. EXPECT_EQ(1, client->num_draws());
  922. scheduler_->SetNeedsRedraw();
  923. EXPECT_TRUE(scheduler_->RedrawPending());
  924. EXPECT_TRUE(client->needs_begin_frames());
  925. // Fail to draw, this should not start a frame.
  926. client->SetDrawWillHappen(false);
  927. client->SetNeedsBeginMainFrameOnNextDraw();
  928. EXPECT_SCOPED(AdvanceFrame());
  929. task_runner_->RunPendingTasks(); // Run posted deadline.
  930. EXPECT_EQ(2, client->num_draws());
  931. }
  932. class SchedulerClientNeedsPrepareTilesInDraw : public FakeSchedulerClient {
  933. public:
  934. DrawResult ScheduledActionDrawIfPossible() override {
  935. scheduler_->SetNeedsPrepareTiles();
  936. return FakeSchedulerClient::ScheduledActionDrawIfPossible();
  937. }
  938. };
  939. // Test prepare tiles is independant of draws.
  940. TEST_F(SchedulerTest, PrepareTiles) {
  941. SchedulerClientNeedsPrepareTilesInDraw* client =
  942. new SchedulerClientNeedsPrepareTilesInDraw;
  943. SetUpScheduler(EXTERNAL_BFS, base::WrapUnique(client));
  944. // Request both draw and prepare tiles. PrepareTiles shouldn't
  945. // be trigged until BeginImplFrame.
  946. client->Reset();
  947. scheduler_->SetNeedsPrepareTiles();
  948. scheduler_->SetNeedsRedraw();
  949. EXPECT_TRUE(scheduler_->RedrawPending());
  950. EXPECT_TRUE(scheduler_->PrepareTilesPending());
  951. EXPECT_TRUE(client->needs_begin_frames());
  952. EXPECT_EQ(0, client->num_draws());
  953. EXPECT_FALSE(client->HasAction("ScheduledActionPrepareTiles"));
  954. EXPECT_FALSE(client->HasAction("ScheduledActionDrawIfPossible"));
  955. // We have no immediate actions to perform, so the BeginImplFrame should post
  956. // the deadline task.
  957. client->Reset();
  958. EXPECT_SCOPED(AdvanceFrame());
  959. EXPECT_ACTIONS("WillBeginImplFrame");
  960. EXPECT_TRUE(client_->IsInsideBeginImplFrame());
  961. // On the deadline, the actions should have occured in the right order.
  962. client->Reset();
  963. task_runner_->RunPendingTasks(); // Run posted deadline.
  964. EXPECT_EQ(1, client->num_draws());
  965. EXPECT_TRUE(client->HasAction("ScheduledActionDrawIfPossible"));
  966. EXPECT_TRUE(client->HasAction("ScheduledActionPrepareTiles"));
  967. EXPECT_LT(client->ActionIndex("ScheduledActionDrawIfPossible"),
  968. client->ActionIndex("ScheduledActionPrepareTiles"));
  969. EXPECT_FALSE(scheduler_->RedrawPending());
  970. EXPECT_FALSE(scheduler_->PrepareTilesPending());
  971. EXPECT_FALSE(client_->IsInsideBeginImplFrame());
  972. // Request a draw. We don't need a PrepareTiles yet.
  973. client->Reset();
  974. scheduler_->SetNeedsRedraw();
  975. EXPECT_TRUE(scheduler_->RedrawPending());
  976. EXPECT_FALSE(scheduler_->PrepareTilesPending());
  977. EXPECT_TRUE(client->needs_begin_frames());
  978. EXPECT_EQ(0, client->num_draws());
  979. // We have no immediate actions to perform, so the BeginImplFrame should post
  980. // the deadline task.
  981. client->Reset();
  982. EXPECT_SCOPED(AdvanceFrame());
  983. EXPECT_ACTIONS("WillBeginImplFrame");
  984. EXPECT_TRUE(client_->IsInsideBeginImplFrame());
  985. // Draw. The draw will trigger SetNeedsPrepareTiles, and
  986. // then the PrepareTiles action will be triggered after the Draw.
  987. // Afterwards, neither a draw nor PrepareTiles are pending.
  988. client->Reset();
  989. task_runner_->RunPendingTasks(); // Run posted deadline.
  990. EXPECT_EQ(1, client->num_draws());
  991. EXPECT_TRUE(client->HasAction("ScheduledActionDrawIfPossible"));
  992. EXPECT_TRUE(client->HasAction("ScheduledActionPrepareTiles"));
  993. EXPECT_LT(client->ActionIndex("ScheduledActionDrawIfPossible"),
  994. client->ActionIndex("ScheduledActionPrepareTiles"));
  995. EXPECT_FALSE(scheduler_->RedrawPending());
  996. EXPECT_FALSE(scheduler_->PrepareTilesPending());
  997. EXPECT_FALSE(client_->IsInsideBeginImplFrame());
  998. // We need a BeginImplFrame where we don't swap to go idle.
  999. client->Reset();
  1000. EXPECT_SCOPED(AdvanceFrame());
  1001. EXPECT_ACTIONS("WillBeginImplFrame");
  1002. EXPECT_TRUE(client_->IsInsideBeginImplFrame());
  1003. client->Reset();
  1004. task_runner_->RunPendingTasks(); // Run posted deadline.
  1005. EXPECT_ACTIONS("RemoveObserver(this)");
  1006. EXPECT_FALSE(client_->IsInsideBeginImplFrame());
  1007. EXPECT_EQ(0, client->num_draws());
  1008. // Now trigger a PrepareTiles outside of a draw. We will then need
  1009. // a begin-frame for the PrepareTiles, but we don't need a draw.
  1010. client->Reset();
  1011. EXPECT_FALSE(client->needs_begin_frames());
  1012. scheduler_->SetNeedsPrepareTiles();
  1013. EXPECT_TRUE(client->needs_begin_frames());
  1014. EXPECT_TRUE(scheduler_->PrepareTilesPending());
  1015. EXPECT_FALSE(scheduler_->RedrawPending());
  1016. // BeginImplFrame. There will be no draw, only PrepareTiles.
  1017. client->Reset();
  1018. EXPECT_SCOPED(AdvanceFrame());
  1019. EXPECT_ACTIONS("WillBeginImplFrame");
  1020. EXPECT_TRUE(client_->IsInsideBeginImplFrame());
  1021. client->Reset();
  1022. task_runner_->RunPendingTasks(); // Run posted deadline.
  1023. EXPECT_EQ(0, client->num_draws());
  1024. EXPECT_FALSE(client->HasAction("ScheduledActionDrawIfPossible"));
  1025. EXPECT_TRUE(client->HasAction("ScheduledActionPrepareTiles"));
  1026. EXPECT_FALSE(client_->IsInsideBeginImplFrame());
  1027. }
  1028. // Test that PrepareTiles only happens once per frame. If an external caller
  1029. // initiates it, then the state machine should not PrepareTiles on that frame.
  1030. TEST_F(SchedulerTest, PrepareTilesOncePerFrame) {
  1031. SetUpScheduler(EXTERNAL_BFS);
  1032. // If DidPrepareTiles during a frame, then PrepareTiles should not occur
  1033. // again.
  1034. scheduler_->SetNeedsPrepareTiles();
  1035. scheduler_->SetNeedsRedraw();
  1036. client_->Reset();
  1037. EXPECT_SCOPED(AdvanceFrame());
  1038. EXPECT_ACTIONS("WillBeginImplFrame");
  1039. EXPECT_TRUE(client_->IsInsideBeginImplFrame());
  1040. EXPECT_TRUE(scheduler_->PrepareTilesPending());
  1041. scheduler_->WillPrepareTiles();
  1042. scheduler_->DidPrepareTiles(); // An explicit PrepareTiles.
  1043. EXPECT_FALSE(scheduler_->PrepareTilesPending());
  1044. client_->Reset();
  1045. task_runner_->RunPendingTasks(); // Run posted deadline.
  1046. EXPECT_EQ(1, client_->num_draws());
  1047. EXPECT_TRUE(client_->HasAction("ScheduledActionDrawIfPossible"));
  1048. EXPECT_FALSE(client_->HasAction("ScheduledActionPrepareTiles"));
  1049. EXPECT_FALSE(scheduler_->RedrawPending());
  1050. EXPECT_FALSE(scheduler_->PrepareTilesPending());
  1051. EXPECT_FALSE(client_->IsInsideBeginImplFrame());
  1052. // Next frame without DidPrepareTiles should PrepareTiles with draw.
  1053. scheduler_->SetNeedsPrepareTiles();
  1054. scheduler_->SetNeedsRedraw();
  1055. client_->Reset();
  1056. EXPECT_SCOPED(AdvanceFrame());
  1057. EXPECT_ACTIONS("WillBeginImplFrame");
  1058. EXPECT_TRUE(client_->IsInsideBeginImplFrame());
  1059. client_->Reset();
  1060. task_runner_->RunPendingTasks(); // Run posted deadline.
  1061. EXPECT_EQ(1, client_->num_draws());
  1062. EXPECT_TRUE(client_->HasAction("ScheduledActionDrawIfPossible"));
  1063. EXPECT_TRUE(client_->HasAction("ScheduledActionPrepareTiles"));
  1064. EXPECT_LT(client_->ActionIndex("ScheduledActionDrawIfPossible"),
  1065. client_->ActionIndex("ScheduledActionPrepareTiles"));
  1066. EXPECT_FALSE(scheduler_->RedrawPending());
  1067. EXPECT_FALSE(scheduler_->PrepareTilesPending());
  1068. EXPECT_FALSE(client_->IsInsideBeginImplFrame());
  1069. // If we get another DidPrepareTiles within the same frame, we should
  1070. // not PrepareTiles on the next frame.
  1071. scheduler_->WillPrepareTiles();
  1072. scheduler_->DidPrepareTiles(); // An explicit PrepareTiles.
  1073. scheduler_->SetNeedsPrepareTiles();
  1074. scheduler_->SetNeedsRedraw();
  1075. client_->Reset();
  1076. EXPECT_SCOPED(AdvanceFrame());
  1077. EXPECT_ACTIONS("WillBeginImplFrame");
  1078. EXPECT_TRUE(client_->IsInsideBeginImplFrame());
  1079. EXPECT_TRUE(scheduler_->PrepareTilesPending());
  1080. client_->Reset();
  1081. task_runner_->RunPendingTasks(); // Run posted deadline.
  1082. EXPECT_EQ(1, client_->num_draws());
  1083. EXPECT_TRUE(client_->HasAction("ScheduledActionDrawIfPossible"));
  1084. EXPECT_FALSE(client_->HasAction("ScheduledActionPrepareTiles"));
  1085. EXPECT_FALSE(scheduler_->RedrawPending());
  1086. EXPECT_FALSE(client_->IsInsideBeginImplFrame());
  1087. // If we get another DidPrepareTiles, we should not PrepareTiles on the next
  1088. // frame. This verifies we don't alternate calling PrepareTiles once and
  1089. // twice.
  1090. EXPECT_TRUE(scheduler_->PrepareTilesPending());
  1091. scheduler_->WillPrepareTiles();
  1092. scheduler_->DidPrepareTiles(); // An explicit PrepareTiles.
  1093. EXPECT_FALSE(scheduler_->PrepareTilesPending());
  1094. scheduler_->SetNeedsPrepareTiles();
  1095. scheduler_->SetNeedsRedraw();
  1096. client_->Reset();
  1097. EXPECT_SCOPED(AdvanceFrame());
  1098. EXPECT_ACTIONS("WillBeginImplFrame");
  1099. EXPECT_TRUE(client_->IsInsideBeginImplFrame());
  1100. EXPECT_TRUE(scheduler_->PrepareTilesPending());
  1101. client_->Reset();
  1102. task_runner_->RunPendingTasks(); // Run posted deadline.
  1103. EXPECT_EQ(1, client_->num_draws());
  1104. EXPECT_TRUE(client_->HasAction("ScheduledActionDrawIfPossible"));
  1105. EXPECT_FALSE(client_->HasAction("ScheduledActionPrepareTiles"));
  1106. EXPECT_FALSE(scheduler_->RedrawPending());
  1107. EXPECT_FALSE(client_->IsInsideBeginImplFrame());
  1108. // Next frame without DidPrepareTiles should PrepareTiles with draw.
  1109. scheduler_->SetNeedsPrepareTiles();
  1110. scheduler_->SetNeedsRedraw();
  1111. client_->Reset();
  1112. EXPECT_SCOPED(AdvanceFrame());
  1113. EXPECT_ACTIONS("WillBeginImplFrame");
  1114. EXPECT_TRUE(client_->IsInsideBeginImplFrame());
  1115. client_->Reset();
  1116. task_runner_->RunPendingTasks(); // Run posted deadline.
  1117. EXPECT_EQ(1, client_->num_draws());
  1118. EXPECT_TRUE(client_->HasAction("ScheduledActionDrawIfPossible"));
  1119. EXPECT_TRUE(client_->HasAction("ScheduledActionPrepareTiles"));
  1120. EXPECT_LT(client_->ActionIndex("ScheduledActionDrawIfPossible"),
  1121. client_->ActionIndex("ScheduledActionPrepareTiles"));
  1122. EXPECT_FALSE(scheduler_->RedrawPending());
  1123. EXPECT_FALSE(scheduler_->PrepareTilesPending());
  1124. EXPECT_FALSE(client_->IsInsideBeginImplFrame());
  1125. }
  1126. TEST_F(SchedulerTest, DidPrepareTilesPreventsPrepareTilesForOneFrame) {
  1127. std::unique_ptr<SchedulerClientNeedsPrepareTilesInDraw> client =
  1128. base::WrapUnique(new SchedulerClientNeedsPrepareTilesInDraw);
  1129. SetUpScheduler(EXTERNAL_BFS, std::move(client));
  1130. client_->Reset();
  1131. scheduler_->SetNeedsRedraw();
  1132. EXPECT_ACTIONS("AddObserver(this)");
  1133. client_->Reset();
  1134. EXPECT_SCOPED(AdvanceFrame());
  1135. EXPECT_ACTIONS("WillBeginImplFrame");
  1136. EXPECT_TRUE(client_->IsInsideBeginImplFrame());
  1137. client_->Reset();
  1138. task_runner_->RunPendingTasks(); // Run posted deadline.
  1139. EXPECT_FALSE(client_->IsInsideBeginImplFrame());
  1140. EXPECT_ACTIONS("ScheduledActionDrawIfPossible",
  1141. "ScheduledActionPrepareTiles");
  1142. // We don't want to hinder scheduled prepare tiles for more than one frame
  1143. // even if we call unscheduled prepare tiles many times.
  1144. for (int i = 0; i < 10; i++) {
  1145. scheduler_->WillPrepareTiles();
  1146. scheduler_->DidPrepareTiles();
  1147. }
  1148. client_->Reset();
  1149. scheduler_->SetNeedsRedraw();
  1150. EXPECT_SCOPED(AdvanceFrame());
  1151. EXPECT_ACTIONS("WillBeginImplFrame");
  1152. EXPECT_TRUE(client_->IsInsideBeginImplFrame());
  1153. // No scheduled prepare tiles because we've already counted a prepare tiles in
  1154. // between frames.
  1155. client_->Reset();
  1156. task_runner_->RunPendingTasks(); // Run posted deadline.
  1157. EXPECT_FALSE(client_->IsInsideBeginImplFrame());
  1158. EXPECT_ACTIONS("ScheduledActionDrawIfPossible");
  1159. client_->Reset();
  1160. scheduler_->SetNeedsRedraw();
  1161. EXPECT_SCOPED(AdvanceFrame());
  1162. EXPECT_ACTIONS("WillBeginImplFrame");
  1163. EXPECT_TRUE(client_->IsInsideBeginImplFrame());
  1164. // Resume scheduled prepare tiles.
  1165. client_->Reset();
  1166. task_runner_->RunPendingTasks(); // Run posted deadline.
  1167. EXPECT_FALSE(client_->IsInsideBeginImplFrame());
  1168. EXPECT_ACTIONS("ScheduledActionDrawIfPossible",
  1169. "ScheduledActionPrepareTiles");
  1170. }
  1171. TEST_F(SchedulerTest, TriggerBeginFrameDeadlineEarly) {
  1172. SchedulerClientNeedsPrepareTilesInDraw* client =
  1173. new SchedulerClientNeedsPrepareTilesInDraw;
  1174. SetUpScheduler(EXTERNAL_BFS, base::WrapUnique(client));
  1175. scheduler_->SetNeedsRedraw();
  1176. EXPECT_SCOPED(AdvanceFrame());
  1177. // The deadline should be zero since there is no work other than drawing
  1178. // pending.
  1179. EXPECT_EQ(base::TimeTicks(), client->posted_begin_impl_frame_deadline());
  1180. }
  1181. TEST_F(SchedulerTest, WaitForReadyToDrawDoNotPostDeadline) {
  1182. SchedulerClientNeedsPrepareTilesInDraw* client =
  1183. new SchedulerClientNeedsPrepareTilesInDraw;
  1184. scheduler_settings_.commit_to_active_tree = true;
  1185. SetUpScheduler(EXTERNAL_BFS, base::WrapUnique(client));
  1186. // SetNeedsBeginMainFrame should begin the frame on the next BeginImplFrame.
  1187. scheduler_->SetNeedsBeginMainFrame();
  1188. EXPECT_ACTIONS("AddObserver(this)");
  1189. client_->Reset();
  1190. // Begin new frame.
  1191. EXPECT_SCOPED(AdvanceFrame());
  1192. scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
  1193. EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame");
  1194. client_->Reset();
  1195. scheduler_->NotifyReadyToCommit(nullptr);
  1196. EXPECT_ACTIONS("ScheduledActionCommit", "ScheduledActionPostCommit");
  1197. client_->Reset();
  1198. scheduler_->NotifyReadyToActivate();
  1199. EXPECT_ACTIONS("ScheduledActionActivateSyncTree");
  1200. // Scheduler won't post deadline in the mode.
  1201. client_->Reset();
  1202. task_runner_->RunPendingTasks(); // Try to run posted deadline.
  1203. // There is no posted deadline.
  1204. EXPECT_NO_ACTION();
  1205. // Scheduler received ready to draw signal, and posted deadline.
  1206. scheduler_->NotifyReadyToDraw();
  1207. client_->Reset();
  1208. task_runner_->RunPendingTasks(); // Run posted deadline.
  1209. EXPECT_EQ(1, client_->num_draws());
  1210. EXPECT_TRUE(client_->HasAction("ScheduledActionDrawIfPossible"));
  1211. }
  1212. TEST_F(SchedulerTest, WaitForReadyToDrawCancelledWhenLostLayerTreeFrameSink) {
  1213. SchedulerClientNeedsPrepareTilesInDraw* client =
  1214. new SchedulerClientNeedsPrepareTilesInDraw;
  1215. scheduler_settings_.commit_to_active_tree = true;
  1216. SetUpScheduler(EXTERNAL_BFS, base::WrapUnique(client));
  1217. // SetNeedsBeginMainFrame should begin the frame on the next BeginImplFrame.
  1218. scheduler_->SetNeedsBeginMainFrame();
  1219. EXPECT_ACTIONS("AddObserver(this)");
  1220. client_->Reset();
  1221. // Begin new frame.
  1222. EXPECT_SCOPED(AdvanceFrame());
  1223. scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
  1224. EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame");
  1225. client_->Reset();
  1226. scheduler_->NotifyReadyToCommit(nullptr);
  1227. EXPECT_ACTIONS("ScheduledActionCommit", "ScheduledActionPostCommit");
  1228. client_->Reset();
  1229. scheduler_->NotifyReadyToActivate();
  1230. EXPECT_ACTIONS("ScheduledActionActivateSyncTree");
  1231. // Scheduler won't post deadline in the mode.
  1232. client_->Reset();
  1233. task_runner_->RunPendingTasks(); // Try to run posted deadline.
  1234. // There is no posted deadline.
  1235. EXPECT_NO_ACTION();
  1236. // Scheduler loses LayerTreeFrameSink, and stops waiting for ready to draw
  1237. // signal.
  1238. client_->Reset();
  1239. scheduler_->DidLoseLayerTreeFrameSink();
  1240. EXPECT_TRUE(client_->IsInsideBeginImplFrame());
  1241. task_runner_->RunPendingTasks(); // Run posted deadline.
  1242. EXPECT_ACTIONS("ScheduledActionBeginLayerTreeFrameSinkCreation",
  1243. "RemoveObserver(this)");
  1244. }
  1245. void SchedulerTest::AdvanceAndMissOneFrame() {
  1246. // Impl thread hits deadline before commit finishes.
  1247. scheduler_->SetNeedsBeginMainFrame();
  1248. EXPECT_FALSE(scheduler_->MainThreadMissedLastDeadline());
  1249. EXPECT_SCOPED(AdvanceFrame());
  1250. EXPECT_FALSE(scheduler_->MainThreadMissedLastDeadline());
  1251. task_runner_->RunTasksWhile(client_->InsideBeginImplFrame(true));
  1252. EXPECT_TRUE(scheduler_->MainThreadMissedLastDeadline());
  1253. scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
  1254. scheduler_->NotifyReadyToCommit(nullptr);
  1255. scheduler_->NotifyReadyToActivate();
  1256. EXPECT_ACTIONS("AddObserver(this)", "WillBeginImplFrame",
  1257. "ScheduledActionSendBeginMainFrame", "ScheduledActionCommit",
  1258. "ScheduledActionPostCommit",
  1259. "ScheduledActionActivateSyncTree");
  1260. EXPECT_TRUE(scheduler_->MainThreadMissedLastDeadline());
  1261. client_->Reset();
  1262. }
  1263. void SchedulerTest::CheckMainFrameNotSkippedAfterLateCommit() {
  1264. AdvanceAndMissOneFrame();
  1265. scheduler_->SetNeedsBeginMainFrame();
  1266. EXPECT_TRUE(scheduler_->MainThreadMissedLastDeadline());
  1267. EXPECT_SCOPED(AdvanceFrame());
  1268. EXPECT_TRUE(scheduler_->MainThreadMissedLastDeadline());
  1269. task_runner_->RunTasksWhile(client_->InsideBeginImplFrame(true));
  1270. EXPECT_TRUE(scheduler_->MainThreadMissedLastDeadline());
  1271. EXPECT_TRUE(client_->HasAction("WillBeginImplFrame"));
  1272. EXPECT_TRUE(client_->HasAction("ScheduledActionSendBeginMainFrame"));
  1273. }
  1274. TEST_F(SchedulerTest, MainFrameNotSkippedAfterLateBeginFrame) {
  1275. // If a begin frame is delivered extremely late (because the browser has
  1276. // some contention), make sure that the main frame is not skipped even
  1277. // if it can activate before the deadline.
  1278. SetUpScheduler(EXTERNAL_BFS);
  1279. fake_compositor_timing_history_->SetAllEstimatesTo(kFastDuration);
  1280. AdvanceAndMissOneFrame();
  1281. EXPECT_TRUE(scheduler_->MainThreadMissedLastDeadline());
  1282. scheduler_->SetNeedsBeginMainFrame();
  1283. // Advance frame and create a begin frame.
  1284. task_runner_->AdvanceMockTickClock(viz::BeginFrameArgs::DefaultInterval());
  1285. viz::BeginFrameArgs args =
  1286. fake_external_begin_frame_source_->CreateBeginFrameArgs(
  1287. BEGINFRAME_FROM_HERE, task_runner_->GetMockTickClock());
  1288. // Deliver this begin frame super late.
  1289. task_runner_->AdvanceMockTickClock(viz::BeginFrameArgs::DefaultInterval() *
  1290. 100);
  1291. fake_external_begin_frame_source_->TestOnBeginFrame(args);
  1292. task_runner_->RunTasksWhile(client_->InsideBeginImplFrame(true));
  1293. EXPECT_EQ(true, scheduler_->MainThreadMissedLastDeadline());
  1294. EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame",
  1295. "ScheduledActionDrawIfPossible");
  1296. }
  1297. TEST_F(SchedulerTest, FrameIntervalUpdated) {
  1298. // Verify that the SchedulerClient gets updates when the begin frame interval
  1299. // changes.
  1300. SetUpScheduler(EXTERNAL_BFS);
  1301. constexpr uint64_t kSourceId = viz::BeginFrameArgs::kStartingSourceId;
  1302. uint64_t sequence_number = viz::BeginFrameArgs::kStartingFrameNumber;
  1303. base::TimeDelta interval =
  1304. base::Microseconds(base::Time::kMicrosecondsPerSecond / 120.0);
  1305. // Send BeginFrameArgs with 120hz refresh rate and confirm client gets update.
  1306. scheduler_->SetNeedsRedraw();
  1307. task_runner_->AdvanceMockTickClock(interval);
  1308. viz::BeginFrameArgs args1 = viz::BeginFrameArgs::Create(
  1309. BEGINFRAME_FROM_HERE, kSourceId, sequence_number++,
  1310. task_runner_->NowTicks(), task_runner_->NowTicks() + interval, interval,
  1311. viz::BeginFrameArgs::NORMAL);
  1312. fake_external_begin_frame_source_->TestOnBeginFrame(args1);
  1313. EXPECT_EQ(client_->frame_interval(), interval);
  1314. // Send another BeginFrameArgs with 120hz refresh rate that arrives late. Even
  1315. // though the interval between begin frames arriving is bigger than |interval|
  1316. // the client only hears the interval specified in BeginFrameArgs.
  1317. scheduler_->SetNeedsRedraw();
  1318. const base::TimeDelta late_delta = base::Milliseconds(4);
  1319. task_runner_->AdvanceMockTickClock(interval + late_delta);
  1320. viz::BeginFrameArgs args2 = viz::BeginFrameArgs::Create(
  1321. BEGINFRAME_FROM_HERE, kSourceId, sequence_number++, args1.deadline,
  1322. args1.deadline + interval, interval, viz::BeginFrameArgs::NORMAL);
  1323. fake_external_begin_frame_source_->TestOnBeginFrame(args2);
  1324. EXPECT_EQ(client_->frame_interval(), interval);
  1325. // Change the interval for 90hz refresh rate.
  1326. interval = base::Microseconds(base::Time::kMicrosecondsPerSecond / 90.0);
  1327. // Send BeginFrameArgs with 90hz refresh rate and confirm client gets update.
  1328. scheduler_->SetNeedsRedraw();
  1329. task_runner_->AdvanceMockTickClock(args2.deadline - task_runner_->NowTicks());
  1330. viz::BeginFrameArgs args3 = viz::BeginFrameArgs::Create(
  1331. BEGINFRAME_FROM_HERE, kSourceId, sequence_number++, args2.deadline,
  1332. args2.deadline + interval, interval, viz::BeginFrameArgs::NORMAL);
  1333. fake_external_begin_frame_source_->TestOnBeginFrame(args3);
  1334. EXPECT_EQ(client_->frame_interval(), interval);
  1335. // Send BeginFrameArgs with zero interval. This isn't a valid interval and
  1336. // client shouldn't find out about it.
  1337. scheduler_->SetNeedsRedraw();
  1338. task_runner_->AdvanceMockTickClock(interval);
  1339. viz::BeginFrameArgs args4 = viz::BeginFrameArgs::Create(
  1340. BEGINFRAME_FROM_HERE, kSourceId, sequence_number++, args3.deadline,
  1341. args3.deadline + interval, base::TimeDelta(),
  1342. viz::BeginFrameArgs::NORMAL);
  1343. fake_external_begin_frame_source_->TestOnBeginFrame(args4);
  1344. EXPECT_EQ(client_->frame_interval(), interval);
  1345. }
  1346. TEST_F(SchedulerTest, MainFrameNotSkippedAfterLateCommit) {
  1347. SetUpScheduler(EXTERNAL_BFS);
  1348. fake_compositor_timing_history_->SetAllEstimatesTo(kFastDuration);
  1349. EXPECT_SCOPED(CheckMainFrameNotSkippedAfterLateCommit());
  1350. }
  1351. // Response times of BeginMainFrame's without the critical path flag set
  1352. // should not affect whether we recover latency or not.
  1353. TEST_F(
  1354. SchedulerTest,
  1355. MainFrameNotSkippedAfterLateCommit_LongMainFrameQueueDurationNotCritical) {
  1356. SetUpScheduler(EXTERNAL_BFS);
  1357. fake_compositor_timing_history_->SetAllEstimatesTo(kFastDuration);
  1358. fake_compositor_timing_history_
  1359. ->SetBeginMainFrameQueueDurationNotCriticalEstimate(kSlowDuration);
  1360. EXPECT_SCOPED(CheckMainFrameNotSkippedAfterLateCommit());
  1361. }
  1362. // Response times of BeginMainFrame's with the critical path flag set
  1363. // should affect whether we recover latency or not.
  1364. TEST_F(SchedulerTest,
  1365. MainFrameNotSkippedAfterLateCommit_LongMainFrameQueueDurationCritical) {
  1366. SetUpScheduler(EXTERNAL_BFS);
  1367. fake_compositor_timing_history_->SetAllEstimatesTo(kFastDuration);
  1368. fake_compositor_timing_history_
  1369. ->SetBeginMainFrameQueueDurationCriticalEstimate(kSlowDuration);
  1370. fake_compositor_timing_history_
  1371. ->SetBeginMainFrameQueueDurationNotCriticalEstimate(kSlowDuration);
  1372. EXPECT_SCOPED(CheckMainFrameNotSkippedAfterLateCommit());
  1373. }
  1374. TEST_F(SchedulerTest,
  1375. MainFrameNotSkippedAfterLateCommitInPreferImplLatencyMode) {
  1376. SetUpScheduler(EXTERNAL_BFS);
  1377. scheduler_->SetTreePrioritiesAndScrollState(
  1378. SMOOTHNESS_TAKES_PRIORITY,
  1379. ScrollHandlerState::SCROLL_DOES_NOT_AFFECT_SCROLL_HANDLER);
  1380. fake_compositor_timing_history_->SetAllEstimatesTo(kFastDuration);
  1381. EXPECT_SCOPED(CheckMainFrameNotSkippedAfterLateCommit());
  1382. }
  1383. TEST_F(SchedulerTest,
  1384. MainFrameNotSkippedAfterLateCommit_CommitEstimateTooLong) {
  1385. SetUpScheduler(EXTERNAL_BFS);
  1386. fake_compositor_timing_history_->SetAllEstimatesTo(kFastDuration);
  1387. fake_compositor_timing_history_
  1388. ->SetBeginMainFrameStartToReadyToCommitDurationEstimate(kSlowDuration);
  1389. EXPECT_SCOPED(CheckMainFrameNotSkippedAfterLateCommit());
  1390. }
  1391. TEST_F(SchedulerTest,
  1392. MainFrameNotSkippedAfterLateCommit_ReadyToActivateEstimateTooLong) {
  1393. SetUpScheduler(EXTERNAL_BFS);
  1394. fake_compositor_timing_history_->SetAllEstimatesTo(kFastDuration);
  1395. fake_compositor_timing_history_->SetCommitToReadyToActivateDurationEstimate(
  1396. kSlowDuration);
  1397. EXPECT_SCOPED(CheckMainFrameNotSkippedAfterLateCommit());
  1398. }
  1399. TEST_F(SchedulerTest,
  1400. MainFrameNotSkippedAfterLateCommit_ActivateEstimateTooLong) {
  1401. SetUpScheduler(EXTERNAL_BFS);
  1402. fake_compositor_timing_history_->SetAllEstimatesTo(kFastDuration);
  1403. fake_compositor_timing_history_->SetActivateDurationEstimate(kSlowDuration);
  1404. EXPECT_SCOPED(CheckMainFrameNotSkippedAfterLateCommit());
  1405. }
  1406. TEST_F(SchedulerTest, MainFrameNotSkippedAfterLateCommit_DrawEstimateTooLong) {
  1407. SetUpScheduler(EXTERNAL_BFS);
  1408. fake_compositor_timing_history_->SetAllEstimatesTo(kFastDuration);
  1409. fake_compositor_timing_history_->SetDrawDurationEstimate(kSlowDuration);
  1410. EXPECT_SCOPED(CheckMainFrameNotSkippedAfterLateCommit());
  1411. }
  1412. // If the BeginMainFrame aborts, it doesn't actually insert a frame into the
  1413. // queue, which means there is no latency to recover.
  1414. TEST_F(SchedulerTest, MainFrameNotSkippedAfterLateBeginMainFrameAbort) {
  1415. SetUpScheduler(EXTERNAL_BFS);
  1416. // Use fast estimates so we think we can recover latency if needed.
  1417. fake_compositor_timing_history_->SetAllEstimatesTo(kFastDuration);
  1418. // Impl thread hits deadline before BeginMainFrame aborts.
  1419. scheduler_->SetNeedsBeginMainFrame();
  1420. EXPECT_FALSE(scheduler_->MainThreadMissedLastDeadline());
  1421. EXPECT_SCOPED(AdvanceFrame());
  1422. EXPECT_ACTIONS("AddObserver(this)", "WillBeginImplFrame",
  1423. "ScheduledActionSendBeginMainFrame");
  1424. EXPECT_FALSE(scheduler_->MainThreadMissedLastDeadline());
  1425. task_runner_->RunTasksWhile(client_->InsideBeginImplFrame(true));
  1426. EXPECT_TRUE(scheduler_->MainThreadMissedLastDeadline());
  1427. scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
  1428. EXPECT_TRUE(scheduler_->MainThreadMissedLastDeadline());
  1429. // After aborting the frame, make sure we don't skip the
  1430. // next BeginMainFrame.
  1431. client_->Reset();
  1432. scheduler_->BeginMainFrameAborted(CommitEarlyOutReason::FINISHED_NO_UPDATES);
  1433. EXPECT_FALSE(scheduler_->MainThreadMissedLastDeadline());
  1434. scheduler_->SetNeedsBeginMainFrame();
  1435. EXPECT_FALSE(scheduler_->MainThreadMissedLastDeadline());
  1436. EXPECT_SCOPED(AdvanceFrame());
  1437. EXPECT_TRUE(client_->HasAction("WillBeginImplFrame"));
  1438. EXPECT_TRUE(client_->HasAction("ScheduledActionSendBeginMainFrame"));
  1439. EXPECT_FALSE(scheduler_->MainThreadMissedLastDeadline());
  1440. task_runner_->RunTasksWhile(client_->InsideBeginImplFrame(true));
  1441. EXPECT_TRUE(scheduler_->MainThreadMissedLastDeadline());
  1442. }
  1443. // If the BeginMainFrame aborts, it doesn't actually insert a frame into the
  1444. // queue, which means there is no latency to recover.
  1445. TEST_F(SchedulerTest, MainFrameNotSkippedAfterCanDrawChanges) {
  1446. SetUpScheduler(EXTERNAL_BFS);
  1447. // Use fast estimates so we think we can recover latency if needed.
  1448. fake_compositor_timing_history_->SetAllEstimatesTo(kFastDuration);
  1449. // Impl thread hits deadline before BeginMainFrame aborts.
  1450. scheduler_->SetNeedsBeginMainFrame();
  1451. EXPECT_FALSE(scheduler_->MainThreadMissedLastDeadline());
  1452. EXPECT_SCOPED(AdvanceFrame());
  1453. EXPECT_ACTIONS("AddObserver(this)", "WillBeginImplFrame",
  1454. "ScheduledActionSendBeginMainFrame");
  1455. EXPECT_FALSE(scheduler_->MainThreadMissedLastDeadline());
  1456. task_runner_->RunTasksWhile(client_->InsideBeginImplFrame(true));
  1457. EXPECT_TRUE(scheduler_->MainThreadMissedLastDeadline());
  1458. scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
  1459. EXPECT_TRUE(scheduler_->MainThreadMissedLastDeadline());
  1460. // Make us abort the upcoming draw.
  1461. client_->Reset();
  1462. scheduler_->NotifyReadyToCommit(nullptr);
  1463. scheduler_->NotifyReadyToActivate();
  1464. EXPECT_ACTIONS("ScheduledActionCommit", "ScheduledActionPostCommit",
  1465. "ScheduledActionActivateSyncTree");
  1466. EXPECT_TRUE(scheduler_->MainThreadMissedLastDeadline());
  1467. scheduler_->SetCanDraw(false);
  1468. EXPECT_FALSE(scheduler_->MainThreadMissedLastDeadline());
  1469. // Make CanDraw true after activation.
  1470. client_->Reset();
  1471. scheduler_->SetCanDraw(true);
  1472. EXPECT_NO_ACTION();
  1473. EXPECT_FALSE(scheduler_->MainThreadMissedLastDeadline());
  1474. // Make sure we don't skip the next BeginMainFrame.
  1475. client_->Reset();
  1476. scheduler_->SetNeedsBeginMainFrame();
  1477. EXPECT_FALSE(scheduler_->MainThreadMissedLastDeadline());
  1478. EXPECT_SCOPED(AdvanceFrame());
  1479. EXPECT_TRUE(client_->HasAction("WillBeginImplFrame"));
  1480. EXPECT_TRUE(client_->HasAction("ScheduledActionSendBeginMainFrame"));
  1481. EXPECT_FALSE(scheduler_->MainThreadMissedLastDeadline());
  1482. task_runner_->RunTasksWhile(client_->InsideBeginImplFrame(true));
  1483. EXPECT_TRUE(scheduler_->MainThreadMissedLastDeadline());
  1484. }
  1485. TEST_F(SchedulerTest, MainFrameNotSkippedWhenNoTimingHistory) {
  1486. SetUpScheduler(EXTERNAL_BFS);
  1487. // Use fast estimates so we think we can recover latency if needed.
  1488. fake_compositor_timing_history_->SetAllEstimatesTo(kFastDuration);
  1489. // Impl thread hits deadline before BeginMainFrame commits.
  1490. scheduler_->SetNeedsBeginMainFrame();
  1491. EXPECT_FALSE(scheduler_->MainThreadMissedLastDeadline());
  1492. EXPECT_SCOPED(AdvanceFrame());
  1493. EXPECT_ACTIONS("AddObserver(this)", "WillBeginImplFrame",
  1494. "ScheduledActionSendBeginMainFrame");
  1495. EXPECT_FALSE(scheduler_->MainThreadMissedLastDeadline());
  1496. task_runner_->RunTasksWhile(client_->InsideBeginImplFrame(true));
  1497. EXPECT_TRUE(scheduler_->MainThreadMissedLastDeadline());
  1498. scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
  1499. EXPECT_TRUE(scheduler_->MainThreadMissedLastDeadline());
  1500. // Commit after the deadline.
  1501. client_->Reset();
  1502. scheduler_->NotifyReadyToCommit(nullptr);
  1503. scheduler_->NotifyReadyToActivate();
  1504. EXPECT_ACTIONS("ScheduledActionCommit", "ScheduledActionPostCommit",
  1505. "ScheduledActionActivateSyncTree");
  1506. EXPECT_TRUE(scheduler_->MainThreadMissedLastDeadline());
  1507. // Clear the timing history. Make sure we don't skip the main frame until we
  1508. // have history from at least one frame.
  1509. client_->Reset();
  1510. scheduler_->SetNeedsBeginMainFrame();
  1511. scheduler_->ClearHistory();
  1512. EXPECT_SCOPED(AdvanceFrame());
  1513. EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame");
  1514. }
  1515. void SchedulerTest::ImplFrameNotSkippedAfterLateAck() {
  1516. // To get into a high latency state, this test disables automatic swap acks.
  1517. client_->SetAutomaticSubmitCompositorFrameAck(false);
  1518. // Draw and swap for first BeginFrame
  1519. client_->Reset();
  1520. scheduler_->SetNeedsBeginMainFrame();
  1521. EXPECT_FALSE(scheduler_->MainThreadMissedLastDeadline());
  1522. SendNextBeginFrame();
  1523. EXPECT_ACTIONS("AddObserver(this)", "WillBeginImplFrame",
  1524. "ScheduledActionSendBeginMainFrame");
  1525. client_->Reset();
  1526. scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
  1527. scheduler_->NotifyReadyToCommit(nullptr);
  1528. scheduler_->NotifyReadyToActivate();
  1529. EXPECT_FALSE(scheduler_->MainThreadMissedLastDeadline());
  1530. task_runner_->RunTasksWhile(client_->InsideBeginImplFrame(true));
  1531. EXPECT_ACTIONS("ScheduledActionCommit", "ScheduledActionPostCommit",
  1532. "ScheduledActionActivateSyncTree",
  1533. "ScheduledActionDrawIfPossible");
  1534. // Verify impl thread consistently operates in high latency mode
  1535. // without skipping any frames.
  1536. for (int i = 0; i < 10; i++) {
  1537. // Not calling scheduler_->DidReceiveCompositorFrameAck() until after next
  1538. // frame
  1539. // puts the impl thread in high latency mode.
  1540. client_->Reset();
  1541. scheduler_->SetNeedsBeginMainFrame();
  1542. EXPECT_FALSE(scheduler_->MainThreadMissedLastDeadline());
  1543. SendNextBeginFrame();
  1544. EXPECT_ACTIONS("WillBeginImplFrame");
  1545. EXPECT_TRUE(client_->IsInsideBeginImplFrame());
  1546. EXPECT_FALSE(scheduler_->MainThreadMissedLastDeadline());
  1547. client_->Reset();
  1548. scheduler_->DidReceiveCompositorFrameAck();
  1549. scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
  1550. scheduler_->NotifyReadyToCommit(nullptr);
  1551. scheduler_->NotifyReadyToActivate();
  1552. task_runner_->RunTasksWhile(client_->InsideBeginImplFrame(true));
  1553. // Verify that we don't skip the actions of the BeginImplFrame
  1554. EXPECT_ACTIONS("ScheduledActionSendBeginMainFrame", "ScheduledActionCommit",
  1555. "ScheduledActionPostCommit",
  1556. "ScheduledActionActivateSyncTree",
  1557. "ScheduledActionDrawIfPossible");
  1558. }
  1559. }
  1560. TEST_F(SchedulerTest,
  1561. ImplFrameNotSkippedAfterLateAck_MainFrameQueueDurationCriticalTooLong) {
  1562. SetUpScheduler(EXTERNAL_BFS);
  1563. fake_compositor_timing_history_->SetAllEstimatesTo(kFastDuration);
  1564. fake_compositor_timing_history_
  1565. ->SetBeginMainFrameQueueDurationCriticalEstimate(kSlowDuration);
  1566. fake_compositor_timing_history_
  1567. ->SetBeginMainFrameQueueDurationNotCriticalEstimate(kSlowDuration);
  1568. EXPECT_SCOPED(ImplFrameNotSkippedAfterLateAck());
  1569. }
  1570. TEST_F(SchedulerTest, ImplFrameNotSkippedAfterLateAck_CommitEstimateTooLong) {
  1571. SetUpScheduler(EXTERNAL_BFS);
  1572. fake_compositor_timing_history_->SetAllEstimatesTo(kFastDuration);
  1573. fake_compositor_timing_history_
  1574. ->SetBeginMainFrameStartToReadyToCommitDurationEstimate(kSlowDuration);
  1575. EXPECT_SCOPED(ImplFrameNotSkippedAfterLateAck());
  1576. }
  1577. TEST_F(SchedulerTest,
  1578. ImplFrameNotSkippedAfterLateAck_ReadyToActivateEstimateTooLong) {
  1579. SetUpScheduler(EXTERNAL_BFS);
  1580. fake_compositor_timing_history_->SetAllEstimatesTo(kFastDuration);
  1581. fake_compositor_timing_history_->SetCommitToReadyToActivateDurationEstimate(
  1582. kSlowDuration);
  1583. EXPECT_SCOPED(ImplFrameNotSkippedAfterLateAck());
  1584. }
  1585. TEST_F(SchedulerTest, ImplFrameNotSkippedAfterLateAck_ActivateEstimateTooLong) {
  1586. SetUpScheduler(EXTERNAL_BFS);
  1587. fake_compositor_timing_history_->SetAllEstimatesTo(kFastDuration);
  1588. fake_compositor_timing_history_->SetActivateDurationEstimate(kSlowDuration);
  1589. EXPECT_SCOPED(ImplFrameNotSkippedAfterLateAck());
  1590. }
  1591. TEST_F(SchedulerTest, ImplFrameNotSkippedAfterLateAck_DrawEstimateTooLong) {
  1592. SetUpScheduler(EXTERNAL_BFS);
  1593. fake_compositor_timing_history_->SetAllEstimatesTo(kFastDuration);
  1594. fake_compositor_timing_history_->SetDrawDurationEstimate(kSlowDuration);
  1595. EXPECT_SCOPED(ImplFrameNotSkippedAfterLateAck());
  1596. }
  1597. void SchedulerTest::BeginFramesNotFromClient(BeginFrameSourceType bfs_type) {
  1598. SetUpScheduler(bfs_type);
  1599. // SetNeedsBeginMainFrame should begin the frame on the next BeginImplFrame
  1600. // without calling SetNeedsBeginFrame.
  1601. scheduler_->SetNeedsBeginMainFrame();
  1602. EXPECT_NO_ACTION();
  1603. client_->Reset();
  1604. EXPECT_SCOPED(AdvanceFrame());
  1605. EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame");
  1606. EXPECT_TRUE(client_->IsInsideBeginImplFrame());
  1607. client_->Reset();
  1608. // Can't run the deadline task because it can race with begin frame for the
  1609. // SyntheticBFS case.
  1610. EXPECT_SCOPED(AdvanceFrame());
  1611. EXPECT_ACTIONS("WillBeginImplFrame");
  1612. EXPECT_TRUE(client_->IsInsideBeginImplFrame());
  1613. client_->Reset();
  1614. // NotifyReadyToCommit should trigger the commit.
  1615. scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
  1616. scheduler_->NotifyReadyToCommit(nullptr);
  1617. EXPECT_ACTIONS("ScheduledActionCommit", "ScheduledActionPostCommit");
  1618. client_->Reset();
  1619. // NotifyReadyToActivate should trigger the activation.
  1620. scheduler_->NotifyReadyToActivate();
  1621. EXPECT_ACTIONS("ScheduledActionActivateSyncTree");
  1622. client_->Reset();
  1623. // BeginImplFrame deadline should draw. The following BeginImplFrame deadline
  1624. // should SetNeedsBeginFrame(false) to avoid excessive toggles.
  1625. EXPECT_SCOPED(AdvanceFrame());
  1626. EXPECT_ACTIONS("ScheduledActionDrawIfPossible", "WillBeginImplFrame");
  1627. client_->Reset();
  1628. // Make sure SetNeedsBeginFrame isn't called on the client
  1629. // when the BeginFrame is no longer needed.
  1630. task_runner_->RunPendingTasks(); // Run posted deadline.
  1631. EXPECT_NO_ACTION();
  1632. client_->Reset();
  1633. }
  1634. TEST_F(SchedulerTest, SyntheticBeginFrames) {
  1635. BeginFramesNotFromClient(THROTTLED_BFS);
  1636. }
  1637. TEST_F(SchedulerTest, UnthrottledBeginFrames) {
  1638. BeginFramesNotFromClient(UNTHROTTLED_BFS);
  1639. }
  1640. void SchedulerTest::BeginFramesNotFromClient_IsDrawThrottled(
  1641. BeginFrameSourceType bfs_type) {
  1642. SetUpScheduler(bfs_type);
  1643. // Set the draw duration estimate to zero so that deadlines are accurate.
  1644. fake_compositor_timing_history_->SetDrawDurationEstimate(base::TimeDelta());
  1645. // To test swap ack throttling, this test disables automatic swap acks.
  1646. client_->SetAutomaticSubmitCompositorFrameAck(false);
  1647. // SetNeedsBeginMainFrame should begin the frame on the next BeginImplFrame.
  1648. client_->Reset();
  1649. scheduler_->SetNeedsBeginMainFrame();
  1650. EXPECT_NO_ACTION();
  1651. client_->Reset();
  1652. // Trigger the first BeginImplFrame and BeginMainFrame
  1653. EXPECT_SCOPED(AdvanceFrame());
  1654. EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame");
  1655. EXPECT_TRUE(client_->IsInsideBeginImplFrame());
  1656. client_->Reset();
  1657. // NotifyReadyToCommit should trigger the pending commit.
  1658. scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
  1659. scheduler_->NotifyReadyToCommit(nullptr);
  1660. EXPECT_ACTIONS("ScheduledActionCommit", "ScheduledActionPostCommit");
  1661. client_->Reset();
  1662. // NotifyReadyToActivate should trigger the activation and draw.
  1663. scheduler_->NotifyReadyToActivate();
  1664. EXPECT_ACTIONS("ScheduledActionActivateSyncTree");
  1665. client_->Reset();
  1666. // Swapping will put us into a swap throttled state.
  1667. // Run posted deadline.
  1668. task_runner_->RunTasksWhile(client_->InsideBeginImplFrame(true));
  1669. EXPECT_ACTIONS("ScheduledActionDrawIfPossible");
  1670. EXPECT_FALSE(client_->IsInsideBeginImplFrame());
  1671. client_->Reset();
  1672. // While swap throttled, BeginFrames should trigger BeginImplFrames,
  1673. // but not a BeginMainFrame or draw.
  1674. scheduler_->SetNeedsBeginMainFrame();
  1675. scheduler_->SetNeedsRedraw();
  1676. EXPECT_SCOPED(AdvanceFrame()); // Run posted BeginFrame.
  1677. EXPECT_ACTIONS("WillBeginImplFrame");
  1678. EXPECT_TRUE(client_->IsInsideBeginImplFrame());
  1679. client_->Reset();
  1680. base::TimeTicks before_deadline, after_deadline;
  1681. // The deadline is set to the regular deadline.
  1682. before_deadline = task_runner_->NowTicks();
  1683. task_runner_->RunTasksWhile(client_->InsideBeginImplFrame(true));
  1684. after_deadline = task_runner_->NowTicks();
  1685. // We can't do an equality comparison here because the scheduler uses a fudge
  1686. // factor that's an internal implementation detail.
  1687. EXPECT_GT(after_deadline, before_deadline);
  1688. EXPECT_LT(after_deadline,
  1689. before_deadline + viz::BeginFrameArgs::DefaultInterval());
  1690. EXPECT_FALSE(client_->IsInsideBeginImplFrame());
  1691. client_->Reset();
  1692. EXPECT_SCOPED(AdvanceFrame()); // Run posted BeginFrame.
  1693. EXPECT_ACTIONS("WillBeginImplFrame");
  1694. EXPECT_TRUE(client_->IsInsideBeginImplFrame());
  1695. client_->Reset();
  1696. // Take us out of a swap throttled state.
  1697. scheduler_->DidReceiveCompositorFrameAck();
  1698. EXPECT_ACTIONS("ScheduledActionSendBeginMainFrame");
  1699. EXPECT_TRUE(client_->IsInsideBeginImplFrame());
  1700. client_->Reset();
  1701. // The deadline is set to the regular deadline.
  1702. before_deadline = task_runner_->NowTicks();
  1703. task_runner_->RunTasksWhile(client_->InsideBeginImplFrame(true));
  1704. after_deadline = task_runner_->NowTicks();
  1705. // We can't do an equality comparison here because the scheduler uses a fudge
  1706. // factor that's an internal implementation detail.
  1707. EXPECT_GT(after_deadline, before_deadline);
  1708. EXPECT_LT(after_deadline,
  1709. before_deadline + viz::BeginFrameArgs::DefaultInterval());
  1710. EXPECT_FALSE(client_->IsInsideBeginImplFrame());
  1711. client_->Reset();
  1712. }
  1713. TEST_F(SchedulerTest, SyntheticBeginFrames_IsDrawThrottled) {
  1714. BeginFramesNotFromClient_IsDrawThrottled(THROTTLED_BFS);
  1715. }
  1716. TEST_F(SchedulerTest, UnthrottledBeginFrames_IsDrawThrottled) {
  1717. BeginFramesNotFromClient_IsDrawThrottled(UNTHROTTLED_BFS);
  1718. }
  1719. TEST_F(SchedulerTest,
  1720. DidLoseLayerTreeFrameSinkAfterLayerTreeFrameSinkIsInitialized) {
  1721. SetUpSchedulerWithNoLayerTreeFrameSink(EXTERNAL_BFS);
  1722. scheduler_->SetVisible(true);
  1723. scheduler_->SetCanDraw(true);
  1724. EXPECT_ACTIONS("ScheduledActionBeginLayerTreeFrameSinkCreation");
  1725. client_->Reset();
  1726. scheduler_->DidCreateAndInitializeLayerTreeFrameSink();
  1727. EXPECT_NO_ACTION();
  1728. scheduler_->DidLoseLayerTreeFrameSink();
  1729. EXPECT_ACTIONS("ScheduledActionBeginLayerTreeFrameSinkCreation");
  1730. }
  1731. TEST_F(SchedulerTest, DidLoseLayerTreeFrameSinkAfterBeginFrameStarted) {
  1732. SetUpScheduler(EXTERNAL_BFS);
  1733. // SetNeedsBeginMainFrame should begin the frame.
  1734. scheduler_->SetNeedsBeginMainFrame();
  1735. EXPECT_ACTIONS("AddObserver(this)");
  1736. client_->Reset();
  1737. EXPECT_SCOPED(AdvanceFrame());
  1738. EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame");
  1739. EXPECT_TRUE(client_->IsInsideBeginImplFrame());
  1740. client_->Reset();
  1741. scheduler_->DidLoseLayerTreeFrameSink();
  1742. // RemoveObserver(this) is not called until the end of the frame.
  1743. EXPECT_NO_ACTION();
  1744. client_->Reset();
  1745. scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
  1746. scheduler_->NotifyReadyToCommit(nullptr);
  1747. EXPECT_ACTIONS("ScheduledActionCommit", "ScheduledActionPostCommit",
  1748. "ScheduledActionActivateSyncTree");
  1749. client_->Reset();
  1750. task_runner_->RunTasksWhile(client_->InsideBeginImplFrame(true));
  1751. EXPECT_ACTIONS("ScheduledActionBeginLayerTreeFrameSinkCreation",
  1752. "RemoveObserver(this)");
  1753. }
  1754. TEST_F(SchedulerTest,
  1755. DidLoseLayerTreeFrameSinkAfterBeginFrameStartedWithHighLatency) {
  1756. SetUpScheduler(EXTERNAL_BFS);
  1757. // SetNeedsBeginMainFrame should begin the frame.
  1758. scheduler_->SetNeedsBeginMainFrame();
  1759. EXPECT_ACTIONS("AddObserver(this)");
  1760. client_->Reset();
  1761. EXPECT_SCOPED(AdvanceFrame());
  1762. EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame");
  1763. EXPECT_TRUE(client_->IsInsideBeginImplFrame());
  1764. client_->Reset();
  1765. scheduler_->DidLoseLayerTreeFrameSink();
  1766. // Do nothing when impl frame is in deadine pending state.
  1767. EXPECT_NO_ACTION();
  1768. client_->Reset();
  1769. // Run posted deadline.
  1770. EXPECT_TRUE(client_->IsInsideBeginImplFrame());
  1771. task_runner_->RunTasksWhile(client_->InsideBeginImplFrame(true));
  1772. // OnBeginImplFrameDeadline didn't schedule LayerTreeFrameSink creation
  1773. // because
  1774. // main frame is not yet completed.
  1775. EXPECT_ACTIONS("RemoveObserver(this)");
  1776. EXPECT_FALSE(client_->IsInsideBeginImplFrame());
  1777. // BeginImplFrame is not started.
  1778. client_->Reset();
  1779. task_runner_->RunUntilTime(task_runner_->NowTicks() + base::Milliseconds(10));
  1780. EXPECT_NO_ACTION();
  1781. EXPECT_FALSE(client_->IsInsideBeginImplFrame());
  1782. client_->Reset();
  1783. scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
  1784. scheduler_->NotifyReadyToCommit(nullptr);
  1785. EXPECT_ACTIONS("ScheduledActionCommit", "ScheduledActionPostCommit",
  1786. "ScheduledActionActivateSyncTree",
  1787. "ScheduledActionBeginLayerTreeFrameSinkCreation");
  1788. }
  1789. TEST_F(SchedulerTest, DidLoseLayerTreeFrameSinkAfterReadyToCommit) {
  1790. SetUpScheduler(EXTERNAL_BFS);
  1791. // SetNeedsBeginMainFrame should begin the frame.
  1792. scheduler_->SetNeedsBeginMainFrame();
  1793. EXPECT_ACTIONS("AddObserver(this)");
  1794. client_->Reset();
  1795. EXPECT_SCOPED(AdvanceFrame());
  1796. EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame");
  1797. EXPECT_TRUE(client_->IsInsideBeginImplFrame());
  1798. client_->Reset();
  1799. scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
  1800. scheduler_->NotifyReadyToCommit(nullptr);
  1801. EXPECT_ACTIONS("ScheduledActionCommit", "ScheduledActionPostCommit");
  1802. client_->Reset();
  1803. scheduler_->DidLoseLayerTreeFrameSink();
  1804. // Sync tree should be forced to activate.
  1805. EXPECT_ACTIONS("ScheduledActionActivateSyncTree");
  1806. // RemoveObserver(this) is not called until the end of the frame.
  1807. client_->Reset();
  1808. task_runner_->RunTasksWhile(client_->InsideBeginImplFrame(true));
  1809. EXPECT_ACTIONS("ScheduledActionBeginLayerTreeFrameSinkCreation",
  1810. "RemoveObserver(this)");
  1811. }
  1812. TEST_F(SchedulerTest, DidLoseLayerTreeFrameSinkAfterSetNeedsPrepareTiles) {
  1813. SetUpScheduler(EXTERNAL_BFS);
  1814. scheduler_->SetNeedsPrepareTiles();
  1815. scheduler_->SetNeedsRedraw();
  1816. EXPECT_ACTIONS("AddObserver(this)");
  1817. client_->Reset();
  1818. EXPECT_SCOPED(AdvanceFrame());
  1819. EXPECT_ACTIONS("WillBeginImplFrame");
  1820. EXPECT_TRUE(client_->IsInsideBeginImplFrame());
  1821. client_->Reset();
  1822. scheduler_->DidLoseLayerTreeFrameSink();
  1823. // RemoveObserver(this) is not called until the end of the frame.
  1824. EXPECT_NO_ACTION();
  1825. client_->Reset();
  1826. task_runner_->RunTasksWhile(client_->InsideBeginImplFrame(true));
  1827. EXPECT_ACTIONS("ScheduledActionPrepareTiles",
  1828. "ScheduledActionBeginLayerTreeFrameSinkCreation",
  1829. "RemoveObserver(this)");
  1830. }
  1831. TEST_F(SchedulerTest, DidLoseLayerTreeFrameSinkWithDelayBasedBeginFrameSource) {
  1832. SetUpScheduler(THROTTLED_BFS);
  1833. // SetNeedsBeginMainFrame should begin the frame on the next BeginImplFrame.
  1834. EXPECT_FALSE(scheduler_->begin_frames_expected());
  1835. scheduler_->SetNeedsBeginMainFrame();
  1836. EXPECT_TRUE(scheduler_->begin_frames_expected());
  1837. client_->Reset();
  1838. AdvanceFrame();
  1839. EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame");
  1840. EXPECT_TRUE(client_->IsInsideBeginImplFrame());
  1841. EXPECT_TRUE(scheduler_->begin_frames_expected());
  1842. // NotifyReadyToCommit should trigger the commit.
  1843. client_->Reset();
  1844. scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
  1845. scheduler_->NotifyReadyToCommit(nullptr);
  1846. EXPECT_ACTIONS("ScheduledActionCommit", "ScheduledActionPostCommit");
  1847. EXPECT_TRUE(scheduler_->begin_frames_expected());
  1848. // NotifyReadyToActivate should trigger the activation.
  1849. client_->Reset();
  1850. scheduler_->NotifyReadyToActivate();
  1851. EXPECT_ACTIONS("ScheduledActionActivateSyncTree");
  1852. EXPECT_TRUE(scheduler_->begin_frames_expected());
  1853. client_->Reset();
  1854. scheduler_->DidLoseLayerTreeFrameSink();
  1855. // RemoveObserver(this) is not called until the end of the frame.
  1856. EXPECT_NO_ACTION();
  1857. EXPECT_TRUE(scheduler_->begin_frames_expected());
  1858. client_->Reset();
  1859. task_runner_->RunTasksWhile(client_->InsideBeginImplFrame(true));
  1860. EXPECT_ACTIONS("ScheduledActionBeginLayerTreeFrameSinkCreation");
  1861. EXPECT_FALSE(scheduler_->begin_frames_expected());
  1862. }
  1863. TEST_F(SchedulerTest, DidLoseLayerTreeFrameSinkWhenIdle) {
  1864. SetUpScheduler(EXTERNAL_BFS);
  1865. // SetNeedsBeginMainFrame should begin the frame.
  1866. scheduler_->SetNeedsBeginMainFrame();
  1867. EXPECT_ACTIONS("AddObserver(this)");
  1868. client_->Reset();
  1869. EXPECT_SCOPED(AdvanceFrame());
  1870. EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame");
  1871. EXPECT_TRUE(client_->IsInsideBeginImplFrame());
  1872. client_->Reset();
  1873. scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
  1874. scheduler_->NotifyReadyToCommit(nullptr);
  1875. EXPECT_ACTIONS("ScheduledActionCommit", "ScheduledActionPostCommit");
  1876. client_->Reset();
  1877. scheduler_->NotifyReadyToActivate();
  1878. EXPECT_ACTIONS("ScheduledActionActivateSyncTree");
  1879. client_->Reset();
  1880. task_runner_->RunTasksWhile(client_->InsideBeginImplFrame(true));
  1881. EXPECT_ACTIONS("ScheduledActionDrawIfPossible");
  1882. // Idle time between BeginFrames.
  1883. client_->Reset();
  1884. scheduler_->DidLoseLayerTreeFrameSink();
  1885. EXPECT_ACTIONS("ScheduledActionBeginLayerTreeFrameSinkCreation",
  1886. "RemoveObserver(this)");
  1887. }
  1888. TEST_F(SchedulerTest, ScheduledActionActivateAfterBecomingInvisible) {
  1889. SetUpScheduler(EXTERNAL_BFS);
  1890. // SetNeedsBeginMainFrame should begin the frame.
  1891. scheduler_->SetNeedsBeginMainFrame();
  1892. EXPECT_ACTIONS("AddObserver(this)");
  1893. client_->Reset();
  1894. EXPECT_SCOPED(AdvanceFrame());
  1895. EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame");
  1896. EXPECT_TRUE(client_->IsInsideBeginImplFrame());
  1897. client_->Reset();
  1898. scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
  1899. scheduler_->NotifyReadyToCommit(nullptr);
  1900. EXPECT_ACTIONS("ScheduledActionCommit", "ScheduledActionPostCommit");
  1901. EXPECT_TRUE(client_->IsInsideBeginImplFrame());
  1902. client_->Reset();
  1903. scheduler_->SetVisible(false);
  1904. task_runner_->RunPendingTasks(); // Run posted deadline.
  1905. // Sync tree should be forced to activate.
  1906. EXPECT_ACTIONS("ScheduledActionActivateSyncTree", "RemoveObserver(this)");
  1907. }
  1908. TEST_F(SchedulerTest, ScheduledActionActivateAfterBeginFrameSourcePaused) {
  1909. SetUpScheduler(EXTERNAL_BFS);
  1910. // SetNeedsBeginMainFrame should begin the frame.
  1911. scheduler_->SetNeedsBeginMainFrame();
  1912. EXPECT_ACTIONS("AddObserver(this)");
  1913. client_->Reset();
  1914. EXPECT_SCOPED(AdvanceFrame());
  1915. EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame");
  1916. EXPECT_TRUE(client_->IsInsideBeginImplFrame());
  1917. client_->Reset();
  1918. scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
  1919. scheduler_->NotifyReadyToCommit(nullptr);
  1920. EXPECT_ACTIONS("ScheduledActionCommit", "ScheduledActionPostCommit");
  1921. EXPECT_TRUE(client_->IsInsideBeginImplFrame());
  1922. client_->Reset();
  1923. fake_external_begin_frame_source_->SetPaused(true);
  1924. task_runner_->RunPendingTasks(); // Run posted deadline.
  1925. // Sync tree should be forced to activate.
  1926. // Pausing the begin frame source aborts the draw. Then
  1927. // ProactiveBeginFrameWanted is no longer true, so the scheduler stops
  1928. // listening for begin frames.
  1929. EXPECT_ACTIONS("ScheduledActionActivateSyncTree", "RemoveObserver(this)");
  1930. }
  1931. // Tests to ensure frame sources can be successfully changed while drawing.
  1932. TEST_F(SchedulerTest, SwitchFrameSourceToUnthrottled) {
  1933. SetUpScheduler(EXTERNAL_BFS);
  1934. // SetNeedsRedraw should begin the frame on the next BeginImplFrame.
  1935. scheduler_->SetNeedsRedraw();
  1936. EXPECT_ACTIONS("AddObserver(this)");
  1937. client_->Reset();
  1938. EXPECT_SCOPED(AdvanceFrame());
  1939. EXPECT_ACTIONS("WillBeginImplFrame");
  1940. EXPECT_TRUE(client_->IsInsideBeginImplFrame());
  1941. EXPECT_TRUE(scheduler_->begin_frames_expected());
  1942. client_->Reset();
  1943. task_runner_->RunPendingTasks(); // Run posted deadline.
  1944. EXPECT_ACTIONS("ScheduledActionDrawIfPossible");
  1945. scheduler_->SetNeedsRedraw();
  1946. // Switch to an unthrottled frame source.
  1947. scheduler_->SetBeginFrameSource(unthrottled_frame_source_.get());
  1948. client_->Reset();
  1949. // Unthrottled frame source will immediately begin a new frame.
  1950. task_runner_->RunPendingTasks(); // Run posted BeginFrame.
  1951. EXPECT_ACTIONS("WillBeginImplFrame");
  1952. EXPECT_TRUE(client_->IsInsideBeginImplFrame());
  1953. client_->Reset();
  1954. // If we don't swap on the deadline, we wait for the next BeginFrame.
  1955. task_runner_->RunPendingTasks(); // Run posted deadline.
  1956. EXPECT_ACTIONS("ScheduledActionDrawIfPossible");
  1957. EXPECT_FALSE(client_->IsInsideBeginImplFrame());
  1958. client_->Reset();
  1959. }
  1960. // Tests to ensure frame sources can be successfully changed while a frame
  1961. // deadline is pending.
  1962. TEST_F(SchedulerTest, SwitchFrameSourceToUnthrottledBeforeDeadline) {
  1963. SetUpScheduler(EXTERNAL_BFS);
  1964. // SetNeedsRedraw should begin the frame on the next BeginImplFrame.
  1965. scheduler_->SetNeedsRedraw();
  1966. EXPECT_ACTIONS("AddObserver(this)");
  1967. client_->Reset();
  1968. EXPECT_SCOPED(AdvanceFrame());
  1969. EXPECT_ACTIONS("WillBeginImplFrame");
  1970. // Switch to an unthrottled frame source before the frame deadline is hit.
  1971. scheduler_->SetBeginFrameSource(unthrottled_frame_source_.get());
  1972. client_->Reset();
  1973. EXPECT_TRUE(client_->IsInsideBeginImplFrame());
  1974. EXPECT_TRUE(scheduler_->begin_frames_expected());
  1975. client_->Reset();
  1976. task_runner_->RunPendingTasks(); // Run posted deadline.
  1977. EXPECT_ACTIONS("ScheduledActionDrawIfPossible",
  1978. // Unthrottled frame source will immediately begin a new frame.
  1979. "WillBeginImplFrame");
  1980. scheduler_->SetNeedsRedraw();
  1981. client_->Reset();
  1982. task_runner_->RunPendingTasks(); // Run posted deadline.
  1983. EXPECT_ACTIONS("ScheduledActionDrawIfPossible");
  1984. EXPECT_FALSE(client_->IsInsideBeginImplFrame());
  1985. client_->Reset();
  1986. }
  1987. // Tests to ensure that the active frame source can successfully be changed from
  1988. // unthrottled to throttled.
  1989. TEST_F(SchedulerTest, SwitchFrameSourceToThrottled) {
  1990. SetUpScheduler(UNTHROTTLED_BFS);
  1991. scheduler_->SetNeedsRedraw();
  1992. EXPECT_NO_ACTION();
  1993. client_->Reset();
  1994. task_runner_->RunPendingTasks(); // Run posted BeginFrame.
  1995. EXPECT_ACTIONS("WillBeginImplFrame");
  1996. EXPECT_TRUE(client_->IsInsideBeginImplFrame());
  1997. client_->Reset();
  1998. task_runner_->RunPendingTasks(); // Run posted deadline.
  1999. EXPECT_ACTIONS("ScheduledActionDrawIfPossible");
  2000. EXPECT_FALSE(client_->IsInsideBeginImplFrame());
  2001. client_->Reset();
  2002. // Switch to a throttled frame source.
  2003. scheduler_->SetBeginFrameSource(fake_external_begin_frame_source_.get());
  2004. client_->Reset();
  2005. // SetNeedsRedraw should begin the frame on the next BeginImplFrame.
  2006. scheduler_->SetNeedsRedraw();
  2007. task_runner_->RunPendingTasks();
  2008. EXPECT_NO_ACTION();
  2009. client_->Reset();
  2010. EXPECT_SCOPED(AdvanceFrame());
  2011. EXPECT_ACTIONS("WillBeginImplFrame");
  2012. EXPECT_TRUE(client_->IsInsideBeginImplFrame());
  2013. EXPECT_TRUE(scheduler_->begin_frames_expected());
  2014. client_->Reset();
  2015. task_runner_->RunPendingTasks(); // Run posted deadline.
  2016. EXPECT_ACTIONS("ScheduledActionDrawIfPossible");
  2017. }
  2018. TEST_F(SchedulerTest, SwitchFrameSourceToNullInsideDeadline) {
  2019. SetUpScheduler(EXTERNAL_BFS);
  2020. scheduler_->SetNeedsRedraw();
  2021. EXPECT_ACTIONS("AddObserver(this)");
  2022. client_->Reset();
  2023. EXPECT_SCOPED(AdvanceFrame());
  2024. EXPECT_ACTIONS("WillBeginImplFrame");
  2025. client_->Reset();
  2026. // Switch to a null frame source.
  2027. scheduler_->SetBeginFrameSource(nullptr);
  2028. EXPECT_ACTIONS("RemoveObserver(this)");
  2029. client_->Reset();
  2030. EXPECT_TRUE(client_->IsInsideBeginImplFrame());
  2031. task_runner_->RunPendingTasks(); // Run posted deadline.
  2032. EXPECT_ACTIONS("ScheduledActionDrawIfPossible");
  2033. EXPECT_FALSE(scheduler_->begin_frames_expected());
  2034. EXPECT_FALSE(client_->IsInsideBeginImplFrame());
  2035. client_->Reset();
  2036. // AdvanceFrame helper can't be used here because there's no deadline posted.
  2037. scheduler_->SetNeedsRedraw();
  2038. EXPECT_FALSE(client_->IsInsideBeginImplFrame());
  2039. EXPECT_NO_ACTION();
  2040. client_->Reset();
  2041. scheduler_->SetNeedsBeginMainFrame();
  2042. EXPECT_FALSE(client_->IsInsideBeginImplFrame());
  2043. EXPECT_NO_ACTION();
  2044. client_->Reset();
  2045. // Switch back to the same source, make sure frames continue to be produced.
  2046. scheduler_->SetBeginFrameSource(fake_external_begin_frame_source_.get());
  2047. EXPECT_ACTIONS("AddObserver(this)");
  2048. EXPECT_FALSE(client_->IsInsideBeginImplFrame());
  2049. client_->Reset();
  2050. EXPECT_SCOPED(AdvanceFrame());
  2051. EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame");
  2052. EXPECT_TRUE(client_->IsInsideBeginImplFrame());
  2053. client_->Reset();
  2054. task_runner_->RunPendingTasks();
  2055. EXPECT_ACTIONS("ScheduledActionDrawIfPossible");
  2056. }
  2057. // This test maskes sure that switching a frame source when not observing
  2058. // such as when not visible also works.
  2059. TEST_F(SchedulerTest, SwitchFrameSourceWhenNotObserving) {
  2060. SetUpScheduler(EXTERNAL_BFS);
  2061. // SetNeedsBeginMainFrame should begin the frame on the next BeginImplFrame.
  2062. scheduler_->SetNeedsBeginMainFrame();
  2063. EXPECT_ACTIONS("AddObserver(this)");
  2064. client_->Reset();
  2065. // Begin new frame.
  2066. EXPECT_SCOPED(AdvanceFrame());
  2067. scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
  2068. EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame");
  2069. client_->Reset();
  2070. scheduler_->NotifyReadyToCommit(nullptr);
  2071. EXPECT_ACTIONS("ScheduledActionCommit", "ScheduledActionPostCommit");
  2072. client_->Reset();
  2073. scheduler_->NotifyReadyToActivate();
  2074. EXPECT_ACTIONS("ScheduledActionActivateSyncTree");
  2075. // Scheduler loses LayerTreeFrameSink, and stops waiting for ready to draw
  2076. // signal.
  2077. client_->Reset();
  2078. scheduler_->DidLoseLayerTreeFrameSink();
  2079. EXPECT_TRUE(client_->IsInsideBeginImplFrame());
  2080. task_runner_->RunPendingTasks();
  2081. EXPECT_ACTIONS("ScheduledActionBeginLayerTreeFrameSinkCreation",
  2082. "RemoveObserver(this)");
  2083. // Changing begin frame source doesn't do anything.
  2084. // The unthrottled source doesn't print Add/RemoveObserver like the fake one.
  2085. client_->Reset();
  2086. scheduler_->SetBeginFrameSource(unthrottled_frame_source_.get());
  2087. EXPECT_NO_ACTION();
  2088. client_->Reset();
  2089. scheduler_->DidCreateAndInitializeLayerTreeFrameSink();
  2090. EXPECT_NO_ACTION();
  2091. client_->Reset();
  2092. scheduler_->SetNeedsBeginMainFrame();
  2093. EXPECT_NO_ACTION();
  2094. client_->Reset();
  2095. EXPECT_SCOPED(AdvanceFrame());
  2096. EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame");
  2097. }
  2098. // Tests to ensure that we send a ScheduledActionBeginMainFrameNotExpectedUntil
  2099. // when expected.
  2100. TEST_F(SchedulerTest, ScheduledActionBeginMainFrameNotExpectedUntil) {
  2101. SetUpScheduler(EXTERNAL_BFS);
  2102. scheduler_->SetNeedsRedraw();
  2103. EXPECT_ACTIONS("AddObserver(this)");
  2104. client_->Reset();
  2105. EXPECT_SCOPED(AdvanceFrame());
  2106. scheduler_->SetMainThreadWantsBeginMainFrameNotExpected(true);
  2107. task_runner_->RunPendingTasks();
  2108. EXPECT_ACTIONS("WillBeginImplFrame",
  2109. "ScheduledActionBeginMainFrameNotExpectedUntil",
  2110. "ScheduledActionDrawIfPossible");
  2111. }
  2112. // Tests to ensure that BeginMainFrameNotExpectedUntil is only sent once within
  2113. // the same frame.
  2114. TEST_F(SchedulerTest,
  2115. ScheduledActionBeginMainFrameNotExpectedUntilSentOnlyOncePerFrame) {
  2116. SetUpScheduler(EXTERNAL_BFS);
  2117. scheduler_->SetNeedsRedraw();
  2118. EXPECT_ACTIONS("AddObserver(this)");
  2119. client_->Reset();
  2120. EXPECT_SCOPED(AdvanceFrame());
  2121. scheduler_->SetMainThreadWantsBeginMainFrameNotExpected(true);
  2122. task_runner_->RunPendingTasks();
  2123. EXPECT_ACTIONS("WillBeginImplFrame",
  2124. "ScheduledActionBeginMainFrameNotExpectedUntil",
  2125. "ScheduledActionDrawIfPossible");
  2126. client_->Reset();
  2127. scheduler_->SetMainThreadWantsBeginMainFrameNotExpected(false);
  2128. task_runner_->RunPendingTasks();
  2129. EXPECT_NO_ACTION();
  2130. scheduler_->SetMainThreadWantsBeginMainFrameNotExpected(true);
  2131. task_runner_->RunPendingTasks();
  2132. EXPECT_NO_ACTION();
  2133. }
  2134. // Tests to ensure that we send a BeginMainFrameNotExpectedSoon when expected.
  2135. TEST_F(SchedulerTest, SendBeginMainFrameNotExpectedSoon_Requested) {
  2136. SetUpScheduler(EXTERNAL_BFS);
  2137. // SetNeedsBeginMainFrame should begin the frame on the next BeginImplFrame.
  2138. scheduler_->SetNeedsBeginMainFrame();
  2139. EXPECT_ACTIONS("AddObserver(this)");
  2140. client_->Reset();
  2141. // Trigger a frame draw.
  2142. EXPECT_SCOPED(AdvanceFrame());
  2143. scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
  2144. scheduler_->NotifyReadyToCommit(nullptr);
  2145. scheduler_->NotifyReadyToActivate();
  2146. task_runner_->RunPendingTasks();
  2147. EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame",
  2148. "ScheduledActionCommit", "ScheduledActionPostCommit",
  2149. "ScheduledActionActivateSyncTree",
  2150. "ScheduledActionDrawIfPossible");
  2151. client_->Reset();
  2152. scheduler_->SetMainThreadWantsBeginMainFrameNotExpected(true);
  2153. EXPECT_SCOPED(AdvanceFrame());
  2154. EXPECT_ACTIONS("WillBeginImplFrame",
  2155. "ScheduledActionBeginMainFrameNotExpectedUntil");
  2156. EXPECT_TRUE(client_->IsInsideBeginImplFrame());
  2157. client_->Reset();
  2158. // The BeginImplFrame deadline should SetNeedsBeginFrame(false) and send a
  2159. // SendBeginMainFrameNotExpectedSoon.
  2160. task_runner_->RunPendingTasks(); // Run posted deadline.
  2161. EXPECT_ACTIONS("SendBeginMainFrameNotExpectedSoon", "RemoveObserver(this)");
  2162. client_->Reset();
  2163. }
  2164. // Tests to ensure that we dont't send a BeginMainFrameNotExpectedSoon when
  2165. // possible but not requested.
  2166. TEST_F(SchedulerTest, SendBeginMainFrameNotExpectedSoon_Unrequested) {
  2167. SetUpScheduler(EXTERNAL_BFS);
  2168. // SetNeedsBeginMainFrame should begin the frame on the next BeginImplFrame.
  2169. scheduler_->SetNeedsBeginMainFrame();
  2170. EXPECT_ACTIONS("AddObserver(this)");
  2171. client_->Reset();
  2172. // Trigger a frame draw.
  2173. EXPECT_SCOPED(AdvanceFrame());
  2174. scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
  2175. scheduler_->NotifyReadyToCommit(nullptr);
  2176. scheduler_->NotifyReadyToActivate();
  2177. task_runner_->RunPendingTasks();
  2178. EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame",
  2179. "ScheduledActionCommit", "ScheduledActionPostCommit",
  2180. "ScheduledActionActivateSyncTree",
  2181. "ScheduledActionDrawIfPossible");
  2182. client_->Reset();
  2183. EXPECT_SCOPED(AdvanceFrame());
  2184. EXPECT_ACTIONS("WillBeginImplFrame");
  2185. EXPECT_TRUE(client_->IsInsideBeginImplFrame());
  2186. client_->Reset();
  2187. // The BeginImplFrame deadline should SetNeedsBeginFrame(false), but doesn't
  2188. // send a SendBeginMainFrameNotExpectedSoon as it's not been requested by the
  2189. // main thread.
  2190. task_runner_->RunPendingTasks(); // Run posted deadline.
  2191. EXPECT_ACTIONS("RemoveObserver(this)");
  2192. client_->Reset();
  2193. scheduler_->SetMainThreadWantsBeginMainFrameNotExpected(true);
  2194. EXPECT_ACTIONS("SendBeginMainFrameNotExpectedSoon");
  2195. }
  2196. // Tests to ensure that we send a BeginMainFrameNotExpectedSoon only once per
  2197. // frame.
  2198. TEST_F(SchedulerTest, SendBeginMainFrameNotExpectedSoonOnlyOncePerFrame) {
  2199. SetUpScheduler(EXTERNAL_BFS);
  2200. // SetNeedsBeginMainFrame should begin the frame on the next BeginImplFrame.
  2201. scheduler_->SetNeedsBeginMainFrame();
  2202. EXPECT_ACTIONS("AddObserver(this)");
  2203. client_->Reset();
  2204. // Trigger a frame draw.
  2205. EXPECT_SCOPED(AdvanceFrame());
  2206. scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
  2207. scheduler_->NotifyReadyToCommit(nullptr);
  2208. scheduler_->NotifyReadyToActivate();
  2209. task_runner_->RunPendingTasks();
  2210. EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame",
  2211. "ScheduledActionCommit", "ScheduledActionPostCommit",
  2212. "ScheduledActionActivateSyncTree",
  2213. "ScheduledActionDrawIfPossible");
  2214. client_->Reset();
  2215. scheduler_->SetMainThreadWantsBeginMainFrameNotExpected(true);
  2216. EXPECT_SCOPED(AdvanceFrame());
  2217. EXPECT_ACTIONS("WillBeginImplFrame",
  2218. "ScheduledActionBeginMainFrameNotExpectedUntil");
  2219. EXPECT_TRUE(client_->IsInsideBeginImplFrame());
  2220. client_->Reset();
  2221. task_runner_->RunPendingTasks(); // Run posted deadline.
  2222. EXPECT_ACTIONS("SendBeginMainFrameNotExpectedSoon", "RemoveObserver(this)");
  2223. client_->Reset();
  2224. scheduler_->SetMainThreadWantsBeginMainFrameNotExpected(false);
  2225. EXPECT_NO_ACTION();
  2226. scheduler_->SetMainThreadWantsBeginMainFrameNotExpected(true);
  2227. EXPECT_NO_ACTION();
  2228. }
  2229. // Tests to ensure that we send a BeginMainFrameNotExpectedSoon in situations
  2230. // where the client doesn't want messages when we first stopped observing
  2231. // BeginFrames but later does.
  2232. TEST_F(SchedulerTest, SendBeginMainFrameNotExpectedSoon_AlreadyIdle) {
  2233. SetUpScheduler(EXTERNAL_BFS);
  2234. // SetNeedsBeginMainFrame should begin the frame on the next BeginImplFrame.
  2235. scheduler_->SetNeedsBeginMainFrame();
  2236. EXPECT_ACTIONS("AddObserver(this)");
  2237. client_->Reset();
  2238. // Trigger a frame draw.
  2239. EXPECT_SCOPED(AdvanceFrame());
  2240. scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
  2241. scheduler_->NotifyReadyToCommit(nullptr);
  2242. scheduler_->NotifyReadyToActivate();
  2243. task_runner_->RunPendingTasks();
  2244. EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame",
  2245. "ScheduledActionCommit", "ScheduledActionPostCommit",
  2246. "ScheduledActionActivateSyncTree",
  2247. "ScheduledActionDrawIfPossible");
  2248. client_->Reset();
  2249. EXPECT_SCOPED(AdvanceFrame());
  2250. task_runner_->RunPendingTasks(); // Run posted deadline.
  2251. EXPECT_ACTIONS("WillBeginImplFrame", "RemoveObserver(this)");
  2252. client_->Reset();
  2253. scheduler_->SetMainThreadWantsBeginMainFrameNotExpected(true);
  2254. EXPECT_ACTIONS("SendBeginMainFrameNotExpectedSoon");
  2255. }
  2256. // This tests to ensure BeginMainFrameNotExpectedSoon is sent during idle
  2257. // periods if (1) it initially wasn't sent because the message wasn't needed at
  2258. // the time, and (2) the BeginMainFrameNotExpectedUntil was already sent in the
  2259. // frame (crbug.com/893653).
  2260. TEST_F(SchedulerTest, SendBeginMainFrameNotExpectedSoonDuringIdleIfNeeded) {
  2261. SetUpScheduler(EXTERNAL_BFS);
  2262. scheduler_->SetNeedsRedraw();
  2263. EXPECT_ACTIONS("AddObserver(this)");
  2264. client_->Reset();
  2265. EXPECT_SCOPED(AdvanceFrame());
  2266. task_runner_->RunPendingTasks();
  2267. EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionDrawIfPossible");
  2268. client_->Reset();
  2269. EXPECT_SCOPED(AdvanceFrame());
  2270. EXPECT_ACTIONS("WillBeginImplFrame");
  2271. EXPECT_TRUE(client_->IsInsideBeginImplFrame());
  2272. client_->Reset();
  2273. // Toggle WantsBeginMainFrameNotExpected while inside BeginImplFrame. This
  2274. // causes the BeginMainFrameNotExpectedUntil message to get sent and the
  2275. // BeginMainFrameNotExpectedSoon message to be withheld.
  2276. scheduler_->SetMainThreadWantsBeginMainFrameNotExpected(true);
  2277. EXPECT_ACTIONS("ScheduledActionBeginMainFrameNotExpectedUntil");
  2278. client_->Reset();
  2279. scheduler_->SetMainThreadWantsBeginMainFrameNotExpected(false);
  2280. task_runner_->RunPendingTasks();
  2281. EXPECT_ACTIONS("RemoveObserver(this)");
  2282. EXPECT_FALSE(client_->IsInsideBeginImplFrame());
  2283. client_->Reset();
  2284. scheduler_->SetMainThreadWantsBeginMainFrameNotExpected(true);
  2285. EXPECT_ACTIONS("SendBeginMainFrameNotExpectedSoon");
  2286. }
  2287. // This tests to ensure BeginMainFrameNotExpectedSoon is sent during idle
  2288. // periods if (1) it initially wasn't sent because the message wasn't needed at
  2289. // the time, and (2) |scheduler_|.visible() is false.
  2290. TEST_F(SchedulerTest,
  2291. ScheduledActionBeginMainFrameNotSoonSentDuringIdleIfNeededNotVisible) {
  2292. SetUpScheduler(EXTERNAL_BFS);
  2293. scheduler_->SetNeedsRedraw();
  2294. EXPECT_ACTIONS("AddObserver(this)");
  2295. client_->Reset();
  2296. EXPECT_SCOPED(AdvanceFrame());
  2297. task_runner_->RunPendingTasks();
  2298. EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionDrawIfPossible");
  2299. client_->Reset();
  2300. EXPECT_SCOPED(AdvanceFrame());
  2301. EXPECT_ACTIONS("WillBeginImplFrame");
  2302. EXPECT_TRUE(client_->IsInsideBeginImplFrame());
  2303. client_->Reset();
  2304. scheduler_->SetVisible(false);
  2305. task_runner_->RunPendingTasks();
  2306. EXPECT_ACTIONS("RemoveObserver(this)");
  2307. EXPECT_FALSE(client_->IsInsideBeginImplFrame());
  2308. // The scheduler won't send BeginMainFrameNotExpectedUntil messages while not
  2309. // visible, but it needs to send a BeginMainFrameNotExpectedSoon to let the
  2310. // client know it's gone idle.
  2311. client_->Reset();
  2312. scheduler_->SetMainThreadWantsBeginMainFrameNotExpected(true);
  2313. EXPECT_ACTIONS("SendBeginMainFrameNotExpectedSoon");
  2314. }
  2315. TEST_F(SchedulerTest, SynchronousCompositorAnimation) {
  2316. scheduler_settings_.using_synchronous_renderer_compositor = true;
  2317. SetUpScheduler(EXTERNAL_BFS);
  2318. scheduler_->SetNeedsOneBeginImplFrame();
  2319. EXPECT_ACTIONS("AddObserver(this)");
  2320. client_->Reset();
  2321. // Testing the case where animation ticks a fling scroll.
  2322. client_->SetWillBeginImplFrameCausesRedraw(true);
  2323. // The animation isn't done so it'll cause another tick in the future.
  2324. client_->SetWillBeginImplFrameRequestsOneBeginImplFrame(true);
  2325. // Next vsync.
  2326. AdvanceFrame();
  2327. EXPECT_ACTIONS("WillBeginImplFrame",
  2328. "ScheduledActionInvalidateLayerTreeFrameSink");
  2329. // Finish frame is deferred until next draw since there was invalidation.
  2330. EXPECT_TRUE(client_->IsInsideBeginImplFrame());
  2331. client_->Reset();
  2332. // Android onDraw. This doesn't consume the single begin frame request.
  2333. scheduler_->SetNeedsRedraw();
  2334. bool resourceless_software_draw = false;
  2335. bool skip_draw = false;
  2336. scheduler_->OnDrawForLayerTreeFrameSink(resourceless_software_draw,
  2337. skip_draw);
  2338. EXPECT_ACTIONS("ScheduledActionDrawIfPossible");
  2339. EXPECT_FALSE(client_->IsInsideBeginImplFrame());
  2340. client_->Reset();
  2341. // The animation inside of WillBeginImplFrame changes stuff on the screen, but
  2342. // ends here, so does not cause another frame to happen.
  2343. client_->SetWillBeginImplFrameCausesRedraw(true);
  2344. // Next vsync.
  2345. AdvanceFrame();
  2346. EXPECT_ACTIONS("WillBeginImplFrame",
  2347. "ScheduledActionInvalidateLayerTreeFrameSink");
  2348. // Finish frame is deferred until next draw since there was invalidation.
  2349. EXPECT_TRUE(client_->IsInsideBeginImplFrame());
  2350. client_->Reset();
  2351. // Android onDraw.
  2352. scheduler_->SetNeedsRedraw();
  2353. scheduler_->OnDrawForLayerTreeFrameSink(resourceless_software_draw,
  2354. skip_draw);
  2355. EXPECT_ACTIONS("ScheduledActionDrawIfPossible");
  2356. EXPECT_FALSE(client_->IsInsideBeginImplFrame());
  2357. client_->Reset();
  2358. // Idle on next vsync, as the animation has completed.
  2359. AdvanceFrame();
  2360. EXPECT_ACTIONS("WillBeginImplFrame", "RemoveObserver(this)");
  2361. EXPECT_FALSE(client_->IsInsideBeginImplFrame());
  2362. client_->Reset();
  2363. }
  2364. TEST_F(SchedulerTest, SynchronousCompositorOnDrawDuringIdle) {
  2365. scheduler_settings_.using_synchronous_renderer_compositor = true;
  2366. SetUpScheduler(EXTERNAL_BFS);
  2367. scheduler_->SetNeedsRedraw();
  2368. bool resourceless_software_draw = false;
  2369. bool skip_draw = false;
  2370. scheduler_->OnDrawForLayerTreeFrameSink(resourceless_software_draw,
  2371. skip_draw);
  2372. EXPECT_ACTIONS("AddObserver(this)", "ScheduledActionDrawIfPossible");
  2373. EXPECT_FALSE(client_->IsInsideBeginImplFrame());
  2374. client_->Reset();
  2375. // Idle on next vsync.
  2376. AdvanceFrame();
  2377. EXPECT_ACTIONS("WillBeginImplFrame", "RemoveObserver(this)");
  2378. EXPECT_FALSE(client_->IsInsideBeginImplFrame());
  2379. client_->Reset();
  2380. }
  2381. TEST_F(SchedulerTest, InvalidateLayerTreeFrameSinkWhenCannotDraw) {
  2382. scheduler_settings_.using_synchronous_renderer_compositor = true;
  2383. SetUpScheduler(EXTERNAL_BFS);
  2384. scheduler_->SetCanDraw(false);
  2385. scheduler_->SetNeedsRedraw();
  2386. EXPECT_ACTIONS("AddObserver(this)");
  2387. client_->Reset();
  2388. // Do not invalidate in next BeginFrame.
  2389. EXPECT_SCOPED(AdvanceFrame());
  2390. EXPECT_ACTIONS("WillBeginImplFrame");
  2391. // Redraw is not cleared.
  2392. EXPECT_TRUE(scheduler_->RedrawPending());
  2393. scheduler_->SetCanDraw(true);
  2394. client_->Reset();
  2395. // Do invalidate in next BeginFrame.
  2396. EXPECT_SCOPED(AdvanceFrame());
  2397. EXPECT_ACTIONS("WillBeginImplFrame",
  2398. "ScheduledActionInvalidateLayerTreeFrameSink");
  2399. client_->Reset();
  2400. bool resourceless_software_draw = false;
  2401. bool skip_draw = false;
  2402. scheduler_->OnDrawForLayerTreeFrameSink(resourceless_software_draw,
  2403. skip_draw);
  2404. EXPECT_ACTIONS("ScheduledActionDrawIfPossible");
  2405. EXPECT_FALSE(scheduler_->RedrawPending());
  2406. }
  2407. TEST_F(SchedulerTest, NeedsPrepareTilesInvalidates) {
  2408. // This is to test that SetNeedsPrepareTiles causes invalidates even if
  2409. // CanDraw is false.
  2410. scheduler_settings_.using_synchronous_renderer_compositor = true;
  2411. SetUpScheduler(EXTERNAL_BFS);
  2412. scheduler_->SetCanDraw(false);
  2413. scheduler_->SetNeedsPrepareTiles();
  2414. EXPECT_ACTIONS("AddObserver(this)");
  2415. client_->Reset();
  2416. // Do not invalidate in next BeginFrame.
  2417. EXPECT_SCOPED(AdvanceFrame());
  2418. EXPECT_ACTIONS("WillBeginImplFrame",
  2419. "ScheduledActionInvalidateLayerTreeFrameSink");
  2420. client_->Reset();
  2421. }
  2422. TEST_F(SchedulerTest, SetNeedsOneBeginImplFrame) {
  2423. SetUpScheduler(EXTERNAL_BFS);
  2424. EXPECT_FALSE(scheduler_->begin_frames_expected());
  2425. // Request a frame, should kick the source.
  2426. scheduler_->SetNeedsOneBeginImplFrame();
  2427. EXPECT_ACTIONS("AddObserver(this)");
  2428. client_->Reset();
  2429. // The incoming WillBeginImplFrame will request another one.
  2430. client_->SetWillBeginImplFrameRequestsOneBeginImplFrame(true);
  2431. // Next vsync, the first requested frame happens.
  2432. EXPECT_SCOPED(AdvanceFrame());
  2433. EXPECT_ACTIONS("WillBeginImplFrame");
  2434. EXPECT_TRUE(client_->IsInsideBeginImplFrame());
  2435. client_->Reset();
  2436. // We don't request another frame here.
  2437. // Next vsync, the second requested frame happens (the one requested inside
  2438. // the previous frame's begin impl frame step).
  2439. EXPECT_SCOPED(AdvanceFrame());
  2440. EXPECT_ACTIONS("WillBeginImplFrame");
  2441. EXPECT_TRUE(client_->IsInsideBeginImplFrame());
  2442. client_->Reset();
  2443. // End that frame's deadline.
  2444. task_runner_->RunTasksWhile(client_->InsideBeginImplFrame(true));
  2445. EXPECT_FALSE(client_->IsInsideBeginImplFrame());
  2446. // Scheduler shuts down the source now that no begin frame is requested.
  2447. EXPECT_ACTIONS("RemoveObserver(this)");
  2448. }
  2449. TEST_F(SchedulerTest, AbortEarlyIfNoDamage) {
  2450. SetUpScheduler(EXTERNAL_BFS);
  2451. // WillBeginImplFrame will return false, so draws should never be scheduled
  2452. // and client_->num_draws() should stay at 0.
  2453. client_->SetWillBeginImplFrameMightHaveDamage(false);
  2454. scheduler_->SetNeedsRedraw();
  2455. EXPECT_EQ(0, client_->num_draws());
  2456. EXPECT_ACTIONS("AddObserver(this)");
  2457. EXPECT_SCOPED(AdvanceFrame());
  2458. task_runner_->RunPendingTasks(); // Run posted deadline.
  2459. // Should not try to schedule a draw. (ScheduledActionDrawIfPossible should
  2460. // not appear.)
  2461. // When the frame is aborted, the scheduler does not ask for a proactive begin
  2462. // frame, so stop listening for begin frames.
  2463. EXPECT_ACTIONS("AddObserver(this)", "WillBeginImplFrame",
  2464. "RemoveObserver(this)");
  2465. EXPECT_EQ(0, client_->num_draws());
  2466. scheduler_->SetNeedsRedraw();
  2467. EXPECT_SCOPED(AdvanceFrame());
  2468. task_runner_->RunPendingTasks(); // Run posted deadline.
  2469. EXPECT_EQ(0, client_->num_draws());
  2470. }
  2471. TEST_F(SchedulerTest, SkipDraw) {
  2472. scheduler_settings_.using_synchronous_renderer_compositor = true;
  2473. SetUpScheduler(EXTERNAL_BFS);
  2474. scheduler_->SetNeedsOneBeginImplFrame();
  2475. EXPECT_ACTIONS("AddObserver(this)");
  2476. client_->Reset();
  2477. client_->SetWillBeginImplFrameCausesRedraw(true);
  2478. // Next vsync.
  2479. AdvanceFrame();
  2480. EXPECT_ACTIONS("WillBeginImplFrame",
  2481. "ScheduledActionInvalidateLayerTreeFrameSink");
  2482. EXPECT_TRUE(client_->invalidate_needs_redraw());
  2483. client_->Reset();
  2484. // Android onDraw. This doesn't consume the single begin frame request.
  2485. scheduler_->SetNeedsPrepareTiles();
  2486. bool resourceless_software_draw = false;
  2487. bool skip_draw = false;
  2488. scheduler_->OnDrawForLayerTreeFrameSink(resourceless_software_draw,
  2489. skip_draw);
  2490. EXPECT_ACTIONS("ScheduledActionDrawIfPossible",
  2491. "ScheduledActionPrepareTiles");
  2492. client_->Reset();
  2493. // Next vsync.
  2494. scheduler_->SetNeedsPrepareTiles();
  2495. AdvanceFrame();
  2496. EXPECT_ACTIONS("WillBeginImplFrame",
  2497. "ScheduledActionInvalidateLayerTreeFrameSink");
  2498. EXPECT_FALSE(client_->invalidate_needs_redraw());
  2499. client_->Reset();
  2500. // Android onDraw.
  2501. scheduler_->SetNeedsRedraw();
  2502. scheduler_->SetNeedsPrepareTiles();
  2503. client_->SetInvalidateNeedsRedraw(false);
  2504. skip_draw = true;
  2505. scheduler_->OnDrawForLayerTreeFrameSink(resourceless_software_draw,
  2506. skip_draw);
  2507. EXPECT_ACTIONS("ScheduledActionPrepareTiles");
  2508. client_->Reset();
  2509. }
  2510. TEST_F(SchedulerTest, SynchronousCompositorCommitAndVerifyBeginFrameAcks) {
  2511. scheduler_settings_.using_synchronous_renderer_compositor = true;
  2512. SetUpScheduler(EXTERNAL_BFS);
  2513. scheduler_->SetNeedsBeginMainFrame();
  2514. EXPECT_ACTIONS("AddObserver(this)");
  2515. client_->Reset();
  2516. // Next vsync.
  2517. viz::BeginFrameArgs args = SendNextBeginFrame();
  2518. EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame");
  2519. EXPECT_FALSE(client_->IsInsideBeginImplFrame());
  2520. bool has_damage = false;
  2521. EXPECT_EQ(viz::BeginFrameAck(args, has_damage),
  2522. client_->last_begin_frame_ack());
  2523. client_->Reset();
  2524. scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
  2525. EXPECT_NO_ACTION();
  2526. // Next vsync.
  2527. args = SendNextBeginFrame();
  2528. EXPECT_ACTIONS("WillBeginImplFrame");
  2529. EXPECT_FALSE(client_->IsInsideBeginImplFrame());
  2530. has_damage = false;
  2531. EXPECT_EQ(viz::BeginFrameAck(args, has_damage),
  2532. client_->last_begin_frame_ack());
  2533. client_->Reset();
  2534. scheduler_->NotifyReadyToCommit(nullptr);
  2535. EXPECT_ACTIONS("ScheduledActionCommit", "ScheduledActionPostCommit");
  2536. client_->Reset();
  2537. scheduler_->NotifyReadyToActivate();
  2538. EXPECT_ACTIONS("ScheduledActionActivateSyncTree");
  2539. client_->Reset();
  2540. // Next vsync.
  2541. args = SendNextBeginFrame();
  2542. EXPECT_ACTIONS("WillBeginImplFrame",
  2543. "ScheduledActionInvalidateLayerTreeFrameSink");
  2544. // Finish frame is deferred until next draw since there was invalidation.
  2545. EXPECT_TRUE(client_->IsInsideBeginImplFrame());
  2546. client_->Reset();
  2547. // Android onDraw.
  2548. scheduler_->SetNeedsRedraw();
  2549. bool resourceless_software_draw = false;
  2550. bool skip_draw = false;
  2551. scheduler_->OnDrawForLayerTreeFrameSink(resourceless_software_draw,
  2552. skip_draw);
  2553. EXPECT_ACTIONS("ScheduledActionDrawIfPossible");
  2554. EXPECT_FALSE(client_->IsInsideBeginImplFrame());
  2555. client_->Reset();
  2556. // Idle on next vsync.
  2557. args = SendNextBeginFrame();
  2558. EXPECT_ACTIONS("WillBeginImplFrame", "RemoveObserver(this)");
  2559. EXPECT_FALSE(client_->IsInsideBeginImplFrame());
  2560. has_damage = false;
  2561. EXPECT_EQ(viz::BeginFrameAck(args, has_damage),
  2562. client_->last_begin_frame_ack());
  2563. client_->Reset();
  2564. }
  2565. class SchedulerClientSetNeedsPrepareTilesOnDraw : public FakeSchedulerClient {
  2566. public:
  2567. SchedulerClientSetNeedsPrepareTilesOnDraw() : FakeSchedulerClient() {}
  2568. protected:
  2569. DrawResult ScheduledActionDrawIfPossible() override {
  2570. scheduler_->SetNeedsPrepareTiles();
  2571. return FakeSchedulerClient::ScheduledActionDrawIfPossible();
  2572. }
  2573. };
  2574. TEST_F(SchedulerTest, SynchronousCompositorPrepareTilesOnDraw) {
  2575. scheduler_settings_.using_synchronous_renderer_compositor = true;
  2576. std::unique_ptr<FakeSchedulerClient> client =
  2577. base::WrapUnique(new SchedulerClientSetNeedsPrepareTilesOnDraw);
  2578. SetUpScheduler(EXTERNAL_BFS, std::move(client));
  2579. scheduler_->SetNeedsRedraw();
  2580. EXPECT_ACTIONS("AddObserver(this)");
  2581. client_->Reset();
  2582. // Next vsync.
  2583. EXPECT_SCOPED(AdvanceFrame());
  2584. EXPECT_ACTIONS("WillBeginImplFrame",
  2585. "ScheduledActionInvalidateLayerTreeFrameSink");
  2586. client_->Reset();
  2587. // Android onDraw.
  2588. scheduler_->SetNeedsRedraw();
  2589. bool resourceless_software_draw = false;
  2590. bool skip_draw = false;
  2591. scheduler_->OnDrawForLayerTreeFrameSink(resourceless_software_draw,
  2592. skip_draw);
  2593. EXPECT_ACTIONS("ScheduledActionDrawIfPossible",
  2594. "ScheduledActionPrepareTiles");
  2595. EXPECT_FALSE(client_->IsInsideBeginImplFrame());
  2596. EXPECT_FALSE(scheduler_->PrepareTilesPending());
  2597. client_->Reset();
  2598. // Android onDraw.
  2599. scheduler_->SetNeedsRedraw();
  2600. scheduler_->OnDrawForLayerTreeFrameSink(resourceless_software_draw,
  2601. skip_draw);
  2602. EXPECT_ACTIONS("ScheduledActionDrawIfPossible",
  2603. "ScheduledActionPrepareTiles");
  2604. EXPECT_FALSE(client_->IsInsideBeginImplFrame());
  2605. EXPECT_FALSE(scheduler_->PrepareTilesPending());
  2606. client_->Reset();
  2607. // Next vsync.
  2608. EXPECT_SCOPED(AdvanceFrame());
  2609. EXPECT_FALSE(scheduler_->PrepareTilesPending());
  2610. EXPECT_ACTIONS("WillBeginImplFrame", "RemoveObserver(this)");
  2611. EXPECT_FALSE(scheduler_->begin_frames_expected());
  2612. client_->Reset();
  2613. }
  2614. // Synchronous compositor does not require the active tree to be drawn at least
  2615. // once before the next activation. This test verifies two commit-activate
  2616. // cycles without draw work correctly.
  2617. TEST_F(SchedulerTest, SynchronousCompositorAllowsActivateBeforeDraw) {
  2618. scheduler_settings_.using_synchronous_renderer_compositor = true;
  2619. std::unique_ptr<FakeSchedulerClient> client =
  2620. base::WrapUnique(new SchedulerClientSetNeedsPrepareTilesOnDraw);
  2621. SetUpScheduler(EXTERNAL_BFS, std::move(client));
  2622. scheduler_->SetNeedsRedraw();
  2623. EXPECT_ACTIONS("AddObserver(this)");
  2624. client_->Reset();
  2625. // Next vsync.
  2626. scheduler_->SetNeedsBeginMainFrame();
  2627. EXPECT_SCOPED(AdvanceFrame());
  2628. EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame",
  2629. "ScheduledActionInvalidateLayerTreeFrameSink");
  2630. client_->Reset();
  2631. // Commit and activate.
  2632. scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
  2633. scheduler_->NotifyReadyToCommit(nullptr);
  2634. EXPECT_ACTIONS("ScheduledActionCommit", "ScheduledActionPostCommit");
  2635. client_->Reset();
  2636. scheduler_->NotifyReadyToActivate();
  2637. EXPECT_ACTIONS("ScheduledActionActivateSyncTree");
  2638. client_->Reset();
  2639. // No Draw.
  2640. // Next vsync.
  2641. scheduler_->SetNeedsBeginMainFrame();
  2642. EXPECT_SCOPED(AdvanceFrame());
  2643. EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame",
  2644. "ScheduledActionInvalidateLayerTreeFrameSink");
  2645. client_->Reset();
  2646. // Commit and activate.
  2647. scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
  2648. scheduler_->NotifyReadyToCommit(nullptr);
  2649. EXPECT_ACTIONS("ScheduledActionCommit", "ScheduledActionPostCommit");
  2650. client_->Reset();
  2651. scheduler_->NotifyReadyToActivate();
  2652. EXPECT_ACTIONS("ScheduledActionActivateSyncTree");
  2653. client_->Reset();
  2654. }
  2655. TEST_F(SchedulerTest, SetNeedsRedrawFromWillBeginImplFrame) {
  2656. client_ = std::make_unique<FakeSchedulerClient>();
  2657. CreateScheduler(EXTERNAL_BFS);
  2658. scheduler_->SetVisible(true);
  2659. scheduler_->SetCanDraw(true);
  2660. client_->SetWillBeginImplFrameCausesRedraw(true);
  2661. scheduler_->DidCreateAndInitializeLayerTreeFrameSink();
  2662. scheduler_->SetNeedsBeginMainFrame();
  2663. AdvanceFrame();
  2664. EXPECT_ACTIONS("ScheduledActionBeginLayerTreeFrameSinkCreation",
  2665. "AddObserver(this)", "WillBeginImplFrame",
  2666. "ScheduledActionSendBeginMainFrame");
  2667. EXPECT_TRUE(scheduler_->RedrawPending());
  2668. // WillBeginFrame calls Scheduler::SetNeedsRedraw, which could try to run
  2669. // another action. If none of the EXPECT_FALSE(inside_action_)s in
  2670. // FakeSchedulerClient fail, we know we didn't re-enter the scheduler.
  2671. }
  2672. TEST_F(SchedulerTest, SynchronousCompositorSendBeginMainFrameWhileIdle) {
  2673. scheduler_settings_.using_synchronous_renderer_compositor = true;
  2674. SetUpScheduler(EXTERNAL_BFS);
  2675. scheduler_->SetNeedsRedraw();
  2676. EXPECT_ACTIONS("AddObserver(this)");
  2677. client_->Reset();
  2678. // Next vsync.
  2679. EXPECT_SCOPED(AdvanceFrame());
  2680. EXPECT_ACTIONS("WillBeginImplFrame",
  2681. "ScheduledActionInvalidateLayerTreeFrameSink");
  2682. client_->Reset();
  2683. // Android onDraw.
  2684. scheduler_->SetNeedsRedraw();
  2685. bool resourceless_software_draw = false;
  2686. bool skip_draw = false;
  2687. scheduler_->OnDrawForLayerTreeFrameSink(resourceless_software_draw,
  2688. skip_draw);
  2689. EXPECT_ACTIONS("ScheduledActionDrawIfPossible");
  2690. EXPECT_FALSE(client_->IsInsideBeginImplFrame());
  2691. EXPECT_FALSE(scheduler_->PrepareTilesPending());
  2692. client_->Reset();
  2693. // Simulate SetNeedsBeginMainFrame due to input event.
  2694. scheduler_->SetNeedsBeginMainFrame();
  2695. EXPECT_ACTIONS("ScheduledActionSendBeginMainFrame");
  2696. client_->Reset();
  2697. scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
  2698. scheduler_->NotifyReadyToCommit(nullptr);
  2699. EXPECT_ACTIONS("ScheduledActionCommit", "ScheduledActionPostCommit");
  2700. client_->Reset();
  2701. scheduler_->NotifyReadyToActivate();
  2702. EXPECT_ACTIONS("ScheduledActionActivateSyncTree");
  2703. client_->Reset();
  2704. // Next vsync.
  2705. EXPECT_SCOPED(AdvanceFrame());
  2706. EXPECT_ACTIONS("WillBeginImplFrame",
  2707. "ScheduledActionInvalidateLayerTreeFrameSink");
  2708. client_->Reset();
  2709. // Android onDraw.
  2710. scheduler_->SetNeedsRedraw();
  2711. scheduler_->OnDrawForLayerTreeFrameSink(resourceless_software_draw,
  2712. skip_draw);
  2713. EXPECT_ACTIONS("ScheduledActionDrawIfPossible");
  2714. EXPECT_FALSE(client_->IsInsideBeginImplFrame());
  2715. EXPECT_FALSE(scheduler_->PrepareTilesPending());
  2716. client_->Reset();
  2717. // Simulate SetNeedsBeginMainFrame due to input event.
  2718. scheduler_->SetNeedsBeginMainFrame();
  2719. EXPECT_ACTIONS("ScheduledActionSendBeginMainFrame");
  2720. client_->Reset();
  2721. }
  2722. TEST_F(SchedulerTest, SynchronousCompositorResourcelessOnDrawWhenInvisible) {
  2723. scheduler_settings_.using_synchronous_renderer_compositor = true;
  2724. SetUpScheduler(EXTERNAL_BFS);
  2725. scheduler_->SetVisible(false);
  2726. scheduler_->SetNeedsRedraw();
  2727. bool resourceless_software_draw = true;
  2728. bool skip_draw = false;
  2729. scheduler_->OnDrawForLayerTreeFrameSink(resourceless_software_draw,
  2730. skip_draw);
  2731. // SynchronousCompositor has to draw regardless of visibility.
  2732. EXPECT_ACTIONS("ScheduledActionDrawIfPossible");
  2733. EXPECT_FALSE(client_->IsInsideBeginImplFrame());
  2734. client_->Reset();
  2735. }
  2736. TEST_F(SchedulerTest, AuthoritativeVSyncInterval) {
  2737. SetUpScheduler(THROTTLED_BFS);
  2738. base::TimeDelta initial_interval = scheduler_->BeginImplFrameInterval();
  2739. base::TimeDelta authoritative_interval = base::Milliseconds(33);
  2740. scheduler_->SetNeedsBeginMainFrame();
  2741. EXPECT_SCOPED(AdvanceFrame());
  2742. EXPECT_EQ(initial_interval, scheduler_->BeginImplFrameInterval());
  2743. scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
  2744. scheduler_->NotifyReadyToCommit(nullptr);
  2745. scheduler_->NotifyReadyToActivate();
  2746. task_runner_->RunTasksWhile(client_->InsideBeginImplFrame(true));
  2747. // Test changing the interval on the frame source external to the scheduler.
  2748. synthetic_frame_source_->OnUpdateVSyncParameters(task_runner_->NowTicks(),
  2749. authoritative_interval);
  2750. EXPECT_SCOPED(AdvanceFrame());
  2751. // At the next BeginFrame, authoritative interval is used instead of previous
  2752. // interval.
  2753. EXPECT_NE(initial_interval, scheduler_->BeginImplFrameInterval());
  2754. EXPECT_EQ(authoritative_interval, scheduler_->BeginImplFrameInterval());
  2755. }
  2756. TEST_F(SchedulerTest, ImplLatencyTakesPriority) {
  2757. SetUpScheduler(THROTTLED_BFS);
  2758. scheduler_->SetTreePrioritiesAndScrollState(
  2759. SMOOTHNESS_TAKES_PRIORITY,
  2760. ScrollHandlerState::SCROLL_DOES_NOT_AFFECT_SCROLL_HANDLER);
  2761. scheduler_->SetCriticalBeginMainFrameToActivateIsFast(true);
  2762. EXPECT_TRUE(scheduler_->ImplLatencyTakesPriority());
  2763. scheduler_->SetCriticalBeginMainFrameToActivateIsFast(false);
  2764. EXPECT_TRUE(scheduler_->ImplLatencyTakesPriority());
  2765. scheduler_->SetTreePrioritiesAndScrollState(
  2766. SMOOTHNESS_TAKES_PRIORITY,
  2767. ScrollHandlerState::SCROLL_AFFECTS_SCROLL_HANDLER);
  2768. scheduler_->SetCriticalBeginMainFrameToActivateIsFast(true);
  2769. EXPECT_FALSE(scheduler_->ImplLatencyTakesPriority());
  2770. scheduler_->SetCriticalBeginMainFrameToActivateIsFast(false);
  2771. EXPECT_TRUE(scheduler_->ImplLatencyTakesPriority());
  2772. scheduler_->SetTreePrioritiesAndScrollState(
  2773. SAME_PRIORITY_FOR_BOTH_TREES,
  2774. ScrollHandlerState::SCROLL_DOES_NOT_AFFECT_SCROLL_HANDLER);
  2775. scheduler_->SetCriticalBeginMainFrameToActivateIsFast(true);
  2776. EXPECT_FALSE(scheduler_->ImplLatencyTakesPriority());
  2777. scheduler_->SetCriticalBeginMainFrameToActivateIsFast(false);
  2778. EXPECT_FALSE(scheduler_->ImplLatencyTakesPriority());
  2779. scheduler_->SetTreePrioritiesAndScrollState(
  2780. SAME_PRIORITY_FOR_BOTH_TREES,
  2781. ScrollHandlerState::SCROLL_AFFECTS_SCROLL_HANDLER);
  2782. scheduler_->SetCriticalBeginMainFrameToActivateIsFast(true);
  2783. EXPECT_FALSE(scheduler_->ImplLatencyTakesPriority());
  2784. scheduler_->SetCriticalBeginMainFrameToActivateIsFast(false);
  2785. EXPECT_FALSE(scheduler_->ImplLatencyTakesPriority());
  2786. }
  2787. TEST_F(SchedulerTest, NoLayerTreeFrameSinkCreationWhileCommitPending) {
  2788. SetUpScheduler(THROTTLED_BFS);
  2789. // SetNeedsBeginMainFrame should begin the frame.
  2790. scheduler_->SetNeedsBeginMainFrame();
  2791. client_->Reset();
  2792. EXPECT_SCOPED(AdvanceFrame());
  2793. EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame");
  2794. // Lose the LayerTreeFrameSink and trigger the deadline.
  2795. client_->Reset();
  2796. scheduler_->DidLoseLayerTreeFrameSink();
  2797. EXPECT_TRUE(client_->IsInsideBeginImplFrame());
  2798. EXPECT_NO_ACTION();
  2799. // The scheduler should not trigger the LayerTreeFrameSink creation till the
  2800. // commit is aborted.
  2801. task_runner_->RunTasksWhile(client_->InsideBeginImplFrame(true));
  2802. EXPECT_FALSE(client_->IsInsideBeginImplFrame());
  2803. EXPECT_NO_ACTION();
  2804. // Abort the commit.
  2805. client_->Reset();
  2806. scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
  2807. scheduler_->BeginMainFrameAborted(
  2808. CommitEarlyOutReason::ABORTED_DEFERRED_COMMIT);
  2809. EXPECT_ACTIONS("ScheduledActionBeginLayerTreeFrameSinkCreation");
  2810. }
  2811. TEST_F(SchedulerTest, ImplSideInvalidationInsideImplFrame) {
  2812. SetUpScheduler(EXTERNAL_BFS);
  2813. // Request an impl-side invalidation. Ensure that it runs before the deadline.
  2814. bool needs_first_draw_on_activation = true;
  2815. scheduler_->SetNeedsImplSideInvalidation(needs_first_draw_on_activation);
  2816. client_->Reset();
  2817. EXPECT_SCOPED(AdvanceFrame());
  2818. EXPECT_ACTIONS("WillBeginImplFrame",
  2819. "ScheduledActionPerformImplSideInvalidation");
  2820. }
  2821. TEST_F(SchedulerTest, ImplSideInvalidationsMergedWithCommit) {
  2822. SetUpScheduler(EXTERNAL_BFS);
  2823. // Request a main frame and invalidation, the only action run should be
  2824. // sending the main frame.
  2825. SetShouldDeferInvalidationForMainFrame(true);
  2826. scheduler_->SetNeedsBeginMainFrame();
  2827. bool needs_first_draw_on_activation = true;
  2828. scheduler_->SetNeedsImplSideInvalidation(needs_first_draw_on_activation);
  2829. client_->Reset();
  2830. EXPECT_SCOPED(AdvanceFrame());
  2831. EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame");
  2832. // Respond with a commit. The scheduler should only perform the commit
  2833. // actions since the impl-side invalidation request will be merged with the
  2834. // commit.
  2835. client_->Reset();
  2836. scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
  2837. scheduler_->NotifyReadyToCommit(nullptr);
  2838. EXPECT_ACTIONS("ScheduledActionCommit", "ScheduledActionPostCommit");
  2839. EXPECT_FALSE(scheduler_->needs_impl_side_invalidation());
  2840. }
  2841. TEST_F(SchedulerTest, AbortedCommitsTriggerImplSideInvalidations) {
  2842. SetUpScheduler(EXTERNAL_BFS);
  2843. // Request a main frame and invalidation, with a fast main thread so we wait
  2844. // for it to respond.
  2845. SetShouldDeferInvalidationForMainFrame(true);
  2846. scheduler_->SetNeedsBeginMainFrame();
  2847. bool needs_first_draw_on_activation = true;
  2848. scheduler_->SetNeedsImplSideInvalidation(needs_first_draw_on_activation);
  2849. client_->Reset();
  2850. EXPECT_SCOPED(AdvanceFrame());
  2851. EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame");
  2852. // Abort the main frame and request another one, the impl-side invalidations
  2853. // should not be blocked on the main frame.
  2854. client_->Reset();
  2855. scheduler_->SetNeedsBeginMainFrame();
  2856. scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
  2857. scheduler_->BeginMainFrameAborted(CommitEarlyOutReason::FINISHED_NO_UPDATES);
  2858. EXPECT_ACTIONS("ScheduledActionPerformImplSideInvalidation");
  2859. }
  2860. TEST_F(SchedulerTest, InvalidationNotBlockedOnMainFrame) {
  2861. SetUpScheduler(EXTERNAL_BFS);
  2862. // Request a main frame and invalidation, with a slow main thread so the
  2863. // invalidation is not blocked on a commit.
  2864. SetShouldDeferInvalidationForMainFrame(false);
  2865. scheduler_->SetNeedsBeginMainFrame();
  2866. bool needs_first_draw_on_activation = true;
  2867. scheduler_->SetNeedsImplSideInvalidation(needs_first_draw_on_activation);
  2868. client_->Reset();
  2869. EXPECT_SCOPED(AdvanceFrame());
  2870. EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame",
  2871. "ScheduledActionPerformImplSideInvalidation");
  2872. }
  2873. // The three letters appeneded to each version of this test mean the following:s
  2874. // tree_priority: B = both trees same priority; A = active tree priority;
  2875. // scroll_handler_state: H = affects scroll handler; N = does not affect scroll
  2876. // handler;
  2877. // durations: F = fast durations; S = slow durations
  2878. bool SchedulerTest::BeginMainFrameOnCriticalPath(
  2879. TreePriority tree_priority,
  2880. ScrollHandlerState scroll_handler_state,
  2881. base::TimeDelta durations) {
  2882. SetUpScheduler(EXTERNAL_BFS);
  2883. fake_compositor_timing_history_->SetAllEstimatesTo(durations);
  2884. client_->Reset();
  2885. scheduler_->SetTreePrioritiesAndScrollState(tree_priority,
  2886. scroll_handler_state);
  2887. scheduler_->SetNeedsBeginMainFrame();
  2888. EXPECT_FALSE(client_->last_begin_main_frame_args().IsValid());
  2889. EXPECT_SCOPED(AdvanceFrame());
  2890. EXPECT_TRUE(client_->last_begin_main_frame_args().IsValid());
  2891. return client_->last_begin_main_frame_args().on_critical_path;
  2892. }
  2893. TEST_F(SchedulerTest, BeginMainFrameOnCriticalPath_BNF) {
  2894. EXPECT_TRUE(BeginMainFrameOnCriticalPath(
  2895. SAME_PRIORITY_FOR_BOTH_TREES,
  2896. ScrollHandlerState::SCROLL_DOES_NOT_AFFECT_SCROLL_HANDLER,
  2897. kFastDuration));
  2898. }
  2899. TEST_F(SchedulerTest, BeginMainFrameOnCriticalPath_BNS) {
  2900. EXPECT_TRUE(BeginMainFrameOnCriticalPath(
  2901. SAME_PRIORITY_FOR_BOTH_TREES,
  2902. ScrollHandlerState::SCROLL_DOES_NOT_AFFECT_SCROLL_HANDLER,
  2903. kSlowDuration));
  2904. }
  2905. TEST_F(SchedulerTest, BeginMainFrameOnCriticalPath_BHF) {
  2906. EXPECT_TRUE(BeginMainFrameOnCriticalPath(
  2907. SAME_PRIORITY_FOR_BOTH_TREES,
  2908. ScrollHandlerState::SCROLL_AFFECTS_SCROLL_HANDLER, kFastDuration));
  2909. }
  2910. TEST_F(SchedulerTest, BeginMainFrameOnCriticalPath_BHS) {
  2911. EXPECT_TRUE(BeginMainFrameOnCriticalPath(
  2912. SAME_PRIORITY_FOR_BOTH_TREES,
  2913. ScrollHandlerState::SCROLL_AFFECTS_SCROLL_HANDLER, kSlowDuration));
  2914. }
  2915. TEST_F(SchedulerTest, BeginMainFrameOnCriticalPath_ANF) {
  2916. EXPECT_FALSE(BeginMainFrameOnCriticalPath(
  2917. SMOOTHNESS_TAKES_PRIORITY,
  2918. ScrollHandlerState::SCROLL_DOES_NOT_AFFECT_SCROLL_HANDLER,
  2919. kFastDuration));
  2920. }
  2921. TEST_F(SchedulerTest, BeginMainFrameOnCriticalPath_ANS) {
  2922. EXPECT_FALSE(BeginMainFrameOnCriticalPath(
  2923. SMOOTHNESS_TAKES_PRIORITY,
  2924. ScrollHandlerState::SCROLL_DOES_NOT_AFFECT_SCROLL_HANDLER,
  2925. kSlowDuration));
  2926. }
  2927. TEST_F(SchedulerTest, BeginMainFrameOnCriticalPath_AHF) {
  2928. EXPECT_TRUE(BeginMainFrameOnCriticalPath(
  2929. SMOOTHNESS_TAKES_PRIORITY,
  2930. ScrollHandlerState::SCROLL_AFFECTS_SCROLL_HANDLER, kFastDuration));
  2931. }
  2932. TEST_F(SchedulerTest, BeginMainFrameOnCriticalPath_AHS) {
  2933. EXPECT_FALSE(BeginMainFrameOnCriticalPath(
  2934. SMOOTHNESS_TAKES_PRIORITY,
  2935. ScrollHandlerState::SCROLL_AFFECTS_SCROLL_HANDLER, kSlowDuration));
  2936. }
  2937. TEST_F(SchedulerTest, BeginFrameAckForFinishedImplFrame) {
  2938. // Sets up scheduler and sends two BeginFrames, both finished.
  2939. SetUpScheduler(EXTERNAL_BFS);
  2940. // Run a successful redraw and verify that a new ack is sent.
  2941. scheduler_->SetNeedsRedraw();
  2942. client_->Reset();
  2943. viz::BeginFrameArgs args = SendNextBeginFrame();
  2944. EXPECT_ACTIONS("WillBeginImplFrame");
  2945. EXPECT_TRUE(client_->IsInsideBeginImplFrame());
  2946. EXPECT_TRUE(scheduler_->begin_frames_expected());
  2947. client_->Reset();
  2948. task_runner_->RunPendingTasks(); // Run posted deadline.
  2949. EXPECT_ACTIONS("ScheduledActionDrawIfPossible");
  2950. EXPECT_FALSE(client_->IsInsideBeginImplFrame());
  2951. EXPECT_TRUE(scheduler_->begin_frames_expected());
  2952. // Successful draw caused damage.
  2953. bool has_damage = true;
  2954. EXPECT_EQ(viz::BeginFrameAck(args, has_damage),
  2955. client_->last_begin_frame_ack());
  2956. client_->Reset();
  2957. // Request another redraw, but fail it. Verify that a new ack is sent.
  2958. scheduler_->SetNeedsRedraw();
  2959. client_->Reset();
  2960. args = SendNextBeginFrame();
  2961. EXPECT_ACTIONS("WillBeginImplFrame");
  2962. EXPECT_TRUE(client_->IsInsideBeginImplFrame());
  2963. EXPECT_TRUE(scheduler_->begin_frames_expected());
  2964. client_->Reset();
  2965. client_->SetDrawWillHappen(false);
  2966. task_runner_->RunPendingTasks(); // Run posted deadline.
  2967. EXPECT_ACTIONS("ScheduledActionDrawIfPossible",
  2968. // Failed draw triggers SendBeginMainFrame.
  2969. "ScheduledActionSendBeginMainFrame");
  2970. EXPECT_FALSE(client_->IsInsideBeginImplFrame());
  2971. EXPECT_TRUE(scheduler_->begin_frames_expected());
  2972. // Failed draw: no damage.
  2973. has_damage = false;
  2974. EXPECT_EQ(viz::BeginFrameAck(args, has_damage),
  2975. client_->last_begin_frame_ack());
  2976. // The begin-main-frame sent has not been acknowledged yet (either by
  2977. // doing a commit, or aborting the draw from the main-thread).
  2978. EXPECT_EQ(FrameSkippedReason::kWaitingOnMain,
  2979. client_->last_frame_skipped_reason());
  2980. client_->Reset();
  2981. // Start another frame, and end the frame without drawing.
  2982. args = SendNextBeginFrame();
  2983. EXPECT_ACTIONS("WillBeginImplFrame");
  2984. EXPECT_TRUE(client_->IsInsideBeginImplFrame());
  2985. EXPECT_TRUE(scheduler_->begin_frames_expected());
  2986. client_->Reset();
  2987. client_->SetDrawWillHappen(false);
  2988. client_->SetSwapWillHappenIfDrawHappens(false);
  2989. task_runner_->RunPendingTasks(); // Run posted deadline.
  2990. EXPECT_ACTIONS("ScheduledActionDrawIfPossible");
  2991. // Draw with no damage.
  2992. has_damage = false;
  2993. EXPECT_EQ(viz::BeginFrameAck(args, has_damage),
  2994. client_->last_begin_frame_ack());
  2995. // The main thread still has not responded to the begin-main-frame.
  2996. EXPECT_EQ(FrameSkippedReason::kWaitingOnMain,
  2997. client_->last_frame_skipped_reason());
  2998. client_->Reset();
  2999. // Allow the commit now. NotifyReadyToCommit should trigger the commit.
  3000. scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
  3001. scheduler_->NotifyReadyToCommit(nullptr);
  3002. EXPECT_ACTIONS("ScheduledActionCommit", "ScheduledActionPostCommit");
  3003. EXPECT_TRUE(scheduler_->begin_frames_expected());
  3004. client_->Reset();
  3005. // Start another frame. For this frame, draw succeeds, but 'swap' does not
  3006. // happen (i.e. no frame is submitted).
  3007. args = SendNextBeginFrame();
  3008. EXPECT_ACTIONS("WillBeginImplFrame");
  3009. EXPECT_TRUE(client_->IsInsideBeginImplFrame());
  3010. EXPECT_TRUE(scheduler_->begin_frames_expected());
  3011. client_->Reset();
  3012. client_->SetDrawWillHappen(true);
  3013. client_->SetSwapWillHappenIfDrawHappens(false);
  3014. task_runner_->RunPendingTasks(); // Run posted deadline.
  3015. // Draw with no damage.
  3016. has_damage = false;
  3017. EXPECT_EQ(viz::BeginFrameAck(args, has_damage),
  3018. client_->last_begin_frame_ack());
  3019. // The pending tree is not activated yet so the frame is still waiting on
  3020. // Main thread update
  3021. EXPECT_EQ(FrameSkippedReason::kWaitingOnMain,
  3022. client_->last_frame_skipped_reason());
  3023. }
  3024. TEST_F(SchedulerTest, BeginFrameAckForBeginFrameBeforeLastDeadline) {
  3025. SetUpScheduler(EXTERNAL_BFS);
  3026. // Request tile preparation to schedule a proactive BeginFrame.
  3027. scheduler_->SetNeedsPrepareTiles();
  3028. client_->Reset();
  3029. SendNextBeginFrame();
  3030. EXPECT_ACTIONS("WillBeginImplFrame");
  3031. EXPECT_TRUE(client_->IsInsideBeginImplFrame());
  3032. // Until tiles were prepared, further proactive BeginFrames are expected.
  3033. EXPECT_TRUE(scheduler_->begin_frames_expected());
  3034. client_->Reset();
  3035. // Send the next BeginFrame before the previous one's deadline was executed.
  3036. // This should post the previous BeginFrame's deadline, during which tiles
  3037. // will be prepared. As a result of that, no further BeginFrames will be
  3038. // needed, and the new BeginFrame should be dropped.
  3039. viz::BeginFrameArgs args = SendNextBeginFrame();
  3040. task_runner_->RunPendingTasks(); // Run posted deadline.
  3041. EXPECT_ACTIONS("ScheduledActionPrepareTiles", "RemoveObserver(this)");
  3042. EXPECT_FALSE(client_->IsInsideBeginImplFrame());
  3043. EXPECT_FALSE(scheduler_->begin_frames_expected());
  3044. // Latest ack should be for the dropped BeginFrame.
  3045. bool has_damage = false;
  3046. EXPECT_EQ(viz::BeginFrameAck(args, has_damage),
  3047. client_->last_begin_frame_ack());
  3048. client_->Reset();
  3049. }
  3050. TEST_F(SchedulerTest, BeginFrameAckForDroppedBeginFrame) {
  3051. SetUpScheduler(EXTERNAL_BFS);
  3052. // Request a single BeginFrame.
  3053. scheduler_->SetNeedsOneBeginImplFrame();
  3054. EXPECT_TRUE(scheduler_->begin_frames_expected());
  3055. client_->Reset();
  3056. // First BeginFrame is handled by StateMachine.
  3057. viz::BeginFrameArgs first_args = SendNextBeginFrame();
  3058. EXPECT_ACTIONS("WillBeginImplFrame");
  3059. EXPECT_TRUE(client_->IsInsideBeginImplFrame());
  3060. // State machine is no longer interested in BeginFrames, but scheduler is
  3061. // still observing the source.
  3062. EXPECT_TRUE(scheduler_->begin_frames_expected());
  3063. EXPECT_FALSE(scheduler_->BeginFrameNeeded());
  3064. client_->Reset();
  3065. // Send the next BeginFrame before the previous one's deadline was executed.
  3066. // The BeginFrame should be dropped immediately, since the state machine is
  3067. // not expecting any BeginFrames.
  3068. viz::BeginFrameArgs second_args = SendNextBeginFrame();
  3069. EXPECT_NO_ACTION();
  3070. // Latest ack should be for the dropped BeginFrame.
  3071. bool has_damage = false;
  3072. EXPECT_EQ(viz::BeginFrameAck(second_args, has_damage),
  3073. client_->last_begin_frame_ack());
  3074. client_->Reset();
  3075. task_runner_->RunPendingTasks(); // Run deadline of prior BeginFrame.
  3076. EXPECT_ACTIONS("RemoveObserver(this)");
  3077. // We'd expect an out-of-order ack for the prior BeginFrame.
  3078. has_damage = false;
  3079. EXPECT_EQ(viz::BeginFrameAck(first_args, has_damage),
  3080. client_->last_begin_frame_ack());
  3081. client_->Reset();
  3082. }
  3083. TEST_F(SchedulerTest, BeginFrameAckForLateMissedBeginFrame) {
  3084. SetUpScheduler(EXTERNAL_BFS);
  3085. scheduler_->SetNeedsRedraw();
  3086. client_->Reset();
  3087. // Send a missed BeginFrame with a passed deadline.
  3088. task_runner_->AdvanceMockTickClock(viz::BeginFrameArgs::DefaultInterval());
  3089. viz::BeginFrameArgs args =
  3090. fake_external_begin_frame_source_->CreateBeginFrameArgs(
  3091. BEGINFRAME_FROM_HERE, task_runner_->GetMockTickClock());
  3092. args.type = viz::BeginFrameArgs::MISSED;
  3093. task_runner_->AdvanceMockTickClock(viz::BeginFrameArgs::DefaultInterval());
  3094. EXPECT_GT(task_runner_->NowTicks(), args.deadline);
  3095. fake_external_begin_frame_source_->TestOnBeginFrame(args);
  3096. task_runner_->RunPendingTasks();
  3097. EXPECT_NO_ACTION();
  3098. EXPECT_FALSE(client_->IsInsideBeginImplFrame());
  3099. // Latest ack should be for the missed BeginFrame that was too late: no
  3100. // damage.
  3101. bool has_damage = false;
  3102. EXPECT_EQ(viz::BeginFrameAck(args, has_damage),
  3103. client_->last_begin_frame_ack());
  3104. client_->Reset();
  3105. }
  3106. TEST_F(SchedulerTest, CriticalBeginMainFrameToActivateIsFast) {
  3107. SetUpScheduler(EXTERNAL_BFS);
  3108. scheduler_->SetNeedsRedraw();
  3109. base::TimeDelta estimate_duration = base::Milliseconds(1);
  3110. fake_compositor_timing_history_->SetAllEstimatesTo(estimate_duration);
  3111. // If we have a scroll handler but the critical main frame is slow, we should
  3112. // still prioritize impl thread latency.
  3113. scheduler_->SetTreePrioritiesAndScrollState(
  3114. SMOOTHNESS_TAKES_PRIORITY,
  3115. ScrollHandlerState::SCROLL_AFFECTS_SCROLL_HANDLER);
  3116. scheduler_->SetNeedsRedraw();
  3117. // An interval of 2ms makes sure that the main frame is considered slow.
  3118. base::TimeDelta interval = base::Milliseconds(2);
  3119. task_runner_->AdvanceMockTickClock(interval);
  3120. viz::BeginFrameArgs args = viz::BeginFrameArgs::Create(
  3121. BEGINFRAME_FROM_HERE, 0u, 1u, task_runner_->NowTicks(),
  3122. task_runner_->NowTicks() + interval, interval,
  3123. viz::BeginFrameArgs::NORMAL);
  3124. fake_external_begin_frame_source_->TestOnBeginFrame(args);
  3125. EXPECT_TRUE(scheduler_->ImplLatencyTakesPriority());
  3126. task_runner_->RunPendingTasks(); // Run posted deadline to finish the frame.
  3127. ASSERT_FALSE(client_->IsInsideBeginImplFrame());
  3128. // Set an interval of 10ms. The bmf_to_activate_interval should be 1*4 = 4ms,
  3129. // to account for queue + main_frame + pending_tree + activation durations.
  3130. // With a draw time of 1ms and fudge factor of 1ms, the interval available for
  3131. // the main frame to be activated is 8ms, so it should be considered fast.
  3132. scheduler_->SetNeedsRedraw();
  3133. interval = base::Milliseconds(10);
  3134. task_runner_->AdvanceMockTickClock(interval);
  3135. args = viz::BeginFrameArgs::Create(BEGINFRAME_FROM_HERE, 0u, 2u,
  3136. task_runner_->NowTicks(),
  3137. task_runner_->NowTicks() + interval,
  3138. interval, viz::BeginFrameArgs::NORMAL);
  3139. fake_external_begin_frame_source_->TestOnBeginFrame(args);
  3140. EXPECT_FALSE(scheduler_->ImplLatencyTakesPriority());
  3141. task_runner_->RunPendingTasks(); // Run posted deadline to finish the frame.
  3142. ASSERT_FALSE(client_->IsInsideBeginImplFrame());
  3143. // Increase the draw duration to decrease the time available for the main
  3144. // frame. This should prioritize the impl thread.
  3145. scheduler_->SetNeedsRedraw();
  3146. fake_compositor_timing_history_->SetDrawDurationEstimate(
  3147. base::Milliseconds(7));
  3148. task_runner_->AdvanceMockTickClock(interval);
  3149. args = viz::BeginFrameArgs::Create(BEGINFRAME_FROM_HERE, 0u, 3u,
  3150. task_runner_->NowTicks(),
  3151. task_runner_->NowTicks() + interval,
  3152. interval, viz::BeginFrameArgs::NORMAL);
  3153. fake_external_begin_frame_source_->TestOnBeginFrame(args);
  3154. EXPECT_TRUE(scheduler_->ImplLatencyTakesPriority());
  3155. }
  3156. TEST_F(SchedulerTest, WaitForAllPipelineStagesUsesMissedBeginFrames) {
  3157. scheduler_settings_.wait_for_all_pipeline_stages_before_draw = true;
  3158. client_ = std::make_unique<FakeSchedulerClient>();
  3159. CreateScheduler(EXTERNAL_BFS);
  3160. // Initialize frame sink so that Scheduler and state machine need BeginFrames.
  3161. scheduler_->SetVisible(true);
  3162. scheduler_->SetCanDraw(true);
  3163. EXPECT_ACTIONS("ScheduledActionBeginLayerTreeFrameSinkCreation");
  3164. client_->Reset();
  3165. scheduler_->DidCreateAndInitializeLayerTreeFrameSink();
  3166. scheduler_->SetNeedsBeginMainFrame();
  3167. EXPECT_TRUE(scheduler_->begin_frames_expected());
  3168. EXPECT_FALSE(client_->IsInsideBeginImplFrame());
  3169. client_->Reset();
  3170. // Uses MISSED BeginFrames even after the deadline has passed.
  3171. base::TimeDelta interval = base::Milliseconds(16);
  3172. task_runner_->AdvanceMockTickClock(interval);
  3173. base::TimeTicks timestamp = task_runner_->NowTicks();
  3174. // Deadline should have passed after this.
  3175. task_runner_->AdvanceMockTickClock(interval * 2);
  3176. viz::BeginFrameArgs args = viz::BeginFrameArgs::Create(
  3177. BEGINFRAME_FROM_HERE, 0u, 1u, timestamp, timestamp + interval, interval,
  3178. viz::BeginFrameArgs::MISSED);
  3179. fake_external_begin_frame_source_->TestOnBeginFrame(args);
  3180. EXPECT_TRUE(client_->IsInsideBeginImplFrame());
  3181. }
  3182. TEST_F(SchedulerTest, WaitForAllPipelineStagesAlwaysObservesBeginFrames) {
  3183. scheduler_settings_.wait_for_all_pipeline_stages_before_draw = true;
  3184. client_ = std::make_unique<FakeSchedulerClient>();
  3185. CreateScheduler(EXTERNAL_BFS);
  3186. // Initialize frame sink, request a main frame but defer commits, so that
  3187. // state machine is idle.
  3188. scheduler_->SetVisible(true);
  3189. scheduler_->SetCanDraw(true);
  3190. EXPECT_ACTIONS("ScheduledActionBeginLayerTreeFrameSinkCreation");
  3191. client_->Reset();
  3192. scheduler_->DidCreateAndInitializeLayerTreeFrameSink();
  3193. scheduler_->SetDeferBeginMainFrame(true);
  3194. scheduler_->SetNeedsBeginMainFrame();
  3195. EXPECT_TRUE(scheduler_->begin_frames_expected());
  3196. EXPECT_FALSE(client_->IsInsideBeginImplFrame());
  3197. client_->Reset();
  3198. // In full-pipe mode, the SchedulerStateMachine always wants BeginFrames, even
  3199. // if it is otherwise idle.
  3200. EXPECT_TRUE(scheduler_->begin_frames_expected());
  3201. EXPECT_TRUE(scheduler_->BeginFrameNeeded());
  3202. // Scheduler begins a frame even if otherwise idle.
  3203. base::TimeDelta interval = base::Milliseconds(16);
  3204. task_runner_->AdvanceMockTickClock(interval);
  3205. base::TimeTicks timestamp = task_runner_->NowTicks();
  3206. viz::BeginFrameArgs args = viz::BeginFrameArgs::Create(
  3207. BEGINFRAME_FROM_HERE, 0u, 1u, timestamp, timestamp + interval, interval,
  3208. viz::BeginFrameArgs::NORMAL);
  3209. fake_external_begin_frame_source_->TestOnBeginFrame(args);
  3210. EXPECT_ACTIONS("WillBeginImplFrame");
  3211. EXPECT_TRUE(client_->IsInsideBeginImplFrame());
  3212. client_->Reset();
  3213. // BeginFrame deadline is not blocked because commits are deferred.
  3214. task_runner_->RunPendingTasks();
  3215. EXPECT_ACTIONS();
  3216. EXPECT_TRUE(!client_->IsInsideBeginImplFrame());
  3217. client_->Reset();
  3218. }
  3219. TEST_F(SchedulerTest, CriticalBeginMainFrameIsFast_CommitEstimateSlow) {
  3220. SetUpScheduler(EXTERNAL_BFS);
  3221. scheduler_->SetNeedsBeginMainFrame();
  3222. fake_compositor_timing_history_->SetAllEstimatesTo(kFastDuration);
  3223. fake_compositor_timing_history_->SetCommitDurationEstimate(kSlowDuration);
  3224. EXPECT_SCOPED(AdvanceFrame());
  3225. EXPECT_FALSE(scheduler_->state_machine()
  3226. .critical_begin_main_frame_to_activate_is_fast());
  3227. }
  3228. TEST_F(SchedulerTest, CriticalBeginMainFrameIsFast_CommitEstimateFast) {
  3229. SetUpScheduler(EXTERNAL_BFS);
  3230. scheduler_->SetNeedsBeginMainFrame();
  3231. fake_compositor_timing_history_->SetAllEstimatesTo(kFastDuration);
  3232. EXPECT_SCOPED(AdvanceFrame());
  3233. EXPECT_TRUE(scheduler_->state_machine()
  3234. .critical_begin_main_frame_to_activate_is_fast());
  3235. }
  3236. TEST_F(SchedulerTest, ShouldDeferInvalidation_AllEstimatesFast) {
  3237. SetUpScheduler(EXTERNAL_BFS);
  3238. scheduler_->SetNeedsBeginMainFrame();
  3239. fake_compositor_timing_history_->SetAllEstimatesTo(kFastDuration);
  3240. EXPECT_SCOPED(AdvanceFrame());
  3241. EXPECT_TRUE(scheduler_->state_machine()
  3242. .should_defer_invalidation_for_fast_main_frame());
  3243. }
  3244. TEST_F(SchedulerTest, ShouldDeferInvalidation_BMFStartToReadyToCommitSlow) {
  3245. SetUpScheduler(EXTERNAL_BFS);
  3246. scheduler_->SetNeedsBeginMainFrame();
  3247. fake_compositor_timing_history_->SetAllEstimatesTo(kFastDuration);
  3248. fake_compositor_timing_history_
  3249. ->SetBeginMainFrameStartToReadyToCommitDurationEstimate(kSlowDuration);
  3250. EXPECT_SCOPED(AdvanceFrame());
  3251. EXPECT_FALSE(scheduler_->state_machine()
  3252. .should_defer_invalidation_for_fast_main_frame());
  3253. }
  3254. TEST_F(SchedulerTest, ShouldDeferInvalidation_BMFQueueDurationCriticalSlow) {
  3255. SetUpScheduler(EXTERNAL_BFS);
  3256. scheduler_->SetNeedsBeginMainFrame();
  3257. fake_compositor_timing_history_->SetAllEstimatesTo(kFastDuration);
  3258. fake_compositor_timing_history_
  3259. ->SetBeginMainFrameQueueDurationCriticalEstimate(kSlowDuration);
  3260. EXPECT_SCOPED(AdvanceFrame());
  3261. EXPECT_FALSE(scheduler_->state_machine()
  3262. .should_defer_invalidation_for_fast_main_frame());
  3263. }
  3264. TEST_F(SchedulerTest, ShouldDeferInvalidation_BMFQueueDurationNotCriticalSlow) {
  3265. SetUpScheduler(EXTERNAL_BFS);
  3266. scheduler_->SetNeedsBeginMainFrame();
  3267. scheduler_->SetTreePrioritiesAndScrollState(
  3268. TreePriority::SMOOTHNESS_TAKES_PRIORITY,
  3269. ScrollHandlerState::SCROLL_DOES_NOT_AFFECT_SCROLL_HANDLER);
  3270. fake_compositor_timing_history_->SetAllEstimatesTo(kFastDuration);
  3271. fake_compositor_timing_history_
  3272. ->SetBeginMainFrameQueueDurationNotCriticalEstimate(kSlowDuration);
  3273. EXPECT_SCOPED(AdvanceFrame());
  3274. EXPECT_FALSE(scheduler_->state_machine()
  3275. .should_defer_invalidation_for_fast_main_frame());
  3276. }
  3277. TEST_F(SchedulerTest, SlowMainThreadButEstimatedFastTriggersInvalidations) {
  3278. SetUpScheduler(EXTERNAL_BFS);
  3279. scheduler_->SetNeedsBeginMainFrame();
  3280. scheduler_->SetNeedsImplSideInvalidation(true);
  3281. fake_compositor_timing_history_->SetAllEstimatesTo(kFastDuration);
  3282. // Main thread is estimated fast, invalidation will be deferred.
  3283. client_->Reset();
  3284. EXPECT_SCOPED(AdvanceFrame());
  3285. EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame");
  3286. // Draw deadline.
  3287. client_->Reset();
  3288. task_runner_->RunPendingTasks();
  3289. EXPECT_ACTIONS();
  3290. // Next frame. The invalidation should not be throttled.
  3291. client_->Reset();
  3292. EXPECT_SCOPED(AdvanceFrame());
  3293. EXPECT_ACTIONS("WillBeginImplFrame",
  3294. "ScheduledActionPerformImplSideInvalidation");
  3295. }
  3296. TEST_F(SchedulerTest,
  3297. SlowMainThreadRasterButEstimatedFastDoesNotTriggersInvalidations) {
  3298. SetUpScheduler(EXTERNAL_BFS);
  3299. scheduler_->SetNeedsBeginMainFrame();
  3300. scheduler_->SetNeedsImplSideInvalidation(true);
  3301. fake_compositor_timing_history_->SetAllEstimatesTo(kFastDuration);
  3302. // Main thread is estimated fast, invalidation will be deferred.
  3303. client_->Reset();
  3304. EXPECT_SCOPED(AdvanceFrame());
  3305. EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame");
  3306. // Commit before deadline but not ready to activate.
  3307. client_->Reset();
  3308. scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
  3309. scheduler_->NotifyReadyToCommit(nullptr);
  3310. EXPECT_ACTIONS("ScheduledActionCommit", "ScheduledActionPostCommit");
  3311. // Draw deadline.
  3312. client_->Reset();
  3313. task_runner_->RunPendingTasks();
  3314. EXPECT_ACTIONS();
  3315. // Next frame. The invalidation should still be throttled.
  3316. client_->Reset();
  3317. EXPECT_SCOPED(AdvanceFrame());
  3318. EXPECT_ACTIONS("WillBeginImplFrame");
  3319. }
  3320. TEST_F(SchedulerTest, SynchronousCompositorImplSideInvalidation) {
  3321. // Synchronous compositor doesn't have a deadline and our heuristics can't
  3322. // work. We should never be prioritizing impl-side invalidations over main
  3323. // frames.
  3324. scheduler_settings_.using_synchronous_renderer_compositor = true;
  3325. SetUpScheduler(EXTERNAL_BFS);
  3326. fake_compositor_timing_history_->SetAllEstimatesTo(kSlowDuration);
  3327. scheduler_->SetNeedsBeginMainFrame();
  3328. const bool needs_first_draw_on_activation = true;
  3329. scheduler_->SetNeedsImplSideInvalidation(needs_first_draw_on_activation);
  3330. client_->Reset();
  3331. EXPECT_SCOPED(AdvanceFrame());
  3332. EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame");
  3333. }
  3334. TEST_F(SchedulerTest, NoInvalidationForAnimateOnlyFrames) {
  3335. SetUpScheduler(EXTERNAL_BFS);
  3336. fake_compositor_timing_history_->SetAllEstimatesTo(kFastDuration);
  3337. client_->Reset();
  3338. scheduler_->SetNeedsImplSideInvalidation(true);
  3339. bool animate_only = true;
  3340. EXPECT_SCOPED(AdvanceFrame(animate_only));
  3341. EXPECT_ACTIONS("AddObserver(this)", "WillBeginImplFrame");
  3342. client_->Reset();
  3343. task_runner_->RunTasksWhile(client_->InsideBeginImplFrame(true));
  3344. EXPECT_ACTIONS();
  3345. // Now send a frame which requires full updates.
  3346. animate_only = false;
  3347. EXPECT_SCOPED(AdvanceFrame(animate_only));
  3348. EXPECT_ACTIONS("WillBeginImplFrame",
  3349. "ScheduledActionPerformImplSideInvalidation");
  3350. client_->Reset();
  3351. task_runner_->RunTasksWhile(client_->InsideBeginImplFrame(true));
  3352. EXPECT_ACTIONS();
  3353. }
  3354. TEST_F(SchedulerTest, SendEarlyDidNotProduceFrameIfIdle) {
  3355. SetUpScheduler(EXTERNAL_BFS);
  3356. scheduler_->SetNeedsBeginMainFrame();
  3357. client_->Reset();
  3358. EXPECT_SCOPED(AdvanceFrame());
  3359. EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame");
  3360. auto begin_main_frame_args = client_->last_begin_main_frame_args();
  3361. EXPECT_NE(client_->last_begin_frame_ack().frame_id.sequence_number,
  3362. begin_main_frame_args.frame_id.sequence_number);
  3363. client_->Reset();
  3364. scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
  3365. // Request a new commit before finishing the current one to simulate behavior
  3366. // seen in certain OOPIF renderers.
  3367. scheduler_->SetNeedsBeginMainFrame();
  3368. scheduler_->BeginMainFrameAborted(CommitEarlyOutReason::FINISHED_NO_UPDATES);
  3369. EXPECT_EQ(client_->last_begin_frame_ack().frame_id.sequence_number,
  3370. begin_main_frame_args.frame_id.sequence_number);
  3371. }
  3372. TEST_F(SchedulerTest,
  3373. HighImplLatencyModePrioritizesMainFramesOverImplInvalidation) {
  3374. SetUpScheduler(EXTERNAL_BFS);
  3375. fake_compositor_timing_history_->SetAllEstimatesTo(kFastDuration);
  3376. // Place the impl thread in high latency mode.
  3377. scheduler_->SetNeedsImplSideInvalidation(true);
  3378. client_->Reset();
  3379. EXPECT_SCOPED(AdvanceFrame());
  3380. EXPECT_ACTIONS("WillBeginImplFrame",
  3381. "ScheduledActionPerformImplSideInvalidation");
  3382. // Request a main frame and start the next impl frame. Since we have an impl
  3383. // side pending tree, we will activate and draw it. This finishes the impl
  3384. // frame before the main thread can respond causing the scheduler to
  3385. // incorrectly assume the main thread is slow.
  3386. client_->Reset();
  3387. EXPECT_SCOPED(AdvanceFrame());
  3388. EXPECT_ACTIONS("WillBeginImplFrame");
  3389. client_->Reset();
  3390. scheduler_->SetNeedsBeginMainFrame();
  3391. EXPECT_ACTIONS("ScheduledActionSendBeginMainFrame");
  3392. fake_compositor_timing_history_->SetBeginMainFrameSentTime(
  3393. task_runner_->NowTicks() + base::Milliseconds(8));
  3394. client_->Reset();
  3395. scheduler_->NotifyReadyToActivate();
  3396. task_runner_->RunTasksWhile(client_->InsideBeginImplFrame(true));
  3397. EXPECT_ACTIONS("ScheduledActionActivateSyncTree",
  3398. "ScheduledActionDrawIfPossible");
  3399. // Start a new frame. We should not assume the main thread is slow.
  3400. client_->Reset();
  3401. EXPECT_SCOPED(AdvanceFrame());
  3402. scheduler_->SetNeedsImplSideInvalidation(true);
  3403. // No invalidation should be performed since we are waiting for the main
  3404. // thread to respond and merge with the commit.
  3405. EXPECT_ACTIONS("WillBeginImplFrame");
  3406. }
  3407. namespace {
  3408. class FakePowerModeObserver : public PowerModeArbiter::Observer {
  3409. public:
  3410. void OnPowerModeChanged(PowerMode old_mode, PowerMode new_mode) override {}
  3411. };
  3412. class SchedulerTestForPowerMode : public SchedulerTest {
  3413. public:
  3414. SchedulerTestForPowerMode()
  3415. : time_overrides_(
  3416. /*time_override=*/nullptr,
  3417. &SchedulerTestForPowerMode::TimeTicksNow,
  3418. /*thread_ticks_override=*/nullptr) {
  3419. DCHECK_EQ(nullptr, current_test_);
  3420. current_test_ = this;
  3421. // Clear the arbiter's initial kCharging vote.
  3422. power_mode_arbiter_.SetOnBatteryPowerForTesting(/*on_battery_power=*/true);
  3423. power_mode_arbiter_.SetTaskRunnerForTesting(task_runner_);
  3424. // Add a fake observer so that reset tasks are executed.
  3425. power_mode_arbiter_.AddObserver(&observer_);
  3426. }
  3427. ~SchedulerTestForPowerMode() override {
  3428. DCHECK_EQ(this, current_test_);
  3429. current_test_ = nullptr;
  3430. power_mode_arbiter_.RemoveObserver(&observer_);
  3431. }
  3432. void AdvanceToArbiterSnapAfter(base::TimeDelta delay) {
  3433. // Align the mock clock with the phase of the arbiter's reset tasks.
  3434. base::TimeTicks target_time =
  3435. (task_runner_->NowTicks() + delay)
  3436. .SnappedToNextTick(base::TimeTicks(),
  3437. PowerModeArbiter::kResetVoteTimeResolution);
  3438. task_runner_->RunUntilTime(target_time);
  3439. }
  3440. static base::TimeTicks TimeTicksNow() {
  3441. DCHECK_NE(nullptr, current_test_);
  3442. return current_test_->task_runner_->NowTicks();
  3443. }
  3444. private:
  3445. // The ScopedTimeClockOverrides below require a function pointer (as opposed
  3446. // to a bound callback). We store the current test instance in this static
  3447. // variable to access its members from the static TimeTicksNow() method above.
  3448. static SchedulerTestForPowerMode* current_test_;
  3449. // The arbiter uses base::TimeTicks::Now(), which needs to be overridden by
  3450. // the test's task runner. Ideally we'd be using base::test::TaskEnvironment
  3451. // for scheduler unittests, which would do this for us.
  3452. base::subtle::ScopedTimeClockOverrides time_overrides_;
  3453. FakePowerModeObserver observer_;
  3454. };
  3455. // static
  3456. SchedulerTestForPowerMode* SchedulerTestForPowerMode::current_test_;
  3457. } // namespace
  3458. TEST_F(SchedulerTestForPowerMode, BeginMainFramePowerModeVoter) {
  3459. // Arbiter should start out in idle mode.
  3460. EXPECT_EQ(power_mode_arbiter_.GetActiveModeForTesting(), PowerMode::kIdle);
  3461. // SetUpScheduler will cause a BeginMainFrame and commit, which should change
  3462. // the PowerMode vote.
  3463. SetUpScheduler(EXTERNAL_BFS);
  3464. EXPECT_EQ(power_mode_arbiter_.GetActiveModeForTesting(),
  3465. PowerMode::kMainThreadAnimation);
  3466. // The scheduler should now be idle, so the PowerMode vote should be reset
  3467. // after kAnimationTimeout.
  3468. AdvanceToArbiterSnapAfter(PowerModeVoter::kAnimationTimeout);
  3469. EXPECT_EQ(power_mode_arbiter_.GetActiveModeForTesting(), PowerMode::kIdle);
  3470. scheduler_->SetNeedsBeginMainFrame();
  3471. EXPECT_EQ(power_mode_arbiter_.GetActiveModeForTesting(),
  3472. PowerMode::kMainThreadAnimation);
  3473. // While BeginMainFrame is needed, the vote is not reset
  3474. AdvanceToArbiterSnapAfter(PowerModeVoter::kAnimationTimeout);
  3475. EXPECT_EQ(power_mode_arbiter_.GetActiveModeForTesting(),
  3476. PowerMode::kMainThreadAnimation);
  3477. client_->Reset();
  3478. EXPECT_SCOPED(AdvanceFrame());
  3479. EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame");
  3480. client_->Reset();
  3481. scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
  3482. // While BeginMainFrame is active, the vote is not reset
  3483. AdvanceToArbiterSnapAfter(PowerModeVoter::kAnimationTimeout);
  3484. EXPECT_EQ(power_mode_arbiter_.GetActiveModeForTesting(),
  3485. PowerMode::kMainThreadAnimation);
  3486. scheduler_->BeginMainFrameAborted(CommitEarlyOutReason::FINISHED_NO_UPDATES);
  3487. // After aborting, the vote is reset.
  3488. AdvanceToArbiterSnapAfter(PowerModeVoter::kAnimationTimeout);
  3489. EXPECT_EQ(power_mode_arbiter_.GetActiveModeForTesting(), PowerMode::kIdle);
  3490. // Go through another two BeginMainFrames that are aborted.
  3491. scheduler_->SetNeedsBeginMainFrame();
  3492. EXPECT_EQ(power_mode_arbiter_.GetActiveModeForTesting(),
  3493. PowerMode::kMainThreadAnimation);
  3494. client_->Reset();
  3495. EXPECT_SCOPED(AdvanceFrame());
  3496. EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame");
  3497. client_->Reset();
  3498. scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
  3499. scheduler_->BeginMainFrameAborted(CommitEarlyOutReason::FINISHED_NO_UPDATES);
  3500. scheduler_->SetNeedsBeginMainFrame();
  3501. client_->Reset();
  3502. EXPECT_SCOPED(AdvanceFrame());
  3503. EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame");
  3504. client_->Reset();
  3505. scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
  3506. scheduler_->BeginMainFrameAborted(CommitEarlyOutReason::FINISHED_NO_UPDATES);
  3507. // Still in animation mode, but a reset is pending.
  3508. EXPECT_EQ(power_mode_arbiter_.GetActiveModeForTesting(),
  3509. PowerMode::kMainThreadAnimation);
  3510. AdvanceToArbiterSnapAfter(PowerModeVoter::kAnimationTimeout);
  3511. EXPECT_EQ(power_mode_arbiter_.GetActiveModeForTesting(), PowerMode::kIdle);
  3512. // Further BeginMainFrame will be ignored, because the main-thread animation
  3513. // is considered no-op after three consecutive aborted BeginMainFrames.
  3514. scheduler_->SetNeedsBeginMainFrame();
  3515. EXPECT_EQ(power_mode_arbiter_.GetActiveModeForTesting(), PowerMode::kIdle);
  3516. client_->Reset();
  3517. EXPECT_SCOPED(AdvanceFrame());
  3518. EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame");
  3519. client_->Reset();
  3520. scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
  3521. scheduler_->BeginMainFrameAborted(CommitEarlyOutReason::FINISHED_NO_UPDATES);
  3522. EXPECT_EQ(power_mode_arbiter_.GetActiveModeForTesting(), PowerMode::kIdle);
  3523. // But once the BeginMainFrame produces updates, we vote for animation again.
  3524. scheduler_->SetNeedsBeginMainFrame();
  3525. EXPECT_EQ(power_mode_arbiter_.GetActiveModeForTesting(), PowerMode::kIdle);
  3526. client_->Reset();
  3527. EXPECT_SCOPED(AdvanceFrame());
  3528. EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame");
  3529. client_->Reset();
  3530. scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
  3531. scheduler_->NotifyReadyToCommit(nullptr);
  3532. EXPECT_ACTIONS("ScheduledActionCommit", "ScheduledActionPostCommit");
  3533. EXPECT_EQ(power_mode_arbiter_.GetActiveModeForTesting(),
  3534. PowerMode::kMainThreadAnimation);
  3535. client_->Reset();
  3536. }
  3537. } // namespace
  3538. } // namespace cc