Chromium Code Reviews| 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_manager.h" | 18 #include "cc/surfaces/surface_manager.h" |
| 19 | 19 |
| 20 namespace cc { | 20 namespace cc { |
| 21 | 21 |
| 22 // The frame index starts at 2 so that empty frames will be treated as | 22 // The frame index starts at 2 so that empty frames will be treated as |
| 23 // completely damaged the first time they're drawn from. | 23 // completely damaged the first time they're drawn from. |
| 24 static const int kFrameIndexStart = 2; | 24 static const int kFrameIndexStart = 2; |
| 25 | 25 |
| 26 Surface::Surface(const SurfaceId& id, base::WeakPtr<SurfaceFactory> factory) | 26 Surface::Surface( |
| 27 const SurfaceId& id, | |
| 28 base::WeakPtr<CompositorFrameSinkSupport> compositor_frame_sink_support) | |
| 27 : surface_id_(id), | 29 : surface_id_(id), |
| 28 previous_frame_surface_id_(id), | 30 previous_frame_surface_id_(id), |
| 29 factory_(factory), | 31 compositor_frame_sink_support_(compositor_frame_sink_support), |
|
danakj
2017/05/03 16:08:39
move?
Alex Z.
2017/05/03 18:07:37
Done.
| |
| 30 frame_index_(kFrameIndexStart), | 32 frame_index_(kFrameIndexStart), |
| 31 destroyed_(false) {} | 33 destroyed_(false) {} |
| 32 | 34 |
| 33 Surface::~Surface() { | 35 Surface::~Surface() { |
| 34 ClearCopyRequests(); | 36 ClearCopyRequests(); |
| 35 for (auto& observer : observers_) | 37 for (auto& observer : observers_) |
| 36 observer.OnSurfaceDiscarded(this); | 38 observer.OnSurfaceDiscarded(this); |
| 37 observers_.Clear(); | 39 observers_.Clear(); |
| 38 | 40 |
| 39 UnrefFrameResourcesAndRunDrawCallback(std::move(pending_frame_data_)); | 41 UnrefFrameResourcesAndRunDrawCallback(std::move(pending_frame_data_)); |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 54 const DrawCallback& callback, | 56 const DrawCallback& callback, |
| 55 const WillDrawCallback& will_draw_callback) { | 57 const WillDrawCallback& will_draw_callback) { |
| 56 TakeLatencyInfoFromPendingFrame(&frame.metadata.latency_info); | 58 TakeLatencyInfoFromPendingFrame(&frame.metadata.latency_info); |
| 57 | 59 |
| 58 base::Optional<FrameData> previous_pending_frame_data = | 60 base::Optional<FrameData> previous_pending_frame_data = |
| 59 std::move(pending_frame_data_); | 61 std::move(pending_frame_data_); |
| 60 pending_frame_data_.reset(); | 62 pending_frame_data_.reset(); |
| 61 | 63 |
| 62 UpdateBlockingSurfaces(previous_pending_frame_data.has_value(), frame); | 64 UpdateBlockingSurfaces(previous_pending_frame_data.has_value(), frame); |
| 63 | 65 |
| 64 // Receive and track the resources referenced from the CompositorFrame | |
| 65 // regardless of whether it's pending or active. | |
| 66 factory_->ReceiveFromChild(frame.resource_list); | |
| 67 | |
| 68 bool is_pending_frame = !blocking_surfaces_.empty(); | 66 bool is_pending_frame = !blocking_surfaces_.empty(); |
| 69 | 67 |
| 70 if (is_pending_frame) { | 68 if (is_pending_frame) { |
| 71 pending_frame_data_ = | 69 pending_frame_data_ = |
| 72 FrameData(std::move(frame), callback, will_draw_callback); | 70 FrameData(std::move(frame), callback, will_draw_callback); |
| 73 // Ask the surface manager to inform |this| when its dependencies are | 71 // Ask the surface manager to inform |this| when its dependencies are |
| 74 // resolved. | 72 // resolved. |
| 75 factory_->manager()->RequestSurfaceResolution(this); | 73 compositor_frame_sink_support_->surface_manager()->RequestSurfaceResolution( |
| 74 this); | |
| 76 } else { | 75 } else { |
| 77 // If there are no blockers, then immediately activate the frame. | 76 // If there are no blockers, then immediately activate the frame. |
| 78 ActivateFrame(FrameData(std::move(frame), callback, will_draw_callback)); | 77 ActivateFrame(FrameData(std::move(frame), callback, will_draw_callback)); |
| 79 } | 78 } |
| 80 | 79 |
| 81 // Returns resources for the previous pending frame. | 80 // Returns resources for the previous pending frame. |
| 82 UnrefFrameResourcesAndRunDrawCallback(std::move(previous_pending_frame_data)); | 81 UnrefFrameResourcesAndRunDrawCallback(std::move(previous_pending_frame_data)); |
| 83 } | 82 } |
| 84 | 83 |
| 85 void Surface::RequestCopyOfOutput( | 84 void Surface::RequestCopyOfOutput( |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 156 void Surface::ActivatePendingFrame() { | 155 void Surface::ActivatePendingFrame() { |
| 157 DCHECK(pending_frame_data_); | 156 DCHECK(pending_frame_data_); |
| 158 ActivateFrame(std::move(*pending_frame_data_)); | 157 ActivateFrame(std::move(*pending_frame_data_)); |
| 159 pending_frame_data_.reset(); | 158 pending_frame_data_.reset(); |
| 160 } | 159 } |
| 161 | 160 |
| 162 // A frame is activated if all its Surface ID dependences are active or a | 161 // A frame is activated if all its Surface ID dependences are active or a |
| 163 // deadline has hit and the frame was forcibly activated by the display | 162 // deadline has hit and the frame was forcibly activated by the display |
| 164 // compositor. | 163 // compositor. |
| 165 void Surface::ActivateFrame(FrameData frame_data) { | 164 void Surface::ActivateFrame(FrameData frame_data) { |
| 166 DCHECK(factory_); | 165 DCHECK(compositor_frame_sink_support_); |
| 167 | 166 |
| 168 // Save root pass copy requests. | 167 // Save root pass copy requests. |
| 169 std::vector<std::unique_ptr<CopyOutputRequest>> old_copy_requests; | 168 std::vector<std::unique_ptr<CopyOutputRequest>> old_copy_requests; |
| 170 if (active_frame_data_ && | 169 if (active_frame_data_ && |
| 171 !active_frame_data_->frame.render_pass_list.empty()) { | 170 !active_frame_data_->frame.render_pass_list.empty()) { |
| 172 std::swap(old_copy_requests, | 171 std::swap(old_copy_requests, |
| 173 active_frame_data_->frame.render_pass_list.back()->copy_requests); | 172 active_frame_data_->frame.render_pass_list.back()->copy_requests); |
| 174 } | 173 } |
| 175 | 174 |
| 176 ClearCopyRequests(); | 175 ClearCopyRequests(); |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 194 UnrefFrameResourcesAndRunDrawCallback(std::move(previous_frame_data)); | 193 UnrefFrameResourcesAndRunDrawCallback(std::move(previous_frame_data)); |
| 195 | 194 |
| 196 for (auto& observer : observers_) | 195 for (auto& observer : observers_) |
| 197 observer.OnSurfaceActivated(this); | 196 observer.OnSurfaceActivated(this); |
| 198 } | 197 } |
| 199 | 198 |
| 200 void Surface::UpdateBlockingSurfaces(bool has_previous_pending_frame, | 199 void Surface::UpdateBlockingSurfaces(bool has_previous_pending_frame, |
| 201 const CompositorFrame& current_frame) { | 200 const CompositorFrame& current_frame) { |
| 202 // If there is no SurfaceDependencyTracker installed then the |current_frame| | 201 // If there is no SurfaceDependencyTracker installed then the |current_frame| |
| 203 // does not block on anything. | 202 // does not block on anything. |
| 204 if (!factory_->manager()->dependency_tracker()) { | 203 if (!compositor_frame_sink_support_->surface_manager() |
| 204 ->dependency_tracker()) { | |
| 205 blocking_surfaces_.clear(); | 205 blocking_surfaces_.clear(); |
| 206 return; | 206 return; |
| 207 } | 207 } |
| 208 | 208 |
| 209 base::flat_set<SurfaceId> new_blocking_surfaces; | 209 base::flat_set<SurfaceId> new_blocking_surfaces; |
| 210 | 210 |
| 211 for (const SurfaceId& surface_id : current_frame.metadata.embedded_surfaces) { | 211 for (const SurfaceId& surface_id : current_frame.metadata.embedded_surfaces) { |
| 212 Surface* surface = factory_->manager()->GetSurfaceForId(surface_id); | 212 Surface* surface = |
| 213 compositor_frame_sink_support_->surface_manager()->GetSurfaceForId( | |
| 214 surface_id); | |
| 213 // If a referenced surface does not have a corresponding active frame in the | 215 // If a referenced surface does not have a corresponding active frame in the |
| 214 // display compositor, then it blocks this frame. | 216 // display compositor, then it blocks this frame. |
| 215 if (!surface || !surface->HasActiveFrame()) | 217 if (!surface || !surface->HasActiveFrame()) |
| 216 new_blocking_surfaces.insert(surface_id); | 218 new_blocking_surfaces.insert(surface_id); |
| 217 } | 219 } |
| 218 | 220 |
| 219 // If this Surface has a previous pending frame, then we must determine the | 221 // If this Surface has a previous pending frame, then we must determine the |
| 220 // changes in dependencies so that we can update the SurfaceDependencyTracker | 222 // changes in dependencies so that we can update the SurfaceDependencyTracker |
| 221 // map. | 223 // map. |
| 222 if (has_previous_pending_frame) { | 224 if (has_previous_pending_frame) { |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 300 std::unordered_set<FrameSinkId, FrameSinkIdHash>* valid_frame_sink_ids) { | 302 std::unordered_set<FrameSinkId, FrameSinkIdHash>* valid_frame_sink_ids) { |
| 301 base::EraseIf(destruction_dependencies_, | 303 base::EraseIf(destruction_dependencies_, |
| 302 [sequences, valid_frame_sink_ids](SurfaceSequence seq) { | 304 [sequences, valid_frame_sink_ids](SurfaceSequence seq) { |
| 303 return (!!sequences->erase(seq) || | 305 return (!!sequences->erase(seq) || |
| 304 !valid_frame_sink_ids->count(seq.frame_sink_id)); | 306 !valid_frame_sink_ids->count(seq.frame_sink_id)); |
| 305 }); | 307 }); |
| 306 } | 308 } |
| 307 | 309 |
| 308 void Surface::UnrefFrameResourcesAndRunDrawCallback( | 310 void Surface::UnrefFrameResourcesAndRunDrawCallback( |
| 309 base::Optional<FrameData> frame_data) { | 311 base::Optional<FrameData> frame_data) { |
| 310 if (!frame_data || !factory_) | 312 if (!frame_data || !compositor_frame_sink_support_) |
| 311 return; | 313 return; |
| 312 | 314 |
| 313 ReturnedResourceArray resources; | 315 ReturnedResourceArray resources; |
| 314 TransferableResource::ReturnResources(frame_data->frame.resource_list, | 316 TransferableResource::ReturnResources(frame_data->frame.resource_list, |
| 315 &resources); | 317 &resources); |
| 316 // No point in returning same sync token to sender. | 318 // No point in returning same sync token to sender. |
| 317 for (auto& resource : resources) | 319 for (auto& resource : resources) |
| 318 resource.sync_token.Clear(); | 320 resource.sync_token.Clear(); |
| 319 factory_->UnrefResources(resources); | 321 compositor_frame_sink_support_->UnrefResources(resources); |
| 320 | 322 |
| 321 if (!frame_data->draw_callback.is_null()) | 323 if (!frame_data->draw_callback.is_null()) |
| 322 frame_data->draw_callback.Run(); | 324 frame_data->draw_callback.Run(); |
| 323 } | 325 } |
| 324 | 326 |
| 325 void Surface::ClearCopyRequests() { | 327 void Surface::ClearCopyRequests() { |
| 326 if (active_frame_data_) { | 328 if (active_frame_data_) { |
| 327 for (const auto& render_pass : active_frame_data_->frame.render_pass_list) { | 329 for (const auto& render_pass : active_frame_data_->frame.render_pass_list) { |
| 328 for (const auto& copy_request : render_pass->copy_requests) | 330 for (const auto& copy_request : render_pass->copy_requests) |
| 329 copy_request->SendEmptyResult(); | 331 copy_request->SendEmptyResult(); |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 346 frame->metadata.latency_info.swap(*latency_info); | 348 frame->metadata.latency_info.swap(*latency_info); |
| 347 return; | 349 return; |
| 348 } | 350 } |
| 349 std::copy(frame->metadata.latency_info.begin(), | 351 std::copy(frame->metadata.latency_info.begin(), |
| 350 frame->metadata.latency_info.end(), | 352 frame->metadata.latency_info.end(), |
| 351 std::back_inserter(*latency_info)); | 353 std::back_inserter(*latency_info)); |
| 352 frame->metadata.latency_info.clear(); | 354 frame->metadata.latency_info.clear(); |
| 353 } | 355 } |
| 354 | 356 |
| 355 } // namespace cc | 357 } // namespace cc |
| OLD | NEW |