recording_source_unittest.cc 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378
  1. // Copyright 2015 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 <vector>
  5. #include "cc/base/region.h"
  6. #include "cc/raster/raster_source.h"
  7. #include "cc/test/fake_content_layer_client.h"
  8. #include "cc/test/fake_recording_source.h"
  9. #include "cc/test/skia_common.h"
  10. #include "testing/gmock/include/gmock/gmock.h"
  11. #include "testing/gtest/include/gtest/gtest.h"
  12. #include "third_party/skia/include/core/SkRefCnt.h"
  13. namespace cc {
  14. namespace {
  15. std::unique_ptr<FakeRecordingSource> CreateRecordingSource(
  16. const gfx::Rect& viewport) {
  17. gfx::Rect layer_rect(viewport.right(), viewport.bottom());
  18. std::unique_ptr<FakeRecordingSource> recording_source =
  19. FakeRecordingSource::CreateRecordingSource(viewport, layer_rect.size());
  20. return recording_source;
  21. }
  22. TEST(RecordingSourceTest, DiscardableImagesWithTransform) {
  23. gfx::Rect recorded_viewport(256, 256);
  24. std::unique_ptr<FakeRecordingSource> recording_source =
  25. FakeRecordingSource::CreateFilledRecordingSource(
  26. recorded_viewport.size());
  27. PaintImage discardable_image[2][2];
  28. gfx::Transform identity_transform;
  29. discardable_image[0][0] = CreateDiscardablePaintImage(gfx::Size(32, 32));
  30. // Translate transform is equivalent to moving using point.
  31. gfx::Transform translate_transform;
  32. translate_transform.Translate(0, 130);
  33. discardable_image[1][0] = CreateDiscardablePaintImage(gfx::Size(32, 32));
  34. // This moves the bitmap to center of viewport and rotate, this would make
  35. // this bitmap in all four tile grids.
  36. gfx::Transform rotate_transform;
  37. rotate_transform.Translate(112, 112);
  38. rotate_transform.Rotate(45);
  39. discardable_image[1][1] = CreateDiscardablePaintImage(gfx::Size(32, 32));
  40. gfx::RectF rect(0, 0, 32, 32);
  41. gfx::RectF translate_rect = rect;
  42. translate_transform.TransformRect(&translate_rect);
  43. gfx::RectF rotate_rect = rect;
  44. rotate_transform.TransformRect(&rotate_rect);
  45. recording_source->add_draw_image_with_transform(discardable_image[0][0],
  46. identity_transform);
  47. recording_source->add_draw_image_with_transform(discardable_image[1][0],
  48. translate_transform);
  49. recording_source->add_draw_image_with_transform(discardable_image[1][1],
  50. rotate_transform);
  51. recording_source->Rerecord();
  52. scoped_refptr<RasterSource> raster_source =
  53. recording_source->CreateRasterSource();
  54. // Tile sized iterators. These should find only one pixel ref.
  55. {
  56. std::vector<const DrawImage*> images;
  57. raster_source->GetDiscardableImagesInRect(gfx::Rect(0, 0, 128, 128),
  58. &images);
  59. EXPECT_EQ(2u, images.size());
  60. EXPECT_TRUE(images[0]->paint_image() == discardable_image[0][0]);
  61. EXPECT_TRUE(images[1]->paint_image() == discardable_image[1][1]);
  62. }
  63. // Shifted tile sized iterators. These should find only one pixel ref.
  64. {
  65. std::vector<const DrawImage*> images;
  66. raster_source->GetDiscardableImagesInRect(gfx::Rect(130, 140, 128, 128),
  67. &images);
  68. EXPECT_EQ(1u, images.size());
  69. EXPECT_TRUE(images[0]->paint_image() == discardable_image[1][1]);
  70. }
  71. // The rotated bitmap would still be in the top right tile.
  72. {
  73. std::vector<const DrawImage*> images;
  74. raster_source->GetDiscardableImagesInRect(gfx::Rect(130, 0, 128, 128),
  75. &images);
  76. EXPECT_EQ(1u, images.size());
  77. EXPECT_TRUE(images[0]->paint_image() == discardable_image[1][1]);
  78. }
  79. // Layer sized iterators. These should find all pixel refs.
  80. {
  81. std::vector<const DrawImage*> images;
  82. raster_source->GetDiscardableImagesInRect(gfx::Rect(0, 0, 256, 256),
  83. &images);
  84. EXPECT_EQ(3u, images.size());
  85. // Top left tile with bitmap[0][0] and bitmap[1][1].
  86. EXPECT_TRUE(images[0]->paint_image() == discardable_image[0][0]);
  87. EXPECT_TRUE(images[1]->paint_image() == discardable_image[1][0]);
  88. EXPECT_TRUE(images[2]->paint_image() == discardable_image[1][1]);
  89. }
  90. // Verify different raster scales
  91. for (float scale = 1.f; scale <= 5.f; scale += 0.5f) {
  92. std::vector<const DrawImage*> images;
  93. raster_source->GetDiscardableImagesInRect(gfx::Rect(130, 0, 128, 128),
  94. &images);
  95. DrawImage image(*images[0], scale, PaintImage::kDefaultFrameIndex,
  96. TargetColorParams());
  97. EXPECT_EQ(1u, images.size());
  98. EXPECT_FLOAT_EQ(scale, image.scale().width());
  99. EXPECT_FLOAT_EQ(scale, image.scale().height());
  100. }
  101. }
  102. TEST(RecordingSourceTest, EmptyImages) {
  103. gfx::Rect recorded_viewport(0, 0, 256, 256);
  104. std::unique_ptr<FakeRecordingSource> recording_source =
  105. CreateRecordingSource(recorded_viewport);
  106. recording_source->Rerecord();
  107. scoped_refptr<RasterSource> raster_source =
  108. recording_source->CreateRasterSource();
  109. // Tile sized iterators.
  110. {
  111. std::vector<const DrawImage*> images;
  112. raster_source->GetDiscardableImagesInRect(gfx::Rect(0, 0, 128, 128),
  113. &images);
  114. EXPECT_TRUE(images.empty());
  115. }
  116. // Shifted tile sized iterators.
  117. {
  118. std::vector<const DrawImage*> images;
  119. raster_source->GetDiscardableImagesInRect(gfx::Rect(140, 140, 128, 128),
  120. &images);
  121. EXPECT_TRUE(images.empty());
  122. }
  123. // Layer sized iterators.
  124. {
  125. std::vector<const DrawImage*> images;
  126. raster_source->GetDiscardableImagesInRect(gfx::Rect(0, 0, 256, 256),
  127. &images);
  128. EXPECT_TRUE(images.empty());
  129. }
  130. }
  131. TEST(RecordingSourceTest, NoDiscardableImages) {
  132. gfx::Rect recorded_viewport(0, 0, 256, 256);
  133. std::unique_ptr<FakeRecordingSource> recording_source =
  134. CreateRecordingSource(recorded_viewport);
  135. PaintFlags simple_flags;
  136. simple_flags.setColor(SkColorSetARGB(255, 12, 23, 34));
  137. auto non_discardable_image =
  138. CreateNonDiscardablePaintImage(gfx::Size(128, 128));
  139. recording_source->add_draw_rect_with_flags(gfx::Rect(0, 0, 256, 256),
  140. simple_flags);
  141. recording_source->add_draw_rect_with_flags(gfx::Rect(128, 128, 512, 512),
  142. simple_flags);
  143. recording_source->add_draw_rect_with_flags(gfx::Rect(512, 0, 256, 256),
  144. simple_flags);
  145. recording_source->add_draw_rect_with_flags(gfx::Rect(0, 512, 256, 256),
  146. simple_flags);
  147. recording_source->add_draw_image(non_discardable_image, gfx::Point(128, 0));
  148. recording_source->add_draw_image(non_discardable_image, gfx::Point(0, 128));
  149. recording_source->add_draw_image(non_discardable_image, gfx::Point(150, 150));
  150. recording_source->Rerecord();
  151. scoped_refptr<RasterSource> raster_source =
  152. recording_source->CreateRasterSource();
  153. // Tile sized iterators.
  154. {
  155. std::vector<const DrawImage*> images;
  156. raster_source->GetDiscardableImagesInRect(gfx::Rect(0, 0, 128, 128),
  157. &images);
  158. EXPECT_TRUE(images.empty());
  159. }
  160. // Shifted tile sized iterators.
  161. {
  162. std::vector<const DrawImage*> images;
  163. raster_source->GetDiscardableImagesInRect(gfx::Rect(140, 140, 128, 128),
  164. &images);
  165. EXPECT_TRUE(images.empty());
  166. }
  167. // Layer sized iterators.
  168. {
  169. std::vector<const DrawImage*> images;
  170. raster_source->GetDiscardableImagesInRect(gfx::Rect(0, 0, 256, 256),
  171. &images);
  172. EXPECT_TRUE(images.empty());
  173. }
  174. }
  175. TEST(RecordingSourceTest, DiscardableImages) {
  176. gfx::Rect recorded_viewport(0, 0, 256, 256);
  177. std::unique_ptr<FakeRecordingSource> recording_source =
  178. CreateRecordingSource(recorded_viewport);
  179. PaintImage discardable_image[2][2];
  180. discardable_image[0][0] = CreateDiscardablePaintImage(gfx::Size(32, 32));
  181. discardable_image[1][0] = CreateDiscardablePaintImage(gfx::Size(32, 32));
  182. discardable_image[1][1] = CreateDiscardablePaintImage(gfx::Size(32, 32));
  183. // Discardable images are found in the following cells:
  184. // |---|---|
  185. // | x | |
  186. // |---|---|
  187. // | x | x |
  188. // |---|---|
  189. recording_source->add_draw_image(discardable_image[0][0], gfx::Point(0, 0));
  190. recording_source->add_draw_image(discardable_image[1][0], gfx::Point(0, 130));
  191. recording_source->add_draw_image(discardable_image[1][1],
  192. gfx::Point(140, 140));
  193. recording_source->Rerecord();
  194. scoped_refptr<RasterSource> raster_source =
  195. recording_source->CreateRasterSource();
  196. // Tile sized iterators. These should find only one image.
  197. {
  198. std::vector<const DrawImage*> images;
  199. raster_source->GetDiscardableImagesInRect(gfx::Rect(0, 0, 128, 128),
  200. &images);
  201. EXPECT_EQ(1u, images.size());
  202. EXPECT_TRUE(images[0]->paint_image() == discardable_image[0][0]);
  203. }
  204. // Shifted tile sized iterators. These should find only one image.
  205. {
  206. std::vector<const DrawImage*> images;
  207. raster_source->GetDiscardableImagesInRect(gfx::Rect(140, 140, 128, 128),
  208. &images);
  209. EXPECT_EQ(1u, images.size());
  210. EXPECT_TRUE(images[0]->paint_image() == discardable_image[1][1]);
  211. }
  212. // Ensure there's no discardable images in the empty cell
  213. {
  214. std::vector<const DrawImage*> images;
  215. raster_source->GetDiscardableImagesInRect(gfx::Rect(140, 0, 128, 128),
  216. &images);
  217. EXPECT_TRUE(images.empty());
  218. }
  219. // Layer sized iterators. These should find all 3 images.
  220. {
  221. std::vector<const DrawImage*> images;
  222. raster_source->GetDiscardableImagesInRect(gfx::Rect(0, 0, 256, 256),
  223. &images);
  224. EXPECT_EQ(3u, images.size());
  225. EXPECT_TRUE(images[0]->paint_image() == discardable_image[0][0]);
  226. EXPECT_TRUE(images[1]->paint_image() == discardable_image[1][0]);
  227. EXPECT_TRUE(images[2]->paint_image() == discardable_image[1][1]);
  228. }
  229. }
  230. TEST(RecordingSourceTest, DiscardableImagesBaseNonDiscardable) {
  231. gfx::Rect recorded_viewport(0, 0, 512, 512);
  232. std::unique_ptr<FakeRecordingSource> recording_source =
  233. CreateRecordingSource(recorded_viewport);
  234. PaintImage non_discardable_image =
  235. CreateNonDiscardablePaintImage(gfx::Size(512, 512));
  236. PaintImage discardable_image[2][2];
  237. discardable_image[0][0] = CreateDiscardablePaintImage(gfx::Size(128, 128));
  238. discardable_image[0][1] = CreateDiscardablePaintImage(gfx::Size(128, 128));
  239. discardable_image[1][1] = CreateDiscardablePaintImage(gfx::Size(128, 128));
  240. // One large non-discardable image covers the whole grid.
  241. // Discardable images are found in the following cells:
  242. // |---|---|
  243. // | x | x |
  244. // |---|---|
  245. // | | x |
  246. // |---|---|
  247. recording_source->add_draw_image(non_discardable_image, gfx::Point(0, 0));
  248. recording_source->add_draw_image(discardable_image[0][0], gfx::Point(0, 0));
  249. recording_source->add_draw_image(discardable_image[0][1], gfx::Point(260, 0));
  250. recording_source->add_draw_image(discardable_image[1][1],
  251. gfx::Point(260, 260));
  252. recording_source->Rerecord();
  253. scoped_refptr<RasterSource> raster_source =
  254. recording_source->CreateRasterSource();
  255. // Tile sized iterators. These should find only one image.
  256. {
  257. std::vector<const DrawImage*> images;
  258. raster_source->GetDiscardableImagesInRect(gfx::Rect(0, 0, 256, 256),
  259. &images);
  260. EXPECT_EQ(1u, images.size());
  261. EXPECT_TRUE(images[0]->paint_image() == discardable_image[0][0]);
  262. }
  263. // Shifted tile sized iterators. These should find only one image.
  264. {
  265. std::vector<const DrawImage*> images;
  266. raster_source->GetDiscardableImagesInRect(gfx::Rect(260, 260, 256, 256),
  267. &images);
  268. EXPECT_EQ(1u, images.size());
  269. EXPECT_TRUE(images[0]->paint_image() == discardable_image[1][1]);
  270. }
  271. // Ensure there's no discardable images in the empty cell
  272. {
  273. std::vector<const DrawImage*> images;
  274. raster_source->GetDiscardableImagesInRect(gfx::Rect(0, 256, 256, 256),
  275. &images);
  276. EXPECT_TRUE(images.empty());
  277. }
  278. // Layer sized iterators. These should find three images.
  279. {
  280. std::vector<const DrawImage*> images;
  281. raster_source->GetDiscardableImagesInRect(gfx::Rect(0, 0, 512, 512),
  282. &images);
  283. EXPECT_EQ(3u, images.size());
  284. EXPECT_TRUE(images[0]->paint_image() == discardable_image[0][0]);
  285. EXPECT_TRUE(images[1]->paint_image() == discardable_image[0][1]);
  286. EXPECT_TRUE(images[2]->paint_image() == discardable_image[1][1]);
  287. }
  288. }
  289. TEST(RecordingSourceTest, AnalyzeIsSolid) {
  290. gfx::Size layer_bounds(400, 400);
  291. const std::vector<float> recording_scales = {1.f, 1.25f, 1.33f, 1.5f, 1.6f,
  292. 1.66f, 2.f, 2.25f, 2.5f};
  293. for (float recording_scale : recording_scales) {
  294. std::unique_ptr<FakeRecordingSource> recording_source =
  295. FakeRecordingSource::CreateFilledRecordingSource(layer_bounds);
  296. recording_source->SetRecordingScaleFactor(recording_scale);
  297. PaintFlags solid_flags;
  298. SkColor4f solid_color{0.1f, 0.2f, 0.3f, 1.0f};
  299. solid_flags.setColor(solid_color);
  300. SkColor4f non_solid_color{0.2f, 0.3f, 0.4f, 0.5f};
  301. PaintFlags non_solid_flags;
  302. non_solid_flags.setColor(non_solid_color);
  303. recording_source->add_draw_rect_with_flags(
  304. gfx::ScaleToEnclosingRect(gfx::Rect(layer_bounds), recording_scale),
  305. solid_flags);
  306. recording_source->Rerecord();
  307. scoped_refptr<RasterSource> raster = recording_source->CreateRasterSource();
  308. EXPECT_TRUE(raster->IsSolidColor())
  309. << " recording scale: " << recording_scale;
  310. EXPECT_EQ(raster->GetSolidColor(), solid_color);
  311. for (int y = 0; y < layer_bounds.height(); y += 50) {
  312. for (int x = 0; x < layer_bounds.width(); x += 50) {
  313. recording_source->reset_draws();
  314. recording_source->add_draw_rect_with_flags(
  315. gfx::ScaleToEnclosingRect(gfx::Rect(layer_bounds), recording_scale),
  316. solid_flags);
  317. recording_source->add_draw_rect_with_flags(
  318. gfx::Rect(std::round(x * recording_scale),
  319. std::round(y * recording_scale), 1, 1),
  320. non_solid_flags);
  321. recording_source->Rerecord();
  322. raster = recording_source->CreateRasterSource();
  323. EXPECT_FALSE(raster->IsSolidColor())
  324. << " recording scale: " << recording_scale << " pixel at: (" << x
  325. << ", " << y << ") was not solid.";
  326. }
  327. }
  328. }
  329. }
  330. } // namespace
  331. } // namespace cc