diff options
author | stuartmorgan@google.com <stuartmorgan@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-08-13 17:56:55 +0000 |
---|---|---|
committer | stuartmorgan@google.com <stuartmorgan@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-08-13 17:56:55 +0000 |
commit | 278429b7cfff0119359708db1b684815ea832115 (patch) | |
tree | 20c2abe641c2bbed98e21ff9fdf85ac80e1b6151 | |
parent | 127017875991e4a1b3d12dfff23d70265f991ef6 (diff) | |
download | chromium_src-278429b7cfff0119359708db1b684815ea832115.zip chromium_src-278429b7cfff0119359708db1b684815ea832115.tar.gz chromium_src-278429b7cfff0119359708db1b684815ea832115.tar.bz2 |
Add an UpdateContext call to WebPluginDelegateImpl on the Mac.
On the Mac, Flash appears to cache the CGContextRef provided in NPP_SetWindow until the next NPP_SetWindow call, so we need to call it sometime before the next plugin paint. This allows us to call NPP_SetWindow before telling the plugin to paint, but not from the Paint function itself (where it could have bad side-effects).
BUG=18894,18980
TEST=Switch to HQ on a YouTube video; Flash should not crash.
Review URL: http://codereview.chromium.org/165344
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@23322 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/plugin/webplugin_proxy.cc | 4 | ||||
-rw-r--r-- | webkit/glue/plugins/webplugin_delegate_impl.h | 6 | ||||
-rw-r--r-- | webkit/glue/plugins/webplugin_delegate_impl_mac.mm | 36 |
3 files changed, 30 insertions, 16 deletions
diff --git a/chrome/plugin/webplugin_proxy.cc b/chrome/plugin/webplugin_proxy.cc index 8a04650..7d2598a 100644 --- a/chrome/plugin/webplugin_proxy.cc +++ b/chrome/plugin/webplugin_proxy.cc @@ -29,6 +29,7 @@ #include "chrome/plugin/webplugin_delegate_stub.h" #include "skia/ext/platform_device.h" #include "webkit/api/public/WebBindings.h" +#include "webkit/glue/plugins/webplugin_delegate_impl.h" #include "webkit/glue/webplugin_delegate.h" #if defined(OS_WIN) @@ -625,6 +626,9 @@ void WebPluginProxy::SetWindowlessBuffer( delegate_->GetRect().height()); CGContextScaleCTM(background_context_, 1, -1); } + + static_cast<WebPluginDelegateImpl*>(delegate_)->UpdateContext( + windowless_context_); } #elif defined (OS_LINUX) void WebPluginProxy::UpdateTransform() { diff --git a/webkit/glue/plugins/webplugin_delegate_impl.h b/webkit/glue/plugins/webplugin_delegate_impl.h index 408a710..4cbf9c1 100644 --- a/webkit/glue/plugins/webplugin_delegate_impl.h +++ b/webkit/glue/plugins/webplugin_delegate_impl.h @@ -88,6 +88,12 @@ class WebPluginDelegateImpl : public WebPluginDelegate { virtual const gfx::Rect& GetClipRect() const { return clip_rect_; } virtual int GetQuirks() const { return quirks_; } +#if defined(OS_MACOSX) + // Informs the delegate that the context used for painting windowless plugins + // has changed. + virtual void UpdateContext(gfx::NativeDrawingContext context); +#endif + private: friend class DeleteTask<WebPluginDelegateImpl>; diff --git a/webkit/glue/plugins/webplugin_delegate_impl_mac.mm b/webkit/glue/plugins/webplugin_delegate_impl_mac.mm index 4fda86d..ebec821 100644 --- a/webkit/glue/plugins/webplugin_delegate_impl_mac.mm +++ b/webkit/glue/plugins/webplugin_delegate_impl_mac.mm @@ -131,6 +131,7 @@ bool WebPluginDelegateImpl::Initialize(const GURL& url, FakePluginWindowTracker* window_tracker = FakePluginWindowTracker::SharedInstance(); cg_context_.window = window_tracker->GenerateFakeWindowForDelegate(this); + cg_context_.context = NULL; Rect window_bounds = { 0, 0, window_rect_.height(), window_rect_.width() }; SetWindowBounds(cg_context_.window, kWindowContentRgn, &window_bounds); window_.window = &cg_context_; @@ -166,6 +167,17 @@ void WebPluginDelegateImpl::UpdateGeometry( WindowlessUpdateGeometry(window_rect, clip_rect); } +void WebPluginDelegateImpl::UpdateContext(CGContextRef context) { + // Flash on the Mac apparently caches the context from the struct it recieves + // in NPP_SetWindow, and continue to use it even when the contents of the + // struct have changed, so we need to call NPP_SetWindow again if the context + // changes. + if (context != cg_context_.context) { + cg_context_.context = context; + WindowlessSetWindow(true); + } +} + void WebPluginDelegateImpl::Paint(CGContextRef context, const gfx::Rect& rect) { DCHECK(windowless_); WindowlessPaint(context, rect); @@ -249,6 +261,11 @@ void WebPluginDelegateImpl::WindowlessUpdateGeometry( void WebPluginDelegateImpl::WindowlessPaint(gfx::NativeDrawingContext context, const gfx::Rect& damage_rect) { + // If we somehow get a paint before we've set up the plugin window, bail. + if (!cg_context_.context) + return; + DCHECK(cg_context_.context == context); + static StatsRate plugin_paint("Plugin.Paint"); StatsScope<StatsRate> scope(plugin_paint); @@ -260,15 +277,6 @@ void WebPluginDelegateImpl::WindowlessPaint(gfx::NativeDrawingContext context, flipped:YES]]; CGContextSaveGState(context); - cg_context_.context = context; - if (window_.window == NULL) - windowless_needs_set_window_ = true; - - window_.window = &cg_context_; - - if (windowless_needs_set_window_) - WindowlessSetWindow(false); - NPEvent paint_event; paint_event.what = updateEvt; paint_event.message = reinterpret_cast<uint32>(cg_context_.window); @@ -323,18 +331,11 @@ void WebPluginDelegateImpl::WindowlessSetWindow(bool force_set_window) { window_.width = window_rect_.width(); window_.x = 0; window_.y = 0; - window_.type = NPWindowTypeWindow; - - if (!force_set_window) - // Reset this flag before entering the instance in case of side-effects. - windowless_needs_set_window_ = false; UpdateDummyWindowBoundsWithOffset(cg_context_.window, window_rect_.x(), window_rect_.y(), window_rect_.width(), window_rect_.height()); - if (!force_set_window) - windowless_needs_set_window_ = false; NPError err = instance()->NPP_SetWindow(&window_); DCHECK(err == NPERR_NO_ERROR); } @@ -479,6 +480,9 @@ static void UpdateWindowLocation(WindowRef window, const WebMouseEvent& event) { bool WebPluginDelegateImpl::HandleInputEvent(const WebInputEvent& event, WebCursorInfo* cursor) { + // If we somehow get an event before we've set up the plugin window, bail. + if (!cg_context_.context) + return false; DCHECK(windowless_) << "events should only be received in windowless mode"; DCHECK(cursor != NULL); |