Index: content/browser/gpu/gpu_process_host.cc |
diff --git a/content/browser/gpu/gpu_process_host.cc b/content/browser/gpu/gpu_process_host.cc |
index a54fe75722d8b2709528479960524802449c0094..fdeadb4f2a732f2d6f740504c28d93cc7db8a035 100644 |
--- a/content/browser/gpu/gpu_process_host.cc |
+++ b/content/browser/gpu/gpu_process_host.cc |
@@ -15,20 +15,15 @@ |
#include "chrome/common/render_messages.h" |
#include "content/browser/browser_thread.h" |
#include "content/browser/gpu/gpu_data_manager.h" |
-#include "content/browser/gpu/gpu_process_host_ui_shim.h" |
+#include "content/browser/renderer_host/render_process_host.h" |
#include "content/browser/renderer_host/render_widget_host.h" |
#include "content/browser/renderer_host/render_widget_host_view.h" |
#include "content/common/gpu/gpu_messages.h" |
-#include "ipc/ipc_channel_handle.h" |
#include "ipc/ipc_switches.h" |
#include "media/base/media_switches.h" |
#include "ui/gfx/gl/gl_context.h" |
#include "ui/gfx/gl/gl_switches.h" |
-#if defined(OS_LINUX) |
-#include "ui/gfx/gtk_native_view_id_manager.h" |
-#endif // defined(OS_LINUX) |
- |
namespace { |
enum GPUProcessLifetimeEvent { |
@@ -52,28 +47,6 @@ static const int kGpuMaxCrashCount = 3; |
int g_last_host_id = 0; |
-#if defined(OS_LINUX) |
- |
-class ReleasePermanentXIDDispatcher: public Task { |
- public: |
- explicit ReleasePermanentXIDDispatcher(gfx::PluginWindowHandle surface); |
- void Run(); |
- private: |
- gfx::PluginWindowHandle surface_; |
-}; |
- |
-ReleasePermanentXIDDispatcher::ReleasePermanentXIDDispatcher( |
- gfx::PluginWindowHandle surface) |
- : surface_(surface) { |
-} |
- |
-void ReleasePermanentXIDDispatcher::Run() { |
- GtkNativeViewManager* manager = GtkNativeViewManager::GetInstance(); |
- manager->ReleasePermanentXID(surface_); |
-} |
- |
-#endif |
- |
void SendGpuProcessMessage(int renderer_id, |
content::CauseForGpuLaunch cause, |
IPC::Message* message) { |
@@ -88,33 +61,6 @@ void SendGpuProcessMessage(int renderer_id, |
} // anonymous namespace |
-#if defined(OS_LINUX) |
-// Used to put a lock on surfaces so that the window to which the GPU |
-// process is drawing to doesn't disappear while it is drawing when |
-// a tab is closed. |
-class GpuProcessHost::SurfaceRef { |
- public: |
- explicit SurfaceRef(gfx::PluginWindowHandle surface); |
- ~SurfaceRef(); |
- private: |
- gfx::PluginWindowHandle surface_; |
-}; |
- |
-GpuProcessHost::SurfaceRef::SurfaceRef(gfx::PluginWindowHandle surface) |
- : surface_(surface) { |
- GtkNativeViewManager* manager = GtkNativeViewManager::GetInstance(); |
- if (!manager->AddRefPermanentXID(surface_)) { |
- LOG(ERROR) << "Surface " << surface << " cannot be referenced."; |
- } |
-} |
- |
-GpuProcessHost::SurfaceRef::~SurfaceRef() { |
- BrowserThread::PostTask(BrowserThread::UI, |
- FROM_HERE, |
- new ReleasePermanentXIDDispatcher(surface_)); |
-} |
-#endif // defined(OS_LINUX) |
- |
// static |
GpuProcessHost* GpuProcessHost::GetForRenderer( |
int renderer_id, content::CauseForGpuLaunch cause) { |
@@ -136,30 +82,7 @@ GpuProcessHost* GpuProcessHost::GetForRenderer( |
if (cause == content::CAUSE_FOR_GPU_LAUNCH_NO_LAUNCH) |
return NULL; |
- int host_id; |
- /* TODO(apatrick): this is currently broken because this function is called on |
- the IO thread from GpuMessageFilter, and we don't have an IO thread object |
- when running the GPU code in the browser at the moment. |
- if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess) || |
- CommandLine::ForCurrentProcess()->HasSwitch(switches::kInProcessGPU)) { |
- if (!g_browser_process->gpu_thread()) |
- return NULL; |
- |
- // Initialize GL on the GPU thread. |
- // TODO(apatrick): Handle failure to initialize (asynchronously). |
- if (!BrowserThread::PostTask( |
- BrowserThread::GPU, |
- FROM_HERE, |
- NewRunnableFunction(&gfx::GLContext::InitializeOneOff))) { |
- return NULL; |
- } |
- |
- host_id = 0; |
- } else { |
- host_id = ++g_last_host_id; |
- } |
- */ |
- host_id = ++g_last_host_id; |
+ int host_id = ++g_last_host_id; |
UMA_HISTOGRAM_ENUMERATION("GPU.GPUProcessLaunchCause", |
cause, |
@@ -198,18 +121,8 @@ GpuProcessHost::GpuProcessHost(int host_id) |
host_id_(host_id), |
gpu_process_(base::kNullProcessHandle) { |
g_hosts_by_id.AddWithID(this, host_id_); |
- if (host_id == 0) |
- gpu_process_ = base::GetCurrentProcessHandle(); |
- |
- // Post a task to create the corresponding GpuProcessHostUIShim. The |
- // GpuProcessHostUIShim will be destroyed if either the browser exits, |
- // in which case it calls GpuProcessHostUIShim::DestroyAll, or the |
- // GpuProcessHost is destroyed, which happens when the corresponding GPU |
- // process terminates or fails to launch. |
- BrowserThread::PostTask( |
- BrowserThread::UI, |
- FROM_HERE, |
- NewRunnableFunction(&GpuProcessHostUIShim::Create, host_id)); |
+ DCHECK(host_id); |
+ message_hub_.reset(new GpuMessageHub(host_id)); |
} |
GpuProcessHost::~GpuProcessHost() { |
@@ -226,11 +139,6 @@ GpuProcessHost::~GpuProcessHost() { |
} |
g_hosts_by_id.Remove(host_id_); |
- |
- BrowserThread::PostTask(BrowserThread::UI, |
- FROM_HERE, |
- NewRunnableFunction(GpuProcessHostUIShim::Destroy, |
- host_id_)); |
} |
bool GpuProcessHost::Init() { |
@@ -243,13 +151,6 @@ bool GpuProcessHost::Init() { |
return Send(new GpuMsg_Initialize()); |
} |
-void GpuProcessHost::RouteOnUIThread(const IPC::Message& message) { |
- BrowserThread::PostTask( |
- BrowserThread::UI, |
- FROM_HERE, |
- new RouteToGpuProcessHostUIShimTask(host_id_, message)); |
-} |
- |
bool GpuProcessHost::Send(IPC::Message* msg) { |
DCHECK(CalledOnValidThread()); |
if (opening_channel()) { |
@@ -262,17 +163,8 @@ bool GpuProcessHost::Send(IPC::Message* msg) { |
bool GpuProcessHost::OnMessageReceived(const IPC::Message& message) { |
DCHECK(CalledOnValidThread()); |
- IPC_BEGIN_MESSAGE_MAP(GpuProcessHost, message) |
- IPC_MESSAGE_HANDLER(GpuHostMsg_ChannelEstablished, OnChannelEstablished) |
- IPC_MESSAGE_HANDLER(GpuHostMsg_SynchronizeReply, OnSynchronizeReply) |
- IPC_MESSAGE_HANDLER(GpuHostMsg_CommandBufferCreated, OnCommandBufferCreated) |
- IPC_MESSAGE_HANDLER(GpuHostMsg_DestroyCommandBuffer, OnDestroyCommandBuffer) |
- IPC_MESSAGE_HANDLER(GpuHostMsg_GraphicsInfoCollected, |
- OnGraphicsInfoCollected) |
- IPC_MESSAGE_UNHANDLED(RouteOnUIThread(message)) |
- IPC_END_MESSAGE_MAP() |
- |
- return true; |
+ DCHECK(message_hub_.get()); |
+ return message_hub_->OnMessageReceived(message); |
} |
void GpuProcessHost::OnChannelConnected(int32 peer_pid) { |
@@ -282,143 +174,6 @@ void GpuProcessHost::OnChannelConnected(int32 peer_pid) { |
} |
} |
-void GpuProcessHost::EstablishGpuChannel( |
- int renderer_id, |
- EstablishChannelCallback *callback) { |
- DCHECK(CalledOnValidThread()); |
- TRACE_EVENT0("gpu", "GpuProcessHostUIShim::EstablishGpuChannel"); |
- linked_ptr<EstablishChannelCallback> wrapped_callback(callback); |
- |
- // If GPU features are already blacklisted, no need to establish the channel. |
- if (!GpuDataManager::GetInstance()->GpuAccessAllowed()) { |
- EstablishChannelError( |
- wrapped_callback.release(), IPC::ChannelHandle(), |
- base::kNullProcessHandle, GPUInfo()); |
- return; |
- } |
- |
- if (Send(new GpuMsg_EstablishChannel(renderer_id))) { |
- channel_requests_.push(wrapped_callback); |
- } else { |
- EstablishChannelError( |
- wrapped_callback.release(), IPC::ChannelHandle(), |
- base::kNullProcessHandle, GPUInfo()); |
- } |
-} |
- |
-void GpuProcessHost::Synchronize(SynchronizeCallback* callback) { |
- DCHECK(CalledOnValidThread()); |
- linked_ptr<SynchronizeCallback> wrapped_callback(callback); |
- |
- if (Send(new GpuMsg_Synchronize())) { |
- synchronize_requests_.push(wrapped_callback); |
- } else { |
- SynchronizeError(wrapped_callback.release()); |
- } |
-} |
- |
-void GpuProcessHost::CreateViewCommandBuffer( |
- gfx::PluginWindowHandle compositing_surface, |
- int32 render_view_id, |
- int32 renderer_id, |
- const GPUCreateCommandBufferConfig& init_params, |
- CreateCommandBufferCallback* callback) { |
- DCHECK(CalledOnValidThread()); |
- linked_ptr<CreateCommandBufferCallback> wrapped_callback(callback); |
- |
-#if defined(OS_LINUX) |
- ViewID view_id(renderer_id, render_view_id); |
- |
- // There should only be one such command buffer (for the compositor). In |
- // practice, if the GPU process lost a context, GraphicsContext3D with |
- // associated command buffer and view surface will not be gone until new |
- // one is in place and all layers are reattached. |
- linked_ptr<SurfaceRef> surface_ref; |
- SurfaceRefMap::iterator it = surface_refs_.find(view_id); |
- if (it != surface_refs_.end()) |
- surface_ref = (*it).second; |
- else |
- surface_ref.reset(new SurfaceRef(compositing_surface)); |
-#endif // defined(OS_LINUX) |
- |
- if (compositing_surface != gfx::kNullPluginWindow && |
- Send(new GpuMsg_CreateViewCommandBuffer( |
- compositing_surface, render_view_id, renderer_id, init_params))) { |
- create_command_buffer_requests_.push(wrapped_callback); |
-#if defined(OS_LINUX) |
- surface_refs_.insert(std::pair<ViewID, linked_ptr<SurfaceRef> >( |
- view_id, surface_ref)); |
-#endif // defined(OS_LINUX) |
- } else { |
- CreateCommandBufferError(wrapped_callback.release(), MSG_ROUTING_NONE); |
- } |
-} |
- |
-void GpuProcessHost::OnChannelEstablished( |
- const IPC::ChannelHandle& channel_handle) { |
- // The GPU process should have launched at this point and this object should |
- // have been notified of its process handle. |
- DCHECK(gpu_process_); |
- |
- linked_ptr<EstablishChannelCallback> callback = channel_requests_.front(); |
- channel_requests_.pop(); |
- |
- // Currently if any of the GPU features are blacklisted, we don't establish a |
- // GPU channel. |
- if (!channel_handle.name.empty() && |
- !GpuDataManager::GetInstance()->GpuAccessAllowed()) { |
- Send(new GpuMsg_CloseChannel(channel_handle)); |
- EstablishChannelError(callback.release(), |
- IPC::ChannelHandle(), |
- base::kNullProcessHandle, |
- GPUInfo()); |
- RouteOnUIThread(GpuHostMsg_OnLogMessage( |
- logging::LOG_WARNING, |
- "WARNING", |
- "Hardware acceleration is unavailable.")); |
- return; |
- } |
- |
- callback->Run( |
- channel_handle, gpu_process_, GpuDataManager::GetInstance()->gpu_info()); |
-} |
- |
-void GpuProcessHost::OnSynchronizeReply() { |
- // Guard against race conditions in abrupt GPU process termination. |
- if (!synchronize_requests_.empty()) { |
- linked_ptr<SynchronizeCallback> callback(synchronize_requests_.front()); |
- synchronize_requests_.pop(); |
- callback->Run(); |
- } |
-} |
- |
-void GpuProcessHost::OnCommandBufferCreated(const int32 route_id) { |
- if (!create_command_buffer_requests_.empty()) { |
- linked_ptr<CreateCommandBufferCallback> callback = |
- create_command_buffer_requests_.front(); |
- create_command_buffer_requests_.pop(); |
- if (route_id == MSG_ROUTING_NONE) |
- CreateCommandBufferError(callback.release(), route_id); |
- else |
- callback->Run(route_id); |
- } |
-} |
- |
-void GpuProcessHost::OnDestroyCommandBuffer( |
- gfx::PluginWindowHandle window, int32 renderer_id, |
- int32 render_view_id) { |
-#if defined(OS_LINUX) |
- ViewID view_id(renderer_id, render_view_id); |
- SurfaceRefMap::iterator it = surface_refs_.find(view_id); |
- if (it != surface_refs_.end()) |
- surface_refs_.erase(it); |
-#endif // defined(OS_LINUX) |
-} |
- |
-void GpuProcessHost::OnGraphicsInfoCollected(const GPUInfo& gpu_info) { |
- GpuDataManager::GetInstance()->UpdateGpuInfo(gpu_info); |
-} |
- |
bool GpuProcessHost::CanShutdown() { |
return true; |
} |
@@ -438,6 +193,9 @@ void GpuProcessHost::OnProcessLaunched() { |
#else |
gpu_process_ = handle(); |
#endif |
+ |
+ DCHECK(message_hub_.get()); |
+ message_hub_->SetGPUProcess(gpu_process_); |
} |
void GpuProcessHost::OnChildDied() { |
@@ -528,41 +286,6 @@ bool GpuProcessHost::LaunchGpuProcess() { |
} |
void GpuProcessHost::SendOutstandingReplies() { |
- // First send empty channel handles for all EstablishChannel requests. |
- while (!channel_requests_.empty()) { |
- linked_ptr<EstablishChannelCallback> callback = channel_requests_.front(); |
- channel_requests_.pop(); |
- EstablishChannelError(callback.release(), |
- IPC::ChannelHandle(), |
- base::kNullProcessHandle, |
- GPUInfo()); |
- } |
- |
- // Now unblock all renderers waiting for synchronization replies. |
- while (!synchronize_requests_.empty()) { |
- linked_ptr<SynchronizeCallback> callback = synchronize_requests_.front(); |
- synchronize_requests_.pop(); |
- SynchronizeError(callback.release()); |
- } |
-} |
- |
-void GpuProcessHost::EstablishChannelError( |
- EstablishChannelCallback* callback, |
- const IPC::ChannelHandle& channel_handle, |
- base::ProcessHandle renderer_process_for_gpu, |
- const GPUInfo& gpu_info) { |
- scoped_ptr<EstablishChannelCallback> wrapped_callback(callback); |
- wrapped_callback->Run(channel_handle, renderer_process_for_gpu, gpu_info); |
-} |
- |
-void GpuProcessHost::CreateCommandBufferError( |
- CreateCommandBufferCallback* callback, int32 route_id) { |
- scoped_ptr<GpuProcessHost::CreateCommandBufferCallback> |
- wrapped_callback(callback); |
- callback->Run(route_id); |
-} |
- |
-void GpuProcessHost::SynchronizeError(SynchronizeCallback* callback) { |
- scoped_ptr<SynchronizeCallback> wrapped_callback(callback); |
- wrapped_callback->Run(); |
+ DCHECK(message_hub_.get()); |
+ message_hub_->SendOutstandingReplies(); |
} |