summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/gpu_process_host_ui_shim.cc89
-rw-r--r--chrome/browser/gpu_process_host_ui_shim.h18
-rw-r--r--chrome/browser/renderer_host/render_widget_host_view_gtk.cc32
-rw-r--r--chrome/browser/renderer_host/render_widget_host_view_gtk.h5
-rw-r--r--chrome/browser/renderer_host/render_widget_host_view_mac.h5
-rw-r--r--chrome/browser/renderer_host/render_widget_host_view_mac.mm18
-rw-r--r--chrome/browser/renderer_host/render_widget_host_view_views.cc6
-rw-r--r--chrome/browser/renderer_host/render_widget_host_view_views.h4
-rw-r--r--chrome/browser/renderer_host/render_widget_host_view_win.cc7
-rw-r--r--chrome/browser/renderer_host/render_widget_host_view_win.h3
-rw-r--r--chrome/test/render_view_test.cc1
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(),