animation_unittest.cc 66 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727
  1. // Copyright 2018 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 "ui/lottie/animation.h"
  5. #include <map>
  6. #include <string>
  7. #include "base/check.h"
  8. #include "base/memory/raw_ptr.h"
  9. #include "base/memory/ref_counted_memory.h"
  10. #include "base/memory/scoped_refptr.h"
  11. #include "base/scoped_observation.h"
  12. #include "base/test/simple_test_tick_clock.h"
  13. #include "cc/paint/display_item_list.h"
  14. #include "cc/paint/paint_op_buffer.h"
  15. #include "cc/paint/paint_record.h"
  16. #include "cc/paint/record_paint_canvas.h"
  17. #include "cc/paint/skottie_frame_data.h"
  18. #include "cc/paint/skottie_frame_data_provider.h"
  19. #include "cc/paint/skottie_resource_metadata.h"
  20. #include "cc/paint/skottie_wrapper.h"
  21. #include "cc/test/lottie_test_data.h"
  22. #include "cc/test/skia_common.h"
  23. #include "testing/gmock/include/gmock/gmock.h"
  24. #include "testing/gtest/include/gtest/gtest.h"
  25. #include "third_party/abseil-cpp/absl/types/optional.h"
  26. #include "third_party/skia/include/core/SkBitmap.h"
  27. #include "third_party/skia/include/core/SkRect.h"
  28. #include "third_party/skia/include/core/SkStream.h"
  29. #include "ui/gfx/canvas.h"
  30. #include "ui/gfx/geometry/rect.h"
  31. #include "ui/lottie/animation_observer.h"
  32. namespace lottie {
  33. namespace {
  34. using ::testing::ElementsAre;
  35. using ::testing::Eq;
  36. using ::testing::FieldsAre;
  37. using ::testing::FloatEq;
  38. using ::testing::FloatNear;
  39. using ::testing::IsEmpty;
  40. using ::testing::NotNull;
  41. using ::testing::Pair;
  42. using ::testing::SizeIs;
  43. using ::testing::UnorderedElementsAre;
  44. // A skottie animation with solid green color for the first 2.5 seconds and then
  45. // a solid blue color for the next 2.5 seconds.
  46. constexpr char kData[] =
  47. "{"
  48. " \"v\" : \"4.12.0\","
  49. " \"fr\": 30,"
  50. " \"w\" : 400,"
  51. " \"h\" : 200,"
  52. " \"ip\": 0,"
  53. " \"op\": 150,"
  54. " \"assets\": [],"
  55. " \"layers\": ["
  56. " {"
  57. " \"ty\": 1,"
  58. " \"sw\": 400,"
  59. " \"sh\": 200,"
  60. " \"sc\": \"#00ff00\","
  61. " \"ip\": 0,"
  62. " \"op\": 75"
  63. " },"
  64. " {"
  65. " \"ty\": 1,"
  66. " \"sw\": 400,"
  67. " \"sh\": 200,"
  68. " \"sc\": \"#0000ff\","
  69. " \"ip\": 76,"
  70. " \"op\": 150"
  71. " }"
  72. " ]"
  73. "}";
  74. constexpr float kAnimationWidth = 400.f;
  75. constexpr float kAnimationHeight = 200.f;
  76. constexpr auto kAnimationDuration = base::Seconds(5);
  77. constexpr float kCanvasImageScale = 2.f;
  78. constexpr float kFrameTimestampToleranceSec = 0.1f;
  79. class TestAnimationObserver : public AnimationObserver {
  80. public:
  81. explicit TestAnimationObserver(Animation* animation) {
  82. observation_.Observe(animation);
  83. }
  84. ~TestAnimationObserver() override = default;
  85. TestAnimationObserver(const TestAnimationObserver&) = delete;
  86. TestAnimationObserver& operator=(const TestAnimationObserver&) = delete;
  87. void AnimationWillStartPlaying(const Animation* animation) override {
  88. animation_will_start_playing_ = true;
  89. }
  90. void AnimationCycleEnded(const Animation* animation) override {
  91. animation_cycle_ended_ = true;
  92. }
  93. void AnimationResuming(const Animation* animation) override {
  94. animation_resuming_ = true;
  95. }
  96. void AnimationFramePainted(const Animation* animation, float t) override {
  97. last_frame_painted_ = t;
  98. }
  99. void AnimationIsDeleting(const Animation* animation) override {
  100. animation_is_deleted_ = true;
  101. observation_.Reset();
  102. }
  103. void Reset() {
  104. animation_cycle_ended_ = false;
  105. animation_will_start_playing_ = false;
  106. animation_resuming_ = false;
  107. }
  108. bool animation_cycle_ended() const { return animation_cycle_ended_; }
  109. bool animation_will_start_playing() const {
  110. return animation_will_start_playing_;
  111. }
  112. bool animation_resuming() const { return animation_resuming_; }
  113. bool animation_is_deleted() const { return animation_is_deleted_; }
  114. const absl::optional<float>& last_frame_painted() const {
  115. return last_frame_painted_;
  116. }
  117. private:
  118. base::ScopedObservation<Animation, AnimationObserver> observation_{this};
  119. bool animation_cycle_ended_ = false;
  120. bool animation_will_start_playing_ = false;
  121. bool animation_resuming_ = false;
  122. bool animation_is_deleted_ = false;
  123. absl::optional<float> last_frame_painted_;
  124. };
  125. class TestSkottieFrameDataProvider : public cc::SkottieFrameDataProvider {
  126. public:
  127. class ImageAssetImpl : public cc::SkottieFrameDataProvider::ImageAsset {
  128. public:
  129. ImageAssetImpl() = default;
  130. ImageAssetImpl(const ImageAssetImpl& other) = delete;
  131. ImageAssetImpl& operator=(const ImageAssetImpl& other) = delete;
  132. cc::SkottieFrameData GetFrameData(float t, float scale_factor) override {
  133. last_frame_t_ = t;
  134. last_frame_scale_factor_ = scale_factor;
  135. return current_frame_data_;
  136. }
  137. void set_current_frame_data(cc::SkottieFrameData current_frame_data) {
  138. current_frame_data_ = std::move(current_frame_data);
  139. }
  140. const absl::optional<float>& last_frame_t() const { return last_frame_t_; }
  141. const absl::optional<float>& last_frame_scale_factor() const {
  142. return last_frame_scale_factor_;
  143. }
  144. private:
  145. friend class TestSkottieFrameDataProvider;
  146. ~ImageAssetImpl() override = default;
  147. cc::SkottieFrameData current_frame_data_;
  148. absl::optional<float> last_frame_t_;
  149. absl::optional<float> last_frame_scale_factor_;
  150. };
  151. TestSkottieFrameDataProvider() = default;
  152. TestSkottieFrameDataProvider(const TestSkottieFrameDataProvider&) = delete;
  153. TestSkottieFrameDataProvider& operator=(const TestSkottieFrameDataProvider&) =
  154. delete;
  155. ~TestSkottieFrameDataProvider() override = default;
  156. scoped_refptr<ImageAsset> LoadImageAsset(
  157. base::StringPiece resource_id,
  158. const base::FilePath& resource_path,
  159. const absl::optional<gfx::Size>& size) override {
  160. auto new_asset = base::MakeRefCounted<ImageAssetImpl>();
  161. CHECK(current_assets_.emplace(std::string(resource_id), new_asset).second);
  162. return new_asset;
  163. }
  164. ImageAssetImpl* GetLoadedImageAsset(const std::string& resource_id) {
  165. auto iter = current_assets_.find(resource_id);
  166. return iter == current_assets_.end() ? nullptr : iter->second.get();
  167. }
  168. private:
  169. std::map<std::string, scoped_refptr<ImageAssetImpl>> current_assets_;
  170. };
  171. } // namespace
  172. class AnimationTest : public testing::Test {
  173. public:
  174. AnimationTest() = default;
  175. ~AnimationTest() override = default;
  176. AnimationTest(const AnimationTest&) = delete;
  177. AnimationTest& operator=(const AnimationTest&) = delete;
  178. void SetUp() override {
  179. canvas_ = std::make_unique<gfx::Canvas>(
  180. gfx::Size(kAnimationWidth, kAnimationHeight), 1.f, false);
  181. skottie_ = cc::SkottieWrapper::CreateNonSerializable(
  182. base::as_bytes(base::make_span(kData, std::strlen(kData))));
  183. animation_ = std::make_unique<Animation>(skottie_);
  184. }
  185. void TearDown() override { animation_.reset(nullptr); }
  186. gfx::Canvas* canvas() { return canvas_.get(); }
  187. Animation::Style GetStyle() const {
  188. return animation_->playback_config_.style;
  189. }
  190. Animation::PlayState GetState() const { return animation_->state_; }
  191. bool IsStopped() const {
  192. return GetState() == Animation::PlayState::kStopped;
  193. }
  194. bool IsScheduledToPlay() const {
  195. return GetState() == Animation::PlayState::kSchedulePlay;
  196. }
  197. bool IsPlaying() const {
  198. return GetState() == Animation::PlayState::kPlaying;
  199. }
  200. bool IsScheduledToResume() const {
  201. return GetState() == Animation::PlayState::kScheduleResume;
  202. }
  203. bool HasAnimationEnded() const {
  204. return GetState() == Animation::PlayState::kEnded;
  205. }
  206. bool IsPaused() const { return GetState() == Animation::PlayState::kPaused; }
  207. const Animation::TimerControl* GetTimerControl() const {
  208. return animation_->timer_control_.get();
  209. }
  210. const base::TickClock* test_clock() const { return &test_clock_; }
  211. void AdvanceClock(base::TimeDelta advance) { test_clock_.Advance(advance); }
  212. base::TimeDelta TimeDeltaSince(const base::TimeTicks& ticks) const {
  213. return test_clock_.NowTicks() - ticks;
  214. }
  215. base::TimeTicks NowTicks() const { return test_clock_.NowTicks(); }
  216. double GetTimerStartOffset() const {
  217. return animation_->timer_control_->GetNormalizedStartOffset();
  218. }
  219. double GetTimerEndOffset() const {
  220. return animation_->timer_control_->GetNormalizedEndOffset();
  221. }
  222. const base::TimeTicks& GetTimerPreviousTick() const {
  223. return animation_->timer_control_->previous_tick_;
  224. }
  225. base::TimeDelta GetTimerTotalDuration() const {
  226. return animation_->timer_control_->total_duration_;
  227. }
  228. int GetTimerCycles() const {
  229. return animation_->timer_control_->completed_cycles();
  230. }
  231. void IsAllSameColor(SkColor color, const SkBitmap& bitmap) const {
  232. if (bitmap.colorType() == kBGRA_8888_SkColorType) {
  233. const SkColor* pixels = reinterpret_cast<SkColor*>(bitmap.getPixels());
  234. const int num_pixels = bitmap.width() * bitmap.height();
  235. for (int i = 0; i < num_pixels; i++)
  236. EXPECT_EQ(pixels[i], color);
  237. } else {
  238. for (int x = 0; x < bitmap.width(); x++)
  239. for (int y = 0; y < bitmap.height(); y++)
  240. EXPECT_EQ(bitmap.getColor(x, y), color);
  241. }
  242. }
  243. protected:
  244. std::unique_ptr<gfx::Canvas> canvas_;
  245. std::unique_ptr<Animation> animation_;
  246. scoped_refptr<cc::SkottieWrapper> skottie_;
  247. private:
  248. base::SimpleTestTickClock test_clock_;
  249. };
  250. class AnimationWithImageAssetsTest : public AnimationTest {
  251. protected:
  252. AnimationWithImageAssetsTest()
  253. : display_list_(base::MakeRefCounted<cc::DisplayItemList>(
  254. cc::DisplayItemList::kToBeReleasedAsPaintOpBuffer)),
  255. record_canvas_(display_list_.get(),
  256. SkRect::MakeIWH(cc::kLottieDataWith2AssetsWidth,
  257. cc::kLottieDataWith2AssetsHeight)) {}
  258. void SetUp() override {
  259. canvas_ = std::make_unique<gfx::Canvas>(&record_canvas_, kCanvasImageScale);
  260. skottie_ = cc::CreateSkottieFromString(cc::kLottieDataWith2Assets);
  261. animation_ = std::make_unique<Animation>(skottie_, cc::SkottieColorMap(),
  262. &frame_data_provider_);
  263. asset_0_ = frame_data_provider_.GetLoadedImageAsset("image_0");
  264. asset_1_ = frame_data_provider_.GetLoadedImageAsset("image_1");
  265. ASSERT_THAT(asset_0_, NotNull());
  266. ASSERT_THAT(asset_1_, NotNull());
  267. }
  268. cc::SkottieFrameData CreateHighQualityTestFrameData() {
  269. return {
  270. .image = cc::CreateDiscardablePaintImage(animation_->GetOriginalSize()),
  271. .quality = cc::PaintFlags::FilterQuality::kHigh};
  272. }
  273. const scoped_refptr<cc::DisplayItemList> display_list_;
  274. cc::RecordPaintCanvas record_canvas_;
  275. TestSkottieFrameDataProvider frame_data_provider_;
  276. raw_ptr<TestSkottieFrameDataProvider::ImageAssetImpl> asset_0_;
  277. raw_ptr<TestSkottieFrameDataProvider::ImageAssetImpl> asset_1_;
  278. };
  279. TEST_F(AnimationTest, InitializationAndLoadingData) {
  280. skottie_ = cc::SkottieWrapper::CreateNonSerializable(
  281. base::as_bytes(base::make_span(kData, std::strlen(kData))));
  282. animation_ = std::make_unique<Animation>(skottie_);
  283. EXPECT_FLOAT_EQ(animation_->GetOriginalSize().width(), kAnimationWidth);
  284. EXPECT_FLOAT_EQ(animation_->GetOriginalSize().height(), kAnimationHeight);
  285. EXPECT_EQ(animation_->GetAnimationDuration(), kAnimationDuration);
  286. EXPECT_TRUE(IsStopped());
  287. skottie_ = cc::SkottieWrapper::CreateNonSerializable(
  288. base::as_bytes(base::make_span(kData, std::strlen(kData))));
  289. animation_ = std::make_unique<Animation>(skottie_);
  290. EXPECT_FLOAT_EQ(animation_->GetOriginalSize().width(), kAnimationWidth);
  291. EXPECT_FLOAT_EQ(animation_->GetOriginalSize().height(), kAnimationHeight);
  292. EXPECT_EQ(animation_->GetAnimationDuration(), kAnimationDuration);
  293. EXPECT_TRUE(IsStopped());
  294. }
  295. TEST_F(AnimationTest, PlayLinearAnimation) {
  296. TestAnimationObserver observer(animation_.get());
  297. AdvanceClock(base::Milliseconds(300));
  298. EXPECT_TRUE(IsStopped());
  299. animation_->Start(Animation::PlaybackConfig::CreateWithStyle(
  300. Animation::Style::kLinear, *animation_));
  301. EXPECT_TRUE(IsScheduledToPlay());
  302. EXPECT_FALSE(observer.animation_will_start_playing());
  303. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  304. EXPECT_FALSE(IsScheduledToPlay());
  305. EXPECT_TRUE(IsPlaying());
  306. EXPECT_TRUE(observer.animation_will_start_playing());
  307. ASSERT_TRUE(animation_->GetCurrentProgress());
  308. EXPECT_FLOAT_EQ(*animation_->GetCurrentProgress(), 0);
  309. EXPECT_FLOAT_EQ(GetTimerStartOffset(), 0);
  310. EXPECT_FLOAT_EQ(GetTimerEndOffset(), 1.f);
  311. IsAllSameColor(SK_ColorGREEN, canvas()->GetBitmap());
  312. EXPECT_EQ(GetTimerTotalDuration(), kAnimationDuration);
  313. constexpr auto kAdvance = base::Milliseconds(50);
  314. AdvanceClock(kAdvance);
  315. EXPECT_EQ(TimeDeltaSince(GetTimerPreviousTick()), kAdvance);
  316. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  317. ASSERT_TRUE(animation_->GetCurrentProgress());
  318. EXPECT_FLOAT_EQ(*animation_->GetCurrentProgress(),
  319. kAdvance / kAnimationDuration);
  320. EXPECT_EQ(TimeDeltaSince(GetTimerPreviousTick()), base::TimeDelta());
  321. IsAllSameColor(SK_ColorGREEN, canvas()->GetBitmap());
  322. // Advance the clock to the end of the animation.
  323. constexpr auto kAdvanceToEnd =
  324. kAnimationDuration - kAdvance + base::Milliseconds(1);
  325. AdvanceClock(kAdvanceToEnd);
  326. EXPECT_EQ(TimeDeltaSince(GetTimerPreviousTick()), kAdvanceToEnd);
  327. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  328. ASSERT_TRUE(animation_->GetCurrentProgress());
  329. EXPECT_FLOAT_EQ(*animation_->GetCurrentProgress(), 1.f);
  330. EXPECT_TRUE(HasAnimationEnded());
  331. EXPECT_TRUE(observer.animation_cycle_ended());
  332. IsAllSameColor(SK_ColorBLUE, canvas()->GetBitmap());
  333. }
  334. TEST_F(AnimationTest, StopLinearAnimation) {
  335. TestAnimationObserver observer(animation_.get());
  336. AdvanceClock(base::Milliseconds(300));
  337. animation_->Start(Animation::PlaybackConfig::CreateWithStyle(
  338. Animation::Style::kLinear, *animation_));
  339. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  340. EXPECT_TRUE(IsPlaying());
  341. ASSERT_TRUE(animation_->GetCurrentProgress());
  342. EXPECT_FLOAT_EQ(*animation_->GetCurrentProgress(), 0);
  343. constexpr auto kAdvance = base::Milliseconds(50);
  344. AdvanceClock(kAdvance);
  345. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  346. ASSERT_TRUE(animation_->GetCurrentProgress());
  347. EXPECT_FLOAT_EQ(*animation_->GetCurrentProgress(),
  348. kAdvance / kAnimationDuration);
  349. animation_->Stop();
  350. EXPECT_FALSE(animation_->GetCurrentProgress());
  351. EXPECT_TRUE(IsStopped());
  352. }
  353. TEST_F(AnimationTest, PlaySubsectionOfLinearAnimation) {
  354. constexpr auto kStartTime = base::Milliseconds(400);
  355. constexpr auto kDuration = base::Milliseconds(1000);
  356. TestAnimationObserver observer(animation_.get());
  357. AdvanceClock(base::Milliseconds(300));
  358. EXPECT_FALSE(observer.animation_cycle_ended());
  359. animation_->Start(Animation::PlaybackConfig(
  360. {{kStartTime, kStartTime + kDuration}}, /*initial_offset=*/kStartTime,
  361. /*initial_completed_cycles=*/0, Animation::Style::kLinear));
  362. EXPECT_TRUE(IsScheduledToPlay());
  363. EXPECT_FALSE(observer.animation_will_start_playing());
  364. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  365. EXPECT_FALSE(IsScheduledToPlay());
  366. EXPECT_TRUE(IsPlaying());
  367. EXPECT_TRUE(observer.animation_will_start_playing());
  368. ASSERT_TRUE(animation_->GetCurrentProgress());
  369. EXPECT_FLOAT_EQ(*animation_->GetCurrentProgress(), GetTimerStartOffset());
  370. EXPECT_FLOAT_EQ(GetTimerEndOffset(),
  371. (kStartTime + kDuration) / kAnimationDuration);
  372. EXPECT_EQ(GetTimerTotalDuration(), kAnimationDuration);
  373. constexpr auto kAdvance = base::Milliseconds(100);
  374. AdvanceClock(kAdvance);
  375. EXPECT_EQ(TimeDeltaSince(GetTimerPreviousTick()), kAdvance);
  376. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  377. EXPECT_EQ(TimeDeltaSince(GetTimerPreviousTick()), base::TimeDelta());
  378. ASSERT_TRUE(animation_->GetCurrentProgress());
  379. EXPECT_FLOAT_EQ(*animation_->GetCurrentProgress(),
  380. (kStartTime + kAdvance) / kAnimationDuration);
  381. EXPECT_FALSE(observer.animation_cycle_ended());
  382. // Advance clock another 300 ms.
  383. constexpr auto kAdvance2 = base::Milliseconds(300);
  384. AdvanceClock(kAdvance2);
  385. EXPECT_EQ(TimeDeltaSince(GetTimerPreviousTick()), kAdvance2);
  386. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  387. EXPECT_EQ(TimeDeltaSince(GetTimerPreviousTick()).InMilliseconds(), 0);
  388. ASSERT_TRUE(animation_->GetCurrentProgress());
  389. EXPECT_FLOAT_EQ(*animation_->GetCurrentProgress(),
  390. (kStartTime + kAdvance + kAdvance2) / kAnimationDuration);
  391. EXPECT_FALSE(observer.animation_cycle_ended());
  392. // Reach the end of animation.
  393. constexpr auto kAdvanceToEnd =
  394. kDuration - kAdvance - kAdvance2 + base::Milliseconds(1);
  395. AdvanceClock(kAdvanceToEnd);
  396. EXPECT_EQ(TimeDeltaSince(GetTimerPreviousTick()), kAdvanceToEnd);
  397. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  398. ASSERT_TRUE(animation_->GetCurrentProgress());
  399. EXPECT_FLOAT_EQ(*animation_->GetCurrentProgress(), GetTimerEndOffset());
  400. EXPECT_TRUE(observer.animation_cycle_ended());
  401. EXPECT_TRUE(HasAnimationEnded());
  402. }
  403. TEST_F(AnimationTest, PausingLinearAnimation) {
  404. constexpr auto kStartTime = base::Milliseconds(400);
  405. constexpr auto kDuration = base::Milliseconds(1000);
  406. TestAnimationObserver observer(animation_.get());
  407. AdvanceClock(base::Milliseconds(200));
  408. animation_->Start(Animation::PlaybackConfig(
  409. {{kStartTime, kStartTime + kDuration}}, /*initial_offset=*/kStartTime,
  410. /*initial_completed_cycles=*/0, Animation::Style::kLinear));
  411. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  412. constexpr auto kAdvance = base::Milliseconds(100);
  413. AdvanceClock(kAdvance);
  414. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  415. ASSERT_TRUE(animation_->GetCurrentProgress());
  416. EXPECT_FLOAT_EQ(*animation_->GetCurrentProgress(),
  417. (kStartTime + kAdvance) / kAnimationDuration);
  418. AdvanceClock(kAdvance);
  419. animation_->Pause();
  420. EXPECT_TRUE(IsPaused());
  421. // Advancing clock and stepping animation should have no effect when animation
  422. // is paused.
  423. AdvanceClock(kAnimationDuration);
  424. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  425. ASSERT_TRUE(animation_->GetCurrentProgress());
  426. EXPECT_FLOAT_EQ(*animation_->GetCurrentProgress(),
  427. (kStartTime + kAdvance) / kAnimationDuration);
  428. // Resume playing the animation.
  429. animation_->ResumePlaying();
  430. EXPECT_TRUE(IsScheduledToResume());
  431. // There should be no progress, since we haven't advanced the clock yet.
  432. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  433. EXPECT_TRUE(IsPlaying());
  434. ASSERT_TRUE(animation_->GetCurrentProgress());
  435. EXPECT_FLOAT_EQ(*animation_->GetCurrentProgress(),
  436. (kStartTime + kAdvance) / kAnimationDuration);
  437. AdvanceClock(kAdvance);
  438. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  439. ASSERT_TRUE(animation_->GetCurrentProgress());
  440. EXPECT_FLOAT_EQ(*animation_->GetCurrentProgress(),
  441. (kStartTime + kAdvance * 2) / kAnimationDuration);
  442. AdvanceClock(kDuration - kAdvance * 2 + base::Milliseconds(1));
  443. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  444. }
  445. TEST_F(AnimationTest, PlayLoopAnimation) {
  446. TestAnimationObserver observer(animation_.get());
  447. AdvanceClock(base::Milliseconds(300));
  448. EXPECT_TRUE(IsStopped());
  449. animation_->Start(Animation::PlaybackConfig::CreateWithStyle(
  450. Animation::Style::kLoop, *animation_));
  451. EXPECT_TRUE(IsScheduledToPlay());
  452. EXPECT_FALSE(observer.animation_will_start_playing());
  453. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  454. EXPECT_FALSE(IsScheduledToPlay());
  455. EXPECT_TRUE(IsPlaying());
  456. EXPECT_TRUE(observer.animation_will_start_playing());
  457. ASSERT_TRUE(animation_->GetCurrentProgress());
  458. EXPECT_FLOAT_EQ(*animation_->GetCurrentProgress(), 0);
  459. EXPECT_FLOAT_EQ(GetTimerStartOffset(), 0);
  460. EXPECT_FLOAT_EQ(GetTimerEndOffset(), 1.0f);
  461. EXPECT_EQ(GetTimerTotalDuration(), kAnimationDuration);
  462. constexpr auto kAdvance = base::Milliseconds(50);
  463. AdvanceClock(kAdvance);
  464. EXPECT_EQ(TimeDeltaSince(GetTimerPreviousTick()), kAdvance);
  465. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  466. ASSERT_TRUE(animation_->GetCurrentProgress());
  467. EXPECT_FLOAT_EQ(*animation_->GetCurrentProgress(),
  468. kAdvance / kAnimationDuration);
  469. EXPECT_EQ(TimeDeltaSince(GetTimerPreviousTick()), base::TimeDelta());
  470. // Advance the clock to the end of the animation.
  471. AdvanceClock(kAnimationDuration - kAdvance);
  472. EXPECT_EQ(TimeDeltaSince(GetTimerPreviousTick()),
  473. kAnimationDuration - kAdvance);
  474. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  475. EXPECT_EQ(GetTimerCycles(), 1);
  476. EXPECT_TRUE(std::abs(*animation_->GetCurrentProgress() - 0.f) < 0.0001f);
  477. EXPECT_TRUE(observer.animation_cycle_ended());
  478. EXPECT_TRUE(IsPlaying());
  479. }
  480. TEST_F(AnimationTest, PlaySubsectionOfLoopAnimation) {
  481. constexpr auto kStartTime = base::Milliseconds(400);
  482. constexpr auto kDuration = base::Milliseconds(1000);
  483. TestAnimationObserver observer(animation_.get());
  484. AdvanceClock(base::Milliseconds(300));
  485. EXPECT_TRUE(IsStopped());
  486. animation_->Start(Animation::PlaybackConfig(
  487. {{kStartTime, kStartTime + kDuration}}, /*initial_offset=*/kStartTime,
  488. /*initial_completed_cycles=*/0, Animation::Style::kLoop));
  489. EXPECT_TRUE(IsScheduledToPlay());
  490. EXPECT_FALSE(observer.animation_will_start_playing());
  491. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  492. EXPECT_FALSE(IsScheduledToPlay());
  493. EXPECT_TRUE(IsPlaying());
  494. EXPECT_TRUE(observer.animation_will_start_playing());
  495. EXPECT_FALSE(observer.animation_cycle_ended());
  496. EXPECT_FLOAT_EQ(GetTimerStartOffset(), kStartTime / kAnimationDuration);
  497. ASSERT_TRUE(animation_->GetCurrentProgress());
  498. EXPECT_FLOAT_EQ(*animation_->GetCurrentProgress(), GetTimerStartOffset());
  499. EXPECT_FLOAT_EQ(GetTimerEndOffset(),
  500. (kStartTime + kDuration) / kAnimationDuration);
  501. EXPECT_EQ(GetTimerTotalDuration(), kAnimationDuration);
  502. constexpr auto kAdvance = base::Milliseconds(100);
  503. AdvanceClock(kAdvance);
  504. EXPECT_EQ(TimeDeltaSince(GetTimerPreviousTick()), kAdvance);
  505. EXPECT_FALSE(observer.animation_cycle_ended());
  506. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  507. EXPECT_EQ(TimeDeltaSince(GetTimerPreviousTick()).InMilliseconds(), 0);
  508. ASSERT_TRUE(animation_->GetCurrentProgress());
  509. EXPECT_FLOAT_EQ(*animation_->GetCurrentProgress(),
  510. (kStartTime + kAdvance) / kAnimationDuration);
  511. constexpr auto kAdvance2 = base::Milliseconds(300);
  512. AdvanceClock(kAdvance2);
  513. EXPECT_EQ(TimeDeltaSince(GetTimerPreviousTick()), kAdvance2);
  514. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  515. EXPECT_EQ(TimeDeltaSince(GetTimerPreviousTick()).InMilliseconds(), 0);
  516. ASSERT_TRUE(animation_->GetCurrentProgress());
  517. EXPECT_FLOAT_EQ(*animation_->GetCurrentProgress(),
  518. (kStartTime + kAdvance + kAdvance2) / kAnimationDuration);
  519. EXPECT_FALSE(observer.animation_cycle_ended());
  520. // Reach the end of animation.
  521. AdvanceClock(kDuration - kAdvance - kAdvance2);
  522. EXPECT_EQ(TimeDeltaSince(GetTimerPreviousTick()),
  523. kDuration - kAdvance - kAdvance2);
  524. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  525. EXPECT_TRUE(observer.animation_cycle_ended());
  526. EXPECT_TRUE(IsPlaying());
  527. ASSERT_TRUE(animation_->GetCurrentProgress());
  528. EXPECT_FLOAT_EQ(*animation_->GetCurrentProgress(), GetTimerStartOffset());
  529. }
  530. TEST_F(AnimationTest, PlayDifferentSubsectionsOfLoopingAnimation) {
  531. constexpr auto kStartTime1 = base::Milliseconds(400);
  532. constexpr auto kDuration1 = base::Milliseconds(1000);
  533. constexpr auto kStartTime2 = base::Milliseconds(100);
  534. constexpr auto kDuration2 = base::Milliseconds(500);
  535. TestAnimationObserver observer(animation_.get());
  536. AdvanceClock(base::Milliseconds(300));
  537. animation_->Start(Animation::PlaybackConfig(
  538. {{kStartTime1, kStartTime1 + kDuration1},
  539. {kStartTime2, kStartTime2 + kDuration2}},
  540. /*initial_offset=*/kStartTime1,
  541. /*initial_completed_cycles=*/0, Animation::Style::kLoop));
  542. // T: 400 ms
  543. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  544. ASSERT_TRUE(animation_->GetCurrentProgress());
  545. EXPECT_FLOAT_EQ(*animation_->GetCurrentProgress(),
  546. kStartTime1 / kAnimationDuration);
  547. // T: 600 ms
  548. AdvanceClock(base::Milliseconds(200));
  549. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  550. ASSERT_TRUE(animation_->GetCurrentProgress());
  551. EXPECT_FLOAT_EQ(*animation_->GetCurrentProgress(),
  552. (kStartTime1 + base::Milliseconds(200)) / kAnimationDuration);
  553. // T: 1399 ms (just before first cycle end)
  554. AdvanceClock(base::Milliseconds(799));
  555. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  556. ASSERT_TRUE(animation_->GetCurrentProgress());
  557. EXPECT_FLOAT_EQ(
  558. *animation_->GetCurrentProgress(),
  559. (kStartTime1 + kDuration1 - base::Milliseconds(1)) / kAnimationDuration);
  560. // T: 100 ms (start of second cycle)
  561. AdvanceClock(base::Milliseconds(1));
  562. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  563. ASSERT_TRUE(animation_->GetCurrentProgress());
  564. EXPECT_FLOAT_EQ(*animation_->GetCurrentProgress(),
  565. kStartTime2 / kAnimationDuration);
  566. // T: 300 ms
  567. AdvanceClock(base::Milliseconds(200));
  568. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  569. ASSERT_TRUE(animation_->GetCurrentProgress());
  570. EXPECT_FLOAT_EQ(*animation_->GetCurrentProgress(),
  571. (kStartTime2 + base::Milliseconds(200)) / kAnimationDuration);
  572. // T: 599 ms (just before second cycle end)
  573. AdvanceClock(base::Milliseconds(299));
  574. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  575. ASSERT_TRUE(animation_->GetCurrentProgress());
  576. EXPECT_FLOAT_EQ(
  577. *animation_->GetCurrentProgress(),
  578. (kStartTime2 + kDuration2 - base::Milliseconds(1)) / kAnimationDuration);
  579. // T: 100 ms (start of second cycle)
  580. AdvanceClock(base::Milliseconds(1));
  581. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  582. ASSERT_TRUE(animation_->GetCurrentProgress());
  583. EXPECT_FLOAT_EQ(*animation_->GetCurrentProgress(),
  584. kStartTime2 / kAnimationDuration);
  585. }
  586. TEST_F(AnimationTest, HandlesLargeStepsInLoopingAnimation) {
  587. constexpr auto kStartTime1 = base::Milliseconds(400);
  588. constexpr auto kDuration1 = base::Milliseconds(1000);
  589. constexpr auto kStartTime2 = base::Milliseconds(100);
  590. constexpr auto kDuration2 = base::Milliseconds(500);
  591. TestAnimationObserver observer(animation_.get());
  592. AdvanceClock(base::Milliseconds(300));
  593. animation_->Start(Animation::PlaybackConfig(
  594. {{kStartTime1, kStartTime1 + kDuration1},
  595. {kStartTime2, kStartTime2 + kDuration2}},
  596. /*initial_offset=*/kStartTime1,
  597. /*initial_completed_cycles=*/0, Animation::Style::kLoop));
  598. // T: 400 ms
  599. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  600. ASSERT_TRUE(animation_->GetCurrentProgress());
  601. EXPECT_FLOAT_EQ(*animation_->GetCurrentProgress(),
  602. kStartTime1 / kAnimationDuration);
  603. // T: 200 ms (end of first cycle + 100 ms into second cycle)
  604. AdvanceClock(kDuration1 + base::Milliseconds(100));
  605. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  606. ASSERT_TRUE(animation_->GetCurrentProgress());
  607. EXPECT_FLOAT_EQ(*animation_->GetCurrentProgress(),
  608. (kStartTime2 + base::Milliseconds(100)) / kAnimationDuration);
  609. // T: 300 ms (end of second cycle + 200 ms into third cycle)
  610. AdvanceClock(base::Milliseconds(600));
  611. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  612. ASSERT_TRUE(animation_->GetCurrentProgress());
  613. EXPECT_FLOAT_EQ(*animation_->GetCurrentProgress(),
  614. (kStartTime2 + base::Milliseconds(200)) / kAnimationDuration);
  615. }
  616. TEST_F(AnimationTest, PausingLoopAnimation) {
  617. constexpr auto kStartTime = base::Milliseconds(400);
  618. constexpr auto kDuration = base::Milliseconds(1000);
  619. TestAnimationObserver observer(animation_.get());
  620. AdvanceClock(base::Milliseconds(200));
  621. animation_->Start(Animation::PlaybackConfig(
  622. {{kStartTime, kStartTime + kDuration}}, /*initial_offset=*/kStartTime,
  623. /*initial_completed_cycles=*/0, Animation::Style::kLoop));
  624. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  625. ASSERT_TRUE(animation_->GetCurrentProgress());
  626. EXPECT_FLOAT_EQ(*animation_->GetCurrentProgress(),
  627. kStartTime / kAnimationDuration);
  628. constexpr auto kAdvance = base::Milliseconds(100);
  629. AdvanceClock(kAdvance);
  630. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  631. ASSERT_TRUE(animation_->GetCurrentProgress());
  632. EXPECT_FLOAT_EQ(*animation_->GetCurrentProgress(),
  633. (kStartTime + kAdvance) / kAnimationDuration);
  634. AdvanceClock(kAdvance);
  635. animation_->Pause();
  636. EXPECT_TRUE(IsPaused());
  637. // Advancing clock and stepping animation should have no effect when animation
  638. // is paused.
  639. AdvanceClock(kAnimationDuration);
  640. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  641. ASSERT_TRUE(animation_->GetCurrentProgress());
  642. EXPECT_FLOAT_EQ(*animation_->GetCurrentProgress(),
  643. (kStartTime + kAdvance) / kAnimationDuration);
  644. // Resume playing the animation.
  645. animation_->ResumePlaying();
  646. EXPECT_TRUE(IsScheduledToResume());
  647. // There should be no progress, since we haven't advanced the clock yet.
  648. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  649. EXPECT_TRUE(IsPlaying());
  650. ASSERT_TRUE(animation_->GetCurrentProgress());
  651. EXPECT_FLOAT_EQ(*animation_->GetCurrentProgress(),
  652. (kStartTime + kAdvance) / kAnimationDuration);
  653. AdvanceClock(kAdvance);
  654. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  655. ASSERT_TRUE(animation_->GetCurrentProgress());
  656. EXPECT_FLOAT_EQ(*animation_->GetCurrentProgress(),
  657. (kStartTime + kAdvance * 2) / kAnimationDuration);
  658. EXPECT_FALSE(observer.animation_cycle_ended());
  659. AdvanceClock(kDuration - kAdvance * 2);
  660. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  661. ASSERT_TRUE(animation_->GetCurrentProgress());
  662. EXPECT_FLOAT_EQ(*animation_->GetCurrentProgress(), GetTimerStartOffset());
  663. EXPECT_TRUE(IsPlaying());
  664. EXPECT_TRUE(observer.animation_cycle_ended());
  665. }
  666. TEST_F(AnimationTest, PlayThrobbingAnimation) {
  667. TestAnimationObserver observer(animation_.get());
  668. AdvanceClock(base::Milliseconds(300));
  669. animation_->Start(Animation::PlaybackConfig::CreateWithStyle(
  670. Animation::Style::kThrobbing, *animation_));
  671. EXPECT_TRUE(IsScheduledToPlay());
  672. EXPECT_FALSE(observer.animation_will_start_playing());
  673. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  674. EXPECT_FALSE(IsScheduledToPlay());
  675. EXPECT_TRUE(IsPlaying());
  676. EXPECT_TRUE(observer.animation_will_start_playing());
  677. ASSERT_TRUE(animation_->GetCurrentProgress());
  678. EXPECT_FLOAT_EQ(*animation_->GetCurrentProgress(), 0);
  679. EXPECT_FLOAT_EQ(GetTimerStartOffset(), 0);
  680. EXPECT_FLOAT_EQ(GetTimerEndOffset(), 1.0f);
  681. EXPECT_EQ(GetTimerTotalDuration(), kAnimationDuration);
  682. constexpr auto kAdvance = base::Milliseconds(50);
  683. AdvanceClock(kAdvance);
  684. EXPECT_EQ(TimeDeltaSince(GetTimerPreviousTick()), kAdvance);
  685. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  686. ASSERT_TRUE(animation_->GetCurrentProgress());
  687. EXPECT_FLOAT_EQ(*animation_->GetCurrentProgress(),
  688. kAdvance / kAnimationDuration);
  689. EXPECT_EQ(TimeDeltaSince(GetTimerPreviousTick()), base::TimeDelta());
  690. // Advance the clock to the end of the animation.
  691. AdvanceClock(kAnimationDuration - kAdvance);
  692. EXPECT_EQ(TimeDeltaSince(GetTimerPreviousTick()),
  693. kAnimationDuration - kAdvance);
  694. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  695. ASSERT_TRUE(animation_->GetCurrentProgress());
  696. EXPECT_FLOAT_EQ(*animation_->GetCurrentProgress(), 1.0f);
  697. EXPECT_TRUE(IsPlaying());
  698. EXPECT_FALSE(observer.animation_cycle_ended());
  699. AdvanceClock(kAnimationDuration / 2);
  700. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  701. ASSERT_TRUE(animation_->GetCurrentProgress());
  702. EXPECT_FLOAT_EQ(*animation_->GetCurrentProgress(), 0.5f);
  703. EXPECT_TRUE(IsPlaying());
  704. EXPECT_FALSE(observer.animation_cycle_ended());
  705. AdvanceClock(kAnimationDuration / 2);
  706. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  707. ASSERT_TRUE(animation_->GetCurrentProgress());
  708. EXPECT_FLOAT_EQ(*animation_->GetCurrentProgress(), 0);
  709. EXPECT_TRUE(IsPlaying());
  710. EXPECT_TRUE(observer.animation_cycle_ended());
  711. }
  712. TEST_F(AnimationTest, PlaySubsectionOfThrobbingAnimation) {
  713. constexpr auto kStartTime = base::Milliseconds(400);
  714. constexpr auto kDuration = base::Milliseconds(1000);
  715. TestAnimationObserver observer(animation_.get());
  716. AdvanceClock(base::Milliseconds(300));
  717. animation_->Start(Animation::PlaybackConfig(
  718. {{kStartTime, kStartTime + kDuration}}, /*initial_offset=*/kStartTime,
  719. /*initial_completed_cycles=*/0, Animation::Style::kThrobbing));
  720. EXPECT_TRUE(IsScheduledToPlay());
  721. EXPECT_FALSE(observer.animation_will_start_playing());
  722. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  723. EXPECT_FALSE(IsScheduledToPlay());
  724. EXPECT_TRUE(IsPlaying());
  725. EXPECT_TRUE(observer.animation_will_start_playing());
  726. EXPECT_FLOAT_EQ(GetTimerStartOffset(), kStartTime / kAnimationDuration);
  727. ASSERT_TRUE(animation_->GetCurrentProgress());
  728. EXPECT_FLOAT_EQ(*animation_->GetCurrentProgress(), GetTimerStartOffset());
  729. EXPECT_FLOAT_EQ(GetTimerEndOffset(),
  730. (kStartTime + kDuration) / kAnimationDuration);
  731. EXPECT_EQ(GetTimerTotalDuration(), kAnimationDuration);
  732. constexpr auto kAdvance = base::Milliseconds(100);
  733. AdvanceClock(kAdvance);
  734. EXPECT_EQ(TimeDeltaSince(GetTimerPreviousTick()), kAdvance);
  735. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  736. EXPECT_FALSE(observer.animation_cycle_ended());
  737. EXPECT_EQ(TimeDeltaSince(GetTimerPreviousTick()).InMilliseconds(), 0);
  738. ASSERT_TRUE(animation_->GetCurrentProgress());
  739. EXPECT_FLOAT_EQ(*animation_->GetCurrentProgress(),
  740. (kStartTime + kAdvance) / kAnimationDuration);
  741. constexpr auto kAdvance2 = base::Milliseconds(300);
  742. AdvanceClock(kAdvance2);
  743. EXPECT_EQ(TimeDeltaSince(GetTimerPreviousTick()), kAdvance2);
  744. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  745. EXPECT_FALSE(observer.animation_cycle_ended());
  746. EXPECT_EQ(TimeDeltaSince(GetTimerPreviousTick()), base::TimeDelta());
  747. ASSERT_TRUE(animation_->GetCurrentProgress());
  748. EXPECT_FLOAT_EQ(*animation_->GetCurrentProgress(),
  749. (kStartTime + kAdvance + kAdvance2) / kAnimationDuration);
  750. // Reach the end of animation.
  751. AdvanceClock(kDuration - kAdvance - kAdvance2);
  752. EXPECT_EQ(TimeDeltaSince(GetTimerPreviousTick()),
  753. kDuration - kAdvance - kAdvance2);
  754. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  755. EXPECT_TRUE(IsPlaying());
  756. ASSERT_TRUE(animation_->GetCurrentProgress());
  757. EXPECT_FLOAT_EQ(*animation_->GetCurrentProgress(), GetTimerEndOffset());
  758. EXPECT_FALSE(observer.animation_cycle_ended());
  759. constexpr auto kAdvance3 = base::Milliseconds(500);
  760. AdvanceClock(kAdvance3);
  761. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  762. ASSERT_TRUE(animation_->GetCurrentProgress());
  763. EXPECT_FLOAT_EQ(*animation_->GetCurrentProgress(),
  764. (kStartTime + kDuration - kAdvance3) / kAnimationDuration);
  765. EXPECT_TRUE(IsPlaying());
  766. EXPECT_FALSE(observer.animation_cycle_ended());
  767. AdvanceClock(kDuration - kAdvance3);
  768. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  769. ASSERT_TRUE(animation_->GetCurrentProgress());
  770. EXPECT_FLOAT_EQ(*animation_->GetCurrentProgress(), GetTimerStartOffset());
  771. EXPECT_TRUE(IsPlaying());
  772. EXPECT_TRUE(observer.animation_cycle_ended());
  773. observer.Reset();
  774. AdvanceClock(kAdvance);
  775. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  776. ASSERT_TRUE(animation_->GetCurrentProgress());
  777. EXPECT_FLOAT_EQ(*animation_->GetCurrentProgress(),
  778. (kStartTime + kAdvance) / kAnimationDuration);
  779. EXPECT_TRUE(IsPlaying());
  780. }
  781. TEST_F(AnimationTest, PlayDifferentSubsectionsOfThrobbingAnimation) {
  782. constexpr auto kStartTime1 = base::Milliseconds(400);
  783. constexpr auto kDuration1 = base::Milliseconds(1000);
  784. constexpr auto kStartTime2 = base::Milliseconds(100);
  785. constexpr auto kDuration2 = base::Milliseconds(500);
  786. TestAnimationObserver observer(animation_.get());
  787. AdvanceClock(base::Milliseconds(300));
  788. animation_->Start(Animation::PlaybackConfig(
  789. {{kStartTime1, kStartTime1 + kDuration1},
  790. {kStartTime2, kStartTime2 + kDuration2}},
  791. /*initial_offset=*/kStartTime1,
  792. /*initial_completed_cycles=*/0, Animation::Style::kThrobbing));
  793. // T: 400 ms
  794. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  795. ASSERT_TRUE(animation_->GetCurrentProgress());
  796. EXPECT_FLOAT_EQ(*animation_->GetCurrentProgress(),
  797. kStartTime1 / kAnimationDuration);
  798. // T: 600 ms
  799. AdvanceClock(base::Milliseconds(200));
  800. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  801. ASSERT_TRUE(animation_->GetCurrentProgress());
  802. EXPECT_FLOAT_EQ(*animation_->GetCurrentProgress(),
  803. (kStartTime1 + base::Milliseconds(200)) / kAnimationDuration);
  804. // T: 1399 ms (just before first cycle end)
  805. AdvanceClock(base::Milliseconds(799));
  806. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  807. ASSERT_TRUE(animation_->GetCurrentProgress());
  808. EXPECT_FLOAT_EQ(
  809. *animation_->GetCurrentProgress(),
  810. (kStartTime1 + kDuration1 - base::Milliseconds(1)) / kAnimationDuration);
  811. // T: 600 ms (end of second cycle, reversed)
  812. AdvanceClock(base::Milliseconds(1));
  813. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  814. ASSERT_TRUE(animation_->GetCurrentProgress());
  815. EXPECT_FLOAT_EQ(*animation_->GetCurrentProgress(),
  816. (kStartTime2 + kDuration2) / kAnimationDuration);
  817. // T: 400 ms
  818. AdvanceClock(base::Milliseconds(200));
  819. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  820. ASSERT_TRUE(animation_->GetCurrentProgress());
  821. EXPECT_FLOAT_EQ(*animation_->GetCurrentProgress(),
  822. (kStartTime2 + kDuration2 - base::Milliseconds(200)) /
  823. kAnimationDuration);
  824. // T: 101 ms (just after start of second cycle start)
  825. AdvanceClock(base::Milliseconds(299));
  826. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  827. ASSERT_TRUE(animation_->GetCurrentProgress());
  828. EXPECT_FLOAT_EQ(*animation_->GetCurrentProgress(),
  829. (kStartTime2 + base::Milliseconds(1)) / kAnimationDuration);
  830. // T: 100 ms (start of second cycle)
  831. AdvanceClock(base::Milliseconds(1));
  832. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  833. ASSERT_TRUE(animation_->GetCurrentProgress());
  834. EXPECT_FLOAT_EQ(*animation_->GetCurrentProgress(),
  835. kStartTime2 / kAnimationDuration);
  836. // T: 300 ms (going forward)
  837. AdvanceClock(base::Milliseconds(200));
  838. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  839. ASSERT_TRUE(animation_->GetCurrentProgress());
  840. EXPECT_FLOAT_EQ(*animation_->GetCurrentProgress(),
  841. (kStartTime2 + base::Milliseconds(200)) / kAnimationDuration);
  842. }
  843. TEST_F(AnimationTest, HandlesLargeStepsInThrobbingAnimation) {
  844. constexpr auto kStartTime1 = base::Milliseconds(400);
  845. constexpr auto kDuration1 = base::Milliseconds(1000);
  846. constexpr auto kStartTime2 = base::Milliseconds(100);
  847. constexpr auto kDuration2 = base::Milliseconds(500);
  848. TestAnimationObserver observer(animation_.get());
  849. AdvanceClock(base::Milliseconds(300));
  850. animation_->Start(Animation::PlaybackConfig(
  851. {{kStartTime1, kStartTime1 + kDuration1},
  852. {kStartTime2, kStartTime2 + kDuration2}},
  853. /*initial_offset=*/kStartTime1,
  854. /*initial_completed_cycles=*/0, Animation::Style::kThrobbing));
  855. // T: 400 ms
  856. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  857. ASSERT_TRUE(animation_->GetCurrentProgress());
  858. EXPECT_FLOAT_EQ(*animation_->GetCurrentProgress(),
  859. kStartTime1 / kAnimationDuration);
  860. // T: 500 ms (end of first cycle + 100 ms into second cycle)
  861. AdvanceClock(kDuration1 + base::Milliseconds(100));
  862. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  863. ASSERT_TRUE(animation_->GetCurrentProgress());
  864. EXPECT_FLOAT_EQ(*animation_->GetCurrentProgress(),
  865. (kStartTime2 + kDuration2 - base::Milliseconds(100)) /
  866. kAnimationDuration);
  867. // T: 300 ms (end of second cycle + 200 ms into third cycle)
  868. AdvanceClock(base::Milliseconds(600));
  869. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  870. ASSERT_TRUE(animation_->GetCurrentProgress());
  871. EXPECT_FLOAT_EQ(*animation_->GetCurrentProgress(),
  872. (kStartTime2 + base::Milliseconds(200)) / kAnimationDuration);
  873. }
  874. TEST_F(AnimationTest, PausingThrobbingAnimation) {
  875. constexpr auto kStartTime = base::Milliseconds(400);
  876. constexpr auto kDuration = base::Milliseconds(1000);
  877. AdvanceClock(base::Milliseconds(200));
  878. animation_->Start(Animation::PlaybackConfig(
  879. {{kStartTime, kStartTime + kDuration}}, /*initial_offset=*/kStartTime,
  880. /*initial_completed_cycles=*/0, Animation::Style::kThrobbing));
  881. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  882. EXPECT_TRUE(IsPlaying());
  883. ASSERT_TRUE(animation_->GetCurrentProgress());
  884. EXPECT_FLOAT_EQ(*animation_->GetCurrentProgress(),
  885. kStartTime / kAnimationDuration);
  886. constexpr auto kAdvance = base::Milliseconds(100);
  887. AdvanceClock(kAdvance);
  888. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  889. ASSERT_TRUE(animation_->GetCurrentProgress());
  890. EXPECT_FLOAT_EQ(*animation_->GetCurrentProgress(),
  891. (kStartTime + kAdvance) / kAnimationDuration);
  892. AdvanceClock(kAdvance);
  893. animation_->Pause();
  894. EXPECT_TRUE(IsPaused());
  895. // Advancing clock and stepping animation should have no effect when animation
  896. // is paused.
  897. AdvanceClock(kAnimationDuration);
  898. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  899. ASSERT_TRUE(animation_->GetCurrentProgress());
  900. EXPECT_FLOAT_EQ(*animation_->GetCurrentProgress(),
  901. (kStartTime + kAdvance) / kAnimationDuration);
  902. // Resume playing the animation.
  903. animation_->ResumePlaying();
  904. EXPECT_TRUE(IsScheduledToResume());
  905. // There should be no progress, since we haven't advanced the clock yet.
  906. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  907. EXPECT_TRUE(IsPlaying());
  908. ASSERT_TRUE(animation_->GetCurrentProgress());
  909. EXPECT_FLOAT_EQ(*animation_->GetCurrentProgress(),
  910. (kStartTime + kAdvance) / kAnimationDuration);
  911. AdvanceClock(kAdvance);
  912. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  913. ASSERT_TRUE(animation_->GetCurrentProgress());
  914. EXPECT_FLOAT_EQ(*animation_->GetCurrentProgress(),
  915. (kStartTime + kAdvance * 2) / kAnimationDuration);
  916. AdvanceClock(kDuration - kAdvance * 2);
  917. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  918. ASSERT_TRUE(animation_->GetCurrentProgress());
  919. EXPECT_FLOAT_EQ(*animation_->GetCurrentProgress(), GetTimerEndOffset());
  920. EXPECT_TRUE(IsPlaying());
  921. AdvanceClock(kAdvance);
  922. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  923. ASSERT_TRUE(animation_->GetCurrentProgress());
  924. EXPECT_FLOAT_EQ(*animation_->GetCurrentProgress(),
  925. (kStartTime + kDuration - kAdvance) / kAnimationDuration);
  926. EXPECT_TRUE(IsPlaying());
  927. animation_->Pause();
  928. EXPECT_TRUE(IsPaused());
  929. AdvanceClock(kAnimationDuration * 2);
  930. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  931. ASSERT_TRUE(animation_->GetCurrentProgress());
  932. EXPECT_FLOAT_EQ(*animation_->GetCurrentProgress(),
  933. (kStartTime + kDuration - kAdvance) / kAnimationDuration);
  934. // Resume playing the animation.
  935. animation_->ResumePlaying();
  936. EXPECT_TRUE(IsScheduledToResume());
  937. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  938. EXPECT_TRUE(IsPlaying());
  939. constexpr auto kAdvance2 = base::Milliseconds(500);
  940. AdvanceClock(kAdvance2);
  941. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  942. EXPECT_FLOAT_EQ(
  943. *animation_->GetCurrentProgress(),
  944. (kStartTime + kDuration - kAdvance - kAdvance2) / kAnimationDuration);
  945. AdvanceClock(kDuration - kAdvance - kAdvance2);
  946. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  947. ASSERT_TRUE(animation_->GetCurrentProgress());
  948. EXPECT_FLOAT_EQ(*animation_->GetCurrentProgress(), GetTimerStartOffset());
  949. AdvanceClock(kAdvance);
  950. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  951. ASSERT_TRUE(animation_->GetCurrentProgress());
  952. EXPECT_FLOAT_EQ(*animation_->GetCurrentProgress(),
  953. (kStartTime + kAdvance) / kAnimationDuration);
  954. EXPECT_TRUE(IsPlaying());
  955. }
  956. // Test to see if the race condition is handled correctly. It may happen that we
  957. // pause the video before it even starts playing.
  958. TEST_F(AnimationTest, PauseBeforePlay) {
  959. TestAnimationObserver observer(animation_.get());
  960. AdvanceClock(base::Milliseconds(300));
  961. animation_->Start();
  962. EXPECT_TRUE(IsScheduledToPlay());
  963. EXPECT_FALSE(animation_->GetCurrentProgress());
  964. animation_->Pause();
  965. EXPECT_TRUE(IsPaused());
  966. EXPECT_FALSE(animation_->GetCurrentProgress());
  967. AdvanceClock(base::Milliseconds(100));
  968. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  969. ASSERT_TRUE(animation_->GetCurrentProgress());
  970. EXPECT_FLOAT_EQ(*animation_->GetCurrentProgress(), GetTimerStartOffset());
  971. animation_->ResumePlaying();
  972. EXPECT_TRUE(IsScheduledToResume());
  973. AdvanceClock(base::Milliseconds(100));
  974. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  975. EXPECT_TRUE(IsPlaying());
  976. ASSERT_TRUE(animation_->GetCurrentProgress());
  977. EXPECT_FLOAT_EQ(*animation_->GetCurrentProgress(), GetTimerStartOffset());
  978. constexpr auto kAdvance = base::Milliseconds(100);
  979. AdvanceClock(kAdvance);
  980. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  981. ASSERT_TRUE(animation_->GetCurrentProgress());
  982. EXPECT_FLOAT_EQ(*animation_->GetCurrentProgress(),
  983. kAdvance / kAnimationDuration);
  984. }
  985. TEST_F(AnimationTest, PaintTest) {
  986. gfx::Canvas canvas(gfx::Size(kAnimationWidth, kAnimationHeight), 1.f, false);
  987. AdvanceClock(base::Milliseconds(300));
  988. animation_->Start(Animation::PlaybackConfig::CreateWithStyle(
  989. Animation::Style::kLinear, *animation_));
  990. animation_->Paint(&canvas, NowTicks(), animation_->GetOriginalSize());
  991. AdvanceClock(base::Milliseconds(50));
  992. animation_->Paint(&canvas, NowTicks(), animation_->GetOriginalSize());
  993. IsAllSameColor(SK_ColorGREEN, canvas.GetBitmap());
  994. AdvanceClock(base::Milliseconds(2450));
  995. animation_->Paint(&canvas, NowTicks(), animation_->GetOriginalSize());
  996. IsAllSameColor(SK_ColorGREEN, canvas.GetBitmap());
  997. AdvanceClock(base::Milliseconds(50));
  998. animation_->Paint(&canvas, NowTicks(), animation_->GetOriginalSize());
  999. IsAllSameColor(SK_ColorBLUE, canvas.GetBitmap());
  1000. AdvanceClock(base::Milliseconds(1000));
  1001. animation_->Paint(&canvas, NowTicks(), animation_->GetOriginalSize());
  1002. IsAllSameColor(SK_ColorBLUE, canvas.GetBitmap());
  1003. AdvanceClock(base::Milliseconds(1400));
  1004. animation_->Paint(&canvas, NowTicks(), animation_->GetOriginalSize());
  1005. IsAllSameColor(SK_ColorBLUE, canvas.GetBitmap());
  1006. }
  1007. TEST_F(AnimationTest, NotifiesObserverFramePainted) {
  1008. TestAnimationObserver observer(animation_.get());
  1009. AdvanceClock(base::Milliseconds(300));
  1010. animation_->Start(Animation::PlaybackConfig::CreateWithStyle(
  1011. Animation::Style::kLoop, *animation_));
  1012. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  1013. ASSERT_TRUE(observer.last_frame_painted());
  1014. EXPECT_EQ(*observer.last_frame_painted(), 0.f);
  1015. AdvanceClock(kAnimationDuration / 4);
  1016. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  1017. ASSERT_TRUE(observer.last_frame_painted());
  1018. EXPECT_FLOAT_EQ(*observer.last_frame_painted(), 0.25f);
  1019. AdvanceClock(kAnimationDuration / 4);
  1020. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  1021. ASSERT_TRUE(observer.last_frame_painted());
  1022. EXPECT_FLOAT_EQ(*observer.last_frame_painted(), 0.5f);
  1023. AdvanceClock(kAnimationDuration / 2 - base::Milliseconds(1));
  1024. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  1025. ASSERT_TRUE(observer.last_frame_painted());
  1026. EXPECT_NEAR(*observer.last_frame_painted(), 1.f, 1E-3);
  1027. AdvanceClock(base::Milliseconds(2));
  1028. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  1029. ASSERT_TRUE(observer.last_frame_painted());
  1030. EXPECT_FLOAT_EQ(*observer.last_frame_painted(),
  1031. base::Milliseconds(1) / kAnimationDuration);
  1032. }
  1033. TEST_F(AnimationTest, SetsPlaybackSpeed) {
  1034. TestAnimationObserver observer(animation_.get());
  1035. AdvanceClock(base::Milliseconds(300));
  1036. animation_->SetPlaybackSpeed(2);
  1037. animation_->Start(Animation::PlaybackConfig::CreateWithStyle(
  1038. Animation::Style::kLinear, *animation_));
  1039. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  1040. ASSERT_TRUE(animation_->GetCurrentProgress());
  1041. EXPECT_FLOAT_EQ(*animation_->GetCurrentProgress(), 0);
  1042. AdvanceClock(kAnimationDuration / 8);
  1043. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  1044. ASSERT_TRUE(animation_->GetCurrentProgress());
  1045. EXPECT_FLOAT_EQ(*animation_->GetCurrentProgress(), 1.f / 4);
  1046. AdvanceClock(kAnimationDuration / 8);
  1047. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  1048. ASSERT_TRUE(animation_->GetCurrentProgress());
  1049. EXPECT_FLOAT_EQ(*animation_->GetCurrentProgress(), 1.f / 2);
  1050. animation_->SetPlaybackSpeed(0.5f);
  1051. AdvanceClock(kAnimationDuration / 4);
  1052. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  1053. ASSERT_TRUE(animation_->GetCurrentProgress());
  1054. EXPECT_FLOAT_EQ(*animation_->GetCurrentProgress(), (1.f / 2) + (1.f / 8));
  1055. AdvanceClock(kAnimationDuration / 4);
  1056. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  1057. ASSERT_TRUE(animation_->GetCurrentProgress());
  1058. EXPECT_FLOAT_EQ(*animation_->GetCurrentProgress(), 3.f / 4);
  1059. }
  1060. TEST_F(AnimationWithImageAssetsTest, PaintsAnimationImagesToCanvas) {
  1061. AdvanceClock(base::Milliseconds(300));
  1062. animation_->Start(Animation::PlaybackConfig::CreateWithStyle(
  1063. Animation::Style::kLoop, *animation_));
  1064. TestSkottieFrameDataProvider::ImageAssetImpl* asset_0 =
  1065. frame_data_provider_.GetLoadedImageAsset("image_0");
  1066. TestSkottieFrameDataProvider::ImageAssetImpl* asset_1 =
  1067. frame_data_provider_.GetLoadedImageAsset("image_1");
  1068. ASSERT_THAT(asset_0, NotNull());
  1069. ASSERT_THAT(asset_1, NotNull());
  1070. cc::SkottieFrameData frame_0 = CreateHighQualityTestFrameData();
  1071. cc::SkottieFrameData frame_1 = CreateHighQualityTestFrameData();
  1072. asset_0->set_current_frame_data(frame_0);
  1073. asset_1->set_current_frame_data(frame_1);
  1074. display_list_->StartPaint();
  1075. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  1076. display_list_->EndPaintOfUnpaired(gfx::Rect(animation_->GetOriginalSize()));
  1077. sk_sp<cc::PaintRecord> paint_record = display_list_->ReleaseAsRecord();
  1078. ASSERT_THAT(paint_record, NotNull());
  1079. ASSERT_THAT(paint_record->size(), Eq(1u));
  1080. const cc::DrawSkottieOp* op =
  1081. paint_record->GetOpAtForTesting<cc::DrawSkottieOp>(0);
  1082. ASSERT_THAT(op, NotNull());
  1083. EXPECT_THAT(op->images, UnorderedElementsAre(Pair(
  1084. cc::HashSkottieResourceId("image_0"), frame_0)));
  1085. AdvanceClock(animation_->GetAnimationDuration() * .75);
  1086. display_list_->StartPaint();
  1087. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  1088. display_list_->EndPaintOfUnpaired(gfx::Rect(animation_->GetOriginalSize()));
  1089. paint_record = display_list_->ReleaseAsRecord();
  1090. ASSERT_THAT(paint_record, NotNull());
  1091. ASSERT_THAT(paint_record->size(), Eq(1u));
  1092. op = paint_record->GetOpAtForTesting<cc::DrawSkottieOp>(0);
  1093. ASSERT_THAT(op, NotNull());
  1094. EXPECT_THAT(op->images, UnorderedElementsAre(Pair(
  1095. cc::HashSkottieResourceId("image_1"), frame_1)));
  1096. }
  1097. TEST_F(AnimationWithImageAssetsTest, GracefullyHandlesNullImages) {
  1098. AdvanceClock(base::Milliseconds(300));
  1099. animation_->Start(Animation::PlaybackConfig::CreateWithStyle(
  1100. Animation::Style::kLoop, *animation_));
  1101. display_list_->StartPaint();
  1102. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  1103. display_list_->EndPaintOfUnpaired(gfx::Rect(animation_->GetOriginalSize()));
  1104. sk_sp<cc::PaintRecord> paint_record = display_list_->ReleaseAsRecord();
  1105. ASSERT_THAT(paint_record, NotNull());
  1106. ASSERT_THAT(paint_record->size(), Eq(1u));
  1107. const cc::DrawSkottieOp* op =
  1108. paint_record->GetOpAtForTesting<cc::DrawSkottieOp>(0);
  1109. ASSERT_THAT(op, NotNull());
  1110. EXPECT_THAT(op->images,
  1111. UnorderedElementsAre(Pair(cc::HashSkottieResourceId("image_0"),
  1112. cc::SkottieFrameData())));
  1113. }
  1114. TEST_F(AnimationWithImageAssetsTest, LoadsCorrectFrameTimestamp) {
  1115. AdvanceClock(base::Milliseconds(300));
  1116. animation_->Start(Animation::PlaybackConfig::CreateWithStyle(
  1117. Animation::Style::kLoop, *animation_));
  1118. asset_0_->set_current_frame_data(CreateHighQualityTestFrameData());
  1119. asset_1_->set_current_frame_data(CreateHighQualityTestFrameData());
  1120. display_list_->StartPaint();
  1121. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  1122. display_list_->EndPaintOfUnpaired(gfx::Rect(animation_->GetOriginalSize()));
  1123. ASSERT_TRUE(asset_0_->last_frame_t().has_value());
  1124. EXPECT_THAT(asset_0_->last_frame_t().value(), FloatEq(0));
  1125. base::TimeDelta three_quarter_duration =
  1126. animation_->GetAnimationDuration() * .75;
  1127. AdvanceClock(three_quarter_duration);
  1128. display_list_->StartPaint();
  1129. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  1130. display_list_->EndPaintOfUnpaired(gfx::Rect(animation_->GetOriginalSize()));
  1131. // The timestamp is "relative to the image layer timeline origin" (see
  1132. // SkResources.h). The test animation used in this case has 2 layers for the
  1133. // first and second halves of the animation. So the 3/4 point of the animation
  1134. // is half way into the second layer, or 1/4 the duration of the whole
  1135. // animation.
  1136. base::TimeDelta half_duration = animation_->GetAnimationDuration() * .5;
  1137. ASSERT_TRUE(asset_1_->last_frame_t().has_value());
  1138. EXPECT_THAT(asset_1_->last_frame_t().value(),
  1139. FloatNear((three_quarter_duration - half_duration).InSecondsF(),
  1140. kFrameTimestampToleranceSec));
  1141. AdvanceClock(half_duration);
  1142. display_list_->StartPaint();
  1143. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  1144. display_list_->EndPaintOfUnpaired(gfx::Rect(animation_->GetOriginalSize()));
  1145. base::TimeDelta quarter_duration = animation_->GetAnimationDuration() / 4;
  1146. ASSERT_TRUE(asset_0_->last_frame_t().has_value());
  1147. EXPECT_THAT(
  1148. asset_0_->last_frame_t().value(),
  1149. FloatNear(quarter_duration.InSecondsF(), kFrameTimestampToleranceSec));
  1150. }
  1151. TEST_F(AnimationWithImageAssetsTest, LoadsCorrectImageScale) {
  1152. AdvanceClock(base::Milliseconds(300));
  1153. animation_->Start(Animation::PlaybackConfig::CreateWithStyle(
  1154. Animation::Style::kLoop, *animation_));
  1155. asset_0_->set_current_frame_data(CreateHighQualityTestFrameData());
  1156. display_list_->StartPaint();
  1157. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  1158. display_list_->EndPaintOfUnpaired(gfx::Rect(animation_->GetOriginalSize()));
  1159. ASSERT_TRUE(asset_0_->last_frame_scale_factor().has_value());
  1160. EXPECT_THAT(asset_0_->last_frame_scale_factor().value(),
  1161. FloatEq(kCanvasImageScale));
  1162. }
  1163. TEST_F(AnimationTest, HandlesTimeStepGreaterThanAnimationDuration) {
  1164. AdvanceClock(base::Milliseconds(300));
  1165. animation_->Start(Animation::PlaybackConfig::CreateWithStyle(
  1166. Animation::Style::kLoop, *animation_));
  1167. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  1168. ASSERT_FLOAT_EQ(*animation_->GetCurrentProgress(), 0);
  1169. AdvanceClock(kAnimationDuration / 2);
  1170. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  1171. ASSERT_TRUE(animation_->GetCurrentProgress());
  1172. EXPECT_FLOAT_EQ(*animation_->GetCurrentProgress(), 0.5f);
  1173. AdvanceClock(kAnimationDuration * 5);
  1174. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  1175. ASSERT_TRUE(animation_->GetCurrentProgress());
  1176. EXPECT_FLOAT_EQ(*animation_->GetCurrentProgress(), 0.5f);
  1177. }
  1178. class AnimationRestarter : public AnimationObserver {
  1179. public:
  1180. explicit AnimationRestarter(Animation* animation) : animation_(animation) {
  1181. observation_.Observe(animation);
  1182. }
  1183. AnimationRestarter(const AnimationRestarter&) = delete;
  1184. AnimationRestarter& operator=(const AnimationRestarter&) = delete;
  1185. ~AnimationRestarter() override = default;
  1186. void AnimationCycleEnded(const Animation* animation) override {
  1187. animation_->Stop();
  1188. animation_->Start(Animation::PlaybackConfig::CreateWithStyle(
  1189. Animation::Style::kLinear, *animation_));
  1190. }
  1191. private:
  1192. const base::raw_ptr<Animation> animation_;
  1193. base::ScopedObservation<Animation, AnimationObserver> observation_{this};
  1194. };
  1195. TEST_F(AnimationTest, HandlesChangingAnimationStateWithinObserverCall) {
  1196. AnimationRestarter observer(animation_.get());
  1197. AdvanceClock(base::Milliseconds(300));
  1198. animation_->Start(Animation::PlaybackConfig::CreateWithStyle(
  1199. Animation::Style::kLinear, *animation_));
  1200. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  1201. // Advance the clock to the end of the animation.
  1202. constexpr auto kAdvanceToEnd = kAnimationDuration + base::Milliseconds(1);
  1203. AdvanceClock(kAdvanceToEnd);
  1204. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  1205. // The AnimationRestarter should have restarted the animation again from the
  1206. // beginning.
  1207. constexpr auto kAdvance = base::Milliseconds(50);
  1208. AdvanceClock(kAdvance);
  1209. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  1210. ASSERT_TRUE(animation_->GetCurrentProgress());
  1211. EXPECT_FLOAT_EQ(*animation_->GetCurrentProgress(), 0.f);
  1212. AdvanceClock(kAdvance);
  1213. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  1214. ASSERT_TRUE(animation_->GetCurrentProgress());
  1215. EXPECT_FLOAT_EQ(*animation_->GetCurrentProgress(),
  1216. kAdvance / kAnimationDuration);
  1217. }
  1218. TEST_F(AnimationTest, NotifiesAnimationIsDeleting) {
  1219. TestAnimationObserver observer_1(animation_.get());
  1220. TestAnimationObserver observer_2(animation_.get());
  1221. ASSERT_FALSE(observer_1.animation_is_deleted());
  1222. ASSERT_FALSE(observer_2.animation_is_deleted());
  1223. animation_.reset();
  1224. EXPECT_TRUE(observer_1.animation_is_deleted());
  1225. EXPECT_TRUE(observer_2.animation_is_deleted());
  1226. }
  1227. TEST_F(AnimationTest, GetPlaybackConfig) {
  1228. EXPECT_FALSE(animation_->GetPlaybackConfig());
  1229. Animation::PlaybackConfig test_config(
  1230. {{/*start_offset=*/kAnimationDuration / 4,
  1231. /*end_offset=*/kAnimationDuration * 3 / 4}},
  1232. /*initial_offset=*/kAnimationDuration / 2,
  1233. /*initial_completed_cycles=*/2, Animation::Style::kThrobbing);
  1234. animation_->Start(test_config);
  1235. ASSERT_TRUE(animation_->GetPlaybackConfig());
  1236. EXPECT_THAT(
  1237. *animation_->GetPlaybackConfig(),
  1238. FieldsAre(ElementsAre(
  1239. FieldsAre(test_config.scheduled_cycles.front().start_offset,
  1240. test_config.scheduled_cycles.front().end_offset)),
  1241. test_config.initial_offset,
  1242. test_config.initial_completed_cycles, test_config.style));
  1243. animation_->Stop();
  1244. EXPECT_FALSE(animation_->GetPlaybackConfig());
  1245. test_config.scheduled_cycles.front().start_offset = kAnimationDuration / 2;
  1246. test_config.style = Animation::Style::kLoop;
  1247. animation_->Start(test_config);
  1248. ASSERT_TRUE(animation_->GetPlaybackConfig());
  1249. EXPECT_THAT(
  1250. *animation_->GetPlaybackConfig(),
  1251. FieldsAre(ElementsAre(
  1252. FieldsAre(test_config.scheduled_cycles.front().start_offset,
  1253. test_config.scheduled_cycles.front().end_offset)),
  1254. test_config.initial_offset,
  1255. test_config.initial_completed_cycles, test_config.style));
  1256. }
  1257. TEST_F(AnimationTest, GetNumCompletedCycles) {
  1258. EXPECT_FALSE(animation_->GetNumCompletedCycles());
  1259. animation_->Start(Animation::PlaybackConfig::CreateDefault(*animation_));
  1260. ASSERT_TRUE(animation_->GetNumCompletedCycles());
  1261. EXPECT_THAT(*animation_->GetNumCompletedCycles(), Eq(0));
  1262. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  1263. ASSERT_TRUE(animation_->GetNumCompletedCycles());
  1264. EXPECT_THAT(*animation_->GetNumCompletedCycles(), Eq(0));
  1265. AdvanceClock(kAnimationDuration / 2);
  1266. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  1267. ASSERT_TRUE(animation_->GetNumCompletedCycles());
  1268. EXPECT_THAT(*animation_->GetNumCompletedCycles(), Eq(0));
  1269. AdvanceClock(kAnimationDuration / 2);
  1270. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  1271. ASSERT_TRUE(animation_->GetNumCompletedCycles());
  1272. EXPECT_THAT(*animation_->GetNumCompletedCycles(), Eq(1));
  1273. AdvanceClock(kAnimationDuration);
  1274. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  1275. ASSERT_TRUE(animation_->GetNumCompletedCycles());
  1276. EXPECT_THAT(*animation_->GetNumCompletedCycles(), Eq(2));
  1277. animation_->Stop();
  1278. EXPECT_FALSE(animation_->GetNumCompletedCycles());
  1279. }
  1280. TEST_F(AnimationTest, GetNumCompletedCyclesLinear) {
  1281. animation_->Start(Animation::PlaybackConfig::CreateWithStyle(
  1282. Animation::Style::kLinear, *animation_));
  1283. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  1284. ASSERT_TRUE(animation_->GetNumCompletedCycles());
  1285. EXPECT_THAT(*animation_->GetNumCompletedCycles(), Eq(0));
  1286. AdvanceClock(kAnimationDuration / 2);
  1287. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  1288. ASSERT_TRUE(animation_->GetNumCompletedCycles());
  1289. EXPECT_THAT(*animation_->GetNumCompletedCycles(), Eq(0));
  1290. AdvanceClock(kAnimationDuration / 2);
  1291. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  1292. ASSERT_TRUE(animation_->GetNumCompletedCycles());
  1293. EXPECT_THAT(*animation_->GetNumCompletedCycles(), Eq(1));
  1294. AdvanceClock(kAnimationDuration);
  1295. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  1296. ASSERT_TRUE(animation_->GetNumCompletedCycles());
  1297. EXPECT_THAT(*animation_->GetNumCompletedCycles(), Eq(1));
  1298. }
  1299. TEST_F(AnimationTest, StartsAtArbitraryInitialTimestamp) {
  1300. constexpr auto kStartTime = base::Milliseconds(400);
  1301. constexpr auto kDuration = base::Milliseconds(1000);
  1302. AdvanceClock(base::Milliseconds(300));
  1303. animation_->Start(Animation::PlaybackConfig(
  1304. {{kStartTime, kStartTime + kDuration}},
  1305. /*initial_offset=*/kStartTime + base::Milliseconds(100),
  1306. /*initial_completed_cycles=*/0, Animation::Style::kThrobbing));
  1307. // T: 500 ms
  1308. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  1309. ASSERT_TRUE(animation_->GetCurrentProgress());
  1310. EXPECT_FLOAT_EQ(*animation_->GetCurrentProgress(),
  1311. (kStartTime + base::Milliseconds(100)) / kAnimationDuration);
  1312. // T: 600 ms
  1313. AdvanceClock(base::Milliseconds(100));
  1314. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  1315. ASSERT_TRUE(animation_->GetCurrentProgress());
  1316. EXPECT_FLOAT_EQ(*animation_->GetCurrentProgress(),
  1317. (kStartTime + base::Milliseconds(200)) / kAnimationDuration);
  1318. animation_->Stop();
  1319. // The animation has 1 completed cycle, so for a throbbing animation, it
  1320. // should immediately start playing in reverse.
  1321. animation_->Start(Animation::PlaybackConfig(
  1322. {{kStartTime, kStartTime + kDuration}},
  1323. /*initial_offset=*/kStartTime + base::Milliseconds(500),
  1324. /*initial_completed_cycles=*/1, Animation::Style::kThrobbing));
  1325. // T: 900 ms
  1326. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  1327. ASSERT_TRUE(animation_->GetCurrentProgress());
  1328. EXPECT_FLOAT_EQ(*animation_->GetCurrentProgress(),
  1329. (kStartTime + base::Milliseconds(500)) / kAnimationDuration);
  1330. // T: 800 ms
  1331. AdvanceClock(base::Milliseconds(100));
  1332. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  1333. ASSERT_TRUE(animation_->GetCurrentProgress());
  1334. EXPECT_FLOAT_EQ(*animation_->GetCurrentProgress(),
  1335. (kStartTime + base::Milliseconds(400)) / kAnimationDuration);
  1336. }
  1337. TEST_F(AnimationTest, GetCurrentCycleBoundaries) {
  1338. constexpr auto kStartTime1 = base::Milliseconds(400);
  1339. constexpr auto kEndTime1 = base::Milliseconds(800);
  1340. constexpr auto kDuration1 = kEndTime1 - kStartTime1;
  1341. constexpr auto kStartTime2 = base::Milliseconds(100);
  1342. constexpr auto kEndTime2 = base::Milliseconds(500);
  1343. constexpr auto kDuration2 = kEndTime2 - kStartTime2;
  1344. TestAnimationObserver observer(animation_.get());
  1345. AdvanceClock(base::Milliseconds(300));
  1346. EXPECT_FALSE(animation_->GetCurrentCycleBoundaries());
  1347. animation_->Start(Animation::PlaybackConfig(
  1348. {{kStartTime1, kEndTime1}, {kStartTime2, kEndTime2}},
  1349. /*initial_offset=*/kStartTime1,
  1350. /*initial_completed_cycles=*/0, Animation::Style::kLoop));
  1351. // No frames have been painted yet.
  1352. EXPECT_FALSE(animation_->GetCurrentCycleBoundaries());
  1353. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  1354. ASSERT_TRUE(animation_->GetCurrentCycleBoundaries());
  1355. EXPECT_THAT(*animation_->GetCurrentCycleBoundaries(),
  1356. FieldsAre(kStartTime1, kEndTime1));
  1357. // T: 1/2 of first cycle
  1358. AdvanceClock(kDuration1 / 2);
  1359. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  1360. ASSERT_TRUE(animation_->GetCurrentProgress());
  1361. EXPECT_THAT(*animation_->GetCurrentCycleBoundaries(),
  1362. FieldsAre(kStartTime1, kEndTime1));
  1363. // T: Start of first cycle
  1364. AdvanceClock(kDuration1 / 2);
  1365. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  1366. ASSERT_TRUE(animation_->GetCurrentProgress());
  1367. EXPECT_THAT(*animation_->GetCurrentCycleBoundaries(),
  1368. FieldsAre(kStartTime2, kEndTime2));
  1369. // T: Middle of second cycle
  1370. AdvanceClock(kDuration2 / 2);
  1371. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  1372. ASSERT_TRUE(animation_->GetCurrentProgress());
  1373. EXPECT_THAT(*animation_->GetCurrentCycleBoundaries(),
  1374. FieldsAre(kStartTime2, kEndTime2));
  1375. // T: Middle of second cycle (again)
  1376. AdvanceClock(kDuration2);
  1377. animation_->Paint(canvas(), NowTicks(), animation_->GetOriginalSize());
  1378. ASSERT_TRUE(animation_->GetCurrentProgress());
  1379. EXPECT_THAT(*animation_->GetCurrentCycleBoundaries(),
  1380. FieldsAre(kStartTime2, kEndTime2));
  1381. animation_->Stop();
  1382. EXPECT_FALSE(animation_->GetCurrentCycleBoundaries());
  1383. }
  1384. } // namespace lottie