diff options
author | apatrick@chromium.org <apatrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-02-16 00:44:34 +0000 |
---|---|---|
committer | apatrick@chromium.org <apatrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-02-16 00:44:34 +0000 |
commit | 6dff3815fda9c86c68b50fcd5d95c6c396d5e209 (patch) | |
tree | 7226dcb0a5f481f2fa56a21329d6062694f18f81 | |
parent | 6cd41bde72984f096af5c92c20833322bca8e230 (diff) | |
download | chromium_src-6dff3815fda9c86c68b50fcd5d95c6c396d5e209.zip chromium_src-6dff3815fda9c86c68b50fcd5d95c6c396d5e209.tar.gz chromium_src-6dff3815fda9c86c68b50fcd5d95c6c396d5e209.tar.bz2 |
Not ready for review yet.
Allow GPU process to present to the compositing surface without the involvement of the UI thread. This is to prevent a potential deadlock and so I can revert this:
https://chromiumcodereview.appspot.com/9295021
BUG=111514
Review URL: http://codereview.chromium.org/9380019
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@122205 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | content/browser/gpu/gpu_process_host.cc | 36 | ||||
-rw-r--r-- | content/browser/gpu/gpu_process_host.h | 9 | ||||
-rw-r--r-- | content/browser/gpu/gpu_surface_tracker.cc | 28 | ||||
-rw-r--r-- | content/browser/gpu/gpu_surface_tracker.h | 14 | ||||
-rw-r--r-- | content/browser/renderer_host/render_widget_host.cc | 2 | ||||
-rw-r--r-- | content/browser/renderer_host/render_widget_host_view_win.cc | 37 | ||||
-rw-r--r-- | ui/gfx/native_widget_types.h | 12 |
7 files changed, 111 insertions, 27 deletions
diff --git a/content/browser/gpu/gpu_process_host.cc b/content/browser/gpu/gpu_process_host.cc index 4308cbc..8a981521 100644 --- a/content/browser/gpu/gpu_process_host.cc +++ b/content/browser/gpu/gpu_process_host.cc @@ -18,6 +18,7 @@ #include "content/browser/browser_child_process_host_impl.h" #include "content/browser/gpu/gpu_data_manager.h" #include "content/browser/gpu/gpu_process_host_ui_shim.h" +#include "content/browser/gpu/gpu_surface_tracker.h" #include "content/browser/renderer_host/render_widget_host.h" #include "content/browser/renderer_host/render_widget_host_view.h" #include "content/common/child_process_host_impl.h" @@ -262,6 +263,7 @@ GpuProcessHost::GpuProcessHost(int host_id, bool sandboxed) CommandLine::ForCurrentProcess()->HasSwitch(switches::kInProcessGPU)) in_process_ = true; + // If the 'single GPU process' policy ever changes, we still want to maintain // it for 'gpu thread' mode and only create one instance of host and thread. DCHECK(!in_process_ || g_hosts_by_id.Pointer()->IsEmpty()); @@ -394,6 +396,12 @@ bool GpuProcessHost::OnMessageReceived(const IPC::Message& message) { IPC_MESSAGE_HANDLER(GpuHostMsg_ChannelEstablished, OnChannelEstablished) IPC_MESSAGE_HANDLER(GpuHostMsg_CommandBufferCreated, OnCommandBufferCreated) IPC_MESSAGE_HANDLER(GpuHostMsg_DestroyCommandBuffer, OnDestroyCommandBuffer) +#if defined(OS_WIN) && !defined(USE_AURA) + IPC_MESSAGE_HANDLER(GpuHostMsg_AcceleratedSurfaceBuffersSwapped, + OnAcceleratedSurfaceBuffersSwapped) + IPC_MESSAGE_HANDLER(GpuHostMsg_AcceleratedSurfacePostSubBuffer, + OnAcceleratedSurfacePostSubBuffer) +#endif IPC_MESSAGE_UNHANDLED(RouteOnUIThread(message)) IPC_END_MESSAGE_MAP() @@ -512,6 +520,34 @@ void GpuProcessHost::OnDestroyCommandBuffer(int32 surface_id) { #endif // defined(TOOLKIT_USES_GTK) } +#if defined(OS_WIN) && !defined(USE_AURA) + +void GpuProcessHost::OnAcceleratedSurfaceBuffersSwapped( + const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params) { + TRACE_EVENT0("renderer", + "GpuProcessHost::OnAcceleratedSurfaceBuffersSwapped"); + + GpuSurfaceTracker::Get()->AsyncPresentAndAcknowledge( + params.surface_id, + params.size, + params.surface_handle, + base::Bind(SendOnIO, + host_id_, + content::CAUSE_FOR_GPU_LAUNCH_NO_LAUNCH, + new AcceleratedSurfaceMsg_BuffersSwappedACK( + params.route_id))); +} + +void GpuProcessHost::OnAcceleratedSurfacePostSubBuffer( + const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params) { + TRACE_EVENT0("renderer", + "GpuProcessHost::OnAcceleratedSurfacePostSubBuffer"); + + NOTIMPLEMENTED(); +} + +#endif // OS_WIN && !USE_AURA + void GpuProcessHost::OnProcessLaunched() { // Send the GPU process handle to the UI thread before it has to // respond to any requests to establish a GPU channel. The response diff --git a/content/browser/gpu/gpu_process_host.h b/content/browser/gpu/gpu_process_host.h index 30a7dcf..c0c8b73 100644 --- a/content/browser/gpu/gpu_process_host.h +++ b/content/browser/gpu/gpu_process_host.h @@ -22,6 +22,8 @@ class GpuMainThread; struct GPUCreateCommandBufferConfig; +struct GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params; +struct GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params; class BrowserChildProcessHostImpl; @@ -106,6 +108,13 @@ class GpuProcessHost : public content::BrowserChildProcessHostDelegate, void OnCommandBufferCreated(const int32 route_id); void OnDestroyCommandBuffer(int32 surface_id); +#if defined(OS_WIN) && !defined(USE_AURA) + void OnAcceleratedSurfaceBuffersSwapped( + const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params); + void OnAcceleratedSurfacePostSubBuffer( + const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params); +#endif + bool LaunchGpuProcess(const std::string& channel_id); void SendOutstandingReplies(); diff --git a/content/browser/gpu/gpu_surface_tracker.cc b/content/browser/gpu/gpu_surface_tracker.cc index ba15dab..909c39d 100644 --- a/content/browser/gpu/gpu_surface_tracker.cc +++ b/content/browser/gpu/gpu_surface_tracker.cc @@ -6,6 +6,10 @@ #include "base/logging.h" +#if defined(OS_WIN) +#include "ui/gfx/surface/accelerated_surface_win.h" +#endif + GpuSurfaceTracker::GpuSurfaceTracker() : next_surface_id_(1) { } @@ -86,3 +90,27 @@ gfx::GLSurfaceHandle GpuSurfaceTracker::GetSurfaceHandle(int surface_id) { return surface_map_[surface_id].handle; } +#if defined(OS_WIN) && !defined(USE_AURA) + +void GpuSurfaceTracker::AsyncPresentAndAcknowledge( + int surface_id, + const gfx::Size& size, + int64 surface_handle, + const base::Closure& completion_task) { + base::AutoLock lock(lock_); + + SurfaceMap::iterator it = surface_map_.find(surface_id); + if (it == surface_map_.end() || !it->second.handle.accelerated_surface) { + completion_task.Run(); + return; + } + + it->second.handle.accelerated_surface->AsyncPresentAndAcknowledge( + it->second.handle.handle, + size, + surface_handle, + completion_task); +} + +#endif // OS_WIN + diff --git a/content/browser/gpu/gpu_surface_tracker.h b/content/browser/gpu/gpu_surface_tracker.h index 98b4eed..a38095a 100644 --- a/content/browser/gpu/gpu_surface_tracker.h +++ b/content/browser/gpu/gpu_surface_tracker.h @@ -11,6 +11,7 @@ #include "base/memory/singleton.h" #include "base/synchronization/lock.h" #include "ui/gfx/native_widget_types.h" +#include "ui/gfx/size.h" // This class is responsible for managing rendering surfaces exposed to the // GPU process. Every surface gets registered to this class, and gets an ID. @@ -57,6 +58,19 @@ class GpuSurfaceTracker { // Note: This is an O(log N) lookup. gfx::GLSurfaceHandle GetSurfaceHandle(int surface_id); +#if defined(OS_WIN) && !defined(USE_AURA) + // This is a member of GpuSurfaceTracker because it holds the lock for its + // duration. This prevents the AcceleratedSurface that it posts to from being + // destroyed by the main thread during that time. This function is only called + // on the IO thread. This function only posts tasks asynchronously. If it + // were to synchronously call the UI thread, there would be a possiblity of + // deadlock. + void AsyncPresentAndAcknowledge(int surface_id, + const gfx::Size& size, + int64 surface_handle, + const base::Closure& completion_task); +#endif + // Gets the global instance of the surface tracker. Identical to Get(), but // named that way for the implementation of Singleton. static GpuSurfaceTracker* GetInstance(); diff --git a/content/browser/renderer_host/render_widget_host.cc b/content/browser/renderer_host/render_widget_host.cc index 1a5ba0e..bfcdb1f 100644 --- a/content/browser/renderer_host/render_widget_host.cc +++ b/content/browser/renderer_host/render_widget_host.cc @@ -775,6 +775,8 @@ void RenderWidgetHost::RendererExited(base::TerminationStatus status, in_flight_event_count_ = 0; if (view_) { + GpuSurfaceTracker::Get()->SetSurfaceHandle(surface_id_, + gfx::GLSurfaceHandle()); view_->RenderViewGone(status, exit_code); view_ = NULL; // The View should be deleted by RenderViewGone. } diff --git a/content/browser/renderer_host/render_widget_host_view_win.cc b/content/browser/renderer_host/render_widget_host_view_win.cc index 3519223..f33665a 100644 --- a/content/browser/renderer_host/render_widget_host_view_win.cc +++ b/content/browser/renderer_host/render_widget_host_view_win.cc @@ -2076,7 +2076,15 @@ gfx::GLSurfaceHandle RenderWidgetHostViewWin::GetCompositingSurface() { ui::SetWindowUserData(compositor_host_window_, this); - return gfx::GLSurfaceHandle(compositor_host_window_, true); + gfx::GLSurfaceHandle surface_handle(compositor_host_window_, true); + + base::win::OSInfo *os_info = base::win::OSInfo::GetInstance(); + if (os_info->version() >= base::win::VERSION_VISTA) { + accelerated_surface_.reset(new AcceleratedSurface); + surface_handle.accelerated_surface = accelerated_surface_.get(); + } + + return surface_handle; } void RenderWidgetHostViewWin::OnAcceleratedCompositingStateChange() { @@ -2088,7 +2096,7 @@ void RenderWidgetHostViewWin::OnAcceleratedCompositingStateChange() { return; if (show) { - ::ShowWindow(compositor_host_window_, SW_SHOW); + //::ShowWindow(compositor_host_window_, SW_SHOW); // Get all the child windows of this view, including the compositor window. std::vector<HWND> all_child_windows; @@ -2125,34 +2133,13 @@ void RenderWidgetHostViewWin::OnAcceleratedCompositingStateChange() { void RenderWidgetHostViewWin::AcceleratedSurfaceBuffersSwapped( const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params, int gpu_host_id) { - if (params.surface_handle) { - if (!accelerated_surface_.get() && compositor_host_window_) { - accelerated_surface_.reset(new AcceleratedSurface); - } - - scoped_ptr<IPC::Message> message( - new AcceleratedSurfaceMsg_BuffersSwappedACK(params.route_id)); - base::Closure acknowledge_task = base::Bind( - SendToGpuProcessHost, - gpu_host_id, - base::Passed(&message)); - - accelerated_surface_->AsyncPresentAndAcknowledge( - compositor_host_window_, - params.size, - params.surface_handle, - base::Bind(PostTaskOnIOThread, - FROM_HERE, - acknowledge_task)); - } else { - RenderWidgetHost::AcknowledgeSwapBuffers(params.route_id, gpu_host_id); - } + NOTREACHED(); } void RenderWidgetHostViewWin::AcceleratedSurfacePostSubBuffer( const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params, int gpu_host_id) { - RenderWidgetHost::AcknowledgePostSubBuffer(params.route_id, gpu_host_id); + NOTREACHED(); } void RenderWidgetHostViewWin::AcceleratedSurfaceSuspend() { diff --git a/ui/gfx/native_widget_types.h b/ui/gfx/native_widget_types.h index 279175b..88746551 100644 --- a/ui/gfx/native_widget_types.h +++ b/ui/gfx/native_widget_types.h @@ -97,6 +97,8 @@ class ChromeView; #endif class SkBitmap; +class AcceleratedSurface; + namespace gfx { #if defined(USE_AURA) @@ -261,7 +263,8 @@ struct GLSurfaceHandle { : handle(kNullPluginWindow), transport(false), parent_client_id(0), - parent_context_id(0) { + parent_context_id(0), + accelerated_surface(NULL) { parent_texture_id[0] = 0; parent_texture_id[1] = 0; } @@ -269,7 +272,8 @@ struct GLSurfaceHandle { : handle(handle_), transport(transport_), parent_client_id(0), - parent_context_id(0) { + parent_context_id(0), + accelerated_surface(NULL) { parent_texture_id[0] = 0; parent_texture_id[1] = 0; } @@ -279,6 +283,10 @@ struct GLSurfaceHandle { uint32 parent_client_id; uint32 parent_context_id; uint32 parent_texture_id[2]; + + // This member does not get serialized and will be null when the + // GPUSurfaceHandle is deserialied. + AcceleratedSurface* accelerated_surface; }; // AcceleratedWidget provides a surface to compositors to paint pixels. |