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 
5 #include "android_webview/browser/gfx/test/rendering_test.h"
6 
7 #include <memory>
8 #include <utility>
9 
10 #include "android_webview/browser/gfx/browser_view_renderer.h"
11 #include "android_webview/browser/gfx/child_frame.h"
12 #include "android_webview/browser/gfx/render_thread_manager.h"
13 #include "base/bind.h"
14 #include "base/command_line.h"
15 #include "base/location.h"
16 #include "base/test/task_environment.h"
17 #include "base/threading/thread_task_runner_handle.h"
18 #include "components/viz/common/quads/compositor_frame.h"
19 #include "components/viz/common/surfaces/frame_sink_id.h"
20 #include "components/viz/test/compositor_frame_helpers.h"
21 #include "content/public/browser/android/synchronous_compositor.h"
22 #include "content/public/test/test_synchronous_compositor_android.h"
23 
24 namespace android_webview {
25 
26 namespace {
27 // BrowserViewRenderer subclass used for enabling tests to observe
28 // OnParentDrawDataUpdated.
29 class TestBrowserViewRenderer : public BrowserViewRenderer {
30  public:
TestBrowserViewRenderer(RenderingTest * rendering_test,const scoped_refptr<base::SingleThreadTaskRunner> & ui_task_runner)31   TestBrowserViewRenderer(
32       RenderingTest* rendering_test,
33       const scoped_refptr<base::SingleThreadTaskRunner>& ui_task_runner)
34       : BrowserViewRenderer(rendering_test, ui_task_runner),
35         rendering_test_(rendering_test) {}
36 
~TestBrowserViewRenderer()37   ~TestBrowserViewRenderer() override {}
38 
OnParentDrawDataUpdated(CompositorFrameConsumer * compositor_frame_consumer)39   void OnParentDrawDataUpdated(
40       CompositorFrameConsumer* compositor_frame_consumer) override {
41     BrowserViewRenderer::OnParentDrawDataUpdated(compositor_frame_consumer);
42     rendering_test_->OnParentDrawDataUpdated();
43   }
44 
45  private:
46   RenderingTest* const rendering_test_;
47 };
48 }  // namespace
49 
RenderingTest()50 RenderingTest::RenderingTest()
51     : task_environment_(std::make_unique<base::test::TaskEnvironment>()) {
52   ui_task_runner_ = base::ThreadTaskRunnerHandle::Get();
53 }
54 
~RenderingTest()55 RenderingTest::~RenderingTest() {
56   DCHECK(ui_task_runner_->BelongsToCurrentThread());
57   if (window_.get())
58     window_->Detach();
59 }
60 
CreateDrawable()61 ui::TouchHandleDrawable* RenderingTest::CreateDrawable() {
62   return nullptr;
63 }
64 
SetUpTestHarness()65 void RenderingTest::SetUpTestHarness() {
66   DCHECK(!browser_view_renderer_.get());
67   DCHECK(!functor_.get());
68   browser_view_renderer_.reset(
69       new TestBrowserViewRenderer(this, base::ThreadTaskRunnerHandle::Get()));
70   browser_view_renderer_->SetActiveFrameSinkId(viz::FrameSinkId(0, 0));
71   InitializeCompositor();
72   std::unique_ptr<FakeWindow> window(
73       new FakeWindow(browser_view_renderer_.get(), this, gfx::Rect(100, 100)));
74   functor_.reset(new FakeFunctor);
75   functor_->Init(window.get(), std::make_unique<RenderThreadManager>(
76                                    base::ThreadTaskRunnerHandle::Get()));
77   browser_view_renderer_->SetCurrentCompositorFrameConsumer(
78       functor_->GetCompositorFrameConsumer());
79   window_ = std::move(window);
80 }
81 
GetCompositorFrameConsumer()82 CompositorFrameConsumer* RenderingTest::GetCompositorFrameConsumer() {
83   return functor_->GetCompositorFrameConsumer();
84 }
85 
GetCompositorFrameProducer()86 CompositorFrameProducer* RenderingTest::GetCompositorFrameProducer() {
87   return browser_view_renderer_.get();
88 }
89 
InitializeCompositor()90 void RenderingTest::InitializeCompositor() {
91   DCHECK(!compositor_.get());
92   DCHECK(browser_view_renderer_.get());
93   compositor_.reset(
94       new content::TestSynchronousCompositor(viz::FrameSinkId(0, 0)));
95   compositor_->SetClient(browser_view_renderer_.get());
96 }
97 
RunTest()98 void RenderingTest::RunTest() {
99   SetUpTestHarness();
100 
101   ui_task_runner_->PostTask(FROM_HERE, base::BindOnce(&RenderingTest::StartTest,
102                                                       base::Unretained(this)));
103   run_loop_.Run();
104 }
105 
StartTest()106 void RenderingTest::StartTest() {
107   EndTest();
108 }
109 
EndTest()110 void RenderingTest::EndTest() {
111   run_loop_.QuitWhenIdle();
112 }
113 
ActiveCompositor() const114 content::SynchronousCompositor* RenderingTest::ActiveCompositor() const {
115   return browser_view_renderer_->GetActiveCompositorForTesting();
116 }
117 
ConstructEmptyFrame()118 std::unique_ptr<viz::CompositorFrame> RenderingTest::ConstructEmptyFrame() {
119   gfx::Rect viewport(browser_view_renderer_->size());
120   return std::make_unique<viz::CompositorFrame>(
121       viz::CompositorFrameBuilder().AddRenderPass(viewport, viewport).Build());
122 }
123 
ConstructFrame(viz::ResourceId resource_id)124 std::unique_ptr<viz::CompositorFrame> RenderingTest::ConstructFrame(
125     viz::ResourceId resource_id) {
126   std::unique_ptr<viz::CompositorFrame> compositor_frame(ConstructEmptyFrame());
127   viz::TransferableResource resource;
128   resource.id = resource_id;
129   compositor_frame->resource_list.push_back(resource);
130   return compositor_frame;
131 }
132 
GetFunctor()133 FakeFunctor* RenderingTest::GetFunctor() {
134   return functor_.get();
135 }
136 
WillOnDraw()137 void RenderingTest::WillOnDraw() {
138   DCHECK(compositor_);
139   compositor_->SetHardwareFrame(0u, ConstructEmptyFrame());
140 }
141 
WillDrawOnRT(HardwareRendererDrawParams * params)142 bool RenderingTest::WillDrawOnRT(HardwareRendererDrawParams* params) {
143   params->width = window_->surface_size().width();
144   params->height = window_->surface_size().height();
145   gfx::Transform transform;
146   transform.matrix().asColMajorf(params->transform);
147   return true;
148 }
149 
OnNewPicture()150 void RenderingTest::OnNewPicture() {}
151 
PostInvalidate()152 void RenderingTest::PostInvalidate() {
153   if (window_)
154     window_->PostInvalidate();
155 }
156 
GetLocationOnScreen()157 gfx::Point RenderingTest::GetLocationOnScreen() {
158   return gfx::Point();
159 }
160 
161 }  // namespace android_webview
162