skottie_serialization_history_unittest.cc 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  1. // Copyright 2022 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "cc/paint/skottie_serialization_history.h"
  5. #include <cstdint>
  6. #include "cc/paint/paint_flags.h"
  7. #include "cc/paint/skottie_frame_data.h"
  8. #include "cc/paint/skottie_resource_metadata.h"
  9. #include "cc/paint/skottie_text_property_value.h"
  10. #include "cc/paint/skottie_wrapper.h"
  11. #include "cc/test/lottie_test_data.h"
  12. #include "cc/test/skia_common.h"
  13. #include "testing/gmock/include/gmock/gmock.h"
  14. #include "testing/gtest/include/gtest/gtest.h"
  15. #include "ui/gfx/geometry/rect_f.h"
  16. #include "ui/gfx/geometry/size.h"
  17. namespace cc {
  18. namespace {
  19. using ::testing::Contains;
  20. using ::testing::IsEmpty;
  21. using ::testing::Pair;
  22. using ::testing::UnorderedElementsAre;
  23. class SkottieSerializationHistoryTest : public ::testing::Test {
  24. protected:
  25. static constexpr int64_t kTestPurgePeriod = 2;
  26. SkottieSerializationHistoryTest() : history_(kTestPurgePeriod) {}
  27. SkottieSerializationHistory history_;
  28. SkottieFrameDataMap empty_images;
  29. SkottieTextPropertyValueMap empty_text_map;
  30. };
  31. TEST_F(SkottieSerializationHistoryTest, FilterNewSkottieFrameImages) {
  32. auto skottie = CreateSkottieFromString(
  33. CreateCustomLottieDataWith2Assets("asset_a", "asset_b"));
  34. PaintImage image_1 = CreateBitmapImage(gfx::Size(10, 10));
  35. PaintImage image_2 = CreateBitmapImage(gfx::Size(20, 20));
  36. PaintImage image_3 = CreateBitmapImage(gfx::Size(30, 30));
  37. PaintImage image_4 = CreateBitmapImage(gfx::Size(40, 40));
  38. SkottieFrameDataMap images = {
  39. {HashSkottieResourceId("asset_a"),
  40. {image_1, PaintFlags::FilterQuality::kMedium}},
  41. {HashSkottieResourceId("asset_b"),
  42. {image_2, PaintFlags::FilterQuality::kMedium}},
  43. };
  44. history_.FilterNewSkottieFrameState(*skottie, images, empty_text_map);
  45. EXPECT_THAT(
  46. images,
  47. UnorderedElementsAre(
  48. Pair(HashSkottieResourceId("asset_a"),
  49. SkottieFrameData({image_1, PaintFlags::FilterQuality::kMedium})),
  50. Pair(HashSkottieResourceId("asset_b"),
  51. SkottieFrameData(
  52. {image_2, PaintFlags::FilterQuality::kMedium}))));
  53. images = {
  54. {HashSkottieResourceId("asset_a"),
  55. {image_3, PaintFlags::FilterQuality::kMedium}},
  56. {HashSkottieResourceId("asset_b"),
  57. {image_2, PaintFlags::FilterQuality::kMedium}},
  58. };
  59. history_.FilterNewSkottieFrameState(*skottie, images, empty_text_map);
  60. EXPECT_THAT(
  61. images,
  62. UnorderedElementsAre(Pair(
  63. HashSkottieResourceId("asset_a"),
  64. SkottieFrameData({image_3, PaintFlags::FilterQuality::kMedium}))));
  65. images = {
  66. {HashSkottieResourceId("asset_a"),
  67. {image_3, PaintFlags::FilterQuality::kMedium}},
  68. {HashSkottieResourceId("asset_b"),
  69. {image_4, PaintFlags::FilterQuality::kMedium}},
  70. };
  71. history_.FilterNewSkottieFrameState(*skottie, images, empty_text_map);
  72. EXPECT_THAT(
  73. images,
  74. UnorderedElementsAre(Pair(
  75. HashSkottieResourceId("asset_b"),
  76. SkottieFrameData({image_4, PaintFlags::FilterQuality::kMedium}))));
  77. history_.FilterNewSkottieFrameState(*skottie, images, empty_text_map);
  78. EXPECT_THAT(images, IsEmpty());
  79. }
  80. TEST_F(SkottieSerializationHistoryTest, HandlesEmptyImages) {
  81. auto skottie = CreateSkottieFromString(
  82. CreateCustomLottieDataWith2Assets("asset_a", "asset_b"));
  83. PaintImage blank_image;
  84. PaintImage image_1 = CreateBitmapImage(gfx::Size(10, 10));
  85. PaintImage image_2 = CreateBitmapImage(gfx::Size(20, 20));
  86. ;
  87. SkottieFrameDataMap images = {
  88. {HashSkottieResourceId("asset_a"),
  89. {blank_image, PaintFlags::FilterQuality::kMedium}},
  90. {HashSkottieResourceId("asset_b"),
  91. {image_2, PaintFlags::FilterQuality::kMedium}},
  92. };
  93. history_.FilterNewSkottieFrameState(*skottie, images, empty_text_map);
  94. EXPECT_THAT(
  95. images,
  96. Contains(Pair(HashSkottieResourceId("asset_a"),
  97. SkottieFrameData(
  98. {blank_image, PaintFlags::FilterQuality::kMedium}))));
  99. images = {{HashSkottieResourceId("asset_a"),
  100. {image_1, PaintFlags::FilterQuality::kMedium}}};
  101. history_.FilterNewSkottieFrameState(*skottie, images, empty_text_map);
  102. EXPECT_THAT(
  103. images,
  104. Contains(Pair(
  105. HashSkottieResourceId("asset_a"),
  106. SkottieFrameData({image_1, PaintFlags::FilterQuality::kMedium}))));
  107. images = {{HashSkottieResourceId("asset_a"),
  108. {blank_image, PaintFlags::FilterQuality::kMedium}}};
  109. history_.FilterNewSkottieFrameState(*skottie, images, empty_text_map);
  110. EXPECT_THAT(
  111. images,
  112. Contains(Pair(HashSkottieResourceId("asset_a"),
  113. SkottieFrameData(
  114. {blank_image, PaintFlags::FilterQuality::kMedium}))));
  115. history_.FilterNewSkottieFrameState(*skottie, images, empty_text_map);
  116. EXPECT_THAT(images, IsEmpty());
  117. }
  118. TEST_F(SkottieSerializationHistoryTest, FilterNewSkottieFrameText) {
  119. auto skottie = CreateSkottie(gfx::Size(10, 10), 1);
  120. SkottieTextPropertyValueMap text_map = {
  121. {HashSkottieResourceId("node_a"),
  122. SkottieTextPropertyValue("test_1a", gfx::RectF(1, 1, 1, 1))},
  123. {HashSkottieResourceId("node_b"),
  124. SkottieTextPropertyValue("test_1b", gfx::RectF(2, 2, 2, 2))},
  125. };
  126. history_.FilterNewSkottieFrameState(*skottie, empty_images, text_map);
  127. EXPECT_THAT(
  128. text_map,
  129. UnorderedElementsAre(
  130. Pair(HashSkottieResourceId("node_a"),
  131. SkottieTextPropertyValue("test_1a", gfx::RectF(1, 1, 1, 1))),
  132. Pair(HashSkottieResourceId("node_b"),
  133. SkottieTextPropertyValue("test_1b", gfx::RectF(2, 2, 2, 2)))));
  134. text_map = {
  135. {HashSkottieResourceId("node_a"),
  136. SkottieTextPropertyValue("test_2a", gfx::RectF(1, 1, 1, 1))},
  137. {HashSkottieResourceId("node_b"),
  138. SkottieTextPropertyValue("test_1b", gfx::RectF(2, 2, 2, 2))},
  139. };
  140. history_.FilterNewSkottieFrameState(*skottie, empty_images, text_map);
  141. EXPECT_THAT(
  142. text_map,
  143. UnorderedElementsAre(
  144. Pair(HashSkottieResourceId("node_a"),
  145. SkottieTextPropertyValue("test_2a", gfx::RectF(1, 1, 1, 1)))));
  146. text_map = {
  147. {HashSkottieResourceId("node_a"),
  148. SkottieTextPropertyValue("test_2a", gfx::RectF(3, 3, 3, 3))},
  149. {HashSkottieResourceId("node_b"),
  150. SkottieTextPropertyValue("test_1b", gfx::RectF(2, 2, 2, 2))},
  151. };
  152. history_.FilterNewSkottieFrameState(*skottie, empty_images, text_map);
  153. EXPECT_THAT(
  154. text_map,
  155. UnorderedElementsAre(
  156. Pair(HashSkottieResourceId("node_a"),
  157. SkottieTextPropertyValue("test_2a", gfx::RectF(3, 3, 3, 3)))));
  158. history_.FilterNewSkottieFrameState(*skottie, empty_images, text_map);
  159. EXPECT_THAT(text_map, IsEmpty());
  160. }
  161. TEST_F(SkottieSerializationHistoryTest,
  162. FilterNewSkottieFrameImagesTakesQualityIntoAccount) {
  163. auto skottie = CreateSkottieFromString(
  164. CreateCustomLottieDataWith2Assets("asset_a", "asset_b"));
  165. PaintImage image_1 = CreateBitmapImage(gfx::Size(10, 10));
  166. PaintImage image_2 = CreateBitmapImage(gfx::Size(20, 20));
  167. SkottieFrameDataMap images = {
  168. {HashSkottieResourceId("asset_a"),
  169. {image_1, PaintFlags::FilterQuality::kMedium}},
  170. {HashSkottieResourceId("asset_b"),
  171. {image_2, PaintFlags::FilterQuality::kMedium}},
  172. };
  173. history_.FilterNewSkottieFrameState(*skottie, images, empty_text_map);
  174. images = {
  175. {HashSkottieResourceId("asset_a"),
  176. {image_1, PaintFlags::FilterQuality::kHigh}},
  177. {HashSkottieResourceId("asset_b"),
  178. {image_2, PaintFlags::FilterQuality::kMedium}},
  179. };
  180. history_.FilterNewSkottieFrameState(*skottie, images, empty_text_map);
  181. EXPECT_THAT(
  182. images,
  183. UnorderedElementsAre(
  184. Pair(HashSkottieResourceId("asset_a"),
  185. SkottieFrameData({image_1, PaintFlags::FilterQuality::kHigh}))));
  186. }
  187. TEST_F(SkottieSerializationHistoryTest,
  188. FilterNewSkottieFrameStateMultipleAnimations) {
  189. auto skottie_1 = CreateSkottieFromString(
  190. CreateCustomLottieDataWith2Assets("asset_1a", "asset_1b"));
  191. auto skottie_2 = CreateSkottieFromString(
  192. CreateCustomLottieDataWith2Assets("asset_2a", "asset_2b"));
  193. PaintImage image_1 = CreateBitmapImage(gfx::Size(10, 10));
  194. PaintImage image_2 = CreateBitmapImage(gfx::Size(20, 20));
  195. PaintImage image_3 = CreateBitmapImage(gfx::Size(30, 30));
  196. PaintImage image_4 = CreateBitmapImage(gfx::Size(40, 40));
  197. SkottieFrameDataMap images_1 = {
  198. {HashSkottieResourceId("asset_1a"),
  199. {image_1, PaintFlags::FilterQuality::kMedium}},
  200. {HashSkottieResourceId("asset_1b"),
  201. {image_2, PaintFlags::FilterQuality::kMedium}},
  202. };
  203. SkottieFrameDataMap images_2 = {
  204. {HashSkottieResourceId("asset_2a"),
  205. {image_1, PaintFlags::FilterQuality::kMedium}},
  206. {HashSkottieResourceId("asset_2b"),
  207. {image_2, PaintFlags::FilterQuality::kMedium}},
  208. };
  209. history_.FilterNewSkottieFrameState(*skottie_1, images_1, empty_text_map);
  210. history_.FilterNewSkottieFrameState(*skottie_2, images_2, empty_text_map);
  211. EXPECT_THAT(
  212. images_2,
  213. UnorderedElementsAre(
  214. Pair(HashSkottieResourceId("asset_2a"),
  215. SkottieFrameData({image_1, PaintFlags::FilterQuality::kMedium})),
  216. Pair(HashSkottieResourceId("asset_2b"),
  217. SkottieFrameData(
  218. {image_2, PaintFlags::FilterQuality::kMedium}))));
  219. images_1 = {
  220. {HashSkottieResourceId("asset_1a"),
  221. {image_3, PaintFlags::FilterQuality::kMedium}},
  222. {HashSkottieResourceId("asset_1b"),
  223. {image_2, PaintFlags::FilterQuality::kMedium}},
  224. };
  225. images_2 = {
  226. {HashSkottieResourceId("asset_2a"),
  227. {image_4, PaintFlags::FilterQuality::kMedium}},
  228. {HashSkottieResourceId("asset_2b"),
  229. {image_2, PaintFlags::FilterQuality::kMedium}},
  230. };
  231. history_.FilterNewSkottieFrameState(*skottie_1, images_1, empty_text_map);
  232. history_.FilterNewSkottieFrameState(*skottie_2, images_2, empty_text_map);
  233. EXPECT_THAT(
  234. images_2,
  235. UnorderedElementsAre(Pair(
  236. HashSkottieResourceId("asset_2a"),
  237. SkottieFrameData({image_4, PaintFlags::FilterQuality::kMedium}))));
  238. }
  239. TEST_F(SkottieSerializationHistoryTest, RequestInactiveAnimationsPurge) {
  240. auto skottie_1 = CreateSkottieFromString(
  241. CreateCustomLottieDataWith2Assets("asset_1a", "asset_1b"));
  242. auto skottie_2 = CreateSkottieFromString(
  243. CreateCustomLottieDataWith2Assets("asset_2a", "asset_2b"));
  244. PaintImage image_1 = CreateBitmapImage(gfx::Size(10, 10));
  245. PaintImage image_2 = CreateBitmapImage(gfx::Size(20, 20));
  246. SkottieFrameDataMap images_1 = {
  247. {HashSkottieResourceId("asset_1a"),
  248. {image_1, PaintFlags::FilterQuality::kMedium}},
  249. {HashSkottieResourceId("asset_1b"),
  250. {image_2, PaintFlags::FilterQuality::kMedium}},
  251. };
  252. SkottieFrameDataMap images_2 = {
  253. {HashSkottieResourceId("asset_2a"),
  254. {image_1, PaintFlags::FilterQuality::kMedium}},
  255. {HashSkottieResourceId("asset_2b"),
  256. {image_2, PaintFlags::FilterQuality::kMedium}},
  257. };
  258. history_.FilterNewSkottieFrameState(*skottie_1, images_1, empty_text_map);
  259. history_.FilterNewSkottieFrameState(*skottie_2, images_2, empty_text_map);
  260. history_.RequestInactiveAnimationsPurge();
  261. history_.FilterNewSkottieFrameState(*skottie_1, images_1, empty_text_map);
  262. // Only |skottie_2| should be purged here since |skottie_1| was updated after
  263. // the first purge.
  264. history_.RequestInactiveAnimationsPurge();
  265. history_.FilterNewSkottieFrameState(*skottie_1, images_1, empty_text_map);
  266. history_.FilterNewSkottieFrameState(*skottie_2, images_2, empty_text_map);
  267. EXPECT_THAT(images_1, IsEmpty());
  268. // History for |skottie_2| should start again.
  269. EXPECT_THAT(
  270. images_2,
  271. UnorderedElementsAre(
  272. Pair(HashSkottieResourceId("asset_2a"),
  273. SkottieFrameData({image_1, PaintFlags::FilterQuality::kMedium})),
  274. Pair(HashSkottieResourceId("asset_2b"),
  275. SkottieFrameData(
  276. {image_2, PaintFlags::FilterQuality::kMedium}))));
  277. }
  278. } // namespace
  279. } // namespace cc