diff options
author | brettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-09-24 05:39:15 +0000 |
---|---|---|
committer | brettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-09-24 05:39:15 +0000 |
commit | ca4847f0a19f9565b6ca19fa47729bb746f5f736 (patch) | |
tree | b8dd17796537fa49e00f66b8d3f9ac8d1c90b9d8 /webkit | |
parent | 61b4a61bf1ea2a610c076cb28de59aa1137b3c4f (diff) | |
download | chromium_src-ca4847f0a19f9565b6ca19fa47729bb746f5f736.zip chromium_src-ca4847f0a19f9565b6ca19fa47729bb746f5f736.tar.gz chromium_src-ca4847f0a19f9565b6ca19fa47729bb746f5f736.tar.bz2 |
Add some optimizations to plugin painting.
The simplest one is to disable blending when the plugin is opaque. The more
complicated one is to bypass webkit painting the background of plugins when we
know the plugin to be always on top and also opaque. The always on top flag is
currently set by a new "Private2" API. Bypassing WebKit makes animations
faster.
This is a re-land of the previous patch with a trivial compilation fix. This
also adds a clip rect to the GetBitmap... function so we can properly handle
plugins in nested iframes with proper clipping.
BUG=none
TEST=none
Original review URL: http://codereview.chromium.org/3421030
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@60426 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit')
-rw-r--r-- | webkit/glue/plugins/pepper_graphics_2d.cc | 18 | ||||
-rw-r--r-- | webkit/glue/plugins/pepper_graphics_2d.h | 6 | ||||
-rw-r--r-- | webkit/glue/plugins/pepper_image_data.h | 4 | ||||
-rw-r--r-- | webkit/glue/plugins/pepper_plugin_delegate.h | 4 | ||||
-rw-r--r-- | webkit/glue/plugins/pepper_plugin_instance.cc | 28 | ||||
-rw-r--r-- | webkit/glue/plugins/pepper_plugin_instance.h | 17 | ||||
-rw-r--r-- | webkit/glue/plugins/pepper_plugin_module.cc | 4 | ||||
-rw-r--r-- | webkit/glue/plugins/pepper_private2.cc | 32 | ||||
-rw-r--r-- | webkit/glue/plugins/pepper_private2.h | 23 | ||||
-rw-r--r-- | webkit/glue/plugins/ppb_private2.h | 21 | ||||
-rw-r--r-- | webkit/glue/webkit_glue.gypi | 2 |
11 files changed, 156 insertions, 3 deletions
diff --git a/webkit/glue/plugins/pepper_graphics_2d.cc b/webkit/glue/plugins/pepper_graphics_2d.cc index 049c17d..5011f87 100644 --- a/webkit/glue/plugins/pepper_graphics_2d.cc +++ b/webkit/glue/plugins/pepper_graphics_2d.cc @@ -174,7 +174,8 @@ Graphics2D::Graphics2D(PluginModule* module) : Resource(module), bound_instance_(NULL), flushed_any_data_(false), - offscreen_flush_pending_(false) { + offscreen_flush_pending_(false), + is_always_opaque_(false) { } Graphics2D::~Graphics2D() { @@ -193,7 +194,7 @@ bool Graphics2D::Init(int width, int height, bool is_always_opaque) { image_data_ = NULL; return false; } - + is_always_opaque_ = is_always_opaque; return true; } @@ -445,13 +446,24 @@ void Graphics2D::Paint(WebKit::WebCanvas* canvas, bounds.size.width = backing_bitmap.width(); bounds.size.height = backing_bitmap.height(); + // TODO(brettw) bug 56673: do a direct memcpy instead of going through CG + // if the is_always_opaque_ flag is set. + CGContextDrawImage(canvas, bounds, image); CGContextRestoreGState(canvas); #else + SkPaint paint; + if (is_always_opaque_) { + // When we know the device is opaque, we can disable blending for slightly + // more optimized painting. + paint.setXfermodeMode(SkXfermode::kSrc_Mode); + } + gfx::Point origin(plugin_rect.origin().x(), plugin_rect.origin().y()); canvas->drawBitmap(backing_bitmap, SkIntToScalar(plugin_rect.origin().x()), - SkIntToScalar(plugin_rect.origin().y())); + SkIntToScalar(plugin_rect.origin().y()), + &paint); #endif } diff --git a/webkit/glue/plugins/pepper_graphics_2d.h b/webkit/glue/plugins/pepper_graphics_2d.h index c3fad68..3af84ded 100644 --- a/webkit/glue/plugins/pepper_graphics_2d.h +++ b/webkit/glue/plugins/pepper_graphics_2d.h @@ -36,6 +36,8 @@ class Graphics2D : public Resource { bool Init(int width, int height, bool is_always_opaque); + bool is_always_opaque() const { return is_always_opaque_; } + // Resource override. virtual Graphics2D* AsGraphics2D() { return this; } @@ -166,6 +168,10 @@ class Graphics2D : public Resource { // enforce the "only one pending flush at a time" constraint in the API. bool offscreen_flush_pending_; + // Set to true if the plugin declares that this device will always be opaque. + // This allows us to do more optimized painting in some cases. + bool is_always_opaque_; + DISALLOW_COPY_AND_ASSIGN(Graphics2D); }; diff --git a/webkit/glue/plugins/pepper_image_data.h b/webkit/glue/plugins/pepper_image_data.h index c5937b2..04d769c 100644 --- a/webkit/glue/plugins/pepper_image_data.h +++ b/webkit/glue/plugins/pepper_image_data.h @@ -37,6 +37,10 @@ class ImageData : public Resource { // invalid or not mapped. See ImageDataAutoMapper below. bool is_mapped() const { return !!mapped_canvas_.get(); } + PluginDelegate::PlatformImage2D* platform_image() const { + return platform_image_.get(); + } + // Returns a pointer to the interface implementing PPB_ImageData that is // exposed to the plugin. static const PPB_ImageData* GetInterface(); diff --git a/webkit/glue/plugins/pepper_plugin_delegate.h b/webkit/glue/plugins/pepper_plugin_delegate.h index d650fa9..3bd8897 100644 --- a/webkit/glue/plugins/pepper_plugin_delegate.h +++ b/webkit/glue/plugins/pepper_plugin_delegate.h @@ -44,6 +44,8 @@ struct PP_VideoCompressedDataBuffer_Dev; struct PP_VideoDecoderConfig_Dev; struct PP_VideoUncompressedDataBuffer_Dev; +class TransportDIB; + namespace pepper { class FileIO; @@ -67,6 +69,8 @@ class PluginDelegate { // this image. This is used by NativeClient to send the image to the // out-of-process plugin. Returns 0 on failure. virtual intptr_t GetSharedMemoryHandle() const = 0; + + virtual TransportDIB* GetTransportDIB() const = 0; }; class PlatformContext3D { diff --git a/webkit/glue/plugins/pepper_plugin_instance.cc b/webkit/glue/plugins/pepper_plugin_instance.cc index 63ce5c3..b4ccd89 100644 --- a/webkit/glue/plugins/pepper_plugin_instance.cc +++ b/webkit/glue/plugins/pepper_plugin_instance.cc @@ -249,6 +249,7 @@ PluginInstance::PluginInstance(PluginDelegate* delegate, #endif // defined (OS_LINUX) plugin_print_interface_(NULL), plugin_graphics_3d_interface_(NULL), + always_on_top_(false), fullscreen_container_(NULL) { memset(¤t_print_settings_, 0, sizeof(current_print_settings_)); DCHECK(delegate); @@ -518,6 +519,33 @@ void PluginInstance::ViewFlushedPaint() { bound_graphics_2d_->ViewFlushedPaint(); } +bool PluginInstance::GetBitmapForOptimizedPluginPaint( + const gfx::Rect& paint_bounds, + TransportDIB** dib, + gfx::Rect* location, + gfx::Rect* clip) { + if (!always_on_top_) + return false; + if (!bound_graphics_2d_ || !bound_graphics_2d_->is_always_opaque()) + return false; + + // We specifically want to compare against the area covered by the backing + // store when seeing if we cover the given paint bounds, since the backing + // store could be smaller than the declared plugin area. + ImageData* image_data = bound_graphics_2d_->image_data(); + gfx::Rect plugin_backing_store_rect(position_.origin(), + gfx::Size(image_data->width(), + image_data->height())); + gfx::Rect plugin_paint_rect = plugin_backing_store_rect.Intersect(clip_); + if (!plugin_paint_rect.Contains(paint_bounds)) + return false; + + *dib = image_data->platform_image()->GetTransportDIB(); + *location = plugin_backing_store_rect; + *clip = clip_; + return true; +} + string16 PluginInstance::GetSelectedText(bool html) { PP_Var rv = instance_interface_->GetSelectedText(GetPPInstance(), html); scoped_refptr<StringVar> string(StringVar::FromPPVar(rv)); diff --git a/webkit/glue/plugins/pepper_plugin_instance.h b/webkit/glue/plugins/pepper_plugin_instance.h index 902d95e..4eb956f 100644 --- a/webkit/glue/plugins/pepper_plugin_instance.h +++ b/webkit/glue/plugins/pepper_plugin_instance.h @@ -30,6 +30,7 @@ struct PPP_Instance; struct PPP_Zoom_Dev; class SkBitmap; +class TransportDIB; namespace gfx { class Rect; @@ -77,6 +78,8 @@ class PluginInstance : public base::RefCounted<PluginInstance> { int find_identifier() const { return find_identifier_; } + void set_always_on_top(bool on_top) { always_on_top_ = on_top; } + PP_Instance GetPPInstance(); // Paints the current backing store to the web page. @@ -120,6 +123,16 @@ class PluginInstance : public base::RefCounted<PluginInstance> { void ViewInitiatedPaint(); void ViewFlushedPaint(); + // If this plugin can be painted merely by copying the backing store to the + // screen, and the plugin bounds encloses the given paint bounds, returns + // true. In this case, the location, clipping, and ID of the backing store + // will be filled into the given output parameters. + bool GetBitmapForOptimizedPluginPaint( + const gfx::Rect& paint_bounds, + TransportDIB** dib, + gfx::Rect* dib_bounds, + gfx::Rect* clip); + string16 GetSelectedText(bool html); void Zoom(float factor, bool text_only); bool StartFind(const string16& search_text, @@ -232,6 +245,10 @@ class PluginInstance : public base::RefCounted<PluginInstance> { // Containes the cursor if it's set by the plugin. scoped_ptr<WebKit::WebCursorInfo> cursor_; + // Set to true if this plugin thinks it will always be on top. This allows us + // to use a more optimized painting path in some cases. + bool always_on_top_; + // Plugin container for fullscreen mode. NULL if not in fullscreen mode. FullscreenContainer* fullscreen_container_; diff --git a/webkit/glue/plugins/pepper_plugin_module.cc b/webkit/glue/plugins/pepper_plugin_module.cc index 7acf06239..e43735f 100644 --- a/webkit/glue/plugins/pepper_plugin_module.cc +++ b/webkit/glue/plugins/pepper_plugin_module.cc @@ -59,6 +59,7 @@ #include "webkit/glue/plugins/pepper_plugin_instance.h" #include "webkit/glue/plugins/pepper_plugin_object.h" #include "webkit/glue/plugins/pepper_private.h" +#include "webkit/glue/plugins/pepper_private2.h" #include "webkit/glue/plugins/pepper_resource_tracker.h" #include "webkit/glue/plugins/pepper_scrollbar.h" #include "webkit/glue/plugins/pepper_transport.h" @@ -70,6 +71,7 @@ #include "webkit/glue/plugins/pepper_video_decoder.h" #include "webkit/glue/plugins/pepper_widget.h" #include "webkit/glue/plugins/ppb_private.h" +#include "webkit/glue/plugins/ppb_private2.h" #ifdef ENABLE_GPU #include "webkit/glue/plugins/pepper_graphics_3d.h" @@ -257,6 +259,8 @@ const void* GetInterface(const char* name) { return UrlUtil::GetInterface(); if (strcmp(name, PPB_PRIVATE_INTERFACE) == 0) return Private::GetInterface(); + if (strcmp(name, PPB_PRIVATE2_INTERFACE) == 0) + return Private2::GetInterface(); if (strcmp(name, PPB_FILECHOOSER_DEV_INTERFACE) == 0) return FileChooser::GetInterface(); if (strcmp(name, PPB_VIDEODECODER_DEV_INTERFACE) == 0) diff --git a/webkit/glue/plugins/pepper_private2.cc b/webkit/glue/plugins/pepper_private2.cc new file mode 100644 index 0000000..9a740aa --- /dev/null +++ b/webkit/glue/plugins/pepper_private2.cc @@ -0,0 +1,32 @@ +// Copyright (c) 2010 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. + +#include "webkit/glue/plugins/pepper_private2.h" + +#include "webkit/glue/plugins/pepper_plugin_instance.h" +#include "webkit/glue/plugins/ppb_private2.h" + +namespace pepper { + +namespace { + +void SetInstanceAlwaysOnTop(PP_Instance pp_instance, bool on_top) { + PluginInstance* instance = PluginInstance::FromPPInstance(pp_instance); + if (!instance) + return; + instance->set_always_on_top(on_top); +} + +const PPB_Private2 ppb_private2 = { + &SetInstanceAlwaysOnTop +}; + +} // namespace + +// static +const PPB_Private2* Private2::GetInterface() { + return &ppb_private2; +} + +} // namespace pepper diff --git a/webkit/glue/plugins/pepper_private2.h b/webkit/glue/plugins/pepper_private2.h new file mode 100644 index 0000000..492669a --- /dev/null +++ b/webkit/glue/plugins/pepper_private2.h @@ -0,0 +1,23 @@ +// Copyright (c) 2010 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. + +#ifndef WEBKIT_GLUE_PLUGINS_PEPPER_PRIVATE2_H_ +#define WEBKIT_GLUE_PLUGINS_PEPPER_PRIVATE2_H_ + +#include "webkit/glue/plugins/pepper_resource.h" + +struct PPB_Private2; + +namespace pepper { + +class Private2 { + public: + // Returns a pointer to the interface implementing PPB_Private2 that is + // exposed to the plugin. + static const PPB_Private2* GetInterface(); +}; + +} // namespace pepper + +#endif // WEBKIT_GLUE_PLUGINS_PEPPER_PRIVATE2_H_ diff --git a/webkit/glue/plugins/ppb_private2.h b/webkit/glue/plugins/ppb_private2.h new file mode 100644 index 0000000..ca45471 --- /dev/null +++ b/webkit/glue/plugins/ppb_private2.h @@ -0,0 +1,21 @@ +// Copyright (c) 2010 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. + +#ifndef WEBKIT_GLUE_PLUGINS_PPB_PRIVATE2_H_ +#define WEBKIT_GLUE_PLUGINS_PPB_PRIVATE2_H_ + +#include "third_party/ppapi/c/pp_instance.h" +#include "third_party/ppapi/c/pp_module.h" +#include "third_party/ppapi/c/pp_var.h" + +#define PPB_PRIVATE2_INTERFACE "PPB_Private2;1" + +struct PPB_Private2 { + // Sets or clears the rendering hint that the given plugin instance is always + // on top of page content. Somewhat more optimized painting can be used in + // this case. + void (*SetInstanceAlwaysOnTop)(PP_Instance instance, bool on_top); +}; + +#endif // WEBKIT_GLUE_PLUGINS_PPB_PRIVATE2_H_ diff --git a/webkit/glue/webkit_glue.gypi b/webkit/glue/webkit_glue.gypi index e27f297..354b2d0 100644 --- a/webkit/glue/webkit_glue.gypi +++ b/webkit/glue/webkit_glue.gypi @@ -222,6 +222,8 @@ 'plugins/pepper_plugin_object.h', 'plugins/pepper_private.cc', 'plugins/pepper_private.h', + 'plugins/pepper_private2.cc', + 'plugins/pepper_private2.h', 'plugins/pepper_resource_tracker.cc', 'plugins/pepper_resource_tracker.h', 'plugins/pepper_resource.cc', |