diff options
author | piman@chromium.org <piman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-01-18 22:29:56 +0000 |
---|---|---|
committer | piman@chromium.org <piman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-01-18 22:29:56 +0000 |
commit | 9f4f3322e7c9a5feedd5ca2b986daf2f8d5b8d3d (patch) | |
tree | a67a3d0397a03e12ee51aa8720f612c62c20e936 /content/browser/gpu | |
parent | a3102766e725636ad23ad99faa1e8a481a1129e7 (diff) | |
download | chromium_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.cc | 20 | ||||
-rw-r--r-- | content/browser/gpu/gpu_process_host.h | 12 | ||||
-rw-r--r-- | content/browser/gpu/gpu_process_host_ui_shim.cc | 46 | ||||
-rw-r--r-- | content/browser/gpu/gpu_process_host_ui_shim.h | 3 | ||||
-rw-r--r-- | content/browser/gpu/gpu_surface_tracker.cc | 75 | ||||
-rw-r--r-- | content/browser/gpu/gpu_surface_tracker.h | 81 |
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_ |