diff options
Diffstat (limited to 'chrome')
11 files changed, 80 insertions, 108 deletions
diff --git a/chrome/browser/gpu_process_host_ui_shim.cc b/chrome/browser/gpu_process_host_ui_shim.cc index d4e8fc9..4d38ad1 100644 --- a/chrome/browser/gpu_process_host_ui_shim.cc +++ b/chrome/browser/gpu_process_host_ui_shim.cc @@ -112,52 +112,33 @@ void RouteToGpuProcessHostUIShimTask::Run() { ui_shim->OnMessageReceived(msg_); } -class GpuProcessHostUIShim::ViewSurface { +#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 GpuProcessHostUIShim::SurfaceRef { public: - explicit ViewSurface(ViewID view_id); - ~ViewSurface(); - gfx::PluginWindowHandle surface() { return surface_; } + explicit SurfaceRef(gfx::PluginWindowHandle surface); + ~SurfaceRef(); private: - RenderWidgetHostView* GetRenderWidgetHostView(); - ViewID view_id_; gfx::PluginWindowHandle surface_; }; -GpuProcessHostUIShim::ViewSurface::ViewSurface(ViewID view_id) - : view_id_(view_id), surface_(gfx::kNullPluginWindow) { - RenderWidgetHostView* view = GetRenderWidgetHostView(); - if (view) - surface_ = view->AcquireCompositingSurface(); -} - -GpuProcessHostUIShim::ViewSurface::~ViewSurface() { - if (!surface_) - return; - - RenderWidgetHostView* view = GetRenderWidgetHostView(); - if (view) - view->ReleaseCompositingSurface(surface_); -} - -// We do separate lookups for the RenderWidgetHostView when acquiring -// and releasing surfaces (rather than caching) because the -// RenderWidgetHostView could die without warning. In such a case, -// it's the RenderWidgetHostView's responsibility to cleanup. -RenderWidgetHostView* GpuProcessHostUIShim::ViewSurface:: - GetRenderWidgetHostView() { - RenderProcessHost* process = RenderProcessHost::FromID(view_id_.first); - RenderWidgetHost* host = NULL; - if (process) { - host = static_cast<RenderWidgetHost*>( - process->GetListenerByID(view_id_.second)); +GpuProcessHostUIShim::SurfaceRef::SurfaceRef(gfx::PluginWindowHandle surface) + : surface_(surface) { + GtkNativeViewManager* manager = GtkNativeViewManager::GetInstance(); + if (!manager->AddRefPermanentXID(surface_)) { + LOG(ERROR) << "Surface " << surface << " cannot be referenced."; } +} - RenderWidgetHostView* view = NULL; - if (host) - view = host->view(); - - return view; +GpuProcessHostUIShim::SurfaceRef::~SurfaceRef() { + // TODO(backer): ReleasePermanentXID has to be done on the UI thread. + // Post task to release once we move this code to the IO thread. + GtkNativeViewManager* manager = GtkNativeViewManager::GetInstance(); + manager->ReleasePermanentXID(surface_); } +#endif // defined(OS_LINUX) GpuProcessHostUIShim::GpuProcessHostUIShim(int host_id, content::CauseForGpuLaunch cause_for_gpu_launch) @@ -418,31 +399,37 @@ void GpuProcessHostUIShim::Synchronize(SynchronizeCallback* callback) { } void GpuProcessHostUIShim::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<ViewSurface> view_surface; - ViewSurfaceMap::iterator it = acquired_surfaces_.find(view_id); - if (it != acquired_surfaces_.end()) - view_surface = (*it).second; + linked_ptr<SurfaceRef> surface_ref; + SurfaceRefMap::iterator it = surface_refs_.find(view_id); + if (it != surface_refs_.end()) + surface_ref = (*it).second; else - view_surface.reset(new ViewSurface(view_id)); + surface_ref.reset(new SurfaceRef(compositing_surface)); +#endif // defined(OS_LINUX) - if (view_surface->surface() != gfx::kNullPluginWindow && + if (compositing_surface != gfx::kNullPluginWindow && Send(new GpuMsg_CreateViewCommandBuffer( - view_surface->surface(), render_view_id, renderer_id, init_params))) { + compositing_surface, render_view_id, renderer_id, init_params))) { create_command_buffer_requests_.push(wrapped_callback); - acquired_surfaces_.insert(std::pair<ViewID, linked_ptr<ViewSurface> >( - view_id, view_surface)); +#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); } @@ -594,10 +581,12 @@ void GpuProcessHostUIShim::OnCommandBufferCreated(const int32 route_id) { void GpuProcessHostUIShim::OnDestroyCommandBuffer( gfx::PluginWindowHandle window, int32 renderer_id, int32 render_view_id) { +#if defined(OS_LINUX) ViewID view_id(renderer_id, render_view_id); - ViewSurfaceMap::iterator it = acquired_surfaces_.find(view_id); - if (it != acquired_surfaces_.end()) - acquired_surfaces_.erase(it); + SurfaceRefMap::iterator it = surface_refs_.find(view_id); + if (it != surface_refs_.end()) + surface_refs_.erase(it); +#endif // defined(OS_LINUX) } void GpuProcessHostUIShim::OnGraphicsInfoCollected(const GPUInfo& gpu_info) { diff --git a/chrome/browser/gpu_process_host_ui_shim.h b/chrome/browser/gpu_process_host_ui_shim.h index 8bcdb23..cd834a5 100644 --- a/chrome/browser/gpu_process_host_ui_shim.h +++ b/chrome/browser/gpu_process_host_ui_shim.h @@ -122,6 +122,7 @@ class GpuProcessHostUIShim // Tells the GPU process to create a new command buffer that draws into the // window associated with the given renderer. void CreateViewCommandBuffer( + gfx::PluginWindowHandle compositing_surface, int32 render_view_id, int32 renderer_id, const GPUCreateCommandBufferConfig& init_params, @@ -197,16 +198,21 @@ class GpuProcessHostUIShim std::queue<linked_ptr<CreateCommandBufferCallback> > create_command_buffer_requests_; +#if defined(OS_LINUX) typedef std::pair<int32 /* renderer_id */, int32 /* render_view_id */> ViewID; - // Encapsulates surfaces that we acquire when creating view command buffers. - // We assume that a render view has at most 1 such surface associated - // with it. Multimap is used to simulate reference counting, see comment in + // 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 + // while the GPU process is drawing to it. + + // Multimap is used to simulate reference counting, see comment in // GpuProcessHostUIShim::CreateViewCommandBuffer. - class ViewSurface; - typedef std::multimap<ViewID, linked_ptr<ViewSurface> > ViewSurfaceMap; - ViewSurfaceMap acquired_surfaces_; + class SurfaceRef; + typedef std::multimap<ViewID, linked_ptr<SurfaceRef> > SurfaceRefMap; + SurfaceRefMap surface_refs_; +#endif // In single process and in process GPU mode, this references the // GpuChannelManager or null otherwise. It must be called and deleted on the diff --git a/chrome/browser/renderer_host/render_widget_host_view_gtk.cc b/chrome/browser/renderer_host/render_widget_host_view_gtk.cc index 3ea582d..9a5a340 100644 --- a/chrome/browser/renderer_host/render_widget_host_view_gtk.cc +++ b/chrome/browser/renderer_host/render_widget_host_view_gtk.cc @@ -513,7 +513,7 @@ RenderWidgetHostViewGtk::RenderWidgetHostViewGtk(RenderWidgetHost* widget_host) destroy_handler_id_(0), dragged_at_horizontal_edge_(0), dragged_at_vertical_edge_(0), - accelerated_surface_acquired_(false), + compositing_surface_(gfx::kNullPluginWindow), last_mouse_down_(NULL) { host_->set_view(this); } @@ -770,11 +770,9 @@ void RenderWidgetHostViewGtk::RenderViewGone(base::TerminationStatus status, } void RenderWidgetHostViewGtk::Destroy() { - if (accelerated_surface_acquired_) { + if (compositing_surface_ != gfx::kNullPluginWindow) { GtkNativeViewManager* manager = GtkNativeViewManager::GetInstance(); - gfx::NativeViewId view_id = gfx::IdFromNativeView(GetNativeView()); - gfx::PluginWindowHandle surface = manager->GetXIDForId(&surface, view_id); - manager->ReleasePermanentXID(surface); + manager->ReleasePermanentXID(compositing_surface_); } if (do_x_grab_) { @@ -1128,24 +1126,16 @@ void RenderWidgetHostViewGtk::AcceleratedCompositingActivated(bool activated) { gtk_preserve_window_delegate_resize(widget, activated); } -gfx::PluginWindowHandle RenderWidgetHostViewGtk::AcquireCompositingSurface() { - GtkNativeViewManager* manager = GtkNativeViewManager::GetInstance(); - gfx::PluginWindowHandle surface = gfx::kNullPluginWindow; - gfx::NativeViewId view_id = gfx::IdFromNativeView(GetNativeView()); +gfx::PluginWindowHandle RenderWidgetHostViewGtk::GetCompositingSurface() { + if (compositing_surface_ == gfx::kNullPluginWindow) { + GtkNativeViewManager* manager = GtkNativeViewManager::GetInstance(); + gfx::NativeViewId view_id = gfx::IdFromNativeView(GetNativeView()); - if (!manager->GetPermanentXIDForId(&surface, view_id)) { - DLOG(ERROR) << "Can't find XID for view id " << view_id; - } else { - accelerated_surface_acquired_ = true; + if (!manager->GetPermanentXIDForId(&compositing_surface_, view_id)) { + DLOG(ERROR) << "Can't find XID for view id " << view_id; + } } - return surface; -} - -void RenderWidgetHostViewGtk::ReleaseCompositingSurface( - gfx::PluginWindowHandle surface) { - GtkNativeViewManager* manager = GtkNativeViewManager::GetInstance(); - manager->ReleasePermanentXID(surface); - accelerated_surface_acquired_ = false; + return compositing_surface_; } void RenderWidgetHostViewGtk::ForwardKeyboardEvent( diff --git a/chrome/browser/renderer_host/render_widget_host_view_gtk.h b/chrome/browser/renderer_host/render_widget_host_view_gtk.h index a0038fd..0cf950a 100644 --- a/chrome/browser/renderer_host/render_widget_host_view_gtk.h +++ b/chrome/browser/renderer_host/render_widget_host_view_gtk.h @@ -94,8 +94,7 @@ class RenderWidgetHostViewGtk : public RenderWidgetHostView, virtual bool ContainsNativeView(gfx::NativeView native_view) const; virtual void AcceleratedCompositingActivated(bool activated); - virtual gfx::PluginWindowHandle AcquireCompositingSurface(); - virtual void ReleaseCompositingSurface(gfx::PluginWindowHandle surface); + virtual gfx::PluginWindowHandle GetCompositingSurface(); // ui::AnimationDelegate implementation. virtual void AnimationEnded(const ui::Animation* animation); @@ -248,7 +247,7 @@ class RenderWidgetHostViewGtk : public RenderWidgetHostView, // indicate the top edge, positive the bottom. int dragged_at_vertical_edge_; - bool accelerated_surface_acquired_; + gfx::PluginWindowHandle compositing_surface_; // The event for the last mouse down we handled. We need this for context // menus and drags. diff --git a/chrome/browser/renderer_host/render_widget_host_view_mac.h b/chrome/browser/renderer_host/render_widget_host_view_mac.h index eee516b..150c448 100644 --- a/chrome/browser/renderer_host/render_widget_host_view_mac.h +++ b/chrome/browser/renderer_host/render_widget_host_view_mac.h @@ -268,8 +268,7 @@ class RenderWidgetHostViewMac : public RenderWidgetHostView { uint64 swap_buffers_count); virtual void GpuRenderingStateDidChange(); - virtual gfx::PluginWindowHandle AcquireCompositingSurface(); - virtual void ReleaseCompositingSurface(gfx::PluginWindowHandle surface); + virtual gfx::PluginWindowHandle GetCompositingSurface(); void DrawAcceleratedSurfaceInstance( CGLContextObj context, @@ -388,6 +387,8 @@ class RenderWidgetHostViewMac : public RenderWidgetHostView { // set when the gpu widget needs to be hidden once a paint is completed. bool needs_gpu_visibility_update_after_repaint_; + gfx::PluginWindowHandle compositing_surface_; + DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostViewMac); }; diff --git a/chrome/browser/renderer_host/render_widget_host_view_mac.mm b/chrome/browser/renderer_host/render_widget_host_view_mac.mm index 350a53b..3708e09 100644 --- a/chrome/browser/renderer_host/render_widget_host_view_mac.mm +++ b/chrome/browser/renderer_host/render_widget_host_view_mac.mm @@ -595,7 +595,8 @@ RenderWidgetHostViewMac::RenderWidgetHostViewMac(RenderWidgetHost* widget) is_loading_(false), is_hidden_(false), shutdown_factory_(this), - needs_gpu_visibility_update_after_repaint_(false) { + needs_gpu_visibility_update_after_repaint_(false), + compositing_surface_(gfx::kNullPluginWindow) { // |cocoa_view_| owns us and we will be deleted when |cocoa_view_| goes away. // Since we autorelease it, our caller must put |native_view()| into the view // hierarchy right after calling us. @@ -1102,8 +1103,7 @@ void RenderWidgetHostViewMac::DeallocFakePluginWindowHandle( plugin_container_manager_.IsRootContainer(window)) { GpuProcessHostUIShim* ui_shim = GpuProcessHostUIShim::GetForRenderer( render_widget_host_->process()->id(), - content:: - CAUSE_FOR_GPU_LAUNCH_RENDERWIDGETHOSTVIEWMAC_DEALLOCFAKEPLUGINWINDOWHANDLE); + content::CAUSE_FOR_GPU_LAUNCH_NO_LAUNCH); if (ui_shim) { ui_shim->DidDestroyAcceleratedSurface( render_widget_host_->process()->id(), @@ -1297,13 +1297,11 @@ void RenderWidgetHostViewMac::GpuRenderingStateDidChange() { } } -gfx::PluginWindowHandle RenderWidgetHostViewMac::AcquireCompositingSurface() { - return AllocateFakePluginWindowHandle(/*opaque=*/true, /*root=*/true); -} - -void RenderWidgetHostViewMac::ReleaseCompositingSurface( - gfx::PluginWindowHandle surface) { - DestroyFakePluginWindowHandle(surface); +gfx::PluginWindowHandle RenderWidgetHostViewMac::GetCompositingSurface() { + if (compositing_surface_ == gfx::kNullPluginWindow) + compositing_surface_ = AllocateFakePluginWindowHandle( + /*opaque=*/true, /*root=*/true); + return compositing_surface_; } void RenderWidgetHostViewMac::DrawAcceleratedSurfaceInstance( diff --git a/chrome/browser/renderer_host/render_widget_host_view_views.cc b/chrome/browser/renderer_host/render_widget_host_view_views.cc index 47dc659..ee2c43f 100644 --- a/chrome/browser/renderer_host/render_widget_host_view_views.cc +++ b/chrome/browser/renderer_host/render_widget_host_view_views.cc @@ -415,7 +415,7 @@ void RenderWidgetHostViewViews::AcceleratedCompositingActivated( NOTIMPLEMENTED(); } -gfx::PluginWindowHandle RenderWidgetHostViewViews::AcquireCompositingSurface() { +gfx::PluginWindowHandle RenderWidgetHostViewViews::GetCompositingSurface() { GtkNativeViewManager* manager = GtkNativeViewManager::GetInstance(); gfx::PluginWindowHandle surface = gfx::kNullPluginWindow; gfx::NativeViewId view_id = gfx::IdFromNativeView(GetInnerNativeView()); @@ -426,10 +426,6 @@ gfx::PluginWindowHandle RenderWidgetHostViewViews::AcquireCompositingSurface() { return surface; } -void RenderWidgetHostViewViews::ReleaseCompositingSurface( - gfx::PluginWindowHandle surface) { -} - gfx::NativeView RenderWidgetHostViewViews::GetInnerNativeView() const { // TODO(sad): Ideally this function should be equivalent to GetNativeView, and // WidgetGtk-specific function call should not be necessary. diff --git a/chrome/browser/renderer_host/render_widget_host_view_views.h b/chrome/browser/renderer_host/render_widget_host_view_views.h index 014844c..177f50b 100644 --- a/chrome/browser/renderer_host/render_widget_host_view_views.h +++ b/chrome/browser/renderer_host/render_widget_host_view_views.h @@ -80,9 +80,7 @@ class RenderWidgetHostViewViews : public RenderWidgetHostView, bool animate) OVERRIDE; virtual bool ContainsNativeView(gfx::NativeView native_view) const OVERRIDE; virtual void AcceleratedCompositingActivated(bool activated) OVERRIDE; - virtual gfx::PluginWindowHandle AcquireCompositingSurface() OVERRIDE; - virtual void ReleaseCompositingSurface( - gfx::PluginWindowHandle surface) OVERRIDE; + virtual gfx::PluginWindowHandle GetCompositingSurface() OVERRIDE; // On some systems, there can be two native views, where an outer native view // contains the inner native view (e.g. when using GTK+). This returns the diff --git a/chrome/browser/renderer_host/render_widget_host_view_win.cc b/chrome/browser/renderer_host/render_widget_host_view_win.cc index 30cf793..a889910 100644 --- a/chrome/browser/renderer_host/render_widget_host_view_win.cc +++ b/chrome/browser/renderer_host/render_widget_host_view_win.cc @@ -1514,7 +1514,7 @@ static LRESULT CALLBACK CompositorHostWindowProc(HWND hWnd, UINT message, // Creates a HWND within the RenderWidgetHostView that will serve as a host // for a HWND that the GPU process will create. The host window is used // to Z-position the GPU's window relative to other plugin windows. -gfx::PluginWindowHandle RenderWidgetHostViewWin::AcquireCompositingSurface() { +gfx::PluginWindowHandle RenderWidgetHostViewWin::GetCompositingSurface() { // If the window has been created, don't recreate it a second time if (compositor_host_window_) return compositor_host_window_; @@ -1554,11 +1554,6 @@ gfx::PluginWindowHandle RenderWidgetHostViewWin::AcquireCompositingSurface() { return static_cast<gfx::PluginWindowHandle>(compositor_host_window_); } -void RenderWidgetHostViewWin::ReleaseCompositingSurface( - gfx::PluginWindowHandle surface) { - ShowCompositorHostWindow(false); -} - void RenderWidgetHostViewWin::ShowCompositorHostWindow(bool show) { // When we first create the compositor, we will get a show request from // the renderer before we have gotten the create request from the GPU. In this diff --git a/chrome/browser/renderer_host/render_widget_host_view_win.h b/chrome/browser/renderer_host/render_widget_host_view_win.h index e2d3aa8..d90487c 100644 --- a/chrome/browser/renderer_host/render_widget_host_view_win.h +++ b/chrome/browser/renderer_host/render_widget_host_view_win.h @@ -161,8 +161,7 @@ class RenderWidgetHostViewWin virtual bool ContainsNativeView(gfx::NativeView native_view) const; virtual void SetVisuallyDeemphasized(const SkColor* color, bool animate); - virtual gfx::PluginWindowHandle AcquireCompositingSurface(); - virtual void ReleaseCompositingSurface(gfx::PluginWindowHandle surface); + virtual gfx::PluginWindowHandle GetCompositingSurface(); virtual void ShowCompositorHostWindow(bool show); virtual void OnAccessibilityNotifications( diff --git a/chrome/test/render_view_test.cc b/chrome/test/render_view_test.cc index ebd16fd..a932d20 100644 --- a/chrome/test/render_view_test.cc +++ b/chrome/test/render_view_test.cc @@ -134,6 +134,7 @@ void RenderViewTest::SetUp() { // This needs to pass the mock render thread to the view. view_ = RenderView::Create(&render_thread_, 0, + gfx::kNullPluginWindow, kOpenerId, RendererPreferences(), WebPreferences(), |