Chromium Code Reviews| Index: content/browser/gpu/gpu_thread_host.cc |
| diff --git a/content/browser/gpu/gpu_thread_host.cc b/content/browser/gpu/gpu_thread_host.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..1ab7a1738f8326d80a4da1c89c30f422ddf08c58 |
| --- /dev/null |
| +++ b/content/browser/gpu/gpu_thread_host.cc |
| @@ -0,0 +1,134 @@ |
| +// 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. |
| + |
| +#include "base/memory/scoped_ptr.h" |
| +#include "base/process_util.h" |
| +#include "chrome/browser/browser_process.h" |
| +#include "content/browser/browser_thread.h" |
| +#include "content/browser/gpu/gpu_thread_host.h" |
| +#include "content/common/gpu/gpu_channel_manager.h" |
| +#include "ipc/ipc_message.h" |
| +#include "ui/gfx/gl/gl_surface.h" |
| + |
| +// This is a helper object to forward messages from the GPU thread to the |
| +// GpuMessageHub. They will then either be forwarded to the UI thread, |
| +// or (in the case of replies) will trigger a callback to the renderer. |
| +class IOThreadSender : public IPC::Channel::Sender { |
| + public: |
| + class SendOnIOThreadTask : public Task { |
| + public: |
| + SendOnIOThreadTask(GpuMessageHub* browser_host, IPC::Message* msg) |
| + : message_hub_(browser_host), |
| + msg_(msg) { |
| + } |
| + |
| + private: |
| + void Run() { |
| + message_hub_->OnMessageReceived(*msg_); |
| + } |
| + |
| + GpuMessageHub* message_hub_; |
| + scoped_ptr<IPC::Message> msg_; |
| + }; |
| + |
| + IOThreadSender(GpuMessageHub* browser_host) |
| + : message_hub_(browser_host) { } |
|
apatrick_chromium
2011/05/23 22:01:33
drop } to next line.
|
| + |
| + virtual bool Send(IPC::Message* msg) { |
| + bool success = BrowserThread::PostTask( |
| + BrowserThread::IO, |
| + FROM_HERE, |
| + new SendOnIOThreadTask(message_hub_, msg)); |
| + |
| + return success; |
| + } |
| + |
| + private: |
| + GpuMessageHub* message_hub_; |
| +}; |
| + |
| +void ForwardMessageToGpuThread(GpuChannelManager* gpu_channel_manager, |
| + IPC::Message* msg) { |
| + bool success = gpu_channel_manager->OnMessageReceived(*msg); |
| + |
| + // If the message was not handled, it is likely it was intended for the |
| + // GpuChildThread, which does not exist in single process and in process GPU |
| + // mode. |
| + DCHECK(success); |
| + |
| + delete msg; |
| +} |
| + |
| +// static |
| +GpuThreadHost* GpuThreadHost::g_instance = NULL; |
| + |
| +// static |
| +GpuThreadHost* GpuThreadHost::GetInstance() { |
| + // This should get created from channel establishment on the IO thread. |
| + DCHECK(g_instance || BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| + |
| + if (!g_instance) |
| + g_instance = new GpuThreadHost(); |
| + |
| + return g_instance; |
| +} |
| + |
| +// static |
| +void GpuThreadHost::Destroy() { |
| + if (g_instance) { |
| + if (BrowserThread::CurrentlyOn(BrowserThread::IO)) |
| + delete g_instance; |
| + else |
| + BrowserThread::DeleteSoon(BrowserThread::IO, |
| + FROM_HERE, |
| + g_instance); |
| + g_instance = NULL; |
| + } |
| +} |
| + |
| +GpuThreadHost::GpuThreadHost() { |
| + message_hub_.reset(new GpuMessageHub(0)); |
| + message_hub_->SetGPUProcess(base::GetCurrentProcessHandle()); |
| + |
| + browser_sender_ = new IOThreadSender(message_hub_.get()); |
| + |
| + BrowserThread::PostTask( |
| + BrowserThread::GPU, |
| + FROM_HERE, |
| + NewRunnableFunction(&gfx::GLSurface::InitializeOneOff)); |
| + |
| + // Initialize GL on the GPU thread. |
| + // TODO(apatrick): Handle failure to initialize (asynchronously). |
|
apatrick_chromium
2011/05/23 22:01:33
redundant block
|
| + BrowserThread::PostTask( |
| + BrowserThread::GPU, |
| + FROM_HERE, |
| + NewRunnableFunction(&gfx::GLSurface::InitializeOneOff)); |
| + |
| + gpu_channel_manager_ = new GpuChannelManager( |
| + browser_sender_, |
| + NULL, |
| + BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO), |
| + g_browser_process->shutdown_event()); |
| +} |
| + |
| +GpuThreadHost::~GpuThreadHost() { |
| + // Ensure these are destroyed on the GPU thread. |
| + if (gpu_channel_manager_) { |
| + BrowserThread::DeleteSoon(BrowserThread::GPU, |
| + FROM_HERE, |
| + gpu_channel_manager_); |
| + gpu_channel_manager_ = NULL; |
| + } |
| + |
| + delete browser_sender_; |
| +} |
| + |
| +bool GpuThreadHost::Send(IPC::Message* message) { |
| + return BrowserThread::PostTask( |
| + BrowserThread::GPU, |
| + FROM_HERE, |
| + NewRunnableFunction(ForwardMessageToGpuThread, |
| + gpu_channel_manager_, |
| + message)); |
| +} |