summaryrefslogtreecommitdiffstats
path: root/webkit/plugins
diff options
context:
space:
mode:
authorkbr@chromium.org <kbr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-11-30 04:42:21 +0000
committerkbr@chromium.org <kbr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-11-30 04:42:21 +0000
commitdc51d1ccc18135493f01464e38ed462825ae8e35 (patch)
tree2da87df4b40a6b8d413c7c94af91b1900952b9e0 /webkit/plugins
parent11a7c5374fc1a712ca52d012fffc26fc10dd3d93 (diff)
downloadchromium_src-dc51d1ccc18135493f01464e38ed462825ae8e35.zip
chromium_src-dc51d1ccc18135493f01464e38ed462825ae8e35.tar.gz
chromium_src-dc51d1ccc18135493f01464e38ed462825ae8e35.tar.bz2
Render Core Animation plugins through WebKit's compositor rather than
directly to the screen in the browser process. The new composited code path is now the default, though the old code path has been left in place under a command line flag while we gain confidence. Issue 105344 has been filed about removing the old code path. The new code path does not currently support 10.5. The consequence is that plugins using the InvalidatingCoreAnimation rendering model will not work on this version of Mac OS. Pepper 3D is not affected; it now uses a different rendering path. Changed the type of IOSurfaces' IDs from uint64 to uint32 in a few places throughout the code to match the IOSurfaceID typedef in the system header. This was necessary in order to simplify integration with Chrome's OpenGL code. There is a known problem in the new code path with garbage occasionally being drawn to the plugin's area during live resizing of Core Animation plugins. Issue 105346 has been filed to track this. It is unclear whether the additional complexity of the fix that is likely needed is worth it. Tested manually with the following content, with and without the --disable-composited-core-animation-plugins flag: - YouTube (does not trigger this code path) - Google+ Hangouts - http://unity3d.com/gallery/demos/live-demos (Unity 3D) - http://www.erain.com/labs/molehill/ (Stage 3D in Flash 11) - http://www.nissan-stagejuk3d.com/ (Stage 3D in Flash 11, live resizing; web site is flaky, sometimes fails to start) BUG=38967 TEST=manual testing with above test cases Review URL: http://codereview.chromium.org/8678037 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@112126 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/plugins')
-rw-r--r--webkit/plugins/npapi/plugin_host.cc17
-rw-r--r--webkit/plugins/npapi/webplugin.h7
-rw-r--r--webkit/plugins/npapi/webplugin_accelerated_surface_mac.h6
-rw-r--r--webkit/plugins/npapi/webplugin_delegate_impl.h1
-rw-r--r--webkit/plugins/npapi/webplugin_delegate_impl_mac.mm34
-rw-r--r--webkit/plugins/npapi/webplugin_impl.cc62
-rw-r--r--webkit/plugins/npapi/webplugin_impl.h13
7 files changed, 111 insertions, 29 deletions
diff --git a/webkit/plugins/npapi/plugin_host.cc b/webkit/plugins/npapi/plugin_host.cc
index bad6fdb..73204d2 100644
--- a/webkit/plugins/npapi/plugin_host.cc
+++ b/webkit/plugins/npapi/plugin_host.cc
@@ -4,6 +4,7 @@
#include "webkit/plugins/npapi/plugin_host.h"
+#include "base/command_line.h"
#include "base/file_util.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
@@ -16,6 +17,7 @@
#include "third_party/npapi/bindings/npruntime.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebBindings.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebKit.h"
+#include "ui/base/ui_base_switches.h"
#include "ui/gfx/gl/gl_implementation.h"
#include "ui/gfx/gl/gl_surface.h"
#include "webkit/glue/webkit_glue.h"
@@ -71,6 +73,11 @@ static bool SupportsSharingAcceleratedSurfaces() {
}
return (implementation == gfx::kGLImplementationDesktopGL);
}
+
+static bool UsingCompositedCoreAnimationPlugins() {
+ return !CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kDisableCompositedCoreAnimationPlugins);
+}
#endif
PluginHost::PluginHost() {
@@ -826,8 +833,12 @@ NPError NPN_GetValue(NPP id, NPNVariable variable, void* value) {
break;
}
case NPNVsupportsInvalidatingCoreAnimationBool: {
+ // The composited code path for this model only works on 10.6 and higher.
+ // The old direct-to-screen code path supports 10.5.
NPBool* supports_model = reinterpret_cast<NPBool*>(value);
- *supports_model = true;
+ bool composited = webkit::npapi::UsingCompositedCoreAnimationPlugins();
+ *supports_model = composited ?
+ webkit::npapi::SupportsSharingAcceleratedSurfaces() : true;
rv = NPERR_NO_ERROR;
break;
}
@@ -901,7 +912,9 @@ NPError NPN_SetValue(NPP id, NPPVariable variable, void* value) {
case NPPVpluginDrawingModel: {
int model = reinterpret_cast<int>(value);
if (model == NPDrawingModelCoreGraphics ||
- model == NPDrawingModelInvalidatingCoreAnimation ||
+ (model == NPDrawingModelInvalidatingCoreAnimation &&
+ (webkit::npapi::SupportsSharingAcceleratedSurfaces() ||
+ !webkit::npapi::UsingCompositedCoreAnimationPlugins())) ||
(model == NPDrawingModelCoreAnimation &&
webkit::npapi::SupportsSharingAcceleratedSurfaces())) {
plugin->set_drawing_model(static_cast<NPDrawingModel>(model));
diff --git a/webkit/plugins/npapi/webplugin.h b/webkit/plugins/npapi/webplugin.h
index 53a2ca4..f861517 100644
--- a/webkit/plugins/npapi/webplugin.h
+++ b/webkit/plugins/npapi/webplugin.h
@@ -156,6 +156,13 @@ class WebPlugin {
// Returns the accelerated surface abstraction for accelerated plugins.
virtual WebPluginAcceleratedSurface* GetAcceleratedSurface(
gfx::GpuPreference gpu_preference);
+
+ // Composited Core Animation plugin support.
+ virtual void AcceleratedPluginEnabledRendering() = 0;
+ virtual void AcceleratedPluginAllocatedIOSurface(int32 width,
+ int32 height,
+ uint32 surface_id) = 0;
+ virtual void AcceleratedPluginSwappedIOSurface() = 0;
#endif
// Handles NPN_URLRedirectResponse calls issued by plugins in response to
diff --git a/webkit/plugins/npapi/webplugin_accelerated_surface_mac.h b/webkit/plugins/npapi/webplugin_accelerated_surface_mac.h
index 5c528f3..2f46861 100644
--- a/webkit/plugins/npapi/webplugin_accelerated_surface_mac.h
+++ b/webkit/plugins/npapi/webplugin_accelerated_surface_mac.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -25,6 +25,10 @@ class WebPluginAcceleratedSurface {
// surface.
virtual void SetWindowHandle(gfx::PluginWindowHandle window) = 0;
+ // Indicates whether the new code path which renders the plugins via
+ // the compositor should be used.
+ virtual bool IsComposited() = 0;
+
// Sets the size of the surface.
virtual void SetSize(const gfx::Size& size) = 0;
diff --git a/webkit/plugins/npapi/webplugin_delegate_impl.h b/webkit/plugins/npapi/webplugin_delegate_impl.h
index 97fde32..f811d72 100644
--- a/webkit/plugins/npapi/webplugin_delegate_impl.h
+++ b/webkit/plugins/npapi/webplugin_delegate_impl.h
@@ -475,6 +475,7 @@ class WebPluginDelegateImpl : public WebPluginDelegate {
CALayer* layer_; // Used for CA drawing mode. Weak, retained by plug-in.
WebPluginAcceleratedSurface* surface_; // Weak ref.
+ bool composited_; // If CA plugin, whether it's rendering via compositor.
CARenderer* renderer_; // Renders layer_ to surface_.
scoped_ptr<base::RepeatingTimer<WebPluginDelegateImpl> > redraw_timer_;
diff --git a/webkit/plugins/npapi/webplugin_delegate_impl_mac.mm b/webkit/plugins/npapi/webplugin_delegate_impl_mac.mm
index 8e0243a..5127eaf 100644
--- a/webkit/plugins/npapi/webplugin_delegate_impl_mac.mm
+++ b/webkit/plugins/npapi/webplugin_delegate_impl_mac.mm
@@ -267,6 +267,7 @@ WebPluginDelegateImpl::WebPluginDelegateImpl(
buffer_context_(NULL),
layer_(nil),
surface_(NULL),
+ composited_(false),
renderer_(nil),
containing_window_has_focus_(false),
initial_window_focus_(false),
@@ -402,11 +403,16 @@ bool WebPluginDelegateImpl::PlatformInitialize() {
// without any drawing; returning false would be a more confusing user
// experience (since it triggers a missing plugin placeholder).
if (surface_ && surface_->context()) {
+ composited_ = surface_->IsComposited();
renderer_ = [[CARenderer rendererWithCGLContext:surface_->context()
options:NULL] retain];
[renderer_ setLayer:layer_];
}
- plugin_->BindFakePluginWindowHandle(false);
+ if (composited_) {
+ plugin_->AcceleratedPluginEnabledRendering();
+ } else {
+ plugin_->BindFakePluginWindowHandle(false);
+ }
}
break;
}
@@ -415,9 +421,10 @@ bool WebPluginDelegateImpl::PlatformInitialize() {
break;
}
- // Let the WebPlugin know that we are windowless (unless this is a
- // Core Animation plugin, in which case BindFakePluginWindowHandle will take
- // care of setting up the appropriate window handle).
+ // Let the WebPlugin know that we are windowless, unless this is a Core
+ // Animation plugin, in which case AcceleratedPluginEnabledRendering
+ // calls SetWindow. Rendering breaks if SetWindow is called before
+ // accelerated rendering is enabled.
if (!layer_)
plugin_->SetWindow(NULL);
@@ -1035,7 +1042,8 @@ void WebPluginDelegateImpl::PluginVisibilityChanged() {
#endif
if (instance()->drawing_model() == NPDrawingModelCoreAnimation) {
bool plugin_visible = container_is_visible_ && !clip_rect_.IsEmpty();
- if (plugin_visible && !redraw_timer_->IsRunning() && windowed_handle()) {
+ if (plugin_visible && !redraw_timer_->IsRunning() &&
+ (composited_ || windowed_handle())) {
redraw_timer_->Start(FROM_HERE,
base::TimeDelta::FromMilliseconds(kCoreAnimationRedrawPeriodMs),
this, &WebPluginDelegateImpl::DrawLayerInSurface);
@@ -1062,7 +1070,10 @@ void WebPluginDelegateImpl::StartIme() {
void WebPluginDelegateImpl::DrawLayerInSurface() {
// If we haven't plumbed up the surface yet, don't try to draw.
- if (!windowed_handle() || !renderer_)
+ if (!renderer_)
+ return;
+
+ if (!composited_ && !windowed_handle())
return;
[renderer_ beginFrameAtTime:CACurrentMediaTime() timeStamp:NULL];
@@ -1084,8 +1095,10 @@ void WebPluginDelegateImpl::DrawLayerInSurface() {
// Update the size of the surface to match the current size of the plug-in.
void WebPluginDelegateImpl::UpdateAcceleratedSurface() {
- // Will only have a window handle when using a Core Animation drawing model.
- if (!windowed_handle() || !layer_)
+ if (!surface_ || !layer_)
+ return;
+
+ if (!composited_ && !windowed_handle())
return;
[CATransaction begin];
@@ -1097,10 +1110,15 @@ void WebPluginDelegateImpl::UpdateAcceleratedSurface() {
[renderer_ setBounds:[layer_ bounds]];
surface_->SetSize(window_rect_.size());
+ if (composited_) {
+ // Kick off the drawing timer, if necessary.
+ PluginVisibilityChanged();
+ }
}
void WebPluginDelegateImpl::set_windowed_handle(
gfx::PluginWindowHandle handle) {
+ DCHECK(!composited_);
windowed_handle_ = handle;
surface_->SetWindowHandle(handle);
UpdateAcceleratedSurface();
diff --git a/webkit/plugins/npapi/webplugin_impl.cc b/webkit/plugins/npapi/webplugin_impl.cc
index b78aeab..3ea5256 100644
--- a/webkit/plugins/npapi/webplugin_impl.cc
+++ b/webkit/plugins/npapi/webplugin_impl.cc
@@ -489,38 +489,31 @@ WebPluginImpl::~WebPluginImpl() {
}
void WebPluginImpl::SetWindow(gfx::PluginWindowHandle window) {
-#if defined(OS_MACOSX)
- // The only time this is called twice, and the second time with a
- // non-zero PluginWindowHandle, is the case when this WebPluginImpl
- // is created on behalf of the GPU plugin. This entire code path
- // will go away soon, as soon as the GPU plugin becomes the GPU
- // process, so it is being separated out for easy deletion.
-
- // The logic we want here is: if (window) DCHECK(!window_);
- DCHECK(!(window_ && window));
- window_ = window;
- // Lie to ourselves about being windowless even if we got a fake
- // plugin window handle, so we continue to get input events.
- windowless_ = true;
- accepts_input_events_ = true;
- // We do not really need to notify the page delegate that a plugin
- // window was created -- so don't.
-#else
if (window) {
DCHECK(!windowless_);
window_ = window;
+#if defined(OS_MACOSX)
+ // TODO(kbr): remove. http://crbug.com/105344
+
+ // Lie to ourselves about being windowless even if we got a fake
+ // plugin window handle, so we continue to get input events.
+ windowless_ = true;
+ accepts_input_events_ = true;
+ // We do not really need to notify the page delegate that a plugin
+ // window was created -- so don't.
+#else
accepts_input_events_ = false;
if (page_delegate_) {
// Tell the view delegate that the plugin window was created, so that it
// can create necessary container widgets.
page_delegate_->CreatedPluginWindow(window);
}
+#endif
} else {
DCHECK(!window_); // Make sure not called twice.
windowless_ = true;
accepts_input_events_ = true;
}
-#endif
}
void WebPluginImpl::SetAcceptsInputEvents(bool accepts) {
@@ -754,6 +747,39 @@ void WebPluginImpl::URLRedirectResponse(bool allow, int resource_id) {
}
}
+#if defined(OS_MACOSX)
+void WebPluginImpl::AcceleratedPluginEnabledRendering() {
+}
+
+void WebPluginImpl::AcceleratedPluginAllocatedIOSurface(int32 width,
+ int32 height,
+ uint32 surface_id) {
+ next_io_surface_allocated_ = true;
+ next_io_surface_width_ = width;
+ next_io_surface_height_ = height;
+ next_io_surface_id_ = surface_id;
+}
+
+void WebPluginImpl::AcceleratedPluginSwappedIOSurface() {
+ if (container_) {
+ // Deferring the call to setBackingIOSurfaceId is an attempt to
+ // work around garbage occasionally showing up in the plugin's
+ // area during live resizing of Core Animation plugins. The
+ // assumption was that by the time this was called, the plugin
+ // process would have populated the newly allocated IOSurface. It
+ // is not 100% clear at this point why any garbage is getting
+ // through. More investigation is needed. http://crbug.com/105346
+ if (next_io_surface_allocated_) {
+ container_->setBackingIOSurfaceId(next_io_surface_width_,
+ next_io_surface_height_,
+ next_io_surface_id_);
+ next_io_surface_allocated_ = false;
+ }
+ container_->commitBackingTexture();
+ }
+}
+#endif
+
void WebPluginImpl::Invalidate() {
if (container_)
container_->invalidate();
diff --git a/webkit/plugins/npapi/webplugin_impl.h b/webkit/plugins/npapi/webplugin_impl.h
index c9c798c..ec0f30f 100644
--- a/webkit/plugins/npapi/webplugin_impl.h
+++ b/webkit/plugins/npapi/webplugin_impl.h
@@ -109,6 +109,13 @@ class WebPluginImpl : public WebPlugin,
virtual std::string GetCookies(const GURL& url,
const GURL& first_party_for_cookies) OVERRIDE;
virtual void URLRedirectResponse(bool allow, int resource_id) OVERRIDE;
+#if defined(OS_MACOSX)
+ virtual void AcceleratedPluginEnabledRendering() OVERRIDE;
+ virtual void AcceleratedPluginAllocatedIOSurface(int32 width,
+ int32 height,
+ uint32 surface_id) OVERRIDE;
+ virtual void AcceleratedPluginSwappedIOSurface() OVERRIDE;
+#endif
// Given a (maybe partial) url, completes using the base url.
GURL CompleteURL(const char* url);
@@ -255,6 +262,12 @@ class WebPluginImpl : public WebPlugin,
bool windowless_;
gfx::PluginWindowHandle window_;
+#if defined(OS_MACOSX)
+ bool next_io_surface_allocated_;
+ int32 next_io_surface_width_;
+ int32 next_io_surface_height_;
+ uint32 next_io_surface_id_;
+#endif
bool accepts_input_events_;
base::WeakPtr<WebPluginPageDelegate> page_delegate_;
WebKit::WebFrame* webframe_;