| 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/display_compositor.h" | 5 #include "services/ui/surfaces/display_compositor.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/memory/ptr_util.h" | 9 #include "base/memory/ptr_util.h" |
| 10 #include "base/threading/thread_task_runner_handle.h" | 10 #include "base/threading/thread_task_runner_handle.h" |
| 11 #include "cc/output/in_process_context_provider.h" | 11 #include "cc/output/in_process_context_provider.h" |
| 12 #include "cc/output/texture_mailbox_deleter.h" | 12 #include "cc/output/texture_mailbox_deleter.h" |
| 13 #include "cc/surfaces/display.h" | 13 #include "cc/surfaces/display.h" |
| 14 #include "cc/surfaces/display_scheduler.h" | 14 #include "cc/surfaces/display_scheduler.h" |
| 15 #include "cc/surfaces/surface.h" | 15 #include "cc/surfaces/surface.h" |
| 16 #include "gpu/command_buffer/client/shared_memory_limits.h" | 16 #include "gpu/command_buffer/client/shared_memory_limits.h" |
| 17 #include "gpu/ipc/gpu_in_process_thread_service.h" | 17 #include "gpu/ipc/gpu_in_process_thread_service.h" |
| 18 #include "mojo/public/cpp/bindings/strong_binding.h" | 18 #include "mojo/public/cpp/bindings/strong_binding.h" |
| 19 #include "services/ui/surfaces/display_output_surface.h" | 19 #include "services/ui/surfaces/display_output_surface.h" |
| 20 #include "services/ui/surfaces/gpu_compositor_frame_sink.h" | 20 #include "services/ui/surfaces/gpu_compositor_frame_sink.h" |
| 21 | 21 |
| 22 #if defined(USE_OZONE) | 22 #if defined(USE_OZONE) |
| 23 #include "gpu/command_buffer/client/gles2_interface.h" | 23 #include "gpu/command_buffer/client/gles2_interface.h" |
| 24 #include "services/ui/surfaces/display_output_surface_ozone.h" | 24 #include "services/ui/surfaces/display_output_surface_ozone.h" |
| 25 #endif | 25 #endif |
| 26 | 26 |
| 27 namespace ui { | 27 namespace ui { |
| 28 | 28 |
| 29 DisplayCompositor::DisplayCompositor( | 29 DisplayCompositor::DisplayCompositor( |
| 30 scoped_refptr<gpu::InProcessCommandBuffer::Service> gpu_service, | 30 scoped_refptr<gpu::InProcessCommandBuffer::Service> gpu_service, |
| 31 std::unique_ptr<gpu::GpuMemoryBufferManager> gpu_memory_buffer_manager, | 31 std::unique_ptr<gpu::GpuMemoryBufferManager> gpu_memory_buffer_manager, |
| 32 gpu::ImageFactory* image_factory, | 32 gpu::ImageFactory* image_factory, |
| 33 cc::mojom::DisplayCompositorRequest request, | 33 cc::mojom::DisplayCompositorRequest request, |
| 34 cc::mojom::DisplayCompositorClientPtr client) | 34 cc::mojom::DisplayCompositorClientPtr client) |
| 35 : manager_(cc::SurfaceManager::LifetimeType::REFERENCES), | 35 : manager_(cc::SurfaceManager::LifetimeType::REFERENCES), |
| 36 reference_manager_(&manager_), | 36 reference_manager_(&manager_), |
| 37 gpu_service_(std::move(gpu_service)), | 37 gpu_service_(std::move(gpu_service)), |
| 38 gpu_memory_buffer_manager_(std::move(gpu_memory_buffer_manager)), | 38 gpu_memory_buffer_manager_(std::move(gpu_memory_buffer_manager)), |
| 39 image_factory_(image_factory), | 39 image_factory_(image_factory), |
| 40 task_runner_(base::ThreadTaskRunnerHandle::Get()), | 40 task_runner_(base::ThreadTaskRunnerHandle::Get()), |
| 41 client_(std::move(client)), | 41 client_(std::move(client)), |
| 42 binding_(this, std::move(request)) { | 42 binding_(this, std::move(request)) { |
| 43 manager_.AddObserver(this); | 43 manager_.AddObserver(this); |
| 44 if (client_) | 44 if (client_) |
| 45 client_->OnDisplayCompositorCreated(GetRootSurfaceId()); | 45 client_->OnDisplayCompositorCreated(GetRootSurfaceId()); |
| 46 } | 46 } |
| 47 | 47 |
| 48 void DisplayCompositor::AddSurfaceReferences( | 48 void DisplayCompositor::AddSurfaceReferences( |
| 49 const std::vector<cc::SurfaceReference>& references) { | 49 const std::vector<cc::SurfaceReference>& references) { |
| 50 DCHECK(thread_checker_.CalledOnValidThread()); | 50 DCHECK(thread_checker_.CalledOnValidThread()); |
| 51 for (auto& reference : references) | 51 for (const auto& reference : references) { |
| 52 AddSurfaceReference(reference); | 52 reference_manager_->AddSurfaceReference(reference.parent_id(), |
| 53 reference.child_id()); |
| 54 } |
| 53 } | 55 } |
| 54 | 56 |
| 55 void DisplayCompositor::RemoveSurfaceReferences( | 57 void DisplayCompositor::RemoveSurfaceReferences( |
| 56 const std::vector<cc::SurfaceReference>& references) { | 58 const std::vector<cc::SurfaceReference>& references) { |
| 57 DCHECK(thread_checker_.CalledOnValidThread()); | 59 DCHECK(thread_checker_.CalledOnValidThread()); |
| 58 | 60 |
| 59 // TODO(kylechar): Each remove reference can trigger GC, it would be better if | 61 // TODO(kylechar): Each remove reference can trigger GC, it would be better if |
| 60 // we GC only once if removing multiple references. | 62 // we GC only once if removing multiple references. |
| 61 for (auto& reference : references) | 63 for (const auto& reference : references) { |
| 62 RemoveSurfaceReference(reference); | 64 reference_manager_->RemoveSurfaceReference(reference.parent_id(), |
| 65 reference.child_id()); |
| 66 } |
| 63 } | 67 } |
| 64 | 68 |
| 65 DisplayCompositor::~DisplayCompositor() { | 69 DisplayCompositor::~DisplayCompositor() { |
| 66 DCHECK(thread_checker_.CalledOnValidThread()); | 70 DCHECK(thread_checker_.CalledOnValidThread()); |
| 67 // Remove all temporary references on shutdown. | |
| 68 for (auto& map_entry : temp_references_) { | |
| 69 const cc::FrameSinkId& frame_sink_id = map_entry.first; | |
| 70 for (auto& local_frame_id : map_entry.second) { | |
| 71 reference_manager_->RemoveSurfaceReference( | |
| 72 GetRootSurfaceId(), cc::SurfaceId(frame_sink_id, local_frame_id)); | |
| 73 } | |
| 74 } | |
| 75 manager_.RemoveObserver(this); | 71 manager_.RemoveObserver(this); |
| 76 } | 72 } |
| 77 | 73 |
| 78 void DisplayCompositor::OnCompositorFrameSinkClientConnectionLost( | 74 void DisplayCompositor::OnCompositorFrameSinkClientConnectionLost( |
| 79 const cc::FrameSinkId& frame_sink_id, | 75 const cc::FrameSinkId& frame_sink_id, |
| 80 bool destroy_compositor_frame_sink) { | 76 bool destroy_compositor_frame_sink) { |
| 81 DCHECK(thread_checker_.CalledOnValidThread()); | 77 DCHECK(thread_checker_.CalledOnValidThread()); |
| 82 if (destroy_compositor_frame_sink) | 78 if (destroy_compositor_frame_sink) |
| 83 compositor_frame_sinks_.erase(frame_sink_id); | 79 compositor_frame_sinks_.erase(frame_sink_id); |
| 84 // TODO(fsamuel): Tell the display compositor host that the client connection | 80 // TODO(fsamuel): Tell the display compositor host that the client connection |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 119 const cc::FrameSinkId& frame_sink_id, | 115 const cc::FrameSinkId& frame_sink_id, |
| 120 cc::mojom::MojoCompositorFrameSinkRequest request, | 116 cc::mojom::MojoCompositorFrameSinkRequest request, |
| 121 cc::mojom::MojoCompositorFrameSinkPrivateRequest private_request, | 117 cc::mojom::MojoCompositorFrameSinkPrivateRequest private_request, |
| 122 cc::mojom::MojoCompositorFrameSinkClientPtr client) { | 118 cc::mojom::MojoCompositorFrameSinkClientPtr client) { |
| 123 CreateCompositorFrameSinkInternal(frame_sink_id, gpu::kNullSurfaceHandle, | 119 CreateCompositorFrameSinkInternal(frame_sink_id, gpu::kNullSurfaceHandle, |
| 124 nullptr, nullptr, std::move(request), | 120 nullptr, nullptr, std::move(request), |
| 125 std::move(private_request), | 121 std::move(private_request), |
| 126 std::move(client), nullptr); | 122 std::move(client), nullptr); |
| 127 } | 123 } |
| 128 | 124 |
| 129 void DisplayCompositor::AddSurfaceReference(const cc::SurfaceReference& ref) { | |
| 130 const cc::SurfaceId& parent_id = ref.parent_id(); | |
| 131 const cc::SurfaceId& child_id = ref.child_id(); | |
| 132 | |
| 133 auto vector_iter = temp_references_.find(child_id.frame_sink_id()); | |
| 134 | |
| 135 // If there are no temporary references for the FrameSinkId then we can just | |
| 136 // add reference and return. | |
| 137 if (vector_iter == temp_references_.end()) { | |
| 138 reference_manager_->AddSurfaceReference(parent_id, child_id); | |
| 139 return; | |
| 140 } | |
| 141 | |
| 142 // Get the vector<LocalFrameId> for the appropriate FrameSinkId and look for | |
| 143 // |child_id.local_frame_id| in that vector. If found, there is a temporary | |
| 144 // reference to |child_id|. | |
| 145 std::vector<cc::LocalFrameId>& refs = vector_iter->second; | |
| 146 auto temp_ref_iter = | |
| 147 std::find(refs.begin(), refs.end(), child_id.local_frame_id()); | |
| 148 | |
| 149 if (temp_ref_iter == refs.end()) { | |
| 150 reference_manager_->AddSurfaceReference(parent_id, child_id); | |
| 151 return; | |
| 152 } | |
| 153 | |
| 154 // All surfaces get a temporary reference to the top level root. If the parent | |
| 155 // wants to add a reference to the top level root then we do nothing. | |
| 156 // Otherwise remove the temporary reference and add the reference. | |
| 157 if (parent_id != GetRootSurfaceId()) { | |
| 158 reference_manager_->AddSurfaceReference(parent_id, child_id); | |
| 159 reference_manager_->RemoveSurfaceReference(GetRootSurfaceId(), child_id); | |
| 160 } | |
| 161 | |
| 162 // Remove temporary references for surfaces with the same FrameSinkId that | |
| 163 // were created before |child_id|. The earlier surfaces were never embedded in | |
| 164 // the parent and the parent is embedding a later surface, so we know the | |
| 165 // parent doesn't need them anymore. | |
| 166 for (auto iter = refs.begin(); iter != temp_ref_iter; ++iter) { | |
| 167 cc::SurfaceId id = cc::SurfaceId(child_id.frame_sink_id(), *iter); | |
| 168 reference_manager_->RemoveSurfaceReference(GetRootSurfaceId(), id); | |
| 169 } | |
| 170 | |
| 171 // Remove markers for temporary references up to |child_id|, as the temporary | |
| 172 // references they correspond to were removed above. If |temp_ref_iter| points | |
| 173 // at the last element in |refs| then we are removing all temporary references | |
| 174 // for the FrameSinkId and can remove the map entry entirely. | |
| 175 if (++temp_ref_iter == refs.end()) | |
| 176 temp_references_.erase(child_id.frame_sink_id()); | |
| 177 else | |
| 178 refs.erase(refs.begin(), temp_ref_iter); | |
| 179 } | |
| 180 | |
| 181 void DisplayCompositor::RemoveSurfaceReference( | |
| 182 const cc::SurfaceReference& ref) { | |
| 183 reference_manager_->RemoveSurfaceReference(ref.parent_id(), ref.child_id()); | |
| 184 } | |
| 185 | |
| 186 std::unique_ptr<cc::Display> DisplayCompositor::CreateDisplay( | 125 std::unique_ptr<cc::Display> DisplayCompositor::CreateDisplay( |
| 187 const cc::FrameSinkId& frame_sink_id, | 126 const cc::FrameSinkId& frame_sink_id, |
| 188 gpu::SurfaceHandle surface_handle, | 127 gpu::SurfaceHandle surface_handle, |
| 189 cc::SyntheticBeginFrameSource* begin_frame_source) { | 128 cc::SyntheticBeginFrameSource* begin_frame_source) { |
| 190 scoped_refptr<cc::InProcessContextProvider> context_provider = | 129 scoped_refptr<cc::InProcessContextProvider> context_provider = |
| 191 new cc::InProcessContextProvider( | 130 new cc::InProcessContextProvider( |
| 192 gpu_service_, surface_handle, gpu_memory_buffer_manager_.get(), | 131 gpu_service_, surface_handle, gpu_memory_buffer_manager_.get(), |
| 193 image_factory_, gpu::SharedMemoryLimits(), | 132 image_factory_, gpu::SharedMemoryLimits(), |
| 194 nullptr /* shared_context */); | 133 nullptr /* shared_context */); |
| 195 | 134 |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 247 std::move(display_request)); | 186 std::move(display_request)); |
| 248 } | 187 } |
| 249 | 188 |
| 250 const cc::SurfaceId& DisplayCompositor::GetRootSurfaceId() const { | 189 const cc::SurfaceId& DisplayCompositor::GetRootSurfaceId() const { |
| 251 return reference_manager_->GetRootSurfaceId(); | 190 return reference_manager_->GetRootSurfaceId(); |
| 252 } | 191 } |
| 253 | 192 |
| 254 void DisplayCompositor::OnSurfaceCreated(const cc::SurfaceInfo& surface_info) { | 193 void DisplayCompositor::OnSurfaceCreated(const cc::SurfaceInfo& surface_info) { |
| 255 DCHECK(thread_checker_.CalledOnValidThread()); | 194 DCHECK(thread_checker_.CalledOnValidThread()); |
| 256 DCHECK_GT(surface_info.device_scale_factor(), 0.0f); | 195 DCHECK_GT(surface_info.device_scale_factor(), 0.0f); |
| 257 // We can get into a situation where multiple CompositorFrames arrive for a | |
| 258 // CompositorFrameSink before the DisplayCompositorClient can add any | |
| 259 // references for the frame. When the second frame with a new size arrives, | |
| 260 // the first will be destroyed and then if there are no references it will be | |
| 261 // deleted during surface GC. A temporary reference, removed when a real | |
| 262 // reference is received, is added to prevent this from happening. | |
| 263 reference_manager_->AddSurfaceReference(GetRootSurfaceId(), | |
| 264 surface_info.id()); | |
| 265 temp_references_[surface_info.id().frame_sink_id()].push_back( | |
| 266 surface_info.id().local_frame_id()); | |
| 267 | 196 |
| 268 if (client_) | 197 if (client_) |
| 269 client_->OnSurfaceCreated(surface_info); | 198 client_->OnSurfaceCreated(surface_info); |
| 270 } | 199 } |
| 271 | 200 |
| 272 void DisplayCompositor::OnSurfaceDamaged(const cc::SurfaceId& surface_id, | 201 void DisplayCompositor::OnSurfaceDamaged(const cc::SurfaceId& surface_id, |
| 273 bool* changed) {} | 202 bool* changed) {} |
| 274 | 203 |
| 275 } // namespace ui | 204 } // namespace ui |
| OLD | NEW |