[Android WebView] Fix webview perf bot switchover to use org.chromium.webview_shell...
[chromium-blink-merge.git] / content / common / gpu / gpu_channel_manager.cc
blob4cec7cb3c8114656a0138f24c144935a56bebb1f
1 // Copyright (c) 2012 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.
5 #include "content/common/gpu/gpu_channel_manager.h"
7 #include "base/bind.h"
8 #include "base/command_line.h"
9 #include "base/location.h"
10 #include "base/single_thread_task_runner.h"
11 #include "base/thread_task_runner_handle.h"
12 #include "content/common/gpu/gpu_channel.h"
13 #include "content/common/gpu/gpu_memory_buffer_factory.h"
14 #include "content/common/gpu/gpu_memory_manager.h"
15 #include "content/common/gpu/gpu_messages.h"
16 #include "content/common/message_router.h"
17 #include "gpu/command_buffer/common/value_state.h"
18 #include "gpu/command_buffer/service/feature_info.h"
19 #include "gpu/command_buffer/service/gpu_switches.h"
20 #include "gpu/command_buffer/service/mailbox_manager_impl.h"
21 #include "gpu/command_buffer/service/memory_program_cache.h"
22 #include "gpu/command_buffer/service/shader_translator_cache.h"
23 #include "gpu/command_buffer/service/sync_point_manager.h"
24 #include "ipc/message_filter.h"
25 #include "ui/gl/gl_bindings.h"
26 #include "ui/gl/gl_share_group.h"
27 #if defined(USE_OZONE)
28 #include "ui/ozone/public/gpu_platform_support.h"
29 #include "ui/ozone/public/ozone_platform.h"
30 #endif
32 namespace content {
34 namespace {
36 class GpuChannelManagerMessageFilter : public IPC::MessageFilter {
37 public:
38 GpuChannelManagerMessageFilter(
39 GpuMemoryBufferFactory* gpu_memory_buffer_factory)
40 : sender_(NULL), gpu_memory_buffer_factory_(gpu_memory_buffer_factory) {}
42 void OnFilterAdded(IPC::Sender* sender) override {
43 DCHECK(!sender_);
44 sender_ = sender;
47 void OnFilterRemoved() override {
48 DCHECK(sender_);
49 sender_ = NULL;
52 bool OnMessageReceived(const IPC::Message& message) override {
53 DCHECK(sender_);
54 bool handled = true;
55 IPC_BEGIN_MESSAGE_MAP(GpuChannelManagerMessageFilter, message)
56 IPC_MESSAGE_HANDLER(GpuMsg_CreateGpuMemoryBuffer, OnCreateGpuMemoryBuffer)
57 IPC_MESSAGE_UNHANDLED(handled = false)
58 IPC_END_MESSAGE_MAP()
59 return handled;
62 protected:
63 ~GpuChannelManagerMessageFilter() override {}
65 // GPU IO thread bounces off GpuMsg_CreateGpuMemoryBuffer message, because
66 // the UI thread in the browser process must remain fast at all times.
67 void OnCreateGpuMemoryBuffer(
68 const GpuMsg_CreateGpuMemoryBuffer_Params& params) {
69 TRACE_EVENT2("gpu",
70 "GpuChannelManagerMessageFilter::OnCreateGpuMemoryBuffer",
71 "id", params.id, "client_id", params.client_id);
72 sender_->Send(new GpuHostMsg_GpuMemoryBufferCreated(
73 gpu_memory_buffer_factory_->CreateGpuMemoryBuffer(
74 params.id, params.size, params.format, params.usage,
75 params.client_id, params.surface_handle)));
78 IPC::Sender* sender_;
79 GpuMemoryBufferFactory* gpu_memory_buffer_factory_;
82 gfx::GpuMemoryBufferType GetGpuMemoryBufferFactoryType() {
83 std::vector<gfx::GpuMemoryBufferType> supported_types;
84 GpuMemoryBufferFactory::GetSupportedTypes(&supported_types);
85 DCHECK(!supported_types.empty());
86 return supported_types[0];
89 } // namespace
91 GpuChannelManager::GpuChannelManager(
92 MessageRouter* router,
93 GpuWatchdog* watchdog,
94 base::SingleThreadTaskRunner* io_task_runner,
95 base::WaitableEvent* shutdown_event,
96 IPC::SyncChannel* channel)
97 : io_task_runner_(io_task_runner),
98 shutdown_event_(shutdown_event),
99 router_(router),
100 gpu_memory_manager_(
101 this,
102 GpuMemoryManager::kDefaultMaxSurfacesWithFrontbufferSoftLimit),
103 watchdog_(watchdog),
104 sync_point_manager_(gpu::SyncPointManager::Create(false)),
105 gpu_memory_buffer_factory_(
106 GpuMemoryBufferFactory::Create(GetGpuMemoryBufferFactoryType())),
107 channel_(channel),
108 filter_(
109 new GpuChannelManagerMessageFilter(gpu_memory_buffer_factory_.get())),
110 relinquish_resources_pending_(false),
111 weak_factory_(this) {
112 DCHECK(router_);
113 DCHECK(io_task_runner);
114 DCHECK(shutdown_event);
115 channel_->AddFilter(filter_.get());
118 GpuChannelManager::~GpuChannelManager() {
119 gpu_channels_.clear();
120 if (default_offscreen_surface_.get()) {
121 default_offscreen_surface_->Destroy();
122 default_offscreen_surface_ = NULL;
126 gpu::gles2::ProgramCache* GpuChannelManager::program_cache() {
127 if (!program_cache_.get() &&
128 (gfx::g_driver_gl.ext.b_GL_ARB_get_program_binary ||
129 gfx::g_driver_gl.ext.b_GL_OES_get_program_binary) &&
130 !base::CommandLine::ForCurrentProcess()->HasSwitch(
131 switches::kDisableGpuProgramCache)) {
132 program_cache_.reset(new gpu::gles2::MemoryProgramCache());
134 return program_cache_.get();
137 gpu::gles2::ShaderTranslatorCache*
138 GpuChannelManager::shader_translator_cache() {
139 if (!shader_translator_cache_.get())
140 shader_translator_cache_ = new gpu::gles2::ShaderTranslatorCache;
141 return shader_translator_cache_.get();
144 void GpuChannelManager::RemoveChannel(int client_id) {
145 Send(new GpuHostMsg_DestroyChannel(client_id));
146 gpu_channels_.erase(client_id);
147 CheckRelinquishGpuResources();
150 int GpuChannelManager::GenerateRouteID() {
151 static int last_id = 0;
152 return ++last_id;
155 void GpuChannelManager::AddRoute(int32 routing_id, IPC::Listener* listener) {
156 router_->AddRoute(routing_id, listener);
159 void GpuChannelManager::RemoveRoute(int32 routing_id) {
160 router_->RemoveRoute(routing_id);
163 GpuChannel* GpuChannelManager::LookupChannel(int32 client_id) {
164 GpuChannelMap::const_iterator iter = gpu_channels_.find(client_id);
165 if (iter == gpu_channels_.end())
166 return NULL;
167 else
168 return iter->second;
171 bool GpuChannelManager::OnMessageReceived(const IPC::Message& msg) {
172 bool handled = true;
173 IPC_BEGIN_MESSAGE_MAP(GpuChannelManager, msg)
174 IPC_MESSAGE_HANDLER(GpuMsg_EstablishChannel, OnEstablishChannel)
175 IPC_MESSAGE_HANDLER(GpuMsg_CloseChannel, OnCloseChannel)
176 IPC_MESSAGE_HANDLER(GpuMsg_CreateViewCommandBuffer,
177 OnCreateViewCommandBuffer)
178 IPC_MESSAGE_HANDLER(GpuMsg_DestroyGpuMemoryBuffer, OnDestroyGpuMemoryBuffer)
179 IPC_MESSAGE_HANDLER(GpuMsg_LoadedShader, OnLoadedShader)
180 IPC_MESSAGE_HANDLER(GpuMsg_RelinquishResources, OnRelinquishResources)
181 IPC_MESSAGE_HANDLER(GpuMsg_UpdateValueState, OnUpdateValueState)
182 IPC_MESSAGE_UNHANDLED(handled = false)
183 IPC_END_MESSAGE_MAP()
184 return handled;
187 bool GpuChannelManager::Send(IPC::Message* msg) { return router_->Send(msg); }
189 void GpuChannelManager::OnEstablishChannel(int client_id,
190 bool share_context,
191 bool allow_future_sync_points) {
192 IPC::ChannelHandle channel_handle;
194 gfx::GLShareGroup* share_group = NULL;
195 gpu::gles2::MailboxManager* mailbox_manager = NULL;
196 if (share_context) {
197 if (!share_group_.get()) {
198 share_group_ = new gfx::GLShareGroup;
199 DCHECK(!mailbox_manager_.get());
200 mailbox_manager_ = new gpu::gles2::MailboxManagerImpl;
202 share_group = share_group_.get();
203 mailbox_manager = mailbox_manager_.get();
206 scoped_ptr<GpuChannel> channel(new GpuChannel(this,
207 watchdog_,
208 share_group,
209 mailbox_manager,
210 client_id,
211 false,
212 allow_future_sync_points));
213 channel->Init(io_task_runner_.get(), shutdown_event_);
214 channel_handle.name = channel->GetChannelName();
216 #if defined(OS_POSIX)
217 // On POSIX, pass the renderer-side FD. Also mark it as auto-close so
218 // that it gets closed after it has been sent.
219 base::ScopedFD renderer_fd = channel->TakeRendererFileDescriptor();
220 DCHECK(renderer_fd.is_valid());
221 channel_handle.socket = base::FileDescriptor(renderer_fd.Pass());
222 #endif
224 gpu_channels_.set(client_id, channel.Pass());
226 Send(new GpuHostMsg_ChannelEstablished(channel_handle));
229 void GpuChannelManager::OnCloseChannel(
230 const IPC::ChannelHandle& channel_handle) {
231 for (GpuChannelMap::iterator iter = gpu_channels_.begin();
232 iter != gpu_channels_.end(); ++iter) {
233 if (iter->second->GetChannelName() == channel_handle.name) {
234 gpu_channels_.erase(iter);
235 CheckRelinquishGpuResources();
236 return;
241 void GpuChannelManager::OnCreateViewCommandBuffer(
242 const gfx::GLSurfaceHandle& window,
243 int32 surface_id,
244 int32 client_id,
245 const GPUCreateCommandBufferConfig& init_params,
246 int32 route_id) {
247 DCHECK(surface_id);
248 CreateCommandBufferResult result = CREATE_COMMAND_BUFFER_FAILED;
250 GpuChannelMap::const_iterator iter = gpu_channels_.find(client_id);
251 if (iter != gpu_channels_.end()) {
252 result = iter->second->CreateViewCommandBuffer(
253 window, surface_id, init_params, route_id);
256 Send(new GpuHostMsg_CommandBufferCreated(result));
259 void GpuChannelManager::DestroyGpuMemoryBuffer(
260 gfx::GpuMemoryBufferId id,
261 int client_id) {
262 io_task_runner_->PostTask(
263 FROM_HERE, base::Bind(&GpuChannelManager::DestroyGpuMemoryBufferOnIO,
264 base::Unretained(this), id, client_id));
267 void GpuChannelManager::DestroyGpuMemoryBufferOnIO(
268 gfx::GpuMemoryBufferId id,
269 int client_id) {
270 gpu_memory_buffer_factory_->DestroyGpuMemoryBuffer(id, client_id);
273 void GpuChannelManager::OnDestroyGpuMemoryBuffer(
274 gfx::GpuMemoryBufferId id,
275 int client_id,
276 int32 sync_point) {
277 if (!sync_point) {
278 DestroyGpuMemoryBuffer(id, client_id);
279 } else {
280 sync_point_manager()->AddSyncPointCallback(
281 sync_point,
282 base::Bind(&GpuChannelManager::DestroyGpuMemoryBuffer,
283 base::Unretained(this),
285 client_id));
289 void GpuChannelManager::OnUpdateValueState(
290 int client_id, unsigned int target, const gpu::ValueState& state) {
291 // Only pass updated state to the channel corresponding to the
292 // render_widget_host where the event originated.
293 GpuChannelMap::const_iterator iter = gpu_channels_.find(client_id);
294 if (iter != gpu_channels_.end()) {
295 iter->second->HandleUpdateValueState(target, state);
299 void GpuChannelManager::OnLoadedShader(std::string program_proto) {
300 if (program_cache())
301 program_cache()->LoadProgram(program_proto);
304 bool GpuChannelManager::HandleMessagesScheduled() {
305 for (GpuChannelMap::iterator iter = gpu_channels_.begin();
306 iter != gpu_channels_.end(); ++iter) {
307 if (iter->second->handle_messages_scheduled())
308 return true;
310 return false;
313 uint64 GpuChannelManager::MessagesProcessed() {
314 uint64 messages_processed = 0;
316 for (GpuChannelMap::iterator iter = gpu_channels_.begin();
317 iter != gpu_channels_.end(); ++iter) {
318 messages_processed += iter->second->messages_processed();
320 return messages_processed;
323 void GpuChannelManager::LoseAllContexts() {
324 for (GpuChannelMap::iterator iter = gpu_channels_.begin();
325 iter != gpu_channels_.end(); ++iter) {
326 iter->second->MarkAllContextsLost();
328 base::ThreadTaskRunnerHandle::Get()->PostTask(
329 FROM_HERE, base::Bind(&GpuChannelManager::OnLoseAllContexts,
330 weak_factory_.GetWeakPtr()));
333 void GpuChannelManager::OnLoseAllContexts() {
334 gpu_channels_.clear();
335 CheckRelinquishGpuResources();
338 gfx::GLSurface* GpuChannelManager::GetDefaultOffscreenSurface() {
339 if (!default_offscreen_surface_.get()) {
340 default_offscreen_surface_ =
341 gfx::GLSurface::CreateOffscreenGLSurface(gfx::Size());
343 return default_offscreen_surface_.get();
346 void GpuChannelManager::OnRelinquishResources() {
347 relinquish_resources_pending_ = true;
348 CheckRelinquishGpuResources();
351 void GpuChannelManager::CheckRelinquishGpuResources() {
352 if (relinquish_resources_pending_ && gpu_channels_.size() <= 1) {
353 relinquish_resources_pending_ = false;
354 if (default_offscreen_surface_.get()) {
355 default_offscreen_surface_->DestroyAndTerminateDisplay();
356 default_offscreen_surface_ = NULL;
358 #if defined(USE_OZONE)
359 ui::OzonePlatform::GetInstance()
360 ->GetGpuPlatformSupport()
361 ->RelinquishGpuResources(
362 base::Bind(&GpuChannelManager::OnResourcesRelinquished,
363 weak_factory_.GetWeakPtr()));
364 #else
365 OnResourcesRelinquished();
366 #endif
370 void GpuChannelManager::OnResourcesRelinquished() {
371 Send(new GpuHostMsg_ResourcesRelinquished());
374 } // namespace content