summaryrefslogtreecommitdiffstats
path: root/content/browser/gpu
diff options
context:
space:
mode:
authorpiman@chromium.org <piman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-01-18 22:29:56 +0000
committerpiman@chromium.org <piman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-01-18 22:29:56 +0000
commit9f4f3322e7c9a5feedd5ca2b986daf2f8d5b8d3d (patch)
treea67a3d0397a03e12ee51aa8720f612c62c20e936 /content/browser/gpu
parenta3102766e725636ad23ad99faa1e8a481a1129e7 (diff)
downloadchromium_src-9f4f3322e7c9a5feedd5ca2b986daf2f8d5b8d3d.zip
chromium_src-9f4f3322e7c9a5feedd5ca2b986daf2f8d5b8d3d.tar.gz
chromium_src-9f4f3322e7c9a5feedd5ca2b986daf2f8d5b8d3d.tar.bz2
gpu: reference target surfaces through a globally unique surface id.
This allows the gpu process to ignore all knowledge of renderers. It simplifies some of the gpu <-> browser and gpu <-> renderer IPC, but mostly paves the way for non-renderer clients. Surfaces are kept in a global GpuSurfaceTracker which is just a thread-safe map. BUG=99516 TEST=covered by existing tests. Run chrome, open poster circle (or other accelerated content page). Review URL: http://codereview.chromium.org/9194005 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@118172 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content/browser/gpu')
-rw-r--r--content/browser/gpu/gpu_process_host.cc20
-rw-r--r--content/browser/gpu/gpu_process_host.h12
-rw-r--r--content/browser/gpu/gpu_process_host_ui_shim.cc46
-rw-r--r--content/browser/gpu/gpu_process_host_ui_shim.h3
-rw-r--r--content/browser/gpu/gpu_surface_tracker.cc75
-rw-r--r--content/browser/gpu/gpu_surface_tracker.h81
6 files changed, 193 insertions, 44 deletions
diff --git a/content/browser/gpu/gpu_process_host.cc b/content/browser/gpu/gpu_process_host.cc
index a9b3c15..1b15780 100644
--- a/content/browser/gpu/gpu_process_host.cc
+++ b/content/browser/gpu/gpu_process_host.cc
@@ -403,21 +403,19 @@ void GpuProcessHost::EstablishGpuChannel(
void GpuProcessHost::CreateViewCommandBuffer(
gfx::PluginWindowHandle compositing_surface,
- int32 render_view_id,
- int32 client_id,
+ int surface_id,
+ int client_id,
const GPUCreateCommandBufferConfig& init_params,
const CreateCommandBufferCallback& callback) {
DCHECK(CalledOnValidThread());
#if defined(TOOLKIT_USES_GTK)
- ViewID view_id(client_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);
+ SurfaceRefMap::iterator it = surface_refs_.find(surface_id);
if (it != surface_refs_.end())
surface_ref = (*it).second;
else
@@ -426,11 +424,10 @@ void GpuProcessHost::CreateViewCommandBuffer(
if (compositing_surface != gfx::kNullPluginWindow &&
Send(new GpuMsg_CreateViewCommandBuffer(
- compositing_surface, render_view_id, client_id, init_params))) {
+ compositing_surface, surface_id, client_id, init_params))) {
create_command_buffer_requests_.push(callback);
#if defined(TOOLKIT_USES_GTK)
- surface_refs_.insert(std::pair<ViewID, linked_ptr<SurfaceRef> >(
- view_id, surface_ref));
+ surface_refs_.insert(std::make_pair(surface_id, surface_ref));
#endif
} else {
CreateCommandBufferError(callback, MSG_ROUTING_NONE);
@@ -478,12 +475,9 @@ void GpuProcessHost::OnCommandBufferCreated(const int32 route_id) {
}
}
-void GpuProcessHost::OnDestroyCommandBuffer(
- gfx::PluginWindowHandle window, int32 client_id,
- int32 render_view_id) {
+void GpuProcessHost::OnDestroyCommandBuffer(int32 surface_id) {
#if defined(TOOLKIT_USES_GTK)
- ViewID view_id(client_id, render_view_id);
- SurfaceRefMap::iterator it = surface_refs_.find(view_id);
+ SurfaceRefMap::iterator it = surface_refs_.find(surface_id);
if (it != surface_refs_.end())
surface_refs_.erase(it);
#endif // defined(TOOLKIT_USES_GTK)
diff --git a/content/browser/gpu/gpu_process_host.h b/content/browser/gpu/gpu_process_host.h
index 295803a..29ec0df 100644
--- a/content/browser/gpu/gpu_process_host.h
+++ b/content/browser/gpu/gpu_process_host.h
@@ -75,8 +75,8 @@ class GpuProcessHost : public BrowserChildProcessHost,
// window associated with the given renderer.
void CreateViewCommandBuffer(
gfx::PluginWindowHandle compositing_surface,
- int32 render_view_id,
- int32 client_id,
+ int surface_id,
+ int client_id,
const GPUCreateCommandBufferConfig& init_params,
const CreateCommandBufferCallback& callback);
@@ -100,8 +100,7 @@ class GpuProcessHost : public BrowserChildProcessHost,
// Message handlers.
void OnChannelEstablished(const IPC::ChannelHandle& channel_handle);
void OnCommandBufferCreated(const int32 route_id);
- void OnDestroyCommandBuffer(
- gfx::PluginWindowHandle window, int32 client_id, int32 render_view_id);
+ void OnDestroyCommandBuffer(int32 surface_id);
bool LaunchGpuProcess(const std::string& channel_id);
@@ -125,9 +124,6 @@ class GpuProcessHost : public BrowserChildProcessHost,
std::queue<CreateCommandBufferCallback> create_command_buffer_requests_;
#if defined(TOOLKIT_USES_GTK)
- typedef std::pair<int32 /* client_id */,
- int32 /* render_view_id */> ViewID;
-
// Encapsulates surfaces that we lock when creating view command buffers.
// We release this lock once the command buffer (or associated GPU process)
// is destroyed. This prevents the browser from destroying the surface
@@ -136,7 +132,7 @@ class GpuProcessHost : public BrowserChildProcessHost,
// Multimap is used to simulate reference counting, see comment in
// GpuProcessHostUIShim::CreateViewCommandBuffer.
class SurfaceRef;
- typedef std::multimap<ViewID, linked_ptr<SurfaceRef> > SurfaceRefMap;
+ typedef std::multimap<int, linked_ptr<SurfaceRef> > SurfaceRefMap;
SurfaceRefMap surface_refs_;
#endif
diff --git a/content/browser/gpu/gpu_process_host_ui_shim.cc b/content/browser/gpu/gpu_process_host_ui_shim.cc
index 488553d..7d26d66 100644
--- a/content/browser/gpu/gpu_process_host_ui_shim.cc
+++ b/content/browser/gpu/gpu_process_host_ui_shim.cc
@@ -13,6 +13,7 @@
#include "base/process_util.h"
#include "content/browser/gpu/gpu_data_manager.h"
#include "content/browser/gpu/gpu_process_host.h"
+#include "content/browser/gpu/gpu_surface_tracker.h"
#include "content/browser/renderer_host/render_process_host_impl.h"
#include "content/browser/renderer_host/render_view_host.h"
#include "content/browser/renderer_host/render_widget_host_view.h"
@@ -73,8 +74,13 @@ class ScopedSendOnIOThread {
bool cancelled_;
};
-RenderWidgetHostView* GetRenderWidgetHostViewFromID(int render_process_id,
- int render_widget_id) {
+RenderWidgetHostView* GetRenderWidgetHostViewFromSurfaceID(int surface_id) {
+ int render_process_id = 0;
+ int render_widget_id = 0;
+ if (!GpuSurfaceTracker::Get()->GetRenderWidgetIDForSurface(
+ surface_id, &render_process_id, &render_widget_id))
+ return NULL;
+
content::RenderProcessHost* process =
content::RenderProcessHost::FromID(render_process_id);
if (!process)
@@ -226,8 +232,7 @@ void GpuProcessHostUIShim::OnGraphicsInfoCollected(
#if defined(TOOLKIT_USES_GTK) || defined(OS_WIN)
-void GpuProcessHostUIShim::OnResizeView(int32 client_id,
- int32 render_view_id,
+void GpuProcessHostUIShim::OnResizeView(int32 surface_id,
int32 route_id,
gfx::Size size) {
// Always respond even if the window no longer exists. The GPU process cannot
@@ -237,8 +242,7 @@ void GpuProcessHostUIShim::OnResizeView(int32 client_id,
host_id_,
new AcceleratedSurfaceMsg_ResizeViewACK(route_id));
- RenderWidgetHostView* view = GetRenderWidgetHostViewFromID(client_id,
- render_view_id);
+ RenderWidgetHostView* view = GetRenderWidgetHostViewFromSurfaceID(surface_id);
if (!view)
return;
@@ -278,16 +282,16 @@ void GpuProcessHostUIShim::OnAcceleratedSurfaceNew(
host_id_,
new AcceleratedSurfaceMsg_NewACK(
params.route_id,
- params.surface_id,
+ params.surface_handle,
TransportDIB::DefaultHandleValue()));
- RenderWidgetHostView* view = GetRenderWidgetHostViewFromID(
- params.client_id, params.render_view_id);
+ RenderWidgetHostView* view = GetRenderWidgetHostViewFromSurfaceID(
+ params.surface_id);
if (!view)
return;
- uint64 surface_id = params.surface_id;
- TransportDIB::Handle surface_handle = TransportDIB::DefaultHandleValue();
+ uint64 surface_handle = params.surface_handle;
+ TransportDIB::Handle shm_handle = TransportDIB::DefaultHandleValue();
#if defined(OS_MACOSX)
if (params.create_transport_dib) {
@@ -305,7 +309,7 @@ void GpuProcessHostUIShim::OnAcceleratedSurfaceNew(
local_handle);
// Create a remote handle for the GPU process to map the SHM.
if (!shared_memory->ShareToProcess(0 /* pid, not needed */,
- &surface_handle)) {
+ &shm_handle)) {
return;
}
}
@@ -314,15 +318,15 @@ void GpuProcessHostUIShim::OnAcceleratedSurfaceNew(
view->AcceleratedSurfaceSetIOSurface(params.window,
params.width,
params.height,
- surface_id);
+ surface_handle);
}
#else // defined(UI_COMPOSITOR_IMAGE_TRANSPORT)
view->AcceleratedSurfaceNew(
- params.width, params.height, &surface_id, &surface_handle);
+ params.width, params.height, &surface_handle, &shm_handle);
#endif
delayed_send.Cancel();
Send(new AcceleratedSurfaceMsg_NewACK(
- params.route_id, surface_id, surface_handle));
+ params.route_id, surface_handle, shm_handle));
}
#endif
@@ -336,8 +340,8 @@ void GpuProcessHostUIShim::OnAcceleratedSurfaceBuffersSwapped(
host_id_,
new AcceleratedSurfaceMsg_BuffersSwappedACK(params.route_id));
- RenderWidgetHostView* view = GetRenderWidgetHostViewFromID(
- params.client_id, params.render_view_id);
+ RenderWidgetHostView* view = GetRenderWidgetHostViewFromSurfaceID(
+ params.surface_id);
if (!view)
return;
@@ -356,8 +360,8 @@ void GpuProcessHostUIShim::OnAcceleratedSurfacePostSubBuffer(
host_id_,
new AcceleratedSurfaceMsg_PostSubBufferACK(params.route_id));
- RenderWidgetHostView* view = GetRenderWidgetHostViewFromID(
- params.client_id, params.render_view_id);
+ RenderWidgetHostView* view = GetRenderWidgetHostViewFromSurfaceID(
+ params.surface_id);
if (!view)
return;
@@ -371,8 +375,8 @@ void GpuProcessHostUIShim::OnAcceleratedSurfacePostSubBuffer(
void GpuProcessHostUIShim::OnAcceleratedSurfaceRelease(
const GpuHostMsg_AcceleratedSurfaceRelease_Params& params) {
- RenderWidgetHostView* view = GetRenderWidgetHostViewFromID(
- params.client_id, params.render_view_id);
+ RenderWidgetHostView* view = GetRenderWidgetHostViewFromSurfaceID(
+ params.surface_id);
if (!view)
return;
view->AcceleratedSurfaceRelease(params.identifier);
diff --git a/content/browser/gpu/gpu_process_host_ui_shim.h b/content/browser/gpu/gpu_process_host_ui_shim.h
index 119a802..8b5a5f8 100644
--- a/content/browser/gpu/gpu_process_host_ui_shim.h
+++ b/content/browser/gpu/gpu_process_host_ui_shim.h
@@ -83,8 +83,7 @@ class GpuProcessHostUIShim
void OnLogMessage(int level, const std::string& header,
const std::string& message);
#if defined(TOOLKIT_USES_GTK) || defined(OS_WIN)
- void OnResizeView(int32 client_id,
- int32 render_view_id,
+ void OnResizeView(int32 surface_id,
int32 route_id,
gfx::Size size);
#endif
diff --git a/content/browser/gpu/gpu_surface_tracker.cc b/content/browser/gpu/gpu_surface_tracker.cc
new file mode 100644
index 0000000..280f48f
--- /dev/null
+++ b/content/browser/gpu/gpu_surface_tracker.cc
@@ -0,0 +1,75 @@
+// Copyright (c) 2012 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 "content/browser/gpu/gpu_surface_tracker.h"
+
+#include "base/logging.h"
+
+GpuSurfaceTracker::GpuSurfaceTracker()
+ : next_surface_id_(1) {
+}
+
+GpuSurfaceTracker::~GpuSurfaceTracker() {
+}
+
+GpuSurfaceTracker* GpuSurfaceTracker::GetInstance() {
+ return Singleton<GpuSurfaceTracker>::get();
+}
+
+int GpuSurfaceTracker::AddSurfaceForRenderer(int renderer_id,
+ int render_widget_id) {
+ base::AutoLock lock(lock_);
+ SurfaceInfo info = { renderer_id, render_widget_id, gfx::kNullPluginWindow };
+ int surface_id = next_surface_id_++;
+ surface_map_[surface_id] = info;
+ return surface_id;
+}
+
+int GpuSurfaceTracker::LookupSurfaceForRenderer(int renderer_id,
+ int render_widget_id) {
+ base::AutoLock lock(lock_);
+ for (SurfaceMap::iterator it = surface_map_.begin(); it != surface_map_.end();
+ ++it) {
+ const SurfaceInfo& info = it->second;
+ if (info.renderer_id == renderer_id &&
+ info.render_widget_id == render_widget_id) {
+ return it->first;
+ }
+ }
+ return 0;
+}
+
+void GpuSurfaceTracker::RemoveSurface(int surface_id) {
+ base::AutoLock lock(lock_);
+ DCHECK(surface_map_.find(surface_id) != surface_map_.end());
+ surface_map_.erase(surface_id);
+}
+
+bool GpuSurfaceTracker::GetRenderWidgetIDForSurface(int surface_id,
+ int* renderer_id,
+ int* render_widget_id) {
+ base::AutoLock lock(lock_);
+ SurfaceMap::iterator it = surface_map_.find(surface_id);
+ if (it == surface_map_.end())
+ return false;
+ const SurfaceInfo& info = it->second;
+ *renderer_id = info.renderer_id;
+ *render_widget_id = info.render_widget_id;
+ return true;
+}
+
+void GpuSurfaceTracker::SetSurfaceHandle(int surface_id,
+ gfx::PluginWindowHandle handle) {
+ base::AutoLock lock(lock_);
+ DCHECK(surface_map_.find(surface_id) != surface_map_.end());
+ SurfaceInfo& info = surface_map_[surface_id];
+ info.handle = handle;
+}
+
+gfx::PluginWindowHandle GpuSurfaceTracker::GetSurfaceHandle(int surface_id) {
+ base::AutoLock lock(lock_);
+ DCHECK(surface_map_.find(surface_id) != surface_map_.end());
+ return surface_map_[surface_id].handle;
+}
+
diff --git a/content/browser/gpu/gpu_surface_tracker.h b/content/browser/gpu/gpu_surface_tracker.h
new file mode 100644
index 0000000..17fa13a
--- /dev/null
+++ b/content/browser/gpu/gpu_surface_tracker.h
@@ -0,0 +1,81 @@
+// Copyright (c) 2012 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.
+
+#ifndef CONTENT_BROWSER_GPU_GPU_SURFACE_TRACKER_H_
+#define CONTENT_BROWSER_GPU_GPU_SURFACE_TRACKER_H_
+
+#include <map>
+
+#include "base/basictypes.h"
+#include "base/memory/singleton.h"
+#include "base/synchronization/lock.h"
+#include "ui/gfx/native_widget_types.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.
+// All calls to and from the GPU process, with the exception of
+// CreateViewCommandBuffer, refer to the rendering surface by its ID.
+// This class is thread safe.
+//
+// Note: The ID can exist before the actual native handle for the surface is
+// created, for example to allow giving a reference to it to a renderer, so that
+// it is unamibiguously identified.
+class GpuSurfaceTracker {
+ public:
+ // Gets the global instance of the surface tracker.
+ static GpuSurfaceTracker* Get() { return GetInstance(); }
+
+ // Adds a surface for a given RenderWidgetHost. |renderer_id| is the renderer
+ // process ID, |render_widget_id| is the RenderWidgetHost route id within that
+ // renderer. Returns the surface ID.
+ int AddSurfaceForRenderer(int renderer_id, int render_widget_id);
+
+ // Looks up a surface for a given RenderWidgetHost. Returns the surface
+ // ID, or 0 if not found.
+ // Note: This is an O(N) lookup.
+ int LookupSurfaceForRenderer(int renderer_id, int render_widget_id);
+
+ // Removes a given existing surface.
+ void RemoveSurface(int surface_id);
+
+ // Gets the renderer process ID and RenderWidgetHost route id for a given
+ // surface, returning true if the surface is found (and corresponds to a
+ // RenderWidgetHost), or false if not.
+ bool GetRenderWidgetIDForSurface(int surface_id,
+ int* renderer_id,
+ int* render_widget_id);
+
+ // Sets the native handle for the given surface.
+ // Note: This is an O(log N) lookup.
+ void SetSurfaceHandle(int surface_id, gfx::PluginWindowHandle handle);
+
+ // Gets the native handle for the given surface.
+ // Note: This is an O(log N) lookup.
+ gfx::PluginWindowHandle GetSurfaceHandle(int surface_id);
+
+ // Gets the global instance of the surface tracker. Identical to Get(), but
+ // named that way for the implementation of Singleton.
+ static GpuSurfaceTracker* GetInstance();
+
+ private:
+ struct SurfaceInfo {
+ int renderer_id;
+ int render_widget_id;
+ gfx::PluginWindowHandle handle;
+ };
+ typedef std::map<int, SurfaceInfo> SurfaceMap;
+
+ friend struct DefaultSingletonTraits<GpuSurfaceTracker>;
+
+ GpuSurfaceTracker();
+ ~GpuSurfaceTracker();
+
+ base::Lock lock_;
+ SurfaceMap surface_map_;
+ int next_surface_id_;
+
+ DISALLOW_COPY_AND_ASSIGN(GpuSurfaceTracker);
+};
+
+#endif // CONTENT_BROWSER_GPU_GPU_SURFACE_TRACKER_H_