OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 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/surface.h" | 5 #include "cc/surfaces/surface.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 #include <stdint.h> | 8 #include <stdint.h> |
9 | 9 |
10 #include <algorithm> | 10 #include <algorithm> |
11 | 11 |
12 #include "base/stl_util.h" | 12 #include "base/stl_util.h" |
13 #include "cc/output/compositor_frame.h" | 13 #include "cc/output/compositor_frame.h" |
14 #include "cc/output/copy_output_request.h" | 14 #include "cc/output/copy_output_request.h" |
| 15 #include "cc/surfaces/compositor_frame_sink_support.h" |
15 #include "cc/surfaces/local_surface_id_allocator.h" | 16 #include "cc/surfaces/local_surface_id_allocator.h" |
16 #include "cc/surfaces/pending_frame_observer.h" | 17 #include "cc/surfaces/pending_frame_observer.h" |
17 #include "cc/surfaces/surface_factory.h" | |
18 #include "cc/surfaces/surface_factory_client.h" | |
19 #include "cc/surfaces/surface_manager.h" | 18 #include "cc/surfaces/surface_manager.h" |
20 #include "cc/surfaces/surface_resource_holder_client.h" | 19 #include "cc/surfaces/surface_resource_holder_client.h" |
21 | 20 |
22 namespace cc { | 21 namespace cc { |
23 | 22 |
24 // The frame index starts at 2 so that empty frames will be treated as | 23 // The frame index starts at 2 so that empty frames will be treated as |
25 // completely damaged the first time they're drawn from. | 24 // completely damaged the first time they're drawn from. |
26 static const int kFrameIndexStart = 2; | 25 static const int kFrameIndexStart = 2; |
27 | 26 |
28 Surface::Surface(const SurfaceId& id, base::WeakPtr<SurfaceFactory> factory) | 27 Surface::Surface( |
| 28 const SurfaceId& id, |
| 29 base::WeakPtr<CompositorFrameSinkSupport> compositor_frame_sink_support) |
29 : surface_id_(id), | 30 : surface_id_(id), |
30 previous_frame_surface_id_(id), | 31 previous_frame_surface_id_(id), |
31 factory_(factory), | 32 compositor_frame_sink_support_(std::move(compositor_frame_sink_support)), |
32 frame_index_(kFrameIndexStart), | 33 frame_index_(kFrameIndexStart), |
33 destroyed_(false) {} | 34 destroyed_(false) {} |
34 | 35 |
35 Surface::~Surface() { | 36 Surface::~Surface() { |
36 ClearCopyRequests(); | 37 ClearCopyRequests(); |
37 for (auto& observer : observers_) | 38 for (auto& observer : observers_) |
38 observer.OnSurfaceDiscarded(this); | 39 observer.OnSurfaceDiscarded(this); |
39 observers_.Clear(); | 40 observers_.Clear(); |
40 | 41 |
41 UnrefFrameResourcesAndRunDrawCallback(std::move(pending_frame_data_)); | 42 UnrefFrameResourcesAndRunDrawCallback(std::move(pending_frame_data_)); |
42 UnrefFrameResourcesAndRunDrawCallback(std::move(active_frame_data_)); | 43 UnrefFrameResourcesAndRunDrawCallback(std::move(active_frame_data_)); |
43 } | 44 } |
44 | 45 |
45 void Surface::SetPreviousFrameSurface(Surface* surface) { | 46 void Surface::SetPreviousFrameSurface(Surface* surface) { |
46 DCHECK(surface && (HasActiveFrame() || HasPendingFrame())); | 47 DCHECK(surface && (HasActiveFrame() || HasPendingFrame())); |
47 frame_index_ = surface->frame_index() + 1; | 48 frame_index_ = surface->frame_index() + 1; |
48 previous_frame_surface_id_ = surface->surface_id(); | 49 previous_frame_surface_id_ = surface->surface_id(); |
49 CompositorFrame& frame = active_frame_data_ ? active_frame_data_->frame | 50 CompositorFrame& frame = active_frame_data_ ? active_frame_data_->frame |
50 : pending_frame_data_->frame; | 51 : pending_frame_data_->frame; |
51 surface->TakeLatencyInfo(&frame.metadata.latency_info); | 52 surface->TakeLatencyInfo(&frame.metadata.latency_info); |
52 surface->TakeLatencyInfoFromPendingFrame(&frame.metadata.latency_info); | 53 surface->TakeLatencyInfoFromPendingFrame(&frame.metadata.latency_info); |
53 } | 54 } |
54 | 55 |
55 void Surface::Close() { | 56 void Surface::Close() { |
56 closed_ = true; | 57 closed_ = true; |
57 } | 58 } |
58 | 59 |
59 void Surface::QueueFrame(CompositorFrame frame, | 60 void Surface::QueueFrame(CompositorFrame frame, |
60 const DrawCallback& callback, | 61 const base::Closure& callback, |
61 const WillDrawCallback& will_draw_callback) { | 62 const WillDrawCallback& will_draw_callback) { |
62 if (closed_) { | 63 if (closed_) { |
63 if (factory_ && factory_->resource_holder_client()) { | 64 if (compositor_frame_sink_support_) { |
64 ReturnedResourceArray resources; | 65 ReturnedResourceArray resources; |
65 TransferableResource::ReturnResources(frame.resource_list, &resources); | 66 TransferableResource::ReturnResources(frame.resource_list, &resources); |
66 factory_->resource_holder_client()->ReturnResources(resources); | 67 compositor_frame_sink_support_->ReturnResources(resources); |
67 } | 68 } |
68 callback.Run(); | 69 callback.Run(); |
69 return; | 70 return; |
70 } | 71 } |
71 | 72 |
72 TakeLatencyInfoFromPendingFrame(&frame.metadata.latency_info); | 73 TakeLatencyInfoFromPendingFrame(&frame.metadata.latency_info); |
73 | 74 |
74 base::Optional<FrameData> previous_pending_frame_data = | 75 base::Optional<FrameData> previous_pending_frame_data = |
75 std::move(pending_frame_data_); | 76 std::move(pending_frame_data_); |
76 pending_frame_data_.reset(); | 77 pending_frame_data_.reset(); |
77 | 78 |
78 UpdateBlockingSurfaces(previous_pending_frame_data.has_value(), frame); | 79 UpdateBlockingSurfaces(previous_pending_frame_data.has_value(), frame); |
79 | 80 |
80 // Receive and track the resources referenced from the CompositorFrame | 81 // Receive and track the resources referenced from the CompositorFrame |
81 // regardless of whether it's pending or active. | 82 // regardless of whether it's pending or active. |
82 factory_->ReceiveFromChild(frame.resource_list); | 83 compositor_frame_sink_support_->ReceiveFromChild(frame.resource_list); |
83 | 84 |
84 bool is_pending_frame = !blocking_surfaces_.empty(); | 85 bool is_pending_frame = !blocking_surfaces_.empty(); |
85 | 86 |
86 if (is_pending_frame) { | 87 if (is_pending_frame) { |
87 // Reject CompositorFrames submitted to surfaces referenced from this | 88 // Reject CompositorFrames submitted to surfaces referenced from this |
88 // CompositorFrame as fallbacks. This saves some CPU cycles to allow | 89 // CompositorFrame as fallbacks. This saves some CPU cycles to allow |
89 // children to catch up to the parent. | 90 // children to catch up to the parent. |
90 base::flat_set<FrameSinkId> frame_sink_ids_for_dependencies; | 91 base::flat_set<FrameSinkId> frame_sink_ids_for_dependencies; |
91 for (const SurfaceId& surface_id : frame.metadata.activation_dependencies) | 92 for (const SurfaceId& surface_id : frame.metadata.activation_dependencies) |
92 frame_sink_ids_for_dependencies.insert(surface_id.frame_sink_id()); | 93 frame_sink_ids_for_dependencies.insert(surface_id.frame_sink_id()); |
93 for (const SurfaceId& surface_id : frame.metadata.referenced_surfaces) { | 94 for (const SurfaceId& surface_id : frame.metadata.referenced_surfaces) { |
94 // A surface ID in |referenced_surfaces| that has a corresponding surface | 95 // A surface ID in |referenced_surfaces| that has a corresponding surface |
95 // ID in |activation_dependencies| with the same frame sink ID is said to | 96 // ID in |activation_dependencies| with the same frame sink ID is said to |
96 // be a fallback surface that can be used in place of the primary surface | 97 // be a fallback surface that can be used in place of the primary surface |
97 // if the deadline passes before the dependency becomes available. | 98 // if the deadline passes before the dependency becomes available. |
98 bool is_fallback_surface = | 99 bool is_fallback_surface = |
99 frame_sink_ids_for_dependencies.count(surface_id.frame_sink_id()) > 0; | 100 frame_sink_ids_for_dependencies.count(surface_id.frame_sink_id()) > 0; |
100 if (is_fallback_surface) { | 101 if (is_fallback_surface) { |
101 Surface* surface = factory_->manager()->GetSurfaceForId(surface_id); | 102 Surface* surface = |
| 103 compositor_frame_sink_support_->surface_manager()->GetSurfaceForId( |
| 104 surface_id); |
102 DCHECK(surface); | 105 DCHECK(surface); |
103 surface->Close(); | 106 surface->Close(); |
104 } | 107 } |
105 } | 108 } |
106 pending_frame_data_ = | 109 pending_frame_data_ = |
107 FrameData(std::move(frame), callback, will_draw_callback); | 110 FrameData(std::move(frame), callback, will_draw_callback); |
108 // Ask the surface manager to inform |this| when its dependencies are | 111 // Ask the surface manager to inform |this| when its dependencies are |
109 // resolved. | 112 // resolved. |
110 factory_->manager()->RequestSurfaceResolution(this); | 113 compositor_frame_sink_support_->surface_manager()->RequestSurfaceResolution( |
| 114 this); |
111 } else { | 115 } else { |
112 // If there are no blockers, then immediately activate the frame. | 116 // If there are no blockers, then immediately activate the frame. |
113 ActivateFrame(FrameData(std::move(frame), callback, will_draw_callback)); | 117 ActivateFrame(FrameData(std::move(frame), callback, will_draw_callback)); |
114 } | 118 } |
115 | 119 |
116 // Returns resources for the previous pending frame. | 120 // Returns resources for the previous pending frame. |
117 UnrefFrameResourcesAndRunDrawCallback(std::move(previous_pending_frame_data)); | 121 UnrefFrameResourcesAndRunDrawCallback(std::move(previous_pending_frame_data)); |
118 } | 122 } |
119 | 123 |
120 void Surface::RequestCopyOfOutput( | 124 void Surface::RequestCopyOfOutput( |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
168 return; | 172 return; |
169 } | 173 } |
170 | 174 |
171 // If a frame is being activated because of a deadline, then clear its set | 175 // If a frame is being activated because of a deadline, then clear its set |
172 // of blockers. | 176 // of blockers. |
173 blocking_surfaces_.clear(); | 177 blocking_surfaces_.clear(); |
174 ActivatePendingFrame(); | 178 ActivatePendingFrame(); |
175 } | 179 } |
176 | 180 |
177 Surface::FrameData::FrameData(CompositorFrame&& frame, | 181 Surface::FrameData::FrameData(CompositorFrame&& frame, |
178 const DrawCallback& draw_callback, | 182 const base::Closure& draw_callback, |
179 const WillDrawCallback& will_draw_callback) | 183 const WillDrawCallback& will_draw_callback) |
180 : frame(std::move(frame)), | 184 : frame(std::move(frame)), |
181 draw_callback(draw_callback), | 185 draw_callback(draw_callback), |
182 will_draw_callback(will_draw_callback) {} | 186 will_draw_callback(will_draw_callback) {} |
183 | 187 |
184 Surface::FrameData::FrameData(FrameData&& other) = default; | 188 Surface::FrameData::FrameData(FrameData&& other) = default; |
185 | 189 |
186 Surface::FrameData& Surface::FrameData::operator=(FrameData&& other) = default; | 190 Surface::FrameData& Surface::FrameData::operator=(FrameData&& other) = default; |
187 | 191 |
188 Surface::FrameData::~FrameData() = default; | 192 Surface::FrameData::~FrameData() = default; |
189 | 193 |
190 void Surface::ActivatePendingFrame() { | 194 void Surface::ActivatePendingFrame() { |
191 DCHECK(pending_frame_data_); | 195 DCHECK(pending_frame_data_); |
192 ActivateFrame(std::move(*pending_frame_data_)); | 196 ActivateFrame(std::move(*pending_frame_data_)); |
193 pending_frame_data_.reset(); | 197 pending_frame_data_.reset(); |
194 } | 198 } |
195 | 199 |
196 // A frame is activated if all its Surface ID dependences are active or a | 200 // A frame is activated if all its Surface ID dependences are active or a |
197 // deadline has hit and the frame was forcibly activated by the display | 201 // deadline has hit and the frame was forcibly activated by the display |
198 // compositor. | 202 // compositor. |
199 void Surface::ActivateFrame(FrameData frame_data) { | 203 void Surface::ActivateFrame(FrameData frame_data) { |
200 DCHECK(factory_); | 204 DCHECK(compositor_frame_sink_support_); |
201 | 205 |
202 // Save root pass copy requests. | 206 // Save root pass copy requests. |
203 std::vector<std::unique_ptr<CopyOutputRequest>> old_copy_requests; | 207 std::vector<std::unique_ptr<CopyOutputRequest>> old_copy_requests; |
204 if (active_frame_data_) { | 208 if (active_frame_data_) { |
205 std::swap(old_copy_requests, | 209 std::swap(old_copy_requests, |
206 active_frame_data_->frame.render_pass_list.back()->copy_requests); | 210 active_frame_data_->frame.render_pass_list.back()->copy_requests); |
207 } | 211 } |
208 | 212 |
209 ClearCopyRequests(); | 213 ClearCopyRequests(); |
210 | 214 |
(...skipping 13 matching lines...) Expand all Loading... |
224 UnrefFrameResourcesAndRunDrawCallback(std::move(previous_frame_data)); | 228 UnrefFrameResourcesAndRunDrawCallback(std::move(previous_frame_data)); |
225 | 229 |
226 for (auto& observer : observers_) | 230 for (auto& observer : observers_) |
227 observer.OnSurfaceActivated(this); | 231 observer.OnSurfaceActivated(this); |
228 } | 232 } |
229 | 233 |
230 void Surface::UpdateBlockingSurfaces(bool has_previous_pending_frame, | 234 void Surface::UpdateBlockingSurfaces(bool has_previous_pending_frame, |
231 const CompositorFrame& current_frame) { | 235 const CompositorFrame& current_frame) { |
232 // If there is no SurfaceDependencyTracker installed then the |current_frame| | 236 // If there is no SurfaceDependencyTracker installed then the |current_frame| |
233 // does not block on anything. | 237 // does not block on anything. |
234 if (!factory_->manager()->dependency_tracker()) { | 238 if (!compositor_frame_sink_support_->surface_manager() |
| 239 ->dependency_tracker()) { |
235 blocking_surfaces_.clear(); | 240 blocking_surfaces_.clear(); |
236 return; | 241 return; |
237 } | 242 } |
238 | 243 |
239 base::flat_set<SurfaceId> new_blocking_surfaces; | 244 base::flat_set<SurfaceId> new_blocking_surfaces; |
240 | 245 |
241 for (const SurfaceId& surface_id : | 246 for (const SurfaceId& surface_id : |
242 current_frame.metadata.activation_dependencies) { | 247 current_frame.metadata.activation_dependencies) { |
243 Surface* surface = factory_->manager()->GetSurfaceForId(surface_id); | 248 Surface* surface = |
| 249 compositor_frame_sink_support_->surface_manager()->GetSurfaceForId( |
| 250 surface_id); |
244 // If a referenced surface does not have a corresponding active frame in the | 251 // If a referenced surface does not have a corresponding active frame in the |
245 // display compositor, then it blocks this frame. | 252 // display compositor, then it blocks this frame. |
246 if (!surface || !surface->HasActiveFrame()) | 253 if (!surface || !surface->HasActiveFrame()) |
247 new_blocking_surfaces.insert(surface_id); | 254 new_blocking_surfaces.insert(surface_id); |
248 } | 255 } |
249 | 256 |
250 // If this Surface has a previous pending frame, then we must determine the | 257 // If this Surface has a previous pending frame, then we must determine the |
251 // changes in dependencies so that we can update the SurfaceDependencyTracker | 258 // changes in dependencies so that we can update the SurfaceDependencyTracker |
252 // map. | 259 // map. |
253 if (has_previous_pending_frame) { | 260 if (has_previous_pending_frame) { |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
301 } | 308 } |
302 | 309 |
303 void Surface::TakeLatencyInfo(std::vector<ui::LatencyInfo>* latency_info) { | 310 void Surface::TakeLatencyInfo(std::vector<ui::LatencyInfo>* latency_info) { |
304 if (!active_frame_data_) | 311 if (!active_frame_data_) |
305 return; | 312 return; |
306 TakeLatencyInfoFromFrame(&active_frame_data_->frame, latency_info); | 313 TakeLatencyInfoFromFrame(&active_frame_data_->frame, latency_info); |
307 } | 314 } |
308 | 315 |
309 void Surface::RunDrawCallback() { | 316 void Surface::RunDrawCallback() { |
310 if (active_frame_data_ && !active_frame_data_->draw_callback.is_null()) { | 317 if (active_frame_data_ && !active_frame_data_->draw_callback.is_null()) { |
311 DrawCallback callback = active_frame_data_->draw_callback; | 318 base::Closure callback = active_frame_data_->draw_callback; |
312 active_frame_data_->draw_callback = DrawCallback(); | 319 active_frame_data_->draw_callback = base::Closure(); |
313 callback.Run(); | 320 callback.Run(); |
314 } | 321 } |
315 } | 322 } |
316 | 323 |
317 void Surface::RunWillDrawCallback(const gfx::Rect& damage_rect) { | 324 void Surface::RunWillDrawCallback(const gfx::Rect& damage_rect) { |
318 if (!active_frame_data_ || active_frame_data_->will_draw_callback.is_null()) | 325 if (!active_frame_data_ || active_frame_data_->will_draw_callback.is_null()) |
319 return; | 326 return; |
320 | 327 |
321 active_frame_data_->will_draw_callback.Run(surface_id_.local_surface_id(), | 328 active_frame_data_->will_draw_callback.Run(surface_id_.local_surface_id(), |
322 damage_rect); | 329 damage_rect); |
323 } | 330 } |
324 | 331 |
325 void Surface::AddDestructionDependency(SurfaceSequence sequence) { | 332 void Surface::AddDestructionDependency(SurfaceSequence sequence) { |
326 destruction_dependencies_.push_back(sequence); | 333 destruction_dependencies_.push_back(sequence); |
327 } | 334 } |
328 | 335 |
329 void Surface::SatisfyDestructionDependencies( | 336 void Surface::SatisfyDestructionDependencies( |
330 std::unordered_set<SurfaceSequence, SurfaceSequenceHash>* sequences, | 337 std::unordered_set<SurfaceSequence, SurfaceSequenceHash>* sequences, |
331 std::unordered_set<FrameSinkId, FrameSinkIdHash>* valid_frame_sink_ids) { | 338 std::unordered_set<FrameSinkId, FrameSinkIdHash>* valid_frame_sink_ids) { |
332 base::EraseIf(destruction_dependencies_, | 339 base::EraseIf(destruction_dependencies_, |
333 [sequences, valid_frame_sink_ids](SurfaceSequence seq) { | 340 [sequences, valid_frame_sink_ids](SurfaceSequence seq) { |
334 return (!!sequences->erase(seq) || | 341 return (!!sequences->erase(seq) || |
335 !valid_frame_sink_ids->count(seq.frame_sink_id)); | 342 !valid_frame_sink_ids->count(seq.frame_sink_id)); |
336 }); | 343 }); |
337 } | 344 } |
338 | 345 |
339 void Surface::UnrefFrameResourcesAndRunDrawCallback( | 346 void Surface::UnrefFrameResourcesAndRunDrawCallback( |
340 base::Optional<FrameData> frame_data) { | 347 base::Optional<FrameData> frame_data) { |
341 if (!frame_data || !factory_) | 348 if (!frame_data || !compositor_frame_sink_support_) |
342 return; | 349 return; |
343 | 350 |
344 ReturnedResourceArray resources; | 351 ReturnedResourceArray resources; |
345 TransferableResource::ReturnResources(frame_data->frame.resource_list, | 352 TransferableResource::ReturnResources(frame_data->frame.resource_list, |
346 &resources); | 353 &resources); |
347 // No point in returning same sync token to sender. | 354 // No point in returning same sync token to sender. |
348 for (auto& resource : resources) | 355 for (auto& resource : resources) |
349 resource.sync_token.Clear(); | 356 resource.sync_token.Clear(); |
350 factory_->UnrefResources(resources); | 357 compositor_frame_sink_support_->UnrefResources(resources); |
351 | 358 |
352 if (!frame_data->draw_callback.is_null()) | 359 if (!frame_data->draw_callback.is_null()) |
353 frame_data->draw_callback.Run(); | 360 frame_data->draw_callback.Run(); |
354 } | 361 } |
355 | 362 |
356 void Surface::ClearCopyRequests() { | 363 void Surface::ClearCopyRequests() { |
357 if (active_frame_data_) { | 364 if (active_frame_data_) { |
358 for (const auto& render_pass : active_frame_data_->frame.render_pass_list) { | 365 for (const auto& render_pass : active_frame_data_->frame.render_pass_list) { |
359 for (const auto& copy_request : render_pass->copy_requests) | 366 for (const auto& copy_request : render_pass->copy_requests) |
360 copy_request->SendEmptyResult(); | 367 copy_request->SendEmptyResult(); |
(...skipping 16 matching lines...) Expand all Loading... |
377 frame->metadata.latency_info.swap(*latency_info); | 384 frame->metadata.latency_info.swap(*latency_info); |
378 return; | 385 return; |
379 } | 386 } |
380 std::copy(frame->metadata.latency_info.begin(), | 387 std::copy(frame->metadata.latency_info.begin(), |
381 frame->metadata.latency_info.end(), | 388 frame->metadata.latency_info.end(), |
382 std::back_inserter(*latency_info)); | 389 std::back_inserter(*latency_info)); |
383 frame->metadata.latency_info.clear(); | 390 frame->metadata.latency_info.clear(); |
384 } | 391 } |
385 | 392 |
386 } // namespace cc | 393 } // namespace cc |
OLD | NEW |