summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorstuartmorgan@google.com <stuartmorgan@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-08-13 17:56:55 +0000
committerstuartmorgan@google.com <stuartmorgan@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-08-13 17:56:55 +0000
commit278429b7cfff0119359708db1b684815ea832115 (patch)
tree20c2abe641c2bbed98e21ff9fdf85ac80e1b6151
parent127017875991e4a1b3d12dfff23d70265f991ef6 (diff)
downloadchromium_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.cc4
-rw-r--r--webkit/glue/plugins/webplugin_delegate_impl.h6
-rw-r--r--webkit/glue/plugins/webplugin_delegate_impl_mac.mm36
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);