OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "services/ui/surfaces/gpu_compositor_frame_sink.h" | 5 #include "services/ui/surfaces/gpu_compositor_frame_sink.h" |
6 | 6 |
7 #include "base/callback.h" | |
8 #include "base/message_loop/message_loop.h" | |
9 #include "base/single_thread_task_runner.h" | |
10 #include "base/threading/thread_task_runner_handle.h" | |
11 #include "cc/output/compositor_frame.h" | |
12 #include "cc/output/output_surface.h" | |
13 #include "cc/quads/shared_quad_state.h" | |
14 #include "cc/quads/surface_draw_quad.h" | |
15 #include "cc/scheduler/begin_frame_source.h" | |
16 #include "cc/surfaces/display.h" | |
17 #include "services/ui/surfaces/display_compositor.h" | 7 #include "services/ui/surfaces/display_compositor.h" |
18 | 8 |
19 namespace ui { | 9 namespace ui { |
20 | 10 |
21 GpuCompositorFrameSink::GpuCompositorFrameSink( | 11 GpuCompositorFrameSink::GpuCompositorFrameSink( |
22 DisplayCompositor* display_compositor, | 12 DisplayCompositor* display_compositor, |
23 const cc::FrameSinkId& frame_sink_id, | 13 const cc::FrameSinkId& frame_sink_id, |
24 std::unique_ptr<cc::Display> display, | 14 std::unique_ptr<cc::Display> display, |
25 cc::mojom::MojoCompositorFrameSinkRequest request, | 15 cc::mojom::MojoCompositorFrameSinkRequest request, |
26 cc::mojom::MojoCompositorFrameSinkPrivateRequest private_request, | 16 cc::mojom::MojoCompositorFrameSinkPrivateRequest private_request, |
27 cc::mojom::MojoCompositorFrameSinkClientPtr client) | 17 cc::mojom::MojoCompositorFrameSinkClientPtr client) |
28 : frame_sink_id_(frame_sink_id), | 18 : display_compositor_(display_compositor), |
29 display_compositor_(display_compositor), | 19 support_(this, |
30 display_(std::move(display)), | 20 display_compositor->manager(), |
31 surface_factory_(frame_sink_id_, display_compositor_->manager(), this), | 21 frame_sink_id, |
| 22 std::move(display)), |
32 client_(std::move(client)), | 23 client_(std::move(client)), |
33 binding_(this, std::move(request)), | 24 binding_(this, std::move(request)), |
34 private_binding_(this, std::move(private_request)), | 25 private_binding_(this, std::move(private_request)) { |
35 weak_factory_(this) { | |
36 display_compositor_->manager()->RegisterFrameSinkId(frame_sink_id_); | |
37 display_compositor_->manager()->RegisterSurfaceFactoryClient(frame_sink_id_, | |
38 this); | |
39 | |
40 if (display_) { | |
41 display_->Initialize(this, display_compositor_->manager()); | |
42 display_->SetVisible(true); | |
43 } | |
44 | |
45 binding_.set_connection_error_handler(base::Bind( | 26 binding_.set_connection_error_handler(base::Bind( |
46 &GpuCompositorFrameSink::OnClientConnectionLost, base::Unretained(this))); | 27 &GpuCompositorFrameSink::OnClientConnectionLost, base::Unretained(this))); |
47 | 28 |
48 private_binding_.set_connection_error_handler( | 29 private_binding_.set_connection_error_handler( |
49 base::Bind(&GpuCompositorFrameSink::OnPrivateConnectionLost, | 30 base::Bind(&GpuCompositorFrameSink::OnPrivateConnectionLost, |
50 base::Unretained(this))); | 31 base::Unretained(this))); |
51 } | 32 } |
52 | 33 |
53 GpuCompositorFrameSink::~GpuCompositorFrameSink() { | 34 GpuCompositorFrameSink::~GpuCompositorFrameSink() { |
54 // SurfaceFactory's destructor will attempt to return resources which will | |
55 // call back into here and access |client_| so we should destroy | |
56 // |surface_factory_|'s resources early on. | |
57 surface_factory_.EvictSurface(); | |
58 display_compositor_->manager()->UnregisterSurfaceFactoryClient( | |
59 frame_sink_id_); | |
60 display_compositor_->manager()->InvalidateFrameSinkId(frame_sink_id_); | |
61 } | 35 } |
62 | 36 |
63 void GpuCompositorFrameSink::SetNeedsBeginFrame(bool needs_begin_frame) { | 37 void GpuCompositorFrameSink::SetNeedsBeginFrame(bool needs_begin_frame) { |
64 needs_begin_frame_ = needs_begin_frame; | 38 support_.SetNeedsBeginFrame(needs_begin_frame); |
65 UpdateNeedsBeginFramesInternal(); | |
66 } | 39 } |
67 | 40 |
68 void GpuCompositorFrameSink::SubmitCompositorFrame( | 41 void GpuCompositorFrameSink::SubmitCompositorFrame( |
69 const cc::LocalFrameId& local_frame_id, | 42 const cc::LocalFrameId& local_frame_id, |
70 cc::CompositorFrame frame) { | 43 cc::CompositorFrame frame) { |
71 // If the size of the CompostiorFrame has changed then destroy the existing | 44 support_.SubmitCompositorFrame(local_frame_id, std::move(frame)); |
72 // Surface and create a new one of the appropriate size. | |
73 if (local_frame_id_ != local_frame_id) { | |
74 local_frame_id_ = local_frame_id; | |
75 if (display_ && !frame.render_pass_list.empty()) { | |
76 gfx::Size frame_size = frame.render_pass_list[0]->output_rect.size(); | |
77 display_->Resize(frame_size); | |
78 } | |
79 } | |
80 ++ack_pending_count_; | |
81 surface_factory_.SubmitCompositorFrame( | |
82 local_frame_id_, std::move(frame), | |
83 base::Bind(&GpuCompositorFrameSink::DidReceiveCompositorFrameAck, | |
84 weak_factory_.GetWeakPtr())); | |
85 if (display_) { | |
86 display_->SetLocalFrameId(local_frame_id_, | |
87 frame.metadata.device_scale_factor); | |
88 } | |
89 } | 45 } |
90 | 46 |
91 void GpuCompositorFrameSink::DidReceiveCompositorFrameAck() { | 47 void GpuCompositorFrameSink::DidReceiveCompositorFrameAck() { |
92 if (!client_) | |
93 return; | |
94 client_->DidReceiveCompositorFrameAck(); | 48 client_->DidReceiveCompositorFrameAck(); |
95 DCHECK_GT(ack_pending_count_, 0); | |
96 if (!surface_returned_resources_.empty()) { | |
97 client_->ReclaimResources(surface_returned_resources_); | |
98 surface_returned_resources_.clear(); | |
99 } | |
100 ack_pending_count_--; | |
101 } | 49 } |
102 | 50 |
103 void GpuCompositorFrameSink::AddChildFrameSink( | 51 void GpuCompositorFrameSink::AddChildFrameSink( |
104 const cc::FrameSinkId& child_frame_sink_id) { | 52 const cc::FrameSinkId& child_frame_sink_id) { |
105 cc::SurfaceManager* surface_manager = display_compositor_->manager(); | 53 support_.AddChildFrameSink(child_frame_sink_id); |
106 surface_manager->RegisterFrameSinkHierarchy(frame_sink_id_, | |
107 child_frame_sink_id); | |
108 } | 54 } |
109 | 55 |
110 void GpuCompositorFrameSink::RemoveChildFrameSink( | 56 void GpuCompositorFrameSink::RemoveChildFrameSink( |
111 const cc::FrameSinkId& child_frame_sink_id) { | 57 const cc::FrameSinkId& child_frame_sink_id) { |
112 cc::SurfaceManager* surface_manager = display_compositor_->manager(); | 58 support_.RemoveChildFrameSink(child_frame_sink_id); |
113 surface_manager->UnregisterFrameSinkHierarchy(frame_sink_id_, | |
114 child_frame_sink_id); | |
115 } | |
116 | |
117 void GpuCompositorFrameSink::DisplayOutputSurfaceLost() {} | |
118 | |
119 void GpuCompositorFrameSink::DisplayWillDrawAndSwap( | |
120 bool will_draw_and_swap, | |
121 const cc::RenderPassList& render_passes) {} | |
122 | |
123 void GpuCompositorFrameSink::DisplayDidDrawAndSwap() {} | |
124 | |
125 void GpuCompositorFrameSink::ReturnResources( | |
126 const cc::ReturnedResourceArray& resources) { | |
127 if (resources.empty()) | |
128 return; | |
129 | |
130 if (!ack_pending_count_ && client_) { | |
131 client_->ReclaimResources(resources); | |
132 return; | |
133 } | |
134 | |
135 std::copy(resources.begin(), resources.end(), | |
136 std::back_inserter(surface_returned_resources_)); | |
137 } | |
138 | |
139 void GpuCompositorFrameSink::SetBeginFrameSource( | |
140 cc::BeginFrameSource* begin_frame_source) { | |
141 // TODO(tansell): Implement this. | |
142 if (begin_frame_source_ && added_frame_observer_) { | |
143 begin_frame_source_->RemoveObserver(this); | |
144 added_frame_observer_ = false; | |
145 } | |
146 begin_frame_source_ = begin_frame_source; | |
147 UpdateNeedsBeginFramesInternal(); | |
148 } | 59 } |
149 | 60 |
150 void GpuCompositorFrameSink::OnBeginFrame(const cc::BeginFrameArgs& args) { | 61 void GpuCompositorFrameSink::OnBeginFrame(const cc::BeginFrameArgs& args) { |
151 UpdateNeedsBeginFramesInternal(); | |
152 last_begin_frame_args_ = args; | |
153 if (client_) | 62 if (client_) |
154 client_->OnBeginFrame(args); | 63 client_->OnBeginFrame(args); |
155 } | 64 } |
156 | 65 |
157 const cc::BeginFrameArgs& GpuCompositorFrameSink::LastUsedBeginFrameArgs() | 66 void GpuCompositorFrameSink::ReclaimResources( |
158 const { | 67 const cc::ReturnedResourceArray& resources) { |
159 return last_begin_frame_args_; | 68 if (client_) |
160 } | 69 client_->ReclaimResources(resources); |
161 | |
162 void GpuCompositorFrameSink::OnBeginFrameSourcePausedChanged(bool paused) {} | |
163 | |
164 void GpuCompositorFrameSink::UpdateNeedsBeginFramesInternal() { | |
165 if (!begin_frame_source_) | |
166 return; | |
167 | |
168 if (needs_begin_frame_ == added_frame_observer_) | |
169 return; | |
170 | |
171 added_frame_observer_ = needs_begin_frame_; | |
172 if (needs_begin_frame_) | |
173 begin_frame_source_->AddObserver(this); | |
174 else | |
175 begin_frame_source_->RemoveObserver(this); | |
176 } | 70 } |
177 | 71 |
178 void GpuCompositorFrameSink::OnClientConnectionLost() { | 72 void GpuCompositorFrameSink::OnClientConnectionLost() { |
179 client_connection_lost_ = true; | 73 client_connection_lost_ = true; |
180 // Request destruction of |this| only if both connections are lost. | 74 // Request destruction of |this| only if both connections are lost. |
181 display_compositor_->OnCompositorFrameSinkClientConnectionLost( | 75 display_compositor_->OnCompositorFrameSinkClientConnectionLost( |
182 frame_sink_id_, private_connection_lost_); | 76 support_.frame_sink_id(), private_connection_lost_); |
183 } | 77 } |
184 | 78 |
185 void GpuCompositorFrameSink::OnPrivateConnectionLost() { | 79 void GpuCompositorFrameSink::OnPrivateConnectionLost() { |
186 private_connection_lost_ = true; | 80 private_connection_lost_ = true; |
187 // Request destruction of |this| only if both connections are lost. | 81 // Request destruction of |this| only if both connections are lost. |
188 display_compositor_->OnCompositorFrameSinkPrivateConnectionLost( | 82 display_compositor_->OnCompositorFrameSinkPrivateConnectionLost( |
189 frame_sink_id_, client_connection_lost_); | 83 support_.frame_sink_id(), client_connection_lost_); |
190 } | 84 } |
191 | 85 |
192 } // namespace ui | 86 } // namespace ui |
OLD | NEW |