15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/renderer/gpu/compositor_output_surface.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/command_line.h" 8868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/message_loop/message_loop_proxy.h" 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/output/compositor_frame.h" 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/output/compositor_frame_ack.h" 1168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "cc/output/managed_memory_policy.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/output/output_surface_client.h" 13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/common/gpu/client/command_buffer_proxy_impl.h" 143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "content/common/gpu/client/context_provider_command_buffer.h" 15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/view_messages.h" 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/common/content_switches.h" 185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/renderer/gpu/frame_swap_message_queue.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/renderer/render_thread_impl.h" 20c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "gpu/command_buffer/client/context_support.h" 215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "gpu/command_buffer/client/gles2_interface.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_forwarding_message_filter.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_sync_channel.h" 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// There are several compositor surfaces in a process, but they share the same 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// compositor thread, so we use a simple int here to track prefer-smoothness. 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int g_prefer_smoothness_count = 0; 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content { 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//------------------------------------------------------------------------------ 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IPC::ForwardingMessageFilter* CompositorOutputSurface::CreateFilter( 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TaskRunner* target_task_runner) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) uint32 messages_to_filter[] = { 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ViewMsg_UpdateVSyncParameters::ID, 41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ViewMsg_SwapCompositorFrameAck::ID, 42d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ViewMsg_ReclaimCompositorResources::ID, 43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined(OS_ANDROID) 4490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ViewMsg_BeginFrame::ID 45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new IPC::ForwardingMessageFilter( 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) messages_to_filter, arraysize(messages_to_filter), 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) target_task_runner); 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CompositorOutputSurface::CompositorOutputSurface( 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32 routing_id, 55ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch uint32 output_surface_id, 563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const scoped_refptr<ContextProviderCommandBuffer>& context_provider, 573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_ptr<cc::SoftwareOutputDevice> software_device, 585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_refptr<FrameSwapMessageQueue> swap_frame_message_queue, 595e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) bool use_swap_compositor_frame_message) 603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) : OutputSurface(context_provider, software_device.Pass()), 61ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch output_surface_id_(output_surface_id), 625e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) use_swap_compositor_frame_message_(use_swap_compositor_frame_message), 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) output_surface_filter_( 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RenderThreadImpl::current()->compositor_output_surface_filter()), 655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) frame_swap_message_queue_(swap_frame_message_queue), 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) routing_id_(routing_id), 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) prefers_smoothness_(false), 687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#if defined(OS_WIN) 697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // TODO(epenner): Implement PlatformThread::CurrentHandle() on windows. 70c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch main_thread_handle_(base::PlatformThreadHandle()), 717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#else 72c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch main_thread_handle_(base::PlatformThread::CurrentHandle()), 737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#endif 74c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch layout_test_mode_(RenderThreadImpl::current()->layout_test_mode()), 75c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch weak_ptrs_(this) { 76868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(output_surface_filter_.get()); 775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK(frame_swap_message_queue_.get()); 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DetachFromThread(); 79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) message_sender_ = RenderThreadImpl::current()->sync_message_filter(); 80868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(message_sender_.get()); 81424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (OutputSurface::software_device()) 823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) capabilities_.max_frames_pending = 1; 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CompositorOutputSurface::~CompositorOutputSurface() { 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(CalledOnValidThread()); 87a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch SetNeedsBeginFrame(false); 887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (!HasClient()) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdateSmoothnessTakesPriority(false); 91868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (output_surface_proxy_.get()) 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) output_surface_proxy_->ClearOutputSurface(); 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output_surface_filter_->RemoveRoute(routing_id_); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool CompositorOutputSurface::BindToClient( 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) cc::OutputSurfaceClient* client) { 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(CalledOnValidThread()); 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!cc::OutputSurface::BindToClient(client)) 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output_surface_proxy_ = new CompositorOutputSurfaceProxy(this); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output_surface_filter_->AddRoute( 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) routing_id_, 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&CompositorOutputSurfaceProxy::OnMessageReceived, 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output_surface_proxy_)); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!context_provider()) { 11068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Without a GPU context, the memory policy otherwise wouldn't be set. 11168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) client->SetMemoryPolicy(cc::ManagedMemoryPolicy( 112cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 128 * 1024 * 1024, 1131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE, 114116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::SharedMemory::GetHandleLimit() / 3)); 11568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 11668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 120c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid CompositorOutputSurface::ShortcutSwapAck( 121c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch uint32 output_surface_id, 122c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch scoped_ptr<cc::GLFrameData> gl_frame_data, 123c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch scoped_ptr<cc::SoftwareFrameData> software_frame_data) { 124c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (!layout_test_previous_frame_ack_) { 125c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch layout_test_previous_frame_ack_.reset(new cc::CompositorFrameAck); 126c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch layout_test_previous_frame_ack_->gl_frame_data.reset(new cc::GLFrameData); 127c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 128c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 129c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch OnSwapAck(output_surface_id, *layout_test_previous_frame_ack_); 130c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 131c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch layout_test_previous_frame_ack_->gl_frame_data = gl_frame_data.Pass(); 132c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch layout_test_previous_frame_ack_->last_software_frame_id = 133c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch software_frame_data ? software_frame_data->id : 0; 134c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 135c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 1365e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)void CompositorOutputSurface::SwapBuffers(cc::CompositorFrame* frame) { 137c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (layout_test_mode_ && use_swap_compositor_frame_message_) { 138c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // This code path is here to support layout tests that are currently 139c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // doing a readback in the renderer instead of the browser. So they 140c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // are using deprecated code paths in the renderer and don't need to 141c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // actually swap anything to the browser. We shortcut the swap to the 142c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // browser here and just ack directly within the renderer process. 143c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // Once crbug.com/311404 is fixed, this can be removed. 144c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 145c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // This would indicate that crbug.com/311404 is being fixed, and this 146c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // block needs to be removed. 147c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DCHECK(!frame->delegated_frame_data); 148c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 149c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch base::Closure closure = 150c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch base::Bind(&CompositorOutputSurface::ShortcutSwapAck, 151c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch weak_ptrs_.GetWeakPtr(), 152c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch output_surface_id_, 153c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch base::Passed(&frame->gl_frame_data), 154c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch base::Passed(&frame->software_frame_data)); 155c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 156116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (context_provider()) { 157116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch gpu::gles2::GLES2Interface* context = context_provider()->ContextGL(); 158c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch context->Flush(); 159c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch uint32 sync_point = context->InsertSyncPointCHROMIUM(); 160116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch context_provider()->ContextSupport()->SignalSyncPoint(sync_point, 161116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch closure); 162c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } else { 163c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch base::MessageLoopProxy::current()->PostTask(FROM_HERE, closure); 164c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 1655c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu client_->DidSwapBuffers(); 166c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return; 167c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 168c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 1695e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) if (use_swap_compositor_frame_message_) { 1705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) { 1715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ScopedVector<IPC::Message> messages; 1725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) std::vector<IPC::Message> messages_to_deliver_with_frame; 1735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_ptr<FrameSwapMessageQueue::SendMessageScope> send_message_scope = 1745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) frame_swap_message_queue_->AcquireSendMessageScope(); 1755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) frame_swap_message_queue_->DrainMessages(&messages); 1765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) FrameSwapMessageQueue::TransferMessages(messages, 1775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) &messages_to_deliver_with_frame); 1785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Send(new ViewHostMsg_SwapCompositorFrame(routing_id_, 1795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) output_surface_id_, 1805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) *frame, 1815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) messages_to_deliver_with_frame)); 1825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // ~send_message_scope. 1835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 1845c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu client_->DidSwapBuffers(); 1855e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) return; 1865e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) } 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1885e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) if (frame->gl_frame_data) { 1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ContextProviderCommandBuffer* provider_command_buffer = 1901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci static_cast<ContextProviderCommandBuffer*>(context_provider()); 1915e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) CommandBufferProxyImpl* command_buffer_proxy = 1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) provider_command_buffer->GetCommandBufferProxy(); 1935e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) DCHECK(command_buffer_proxy); 1945e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) command_buffer_proxy->SetLatencyInfo(frame->metadata.latency_info); 1955e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) } 196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1975e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles) OutputSurface::SwapBuffers(frame); 198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CompositorOutputSurface::OnMessageReceived(const IPC::Message& message) { 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(CalledOnValidThread()); 2027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (!HasClient()) 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_BEGIN_MESSAGE_MAP(CompositorOutputSurface, message) 2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) IPC_MESSAGE_HANDLER(ViewMsg_UpdateVSyncParameters, 2065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) OnUpdateVSyncParametersFromBrowser); 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) IPC_MESSAGE_HANDLER(ViewMsg_SwapCompositorFrameAck, OnSwapAck); 208d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) IPC_MESSAGE_HANDLER(ViewMsg_ReclaimCompositorResources, OnReclaimResources); 209c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined(OS_ANDROID) 210a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch IPC_MESSAGE_HANDLER(ViewMsg_BeginFrame, OnBeginFrame); 211c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_END_MESSAGE_MAP() 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void CompositorOutputSurface::OnUpdateVSyncParametersFromBrowser( 2165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::TimeTicks timebase, 2175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::TimeDelta interval) { 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(CalledOnValidThread()); 2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CommitVSyncParameters(timebase, interval); 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 222c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined(OS_ANDROID) 223a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid CompositorOutputSurface::SetNeedsBeginFrame(bool enable) { 224c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(CalledOnValidThread()); 2255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu Send(new ViewHostMsg_SetNeedsBeginFrame(routing_id_, enable)); 226c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 228a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid CompositorOutputSurface::OnBeginFrame(const cc::BeginFrameArgs& args) { 229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(CalledOnValidThread()); 2305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu client_->BeginFrame(args); 231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif // defined(OS_ANDROID) 233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 234ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid CompositorOutputSurface::OnSwapAck(uint32 output_surface_id, 235ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const cc::CompositorFrameAck& ack) { 236ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Ignore message if it's a stale one coming from a different output surface 237ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // (e.g. after a lost context). 238ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (output_surface_id != output_surface_id_) 239ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return; 240d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ReclaimResources(&ack); 2415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu client_->DidSwapBuffersComplete(); 242d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 243d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 244d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void CompositorOutputSurface::OnReclaimResources( 245d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) uint32 output_surface_id, 246d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const cc::CompositorFrameAck& ack) { 247d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Ignore message if it's a stale one coming from a different output surface 248d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // (e.g. after a lost context). 249d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (output_surface_id != output_surface_id_) 250d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return; 251d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ReclaimResources(&ack); 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool CompositorOutputSurface::Send(IPC::Message* message) { 255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return message_sender_->Send(message); 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_ANDROID) 26090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) void SetThreadPriorityToIdle(base::PlatformThreadHandle handle) { 26190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::PlatformThread::SetThreadPriority( 26290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) handle, base::kThreadPriority_Background); 2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 26490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) void SetThreadPriorityToDefault(base::PlatformThreadHandle handle) { 26590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::PlatformThread::SetThreadPriority( 26690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) handle, base::kThreadPriority_Normal); 2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else 26990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) void SetThreadPriorityToIdle(base::PlatformThreadHandle handle) {} 27090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) void SetThreadPriorityToDefault(base::PlatformThreadHandle handle) {} 2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void CompositorOutputSurface::UpdateSmoothnessTakesPriority( 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool prefers_smoothness) { 2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef NDEBUG 2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If we use different compositor threads, we need to 2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // use an atomic int to track prefer smoothness count. 2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::PlatformThreadId g_last_thread = base::PlatformThread::CurrentId(); 2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_EQ(g_last_thread, base::PlatformThread::CurrentId()); 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (prefers_smoothness_ == prefers_smoothness) 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If this is the first surface to start preferring smoothness, 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Throttle the main thread's priority. 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (prefers_smoothness_ == false && 2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ++g_prefer_smoothness_count == 1) { 28890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SetThreadPriorityToIdle(main_thread_handle_); 2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If this is the last surface to stop preferring smoothness, 2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Reset the main thread's priority to the default. 2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (prefers_smoothness_ == true && 2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) --g_prefer_smoothness_count == 0) { 29490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SetThreadPriorityToDefault(main_thread_handle_); 2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) prefers_smoothness_ = prefers_smoothness; 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace content 300