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)#if defined(OS_WIN) 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <windows.h> 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/gpu/gpu_channel.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <queue> 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <vector> 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/debug/trace_event.h" 17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/message_loop/message_loop_proxy.h" 18cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/stl_util.h" 197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/strings/string_util.h" 20eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/timer/timer.h" 21f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "content/common/gpu/devtools_gpu_agent.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/gpu/gpu_channel_manager.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/gpu/gpu_messages.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/gpu/sync_point_manager.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/content_switches.h" 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "gpu/command_buffer/common/mailbox.h" 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "gpu/command_buffer/service/gpu_scheduler.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/service/image_manager.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/service/mailbox_manager.h" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_channel.h" 315c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "ipc/message_filter.h" 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gl/gl_context.h" 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gl/gl_image.h" 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gl/gl_surface.h" 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_POSIX) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_channel_posix.h" 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content { 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Number of milliseconds between successive vsync. Many GL commands block 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// on vsync, so thresholds for preemption should be multiples of this. 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int64 kVsyncIntervalMs = 17; 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Amount of time that we will wait for an IPC to be processed before 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// preempting. After a preemption, we must wait this long before triggering 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// another preemption. 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int64 kPreemptWaitTimeMs = 2 * kVsyncIntervalMs; 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Once we trigger a preemption, the maximum duration that we will wait 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// before clearing the preemption. 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int64 kMaxPreemptTimeMs = kVsyncIntervalMs; 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Stop the preemption once the time for the longest pending IPC drops 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// below this threshold. 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int64 kStopPreemptThresholdMs = kVsyncIntervalMs; 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // anonymous namespace 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// This filter does three things: 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// - it counts and timestamps each message forwarded to the channel 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// so that we can preempt other channels if a message takes too long to 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// process. To guarantee fairness, we must wait a minimum amount of time 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// before preempting and we limit the amount of time that we can preempt in 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// one shot (see constants above). 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// - it handles the GpuCommandBufferMsg_InsertSyncPoint message on the IO 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// thread, generating the sync point ID and responding immediately, and then 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// posting a task to insert the GpuCommandBufferMsg_RetireSyncPoint message 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// into the channel's queue. 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// - it generates mailbox names for clients of the GPU process on the IO thread. 735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuclass GpuChannelMessageFilter : public IPC::MessageFilter { 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 75cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) GpuChannelMessageFilter(base::WeakPtr<GpuChannel> gpu_channel, 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<SyncPointManager> sync_point_manager, 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<base::MessageLoopProxy> message_loop) 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : preemption_state_(IDLE), 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gpu_channel_(gpu_channel), 80f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) sender_(NULL), 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_point_manager_(sync_point_manager), 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_loop_(message_loop), 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) messages_forwarded_to_channel_(0), 84cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) a_stub_is_descheduled_(false) {} 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 86f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) virtual void OnFilterAdded(IPC::Sender* sender) OVERRIDE { 87f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DCHECK(!sender_); 88f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) sender_ = sender; 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void OnFilterRemoved() OVERRIDE { 92f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DCHECK(sender_); 93f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) sender_ = NULL; 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE { 97f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DCHECK(sender_); 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool handled = false; 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (message.type() == GpuCommandBufferMsg_RetireSyncPoint::ID) { 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // This message should not be sent explicitly by the renderer. 1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DLOG(ERROR) << "Client should not send " 1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "GpuCommandBufferMsg_RetireSyncPoint message"; 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) handled = true; 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // All other messages get processed by the GpuChannel. 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!handled) { 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) messages_forwarded_to_channel_++; 110868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (preempting_flag_.get()) 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) pending_messages_.push(PendingMessage(messages_forwarded_to_channel_)); 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdatePreemptionState(); 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (message.type() == GpuCommandBufferMsg_InsertSyncPoint::ID) { 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 sync_point = sync_point_manager_->GenerateSyncPoint(); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC::Message* reply = IPC::SyncMessage::GenerateReply(&message); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GpuCommandBufferMsg_InsertSyncPoint::WriteReplyParams(reply, sync_point); 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Send(reply); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_loop_->PostTask(FROM_HERE, base::Bind( 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &GpuChannelMessageFilter::InsertSyncPointOnMainThread, 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gpu_channel_, 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_point_manager_, 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message.routing_id(), 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) sync_point)); 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) handled = true; 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return handled; 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void MessageProcessed(uint64 messages_processed) { 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) while (!pending_messages_.empty() && 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) pending_messages_.front().message_number <= messages_processed) 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) pending_messages_.pop(); 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdatePreemptionState(); 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void SetPreemptingFlagAndSchedulingState( 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gpu::PreemptionFlag* preempting_flag, 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool a_stub_is_descheduled) { 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) preempting_flag_ = preempting_flag; 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) a_stub_is_descheduled_ = a_stub_is_descheduled; 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void UpdateStubSchedulingState(bool a_stub_is_descheduled) { 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) a_stub_is_descheduled_ = a_stub_is_descheduled; 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdatePreemptionState(); 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool Send(IPC::Message* message) { 151f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return sender_->Send(message); 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 155cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) virtual ~GpuChannelMessageFilter() {} 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) enum PreemptionState { 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Either there's no other channel to preempt, there are no messages 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // pending processing, or we just finished preempting and have to wait 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // before preempting again. 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) IDLE, 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We are waiting kPreemptWaitTimeMs before checking if we should preempt. 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WAITING, 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We can preempt whenever any IPC processing takes more than 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // kPreemptWaitTimeMs. 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CHECKING, 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We are currently preempting (i.e. no stub is descheduled). 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PREEMPTING, 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We would like to preempt, but some stub is descheduled. 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WOULD_PREEMPT_DESCHEDULED, 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PreemptionState preemption_state_; 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Maximum amount of time that we can spend in PREEMPTING. 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // It is reset when we transition to IDLE. 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeDelta max_preemption_time_; 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) struct PendingMessage { 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) uint64 message_number; 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeTicks time_received; 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) explicit PendingMessage(uint64 message_number) 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : message_number(message_number), 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) time_received(base::TimeTicks::Now()) { 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void UpdatePreemptionState() { 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch (preemption_state_) { 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case IDLE: 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (preempting_flag_.get() && !pending_messages_.empty()) 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TransitionToWaiting(); 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case WAITING: 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // A timer will transition us to CHECKING. 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(timer_.IsRunning()); 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case CHECKING: 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!pending_messages_.empty()) { 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeDelta time_elapsed = 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeTicks::Now() - pending_messages_.front().time_received; 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (time_elapsed.InMilliseconds() < kPreemptWaitTimeMs) { 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Schedule another check for when the IPC may go long. 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) timer_.Start( 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeDelta::FromMilliseconds(kPreemptWaitTimeMs) - 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) time_elapsed, 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this, &GpuChannelMessageFilter::UpdatePreemptionState); 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (a_stub_is_descheduled_) 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TransitionToWouldPreemptDescheduled(); 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TransitionToPreempting(); 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case PREEMPTING: 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // A TransitionToIdle() timer should always be running in this state. 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(timer_.IsRunning()); 2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (a_stub_is_descheduled_) 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TransitionToWouldPreemptDescheduled(); 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TransitionToIdleIfCaughtUp(); 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case WOULD_PREEMPT_DESCHEDULED: 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // A TransitionToIdle() timer should never be running in this state. 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!timer_.IsRunning()); 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!a_stub_is_descheduled_) 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TransitionToPreempting(); 2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else 2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TransitionToIdleIfCaughtUp(); 2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default: 2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NOTREACHED(); 2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void TransitionToIdleIfCaughtUp() { 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(preemption_state_ == PREEMPTING || 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) preemption_state_ == WOULD_PREEMPT_DESCHEDULED); 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (pending_messages_.empty()) { 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TransitionToIdle(); 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeDelta time_elapsed = 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeTicks::Now() - pending_messages_.front().time_received; 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (time_elapsed.InMilliseconds() < kStopPreemptThresholdMs) 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TransitionToIdle(); 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void TransitionToIdle() { 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(preemption_state_ == PREEMPTING || 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) preemption_state_ == WOULD_PREEMPT_DESCHEDULED); 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Stop any outstanding timer set to force us from PREEMPTING to IDLE. 2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) timer_.Stop(); 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) preemption_state_ = IDLE; 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) preempting_flag_->Reset(); 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_COUNTER_ID1("gpu", "GpuChannel::Preempting", this, 0); 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdatePreemptionState(); 2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void TransitionToWaiting() { 2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_EQ(preemption_state_, IDLE); 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!timer_.IsRunning()); 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) preemption_state_ = WAITING; 2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) timer_.Start( 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeDelta::FromMilliseconds(kPreemptWaitTimeMs), 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this, &GpuChannelMessageFilter::TransitionToChecking); 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void TransitionToChecking() { 2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_EQ(preemption_state_, WAITING); 2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!timer_.IsRunning()); 2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) preemption_state_ = CHECKING; 2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) max_preemption_time_ = base::TimeDelta::FromMilliseconds(kMaxPreemptTimeMs); 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdatePreemptionState(); 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void TransitionToPreempting() { 2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(preemption_state_ == CHECKING || 2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) preemption_state_ == WOULD_PREEMPT_DESCHEDULED); 2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!a_stub_is_descheduled_); 2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Stop any pending state update checks that we may have queued 2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // while CHECKING. 2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (preemption_state_ == CHECKING) 2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) timer_.Stop(); 2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) preemption_state_ = PREEMPTING; 2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) preempting_flag_->Set(); 2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_COUNTER_ID1("gpu", "GpuChannel::Preempting", this, 1); 2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) timer_.Start( 3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) max_preemption_time_, 3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this, &GpuChannelMessageFilter::TransitionToIdle); 3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdatePreemptionState(); 3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void TransitionToWouldPreemptDescheduled() { 3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(preemption_state_ == CHECKING || 3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) preemption_state_ == PREEMPTING); 3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(a_stub_is_descheduled_); 3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (preemption_state_ == CHECKING) { 3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Stop any pending state update checks that we may have queued 3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // while CHECKING. 3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) timer_.Stop(); 3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Stop any TransitionToIdle() timers that we may have queued 3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // while PREEMPTING. 3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) timer_.Stop(); 3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) max_preemption_time_ = timer_.desired_run_time() - base::TimeTicks::Now(); 3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (max_preemption_time_ < base::TimeDelta()) { 3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TransitionToIdle(); 3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) preemption_state_ = WOULD_PREEMPT_DESCHEDULED; 3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) preempting_flag_->Reset(); 3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_COUNTER_ID1("gpu", "GpuChannel::Preempting", this, 0); 3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdatePreemptionState(); 3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void InsertSyncPointOnMainThread( 336cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::WeakPtr<GpuChannel> gpu_channel, 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<SyncPointManager> manager, 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32 routing_id, 3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) uint32 sync_point) { 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This function must ensure that the sync point will be retired. Normally 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we'll find the stub based on the routing ID, and associate the sync point 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // with it, but if that fails for any reason (channel or stub already 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // deleted, invalid routing id), we need to retire the sync point 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // immediately. 345cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (gpu_channel) { 346cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) GpuCommandBufferStub* stub = gpu_channel->LookupCommandBuffer(routing_id); 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (stub) { 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stub->AddSyncPoint(sync_point); 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GpuCommandBufferMsg_RetireSyncPoint message(routing_id, sync_point); 350cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) gpu_channel->OnMessageReceived(message); 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 353cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) gpu_channel->MessageProcessed(); 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) manager->RetireSyncPoint(sync_point); 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 359cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // NOTE: this weak pointer is never dereferenced on the IO thread, it's only 360cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // passed through - therefore the WeakPtr assumptions are respected. 361cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::WeakPtr<GpuChannel> gpu_channel_; 362f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) IPC::Sender* sender_; 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<SyncPointManager> sync_point_manager_; 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<base::MessageLoopProxy> message_loop_; 3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<gpu::PreemptionFlag> preempting_flag_; 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::queue<PendingMessage> pending_messages_; 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Count of the number of IPCs forwarded to the GpuChannel. 3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) uint64 messages_forwarded_to_channel_; 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::OneShotTimer<GpuChannelMessageFilter> timer_; 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool a_stub_is_descheduled_; 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GpuChannel::GpuChannel(GpuChannelManager* gpu_channel_manager, 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GpuWatchdog* watchdog, 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::GLShareGroup* share_group, 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gpu::gles2::MailboxManager* mailbox, 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int client_id, 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool software) 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : gpu_channel_manager_(gpu_channel_manager), 3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) messages_processed_(0), 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client_id_(client_id), 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) share_group_(share_group ? share_group : new gfx::GLShareGroup), 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mailbox_manager_(mailbox ? mailbox : new gpu::gles2::MailboxManager), 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) image_manager_(new gpu::gles2::ImageManager), 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) watchdog_(watchdog), 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) software_(software), 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) handle_messages_scheduled_(false), 3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) currently_processing_message_(NULL), 393c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) weak_factory_(this), 3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) num_stubs_descheduled_(0) { 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(gpu_channel_manager); 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(client_id); 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel_id_ = IPC::Channel::GenerateVerifiedChannelID("gpu"); 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const CommandLine* command_line = CommandLine::ForCurrentProcess(); 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) log_messages_ = command_line->HasSwitch(switches::kLogPluginMessages); 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 403cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)GpuChannel::~GpuChannel() { 404cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) STLDeleteElements(&deferred_messages_); 405cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (preempting_flag_.get()) 406cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) preempting_flag_->Reset(); 407cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 409a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void GpuChannel::Init(base::MessageLoopProxy* io_message_loop, 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::WaitableEvent* shutdown_event) { 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!channel_.get()); 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Map renderer ID to a (single) channel to that process. 41446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) channel_ = IPC::SyncChannel::Create(channel_id_, 41546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) IPC::Channel::MODE_SERVER, 41646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) this, 41746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) io_message_loop, 41846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) false, 41946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) shutdown_event); 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 421cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) filter_ = 422cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) new GpuChannelMessageFilter(weak_factory_.GetWeakPtr(), 423cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) gpu_channel_manager_->sync_point_manager(), 424cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::MessageLoopProxy::current()); 4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) io_message_loop_ = io_message_loop; 426868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) channel_->AddFilter(filter_.get()); 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 428f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) devtools_gpu_agent_.reset(new DevToolsGpuAgent(this)); 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string GpuChannel::GetChannelName() { 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return channel_id_; 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_POSIX) 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int GpuChannel::TakeRendererFileDescriptor() { 437c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!channel_) { 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return -1; 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return channel_->TakeClientFileDescriptor(); 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // defined(OS_POSIX) 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GpuChannel::OnMessageReceived(const IPC::Message& message) { 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (log_messages_) { 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "received message @" << &message << " on channel @" << this 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << " with type " << message.type(); 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 451c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (message.type() == GpuCommandBufferMsg_WaitForTokenInRange::ID || 452c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch message.type() == GpuCommandBufferMsg_WaitForGetOffsetInRange::ID) { 453c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // Move Wait commands to the head of the queue, so the renderer 454c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // doesn't have to wait any longer than necessary. 455c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch deferred_messages_.push_front(new IPC::Message(message)); 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) deferred_messages_.push_back(new IPC::Message(message)); 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnScheduled(); 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuChannel::OnChannelError() { 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gpu_channel_manager_->RemoveChannel(client_id_); 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GpuChannel::Send(IPC::Message* message) { 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The GPU process must never send a synchronous IPC message to the renderer 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // process. This could result in deadlock. 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!message->is_sync()); 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (log_messages_) { 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "sending message @" << message << " on channel @" << this 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << " with type " << message->type(); 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 478c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!channel_) { 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete message; 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return channel_->Send(message); 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GpuChannel::RequeueMessage() { 4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(currently_processing_message_); 4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) deferred_messages_.push_front( 4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new IPC::Message(*currently_processing_message_)); 4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) messages_processed_--; 4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) currently_processing_message_ = NULL; 4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuChannel::OnScheduled() { 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (handle_messages_scheduled_) 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Post a task to handle any deferred messages. The deferred message queue is 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // not emptied here, which ensures that OnMessageReceived will continue to 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // defer newly received messages until the ones in the queue have all been 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // handled by HandleMessage. HandleMessage is invoked as a 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // task to prevent reentrancy. 502c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::MessageLoop::current()->PostTask( 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&GpuChannel::HandleMessage, weak_factory_.GetWeakPtr())); 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) handle_messages_scheduled_ = true; 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GpuChannel::StubSchedulingChanged(bool scheduled) { 5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool a_stub_was_descheduled = num_stubs_descheduled_ > 0; 5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (scheduled) { 5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) num_stubs_descheduled_--; 5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) OnScheduled(); 5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) num_stubs_descheduled_++; 5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_LE(num_stubs_descheduled_, stubs_.size()); 5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool a_stub_is_descheduled = num_stubs_descheduled_ > 0; 5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (a_stub_is_descheduled != a_stub_was_descheduled) { 520868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (preempting_flag_.get()) { 5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) io_message_loop_->PostTask( 5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&GpuChannelMessageFilter::UpdateStubSchedulingState, 524868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) filter_, 525868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) a_stub_is_descheduled)); 5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5309a3a4bc965704498ea9f22876627cda96ff9a77eBo LiuCreateCommandBufferResult GpuChannel::CreateViewCommandBuffer( 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::GLSurfaceHandle& window, 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32 surface_id, 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GPUCreateCommandBufferConfig& init_params, 534c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch int32 route_id) { 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TRACE_EVENT1("gpu", 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "GpuChannel::CreateViewCommandBuffer", 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "surface_id", 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) surface_id); 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GpuCommandBufferStub* share_group = stubs_.Lookup(init_params.share_group_id); 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 542c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Virtualize compositor contexts on OS X to prevent performance regressions 543c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // when enabling FCM. 544c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // http://crbug.com/180463 545c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool use_virtualized_gl_context = false; 546c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined(OS_MACOSX) 547c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) use_virtualized_gl_context = true; 548c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif 549c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 550868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<GpuCommandBufferStub> stub( 551868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) new GpuCommandBufferStub(this, 552868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) share_group, 553868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) window, 554868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) mailbox_manager_.get(), 555868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) image_manager_.get(), 556868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) gfx::Size(), 557868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) disallowed_features_, 558868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) init_params.attribs, 559868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) init_params.gpu_preference, 560868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) use_virtualized_gl_context, 561c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch route_id, 562868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) surface_id, 563868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) watchdog_, 564868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) software_, 565868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) init_params.active_url)); 566868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (preempted_flag_.get()) 5672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) stub->SetPreemptByFlag(preempted_flag_); 568c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (!router_.AddRoute(route_id, stub.get())) { 569c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DLOG(ERROR) << "GpuChannel::CreateViewCommandBuffer(): " 570c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch "failed to add route"; 5719a3a4bc965704498ea9f22876627cda96ff9a77eBo Liu return CREATE_COMMAND_BUFFER_FAILED_AND_CHANNEL_LOST; 572c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 573c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch stubs_.AddWithID(stub.release(), route_id); 5749a3a4bc965704498ea9f22876627cda96ff9a77eBo Liu return CREATE_COMMAND_BUFFER_SUCCEEDED; 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GpuCommandBufferStub* GpuChannel::LookupCommandBuffer(int32 route_id) { 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return stubs_.Lookup(route_id); 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuChannel::CreateImage( 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::PluginWindowHandle window, 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32 image_id, 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Size* size) { 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TRACE_EVENT1("gpu", 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "GpuChannel::CreateImage", 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "image_id", 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) image_id); 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *size = gfx::Size(); 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (image_manager_->LookupImage(image_id)) { 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "CreateImage failed, image_id already in use."; 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<gfx::GLImage> image = gfx::GLImage::CreateGLImage(window); 598868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!image.get()) 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) image_manager_->AddImage(image.get(), image_id); 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *size = image->GetSize(); 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuChannel::DeleteImage(int32 image_id) { 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TRACE_EVENT1("gpu", 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "GpuChannel::DeleteImage", 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "image_id", 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) image_id); 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) image_manager_->RemoveImage(image_id); 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuChannel::LoseAllContexts() { 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gpu_channel_manager_->LoseAllContexts(); 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid GpuChannel::MarkAllContextsLost() { 6197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch for (StubMap::Iterator<GpuCommandBufferStub> it(&stubs_); 6207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch !it.IsAtEnd(); it.Advance()) { 6217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch it.GetCurrentValue()->MarkContextLost(); 6227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 6237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 6247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 625c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochbool GpuChannel::AddRoute(int32 route_id, IPC::Listener* listener) { 626c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return router_.AddRoute(route_id, listener); 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuChannel::RemoveRoute(int32 route_id) { 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) router_.RemoveRoute(route_id); 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)gpu::PreemptionFlag* GpuChannel::GetPreemptionFlag() { 634868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!preempting_flag_.get()) { 6352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) preempting_flag_ = new gpu::PreemptionFlag; 6362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) io_message_loop_->PostTask( 6372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, base::Bind( 6382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &GpuChannelMessageFilter::SetPreemptingFlagAndSchedulingState, 6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) filter_, preempting_flag_, num_stubs_descheduled_ > 0)); 6402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return preempting_flag_.get(); 6422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GpuChannel::SetPreemptByFlag( 6452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<gpu::PreemptionFlag> preempted_flag) { 6462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) preempted_flag_ = preempted_flag; 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (StubMap::Iterator<GpuCommandBufferStub> it(&stubs_); 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !it.IsAtEnd(); it.Advance()) { 6502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) it.GetCurrentValue()->SetPreemptByFlag(preempted_flag_); 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuChannel::OnDestroy() { 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TRACE_EVENT0("gpu", "GpuChannel::OnDestroy"); 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gpu_channel_manager_->RemoveChannel(client_id_); 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GpuChannel::OnControlMessageReceived(const IPC::Message& msg) { 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool handled = true; 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_BEGIN_MESSAGE_MAP(GpuChannel, msg) 6622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) IPC_MESSAGE_HANDLER(GpuChannelMsg_CreateOffscreenCommandBuffer, 6633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) OnCreateOffscreenCommandBuffer) 6642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) IPC_MESSAGE_HANDLER(GpuChannelMsg_DestroyCommandBuffer, 6653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) OnDestroyCommandBuffer) 666f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) IPC_MESSAGE_HANDLER(GpuChannelMsg_DevToolsStartEventsRecording, 667f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) OnDevToolsStartEventsRecording) 668f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) IPC_MESSAGE_HANDLER(GpuChannelMsg_DevToolsStopEventsRecording, 669f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) OnDevToolsStopEventsRecording) 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_UNHANDLED(handled = false) 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_END_MESSAGE_MAP() 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(handled) << msg.type(); 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return handled; 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuChannel::HandleMessage() { 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) handle_messages_scheduled_ = false; 6782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (deferred_messages_.empty()) 6792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool should_fast_track_ack = false; 6822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) IPC::Message* m = deferred_messages_.front(); 6832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GpuCommandBufferStub* stub = stubs_.Lookup(m->routing_id()); 6842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) do { 6862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (stub) { 6872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!stub->IsScheduled()) 6882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 6892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (stub->IsPreempted()) { 6902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) OnScheduled(); 6912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<IPC::Message> message(m); 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) deferred_messages_.pop_front(); 6972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool message_processed = true; 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) currently_processing_message_ = message.get(); 7002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool result; 7012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (message->routing_id() == MSG_ROUTING_CONTROL) 7022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) result = OnControlMessageReceived(*message); 7032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else 7042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) result = router_.RouteMessage(*message); 7052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) currently_processing_message_ = NULL; 7062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!result) { 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Respond to sync messages even if router failed to route. 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (message->is_sync()) { 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC::Message* reply = IPC::SyncMessage::GenerateReply(&*message); 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reply->set_reply_error(); 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Send(reply); 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the command buffer becomes unscheduled as a result of handling the 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // message but still has more commands to process, synthesize an IPC 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // message to flush that command buffer. 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (stub) { 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (stub->HasUnprocessedCommands()) { 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) deferred_messages_.push_front(new GpuCommandBufferMsg_Rescheduled( 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stub->route_id())); 7222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) message_processed = false; 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (message_processed) 7272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MessageProcessed(); 7282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We want the EchoACK following the SwapBuffers to be sent as close as 7302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // possible, avoiding scheduling other channels in the meantime. 7312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) should_fast_track_ack = false; 7322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!deferred_messages_.empty()) { 7332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) m = deferred_messages_.front(); 7342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) stub = stubs_.Lookup(m->routing_id()); 7352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) should_fast_track_ack = 7362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (m->type() == GpuCommandBufferMsg_Echo::ID) && 7372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) stub && stub->IsScheduled(); 7382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } while (should_fast_track_ack); 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!deferred_messages_.empty()) { 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnScheduled(); 7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GpuChannel::OnCreateOffscreenCommandBuffer( 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Size& size, 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GPUCreateCommandBufferConfig& init_params, 749c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch int32 route_id, 750c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch bool* succeeded) { 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TRACE_EVENT0("gpu", "GpuChannel::OnCreateOffscreenCommandBuffer"); 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GpuCommandBufferStub* share_group = stubs_.Lookup(init_params.share_group_id); 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<GpuCommandBufferStub> stub(new GpuCommandBufferStub( 7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, 7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) share_group, 7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::GLSurfaceHandle(), 7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mailbox_manager_.get(), 7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) image_manager_.get(), 7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size, 7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) disallowed_features_, 7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) init_params.attribs, 7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) init_params.gpu_preference, 764c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) false, 765c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch route_id, 766c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 0, 767c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) watchdog_, 7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) software_, 7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) init_params.active_url)); 770868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (preempted_flag_.get()) 7712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) stub->SetPreemptByFlag(preempted_flag_); 772c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (!router_.AddRoute(route_id, stub.get())) { 773c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DLOG(ERROR) << "GpuChannel::OnCreateOffscreenCommandBuffer(): " 774c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch "failed to add route"; 775c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch *succeeded = false; 776c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return; 777c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 778c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch stubs_.AddWithID(stub.release(), route_id); 7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TRACE_EVENT1("gpu", "GpuChannel::OnCreateOffscreenCommandBuffer", 7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "route_id", route_id); 781c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch *succeeded = true; 7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GpuChannel::OnDestroyCommandBuffer(int32 route_id) { 7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TRACE_EVENT1("gpu", "GpuChannel::OnDestroyCommandBuffer", 7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "route_id", route_id); 7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 788c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GpuCommandBufferStub* stub = stubs_.Lookup(route_id); 789c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!stub) 790c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 791c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool need_reschedule = (stub && !stub->IsScheduled()); 792c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) router_.RemoveRoute(route_id); 793c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) stubs_.Remove(route_id); 794c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // In case the renderer is currently blocked waiting for a sync reply from the 795c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // stub, we need to make sure to reschedule the GpuChannel here. 796c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (need_reschedule) { 797c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // This stub won't get a chance to reschedule, so update the count now. 798c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) StubSchedulingChanged(true); 7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 802c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid GpuChannel::OnDevToolsStartEventsRecording(int32 route_id, 803c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch bool* succeeded) { 804c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch *succeeded = devtools_gpu_agent_->StartEventsRecording(route_id); 805f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 806f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 807f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void GpuChannel::OnDevToolsStopEventsRecording() { 808f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) devtools_gpu_agent_->StopEventsRecording(); 809f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 810f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 8112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GpuChannel::MessageProcessed() { 8122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) messages_processed_++; 813868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (preempting_flag_.get()) { 8142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) io_message_loop_->PostTask( 8152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 8162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&GpuChannelMessageFilter::MessageProcessed, 817868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) filter_, 818868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) messages_processed_)); 8192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 8202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GpuChannel::CacheShader(const std::string& key, 8232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& shader) { 8242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gpu_channel_manager_->Send( 8252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new GpuHostMsg_CacheShader(client_id_, key, shader)); 8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8285c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid GpuChannel::AddFilter(IPC::MessageFilter* filter) { 829424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) channel_->AddFilter(filter); 830424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 831424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 8325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid GpuChannel::RemoveFilter(IPC::MessageFilter* filter) { 833424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) channel_->RemoveFilter(filter); 834424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 835424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 836effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochuint64 GpuChannel::GetMemoryUsage() { 837effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch uint64 size = 0; 838effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch for (StubMap::Iterator<GpuCommandBufferStub> it(&stubs_); 839effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch !it.IsAtEnd(); it.Advance()) { 840effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch size += it.GetCurrentValue()->GetMemoryUsage(); 841effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 842effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return size; 843effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 844effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace content 846