summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorapatrick@chromium.org <apatrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-02-16 00:44:34 +0000
committerapatrick@chromium.org <apatrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-02-16 00:44:34 +0000
commit6dff3815fda9c86c68b50fcd5d95c6c396d5e209 (patch)
tree7226dcb0a5f481f2fa56a21329d6062694f18f81
parent6cd41bde72984f096af5c92c20833322bca8e230 (diff)
downloadchromium_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.cc36
-rw-r--r--content/browser/gpu/gpu_process_host.h9
-rw-r--r--content/browser/gpu/gpu_surface_tracker.cc28
-rw-r--r--content/browser/gpu/gpu_surface_tracker.h14
-rw-r--r--content/browser/renderer_host/render_widget_host.cc2
-rw-r--r--content/browser/renderer_host/render_widget_host_view_win.cc37
-rw-r--r--ui/gfx/native_widget_types.h12
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.