[email protected] | 1842fe2 | 2012-08-13 23:24:35 | [diff] [blame] | 1 | // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
| 5 | #include "content/renderer/gpu/compositor_output_surface.h" |
| 6 | |
[email protected] | 56f3373 | 2013-03-05 04:41:49 | [diff] [blame] | 7 | #include "base/command_line.h" |
skyostil | 2d3b5bd | 2015-05-27 15:40:59 | [diff] [blame] | 8 | #include "base/location.h" |
| 9 | #include "base/single_thread_task_runner.h" |
| 10 | #include "base/thread_task_runner_handle.h" |
[email protected] | 7f0d825f | 2013-03-18 07:24:30 | [diff] [blame] | 11 | #include "cc/output/compositor_frame.h" |
| 12 | #include "cc/output/compositor_frame_ack.h" |
[email protected] | e15c3d73 | 2013-09-24 07:30:27 | [diff] [blame] | 13 | #include "cc/output/managed_memory_policy.h" |
[email protected] | 7f0d825f | 2013-03-18 07:24:30 | [diff] [blame] | 14 | #include "cc/output/output_surface_client.h" |
[email protected] | 3ae68c5 | 2013-04-12 06:10:05 | [diff] [blame] | 15 | #include "content/common/gpu/client/command_buffer_proxy_impl.h" |
[email protected] | 0634cdd4 | 2013-08-16 00:46:09 | [diff] [blame] | 16 | #include "content/common/gpu/client/context_provider_command_buffer.h" |
[email protected] | 3ae68c5 | 2013-04-12 06:10:05 | [diff] [blame] | 17 | #include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h" |
[email protected] | 1842fe2 | 2012-08-13 23:24:35 | [diff] [blame] | 18 | #include "content/common/view_messages.h" |
[email protected] | 56f3373 | 2013-03-05 04:41:49 | [diff] [blame] | 19 | #include "content/public/common/content_switches.h" |
[email protected] | 586871b | 2014-07-22 17:05:11 | [diff] [blame] | 20 | #include "content/renderer/gpu/frame_swap_message_queue.h" |
[email protected] | 1842fe2 | 2012-08-13 23:24:35 | [diff] [blame] | 21 | #include "content/renderer/render_thread_impl.h" |
[email protected] | 758efb0 | 2014-04-05 07:53:45 | [diff] [blame] | 22 | #include "gpu/command_buffer/client/context_support.h" |
[email protected] | a770f2a | 2014-01-07 22:29:23 | [diff] [blame] | 23 | #include "gpu/command_buffer/client/gles2_interface.h" |
[email protected] | 1842fe2 | 2012-08-13 23:24:35 | [diff] [blame] | 24 | #include "ipc/ipc_sync_channel.h" |
[email protected] | 1842fe2 | 2012-08-13 23:24:35 | [diff] [blame] | 25 | |
[email protected] | e9ff79c | 2012-10-19 21:31:26 | [diff] [blame] | 26 | namespace content { |
| 27 | |
[email protected] | 1842fe2 | 2012-08-13 23:24:35 | [diff] [blame] | 28 | CompositorOutputSurface::CompositorOutputSurface( |
| 29 | int32 routing_id, |
[email protected] | 53b4cc1 | 2013-07-18 23:02:30 | [diff] [blame] | 30 | uint32 output_surface_id, |
[email protected] | 0634cdd4 | 2013-08-16 00:46:09 | [diff] [blame] | 31 | const scoped_refptr<ContextProviderCommandBuffer>& context_provider, |
caseq | ff9c74c | 2015-02-10 14:56:29 | [diff] [blame] | 32 | const scoped_refptr<ContextProviderCommandBuffer>& worker_context_provider, |
[email protected] | 0634cdd4 | 2013-08-16 00:46:09 | [diff] [blame] | 33 | scoped_ptr<cc::SoftwareOutputDevice> software_device, |
[email protected] | 586871b | 2014-07-22 17:05:11 | [diff] [blame] | 34 | scoped_refptr<FrameSwapMessageQueue> swap_frame_message_queue, |
[email protected] | 36e5ff1 | 2013-06-11 12:19:29 | [diff] [blame] | 35 | bool use_swap_compositor_frame_message) |
caseq | ff9c74c | 2015-02-10 14:56:29 | [diff] [blame] | 36 | : OutputSurface(context_provider, |
| 37 | worker_context_provider, |
| 38 | software_device.Pass()), |
[email protected] | 53b4cc1 | 2013-07-18 23:02:30 | [diff] [blame] | 39 | output_surface_id_(output_surface_id), |
[email protected] | 36e5ff1 | 2013-06-11 12:19:29 | [diff] [blame] | 40 | use_swap_compositor_frame_message_(use_swap_compositor_frame_message), |
[email protected] | 79a1be5 | 2013-02-13 23:59:50 | [diff] [blame] | 41 | output_surface_filter_( |
simonhong | a7e3ac4 | 2014-11-11 20:50:22 | [diff] [blame] | 42 | RenderThreadImpl::current()->compositor_message_filter()), |
[email protected] | 586871b | 2014-07-22 17:05:11 | [diff] [blame] | 43 | frame_swap_message_queue_(swap_frame_message_queue), |
[email protected] | 7d4481d1 | 2012-09-24 21:26:47 | [diff] [blame] | 44 | routing_id_(routing_id), |
toyoshim | a2815472 | 2015-06-26 00:02:12 | [diff] [blame] | 45 | #if defined(OS_ANDROID) |
[email protected] | 34351cca | 2013-01-23 03:22:15 | [diff] [blame] | 46 | prefers_smoothness_(false), |
toyoshim | a2815472 | 2015-06-26 00:02:12 | [diff] [blame] | 47 | main_thread_runner_(base::MessageLoop::current()->task_runner()), |
[email protected] | 8d14e56b | 2013-07-12 23:22:36 | [diff] [blame] | 48 | #endif |
[email protected] | 758efb0 | 2014-04-05 07:53:45 | [diff] [blame] | 49 | layout_test_mode_(RenderThreadImpl::current()->layout_test_mode()), |
| 50 | weak_ptrs_(this) { |
[email protected] | fc72bb1 | 2013-06-02 21:13:46 | [diff] [blame] | 51 | DCHECK(output_surface_filter_.get()); |
[email protected] | 586871b | 2014-07-22 17:05:11 | [diff] [blame] | 52 | DCHECK(frame_swap_message_queue_.get()); |
[email protected] | 1842fe2 | 2012-08-13 23:24:35 | [diff] [blame] | 53 | DetachFromThread(); |
sunnyps | 39c5af24 | 2015-06-08 22:07:33 | [diff] [blame] | 54 | capabilities_.max_frames_pending = 1; |
[email protected] | 2462b7f0 | 2013-04-23 02:12:02 | [diff] [blame] | 55 | message_sender_ = RenderThreadImpl::current()->sync_message_filter(); |
[email protected] | fc72bb1 | 2013-06-02 21:13:46 | [diff] [blame] | 56 | DCHECK(message_sender_.get()); |
[email protected] | 1842fe2 | 2012-08-13 23:24:35 | [diff] [blame] | 57 | } |
| 58 | |
| 59 | CompositorOutputSurface::~CompositorOutputSurface() { |
| 60 | DCHECK(CalledOnValidThread()); |
[email protected] | 049fc7a | 2013-06-18 12:32:35 | [diff] [blame] | 61 | if (!HasClient()) |
[email protected] | 1842fe2 | 2012-08-13 23:24:35 | [diff] [blame] | 62 | return; |
[email protected] | 34351cca | 2013-01-23 03:22:15 | [diff] [blame] | 63 | UpdateSmoothnessTakesPriority(false); |
[email protected] | fc72bb1 | 2013-06-02 21:13:46 | [diff] [blame] | 64 | if (output_surface_proxy_.get()) |
[email protected] | 79a1be5 | 2013-02-13 23:59:50 | [diff] [blame] | 65 | output_surface_proxy_->ClearOutputSurface(); |
simonhong | a7e3ac4 | 2014-11-11 20:50:22 | [diff] [blame] | 66 | output_surface_filter_->RemoveHandlerOnCompositorThread( |
| 67 | routing_id_, |
| 68 | output_surface_filter_handler_); |
[email protected] | 1842fe2 | 2012-08-13 23:24:35 | [diff] [blame] | 69 | } |
| 70 | |
[email protected] | a46f3293 | 2012-12-07 21:43:16 | [diff] [blame] | 71 | bool CompositorOutputSurface::BindToClient( |
| 72 | cc::OutputSurfaceClient* client) { |
[email protected] | 1842fe2 | 2012-08-13 23:24:35 | [diff] [blame] | 73 | DCHECK(CalledOnValidThread()); |
[email protected] | 1842fe2 | 2012-08-13 23:24:35 | [diff] [blame] | 74 | |
[email protected] | 79a1be5 | 2013-02-13 23:59:50 | [diff] [blame] | 75 | if (!cc::OutputSurface::BindToClient(client)) |
| 76 | return false; |
[email protected] | 1842fe2 | 2012-08-13 23:24:35 | [diff] [blame] | 77 | |
[email protected] | d4b437ef | 2012-10-03 06:03:39 | [diff] [blame] | 78 | output_surface_proxy_ = new CompositorOutputSurfaceProxy(this); |
simonhong | a7e3ac4 | 2014-11-11 20:50:22 | [diff] [blame] | 79 | output_surface_filter_handler_ = |
[email protected] | d4b437ef | 2012-10-03 06:03:39 | [diff] [blame] | 80 | base::Bind(&CompositorOutputSurfaceProxy::OnMessageReceived, |
simonhong | a7e3ac4 | 2014-11-11 20:50:22 | [diff] [blame] | 81 | output_surface_proxy_); |
| 82 | output_surface_filter_->AddHandlerOnCompositorThread( |
| 83 | routing_id_, |
| 84 | output_surface_filter_handler_); |
[email protected] | 1842fe2 | 2012-08-13 23:24:35 | [diff] [blame] | 85 | |
[email protected] | e15c3d73 | 2013-09-24 07:30:27 | [diff] [blame] | 86 | if (!context_provider()) { |
| 87 | // Without a GPU context, the memory policy otherwise wouldn't be set. |
| 88 | client->SetMemoryPolicy(cc::ManagedMemoryPolicy( |
[email protected] | 23b7297f | 2014-05-21 22:26:24 | [diff] [blame] | 89 | 128 * 1024 * 1024, |
[email protected] | f44d555 | 2013-10-29 04:56:29 | [diff] [blame] | 90 | gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE, |
[email protected] | 721532e2b | 2014-07-16 05:57:45 | [diff] [blame] | 91 | base::SharedMemory::GetHandleLimit() / 3)); |
[email protected] | e15c3d73 | 2013-09-24 07:30:27 | [diff] [blame] | 92 | } |
| 93 | |
[email protected] | 1842fe2 | 2012-08-13 23:24:35 | [diff] [blame] | 94 | return true; |
| 95 | } |
| 96 | |
[email protected] | 758efb0 | 2014-04-05 07:53:45 | [diff] [blame] | 97 | void CompositorOutputSurface::ShortcutSwapAck( |
| 98 | uint32 output_surface_id, |
jbauman | 95f74135 | 2015-08-07 02:10:34 | [diff] [blame^] | 99 | scoped_ptr<cc::GLFrameData> gl_frame_data) { |
[email protected] | 758efb0 | 2014-04-05 07:53:45 | [diff] [blame] | 100 | if (!layout_test_previous_frame_ack_) { |
| 101 | layout_test_previous_frame_ack_.reset(new cc::CompositorFrameAck); |
| 102 | layout_test_previous_frame_ack_->gl_frame_data.reset(new cc::GLFrameData); |
| 103 | } |
| 104 | |
| 105 | OnSwapAck(output_surface_id, *layout_test_previous_frame_ack_); |
| 106 | |
| 107 | layout_test_previous_frame_ack_->gl_frame_data = gl_frame_data.Pass(); |
[email protected] | 758efb0 | 2014-04-05 07:53:45 | [diff] [blame] | 108 | } |
| 109 | |
[email protected] | 36e5ff1 | 2013-06-11 12:19:29 | [diff] [blame] | 110 | void CompositorOutputSurface::SwapBuffers(cc::CompositorFrame* frame) { |
sievers | 4941650f | 2014-10-07 17:21:31 | [diff] [blame] | 111 | DCHECK(use_swap_compositor_frame_message_); |
| 112 | if (layout_test_mode_) { |
[email protected] | 758efb0 | 2014-04-05 07:53:45 | [diff] [blame] | 113 | // This code path is here to support layout tests that are currently |
| 114 | // doing a readback in the renderer instead of the browser. So they |
| 115 | // are using deprecated code paths in the renderer and don't need to |
| 116 | // actually swap anything to the browser. We shortcut the swap to the |
| 117 | // browser here and just ack directly within the renderer process. |
| 118 | // Once crbug.com/311404 is fixed, this can be removed. |
| 119 | |
| 120 | // This would indicate that crbug.com/311404 is being fixed, and this |
| 121 | // block needs to be removed. |
| 122 | DCHECK(!frame->delegated_frame_data); |
| 123 | |
jbauman | 95f74135 | 2015-08-07 02:10:34 | [diff] [blame^] | 124 | base::Closure closure = base::Bind( |
| 125 | &CompositorOutputSurface::ShortcutSwapAck, weak_ptrs_.GetWeakPtr(), |
| 126 | output_surface_id_, base::Passed(&frame->gl_frame_data)); |
[email protected] | 758efb0 | 2014-04-05 07:53:45 | [diff] [blame] | 127 | |
[email protected] | e636734 | 2014-06-21 02:52:31 | [diff] [blame] | 128 | if (context_provider()) { |
| 129 | gpu::gles2::GLES2Interface* context = context_provider()->ContextGL(); |
[email protected] | 758efb0 | 2014-04-05 07:53:45 | [diff] [blame] | 130 | context->Flush(); |
| 131 | uint32 sync_point = context->InsertSyncPointCHROMIUM(); |
[email protected] | e636734 | 2014-06-21 02:52:31 | [diff] [blame] | 132 | context_provider()->ContextSupport()->SignalSyncPoint(sync_point, |
| 133 | closure); |
[email protected] | 758efb0 | 2014-04-05 07:53:45 | [diff] [blame] | 134 | } else { |
skyostil | 2d3b5bd | 2015-05-27 15:40:59 | [diff] [blame] | 135 | base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, closure); |
[email protected] | 758efb0 | 2014-04-05 07:53:45 | [diff] [blame] | 136 | } |
[email protected] | 3dc0c77 | 2014-04-26 10:06:05 | [diff] [blame] | 137 | client_->DidSwapBuffers(); |
[email protected] | 758efb0 | 2014-04-05 07:53:45 | [diff] [blame] | 138 | return; |
sievers | 4941650f | 2014-10-07 17:21:31 | [diff] [blame] | 139 | } else { |
[email protected] | 586871b | 2014-07-22 17:05:11 | [diff] [blame] | 140 | { |
| 141 | ScopedVector<IPC::Message> messages; |
| 142 | std::vector<IPC::Message> messages_to_deliver_with_frame; |
| 143 | scoped_ptr<FrameSwapMessageQueue::SendMessageScope> send_message_scope = |
| 144 | frame_swap_message_queue_->AcquireSendMessageScope(); |
| 145 | frame_swap_message_queue_->DrainMessages(&messages); |
| 146 | FrameSwapMessageQueue::TransferMessages(messages, |
| 147 | &messages_to_deliver_with_frame); |
| 148 | Send(new ViewHostMsg_SwapCompositorFrame(routing_id_, |
| 149 | output_surface_id_, |
| 150 | *frame, |
| 151 | messages_to_deliver_with_frame)); |
| 152 | // ~send_message_scope. |
| 153 | } |
[email protected] | 3dc0c77 | 2014-04-26 10:06:05 | [diff] [blame] | 154 | client_->DidSwapBuffers(); |
[email protected] | 36e5ff1 | 2013-06-11 12:19:29 | [diff] [blame] | 155 | } |
[email protected] | 3ae68c5 | 2013-04-12 06:10:05 | [diff] [blame] | 156 | } |
| 157 | |
[email protected] | 1842fe2 | 2012-08-13 23:24:35 | [diff] [blame] | 158 | void CompositorOutputSurface::OnMessageReceived(const IPC::Message& message) { |
| 159 | DCHECK(CalledOnValidThread()); |
[email protected] | 049fc7a | 2013-06-18 12:32:35 | [diff] [blame] | 160 | if (!HasClient()) |
[email protected] | b75ce46a0 | 2012-08-15 22:27:06 | [diff] [blame] | 161 | return; |
[email protected] | 1842fe2 | 2012-08-13 23:24:35 | [diff] [blame] | 162 | IPC_BEGIN_MESSAGE_MAP(CompositorOutputSurface, message) |
[email protected] | 2bd1fcf0 | 2014-02-12 22:35:53 | [diff] [blame] | 163 | IPC_MESSAGE_HANDLER(ViewMsg_UpdateVSyncParameters, |
| 164 | OnUpdateVSyncParametersFromBrowser); |
[email protected] | 534f9aa | 2013-03-03 21:58:16 | [diff] [blame] | 165 | IPC_MESSAGE_HANDLER(ViewMsg_SwapCompositorFrameAck, OnSwapAck); |
[email protected] | a7335e0b | 2013-09-18 09:34:51 | [diff] [blame] | 166 | IPC_MESSAGE_HANDLER(ViewMsg_ReclaimCompositorResources, OnReclaimResources); |
[email protected] | 1842fe2 | 2012-08-13 23:24:35 | [diff] [blame] | 167 | IPC_END_MESSAGE_MAP() |
| 168 | } |
| 169 | |
[email protected] | 2bd1fcf0 | 2014-02-12 22:35:53 | [diff] [blame] | 170 | void CompositorOutputSurface::OnUpdateVSyncParametersFromBrowser( |
| 171 | base::TimeTicks timebase, |
| 172 | base::TimeDelta interval) { |
[email protected] | 1842fe2 | 2012-08-13 23:24:35 | [diff] [blame] | 173 | DCHECK(CalledOnValidThread()); |
[email protected] | 2bd1fcf0 | 2014-02-12 22:35:53 | [diff] [blame] | 174 | CommitVSyncParameters(timebase, interval); |
[email protected] | 1842fe2 | 2012-08-13 23:24:35 | [diff] [blame] | 175 | } |
[email protected] | e9ff79c | 2012-10-19 21:31:26 | [diff] [blame] | 176 | |
[email protected] | 53b4cc1 | 2013-07-18 23:02:30 | [diff] [blame] | 177 | void CompositorOutputSurface::OnSwapAck(uint32 output_surface_id, |
| 178 | const cc::CompositorFrameAck& ack) { |
| 179 | // Ignore message if it's a stale one coming from a different output surface |
| 180 | // (e.g. after a lost context). |
| 181 | if (output_surface_id != output_surface_id_) |
| 182 | return; |
[email protected] | a7335e0b | 2013-09-18 09:34:51 | [diff] [blame] | 183 | ReclaimResources(&ack); |
[email protected] | 3dc0c77 | 2014-04-26 10:06:05 | [diff] [blame] | 184 | client_->DidSwapBuffersComplete(); |
[email protected] | a7335e0b | 2013-09-18 09:34:51 | [diff] [blame] | 185 | } |
| 186 | |
| 187 | void CompositorOutputSurface::OnReclaimResources( |
| 188 | uint32 output_surface_id, |
| 189 | const cc::CompositorFrameAck& ack) { |
| 190 | // Ignore message if it's a stale one coming from a different output surface |
| 191 | // (e.g. after a lost context). |
| 192 | if (output_surface_id != output_surface_id_) |
| 193 | return; |
| 194 | ReclaimResources(&ack); |
[email protected] | 534f9aa | 2013-03-03 21:58:16 | [diff] [blame] | 195 | } |
| 196 | |
[email protected] | bf189f6 | 2012-12-18 03:42:11 | [diff] [blame] | 197 | bool CompositorOutputSurface::Send(IPC::Message* message) { |
[email protected] | 2462b7f0 | 2013-04-23 02:12:02 | [diff] [blame] | 198 | return message_sender_->Send(message); |
[email protected] | bf189f6 | 2012-12-18 03:42:11 | [diff] [blame] | 199 | } |
| 200 | |
[email protected] | 34351cca | 2013-01-23 03:22:15 | [diff] [blame] | 201 | #if defined(OS_ANDROID) |
toyoshim | a2815472 | 2015-06-26 00:02:12 | [diff] [blame] | 202 | namespace { |
| 203 | void SetThreadPriorityToIdle() { |
toyoshim | 7c0e195 | 2015-07-14 09:42:03 | [diff] [blame] | 204 | base::PlatformThread::SetCurrentThreadPriority( |
| 205 | base::ThreadPriority::BACKGROUND); |
[email protected] | 34351cca | 2013-01-23 03:22:15 | [diff] [blame] | 206 | } |
toyoshim | a2815472 | 2015-06-26 00:02:12 | [diff] [blame] | 207 | void SetThreadPriorityToDefault() { |
toyoshim | 7c0e195 | 2015-07-14 09:42:03 | [diff] [blame] | 208 | base::PlatformThread::SetCurrentThreadPriority(base::ThreadPriority::NORMAL); |
toyoshim | a2815472 | 2015-06-26 00:02:12 | [diff] [blame] | 209 | } |
| 210 | } // namespace |
| 211 | #endif |
[email protected] | 34351cca | 2013-01-23 03:22:15 | [diff] [blame] | 212 | |
| 213 | void CompositorOutputSurface::UpdateSmoothnessTakesPriority( |
| 214 | bool prefers_smoothness) { |
toyoshim | a2815472 | 2015-06-26 00:02:12 | [diff] [blame] | 215 | #if defined(OS_ANDROID) |
[email protected] | 34351cca | 2013-01-23 03:22:15 | [diff] [blame] | 216 | if (prefers_smoothness_ == prefers_smoothness) |
| 217 | return; |
[email protected] | 34351cca | 2013-01-23 03:22:15 | [diff] [blame] | 218 | prefers_smoothness_ = prefers_smoothness; |
toyoshim | a2815472 | 2015-06-26 00:02:12 | [diff] [blame] | 219 | if (prefers_smoothness) { |
| 220 | main_thread_runner_->PostTask(FROM_HERE, |
| 221 | base::Bind(&SetThreadPriorityToIdle)); |
| 222 | } else { |
| 223 | main_thread_runner_->PostTask(FROM_HERE, |
| 224 | base::Bind(&SetThreadPriorityToDefault)); |
| 225 | } |
| 226 | #endif |
[email protected] | 34351cca | 2013-01-23 03:22:15 | [diff] [blame] | 227 | } |
| 228 | |
[email protected] | e9ff79c | 2012-10-19 21:31:26 | [diff] [blame] | 229 | } // namespace content |