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