summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorbacker@chromium.org <backer@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-11-25 17:50:00 +0000
committerbacker@chromium.org <backer@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-11-25 17:50:00 +0000
commit7ff86b93008f19aaddac784323ce4117d6725aa0 (patch)
treead24f5498395eb8a98232134ee23d092b7ee1240 /chrome
parent49952775c67f130e37d3d892f17657f56efbbe7a (diff)
downloadchromium_src-7ff86b93008f19aaddac784323ce4117d6725aa0.zip
chromium_src-7ff86b93008f19aaddac784323ce4117d6725aa0.tar.gz
chromium_src-7ff86b93008f19aaddac784323ce4117d6725aa0.tar.bz2
Resize synchronization for Linux.
This patch makes synchronous calls from the GPU to the Browser process to resize windows. It must be synchronous because we must be sure when the resize happens, it must be initiated by the GPU because we have to time the resize with GL drawing, and the resize must be done by the Browser because of how GDK/GTK is structured. Specifically, when a window that a GL context is associated with is resized, the back buffer gets blanked. So it is important that we synchronize the resize with the drawing to the back buffer. On Linux, the X window that we are drawing to is wrapped in a GdkWindow inside the Browser process. GDK/GTK assumes that all changes to the window happen via GDK calls. In particular, the size of the window is cached inside the GdkWindow object so that it does not have to make a call to the X server in order to get window geometry. Unfortunately, this necessitates resizing the window inside of the Browser process. For more discussion of this approach and (some unsuccessfully attempted) alternatives see https://docs.google.com/a/google.com/document/d/1ZNouL-X_Ml1x8sqy-sofz63pDAeo36VWi_yQihaE2YI/edit?hl=en This patch set uncovered another bug: - open in two separate windows http://webkit.org/blog/386/3d-transforms/ and http://webkit.org/blog-files/3d-transforms/poster-circle.html - resize the former until it is smallish - watch the root layer of the former show up as the root layer of the later. To my knowledge, this is first trigger of this bug. If and when this patch is accepted, I will file the bug. BUG=http://code.google.com/p/chromium/issues/detail?id=54430 TEST=Go to http://peter.sh/2010/06/chromium-now-features-gpu-acceleration-and-css-3d-transforms/ . Rotate Z with the slider to trigger the compositor. Resize the window. The resize may be janky (we're uploading large textures), but it should display properly. Contributed by backer@chromium.org Review URL: http://codereview.chromium.org/5105006 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@67416 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/gpu_process_host.cc31
-rw-r--r--chrome/browser/gpu_process_host.h5
-rw-r--r--chrome/browser/renderer_host/render_widget_host.cc2
-rw-r--r--chrome/browser/renderer_host/render_widget_host_view.h1
-rw-r--r--chrome/browser/renderer_host/render_widget_host_view_gtk.cc7
-rw-r--r--chrome/browser/renderer_host/render_widget_host_view_gtk.h1
-rw-r--r--chrome/browser/renderer_host/test/test_render_view_host.h1
-rw-r--r--chrome/common/gpu_messages_internal.h6
-rw-r--r--chrome/gpu/gpu_command_buffer_stub.cc17
-rw-r--r--chrome/gpu/gpu_command_buffer_stub.h4
10 files changed, 74 insertions, 1 deletions
diff --git a/chrome/browser/gpu_process_host.cc b/chrome/browser/gpu_process_host.cc
index 2f5a8b7..bf9c1c9 100644
--- a/chrome/browser/gpu_process_host.cc
+++ b/chrome/browser/gpu_process_host.cc
@@ -23,8 +23,11 @@
#include "media/base/media_switches.h"
#if defined(OS_LINUX)
+#include <gdk/gdkwindow.h>
+#include <gdk/gdkx.h>
#include "app/x11_util.h"
#include "gfx/gtk_native_view_id_manager.h"
+#include "gfx/size.h"
#endif
namespace {
@@ -168,6 +171,7 @@ void GpuProcessHost::OnControlMessageReceived(const IPC::Message& message) {
IPC_MESSAGE_HANDLER(GpuHostMsg_SynchronizeReply, OnSynchronizeReply)
#if defined(OS_LINUX)
IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuHostMsg_GetViewXID, OnGetViewXID)
+ IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuHostMsg_ResizeXID, OnResizeXID)
#elif defined(OS_MACOSX)
IPC_MESSAGE_HANDLER(GpuHostMsg_AcceleratedSurfaceSetIOSurface,
OnAcceleratedSurfaceSetIOSurface)
@@ -221,7 +225,24 @@ void GetViewXIDDispatcher(gfx::NativeViewId id, IPC::Message* reply_msg) {
NewRunnableFunction(&SendDelayedReply, reply_msg));
}
-} // namespace
+void ResizeXIDDispatcher(unsigned long xid, gfx::Size size,
+ IPC::Message *reply_msg) {
+ GdkWindow* window = reinterpret_cast<GdkWindow*>(gdk_xid_table_lookup(xid));
+ if (window) {
+ Display* display = GDK_WINDOW_XDISPLAY(window);
+ gdk_window_resize(window, size.width(), size.height());
+ XSync(display, False);
+ }
+
+ GpuHostMsg_ResizeXID::WriteReplyParams(reply_msg, (window != NULL));
+
+ // Have to reply from IO thread.
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ NewRunnableFunction(&SendDelayedReply, reply_msg));
+}
+
+} // namespace
void GpuProcessHost::OnGetViewXID(gfx::NativeViewId id,
IPC::Message *reply_msg) {
@@ -231,6 +252,14 @@ void GpuProcessHost::OnGetViewXID(gfx::NativeViewId id,
NewRunnableFunction(&GetViewXIDDispatcher, id, reply_msg));
}
+void GpuProcessHost::OnResizeXID(unsigned long xid, gfx::Size size,
+ IPC::Message *reply_msg) {
+ // Have to resize the window from UI thread.
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ NewRunnableFunction(&ResizeXIDDispatcher, xid, size, reply_msg));
+}
+
#elif defined(OS_MACOSX)
namespace {
diff --git a/chrome/browser/gpu_process_host.h b/chrome/browser/gpu_process_host.h
index c7492eb..69969c6 100644
--- a/chrome/browser/gpu_process_host.h
+++ b/chrome/browser/gpu_process_host.h
@@ -18,6 +18,10 @@ struct GpuHostMsg_AcceleratedSurfaceSetIOSurface_Params;
class GPUInfo;
class ResourceMessageFilter;
+namespace gfx {
+class Size;
+}
+
namespace IPC {
struct ChannelHandle;
class Message;
@@ -82,6 +86,7 @@ class GpuProcessHost : public BrowserChildProcessHost, public NonThreadSafe {
void OnSynchronizeReply();
#if defined(OS_LINUX)
void OnGetViewXID(gfx::NativeViewId id, IPC::Message* reply_msg);
+ void OnResizeXID(unsigned long xid, gfx::Size size, IPC::Message* reply_msg);
#elif defined(OS_MACOSX)
void OnAcceleratedSurfaceSetIOSurface(
const GpuHostMsg_AcceleratedSurfaceSetIOSurface_Params& params);
diff --git a/chrome/browser/renderer_host/render_widget_host.cc b/chrome/browser/renderer_host/render_widget_host.cc
index 7e6f2ce..2617cbd 100644
--- a/chrome/browser/renderer_host/render_widget_host.cc
+++ b/chrome/browser/renderer_host/render_widget_host.cc
@@ -985,6 +985,8 @@ void RenderWidgetHost::OnMsgGpuRenderingActivated(bool activated) {
#if defined(OS_MACOSX)
if (old_state != is_gpu_rendering_active_ && view_)
view_->GpuRenderingStateDidChange();
+#elif defined(TOOLKIT_USES_GTK)
+ view_->AcceleratedCompositingActivated(activated);
#endif
}
diff --git a/chrome/browser/renderer_host/render_widget_host_view.h b/chrome/browser/renderer_host/render_widget_host_view.h
index 1c8bb13..2c99926 100644
--- a/chrome/browser/renderer_host/render_widget_host_view.h
+++ b/chrome/browser/renderer_host/render_widget_host_view.h
@@ -233,6 +233,7 @@ class RenderWidgetHostView {
#if defined(TOOLKIT_USES_GTK)
virtual void CreatePluginContainer(gfx::PluginWindowHandle id) = 0;
virtual void DestroyPluginContainer(gfx::PluginWindowHandle id) = 0;
+ virtual void AcceleratedCompositingActivated(bool activated) = 0;
#endif
// Toggles visual muting of the render view area. This is on when a
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 67b1a00..bf39966 100644
--- a/chrome/browser/renderer_host/render_widget_host_view_gtk.cc
+++ b/chrome/browser/renderer_host/render_widget_host_view_gtk.cc
@@ -1046,6 +1046,13 @@ bool RenderWidgetHostViewGtk::ContainsNativeView(
return false;
}
+void RenderWidgetHostViewGtk::AcceleratedCompositingActivated(bool activated) {
+ GtkPreserveWindow* widget =
+ reinterpret_cast<GtkPreserveWindow*>(view_.get());
+
+ gtk_preserve_window_delegate_resize(widget, activated);
+}
+
void RenderWidgetHostViewGtk::ForwardKeyboardEvent(
const NativeWebKeyboardEvent& event) {
if (!host_)
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 1817569..0665558 100644
--- a/chrome/browser/renderer_host/render_widget_host_view_gtk.h
+++ b/chrome/browser/renderer_host/render_widget_host_view_gtk.h
@@ -86,6 +86,7 @@ class RenderWidgetHostViewGtk : public RenderWidgetHostView {
virtual void DestroyPluginContainer(gfx::PluginWindowHandle id);
virtual void SetVisuallyDeemphasized(bool deemphasized);
virtual bool ContainsNativeView(gfx::NativeView native_view) const;
+ virtual void AcceleratedCompositingActivated(bool activated);
gfx::NativeView native_view() const { return view_.get(); }
diff --git a/chrome/browser/renderer_host/test/test_render_view_host.h b/chrome/browser/renderer_host/test/test_render_view_host.h
index fe58b68..4f262f4 100644
--- a/chrome/browser/renderer_host/test/test_render_view_host.h
+++ b/chrome/browser/renderer_host/test/test_render_view_host.h
@@ -126,6 +126,7 @@ class TestRenderWidgetHostView : public RenderWidgetHostView {
#if defined(TOOLKIT_USES_GTK)
virtual void CreatePluginContainer(gfx::PluginWindowHandle id) { }
virtual void DestroyPluginContainer(gfx::PluginWindowHandle id) { }
+ virtual void AcceleratedCompositingActivated(bool activated) { }
#endif
virtual bool ContainsNativeView(gfx::NativeView native_view) const {
diff --git a/chrome/common/gpu_messages_internal.h b/chrome/common/gpu_messages_internal.h
index 1b51c03..300cbef 100644
--- a/chrome/common/gpu_messages_internal.h
+++ b/chrome/common/gpu_messages_internal.h
@@ -81,6 +81,12 @@ IPC_BEGIN_MESSAGES(GpuHost)
IPC_SYNC_MESSAGE_CONTROL1_1(GpuHostMsg_GetViewXID,
gfx::NativeViewId, /* view */
unsigned long /* xid */)
+
+ IPC_SYNC_MESSAGE_CONTROL2_1(GpuHostMsg_ResizeXID,
+ unsigned long, /* xid */
+ gfx::Size, /* size */
+ bool /* success */)
+
#elif defined(OS_MACOSX)
// This message, used on Mac OS X 10.6 and later (where IOSurface is
// supported), is sent from the GPU process to the browser to indicate that a
diff --git a/chrome/gpu/gpu_command_buffer_stub.cc b/chrome/gpu/gpu_command_buffer_stub.cc
index 2834c00..1adb22c 100644
--- a/chrome/gpu/gpu_command_buffer_stub.cc
+++ b/chrome/gpu/gpu_command_buffer_stub.cc
@@ -113,6 +113,14 @@ void GpuCommandBufferStub::OnInitialize(
NewCallback(this,
&GpuCommandBufferStub::SwapBuffersCallback));
}
+#elif defined(OS_LINUX)
+ if (handle_) {
+ // Set up a pathway to allow the Gpu process to ask the browser
+ // for a window resize.
+ processor_->SetResizeCallback(
+ NewCallback(this,
+ &GpuCommandBufferStub::ResizeCallback));
+ }
#endif
} else {
processor_.reset();
@@ -203,4 +211,13 @@ void GpuCommandBufferStub::SwapBuffersCallback() {
}
#endif // defined(OS_MACOSX)
+#if defined(OS_LINUX)
+void GpuCommandBufferStub::ResizeCallback(gfx::Size size) {
+ ChildThread* gpu_thread = ChildThread::current();
+ bool result = false;
+ gpu_thread->Send(
+ new GpuHostMsg_ResizeXID(handle_, size, &result));
+}
+#endif // defined(OS_LINUX)
+
#endif // ENABLE_GPU
diff --git a/chrome/gpu/gpu_command_buffer_stub.h b/chrome/gpu/gpu_command_buffer_stub.h
index fe8b743..1a1e9be 100644
--- a/chrome/gpu/gpu_command_buffer_stub.h
+++ b/chrome/gpu/gpu_command_buffer_stub.h
@@ -72,6 +72,10 @@ class GpuCommandBufferStub
void SwapBuffersCallback();
#endif
+#if defined(OS_LINUX)
+ void ResizeCallback(gfx::Size size);
+#endif
+
// The lifetime of objects of this class is managed by a GpuChannel. The
// GpuChannels destroy all the GpuCommandBufferStubs that they own when they
// are destroyed. So a raw pointer is safe.