| 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/gpu_compositor_frame_sink.h" | 5 #include "services/ui/surfaces/gpu_compositor_frame_sink.h" |
| 6 | 6 |
| 7 #include "base/callback.h" | |
| 8 #include "base/message_loop/message_loop.h" | |
| 9 #include "base/single_thread_task_runner.h" | |
| 10 #include "base/threading/thread_task_runner_handle.h" | |
| 11 #include "cc/output/compositor_frame.h" | |
| 12 #include "cc/output/output_surface.h" | |
| 13 #include "cc/quads/shared_quad_state.h" | |
| 14 #include "cc/quads/surface_draw_quad.h" | |
| 15 #include "cc/scheduler/begin_frame_source.h" | |
| 16 #include "cc/surfaces/display.h" | |
| 17 #include "services/ui/surfaces/display_compositor.h" | 7 #include "services/ui/surfaces/display_compositor.h" |
| 18 | 8 |
| 19 namespace ui { | 9 namespace ui { |
| 20 | 10 |
| 21 GpuCompositorFrameSink::GpuCompositorFrameSink( | 11 GpuCompositorFrameSink::GpuCompositorFrameSink( |
| 22 DisplayCompositor* display_compositor, | 12 DisplayCompositor* display_compositor, |
| 23 const cc::FrameSinkId& frame_sink_id, | 13 const cc::FrameSinkId& frame_sink_id, |
| 24 std::unique_ptr<cc::Display> display, | 14 std::unique_ptr<cc::Display> display, |
| 25 cc::mojom::MojoCompositorFrameSinkRequest request, | 15 cc::mojom::MojoCompositorFrameSinkRequest request, |
| 26 cc::mojom::MojoCompositorFrameSinkPrivateRequest private_request, | 16 cc::mojom::MojoCompositorFrameSinkPrivateRequest private_request, |
| 27 cc::mojom::MojoCompositorFrameSinkClientPtr client) | 17 cc::mojom::MojoCompositorFrameSinkClientPtr client) |
| 28 : frame_sink_id_(frame_sink_id), | 18 : display_compositor_(display_compositor), |
| 29 display_compositor_(display_compositor), | 19 support_(this, |
| 30 display_(std::move(display)), | 20 display_compositor->manager(), |
| 31 surface_factory_(frame_sink_id_, display_compositor_->manager(), this), | 21 frame_sink_id, |
| 22 std::move(display)), |
| 32 client_(std::move(client)), | 23 client_(std::move(client)), |
| 33 binding_(this, std::move(request)), | 24 binding_(this, std::move(request)), |
| 34 private_binding_(this, std::move(private_request)), | 25 private_binding_(this, std::move(private_request)) { |
| 35 weak_factory_(this) { | |
| 36 display_compositor_->manager()->RegisterFrameSinkId(frame_sink_id_); | |
| 37 display_compositor_->manager()->RegisterSurfaceFactoryClient(frame_sink_id_, | |
| 38 this); | |
| 39 | |
| 40 if (display_) { | |
| 41 display_->Initialize(this, display_compositor_->manager()); | |
| 42 display_->SetVisible(true); | |
| 43 } | |
| 44 | |
| 45 binding_.set_connection_error_handler(base::Bind( | 26 binding_.set_connection_error_handler(base::Bind( |
| 46 &GpuCompositorFrameSink::OnClientConnectionLost, base::Unretained(this))); | 27 &GpuCompositorFrameSink::OnClientConnectionLost, base::Unretained(this))); |
| 47 | 28 |
| 48 private_binding_.set_connection_error_handler( | 29 private_binding_.set_connection_error_handler( |
| 49 base::Bind(&GpuCompositorFrameSink::OnPrivateConnectionLost, | 30 base::Bind(&GpuCompositorFrameSink::OnPrivateConnectionLost, |
| 50 base::Unretained(this))); | 31 base::Unretained(this))); |
| 51 } | 32 } |
| 52 | 33 |
| 53 GpuCompositorFrameSink::~GpuCompositorFrameSink() { | 34 GpuCompositorFrameSink::~GpuCompositorFrameSink() {} |
| 54 // SurfaceFactory's destructor will attempt to return resources which will | 35 |
| 55 // call back into here and access |client_| so we should destroy | 36 void GpuCompositorFrameSink::EvictFrame() { |
| 56 // |surface_factory_|'s resources early on. | 37 support_.EvictFrame(); |
| 57 surface_factory_.EvictSurface(); | |
| 58 display_compositor_->manager()->UnregisterSurfaceFactoryClient( | |
| 59 frame_sink_id_); | |
| 60 display_compositor_->manager()->InvalidateFrameSinkId(frame_sink_id_); | |
| 61 } | 38 } |
| 62 | 39 |
| 63 void GpuCompositorFrameSink::SetNeedsBeginFrame(bool needs_begin_frame) { | 40 void GpuCompositorFrameSink::SetNeedsBeginFrame(bool needs_begin_frame) { |
| 64 needs_begin_frame_ = needs_begin_frame; | 41 support_.SetNeedsBeginFrame(needs_begin_frame); |
| 65 UpdateNeedsBeginFramesInternal(); | |
| 66 } | 42 } |
| 67 | 43 |
| 68 void GpuCompositorFrameSink::SubmitCompositorFrame( | 44 void GpuCompositorFrameSink::SubmitCompositorFrame( |
| 69 const cc::LocalFrameId& local_frame_id, | 45 const cc::LocalFrameId& local_frame_id, |
| 70 cc::CompositorFrame frame) { | 46 cc::CompositorFrame frame) { |
| 71 // If the size of the CompostiorFrame has changed then destroy the existing | 47 support_.SubmitCompositorFrame(local_frame_id, std::move(frame)); |
| 72 // Surface and create a new one of the appropriate size. | |
| 73 if (local_frame_id_ != local_frame_id) { | |
| 74 local_frame_id_ = local_frame_id; | |
| 75 if (display_ && !frame.render_pass_list.empty()) { | |
| 76 gfx::Size frame_size = frame.render_pass_list[0]->output_rect.size(); | |
| 77 display_->Resize(frame_size); | |
| 78 } | |
| 79 } | |
| 80 ++ack_pending_count_; | |
| 81 surface_factory_.SubmitCompositorFrame( | |
| 82 local_frame_id_, std::move(frame), | |
| 83 base::Bind(&GpuCompositorFrameSink::DidReceiveCompositorFrameAck, | |
| 84 weak_factory_.GetWeakPtr())); | |
| 85 if (display_) { | |
| 86 display_->SetLocalFrameId(local_frame_id_, | |
| 87 frame.metadata.device_scale_factor); | |
| 88 } | |
| 89 } | |
| 90 | |
| 91 void GpuCompositorFrameSink::EvictFrame() { | |
| 92 surface_factory_.EvictSurface(); | |
| 93 } | 48 } |
| 94 | 49 |
| 95 void GpuCompositorFrameSink::DidReceiveCompositorFrameAck() { | 50 void GpuCompositorFrameSink::DidReceiveCompositorFrameAck() { |
| 96 if (!client_) | |
| 97 return; | |
| 98 client_->DidReceiveCompositorFrameAck(); | 51 client_->DidReceiveCompositorFrameAck(); |
| 99 DCHECK_GT(ack_pending_count_, 0); | |
| 100 if (!surface_returned_resources_.empty()) { | |
| 101 client_->ReclaimResources(surface_returned_resources_); | |
| 102 surface_returned_resources_.clear(); | |
| 103 } | |
| 104 ack_pending_count_--; | |
| 105 } | 52 } |
| 106 | 53 |
| 107 void GpuCompositorFrameSink::AddChildFrameSink( | 54 void GpuCompositorFrameSink::AddChildFrameSink( |
| 108 const cc::FrameSinkId& child_frame_sink_id) { | 55 const cc::FrameSinkId& child_frame_sink_id) { |
| 109 cc::SurfaceManager* surface_manager = display_compositor_->manager(); | 56 support_.AddChildFrameSink(child_frame_sink_id); |
| 110 surface_manager->RegisterFrameSinkHierarchy(frame_sink_id_, | |
| 111 child_frame_sink_id); | |
| 112 } | 57 } |
| 113 | 58 |
| 114 void GpuCompositorFrameSink::RemoveChildFrameSink( | 59 void GpuCompositorFrameSink::RemoveChildFrameSink( |
| 115 const cc::FrameSinkId& child_frame_sink_id) { | 60 const cc::FrameSinkId& child_frame_sink_id) { |
| 116 cc::SurfaceManager* surface_manager = display_compositor_->manager(); | 61 support_.RemoveChildFrameSink(child_frame_sink_id); |
| 117 surface_manager->UnregisterFrameSinkHierarchy(frame_sink_id_, | |
| 118 child_frame_sink_id); | |
| 119 } | |
| 120 | |
| 121 void GpuCompositorFrameSink::DisplayOutputSurfaceLost() {} | |
| 122 | |
| 123 void GpuCompositorFrameSink::DisplayWillDrawAndSwap( | |
| 124 bool will_draw_and_swap, | |
| 125 const cc::RenderPassList& render_passes) {} | |
| 126 | |
| 127 void GpuCompositorFrameSink::DisplayDidDrawAndSwap() {} | |
| 128 | |
| 129 void GpuCompositorFrameSink::ReturnResources( | |
| 130 const cc::ReturnedResourceArray& resources) { | |
| 131 if (resources.empty()) | |
| 132 return; | |
| 133 | |
| 134 if (!ack_pending_count_ && client_) { | |
| 135 client_->ReclaimResources(resources); | |
| 136 return; | |
| 137 } | |
| 138 | |
| 139 std::copy(resources.begin(), resources.end(), | |
| 140 std::back_inserter(surface_returned_resources_)); | |
| 141 } | |
| 142 | |
| 143 void GpuCompositorFrameSink::SetBeginFrameSource( | |
| 144 cc::BeginFrameSource* begin_frame_source) { | |
| 145 // TODO(tansell): Implement this. | |
| 146 if (begin_frame_source_ && added_frame_observer_) { | |
| 147 begin_frame_source_->RemoveObserver(this); | |
| 148 added_frame_observer_ = false; | |
| 149 } | |
| 150 begin_frame_source_ = begin_frame_source; | |
| 151 UpdateNeedsBeginFramesInternal(); | |
| 152 } | 62 } |
| 153 | 63 |
| 154 void GpuCompositorFrameSink::OnBeginFrame(const cc::BeginFrameArgs& args) { | 64 void GpuCompositorFrameSink::OnBeginFrame(const cc::BeginFrameArgs& args) { |
| 155 UpdateNeedsBeginFramesInternal(); | |
| 156 last_begin_frame_args_ = args; | |
| 157 if (client_) | 65 if (client_) |
| 158 client_->OnBeginFrame(args); | 66 client_->OnBeginFrame(args); |
| 159 } | 67 } |
| 160 | 68 |
| 161 const cc::BeginFrameArgs& GpuCompositorFrameSink::LastUsedBeginFrameArgs() | 69 void GpuCompositorFrameSink::ReclaimResources( |
| 162 const { | 70 const cc::ReturnedResourceArray& resources) { |
| 163 return last_begin_frame_args_; | 71 if (client_) |
| 72 client_->ReclaimResources(resources); |
| 164 } | 73 } |
| 165 | 74 |
| 166 void GpuCompositorFrameSink::OnBeginFrameSourcePausedChanged(bool paused) {} | 75 void GpuCompositorFrameSink::WillDrawSurface() { |
| 167 | 76 if (client_) |
| 168 void GpuCompositorFrameSink::UpdateNeedsBeginFramesInternal() { | 77 client_->WillDrawSurface(); |
| 169 if (!begin_frame_source_) | |
| 170 return; | |
| 171 | |
| 172 if (needs_begin_frame_ == added_frame_observer_) | |
| 173 return; | |
| 174 | |
| 175 added_frame_observer_ = needs_begin_frame_; | |
| 176 if (needs_begin_frame_) | |
| 177 begin_frame_source_->AddObserver(this); | |
| 178 else | |
| 179 begin_frame_source_->RemoveObserver(this); | |
| 180 } | 78 } |
| 181 | 79 |
| 182 void GpuCompositorFrameSink::OnClientConnectionLost() { | 80 void GpuCompositorFrameSink::OnClientConnectionLost() { |
| 183 client_connection_lost_ = true; | 81 client_connection_lost_ = true; |
| 184 // Request destruction of |this| only if both connections are lost. | 82 // Request destruction of |this| only if both connections are lost. |
| 185 display_compositor_->OnCompositorFrameSinkClientConnectionLost( | 83 display_compositor_->OnCompositorFrameSinkClientConnectionLost( |
| 186 frame_sink_id_, private_connection_lost_); | 84 support_.frame_sink_id(), private_connection_lost_); |
| 187 } | 85 } |
| 188 | 86 |
| 189 void GpuCompositorFrameSink::OnPrivateConnectionLost() { | 87 void GpuCompositorFrameSink::OnPrivateConnectionLost() { |
| 190 private_connection_lost_ = true; | 88 private_connection_lost_ = true; |
| 191 // Request destruction of |this| only if both connections are lost. | 89 // Request destruction of |this| only if both connections are lost. |
| 192 display_compositor_->OnCompositorFrameSinkPrivateConnectionLost( | 90 display_compositor_->OnCompositorFrameSinkPrivateConnectionLost( |
| 193 frame_sink_id_, client_connection_lost_); | 91 support_.frame_sink_id(), client_connection_lost_); |
| 194 } | 92 } |
| 195 | 93 |
| 196 } // namespace ui | 94 } // namespace ui |
| OLD | NEW |