summaryrefslogtreecommitdiffstats
path: root/chrome/browser/gpu_process_host_ui_shim.h
blob: 8bcdb23a7434054954268942028e0821e7e1be7d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_BROWSER_GPU_PROCESS_HOST_UI_SHIM_H_
#define CHROME_BROWSER_GPU_PROCESS_HOST_UI_SHIM_H_
#pragma once

// This class lives on the UI thread and supports classes like the
// BackingStoreProxy, which must live on the UI thread. The IO thread
// portion of this class, the GpuProcessHost, is responsible for
// shuttling messages between the browser and GPU processes.

#include <map>
#include <queue>

#include "base/callback.h"
#include "base/memory/linked_ptr.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/singleton.h"
#include "base/process.h"
#include "base/threading/non_thread_safe.h"
#include "content/common/gpu/gpu_channel_manager.h"
#include "content/common/gpu/gpu_info.h"
#include "content/common/gpu_feature_flags.h"
#include "content/common/gpu_process_launch_causes.h"
#include "content/common/message_router.h"
#include "ui/gfx/native_widget_types.h"

namespace gfx {
class Size;
}

class GpuDataManager;
struct GPUCreateCommandBufferConfig;
struct GpuHostMsg_AcceleratedSurfaceSetIOSurface_Params;
struct GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params;

namespace IPC {
struct ChannelHandle;
class Message;
}

// A task that will forward an IPC message to the UI shim.
class RouteToGpuProcessHostUIShimTask : public Task {
 public:
  RouteToGpuProcessHostUIShimTask(int host_id, const IPC::Message& msg);
  ~RouteToGpuProcessHostUIShimTask();

 private:
  virtual void Run();

  int host_id_;
  IPC::Message msg_;
};

class GpuProcessHostUIShim
    : public IPC::Channel::Listener,
      public IPC::Channel::Sender,
      public base::NonThreadSafe {
 public:
  // Creates a new GpuProcessHostUIShim or gets one for a particular
  // renderer process, resulting in the launching of a GPU process if required.
  // Returns null on failure. It is not safe to store the pointer once control
  // has returned to the message loop as it can be destroyed. Instead store the
  // associated GPU host ID. A renderer ID of zero means the browser process.
  // This could return NULL if GPU access is not allowed (blacklisted).
  static GpuProcessHostUIShim* GetForRenderer(int renderer_id,
                                              content::CauseForGpuLaunch);

  // Destroy the GpuProcessHostUIShim with the given host ID. This can only
  // be called on the UI thread. Only the GpuProcessHost should destroy the
  // UI shim.
  static void Destroy(int host_id);

  // Destroy all remaining GpuProcessHostUIShims.
  static void DestroyAll();

  // The GPU process is launched asynchronously. If it launches successfully,
  // this function is called on the UI thread with the process handle. On
  // Windows, the UI shim takes ownership of the handle.
  static void NotifyGpuProcessLaunched(int host_id,
                                       base::ProcessHandle gpu_process);

  static GpuProcessHostUIShim* FromID(int host_id);
  int host_id() const { return host_id_; }

  // IPC::Channel::Sender implementation.
  virtual bool Send(IPC::Message* msg);

  // Sends outstanding replies. This is only called
  // in error situations like the GPU process crashing -- but is necessary
  // to prevent the blocked clients from hanging.
  void SendOutstandingReplies();

  // IPC::Channel::Listener implementation.
  // The GpuProcessHost causes this to be called on the UI thread to
  // dispatch the incoming messages from the GPU process, which are
  // actually received on the IO thread.
  virtual bool OnMessageReceived(const IPC::Message& message);

  typedef Callback3<const IPC::ChannelHandle&,
                    base::ProcessHandle,
                    const GPUInfo&>::Type
    EstablishChannelCallback;

  // Tells the GPU process to create a new channel for communication with a
  // renderer. Once the GPU process responds asynchronously with the IPC handle
  // and GPUInfo, we call the callback.
  void EstablishGpuChannel(
      int renderer_id, EstablishChannelCallback* callback);

  typedef Callback0::Type SynchronizeCallback;

  // Sends a reply message later when the next GpuHostMsg_SynchronizeReply comes
  // in.
  void Synchronize(SynchronizeCallback* callback);

  typedef Callback1<int32>::Type CreateCommandBufferCallback;

  // Tells the GPU process to create a new command buffer that draws into the
  // window associated with the given renderer.
  void CreateViewCommandBuffer(
      int32 render_view_id,
      int32 renderer_id,
      const GPUCreateCommandBufferConfig& init_params,
      CreateCommandBufferCallback* callback);

#if defined(OS_MACOSX)
  // Notify the GPU process that an accelerated surface was destroyed.
  void DidDestroyAcceleratedSurface(int renderer_id, int32 render_view_id);

  // TODO(apatrick): Remove this when mac does not use AcceleratedSurfaces for
  // when running the GPU thread in the browser process.
  static void SendToGpuHost(int host_id, IPC::Message* msg);
#endif

  // Sends a message to the browser process to collect the information from the
  // graphics card.
  void CollectGpuInfoAsynchronously();

  // Tells the GPU process to crash. Useful for testing.
  void SendAboutGpuCrash();

  // Tells the GPU process to let its main thread enter an infinite loop.
  // Useful for testing.
  void SendAboutGpuHang();

  // Can be called directly from the UI thread to log a message.
  void AddCustomLogMessage(int level, const std::string& header,
      const std::string& message);

 private:
  explicit GpuProcessHostUIShim(int host_id, content::CauseForGpuLaunch);
  virtual ~GpuProcessHostUIShim();

  // Message handlers.
  bool OnControlMessageReceived(const IPC::Message& message);

  void OnChannelEstablished(const IPC::ChannelHandle& channel_handle);
  void OnCommandBufferCreated(const int32 route_id);
  void OnDestroyCommandBuffer(gfx::PluginWindowHandle window,
                              int32 renderer_id, int32 render_view_id);
  void OnGraphicsInfoCollected(const GPUInfo& gpu_info);
  void OnLogMessage(int level, const std::string& header,
      const std::string& message);
  void OnSynchronizeReply();
#if defined(OS_LINUX)
  void OnResizeXID(unsigned long xid, gfx::Size size, IPC::Message* reply_msg);
#elif defined(OS_MACOSX)
  void OnAcceleratedSurfaceSetIOSurface(
      const GpuHostMsg_AcceleratedSurfaceSetIOSurface_Params& params);
  void OnAcceleratedSurfaceBuffersSwapped(
      const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params);
#elif defined(OS_WIN)
  void OnScheduleComposite(int32 renderer_id, int32 render_view_id);
#endif

  // The serial number of the GpuProcessHost / GpuProcessHostUIShim pair.
  int host_id_;

  // The handle for the GPU process or null if it is not known to be launched.
  base::ProcessHandle gpu_process_;

  // Cached pointer to the singleton for efficiency purpose.
  GpuDataManager* gpu_data_manager_;

  // These are the channel requests that we have already sent to
  // the GPU process, but haven't heard back about yet.
  std::queue<linked_ptr<EstablishChannelCallback> > channel_requests_;

  // The pending synchronization requests we need to reply to.
  std::queue<linked_ptr<SynchronizeCallback> > synchronize_requests_;

  // The pending create command buffer requests we need to reply to.
  std::queue<linked_ptr<CreateCommandBufferCallback> >
      create_command_buffer_requests_;

  typedef std::pair<int32 /* renderer_id */,
                    int32 /* render_view_id */> ViewID;

  // Encapsulates surfaces that we acquire when creating view command buffers.
  // We assume that a render view has at most 1 such surface associated
  // with it.  Multimap is used to simulate reference counting, see comment in
  // GpuProcessHostUIShim::CreateViewCommandBuffer.
  class ViewSurface;
  typedef std::multimap<ViewID, linked_ptr<ViewSurface> > ViewSurfaceMap;
  ViewSurfaceMap acquired_surfaces_;

  // In single process and in process GPU mode, this references the
  // GpuChannelManager or null otherwise. It must be called and deleted on the
  // GPU thread.
  GpuChannelManager* gpu_channel_manager_;

  // This is likewise single process / in process GPU specific. This is a Sender
  // implementation that forwards IPC messages to this UI shim on the UI thread.
  IPC::Channel::Sender* ui_thread_sender_;
};

#endif  // CHROME_BROWSER_GPU_PROCESS_HOST_UI_SHIM_H_