OLD | NEW |
| (Empty) |
1 // Copyright 2016 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 "cc/test/test_delegating_output_surface.h" | |
6 | |
7 #include <stdint.h> | |
8 #include <utility> | |
9 | |
10 #include "cc/output/begin_frame_args.h" | |
11 #include "cc/output/copy_output_request.h" | |
12 #include "cc/output/direct_renderer.h" | |
13 #include "cc/output/texture_mailbox_deleter.h" | |
14 | |
15 static constexpr uint32_t kCompositorClientId = 1; | |
16 | |
17 namespace cc { | |
18 | |
19 TestDelegatingOutputSurface::TestDelegatingOutputSurface( | |
20 scoped_refptr<ContextProvider> compositor_context_provider, | |
21 scoped_refptr<ContextProvider> worker_context_provider, | |
22 std::unique_ptr<OutputSurface> display_output_surface, | |
23 SharedBitmapManager* shared_bitmap_manager, | |
24 gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, | |
25 const RendererSettings& renderer_settings, | |
26 base::SingleThreadTaskRunner* task_runner, | |
27 bool synchronous_composite, | |
28 bool force_disable_reclaim_resources) | |
29 : OutputSurface(std::move(compositor_context_provider), | |
30 std::move(worker_context_provider), | |
31 nullptr), | |
32 surface_manager_(new SurfaceManager), | |
33 surface_id_allocator_(new SurfaceIdAllocator(kCompositorClientId)), | |
34 surface_factory_(new SurfaceFactory(surface_manager_.get(), this)), | |
35 weak_ptrs_(this) { | |
36 std::unique_ptr<SyntheticBeginFrameSource> begin_frame_source; | |
37 std::unique_ptr<DisplayScheduler> scheduler; | |
38 if (!synchronous_composite) { | |
39 if (renderer_settings.disable_display_vsync) { | |
40 begin_frame_source.reset(new BackToBackBeginFrameSource( | |
41 base::MakeUnique<DelayBasedTimeSource>(task_runner))); | |
42 } else { | |
43 begin_frame_source.reset(new DelayBasedBeginFrameSource( | |
44 base::MakeUnique<DelayBasedTimeSource>(task_runner))); | |
45 begin_frame_source->SetAuthoritativeVSyncInterval( | |
46 base::TimeDelta::FromMilliseconds(1000.f / | |
47 renderer_settings.refresh_rate)); | |
48 } | |
49 scheduler.reset(new DisplayScheduler( | |
50 begin_frame_source.get(), task_runner, | |
51 display_output_surface->capabilities().max_frames_pending)); | |
52 } | |
53 const bool context_shared_with_compositor = | |
54 display_output_surface->context_provider() == context_provider(); | |
55 display_.reset( | |
56 new Display(shared_bitmap_manager, gpu_memory_buffer_manager, | |
57 renderer_settings, std::move(begin_frame_source), | |
58 std::move(display_output_surface), std::move(scheduler), | |
59 base::MakeUnique<TextureMailboxDeleter>(task_runner))); | |
60 | |
61 capabilities_.delegated_rendering = true; | |
62 // Since this OutputSurface and the Display are tightly coupled and in the | |
63 // same process/thread, the LayerTreeHostImpl can reclaim resources from | |
64 // the Display. But we allow tests to disable this to mimic an out-of-process | |
65 // Display. | |
66 capabilities_.can_force_reclaim_resources = !force_disable_reclaim_resources; | |
67 capabilities_.delegated_sync_points_required = | |
68 !context_shared_with_compositor; | |
69 } | |
70 | |
71 TestDelegatingOutputSurface::~TestDelegatingOutputSurface() { | |
72 DCHECK(copy_requests_.empty()); | |
73 } | |
74 | |
75 void TestDelegatingOutputSurface::RequestCopyOfOutput( | |
76 std::unique_ptr<CopyOutputRequest> request) { | |
77 copy_requests_.push_back(std::move(request)); | |
78 } | |
79 | |
80 bool TestDelegatingOutputSurface::BindToClient(OutputSurfaceClient* client) { | |
81 if (!OutputSurface::BindToClient(client)) | |
82 return false; | |
83 | |
84 // We want the Display's output surface to hear about lost context, and since | |
85 // this shares a context with it (when delegated_sync_points_required is | |
86 // false), we should not be listening for lost context callbacks on the | |
87 // context here. | |
88 if (!capabilities_.delegated_sync_points_required && context_provider()) | |
89 context_provider()->SetLostContextCallback(base::Closure()); | |
90 | |
91 surface_manager_->RegisterSurfaceClientId(surface_id_allocator_->client_id()); | |
92 surface_manager_->RegisterSurfaceFactoryClient( | |
93 surface_id_allocator_->client_id(), this); | |
94 display_->Initialize(this, surface_manager_.get(), | |
95 surface_id_allocator_->client_id()); | |
96 display_->renderer_for_testing()->SetEnlargePassTextureAmountForTesting( | |
97 enlarge_pass_texture_amount_); | |
98 display_->SetVisible(true); | |
99 bound_ = true; | |
100 return true; | |
101 } | |
102 | |
103 void TestDelegatingOutputSurface::DetachFromClient() { | |
104 // Some tests make BindToClient fail on purpose. ^__^ | |
105 if (bound_) { | |
106 if (!delegated_surface_id_.is_null()) | |
107 surface_factory_->Destroy(delegated_surface_id_); | |
108 surface_manager_->UnregisterSurfaceFactoryClient( | |
109 surface_id_allocator_->client_id()); | |
110 surface_manager_->InvalidateSurfaceClientId( | |
111 surface_id_allocator_->client_id()); | |
112 bound_ = false; | |
113 } | |
114 display_ = nullptr; | |
115 surface_factory_ = nullptr; | |
116 surface_id_allocator_ = nullptr; | |
117 surface_manager_ = nullptr; | |
118 weak_ptrs_.InvalidateWeakPtrs(); | |
119 OutputSurface::DetachFromClient(); | |
120 } | |
121 | |
122 void TestDelegatingOutputSurface::SwapBuffers(CompositorFrame frame) { | |
123 if (test_client_) | |
124 test_client_->DisplayReceivedCompositorFrame(frame); | |
125 | |
126 if (delegated_surface_id_.is_null()) { | |
127 delegated_surface_id_ = surface_id_allocator_->GenerateId(); | |
128 surface_factory_->Create(delegated_surface_id_); | |
129 } | |
130 display_->SetSurfaceId(delegated_surface_id_, | |
131 frame.metadata.device_scale_factor); | |
132 | |
133 gfx::Size frame_size = | |
134 frame.delegated_frame_data->render_pass_list.back()->output_rect.size(); | |
135 display_->Resize(frame_size); | |
136 | |
137 bool synchronous = !display_->has_scheduler(); | |
138 | |
139 surface_factory_->SubmitCompositorFrame( | |
140 delegated_surface_id_, std::move(frame), | |
141 base::Bind(&TestDelegatingOutputSurface::DidDrawCallback, | |
142 weak_ptrs_.GetWeakPtr(), synchronous)); | |
143 | |
144 for (std::unique_ptr<CopyOutputRequest>& copy_request : copy_requests_) | |
145 surface_factory_->RequestCopyOfSurface(delegated_surface_id_, | |
146 std::move(copy_request)); | |
147 copy_requests_.clear(); | |
148 | |
149 if (synchronous) | |
150 display_->DrawAndSwap(); | |
151 } | |
152 | |
153 void TestDelegatingOutputSurface::DidDrawCallback(bool synchronous) { | |
154 // This is the frame ack to unthrottle the next frame, not actually a notice | |
155 // that drawing is done. | |
156 if (synchronous) { | |
157 // For synchronous draws, this must be posted to a new stack because we are | |
158 // still the original call to SwapBuffers, and we want to leave that before | |
159 // saying that it is done. | |
160 OutputSurface::PostSwapBuffersComplete(); | |
161 } else { | |
162 client_->DidSwapBuffersComplete(); | |
163 } | |
164 } | |
165 | |
166 void TestDelegatingOutputSurface::ForceReclaimResources() { | |
167 if (capabilities_.can_force_reclaim_resources && | |
168 !delegated_surface_id_.is_null()) { | |
169 surface_factory_->SubmitCompositorFrame(delegated_surface_id_, | |
170 CompositorFrame(), | |
171 SurfaceFactory::DrawCallback()); | |
172 } | |
173 } | |
174 | |
175 void TestDelegatingOutputSurface::BindFramebuffer() { | |
176 // This is a delegating output surface, no framebuffer/direct drawing support. | |
177 NOTREACHED(); | |
178 } | |
179 | |
180 uint32_t TestDelegatingOutputSurface::GetFramebufferCopyTextureFormat() { | |
181 // This is a delegating output surface, no framebuffer/direct drawing support. | |
182 NOTREACHED(); | |
183 return 0; | |
184 } | |
185 | |
186 void TestDelegatingOutputSurface::ReturnResources( | |
187 const ReturnedResourceArray& resources) { | |
188 client_->ReclaimResources(resources); | |
189 } | |
190 | |
191 void TestDelegatingOutputSurface::SetBeginFrameSource( | |
192 BeginFrameSource* begin_frame_source) { | |
193 client_->SetBeginFrameSource(begin_frame_source); | |
194 } | |
195 | |
196 void TestDelegatingOutputSurface::DisplayOutputSurfaceLost() { | |
197 client_->DidLoseOutputSurface(); | |
198 } | |
199 | |
200 void TestDelegatingOutputSurface::DisplayWillDrawAndSwap( | |
201 bool will_draw_and_swap, | |
202 const RenderPassList& render_passes) { | |
203 if (test_client_) | |
204 test_client_->DisplayWillDrawAndSwap(will_draw_and_swap, render_passes); | |
205 } | |
206 | |
207 void TestDelegatingOutputSurface::DisplayDidDrawAndSwap() { | |
208 if (test_client_) | |
209 test_client_->DisplayDidDrawAndSwap(); | |
210 } | |
211 | |
212 } // namespace cc | |
OLD | NEW |