OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 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 | 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 "cc/surfaces/compositor_frame_sink_support.h" | 5 #include "cc/surfaces/compositor_frame_sink_support.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "cc/output/compositor_frame.h" | 10 #include "cc/output/compositor_frame.h" |
11 #include "cc/scheduler/begin_frame_source.h" | 11 #include "cc/scheduler/begin_frame_source.h" |
12 #include "cc/surfaces/compositor_frame_sink_support_client.h" | 12 #include "cc/surfaces/compositor_frame_sink_support_client.h" |
13 #include "cc/surfaces/display.h" | 13 #include "cc/surfaces/display.h" |
14 #include "cc/surfaces/surface.h" | 14 #include "cc/surfaces/surface.h" |
| 15 #include "cc/surfaces/surface_info.h" |
15 #include "cc/surfaces/surface_manager.h" | 16 #include "cc/surfaces/surface_manager.h" |
16 #include "cc/surfaces/surface_reference.h" | 17 #include "cc/surfaces/surface_reference.h" |
17 | 18 |
18 namespace cc { | 19 namespace cc { |
19 | 20 |
20 CompositorFrameSinkSupport::CompositorFrameSinkSupport( | 21 CompositorFrameSinkSupport::CompositorFrameSinkSupport( |
21 CompositorFrameSinkSupportClient* client, | 22 CompositorFrameSinkSupportClient* client, |
22 SurfaceManager* surface_manager, | 23 SurfaceManager* surface_manager, |
23 const FrameSinkId& frame_sink_id, | 24 const FrameSinkId& frame_sink_id, |
24 bool is_root, | 25 bool is_root, |
25 bool handles_frame_sink_id_invalidation, | 26 bool handles_frame_sink_id_invalidation, |
26 bool needs_sync_points) | 27 bool needs_sync_points) |
27 : client_(client), | 28 : client_(client), |
28 surface_manager_(surface_manager), | 29 surface_manager_(surface_manager), |
| 30 surface_resource_holder_(this), |
29 frame_sink_id_(frame_sink_id), | 31 frame_sink_id_(frame_sink_id), |
30 surface_factory_(frame_sink_id_, surface_manager_, this), | |
31 reference_tracker_(frame_sink_id), | 32 reference_tracker_(frame_sink_id), |
32 is_root_(is_root), | 33 is_root_(is_root), |
| 34 needs_sync_points_(needs_sync_points), |
33 handles_frame_sink_id_invalidation_(handles_frame_sink_id_invalidation), | 35 handles_frame_sink_id_invalidation_(handles_frame_sink_id_invalidation), |
34 weak_factory_(this) { | 36 weak_factory_(this) { |
35 surface_factory_.set_needs_sync_points(needs_sync_points); | |
36 if (handles_frame_sink_id_invalidation_) | 37 if (handles_frame_sink_id_invalidation_) |
37 surface_manager_->RegisterFrameSinkId(frame_sink_id_); | 38 surface_manager_->RegisterFrameSinkId(frame_sink_id_); |
38 surface_manager_->RegisterSurfaceFactoryClient(frame_sink_id_, this); | 39 surface_manager_->RegisterCompositorFrameSinkSupport(frame_sink_id_, this); |
39 } | 40 } |
40 | 41 |
41 CompositorFrameSinkSupport::~CompositorFrameSinkSupport() { | 42 CompositorFrameSinkSupport::~CompositorFrameSinkSupport() { |
42 // Unregister |this| as a BeginFrameObserver so that the BeginFrameSource does | 43 // Unregister |this| as a BeginFrameObserver so that the BeginFrameSource does |
43 // not call into |this| after it's deleted. | 44 // not call into |this| after it's deleted. |
44 SetNeedsBeginFrame(false); | 45 SetNeedsBeginFrame(false); |
45 | 46 |
46 // For display root surfaces, the surface is no longer going to be visible | 47 // For display root surfaces, the surface is no longer going to be visible |
47 // so make it unreachable from the top-level root. | 48 // so make it unreachable from the top-level root. |
48 if (surface_manager_->using_surface_references() && is_root_ && | 49 if (surface_manager_->using_surface_references() && is_root_ && |
49 reference_tracker_.current_surface_id().is_valid()) | 50 reference_tracker_.current_surface_id().is_valid()) |
50 RemoveTopLevelRootReference(reference_tracker_.current_surface_id()); | 51 RemoveTopLevelRootReference(reference_tracker_.current_surface_id()); |
51 | 52 |
52 // SurfaceFactory's destructor will attempt to return resources which will | 53 EvictFrame(); |
53 // call back into here and access |client_| so we should destroy | 54 surface_manager_->UnregisterCompositorFrameSinkSupport(frame_sink_id_); |
54 // |surface_factory_|'s resources early on. | |
55 surface_factory_.EvictSurface(); | |
56 surface_manager_->UnregisterSurfaceFactoryClient(frame_sink_id_); | |
57 if (handles_frame_sink_id_invalidation_) | 55 if (handles_frame_sink_id_invalidation_) |
58 surface_manager_->InvalidateFrameSinkId(frame_sink_id_); | 56 surface_manager_->InvalidateFrameSinkId(frame_sink_id_); |
59 } | 57 } |
60 | 58 |
61 void CompositorFrameSinkSupport::EvictFrame() { | 59 void CompositorFrameSinkSupport::EvictFrame() { |
62 surface_factory_.EvictSurface(); | 60 if (!current_surface_) |
| 61 return; |
| 62 DestroyCurrentSurface(); |
63 } | 63 } |
64 | 64 |
65 void CompositorFrameSinkSupport::SetNeedsBeginFrame(bool needs_begin_frame) { | 65 void CompositorFrameSinkSupport::SetNeedsBeginFrame(bool needs_begin_frame) { |
66 needs_begin_frame_ = needs_begin_frame; | 66 needs_begin_frame_ = needs_begin_frame; |
67 UpdateNeedsBeginFramesInternal(); | 67 UpdateNeedsBeginFramesInternal(); |
68 } | 68 } |
69 | 69 |
70 void CompositorFrameSinkSupport::BeginFrameDidNotSwap( | 70 void CompositorFrameSinkSupport::BeginFrameDidNotSwap( |
71 const BeginFrameAck& ack) { | 71 const BeginFrameAck& ack) { |
72 // TODO(eseckler): While a pending CompositorFrame exists (see TODO below), we | 72 // TODO(eseckler): While a pending CompositorFrame exists (see TODO below), we |
73 // should not acknowledge immediately. Instead, we should update the ack that | 73 // should not acknowledge immediately. Instead, we should update the ack that |
74 // will be sent to DisplayScheduler when the pending frame is activated. | 74 // will be sent to DisplayScheduler when the pending frame is activated. |
75 if (ack.sequence_number < BeginFrameArgs::kStartingFrameNumber) { | 75 if (ack.sequence_number < BeginFrameArgs::kStartingFrameNumber) { |
76 DLOG(ERROR) << "Received BeginFrameDidNotSwap with invalid BeginFrameAck."; | 76 DLOG(ERROR) << "Received BeginFrameDidNotSwap with invalid BeginFrameAck."; |
77 return; | 77 return; |
78 } | 78 } |
79 | 79 |
80 // |has_damage| is not transmitted, but false by default. | 80 // |has_damage| is not transmitted, but false by default. |
81 DCHECK(!ack.has_damage); | 81 DCHECK(!ack.has_damage); |
82 if (begin_frame_source_) | 82 if (begin_frame_source_) |
83 begin_frame_source_->DidFinishFrame(this, ack); | 83 begin_frame_source_->DidFinishFrame(this, ack); |
84 } | 84 } |
85 | 85 |
86 void CompositorFrameSinkSupport::SubmitCompositorFrame( | 86 void CompositorFrameSinkSupport::SubmitCompositorFrame( |
87 const LocalSurfaceId& local_surface_id, | 87 const LocalSurfaceId& local_surface_id, |
88 CompositorFrame frame) { | 88 CompositorFrame frame) { |
| 89 DCHECK(local_surface_id.is_valid()); |
| 90 TRACE_EVENT0("cc", "CompositorFrameSinkSupport::SubmitCompositorFrame"); |
89 ++ack_pending_count_; | 91 ++ack_pending_count_; |
90 | 92 |
91 if (frame.metadata.begin_frame_ack.sequence_number < | 93 if (frame.metadata.begin_frame_ack.sequence_number < |
92 BeginFrameArgs::kStartingFrameNumber) { | 94 BeginFrameArgs::kStartingFrameNumber) { |
93 DLOG(ERROR) << "Received CompositorFrame with invalid BeginFrameAck."; | 95 DLOG(ERROR) << "Received CompositorFrame with invalid BeginFrameAck."; |
94 frame.metadata.begin_frame_ack.source_id = BeginFrameArgs::kManualSourceId; | 96 frame.metadata.begin_frame_ack.source_id = BeginFrameArgs::kManualSourceId; |
95 frame.metadata.begin_frame_ack.sequence_number = | 97 frame.metadata.begin_frame_ack.sequence_number = |
96 BeginFrameArgs::kStartingFrameNumber; | 98 BeginFrameArgs::kStartingFrameNumber; |
97 } | 99 } |
98 // |has_damage| is not transmitted. | 100 // |has_damage| is not transmitted. |
99 frame.metadata.begin_frame_ack.has_damage = true; | 101 frame.metadata.begin_frame_ack.has_damage = true; |
100 | 102 |
101 BeginFrameAck ack = frame.metadata.begin_frame_ack; | 103 BeginFrameAck ack = frame.metadata.begin_frame_ack; |
102 surface_factory_.SubmitCompositorFrame( | 104 |
103 local_surface_id, std::move(frame), | 105 DCHECK(local_surface_id.is_valid()); |
| 106 std::unique_ptr<Surface> surface; |
| 107 bool create_new_surface = |
| 108 (!current_surface_ || |
| 109 local_surface_id != current_surface_->surface_id().local_surface_id()); |
| 110 if (!create_new_surface) { |
| 111 surface = std::move(current_surface_); |
| 112 } else { |
| 113 surface = CreateSurface(local_surface_id); |
| 114 } |
| 115 surface->QueueFrame( |
| 116 std::move(frame), |
104 base::Bind(&CompositorFrameSinkSupport::DidReceiveCompositorFrameAck, | 117 base::Bind(&CompositorFrameSinkSupport::DidReceiveCompositorFrameAck, |
105 weak_factory_.GetWeakPtr())); | 118 weak_factory_.GetWeakPtr())); |
106 | 119 |
| 120 if (!surface_manager_->SurfaceModified( |
| 121 SurfaceId(frame_sink_id_, local_surface_id))) { |
| 122 TRACE_EVENT_INSTANT0("cc", "Damage not visible.", TRACE_EVENT_SCOPE_THREAD); |
| 123 surface->RunDrawCallbacks(); |
| 124 } |
| 125 if (current_surface_ && create_new_surface) { |
| 126 surface->SetPreviousFrameSurface(current_surface_.get()); |
| 127 DestroyCurrentSurface(); |
| 128 } |
| 129 current_surface_ = std::move(surface); |
| 130 |
107 // TODO(eseckler): The CompositorFrame submitted below might not be activated | 131 // TODO(eseckler): The CompositorFrame submitted below might not be activated |
108 // right away b/c of surface synchronization. We should only send the | 132 // right away b/c of surface synchronization. We should only send the |
109 // BeginFrameAck to DisplayScheduler when it is activated. This also means | 133 // BeginFrameAck to DisplayScheduler when it is activated. This also means |
110 // that we need to stay an active BFO while a CompositorFrame is pending. | 134 // that we need to stay an active BFO while a CompositorFrame is pending. |
111 // See https://crbug.com/703079. | 135 // See https://crbug.com/703079. |
112 if (begin_frame_source_) | 136 if (begin_frame_source_) |
113 begin_frame_source_->DidFinishFrame(this, ack); | 137 begin_frame_source_->DidFinishFrame(this, ack); |
114 } | 138 } |
115 | 139 |
116 void CompositorFrameSinkSupport::UpdateSurfaceReferences( | 140 void CompositorFrameSinkSupport::UpdateSurfaceReferences( |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
168 // We return the resources before sending an ack so they can be reused in | 192 // We return the resources before sending an ack so they can be reused in |
169 // making the next CompositorFrame. | 193 // making the next CompositorFrame. |
170 if (!surface_returned_resources_.empty()) { | 194 if (!surface_returned_resources_.empty()) { |
171 client_->ReclaimResources(surface_returned_resources_); | 195 client_->ReclaimResources(surface_returned_resources_); |
172 surface_returned_resources_.clear(); | 196 surface_returned_resources_.clear(); |
173 } | 197 } |
174 client_->DidReceiveCompositorFrameAck(); | 198 client_->DidReceiveCompositorFrameAck(); |
175 } | 199 } |
176 | 200 |
177 void CompositorFrameSinkSupport::ForceReclaimResources() { | 201 void CompositorFrameSinkSupport::ForceReclaimResources() { |
178 surface_factory_.ClearSurface(); | 202 if (!current_surface_) |
| 203 return; |
| 204 current_surface_->EvictFrame(); |
| 205 surface_manager_->SurfaceModified(current_surface_->surface_id()); |
179 } | 206 } |
180 | 207 |
181 void CompositorFrameSinkSupport::ClaimTemporaryReference( | 208 void CompositorFrameSinkSupport::ClaimTemporaryReference( |
182 const SurfaceId& surface_id) { | 209 const SurfaceId& surface_id) { |
183 surface_manager_->AssignTemporaryReference(surface_id, frame_sink_id_); | 210 surface_manager_->AssignTemporaryReference(surface_id, frame_sink_id_); |
184 } | 211 } |
185 | 212 |
| 213 void CompositorFrameSinkSupport::ReceiveFromChild( |
| 214 const TransferableResourceArray& resources) { |
| 215 surface_resource_holder_.ReceiveFromChild(resources); |
| 216 } |
| 217 |
| 218 void CompositorFrameSinkSupport::RefResources( |
| 219 const TransferableResourceArray& resources) { |
| 220 surface_resource_holder_.RefResources(resources); |
| 221 } |
| 222 |
| 223 void CompositorFrameSinkSupport::UnrefResources( |
| 224 const ReturnedResourceArray& resources) { |
| 225 surface_resource_holder_.UnrefResources(resources); |
| 226 } |
| 227 |
186 BeginFrameSource* CompositorFrameSinkSupport::BeginFrameSourceForTesting() | 228 BeginFrameSource* CompositorFrameSinkSupport::BeginFrameSourceForTesting() |
187 const { | 229 const { |
188 return begin_frame_source_; | 230 return begin_frame_source_; |
189 } | 231 } |
190 | 232 |
191 void CompositorFrameSinkSupport::ReferencedSurfacesChanged( | |
192 const LocalSurfaceId& local_surface_id, | |
193 const std::vector<SurfaceId>* active_referenced_surfaces, | |
194 const std::vector<SurfaceId>* pending_referenced_surfaces) { | |
195 if (!surface_manager_->using_surface_references()) | |
196 return; | |
197 | |
198 SurfaceId last_surface_id = reference_tracker_.current_surface_id(); | |
199 | |
200 // Populate list of surface references to add and remove based on reference | |
201 // surfaces in current frame compared with the last frame. The list of | |
202 // surface references includes references from both the pending and active | |
203 // frame if any. | |
204 reference_tracker_.UpdateReferences(local_surface_id, | |
205 active_referenced_surfaces, | |
206 pending_referenced_surfaces); | |
207 | |
208 UpdateSurfaceReferences(last_surface_id, local_surface_id); | |
209 } | |
210 | |
211 void CompositorFrameSinkSupport::ReturnResources( | 233 void CompositorFrameSinkSupport::ReturnResources( |
212 const ReturnedResourceArray& resources) { | 234 const ReturnedResourceArray& resources) { |
213 if (resources.empty()) | 235 if (resources.empty()) |
214 return; | 236 return; |
215 | 237 |
216 if (!ack_pending_count_ && client_) { | 238 if (!ack_pending_count_ && client_) { |
217 client_->ReclaimResources(resources); | 239 client_->ReclaimResources(resources); |
218 return; | 240 return; |
219 } | 241 } |
220 | 242 |
(...skipping 25 matching lines...) Expand all Loading... |
246 client_->OnBeginFrame(args); | 268 client_->OnBeginFrame(args); |
247 } | 269 } |
248 | 270 |
249 const BeginFrameArgs& CompositorFrameSinkSupport::LastUsedBeginFrameArgs() | 271 const BeginFrameArgs& CompositorFrameSinkSupport::LastUsedBeginFrameArgs() |
250 const { | 272 const { |
251 return last_begin_frame_args_; | 273 return last_begin_frame_args_; |
252 } | 274 } |
253 | 275 |
254 void CompositorFrameSinkSupport::OnBeginFrameSourcePausedChanged(bool paused) {} | 276 void CompositorFrameSinkSupport::OnBeginFrameSourcePausedChanged(bool paused) {} |
255 | 277 |
| 278 void CompositorFrameSinkSupport::OnReferencedSurfacesChanged( |
| 279 Surface* surface, |
| 280 const std::vector<SurfaceId>* active_referenced_surfaces, |
| 281 const std::vector<SurfaceId>* pending_referenced_surfaces) { |
| 282 if (!surface_manager_->using_surface_references()) |
| 283 return; |
| 284 |
| 285 SurfaceId last_surface_id = reference_tracker_.current_surface_id(); |
| 286 LocalSurfaceId local_surface_id = surface->surface_id().local_surface_id(); |
| 287 // Populate list of surface references to add and remove based on reference |
| 288 // surfaces in current frame compared with the last frame. The list of |
| 289 // surface references includes references from both the pending and active |
| 290 // frame if any. |
| 291 reference_tracker_.UpdateReferences(local_surface_id, |
| 292 active_referenced_surfaces, |
| 293 pending_referenced_surfaces); |
| 294 |
| 295 UpdateSurfaceReferences(last_surface_id, local_surface_id); |
| 296 } |
| 297 |
| 298 void CompositorFrameSinkSupport::OnSurfaceActivated(Surface* surface) { |
| 299 DCHECK(surface->HasActiveFrame()); |
| 300 // TODO(staraz): Notify BeginFrameSource about the last activated sequence |
| 301 // number. |
| 302 if (seen_first_frame_activation_) |
| 303 return; |
| 304 |
| 305 seen_first_frame_activation_ = true; |
| 306 |
| 307 const CompositorFrame& frame = surface->GetActiveFrame(); |
| 308 // CompositorFrames might not be populated with a RenderPass in unit tests. |
| 309 gfx::Size frame_size; |
| 310 if (!frame.render_pass_list.empty()) |
| 311 frame_size = frame.render_pass_list.back()->output_rect.size(); |
| 312 |
| 313 // SurfaceCreated only applies for the first Surface activation. Thus, |
| 314 // CompositorFrameSinkSupport stops observing new activations after the first |
| 315 // one. |
| 316 surface_manager_->SurfaceCreated(SurfaceInfo( |
| 317 surface->surface_id(), frame.metadata.device_scale_factor, frame_size)); |
| 318 } |
| 319 |
| 320 void CompositorFrameSinkSupport::OnSurfaceDependenciesChanged( |
| 321 Surface* surface, |
| 322 const SurfaceDependencies& added_dependencies, |
| 323 const SurfaceDependencies& removed_dependencies) {} |
| 324 |
| 325 void CompositorFrameSinkSupport::OnSurfaceDiscarded(Surface* surface) {} |
| 326 |
256 void CompositorFrameSinkSupport::UpdateNeedsBeginFramesInternal() { | 327 void CompositorFrameSinkSupport::UpdateNeedsBeginFramesInternal() { |
257 if (!begin_frame_source_) | 328 if (!begin_frame_source_) |
258 return; | 329 return; |
259 | 330 |
260 if (needs_begin_frame_ == added_frame_observer_) | 331 if (needs_begin_frame_ == added_frame_observer_) |
261 return; | 332 return; |
262 | 333 |
263 added_frame_observer_ = needs_begin_frame_; | 334 added_frame_observer_ = needs_begin_frame_; |
264 if (needs_begin_frame_) | 335 if (needs_begin_frame_) |
265 begin_frame_source_->AddObserver(this); | 336 begin_frame_source_->AddObserver(this); |
266 else | 337 else |
267 begin_frame_source_->RemoveObserver(this); | 338 begin_frame_source_->RemoveObserver(this); |
268 } | 339 } |
269 | 340 |
| 341 std::unique_ptr<Surface> CompositorFrameSinkSupport::CreateSurface( |
| 342 const LocalSurfaceId& local_surface_id) { |
| 343 seen_first_frame_activation_ = false; |
| 344 std::unique_ptr<Surface> surface = surface_manager_->CreateSurface( |
| 345 weak_factory_.GetWeakPtr(), local_surface_id); |
| 346 surface->AddObserver(this); |
| 347 return surface; |
| 348 } |
| 349 |
| 350 void CompositorFrameSinkSupport::DestroyCurrentSurface() { |
| 351 current_surface_->RemoveObserver(this); |
| 352 surface_manager_->DestroySurface(std::move(current_surface_)); |
| 353 } |
| 354 |
270 void CompositorFrameSinkSupport::RequestCopyOfSurface( | 355 void CompositorFrameSinkSupport::RequestCopyOfSurface( |
271 std::unique_ptr<CopyOutputRequest> request) { | 356 std::unique_ptr<CopyOutputRequest> copy_request) { |
272 surface_factory_.RequestCopyOfSurface(std::move(request)); | 357 if (!current_surface_) { |
| 358 copy_request->SendEmptyResult(); |
| 359 return; |
| 360 } |
| 361 DCHECK(current_surface_->compositor_frame_sink_support().get() == this); |
| 362 current_surface_->RequestCopyOfOutput(std::move(copy_request)); |
| 363 surface_manager_->SurfaceModified(current_surface_->surface_id()); |
273 } | 364 } |
274 | 365 |
275 } // namespace cc | 366 } // namespace cc |
OLD | NEW |