1// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "content/common/gpu/devtools_gpu_agent.h"
6
7#include "base/logging.h"
8#include "content/common/devtools_messages.h"
9#include "content/common/gpu/gpu_channel.h"
10#include "content/common/gpu/gpu_channel_manager.h"
11
12namespace content {
13
14DevToolsGpuAgent::DevToolsGpuAgent(GpuChannel* gpu_channel) :
15    gpu_channel_(gpu_channel),
16    route_id_(MSG_ROUTING_NONE) {
17}
18
19DevToolsGpuAgent::~DevToolsGpuAgent() {
20}
21
22bool DevToolsGpuAgent::StartEventsRecording(int32 route_id) {
23  DCHECK(CalledOnValidThread());
24  if (route_id_ != MSG_ROUTING_NONE) {
25    // Events recording is already in progress, so "fail" the call by
26    // returning false.
27    return false;
28  }
29  route_id_ = route_id;
30  tasks_.reset(new GpuTaskInfoList());
31  GpuEventsDispatcher* dispatcher =
32      gpu_channel_->gpu_channel_manager()->gpu_devtools_events_dispatcher();
33  dispatcher->AddProcessor(this);
34  return true;
35}
36
37void DevToolsGpuAgent::StopEventsRecording() {
38  DCHECK(CalledOnValidThread());
39  if (route_id_ == MSG_ROUTING_NONE)
40    return;
41  GpuEventsDispatcher* dispatcher =
42      gpu_channel_->gpu_channel_manager()->gpu_devtools_events_dispatcher();
43  dispatcher->RemoveProcessor(this);
44  route_id_ = MSG_ROUTING_NONE;
45}
46
47void DevToolsGpuAgent::ProcessEvent(
48    TimeTicks timestamp,
49    GpuEventsDispatcher::EventPhase phase,
50    GpuChannel* channel) {
51  DCHECK(CalledOnValidThread());
52  if (route_id_ == MSG_ROUTING_NONE)
53    return;
54
55  GpuTaskInfo task;
56  task.timestamp = (timestamp - TimeTicks()).InSecondsF();
57  task.phase = phase;
58  task.foreign = channel != gpu_channel_;
59  task.gpu_memory_used_bytes = channel->GetMemoryUsage();
60  task.gpu_memory_limit_bytes = gpu_channel_->gpu_channel_manager()->
61      gpu_memory_manager()->GetMaximumClientAllocation();
62
63  const int kFlushIntervalMs = 100;
64  const unsigned kMaxPendingItems = 100;
65  if (!tasks_->empty() &&
66      ((timestamp - last_flush_time_).InMilliseconds() >= kFlushIntervalMs ||
67       tasks_->size() >= kMaxPendingItems)) {
68    Send(new DevToolsAgentMsg_GpuTasksChunk(route_id_, *tasks_));
69    tasks_->clear();
70    last_flush_time_ = timestamp;
71  }
72  tasks_->push_back(task);
73}
74
75bool DevToolsGpuAgent::Send(IPC::Message* msg) {
76  scoped_ptr<IPC::Message> message(msg);
77  return gpu_channel_ && gpu_channel_->Send(message.release());
78}
79
80}  // namespace content
81