| 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> |
| (...skipping 13 matching lines...) Expand all Loading... |
| 24 | 24 |
| 25 Surface::Surface(const SurfaceId& id, base::WeakPtr<SurfaceFactory> factory) | 25 Surface::Surface(const SurfaceId& id, base::WeakPtr<SurfaceFactory> factory) |
| 26 : surface_id_(id), | 26 : surface_id_(id), |
| 27 previous_frame_surface_id_(id), | 27 previous_frame_surface_id_(id), |
| 28 factory_(factory), | 28 factory_(factory), |
| 29 frame_index_(kFrameIndexStart), | 29 frame_index_(kFrameIndexStart), |
| 30 destroyed_(false) {} | 30 destroyed_(false) {} |
| 31 | 31 |
| 32 Surface::~Surface() { | 32 Surface::~Surface() { |
| 33 ClearCopyRequests(); | 33 ClearCopyRequests(); |
| 34 if (current_frame_.delegated_frame_data && factory_) { | 34 if (current_frame_ && factory_) { |
| 35 UnrefFrameResources(current_frame_.delegated_frame_data.get()); | 35 UnrefFrameResources(*current_frame_); |
| 36 } | 36 } |
| 37 if (!draw_callback_.is_null()) | 37 if (!draw_callback_.is_null()) |
| 38 draw_callback_.Run(); | 38 draw_callback_.Run(); |
| 39 } | 39 } |
| 40 | 40 |
| 41 void Surface::SetPreviousFrameSurface(Surface* surface) { | 41 void Surface::SetPreviousFrameSurface(Surface* surface) { |
| 42 DCHECK(surface); | 42 DCHECK(surface); |
| 43 frame_index_ = surface->frame_index() + 1; | 43 frame_index_ = surface->frame_index() + 1; |
| 44 previous_frame_surface_id_ = surface->surface_id(); | 44 previous_frame_surface_id_ = surface->surface_id(); |
| 45 } | 45 } |
| 46 | 46 |
| 47 void Surface::QueueFrame(CompositorFrame frame, const DrawCallback& callback) { | 47 void Surface::QueueFrame(CompositorFrame frame, const DrawCallback& callback) { |
| 48 DCHECK(factory_); | 48 DCHECK(factory_); |
| 49 ClearCopyRequests(); | 49 ClearCopyRequests(); |
| 50 | 50 |
| 51 if (frame.delegated_frame_data) { | 51 TakeLatencyInfo(&frame.metadata.latency_info); |
| 52 TakeLatencyInfo(&frame.metadata.latency_info); | |
| 53 } | |
| 54 | 52 |
| 55 CompositorFrame previous_frame = std::move(current_frame_); | 53 base::Optional<CompositorFrame> previous_frame = std::move(current_frame_); |
| 56 current_frame_ = std::move(frame); | 54 current_frame_ = std::move(frame); |
| 57 | 55 |
| 58 if (current_frame_.delegated_frame_data) { | 56 if (current_frame_) { |
| 59 factory_->ReceiveFromChild( | 57 factory_->ReceiveFromChild(current_frame_->resource_list); |
| 60 current_frame_.delegated_frame_data->resource_list); | |
| 61 } | 58 } |
| 62 | 59 |
| 63 // Empty frames shouldn't be drawn and shouldn't contribute damage, so don't | 60 // Empty frames shouldn't be drawn and shouldn't contribute damage, so don't |
| 64 // increment frame index for them. | 61 // increment frame index for them. |
| 65 if (current_frame_.delegated_frame_data && | 62 if (current_frame_ && !current_frame_->render_pass_list.empty()) { |
| 66 !current_frame_.delegated_frame_data->render_pass_list.empty()) { | |
| 67 ++frame_index_; | 63 ++frame_index_; |
| 68 } | 64 } |
| 69 | 65 |
| 70 previous_frame_surface_id_ = surface_id(); | 66 previous_frame_surface_id_ = surface_id(); |
| 71 | 67 |
| 72 std::vector<SurfaceId> new_referenced_surfaces; | 68 std::vector<SurfaceId> new_referenced_surfaces; |
| 73 new_referenced_surfaces = current_frame_.metadata.referenced_surfaces; | 69 new_referenced_surfaces = current_frame_->metadata.referenced_surfaces; |
| 74 | 70 |
| 75 if (previous_frame.delegated_frame_data) | 71 if (previous_frame) |
| 76 UnrefFrameResources(previous_frame.delegated_frame_data.get()); | 72 UnrefFrameResources(*previous_frame); |
| 77 | 73 |
| 78 if (!draw_callback_.is_null()) | 74 if (!draw_callback_.is_null()) |
| 79 draw_callback_.Run(); | 75 draw_callback_.Run(); |
| 80 draw_callback_ = callback; | 76 draw_callback_ = callback; |
| 81 | 77 |
| 82 bool referenced_surfaces_changed = | 78 bool referenced_surfaces_changed = |
| 83 (referenced_surfaces_ != new_referenced_surfaces); | 79 (referenced_surfaces_ != new_referenced_surfaces); |
| 84 referenced_surfaces_ = new_referenced_surfaces; | 80 referenced_surfaces_ = new_referenced_surfaces; |
| 85 std::vector<uint32_t> satisfies_sequences = | 81 std::vector<uint32_t> satisfies_sequences = |
| 86 std::move(current_frame_.metadata.satisfies_sequences); | 82 std::move(current_frame_->metadata.satisfies_sequences); |
| 87 | 83 |
| 88 if (referenced_surfaces_changed || !satisfies_sequences.empty()) { | 84 if (referenced_surfaces_changed || !satisfies_sequences.empty()) { |
| 89 // Notify the manager that sequences were satisfied either if some new | 85 // Notify the manager that sequences were satisfied either if some new |
| 90 // sequences were satisfied, or if the set of referenced surfaces changed | 86 // sequences were satisfied, or if the set of referenced surfaces changed |
| 91 // to force a GC to happen. | 87 // to force a GC to happen. |
| 92 factory_->manager()->DidSatisfySequences(surface_id_.frame_sink_id(), | 88 factory_->manager()->DidSatisfySequences(surface_id_.frame_sink_id(), |
| 93 &satisfies_sequences); | 89 &satisfies_sequences); |
| 94 } | 90 } |
| 95 } | 91 } |
| 96 | 92 |
| 93 void Surface::EvictFrame() { |
| 94 QueueFrame(CompositorFrame(), DrawCallback()); |
| 95 current_frame_.reset(); |
| 96 } |
| 97 |
| 97 void Surface::RequestCopyOfOutput( | 98 void Surface::RequestCopyOfOutput( |
| 98 std::unique_ptr<CopyOutputRequest> copy_request) { | 99 std::unique_ptr<CopyOutputRequest> copy_request) { |
| 99 if (current_frame_.delegated_frame_data && | 100 if (current_frame_ && !current_frame_->render_pass_list.empty()) { |
| 100 !current_frame_.delegated_frame_data->render_pass_list.empty()) { | |
| 101 std::vector<std::unique_ptr<CopyOutputRequest>>& copy_requests = | 101 std::vector<std::unique_ptr<CopyOutputRequest>>& copy_requests = |
| 102 current_frame_.delegated_frame_data->render_pass_list.back() | 102 current_frame_->render_pass_list.back()->copy_requests; |
| 103 ->copy_requests; | |
| 104 | 103 |
| 105 if (void* source = copy_request->source()) { | 104 if (void* source = copy_request->source()) { |
| 106 // Remove existing CopyOutputRequests made on the Surface by the same | 105 // Remove existing CopyOutputRequests made on the Surface by the same |
| 107 // source. | 106 // source. |
| 108 auto to_remove = | 107 auto to_remove = |
| 109 std::remove_if(copy_requests.begin(), copy_requests.end(), | 108 std::remove_if(copy_requests.begin(), copy_requests.end(), |
| 110 [source](const std::unique_ptr<CopyOutputRequest>& x) { | 109 [source](const std::unique_ptr<CopyOutputRequest>& x) { |
| 111 return x->source() == source; | 110 return x->source() == source; |
| 112 }); | 111 }); |
| 113 copy_requests.erase(to_remove, copy_requests.end()); | 112 copy_requests.erase(to_remove, copy_requests.end()); |
| 114 } | 113 } |
| 115 copy_requests.push_back(std::move(copy_request)); | 114 copy_requests.push_back(std::move(copy_request)); |
| 116 } else { | 115 } else { |
| 117 copy_request->SendEmptyResult(); | 116 copy_request->SendEmptyResult(); |
| 118 } | 117 } |
| 119 } | 118 } |
| 120 | 119 |
| 121 void Surface::TakeCopyOutputRequests( | 120 void Surface::TakeCopyOutputRequests( |
| 122 std::multimap<RenderPassId, std::unique_ptr<CopyOutputRequest>>* | 121 std::multimap<RenderPassId, std::unique_ptr<CopyOutputRequest>>* |
| 123 copy_requests) { | 122 copy_requests) { |
| 124 DCHECK(copy_requests->empty()); | 123 DCHECK(copy_requests->empty()); |
| 125 if (current_frame_.delegated_frame_data) { | 124 if (current_frame_) { |
| 126 for (const auto& render_pass : | 125 for (const auto& render_pass : current_frame_->render_pass_list) { |
| 127 current_frame_.delegated_frame_data->render_pass_list) { | |
| 128 for (auto& request : render_pass->copy_requests) { | 126 for (auto& request : render_pass->copy_requests) { |
| 129 copy_requests->insert( | 127 copy_requests->insert( |
| 130 std::make_pair(render_pass->id, std::move(request))); | 128 std::make_pair(render_pass->id, std::move(request))); |
| 131 } | 129 } |
| 132 render_pass->copy_requests.clear(); | 130 render_pass->copy_requests.clear(); |
| 133 } | 131 } |
| 134 } | 132 } |
| 135 } | 133 } |
| 136 | 134 |
| 137 const CompositorFrame& Surface::GetEligibleFrame() { | 135 const CompositorFrame& Surface::GetEligibleFrame() { |
| 138 return current_frame_; | 136 DCHECK(current_frame_); |
| 137 return current_frame_.value(); |
| 139 } | 138 } |
| 140 | 139 |
| 141 void Surface::TakeLatencyInfo(std::vector<ui::LatencyInfo>* latency_info) { | 140 void Surface::TakeLatencyInfo(std::vector<ui::LatencyInfo>* latency_info) { |
| 142 if (!current_frame_.delegated_frame_data) | 141 if (!current_frame_) |
| 143 return; | 142 return; |
| 144 if (latency_info->empty()) { | 143 if (latency_info->empty()) { |
| 145 current_frame_.metadata.latency_info.swap(*latency_info); | 144 current_frame_->metadata.latency_info.swap(*latency_info); |
| 146 return; | 145 return; |
| 147 } | 146 } |
| 148 std::copy(current_frame_.metadata.latency_info.begin(), | 147 std::copy(current_frame_->metadata.latency_info.begin(), |
| 149 current_frame_.metadata.latency_info.end(), | 148 current_frame_->metadata.latency_info.end(), |
| 150 std::back_inserter(*latency_info)); | 149 std::back_inserter(*latency_info)); |
| 151 current_frame_.metadata.latency_info.clear(); | 150 current_frame_->metadata.latency_info.clear(); |
| 152 } | 151 } |
| 153 | 152 |
| 154 void Surface::RunDrawCallbacks() { | 153 void Surface::RunDrawCallbacks() { |
| 155 if (!draw_callback_.is_null()) { | 154 if (!draw_callback_.is_null()) { |
| 156 DrawCallback callback = draw_callback_; | 155 DrawCallback callback = draw_callback_; |
| 157 draw_callback_ = DrawCallback(); | 156 draw_callback_ = DrawCallback(); |
| 158 callback.Run(); | 157 callback.Run(); |
| 159 } | 158 } |
| 160 } | 159 } |
| 161 | 160 |
| 162 void Surface::AddDestructionDependency(SurfaceSequence sequence) { | 161 void Surface::AddDestructionDependency(SurfaceSequence sequence) { |
| 163 destruction_dependencies_.push_back(sequence); | 162 destruction_dependencies_.push_back(sequence); |
| 164 } | 163 } |
| 165 | 164 |
| 166 void Surface::SatisfyDestructionDependencies( | 165 void Surface::SatisfyDestructionDependencies( |
| 167 std::unordered_set<SurfaceSequence, SurfaceSequenceHash>* sequences, | 166 std::unordered_set<SurfaceSequence, SurfaceSequenceHash>* sequences, |
| 168 std::unordered_set<FrameSinkId, FrameSinkIdHash>* valid_frame_sink_ids) { | 167 std::unordered_set<FrameSinkId, FrameSinkIdHash>* valid_frame_sink_ids) { |
| 169 destruction_dependencies_.erase( | 168 destruction_dependencies_.erase( |
| 170 std::remove_if(destruction_dependencies_.begin(), | 169 std::remove_if(destruction_dependencies_.begin(), |
| 171 destruction_dependencies_.end(), | 170 destruction_dependencies_.end(), |
| 172 [sequences, valid_frame_sink_ids](SurfaceSequence seq) { | 171 [sequences, valid_frame_sink_ids](SurfaceSequence seq) { |
| 173 return (!!sequences->erase(seq) || | 172 return (!!sequences->erase(seq) || |
| 174 !valid_frame_sink_ids->count(seq.frame_sink_id)); | 173 !valid_frame_sink_ids->count(seq.frame_sink_id)); |
| 175 }), | 174 }), |
| 176 destruction_dependencies_.end()); | 175 destruction_dependencies_.end()); |
| 177 } | 176 } |
| 178 | 177 |
| 179 void Surface::UnrefFrameResources(DelegatedFrameData* frame_data) { | 178 void Surface::UnrefFrameResources(const CompositorFrame& frame) { |
| 180 ReturnedResourceArray resources; | 179 ReturnedResourceArray resources; |
| 181 TransferableResource::ReturnResources(frame_data->resource_list, &resources); | 180 TransferableResource::ReturnResources(frame.resource_list, &resources); |
| 182 // No point in returning same sync token to sender. | 181 // No point in returning same sync token to sender. |
| 183 for (auto& resource : resources) | 182 for (auto& resource : resources) |
| 184 resource.sync_token.Clear(); | 183 resource.sync_token.Clear(); |
| 185 factory_->UnrefResources(resources); | 184 factory_->UnrefResources(resources); |
| 186 } | 185 } |
| 187 | 186 |
| 188 void Surface::ClearCopyRequests() { | 187 void Surface::ClearCopyRequests() { |
| 189 if (current_frame_.delegated_frame_data) { | 188 if (current_frame_) { |
| 190 for (const auto& render_pass : | 189 for (const auto& render_pass : current_frame_->render_pass_list) { |
| 191 current_frame_.delegated_frame_data->render_pass_list) { | |
| 192 for (const auto& copy_request : render_pass->copy_requests) | 190 for (const auto& copy_request : render_pass->copy_requests) |
| 193 copy_request->SendEmptyResult(); | 191 copy_request->SendEmptyResult(); |
| 194 } | 192 } |
| 195 } | 193 } |
| 196 } | 194 } |
| 197 | 195 |
| 198 } // namespace cc | 196 } // namespace cc |
| OLD | NEW |