diff options
author | kbr@chromium.org <kbr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-11-30 04:42:21 +0000 |
---|---|---|
committer | kbr@chromium.org <kbr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-11-30 04:42:21 +0000 |
commit | dc51d1ccc18135493f01464e38ed462825ae8e35 (patch) | |
tree | 2da87df4b40a6b8d413c7c94af91b1900952b9e0 /webkit/plugins | |
parent | 11a7c5374fc1a712ca52d012fffc26fc10dd3d93 (diff) | |
download | chromium_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.cc | 17 | ||||
-rw-r--r-- | webkit/plugins/npapi/webplugin.h | 7 | ||||
-rw-r--r-- | webkit/plugins/npapi/webplugin_accelerated_surface_mac.h | 6 | ||||
-rw-r--r-- | webkit/plugins/npapi/webplugin_delegate_impl.h | 1 | ||||
-rw-r--r-- | webkit/plugins/npapi/webplugin_delegate_impl_mac.mm | 34 | ||||
-rw-r--r-- | webkit/plugins/npapi/webplugin_impl.cc | 62 | ||||
-rw-r--r-- | webkit/plugins/npapi/webplugin_impl.h | 13 |
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_; |