summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorananta@chromium.org <ananta@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2008-11-21 18:29:14 +0000
committerananta@chromium.org <ananta@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2008-11-21 18:29:14 +0000
commitf1a0eae704dcc8848847201d48922aa1984e522a (patch)
tree044105541a11d8db2468416711d2e9397e441038 /chrome
parentdb5de6e6dc5b1692f2aa557ab1931246f43b775d (diff)
downloadchromium_src-f1a0eae704dcc8848847201d48922aa1984e522a.zip
chromium_src-f1a0eae704dcc8848847201d48922aa1984e522a.tar.gz
chromium_src-f1a0eae704dcc8848847201d48922aa1984e522a.tar.bz2
Relanding this fix. The earlier attempt broke test_shell_tests. The fix
has been added to this CB. Fix Silverlight windowless plugin painting issues. This fixes the following issues:- 1. http://code.google.com/p/chromium/issues/detail?id=4272 2. http://code.google.com/p/chromium/issues/detail?id=301 (Partially) The fixes are as below:- 1. Silverlight in the NPP_HandleEvent call for WM_PAINT, calls NPN_GetProperty for a bunch of properties like pageXOffset, pageYOffset, etc. It expects these properties to have integer types on return. We always return double. Firefox returns integer for these properties. Added a check in the conversion to NPVariant function in v8 to check for whether the value is an integer and return the intger type. 2. When the windowless plugin calls NPN_InvalidateRect we ask the plugin to paint in the same call, which the Silverlight plugin does not like. It relies on the fact that browsers would initiate invalidation asynchronously and eventually paint. This is a perfectly legal assumption. The Flash plugin does work if we synchronously ask it to paint. However other plugins could have similar issues. I verified with worldofwarcraft.com to see if the async paint has any sideeffects and there were none. 3.If the Silverlight plugin is not visible initially as on msdn.microsoft.com, it does not paint. This occurs because the plugin expects proper paints to come from the browser. It does not invalidate itself in UpdateGeometry as Flash. The plugin widget on msdn is not dynamic. It does call NPN_InvalidateRect initially when it is not visible. We don't send the call to the renderer as the plugin is not visible. To workaround this we now track the damaged rect even if the rect does not intersect the clipping rect of the plugin. In a geometry update if the plugin is visible, we send over the accumulated damaged rect to the renderer. The Silverlight plugin instance on msdn.microsoft.com does not work correctly even with these fixes. However it paints correctly. R=jam Bug=4272,301 Review URL: http://codereview.chromium.org/11569 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@5829 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/plugin/webplugin_proxy.cc28
-rw-r--r--chrome/plugin/webplugin_proxy.h5
2 files changed, 27 insertions, 6 deletions
diff --git a/chrome/plugin/webplugin_proxy.cc b/chrome/plugin/webplugin_proxy.cc
index 2cbb3ee..255c843 100644
--- a/chrome/plugin/webplugin_proxy.cc
+++ b/chrome/plugin/webplugin_proxy.cc
@@ -34,7 +34,9 @@ WebPluginProxy::WebPluginProxy(
window_npobject_(NULL),
plugin_element_(NULL),
delegate_(delegate),
- waiting_for_paint_(false) {
+ waiting_for_paint_(false),
+#pragma warning(suppress: 4355) // can use this
+ runnable_method_factory_(this) {
HANDLE event;
BOOL result = DuplicateHandle(channel->renderer_handle(),
@@ -84,21 +86,22 @@ void WebPluginProxy::Invalidate() {
}
void WebPluginProxy::InvalidateRect(const gfx::Rect& rect) {
+ damaged_rect_ = damaged_rect_.Union(rect);
// Ignore NPN_InvalidateRect calls with empty rects. Also don't send an
// invalidate if it's outside the clipping region, since if we did it won't
// lead to a paint and we'll be stuck waiting forever for a DidPaint response.
if (rect.IsEmpty() || !delegate_->clip_rect().Intersects(rect))
return;
- damaged_rect_ = damaged_rect_.Union(rect);
// Only send a single InvalidateRect message at a time. From DidPaint we
// will dispatch an additional InvalidateRect message if necessary.
if (!waiting_for_paint_) {
waiting_for_paint_ = true;
- // Paint to the plugin bitmap and let the renderer know so it can update
- // its backing store.
- Paint(damaged_rect_);
- Send(new PluginHostMsg_InvalidateRect(route_id_, damaged_rect_));
+ // Invalidates caused by calls to NPN_InvalidateRect/NPN_InvalidateRgn
+ // need to be painted asynchronously as per the NPAPI spec.
+ MessageLoop::current()->PostTask(FROM_HERE,
+ runnable_method_factory_.NewRunnableMethod(
+ &WebPluginProxy::OnPaint, damaged_rect_));
damaged_rect_ = gfx::Rect();
}
}
@@ -282,6 +285,8 @@ void WebPluginProxy::UpdateGeometry(
const base::SharedMemoryHandle& windowless_buffer,
const base::SharedMemoryHandle& background_buffer) {
gfx::Rect old = delegate_->rect();
+ gfx::Rect old_clip_rect = delegate_->clip_rect();
+
bool moved = delegate_->rect().x() != window_rect.x() ||
delegate_->rect().y() != window_rect.y();
delegate_->UpdateGeometry(window_rect, clip_rect, cutout_rects, visible);
@@ -292,6 +297,12 @@ void WebPluginProxy::UpdateGeometry(
// The plugin moved, so update our world transform.
UpdateTransform();
}
+ // Send over any pending invalidates which occured when the plugin was
+ // off screen.
+ if (visible && delegate_->windowless() && !clip_rect.IsEmpty() &&
+ old_clip_rect.IsEmpty() && !damaged_rect_.IsEmpty()) {
+ InvalidateRect(damaged_rect_);
+ }
}
void WebPluginProxy::SetWindowlessBuffer(
@@ -376,3 +387,8 @@ void WebPluginProxy::InitiateHTTPRangeRequest(const char* url,
range_info, existing_stream,
notify_needed, notify_data));
}
+
+void WebPluginProxy::OnPaint(const gfx::Rect& damaged_rect) {
+ Paint(damaged_rect);
+ Send(new PluginHostMsg_InvalidateRect(route_id_, damaged_rect));
+}
diff --git a/chrome/plugin/webplugin_proxy.h b/chrome/plugin/webplugin_proxy.h
index e6a231d..c2cefc7 100644
--- a/chrome/plugin/webplugin_proxy.h
+++ b/chrome/plugin/webplugin_proxy.h
@@ -108,6 +108,9 @@ class WebPluginProxy : public WebPlugin {
ScopedBitmap* bitmap,
ScopedHDC* hdc);
+ // Handler for sending over the paint event to the plugin.
+ void OnPaint(const gfx::Rect& damaged_rect);
+
// Called when a plugin's origin moves, so that we can update the world
// transform of the local HDC.
void UpdateTransform();
@@ -137,6 +140,8 @@ class WebPluginProxy : public WebPlugin {
ScopedHandle background_shared_section_;
ScopedBitmap background_bitmap_;
ScopedHDC background_hdc_;
+
+ ScopedRunnableMethodFactory<WebPluginProxy> runnable_method_factory_;
};
#endif // CHROME_PLUGIN_PLUGIN_WEBPLUGIN_PROXY_H__