browser_view_renderer_unittest.cc 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740
  1. // Copyright 2014 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 "android_webview/browser/gfx/browser_view_renderer.h"
  5. #include <map>
  6. #include <memory>
  7. #include <queue>
  8. #include <utility>
  9. #include "android_webview/browser/gfx/child_frame.h"
  10. #include "android_webview/browser/gfx/compositor_frame_consumer.h"
  11. #include "android_webview/browser/gfx/render_thread_manager.h"
  12. #include "android_webview/browser/gfx/test/rendering_test.h"
  13. #include "base/bind.h"
  14. #include "base/location.h"
  15. #include "base/task/single_thread_task_runner.h"
  16. #include "base/threading/thread_task_runner_handle.h"
  17. #include "components/viz/common/quads/compositor_frame.h"
  18. #include "components/viz/common/surfaces/frame_sink_id.h"
  19. #include "content/public/test/test_synchronous_compositor_android.h"
  20. namespace android_webview {
  21. class SmokeTest : public RenderingTest {
  22. void StartTest() override {
  23. browser_view_renderer_->PostInvalidate(ActiveCompositor());
  24. }
  25. void DidDrawOnRT() override { EndTest(); }
  26. };
  27. RENDERING_TEST_F(SmokeTest);
  28. // Test the case where SynchronousCompositor is constructed after the RVH that
  29. // owns it is switched to be active.
  30. class ActiveCompositorSwitchBeforeConstructionTest : public RenderingTest {
  31. public:
  32. ActiveCompositorSwitchBeforeConstructionTest()
  33. : on_draw_count_(0), new_compositor_(nullptr) {}
  34. void StartTest() override {
  35. browser_view_renderer_->PostInvalidate(ActiveCompositor());
  36. }
  37. void DidOnDraw(bool success) override {
  38. on_draw_count_++;
  39. switch (on_draw_count_) {
  40. case 1:
  41. EXPECT_TRUE(success);
  42. // Change compositor here. And do another ondraw.
  43. // The previous active compositor id is 1, 0, now change it to 1, 1.
  44. browser_view_renderer_->SetActiveFrameSinkId(viz::FrameSinkId(1, 1));
  45. browser_view_renderer_->PostInvalidate(ActiveCompositor());
  46. break;
  47. case 2:
  48. // The 2nd ondraw is skipped because there is no active compositor at
  49. // the moment.
  50. EXPECT_FALSE(success);
  51. new_compositor_ = std::make_unique<content::TestSynchronousCompositor>(
  52. viz::FrameSinkId(1, 1));
  53. new_compositor_->SetClient(browser_view_renderer_.get());
  54. EXPECT_EQ(ActiveCompositor(), new_compositor_.get());
  55. browser_view_renderer_->PostInvalidate(ActiveCompositor());
  56. break;
  57. case 3:
  58. EXPECT_TRUE(success);
  59. compositor_ = std::move(new_compositor_);
  60. EXPECT_EQ(ActiveCompositor(), compositor_.get());
  61. browser_view_renderer_->PostInvalidate(ActiveCompositor());
  62. break;
  63. case 4:
  64. EXPECT_TRUE(success);
  65. EndTest();
  66. }
  67. }
  68. private:
  69. int on_draw_count_;
  70. std::unique_ptr<content::TestSynchronousCompositor> new_compositor_;
  71. };
  72. RENDERING_TEST_F(ActiveCompositorSwitchBeforeConstructionTest);
  73. // Test the case where SynchronousCompositor is constructed before the RVH that
  74. // owns it is switched to be active.
  75. class ActiveCompositorSwitchAfterConstructionTest : public RenderingTest {
  76. public:
  77. ActiveCompositorSwitchAfterConstructionTest()
  78. : on_draw_count_(0), new_compositor_(nullptr) {}
  79. void StartTest() override {
  80. browser_view_renderer_->PostInvalidate(ActiveCompositor());
  81. }
  82. void DidOnDraw(bool success) override {
  83. on_draw_count_++;
  84. switch (on_draw_count_) {
  85. case 1:
  86. EXPECT_TRUE(success);
  87. // Create a new compositor here. And switch it to be active. And then
  88. // do another ondraw.
  89. new_compositor_ = std::make_unique<content::TestSynchronousCompositor>(
  90. viz::FrameSinkId(1, 1));
  91. new_compositor_->SetClient(browser_view_renderer_.get());
  92. browser_view_renderer_->SetActiveFrameSinkId(viz::FrameSinkId(1, 1));
  93. EXPECT_EQ(ActiveCompositor(), new_compositor_.get());
  94. browser_view_renderer_->PostInvalidate(ActiveCompositor());
  95. break;
  96. case 2:
  97. EXPECT_TRUE(success);
  98. compositor_ = std::move(new_compositor_);
  99. EXPECT_EQ(ActiveCompositor(), compositor_.get());
  100. browser_view_renderer_->PostInvalidate(ActiveCompositor());
  101. break;
  102. case 3:
  103. EXPECT_TRUE(success);
  104. EndTest();
  105. }
  106. }
  107. private:
  108. int on_draw_count_;
  109. std::unique_ptr<content::TestSynchronousCompositor> new_compositor_;
  110. };
  111. RENDERING_TEST_F(ActiveCompositorSwitchAfterConstructionTest);
  112. class ClearViewTest : public RenderingTest {
  113. public:
  114. ClearViewTest() : on_draw_count_(0) {}
  115. void StartTest() override {
  116. browser_view_renderer_->PostInvalidate(ActiveCompositor());
  117. browser_view_renderer_->ClearView();
  118. }
  119. void DidOnDraw(bool success) override {
  120. on_draw_count_++;
  121. if (on_draw_count_ == 1) {
  122. // First OnDraw should be skipped due to ClearView.
  123. EXPECT_FALSE(success);
  124. browser_view_renderer_->DidUpdateContent(
  125. ActiveCompositor()); // Unset ClearView.
  126. browser_view_renderer_->PostInvalidate(ActiveCompositor());
  127. } else {
  128. // Following OnDraws should succeed.
  129. EXPECT_TRUE(success);
  130. }
  131. }
  132. void DidDrawOnRT() override { EndTest(); }
  133. private:
  134. int on_draw_count_;
  135. };
  136. RENDERING_TEST_F(ClearViewTest);
  137. class TestAnimateInAndOutOfScreen : public RenderingTest {
  138. public:
  139. TestAnimateInAndOutOfScreen() : on_draw_count_(0), draw_gl_count_on_rt_(0) {}
  140. void StartTest() override {
  141. initial_constraints_ = ParentCompositorDrawConstraints(
  142. window_->surface_size(), gfx::Transform());
  143. new_constraints_ = ParentCompositorDrawConstraints(window_->surface_size(),
  144. gfx::Transform());
  145. new_constraints_.transform.Scale(2.0, 2.0);
  146. browser_view_renderer_->PostInvalidate(ActiveCompositor());
  147. }
  148. void WillOnDraw() override {
  149. RenderingTest::WillOnDraw();
  150. // Step 0: A single onDraw on screen. The parent draw constraints
  151. // of the BVR will updated to be the initial constraints.
  152. // Step 1: A single onDrraw off screen. The parent draw constraints of the
  153. // BVR will be updated to the new constraints.
  154. // Step 2: This onDraw is to introduce the DrawGL that animates the
  155. // webview onto the screen on render thread. End the test when the parent
  156. // draw constraints of BVR is updated to initial constraints.
  157. if (on_draw_count_ == 1 || on_draw_count_ == 2)
  158. browser_view_renderer_->PrepareToDraw(gfx::Point(), gfx::Rect());
  159. }
  160. void DidOnDraw(bool success) override {
  161. EXPECT_TRUE(success);
  162. on_draw_count_++;
  163. }
  164. bool WillDrawOnRT(HardwareRendererDrawParams* params) override {
  165. if (draw_gl_count_on_rt_ == 1) {
  166. draw_gl_count_on_rt_++;
  167. ui_task_runner_->PostTask(
  168. FROM_HERE,
  169. base::BindOnce(&RenderingTest::PostInvalidate, base::Unretained(this),
  170. /*inside_vsync=*/false));
  171. return false;
  172. }
  173. params->width = window_->surface_size().width();
  174. params->height = window_->surface_size().height();
  175. gfx::Transform transform;
  176. if (draw_gl_count_on_rt_ == 0)
  177. transform = new_constraints_.transform;
  178. transform.matrix().getColMajor(params->transform);
  179. return true;
  180. }
  181. void DidDrawOnRT() override { draw_gl_count_on_rt_++; }
  182. bool DrawConstraintsEquals(
  183. const ParentCompositorDrawConstraints& constraints1,
  184. const ParentCompositorDrawConstraints& constraints2) {
  185. return constraints1 == constraints2;
  186. }
  187. void OnParentDrawDataUpdated() override {
  188. ParentCompositorDrawConstraints constraints;
  189. viz::FrameSinkId frame_sink_id;
  190. viz::FrameTimingDetailsMap timing_details;
  191. uint32_t frame_token = 0u;
  192. GetCompositorFrameConsumer()->TakeParentDrawDataOnUI(
  193. &constraints, &frame_sink_id, &timing_details, &frame_token);
  194. switch (on_draw_count_) {
  195. case 0u:
  196. // This OnParentDrawDataUpdated is generated by
  197. // connecting the compositor frame consumer to the producer.
  198. break;
  199. case 1u:
  200. EXPECT_TRUE(DrawConstraintsEquals(constraints, new_constraints_));
  201. break;
  202. case 3u:
  203. EXPECT_TRUE(DrawConstraintsEquals(constraints, initial_constraints_));
  204. EndTest();
  205. break;
  206. // There will be a following 4th onDraw. But the hardware renderer won't
  207. // post back the draw constraints in DrawGL because the constraints
  208. // don't change.
  209. default:
  210. FAIL();
  211. }
  212. }
  213. private:
  214. int on_draw_count_;
  215. int draw_gl_count_on_rt_;
  216. ParentCompositorDrawConstraints initial_constraints_;
  217. ParentCompositorDrawConstraints new_constraints_;
  218. };
  219. RENDERING_TEST_F(TestAnimateInAndOutOfScreen);
  220. class TestAnimateOnScreenWithoutOnDraw : public RenderingTest {
  221. public:
  222. void StartTest() override {
  223. browser_view_renderer_->PostInvalidate(ActiveCompositor());
  224. }
  225. void WillOnDraw() override {
  226. RenderingTest::WillOnDraw();
  227. // Set empty tile viewport on first frame.
  228. browser_view_renderer_->PrepareToDraw(gfx::Point(), gfx::Rect());
  229. }
  230. void DidOnDraw(bool success) override {
  231. EXPECT_TRUE(success);
  232. on_draw_count_++;
  233. }
  234. bool WillDrawOnRT(HardwareRendererDrawParams* params) override {
  235. will_draw_on_rt_count_++;
  236. // What happens in practice is draw functor is skipped initially since
  237. // it is offscreen so entirely clipped. Then later, the webview is moved
  238. // onscreen without another OnDrawon UI thread, and draw functor is called
  239. // with non-empty clip. Here in the test we pretend this second draw happens
  240. // immediately.
  241. bool result = RenderingTest::WillDrawOnRT(params);
  242. assertNonEmptyClip(params);
  243. return result;
  244. }
  245. void OnParentDrawDataUpdated() override {
  246. switch (on_draw_count_) {
  247. case 0:
  248. // This OnParentDrawDataUpdated is generated by
  249. // connecting the compositor frame consumer to the producer.
  250. break;
  251. case 1:
  252. // DrawOnRT skipped for frame 1 so this should not happen.
  253. EXPECT_TRUE(window_->on_draw_hardware_pending());
  254. EndTest();
  255. break;
  256. case 2:
  257. // Might happen due to invalidate on_draw_hardware_pending from
  258. // previous frame.
  259. break;
  260. default:
  261. FAIL();
  262. }
  263. }
  264. private:
  265. void assertNonEmptyClip(HardwareRendererDrawParams* params) {
  266. gfx::Rect clip(params->clip_left, params->clip_top,
  267. params->clip_right - params->clip_left,
  268. params->clip_bottom - params->clip_top);
  269. ASSERT_FALSE(clip.IsEmpty());
  270. }
  271. int on_draw_count_ = 0;
  272. int will_draw_on_rt_count_ = 0;
  273. };
  274. RENDERING_TEST_F(TestAnimateOnScreenWithoutOnDraw);
  275. class CompositorNoFrameTest : public RenderingTest {
  276. public:
  277. CompositorNoFrameTest() : on_draw_count_(0) {}
  278. void StartTest() override {
  279. browser_view_renderer_->PostInvalidate(ActiveCompositor());
  280. }
  281. void WillOnDraw() override {
  282. if (0 == on_draw_count_) {
  283. // No frame from compositor.
  284. } else if (1 == on_draw_count_) {
  285. compositor_->SetHardwareFrame(0u, ConstructEmptyFrame());
  286. } else if (2 == on_draw_count_) {
  287. // No frame from compositor.
  288. }
  289. // There may be trailing invalidates.
  290. }
  291. void DidOnDraw(bool success) override {
  292. // OnDraw should succeed even when there are no frames from compositor.
  293. EXPECT_TRUE(success);
  294. if (0 == on_draw_count_) {
  295. browser_view_renderer_->PostInvalidate(ActiveCompositor());
  296. } else if (1 == on_draw_count_) {
  297. browser_view_renderer_->PostInvalidate(ActiveCompositor());
  298. } else if (2 == on_draw_count_) {
  299. EndTest();
  300. }
  301. on_draw_count_++;
  302. }
  303. private:
  304. int on_draw_count_;
  305. };
  306. RENDERING_TEST_F(CompositorNoFrameTest);
  307. class ClientIsVisibleOnConstructionTest : public RenderingTest {
  308. void SetUpTestHarness() override {
  309. browser_view_renderer_ = std::make_unique<BrowserViewRenderer>(
  310. this, base::ThreadTaskRunnerHandle::Get());
  311. }
  312. void StartTest() override {
  313. EXPECT_FALSE(browser_view_renderer_->attached_to_window());
  314. EXPECT_FALSE(browser_view_renderer_->window_visible_for_tests());
  315. EXPECT_TRUE(browser_view_renderer_->IsClientVisible());
  316. EndTest();
  317. }
  318. };
  319. RENDERING_TEST_F(ClientIsVisibleOnConstructionTest);
  320. class ClientIsVisibleAfterAttachTest : public RenderingTest {
  321. void StartTest() override {
  322. EXPECT_TRUE(browser_view_renderer_->attached_to_window());
  323. EXPECT_TRUE(browser_view_renderer_->window_visible_for_tests());
  324. EXPECT_TRUE(browser_view_renderer_->IsClientVisible());
  325. EndTest();
  326. }
  327. };
  328. RENDERING_TEST_F(ClientIsVisibleAfterAttachTest);
  329. class ClientIsInvisibleAfterWindowGoneTest : public RenderingTest {
  330. void StartTest() override {
  331. browser_view_renderer_->SetWindowVisibility(false);
  332. EXPECT_FALSE(browser_view_renderer_->IsClientVisible());
  333. EndTest();
  334. }
  335. };
  336. RENDERING_TEST_F(ClientIsInvisibleAfterWindowGoneTest);
  337. class ClientIsInvisibleAfterDetachTest : public RenderingTest {
  338. void StartTest() override {
  339. browser_view_renderer_->OnDetachedFromWindow();
  340. EXPECT_FALSE(browser_view_renderer_->IsClientVisible());
  341. EndTest();
  342. }
  343. };
  344. RENDERING_TEST_F(ClientIsInvisibleAfterDetachTest);
  345. class ResourceRenderingTest : public RenderingTest {
  346. public:
  347. using ResourceCountMap = std::map<viz::ResourceId, int>;
  348. using LayerTreeFrameSinkResourceCountMap =
  349. std::map<uint32_t, ResourceCountMap>;
  350. virtual std::unique_ptr<content::SynchronousCompositor::Frame> GetFrame(
  351. int frame_number) = 0;
  352. void StartTest() override {
  353. frame_number_ = 0;
  354. AdvanceFrame();
  355. }
  356. void WillOnDraw() override {
  357. if (next_frame_) {
  358. compositor_->SetHardwareFrame(next_frame_->layer_tree_frame_sink_id,
  359. std::move(next_frame_->frame));
  360. }
  361. }
  362. void DidOnDraw(bool success) override {
  363. EXPECT_EQ(next_frame_ != nullptr, success);
  364. if (!AdvanceFrame()) {
  365. ui_task_runner_->PostTask(
  366. FROM_HERE, base::BindOnce(&ResourceRenderingTest::CheckResults,
  367. base::Unretained(this)));
  368. }
  369. }
  370. LayerTreeFrameSinkResourceCountMap GetReturnedResourceCounts() {
  371. LayerTreeFrameSinkResourceCountMap counts;
  372. content::TestSynchronousCompositor::FrameAckArray returned_resources_array;
  373. compositor_->SwapReturnedResources(&returned_resources_array);
  374. for (const auto& resources : returned_resources_array) {
  375. for (const auto& returned_resource : resources.resources) {
  376. counts[resources.layer_tree_frame_sink_id][returned_resource.id] +=
  377. returned_resource.count;
  378. }
  379. }
  380. return counts;
  381. }
  382. virtual void CheckResults() = 0;
  383. private:
  384. bool AdvanceFrame() {
  385. next_frame_ = GetFrame(frame_number_++);
  386. if (next_frame_) {
  387. browser_view_renderer_->PostInvalidate(ActiveCompositor());
  388. return true;
  389. }
  390. return false;
  391. }
  392. std::unique_ptr<content::SynchronousCompositor::Frame> next_frame_;
  393. int frame_number_;
  394. };
  395. class SwitchLayerTreeFrameSinkIdTest : public ResourceRenderingTest {
  396. struct FrameInfo {
  397. FrameInfo(uint32_t frame_sink_id, viz::ResourceId id)
  398. : layer_tree_frame_sink_id(frame_sink_id), resource_id(id) {}
  399. uint32_t layer_tree_frame_sink_id;
  400. viz::ResourceId resource_id; // Each frame contains a single resource.
  401. };
  402. std::unique_ptr<content::SynchronousCompositor::Frame> GetFrame(
  403. int frame_number) override {
  404. static const FrameInfo infos[] = {
  405. // First output surface.
  406. {0u, viz::ResourceId(1u)},
  407. {0u, viz::ResourceId(1u)},
  408. {0u, viz::ResourceId(2u)},
  409. {0u, viz::ResourceId(2u)},
  410. {0u, viz::ResourceId(3u)},
  411. {0u, viz::ResourceId(3u)},
  412. {0u, viz::ResourceId(4u)},
  413. // Second output surface.
  414. {1u, viz::ResourceId(1u)},
  415. {1u, viz::ResourceId(1u)},
  416. {1u, viz::ResourceId(2u)},
  417. {1u, viz::ResourceId(2u)},
  418. {1u, viz::ResourceId(3u)},
  419. {1u, viz::ResourceId(3u)},
  420. {1u, viz::ResourceId(4u)},
  421. };
  422. if (frame_number >= static_cast<int>(std::size(infos))) {
  423. return nullptr;
  424. }
  425. std::unique_ptr<content::SynchronousCompositor::Frame> frame(
  426. new content::SynchronousCompositor::Frame);
  427. frame->layer_tree_frame_sink_id =
  428. infos[frame_number].layer_tree_frame_sink_id;
  429. frame->frame = ConstructFrame(infos[frame_number].resource_id);
  430. if (last_layer_tree_frame_sink_id_ !=
  431. infos[frame_number].layer_tree_frame_sink_id) {
  432. expected_return_count_.clear();
  433. last_layer_tree_frame_sink_id_ =
  434. infos[frame_number].layer_tree_frame_sink_id;
  435. }
  436. ++expected_return_count_[infos[frame_number].resource_id];
  437. return frame;
  438. }
  439. void StartTest() override {
  440. last_layer_tree_frame_sink_id_ = -1U;
  441. ResourceRenderingTest::StartTest();
  442. }
  443. void CheckResults() override {
  444. window_->Detach();
  445. functor_->ReleaseOnUIWithInvoke();
  446. ui_task_runner_->PostTask(
  447. FROM_HERE,
  448. base::BindOnce(&SwitchLayerTreeFrameSinkIdTest::PostedCheckResults,
  449. base::Unretained(this)));
  450. }
  451. void PostedCheckResults() {
  452. // Make sure resources for the last output surface are returned.
  453. EXPECT_EQ(expected_return_count_,
  454. GetReturnedResourceCounts()[last_layer_tree_frame_sink_id_]);
  455. EndTest();
  456. }
  457. private:
  458. uint32_t last_layer_tree_frame_sink_id_;
  459. ResourceCountMap expected_return_count_;
  460. };
  461. RENDERING_TEST_F(SwitchLayerTreeFrameSinkIdTest);
  462. class RenderThreadManagerDeletionTest : public ResourceRenderingTest {
  463. std::unique_ptr<content::SynchronousCompositor::Frame> GetFrame(
  464. int frame_number) override {
  465. if (frame_number > 0) {
  466. return nullptr;
  467. }
  468. const uint32_t layer_tree_frame_sink_id = 0u;
  469. const viz::ResourceId resource_id =
  470. static_cast<viz::ResourceId>(frame_number);
  471. std::unique_ptr<content::SynchronousCompositor::Frame> frame(
  472. new content::SynchronousCompositor::Frame);
  473. frame->layer_tree_frame_sink_id = layer_tree_frame_sink_id;
  474. frame->frame = ConstructFrame(resource_id);
  475. ++expected_return_count_[layer_tree_frame_sink_id][resource_id];
  476. return frame;
  477. }
  478. void CheckResults() override {
  479. functor_.reset();
  480. ui_task_runner_->PostTask(
  481. FROM_HERE,
  482. base::BindOnce(&RenderThreadManagerDeletionTest::PostedCheckResults,
  483. base::Unretained(this)));
  484. }
  485. void PostedCheckResults() {
  486. // Make sure resources for the last frame are returned.
  487. EXPECT_EQ(expected_return_count_, GetReturnedResourceCounts());
  488. EndTest();
  489. }
  490. private:
  491. LayerTreeFrameSinkResourceCountMap expected_return_count_;
  492. };
  493. RENDERING_TEST_F(RenderThreadManagerDeletionTest);
  494. class RenderThreadManagerDeletionOnRTTest : public ResourceRenderingTest {
  495. std::unique_ptr<content::SynchronousCompositor::Frame> GetFrame(
  496. int frame_number) override {
  497. if (frame_number > 0) {
  498. return nullptr;
  499. }
  500. const uint32_t layer_tree_frame_sink_id = 0u;
  501. const viz::ResourceId resource_id =
  502. static_cast<viz::ResourceId>(frame_number);
  503. std::unique_ptr<content::SynchronousCompositor::Frame> frame(
  504. new content::SynchronousCompositor::Frame);
  505. frame->layer_tree_frame_sink_id = layer_tree_frame_sink_id;
  506. frame->frame = ConstructFrame(resource_id);
  507. ++expected_return_count_[layer_tree_frame_sink_id][resource_id];
  508. return frame;
  509. }
  510. void CheckResults() override {
  511. functor_->ReleaseOnUIWithoutInvoke(
  512. base::BindOnce(&RenderThreadManagerDeletionOnRTTest::PostedCheckResults,
  513. base::Unretained(this)));
  514. }
  515. void PostedCheckResults() {
  516. // Make sure resources for the last frame are returned.
  517. EXPECT_EQ(expected_return_count_, GetReturnedResourceCounts());
  518. EndTest();
  519. }
  520. private:
  521. LayerTreeFrameSinkResourceCountMap expected_return_count_;
  522. };
  523. RENDERING_TEST_F(RenderThreadManagerDeletionOnRTTest);
  524. class RenderThreadManagerSwitchTest : public ResourceRenderingTest {
  525. std::unique_ptr<content::SynchronousCompositor::Frame> GetFrame(
  526. int frame_number) override {
  527. switch (frame_number) {
  528. case 0: {
  529. // Draw a frame with initial RTM.
  530. break;
  531. }
  532. case 1: {
  533. // Switch to new RTM.
  534. std::unique_ptr<FakeFunctor> functor(new FakeFunctor);
  535. functor->Init(window_.get(), std::make_unique<RenderThreadManager>(
  536. base::ThreadTaskRunnerHandle::Get()));
  537. browser_view_renderer_->SetCurrentCompositorFrameConsumer(
  538. functor->GetCompositorFrameConsumer());
  539. saved_functor_ = std::move(functor_);
  540. functor_ = std::move(functor);
  541. break;
  542. }
  543. case 2: {
  544. // Draw a frame with the new RTM, but also redraw the initial RTM.
  545. window_->RequestDrawGL(saved_functor_.get());
  546. break;
  547. }
  548. case 3: {
  549. // Switch back to the initial RTM, allowing the new RTM to be destroyed.
  550. functor_ = std::move(saved_functor_);
  551. browser_view_renderer_->SetCurrentCompositorFrameConsumer(
  552. functor_->GetCompositorFrameConsumer());
  553. break;
  554. }
  555. default:
  556. return nullptr;
  557. }
  558. const uint32_t layer_tree_frame_sink_id = 0u;
  559. const viz::ResourceId resource_id =
  560. static_cast<viz::ResourceId>(frame_number);
  561. std::unique_ptr<content::SynchronousCompositor::Frame> frame(
  562. new content::SynchronousCompositor::Frame);
  563. frame->layer_tree_frame_sink_id = layer_tree_frame_sink_id;
  564. frame->frame = ConstructFrame(resource_id);
  565. ++expected_return_count_[layer_tree_frame_sink_id][resource_id];
  566. return frame;
  567. }
  568. void CheckResults() override {
  569. functor_.reset();
  570. ui_task_runner_->PostTask(
  571. FROM_HERE,
  572. base::BindOnce(&RenderThreadManagerSwitchTest::PostedCheckResults,
  573. base::Unretained(this)));
  574. }
  575. void PostedCheckResults() {
  576. // Make sure resources for all frames are returned.
  577. EXPECT_EQ(expected_return_count_, GetReturnedResourceCounts());
  578. EndTest();
  579. }
  580. private:
  581. std::unique_ptr<FakeFunctor> saved_functor_;
  582. LayerTreeFrameSinkResourceCountMap expected_return_count_;
  583. };
  584. RENDERING_TEST_F(RenderThreadManagerSwitchTest);
  585. // Test for https://crbug.com/881458, this test is to make sure we will reach
  586. // the maximal scroll offset.
  587. class DidReachMaximalScrollOffsetTest : public RenderingTest {
  588. public:
  589. void StartTest() override {
  590. browser_view_renderer_->SetDipScale(kDipScale);
  591. gfx::PointF total_scroll_offset = kTotalScrollOffset;
  592. gfx::PointF total_max_scroll_offset = kTotalMaxScrollOffset;
  593. gfx::SizeF scrollable_size = kScrollableSize;
  594. total_scroll_offset.Scale(kDipScale);
  595. total_max_scroll_offset.Scale(kDipScale);
  596. scrollable_size.Scale(kDipScale);
  597. // |UpdateRootLayerState()| will call |SetTotalRootLayerScrollOffset()|.
  598. browser_view_renderer_->UpdateRootLayerState(
  599. ActiveCompositor(), total_scroll_offset, total_max_scroll_offset,
  600. scrollable_size, kPageScaleFactor, kMinPageScaleFactor,
  601. kMaxPageScaleFactor);
  602. }
  603. void ScrollContainerViewTo(const gfx::Point& new_value) override {
  604. EXPECT_EQ(kExpectedScrollOffset, new_value);
  605. EndTest();
  606. }
  607. private:
  608. static constexpr float kDipScale = 2.625f;
  609. static const gfx::PointF kTotalScrollOffset;
  610. static const gfx::PointF kTotalMaxScrollOffset;
  611. static const gfx::SizeF kScrollableSize;
  612. static constexpr float kPageScaleFactor = 1.f;
  613. // These two are not used in this test.
  614. static constexpr float kMinPageScaleFactor = 1.f;
  615. static constexpr float kMaxPageScaleFactor = 5.f;
  616. static const gfx::Point kExpectedScrollOffset;
  617. };
  618. // The current scroll offset in logical pixel, which is at the end.
  619. const gfx::PointF DidReachMaximalScrollOffsetTest::kTotalScrollOffset =
  620. gfx::PointF(0.f, 6132.f);
  621. // The maximum possible scroll offset in logical pixel.
  622. const gfx::PointF DidReachMaximalScrollOffsetTest::kTotalMaxScrollOffset =
  623. gfx::PointF(0.f, 6132.f);
  624. // This is what passed to CTS test, not used for this test.
  625. const gfx::SizeF DidReachMaximalScrollOffsetTest::kScrollableSize =
  626. gfx::SizeF(412.f, 6712.f);
  627. // In max_scroll_offset() we are using ceiling rounding for scaled scroll
  628. // offset. Therefore ceiling(2.625 * 6132 = 16096.5) = 16097.
  629. const gfx::Point DidReachMaximalScrollOffsetTest::kExpectedScrollOffset =
  630. gfx::Point(0, 16097);
  631. RENDERING_TEST_F(DidReachMaximalScrollOffsetTest);
  632. } // namespace android_webview