summaryrefslogtreecommitdiffstats
path: root/chrome/browser
diff options
context:
space:
mode:
authorjam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-01-22 01:27:38 +0000
committerjam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-01-22 01:27:38 +0000
commit4115925c9a0c074e79c0b5a181a7cf8d50180b86 (patch)
tree779ffaa81d9c4e1c6d4a491241f0f44cb0e1b815 /chrome/browser
parent5bc0feb22687326cc26214c100c4658c79ce314f (diff)
downloadchromium_src-4115925c9a0c074e79c0b5a181a7cf8d50180b86.zip
chromium_src-4115925c9a0c074e79c0b5a181a7cf8d50180b86.tar.gz
chromium_src-4115925c9a0c074e79c0b5a181a7cf8d50180b86.tar.bz2
More speedup of scrolling when many windowed plugins in a page. Scrolling is now at parity with single process browsers in my testing.
This works by making painting of child windows asynchronous. The key is to send, not post, the custom message. This allows the redraw message to jump the queue and get dispatched before other queued [Windows, IPC] messages, which eliminates painting artifacts. Now that painting is asynchronous, I had to take out the SWP_NOREDRAW flag to DeferWindowPos. While it's slightly faster without it, the visual aritfacts are noticable. Review URL: http://codereview.chromium.org/18637 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@8432 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
-rw-r--r--chrome/browser/plugin_process_host.cc3
-rw-r--r--chrome/browser/render_widget_host.cc5
-rw-r--r--chrome/browser/render_widget_host_view_win.cc62
-rw-r--r--chrome/browser/render_widget_host_view_win.h4
4 files changed, 47 insertions, 27 deletions
diff --git a/chrome/browser/plugin_process_host.cc b/chrome/browser/plugin_process_host.cc
index 0362423..7c272a5 100644
--- a/chrome/browser/plugin_process_host.cc
+++ b/chrome/browser/plugin_process_host.cc
@@ -39,6 +39,7 @@
#include "net/proxy/proxy_service.h"
#include "net/url_request/url_request.h"
#include "sandbox/src/sandbox.h"
+#include "webkit/glue/plugins/plugin_constants_win.h"
static const char kDefaultPluginFinderURL[] =
"http://dl.google.com/chrome/plugins/plugins2.xml";
@@ -389,7 +390,7 @@ class CreateWindowTask : public Task {
wcex.hCursor = 0;
wcex.hbrBackground = reinterpret_cast<HBRUSH>(COLOR_WINDOW+1);
wcex.lpszMenuName = 0;
- wcex.lpszClassName = L"NativeWindowClassWrapper";
+ wcex.lpszClassName = kWrapperNativeWindowClassName;
wcex.hIconSm = 0;
window_class = RegisterClassEx(&wcex);
}
diff --git a/chrome/browser/render_widget_host.cc b/chrome/browser/render_widget_host.cc
index 9ce5f0a..fdbec92 100644
--- a/chrome/browser/render_widget_host.cc
+++ b/chrome/browser/render_widget_host.cc
@@ -448,10 +448,7 @@ void RenderWidgetHost::MovePluginWindows(
}
for (size_t i = 0; i < plugin_window_moves.size(); ++i) {
- // Don't invalidate now because that would result in cross process calls
- // that make scrolling slow. Instead the window is invalidated
- // asynchronously by the plugin code.
- unsigned long flags = SWP_NOREDRAW;
+ unsigned long flags = 0;
const WebPluginGeometry& move = plugin_window_moves[i];
if (move.visible)
diff --git a/chrome/browser/render_widget_host_view_win.cc b/chrome/browser/render_widget_host_view_win.cc
index 0aa756d..251a8c7 100644
--- a/chrome/browser/render_widget_host_view_win.cc
+++ b/chrome/browser/render_widget_host_view_win.cc
@@ -24,6 +24,8 @@
#include "chrome/common/win_util.h"
// Included for views::kReflectedMessage - TODO(beng): move this to win_util.h!
#include "chrome/views/widget_win.h"
+#include "webkit/glue/plugins/plugin_constants_win.h"
+#include "webkit/glue/plugins/webplugin_delegate_impl.h"
#include "webkit/glue/webcursor.h"
using base::TimeDelta;
@@ -259,22 +261,51 @@ void RenderWidgetHostViewWin::IMEUpdateStatus(ViewHostMsg_ImeControl control,
}
}
-void RenderWidgetHostViewWin::DidPaintRect(const gfx::Rect& rect) {
- if (is_hidden_)
- return;
+BOOL CALLBACK EnumChildProc(HWND hwnd, LPARAM lparam) {
+ if (!WebPluginDelegateImpl::IsPluginDelegateWindow(hwnd))
+ return TRUE;
- RECT invalid_rect = rect.ToRECT();
+ gfx::Rect* rect = reinterpret_cast<gfx::Rect*>(lparam);
+ static UINT msg = RegisterWindowMessage(kPaintMessageName);
+ WPARAM wparam = rect->x() << 16 | rect->y();
+ lparam = rect->width() << 16 | rect->height();
+ // SendMessage gets the message across much quicker than PostMessage, since it
+ // doesn't get queued. When the plugin thread calls PeekMessage or other
+ // Win32 APIs, sent messages are dispatched automatically.
+ SendNotifyMessage(hwnd, msg, wparam, lparam);
+
+ return TRUE;
+}
+
+void RenderWidgetHostViewWin::Redraw(const gfx::Rect& rect) {
// Paint the invalid region synchronously. Our caller will not paint again
// until we return, so by painting to the screen here, we ensure effective
// rate-limiting of backing store updates. This helps a lot on pages that
// have animations or fairly expensive layout (e.g., google maps).
//
- // Please refer to the RenderWidgetHostViewWin::DidScrollRect function for the
- // reasoning behind the combination of flags passed to RedrawWindow.
+ // We paint this window synchronously, however child windows (i.e. plugins)
+ // are painted asynchronously. By avoiding synchronous cross-process window
+ // message dispatching we allow scrolling to be smooth, and also avoid the
+ // browser process locking up if the plugin process is hung.
//
- RedrawWindow(&invalid_rect, NULL,
- RDW_INVALIDATE | RDW_UPDATENOW | RDW_ALLCHILDREN | RDW_FRAME);
+ RedrawWindow(
+ &rect.ToRECT(), NULL, RDW_INVALIDATE | RDW_UPDATENOW | RDW_NOCHILDREN);
+
+ // Send the invalid rect in screen coordinates.
+ gfx::Rect screen_rect = GetViewBounds();
+ gfx::Rect invalid_screen_rect = rect;
+ invalid_screen_rect.Offset(screen_rect.x(), screen_rect.y());
+
+ LPARAM lparam = reinterpret_cast<LPARAM>(&invalid_screen_rect);
+ EnumChildWindows(m_hWnd, EnumChildProc, lparam);
+}
+
+void RenderWidgetHostViewWin::DidPaintRect(const gfx::Rect& rect) {
+ if (is_hidden_)
+ return;
+
+ Redraw(rect);
}
void RenderWidgetHostViewWin::DidScrollRect(
@@ -291,20 +322,7 @@ void RenderWidgetHostViewWin::DidScrollRect(
RECT invalid_rect = {0};
GetUpdateRect(&invalid_rect);
-
- // Paint the invalid region synchronously. Our caller will not paint again
- // until we return, so by painting to the screen here, we ensure effective
- // rate-limiting of backing store updates. This helps a lot on pages that
- // have animations or fairly expensive layout (e.g., google maps).
- //
- // Our RenderWidgetHostViewWin does not have a non-client area, whereas the
- // children (plugin windows) may. If we don't pass in RDW_FRAME then the
- // children don't receive WM_NCPAINT messages while scrolling, which causes
- // painting problems (http://b/issue?id=923945). We need to pass
- // RDW_INVALIDATE as it is required for RDW_FRAME to work.
- //
- RedrawWindow(&invalid_rect, NULL,
- RDW_INVALIDATE | RDW_UPDATENOW | RDW_ALLCHILDREN | RDW_FRAME);
+ Redraw(gfx::Rect(invalid_rect));
}
void RenderWidgetHostViewWin::RendererGone() {
diff --git a/chrome/browser/render_widget_host_view_win.h b/chrome/browser/render_widget_host_view_win.h
index bbf6e63..91b3684 100644
--- a/chrome/browser/render_widget_host_view_win.h
+++ b/chrome/browser/render_widget_host_view_win.h
@@ -209,6 +209,10 @@ class RenderWidgetHostViewWin :
// invoke it from the message loop.
void ShutdownHost();
+ // Redraws the window synchronously, and any child windows (i.e. plugins)
+ // asynchronously.
+ void Redraw(const gfx::Rect& invalid_rect);
+
// The associated Model.
RenderWidgetHost* render_widget_host_;