layer_animation_element_unittest.cc 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650
  1. // Copyright (c) 2012 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/compositor/layer_animation_element.h"
  5. #include <memory>
  6. #include "base/compiler_specific.h"
  7. #include "base/strings/stringprintf.h"
  8. #include "base/time/time.h"
  9. #include "testing/gtest/include/gtest/gtest.h"
  10. #include "ui/compositor/layer_animation_delegate.h"
  11. #include "ui/compositor/scoped_animation_duration_scale_mode.h"
  12. #include "ui/compositor/test/test_layer_animation_delegate.h"
  13. #include "ui/compositor/test/test_utils.h"
  14. #include "ui/gfx/geometry/rect.h"
  15. #include "ui/gfx/geometry/transform.h"
  16. namespace ui {
  17. namespace {
  18. // Verify that the TargetValue(TestLayerAnimationDelegate*) constructor
  19. // correctly assigns values. See www.crbug.com/483134.
  20. TEST(TargetValueTest, VerifyLayerAnimationDelegateConstructor) {
  21. const gfx::Rect kBounds(1, 2, 3, 5);
  22. const gfx::Transform kTransform(1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f);
  23. const float kOpacity = 1.235f;
  24. const bool kVisibility = false;
  25. const float kBrightness = 2.358f;
  26. const float kGrayscale = 2.5813f;
  27. const SkColor kColor = SK_ColorCYAN;
  28. const gfx::Rect kClipRect(2, 3, 4, 5);
  29. const gfx::RoundedCornersF kRoundedCorners(2.0f, 3.0f, 4.0f, 5.0f);
  30. TestLayerAnimationDelegate delegate;
  31. delegate.SetBoundsFromAnimation(kBounds,
  32. PropertyChangeReason::NOT_FROM_ANIMATION);
  33. delegate.SetTransformFromAnimation(kTransform,
  34. PropertyChangeReason::NOT_FROM_ANIMATION);
  35. delegate.SetOpacityFromAnimation(kOpacity,
  36. PropertyChangeReason::NOT_FROM_ANIMATION);
  37. delegate.SetVisibilityFromAnimation(kVisibility,
  38. PropertyChangeReason::NOT_FROM_ANIMATION);
  39. delegate.SetBrightnessFromAnimation(kBrightness,
  40. PropertyChangeReason::NOT_FROM_ANIMATION);
  41. delegate.SetGrayscaleFromAnimation(kGrayscale,
  42. PropertyChangeReason::NOT_FROM_ANIMATION);
  43. delegate.SetColorFromAnimation(kColor,
  44. PropertyChangeReason::NOT_FROM_ANIMATION);
  45. delegate.SetClipRectFromAnimation(kClipRect,
  46. PropertyChangeReason::NOT_FROM_ANIMATION);
  47. delegate.SetRoundedCornersFromAnimation(
  48. kRoundedCorners, PropertyChangeReason::NOT_FROM_ANIMATION);
  49. LayerAnimationElement::TargetValue target_value(&delegate);
  50. EXPECT_EQ(kBounds, target_value.bounds);
  51. EXPECT_EQ(kTransform, target_value.transform);
  52. EXPECT_FLOAT_EQ(kOpacity, target_value.opacity);
  53. EXPECT_EQ(kVisibility, target_value.visibility);
  54. EXPECT_FLOAT_EQ(kBrightness, target_value.brightness);
  55. EXPECT_FLOAT_EQ(kGrayscale, target_value.grayscale);
  56. EXPECT_EQ(SK_ColorCYAN, target_value.color);
  57. EXPECT_EQ(kClipRect, target_value.clip_rect);
  58. EXPECT_EQ(kRoundedCorners, target_value.rounded_corners);
  59. }
  60. // Check that the transformation element progresses the delegate as expected and
  61. // that the element can be reused after it completes.
  62. TEST(LayerAnimationElementTest, TransformElement) {
  63. TestLayerAnimationDelegate delegate;
  64. gfx::Transform start_transform, target_transform;
  65. start_transform.Rotate(-30.0);
  66. target_transform.Rotate(30.0);
  67. base::TimeTicks start_time;
  68. base::TimeTicks effective_start_time;
  69. base::TimeDelta delta = base::Seconds(1);
  70. std::unique_ptr<LayerAnimationElement> element =
  71. LayerAnimationElement::CreateTransformElement(target_transform, delta);
  72. element->set_animation_group_id(1);
  73. for (int i = 0; i < 2; ++i) {
  74. start_time = effective_start_time + delta;
  75. element->set_requested_start_time(start_time);
  76. delegate.SetTransformFromAnimation(
  77. start_transform, PropertyChangeReason::NOT_FROM_ANIMATION);
  78. element->Start(&delegate, 1);
  79. element->Progress(start_time, &delegate);
  80. CheckApproximatelyEqual(start_transform,
  81. delegate.GetTransformForAnimation());
  82. delegate.ExpectLastPropertyChangeReason(
  83. PropertyChangeReason::FROM_ANIMATION);
  84. effective_start_time = start_time + delta;
  85. element->set_effective_start_time(effective_start_time);
  86. element->Progress(effective_start_time, &delegate);
  87. EXPECT_FLOAT_EQ(0.0, element->last_progressed_fraction());
  88. element->Progress(effective_start_time + delta/2, &delegate);
  89. EXPECT_FLOAT_EQ(0.5, element->last_progressed_fraction());
  90. base::TimeDelta element_duration;
  91. EXPECT_TRUE(element->IsFinished(effective_start_time + delta,
  92. &element_duration));
  93. EXPECT_EQ(2 * delta, element_duration);
  94. element->Progress(effective_start_time + delta, &delegate);
  95. EXPECT_FLOAT_EQ(1.0, element->last_progressed_fraction());
  96. CheckApproximatelyEqual(target_transform,
  97. delegate.GetTransformForAnimation());
  98. delegate.ExpectLastPropertyChangeReason(
  99. PropertyChangeReason::FROM_ANIMATION);
  100. }
  101. LayerAnimationElement::TargetValue target_value(&delegate);
  102. element->GetTargetValue(&target_value);
  103. CheckApproximatelyEqual(target_transform, target_value.transform);
  104. }
  105. // Check that the bounds element progresses the delegate as expected and
  106. // that the element can be reused after it completes.
  107. TEST(LayerAnimationElementTest, BoundsElement) {
  108. TestLayerAnimationDelegate delegate;
  109. gfx::Rect start, target, middle;
  110. start = target = middle = gfx::Rect(0, 0, 50, 50);
  111. start.set_x(-90);
  112. target.set_x(90);
  113. base::TimeTicks start_time;
  114. base::TimeDelta delta = base::Seconds(1);
  115. std::unique_ptr<LayerAnimationElement> element =
  116. LayerAnimationElement::CreateBoundsElement(target, delta);
  117. for (int i = 0; i < 2; ++i) {
  118. start_time += delta;
  119. element->set_requested_start_time(start_time);
  120. delegate.SetBoundsFromAnimation(start,
  121. PropertyChangeReason::NOT_FROM_ANIMATION);
  122. element->Start(&delegate, 1);
  123. element->Progress(start_time, &delegate);
  124. CheckApproximatelyEqual(start, delegate.GetBoundsForAnimation());
  125. delegate.ExpectLastPropertyChangeReason(
  126. PropertyChangeReason::FROM_ANIMATION);
  127. element->Progress(start_time + delta/2, &delegate);
  128. CheckApproximatelyEqual(middle, delegate.GetBoundsForAnimation());
  129. delegate.ExpectLastPropertyChangeReason(
  130. PropertyChangeReason::FROM_ANIMATION);
  131. base::TimeDelta element_duration;
  132. EXPECT_TRUE(element->IsFinished(start_time + delta, &element_duration));
  133. EXPECT_EQ(delta, element_duration);
  134. element->Progress(start_time + delta, &delegate);
  135. CheckApproximatelyEqual(target, delegate.GetBoundsForAnimation());
  136. delegate.ExpectLastPropertyChangeReason(
  137. PropertyChangeReason::FROM_ANIMATION);
  138. }
  139. LayerAnimationElement::TargetValue target_value(&delegate);
  140. element->GetTargetValue(&target_value);
  141. CheckApproximatelyEqual(target, target_value.bounds);
  142. }
  143. // Check that the opacity element progresses the delegate as expected and
  144. // that the element can be reused after it completes.
  145. TEST(LayerAnimationElementTest, OpacityElement) {
  146. TestLayerAnimationDelegate delegate;
  147. float start = 0.0;
  148. float middle = 0.5;
  149. float target = 1.0;
  150. base::TimeTicks start_time;
  151. base::TimeTicks effective_start_time;
  152. base::TimeDelta delta = base::Seconds(1);
  153. std::unique_ptr<LayerAnimationElement> element =
  154. LayerAnimationElement::CreateOpacityElement(target, delta);
  155. for (int i = 0; i < 2; ++i) {
  156. start_time = effective_start_time + delta;
  157. element->set_requested_start_time(start_time);
  158. delegate.SetOpacityFromAnimation(start,
  159. PropertyChangeReason::NOT_FROM_ANIMATION);
  160. element->Start(&delegate, 1);
  161. element->Progress(start_time, &delegate);
  162. EXPECT_FLOAT_EQ(start, element->last_progressed_fraction());
  163. effective_start_time = start_time + delta;
  164. element->set_effective_start_time(effective_start_time);
  165. element->Progress(effective_start_time, &delegate);
  166. EXPECT_FLOAT_EQ(start, element->last_progressed_fraction());
  167. element->Progress(effective_start_time + delta/2, &delegate);
  168. EXPECT_FLOAT_EQ(middle, element->last_progressed_fraction());
  169. base::TimeDelta element_duration;
  170. EXPECT_TRUE(element->IsFinished(effective_start_time + delta,
  171. &element_duration));
  172. EXPECT_EQ(2 * delta, element_duration);
  173. element->Progress(effective_start_time + delta, &delegate);
  174. EXPECT_FLOAT_EQ(target, element->last_progressed_fraction());
  175. EXPECT_FLOAT_EQ(target, delegate.GetOpacityForAnimation());
  176. delegate.ExpectLastPropertyChangeReason(
  177. PropertyChangeReason::FROM_ANIMATION);
  178. }
  179. LayerAnimationElement::TargetValue target_value(&delegate);
  180. element->GetTargetValue(&target_value);
  181. EXPECT_FLOAT_EQ(target, target_value.opacity);
  182. }
  183. // Check that the visibility element progresses the delegate as expected and
  184. // that the element can be reused after it completes.
  185. TEST(LayerAnimationElementTest, VisibilityElement) {
  186. TestLayerAnimationDelegate delegate;
  187. bool start = true;
  188. bool target = false;
  189. base::TimeTicks start_time;
  190. base::TimeDelta delta = base::Seconds(1);
  191. std::unique_ptr<LayerAnimationElement> element =
  192. LayerAnimationElement::CreateVisibilityElement(target, delta);
  193. for (int i = 0; i < 2; ++i) {
  194. start_time += delta;
  195. element->set_requested_start_time(start_time);
  196. delegate.SetVisibilityFromAnimation(
  197. start, PropertyChangeReason::NOT_FROM_ANIMATION);
  198. element->Start(&delegate, 1);
  199. element->Progress(start_time, &delegate);
  200. EXPECT_TRUE(delegate.GetVisibilityForAnimation());
  201. delegate.ExpectLastPropertyChangeReason(
  202. PropertyChangeReason::FROM_ANIMATION);
  203. element->Progress(start_time + delta/2, &delegate);
  204. EXPECT_TRUE(delegate.GetVisibilityForAnimation());
  205. delegate.ExpectLastPropertyChangeReason(
  206. PropertyChangeReason::FROM_ANIMATION);
  207. base::TimeDelta element_duration;
  208. EXPECT_TRUE(element->IsFinished(start_time + delta, &element_duration));
  209. EXPECT_EQ(delta, element_duration);
  210. element->Progress(start_time + delta, &delegate);
  211. EXPECT_FALSE(delegate.GetVisibilityForAnimation());
  212. delegate.ExpectLastPropertyChangeReason(
  213. PropertyChangeReason::FROM_ANIMATION);
  214. }
  215. LayerAnimationElement::TargetValue target_value(&delegate);
  216. element->GetTargetValue(&target_value);
  217. EXPECT_FALSE(target_value.visibility);
  218. }
  219. // Check that the Brightness element progresses the delegate as expected and
  220. // that the element can be reused after it completes.
  221. TEST(LayerAnimationElementTest, BrightnessElement) {
  222. TestLayerAnimationDelegate delegate;
  223. float start = 0.0;
  224. float middle = 0.5;
  225. float target = 1.0;
  226. base::TimeTicks start_time;
  227. base::TimeDelta delta = base::Seconds(1);
  228. std::unique_ptr<LayerAnimationElement> element =
  229. LayerAnimationElement::CreateBrightnessElement(target, delta);
  230. for (int i = 0; i < 2; ++i) {
  231. start_time += delta;
  232. element->set_requested_start_time(start_time);
  233. delegate.SetBrightnessFromAnimation(
  234. start, PropertyChangeReason::NOT_FROM_ANIMATION);
  235. element->Start(&delegate, 1);
  236. element->Progress(start_time, &delegate);
  237. EXPECT_FLOAT_EQ(start, delegate.GetBrightnessForAnimation());
  238. delegate.ExpectLastPropertyChangeReason(
  239. PropertyChangeReason::FROM_ANIMATION);
  240. element->Progress(start_time + delta/2, &delegate);
  241. EXPECT_FLOAT_EQ(middle, delegate.GetBrightnessForAnimation());
  242. delegate.ExpectLastPropertyChangeReason(
  243. PropertyChangeReason::FROM_ANIMATION);
  244. base::TimeDelta element_duration;
  245. EXPECT_TRUE(element->IsFinished(start_time + delta, &element_duration));
  246. EXPECT_EQ(delta, element_duration);
  247. element->Progress(start_time + delta, &delegate);
  248. EXPECT_FLOAT_EQ(target, delegate.GetBrightnessForAnimation());
  249. delegate.ExpectLastPropertyChangeReason(
  250. PropertyChangeReason::FROM_ANIMATION);
  251. }
  252. LayerAnimationElement::TargetValue target_value(&delegate);
  253. element->GetTargetValue(&target_value);
  254. EXPECT_FLOAT_EQ(target, target_value.brightness);
  255. }
  256. // Check that the Grayscale element progresses the delegate as expected and
  257. // that the element can be reused after it completes.
  258. TEST(LayerAnimationElementTest, GrayscaleElement) {
  259. TestLayerAnimationDelegate delegate;
  260. float start = 0.0;
  261. float middle = 0.5;
  262. float target = 1.0;
  263. base::TimeTicks start_time;
  264. base::TimeDelta delta = base::Seconds(1);
  265. std::unique_ptr<LayerAnimationElement> element =
  266. LayerAnimationElement::CreateGrayscaleElement(target, delta);
  267. for (int i = 0; i < 2; ++i) {
  268. start_time += delta;
  269. element->set_requested_start_time(start_time);
  270. delegate.SetGrayscaleFromAnimation(
  271. start, PropertyChangeReason::NOT_FROM_ANIMATION);
  272. element->Start(&delegate, 1);
  273. element->Progress(start_time, &delegate);
  274. EXPECT_FLOAT_EQ(start, delegate.GetGrayscaleForAnimation());
  275. delegate.ExpectLastPropertyChangeReason(
  276. PropertyChangeReason::FROM_ANIMATION);
  277. element->Progress(start_time + delta/2, &delegate);
  278. EXPECT_FLOAT_EQ(middle, delegate.GetGrayscaleForAnimation());
  279. delegate.ExpectLastPropertyChangeReason(
  280. PropertyChangeReason::FROM_ANIMATION);
  281. base::TimeDelta element_duration;
  282. EXPECT_TRUE(element->IsFinished(start_time + delta, &element_duration));
  283. EXPECT_EQ(delta, element_duration);
  284. element->Progress(start_time + delta, &delegate);
  285. EXPECT_FLOAT_EQ(target, delegate.GetGrayscaleForAnimation());
  286. delegate.ExpectLastPropertyChangeReason(
  287. PropertyChangeReason::FROM_ANIMATION);
  288. }
  289. LayerAnimationElement::TargetValue target_value(&delegate);
  290. element->GetTargetValue(&target_value);
  291. EXPECT_FLOAT_EQ(target, target_value.grayscale);
  292. }
  293. // Check that the pause element progresses the delegate as expected and
  294. // that the element can be reused after it completes.
  295. TEST(LayerAnimationElementTest, PauseElement) {
  296. LayerAnimationElement::AnimatableProperties properties =
  297. LayerAnimationElement::TRANSFORM | LayerAnimationElement::BOUNDS |
  298. LayerAnimationElement::OPACITY | LayerAnimationElement::BRIGHTNESS |
  299. LayerAnimationElement::GRAYSCALE;
  300. base::TimeTicks start_time;
  301. base::TimeDelta delta = base::Seconds(1);
  302. std::unique_ptr<LayerAnimationElement> element =
  303. LayerAnimationElement::CreatePauseElement(properties, delta);
  304. TestLayerAnimationDelegate delegate;
  305. TestLayerAnimationDelegate copy = delegate;
  306. start_time += delta;
  307. element->set_requested_start_time(start_time);
  308. element->Start(&delegate, 1);
  309. // Pause should last for |delta|.
  310. base::TimeDelta element_duration;
  311. EXPECT_TRUE(element->IsFinished(start_time + delta, &element_duration));
  312. EXPECT_EQ(delta, element_duration);
  313. element->Progress(start_time + delta, &delegate);
  314. // Nothing should have changed.
  315. CheckApproximatelyEqual(delegate.GetBoundsForAnimation(),
  316. copy.GetBoundsForAnimation());
  317. CheckApproximatelyEqual(delegate.GetTransformForAnimation(),
  318. copy.GetTransformForAnimation());
  319. EXPECT_FLOAT_EQ(delegate.GetOpacityForAnimation(),
  320. copy.GetOpacityForAnimation());
  321. EXPECT_FLOAT_EQ(delegate.GetBrightnessForAnimation(),
  322. copy.GetBrightnessForAnimation());
  323. EXPECT_FLOAT_EQ(delegate.GetGrayscaleForAnimation(),
  324. copy.GetGrayscaleForAnimation());
  325. }
  326. // Check that the ClipRect element progresses the delegate as expected and
  327. // that the element can be reused after it completes.
  328. TEST(LayerAnimationElementTest, ClipRectElement) {
  329. TestLayerAnimationDelegate delegate;
  330. gfx::Rect start, target, middle;
  331. start = target = middle = gfx::Rect(0, 0, 50, 50);
  332. start.set_x(-10);
  333. target.set_x(10);
  334. start.set_y(-20);
  335. target.set_y(20);
  336. start.set_width(70);
  337. target.set_width(30);
  338. base::TimeTicks start_time;
  339. base::TimeDelta delta = base::Seconds(1);
  340. std::unique_ptr<LayerAnimationElement> element =
  341. LayerAnimationElement::CreateClipRectElement(target, delta);
  342. for (int i = 0; i < 2; ++i) {
  343. start_time += delta;
  344. element->set_requested_start_time(start_time);
  345. delegate.SetClipRectFromAnimation(start,
  346. PropertyChangeReason::NOT_FROM_ANIMATION);
  347. element->Start(&delegate, 1);
  348. element->Progress(start_time, &delegate);
  349. CheckApproximatelyEqual(start, delegate.GetClipRectForAnimation());
  350. delegate.ExpectLastPropertyChangeReason(
  351. PropertyChangeReason::FROM_ANIMATION);
  352. element->Progress(start_time + delta / 2, &delegate);
  353. CheckApproximatelyEqual(middle, delegate.GetClipRectForAnimation());
  354. delegate.ExpectLastPropertyChangeReason(
  355. PropertyChangeReason::FROM_ANIMATION);
  356. base::TimeDelta element_duration;
  357. EXPECT_TRUE(element->IsFinished(start_time + delta, &element_duration));
  358. EXPECT_EQ(delta, element_duration);
  359. element->Progress(start_time + delta, &delegate);
  360. CheckApproximatelyEqual(target, delegate.GetClipRectForAnimation());
  361. delegate.ExpectLastPropertyChangeReason(
  362. PropertyChangeReason::FROM_ANIMATION);
  363. }
  364. LayerAnimationElement::TargetValue target_value(&delegate);
  365. element->GetTargetValue(&target_value);
  366. CheckApproximatelyEqual(target, target_value.clip_rect);
  367. }
  368. // Check that the RoundedCorners element progresses the delegate as expected and
  369. // that the element can be reused after it completes.
  370. TEST(LayerAnimationElementTest, RoundedCornersElement) {
  371. TestLayerAnimationDelegate delegate;
  372. gfx::RoundedCornersF start(1.0f, 2.0f, 3.0f, 4.0f);
  373. gfx::RoundedCornersF target(11.0f, 12.0f, 13.0f, 14.0f);
  374. gfx::RoundedCornersF middle(6.0f, 7.0f, 8.0f, 9.0f);
  375. base::TimeTicks start_time;
  376. base::TimeDelta delta = base::Seconds(1);
  377. std::unique_ptr<LayerAnimationElement> element =
  378. LayerAnimationElement::CreateRoundedCornersElement(target, delta);
  379. for (int i = 0; i < 2; ++i) {
  380. start_time += delta;
  381. element->set_requested_start_time(start_time);
  382. delegate.SetRoundedCornersFromAnimation(
  383. start, PropertyChangeReason::NOT_FROM_ANIMATION);
  384. element->Start(&delegate, 1);
  385. element->Progress(start_time, &delegate);
  386. CheckApproximatelyEqual(start, delegate.GetRoundedCornersForAnimation());
  387. delegate.ExpectLastPropertyChangeReason(
  388. PropertyChangeReason::FROM_ANIMATION);
  389. element->Progress(start_time + delta / 2, &delegate);
  390. CheckApproximatelyEqual(middle, delegate.GetRoundedCornersForAnimation());
  391. delegate.ExpectLastPropertyChangeReason(
  392. PropertyChangeReason::FROM_ANIMATION);
  393. base::TimeDelta element_duration;
  394. EXPECT_TRUE(element->IsFinished(start_time + delta, &element_duration));
  395. EXPECT_EQ(delta, element_duration);
  396. element->Progress(start_time + delta, &delegate);
  397. CheckApproximatelyEqual(target, delegate.GetRoundedCornersForAnimation());
  398. delegate.ExpectLastPropertyChangeReason(
  399. PropertyChangeReason::FROM_ANIMATION);
  400. }
  401. LayerAnimationElement::TargetValue target_value(&delegate);
  402. element->GetTargetValue(&target_value);
  403. CheckApproximatelyEqual(target, target_value.rounded_corners);
  404. }
  405. // Check that the GradientMask element progresses the delegate as expected and
  406. // that the element can be reused after it completes.
  407. TEST(LayerAnimationElementTest, GradientMaskElement) {
  408. TestLayerAnimationDelegate delegate;
  409. gfx::LinearGradient start(45);
  410. start.AddStep(0, 0);
  411. gfx::LinearGradient target(135);
  412. target.AddStep(.5, 255);
  413. gfx::LinearGradient middle(90);
  414. middle.AddStep(.25, 127);
  415. base::TimeTicks start_time;
  416. base::TimeDelta delta = base::Seconds(1);
  417. std::unique_ptr<LayerAnimationElement> element =
  418. LayerAnimationElement::CreateGradientMaskElement(target, delta);
  419. for (int i = 0; i < 2; ++i) {
  420. start_time += delta;
  421. element->set_requested_start_time(start_time);
  422. delegate.SetGradientMaskFromAnimation(
  423. start, PropertyChangeReason::NOT_FROM_ANIMATION);
  424. element->Start(&delegate, 1);
  425. element->Progress(start_time, &delegate);
  426. EXPECT_EQ(start, delegate.GetGradientMaskForAnimation());
  427. delegate.ExpectLastPropertyChangeReason(
  428. PropertyChangeReason::FROM_ANIMATION);
  429. element->Progress(start_time + delta / 2, &delegate);
  430. EXPECT_EQ(middle, delegate.GetGradientMaskForAnimation());
  431. delegate.ExpectLastPropertyChangeReason(
  432. PropertyChangeReason::FROM_ANIMATION);
  433. base::TimeDelta element_duration;
  434. EXPECT_TRUE(element->IsFinished(start_time + delta, &element_duration));
  435. EXPECT_EQ(delta, element_duration);
  436. element->Progress(start_time + delta, &delegate);
  437. EXPECT_EQ(target, delegate.GetGradientMaskForAnimation());
  438. delegate.ExpectLastPropertyChangeReason(
  439. PropertyChangeReason::FROM_ANIMATION);
  440. }
  441. LayerAnimationElement::TargetValue target_value(&delegate);
  442. element->GetTargetValue(&target_value);
  443. EXPECT_EQ(target, target_value.gradient_mask);
  444. }
  445. // Check that a threaded opacity element updates the delegate as expected when
  446. // aborted.
  447. TEST(LayerAnimationElementTest, AbortOpacityElement) {
  448. TestLayerAnimationDelegate delegate;
  449. float start = 0.0;
  450. float target = 1.0;
  451. base::TimeTicks start_time;
  452. base::TimeTicks effective_start_time;
  453. base::TimeDelta delta = base::Seconds(1);
  454. std::unique_ptr<LayerAnimationElement> element =
  455. LayerAnimationElement::CreateOpacityElement(target, delta);
  456. // Choose a non-linear Tween type.
  457. gfx::Tween::Type tween_type = gfx::Tween::EASE_IN;
  458. element->set_tween_type(tween_type);
  459. delegate.SetOpacityFromAnimation(start,
  460. PropertyChangeReason::NOT_FROM_ANIMATION);
  461. delegate.ExpectLastPropertyChangeReason(
  462. PropertyChangeReason::NOT_FROM_ANIMATION);
  463. // Aborting the element before it has started should not update the delegate.
  464. element->Abort(&delegate);
  465. EXPECT_FLOAT_EQ(start, delegate.GetOpacityForAnimation());
  466. delegate.ExpectLastPropertyChangeReasonIsUnset();
  467. start_time += delta;
  468. element->set_requested_start_time(start_time);
  469. element->Start(&delegate, 1);
  470. element->Progress(start_time, &delegate);
  471. effective_start_time = start_time + delta;
  472. element->set_effective_start_time(effective_start_time);
  473. element->Progress(effective_start_time, &delegate);
  474. element->Progress(effective_start_time + delta/2, &delegate);
  475. // Since the element has started, it should update the delegate when
  476. // aborted.
  477. element->Abort(&delegate);
  478. EXPECT_FLOAT_EQ(gfx::Tween::CalculateValue(tween_type, 0.5),
  479. delegate.GetOpacityForAnimation());
  480. delegate.ExpectLastPropertyChangeReason(PropertyChangeReason::FROM_ANIMATION);
  481. }
  482. // Check that a threaded transform element updates the delegate as expected when
  483. // aborted.
  484. TEST(LayerAnimationElementTest, AbortTransformElement) {
  485. TestLayerAnimationDelegate delegate;
  486. gfx::Transform start_transform, target_transform;
  487. start_transform.Rotate(-30.0);
  488. target_transform.Rotate(30.0);
  489. base::TimeTicks start_time;
  490. base::TimeTicks effective_start_time;
  491. base::TimeDelta delta = base::Seconds(1);
  492. std::unique_ptr<LayerAnimationElement> element =
  493. LayerAnimationElement::CreateTransformElement(target_transform, delta);
  494. // Choose a non-linear Tween type.
  495. gfx::Tween::Type tween_type = gfx::Tween::EASE_IN;
  496. element->set_tween_type(tween_type);
  497. delegate.SetTransformFromAnimation(start_transform,
  498. PropertyChangeReason::NOT_FROM_ANIMATION);
  499. delegate.ExpectLastPropertyChangeReason(
  500. PropertyChangeReason::NOT_FROM_ANIMATION);
  501. // Aborting the element before it has started should not update the delegate.
  502. element->Abort(&delegate);
  503. CheckApproximatelyEqual(start_transform, delegate.GetTransformForAnimation());
  504. delegate.ExpectLastPropertyChangeReasonIsUnset();
  505. start_time += delta;
  506. element->set_requested_start_time(start_time);
  507. element->Start(&delegate, 1);
  508. element->Progress(start_time, &delegate);
  509. effective_start_time = start_time + delta;
  510. element->set_effective_start_time(effective_start_time);
  511. element->Progress(effective_start_time, &delegate);
  512. element->Progress(effective_start_time + delta/2, &delegate);
  513. // Since the element has started, it should update the delegate when
  514. // aborted.
  515. element->Abort(&delegate);
  516. target_transform.Blend(start_transform,
  517. gfx::Tween::CalculateValue(tween_type, 0.5));
  518. CheckApproximatelyEqual(target_transform,
  519. delegate.GetTransformForAnimation());
  520. delegate.ExpectLastPropertyChangeReason(PropertyChangeReason::FROM_ANIMATION);
  521. }
  522. // Check that an opacity element is not threaded if the start and target values
  523. // are the same.
  524. TEST(LayerAnimationElementTest, OpacityElementIsThreaded) {
  525. TestLayerAnimationDelegate delegate;
  526. float start = 0.0;
  527. float target = 1.0;
  528. delegate.SetOpacityFromAnimation(start,
  529. PropertyChangeReason::NOT_FROM_ANIMATION);
  530. base::TimeDelta delta = base::Seconds(1);
  531. std::unique_ptr<LayerAnimationElement> element =
  532. LayerAnimationElement::CreateOpacityElement(target, delta);
  533. EXPECT_TRUE(element->IsThreaded(&delegate));
  534. element->ProgressToEnd(&delegate);
  535. EXPECT_FLOAT_EQ(target, delegate.GetOpacityForAnimation());
  536. delegate.ExpectLastPropertyChangeReason(PropertyChangeReason::FROM_ANIMATION);
  537. start = 1.0;
  538. delegate.SetOpacityFromAnimation(start,
  539. PropertyChangeReason::NOT_FROM_ANIMATION);
  540. element = LayerAnimationElement::CreateOpacityElement(target, delta);
  541. EXPECT_FALSE(element->IsThreaded(&delegate));
  542. element->ProgressToEnd(&delegate);
  543. EXPECT_FLOAT_EQ(target, delegate.GetOpacityForAnimation());
  544. delegate.ExpectLastPropertyChangeReason(PropertyChangeReason::FROM_ANIMATION);
  545. }
  546. TEST(LayerAnimationElementTest, ToString) {
  547. float target = 1.0;
  548. base::TimeDelta delta = base::Seconds(1);
  549. std::unique_ptr<LayerAnimationElement> element =
  550. LayerAnimationElement::CreateOpacityElement(target, delta);
  551. element->set_animation_group_id(42);
  552. // TODO(wkorman): Test varying last_progressed_fraction.
  553. EXPECT_EQ(
  554. base::StringPrintf("LayerAnimationElement{name=ThreadedOpacityTransition,"
  555. " id=%d, group=42, "
  556. "last_progressed_fraction=0.00}",
  557. element->keyframe_model_id()),
  558. element->ToString());
  559. }
  560. } // namespace
  561. } // namespace ui