diff options
author | brettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-12-22 20:36:46 +0000 |
---|---|---|
committer | brettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-12-22 20:36:46 +0000 |
commit | 719b36f60b1731c3260825ef281d10b252d96b65 (patch) | |
tree | 742fbd3353bd152763efe412495182f564a07144 | |
parent | ca2b1cbcace07670d6631bfe226ffc906c009453 (diff) | |
download | chromium_src-719b36f60b1731c3260825ef281d10b252d96b65.zip chromium_src-719b36f60b1731c3260825ef281d10b252d96b65.tar.gz chromium_src-719b36f60b1731c3260825ef281d10b252d96b65.tar.bz2 |
Add an additional level of optimization for PPAPI plugins to paint without
doing a WebKit paint.
Currently, this will not get triggered very much because the % coverage
required for combining rects in the paint manager is so low. I'm going to try
tweaking that but want to do it in another CL.
TEST=none
BUG=none
Review URL: http://codereview.chromium.org/6020007
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@69974 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/renderer/pepper_plugin_delegate_impl.cc | 13 | ||||
-rw-r--r-- | chrome/renderer/pepper_plugin_delegate_impl.h | 2 | ||||
-rw-r--r-- | chrome/renderer/render_view.cc | 2 | ||||
-rw-r--r-- | chrome/renderer/render_view.h | 2 | ||||
-rw-r--r-- | chrome/renderer/render_widget.cc | 59 | ||||
-rw-r--r-- | chrome/renderer/render_widget.h | 19 | ||||
-rw-r--r-- | chrome/renderer/render_widget_fullscreen_pepper.cc | 13 | ||||
-rw-r--r-- | chrome/renderer/render_widget_fullscreen_pepper.h | 2 |
8 files changed, 82 insertions, 30 deletions
diff --git a/chrome/renderer/pepper_plugin_delegate_impl.cc b/chrome/renderer/pepper_plugin_delegate_impl.cc index e223202..6e31439 100644 --- a/chrome/renderer/pepper_plugin_delegate_impl.cc +++ b/chrome/renderer/pepper_plugin_delegate_impl.cc @@ -379,8 +379,10 @@ PepperPluginDelegateImpl::CreatePepperPlugin(const FilePath& path) { IPC::ChannelHandle channel_handle; render_view_->Send(new ViewHostMsg_OpenChannelToPepperPlugin( path, &plugin_process_handle, &channel_handle)); - if (channel_handle.name.empty()) - return scoped_refptr<webkit::ppapi::PluginModule>(); // Couldn't be initialized. + if (channel_handle.name.empty()) { + // Couldn't be initialized. + return scoped_refptr<webkit::ppapi::PluginModule>(); + } // Create a new HostDispatcher for the proxying, and hook it to a new // PluginModule. @@ -435,7 +437,8 @@ void PepperPluginDelegateImpl::ViewFlushedPaint() { } } -bool PepperPluginDelegateImpl::GetBitmapForOptimizedPluginPaint( +webkit::ppapi::PluginInstance* +PepperPluginDelegateImpl::GetBitmapForOptimizedPluginPaint( const gfx::Rect& paint_bounds, TransportDIB** dib, gfx::Rect* location, @@ -446,9 +449,9 @@ bool PepperPluginDelegateImpl::GetBitmapForOptimizedPluginPaint( webkit::ppapi::PluginInstance* instance = *i; if (instance->GetBitmapForOptimizedPluginPaint( paint_bounds, dib, location, clip)) - return true; + return *i; } - return false; + return NULL; } void PepperPluginDelegateImpl::InstanceCreated( diff --git a/chrome/renderer/pepper_plugin_delegate_impl.h b/chrome/renderer/pepper_plugin_delegate_impl.h index 783cfc8..cd732fe 100644 --- a/chrome/renderer/pepper_plugin_delegate_impl.h +++ b/chrome/renderer/pepper_plugin_delegate_impl.h @@ -57,7 +57,7 @@ class PepperPluginDelegateImpl // Called by RenderView to implement the corresponding function in its base // class RenderWidget (see that for more). - bool GetBitmapForOptimizedPluginPaint( + webkit::ppapi::PluginInstance* GetBitmapForOptimizedPluginPaint( const gfx::Rect& paint_bounds, TransportDIB** dib, gfx::Rect* location, diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc index 3522f12..7a84c11 100644 --- a/chrome/renderer/render_view.cc +++ b/chrome/renderer/render_view.cc @@ -5228,7 +5228,7 @@ void RenderView::DidFlushPaint() { } } -bool RenderView::GetBitmapForOptimizedPluginPaint( +webkit::ppapi::PluginInstance* RenderView::GetBitmapForOptimizedPluginPaint( const gfx::Rect& paint_bounds, TransportDIB** dib, gfx::Rect* location, diff --git a/chrome/renderer/render_view.h b/chrome/renderer/render_view.h index af7b969..1f97fa6 100644 --- a/chrome/renderer/render_view.h +++ b/chrome/renderer/render_view.h @@ -679,7 +679,7 @@ class RenderView : public RenderWidget, const gfx::Rect& resizer_rect); virtual void DidInitiatePaint(); virtual void DidFlushPaint(); - virtual bool GetBitmapForOptimizedPluginPaint( + virtual webkit::ppapi::PluginInstance* GetBitmapForOptimizedPluginPaint( const gfx::Rect& paint_bounds, TransportDIB** dib, gfx::Rect* location, diff --git a/chrome/renderer/render_widget.cc b/chrome/renderer/render_widget.cc index 041fcd9..9cf323c 100644 --- a/chrome/renderer/render_widget.cc +++ b/chrome/renderer/render_widget.cc @@ -29,6 +29,7 @@ #include "third_party/WebKit/WebKit/chromium/public/WebSize.h" #include "webkit/glue/webkit_glue.h" #include "webkit/plugins/npapi/webplugin.h" +#include "webkit/plugins/ppapi/ppapi_plugin_instance.h" #if defined(OS_POSIX) #include "ipc/ipc_channel_posix.h" @@ -389,6 +390,7 @@ void RenderWidget::ClearFocus() { void RenderWidget::PaintRect(const gfx::Rect& rect, const gfx::Point& canvas_origin, skia::PlatformCanvas* canvas) { + canvas->save(); // Bring the canvas into the coordinate system of the paint rect. @@ -406,13 +408,45 @@ void RenderWidget::PaintRect(const gfx::Rect& rect, canvas->drawPaint(paint); } - webwidget_->paint(webkit_glue::ToWebCanvas(canvas), rect); - - PaintDebugBorder(rect, canvas); + // First see if this rect is a plugin that can paint itself faster. + TransportDIB* optimized_dib = NULL; + gfx::Rect optimized_copy_rect, optimized_copy_location; + webkit::ppapi::PluginInstance* optimized_instance = + GetBitmapForOptimizedPluginPaint(rect, &optimized_dib, + &optimized_copy_location, + &optimized_copy_rect); + if (optimized_instance) { + // This plugin can be optimize-painted and we can just ask it to paint + // itself. We don't actually need the TransportDIB in this case. + // + // This is an optimization for PPAPI plugins that know they're on top of + // the page content. If this rect is inside such a plugin, we can save some + // time and avoid re-rendering the page content which we know will be + // covered by the plugin later (this time can be significant, especially + // for a playing movie that is invalidating a lot). + // + // In the plugin movie case, hopefully the similar call to + // GetBitmapForOptimizedPluginPaint in DoDeferredUpdate handles the + // painting, because that avoids copying the plugin image to a different + // paint rect. Unfortunately, if anything on the page is animating other + // than the movie, it break this optimization since the union of the + // invalid regions will be larger than the plugin. + // + // This code optimizes that case, where we can still avoid painting in + // WebKit and filling the background (which can be slow) and just painting + // the plugin. Unlike the DoDeferredUpdate case, an extra copy is still + // required. + optimized_instance->Paint(webkit_glue::ToWebCanvas(canvas), + optimized_copy_location, optimized_copy_location); + } else { + // Normal painting case. + webwidget_->paint(webkit_glue::ToWebCanvas(canvas), rect); - // Flush to underlying bitmap. TODO(darin): is this needed? - canvas->getTopPlatformDevice().accessBitmap(false); + // Flush to underlying bitmap. TODO(darin): is this needed? + canvas->getTopPlatformDevice().accessBitmap(false); + } + PaintDebugBorder(rect, canvas); canvas->restore(); } @@ -475,6 +509,15 @@ void RenderWidget::DoDeferredUpdate() { // A plugin may be able to do an optimized paint. First check this, in which // case we can skip all of the bitmap generation and regular paint code. + // This optimization allows PPAPI plugins that declare themselves on top of + // the page (like a traditional windowed plugin) to be able to animate (think + // movie playing) without repeatedly re-painting the page underneath, or + // copying the plugin backing store (since we can send the plugin's backing + // store directly to the browser). + // + // This optimization only works when the entire invalid region is contained + // within the plugin. There is a related optimization in PaintRect for the + // case where there may be multiple invalid regions. TransportDIB::Id dib_id = TransportDIB::Id(); TransportDIB* dib = NULL; std::vector<gfx::Rect> copy_rects; @@ -864,13 +907,13 @@ void RenderWidget::OnSetTextDirection(WebTextDirection direction) { webwidget_->setTextDirection(direction); } -bool RenderWidget::GetBitmapForOptimizedPluginPaint( +webkit::ppapi::PluginInstance* RenderWidget::GetBitmapForOptimizedPluginPaint( const gfx::Rect& paint_bounds, TransportDIB** dib, gfx::Rect* location, gfx::Rect* clip) { - // Normal RenderWidgets don't support optimized plugin painting. - return false; + // Bare RenderWidgets don't support optimized plugin painting. + return NULL; } void RenderWidget::SetHidden(bool hidden) { diff --git a/chrome/renderer/render_widget.h b/chrome/renderer/render_widget.h index 92826e9..bf542bf 100644 --- a/chrome/renderer/render_widget.h +++ b/chrome/renderer/render_widget.h @@ -49,8 +49,12 @@ struct WebPopupMenuInfo; namespace webkit { namespace npapi { struct WebPluginGeometry; -} -} +} // namespace npapi + +namespace ppapi { +class PluginInstance; +} // namespace ppapi +} // namespace webkit // RenderWidget provides a communication bridge between a WebWidget and // a RenderWidgetHost, the latter of which lives in a different process. @@ -202,13 +206,14 @@ class RenderWidget : public IPC::Channel::Listener, // Detects if a suitable opaque plugin covers the given paint bounds with no // compositing necessary. // - // Returns true if the paint can be handled by just blitting the plugin - // bitmap. In this case, the location, clipping, and ID of the backing store - // will be filled into the given output parameters. + // Returns the plugin instance that's the source of the paint if the paint + // can be handled by just blitting the plugin bitmap. In this case, the + // location, clipping, and ID of the backing store will be filled into the + // given output parameters. // - // A return value of false means optimized painting can not be used and we + // A return value of null means optimized painting can not be used and we // should continue with the normal painting code path. - virtual bool GetBitmapForOptimizedPluginPaint( + virtual webkit::ppapi::PluginInstance* GetBitmapForOptimizedPluginPaint( const gfx::Rect& paint_bounds, TransportDIB** dib, gfx::Rect* location, diff --git a/chrome/renderer/render_widget_fullscreen_pepper.cc b/chrome/renderer/render_widget_fullscreen_pepper.cc index 3df4be2..42b7a93 100644 --- a/chrome/renderer/render_widget_fullscreen_pepper.cc +++ b/chrome/renderer/render_widget_fullscreen_pepper.cc @@ -217,14 +217,15 @@ void RenderWidgetFullscreenPepper::GenerateFullRepaint() { didInvalidateRect(gfx::Rect(size_.width(), size_.height())); } -bool RenderWidgetFullscreenPepper::GetBitmapForOptimizedPluginPaint( +webkit::ppapi::PluginInstance* +RenderWidgetFullscreenPepper::GetBitmapForOptimizedPluginPaint( const gfx::Rect& paint_bounds, TransportDIB** dib, gfx::Rect* location, gfx::Rect* clip) { - if (plugin_) { - return plugin_->GetBitmapForOptimizedPluginPaint( - paint_bounds, dib, location, clip); - } - return false; + if (plugin_ && + plugin_->GetBitmapForOptimizedPluginPaint(paint_bounds, dib, + location, clip)) + return plugin_; + return NULL; } diff --git a/chrome/renderer/render_widget_fullscreen_pepper.h b/chrome/renderer/render_widget_fullscreen_pepper.h index 4d74b1d..7133ec5 100644 --- a/chrome/renderer/render_widget_fullscreen_pepper.h +++ b/chrome/renderer/render_widget_fullscreen_pepper.h @@ -47,7 +47,7 @@ class RenderWidgetFullscreenPepper : public RenderWidgetFullscreen { virtual void DidInitiatePaint(); virtual void DidFlushPaint(); virtual void Close(); - virtual bool GetBitmapForOptimizedPluginPaint( + virtual webkit::ppapi::PluginInstance* GetBitmapForOptimizedPluginPaint( const gfx::Rect& paint_bounds, TransportDIB** dib, gfx::Rect* location, |