summaryrefslogtreecommitdiffstats
path: root/webkit
diff options
context:
space:
mode:
authorpiman@chromium.org <piman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-08-05 02:54:42 +0000
committerpiman@chromium.org <piman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-08-05 02:54:42 +0000
commitcb632c310910db456fbc3083fcad1fce0e1a2197 (patch)
tree73892688ceae64bf6b01f25c721a04f06e285a72 /webkit
parent5d682cb2177736c065b7ff271c6151c73fdc8caf (diff)
downloadchromium_src-cb632c310910db456fbc3083fcad1fce0e1a2197.zip
chromium_src-cb632c310910db456fbc3083fcad1fce0e1a2197.tar.gz
chromium_src-cb632c310910db456fbc3083fcad1fce0e1a2197.tar.bz2
If SHM pixmaps support is available, for example, Intel drivers now support that
(http://cgit.freedesktop.org/xorg/driver/xf86-video-intel/commit/?id=4b7142baa0b3bf6f38843d06aadc579d8624cefc), use SHM pixmaps support to accelerate windowless plugin painting. Modify WindowlessPaint to directly use Xlib interfaces for SHM pixmaps support, similarly to the way how backing_store_x handles different SHM support levels provided by X server. BUG=50912 TEST=Open the page "http://disney.go.com/official-sites/demi-lovato/albums" using Chromium browser, compare the CPU usage of browser and X server before and after the change, and confirm CPU usage is reduced with this change (for example, on an Atom N450 Netbook with MeeGo 1.0 and Chromium browser 6.0.417.0 there's >30% CPU usage reduction, especially X server CPU usage is reduced by half). Review URL: http://codereview.chromium.org/3052039 Patch from Yuqiang Xian <yuqiang.xian@intel.com>. git-svn-id: svn://svn.chromium.org/chrome/trunk/src@55020 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit')
-rw-r--r--webkit/glue/plugins/webplugin_delegate_impl.h11
-rw-r--r--webkit/glue/plugins/webplugin_delegate_impl_gtk.cc109
2 files changed, 92 insertions, 28 deletions
diff --git a/webkit/glue/plugins/webplugin_delegate_impl.h b/webkit/glue/plugins/webplugin_delegate_impl.h
index ebf5d3e..1c7ccb2 100644
--- a/webkit/glue/plugins/webplugin_delegate_impl.h
+++ b/webkit/glue/plugins/webplugin_delegate_impl.h
@@ -27,6 +27,8 @@
#endif
#if defined(USE_X11)
+#include "app/x11_util.h"
+
typedef struct _GdkDrawable GdkPixmap;
#endif
@@ -181,6 +183,12 @@ class WebPluginDelegateImpl : public webkit_glue::WebPluginDelegate {
void set_windowed_handle(gfx::PluginWindowHandle handle);
#endif
+#if defined(USE_X11)
+ void SetWindowlessShmPixmap(XID shm_pixmap) {
+ windowless_shm_pixmap_ = shm_pixmap;
+ }
+#endif
+
private:
friend class DeleteTask<WebPluginDelegateImpl>;
friend class webkit_glue::WebPluginDelegate;
@@ -292,6 +300,9 @@ class WebPluginDelegateImpl : public webkit_glue::WebPluginDelegate {
#endif // OS_WIN
#if defined(USE_X11)
+ // The SHM pixmap for a windowless plugin.
+ XID windowless_shm_pixmap_;
+
// The pixmap we're drawing into, for a windowless plugin.
GdkPixmap* pixmap_;
double first_event_time_;
diff --git a/webkit/glue/plugins/webplugin_delegate_impl_gtk.cc b/webkit/glue/plugins/webplugin_delegate_impl_gtk.cc
index 18b1504..d4a98a8 100644
--- a/webkit/glue/plugins/webplugin_delegate_impl_gtk.cc
+++ b/webkit/glue/plugins/webplugin_delegate_impl_gtk.cc
@@ -44,6 +44,7 @@ WebPluginDelegateImpl::WebPluginDelegateImpl(
windowless_(false),
plugin_(NULL),
instance_(instance),
+ windowless_shm_pixmap_(None),
pixmap_(NULL),
first_event_time_(-1.0),
plug_(NULL),
@@ -399,47 +400,99 @@ void WebPluginDelegateImpl::WindowlessPaint(cairo_t* context,
pixmap_draw_rect.right(),
pixmap_draw_rect.bottom());
- EnsurePixmapAtLeastSize(pixmap_rect.width(), pixmap_rect.height());
-
- // Copy the current image into the pixmap, so the plugin can draw over
- // this background.
- cairo_t* cairo = gdk_cairo_create(pixmap_);
- BlitContextToContext(cairo, pixmap_draw_rect, context, draw_rect.origin());
- cairo_destroy(cairo);
-
// Construct the paint message, targeting the pixmap.
NPEvent np_event = {0};
XGraphicsExposeEvent &event = np_event.xgraphicsexpose;
event.type = GraphicsExpose;
- event.display = GDK_DISPLAY();
- event.drawable = GDK_PIXMAP_XID(pixmap_);
event.x = pixmap_draw_rect.x();
event.y = pixmap_draw_rect.y();
event.width = pixmap_draw_rect.width();
event.height = pixmap_draw_rect.height();
+ event.display = GDK_DISPLAY();
+
+ if (windowless_shm_pixmap_ != None) {
+ Pixmap pixmap = None;
+ GC xgc = NULL;
+ Display* display = event.display;
+ gfx::Rect plugin_draw_rect = draw_rect;
+
+ // Make plugin_draw_rect relative to the plugin window.
+ plugin_draw_rect.Offset(-window_rect_.x(), -window_rect_.y());
+
+ // In case the drawing area does not start with the plugin window origin,
+ // we can not let the plugin directly draw over the shared memory pixmap.
+ if (plugin_draw_rect.x() != pixmap_draw_rect.x() ||
+ plugin_draw_rect.y() != pixmap_draw_rect.y()) {
+ pixmap = XCreatePixmap(display, windowless_shm_pixmap_,
+ std::max(1, pixmap_rect.width()),
+ std::max(1, pixmap_rect.height()),
+ DefaultDepth(display, 0));
+ xgc = XCreateGC(display, windowless_shm_pixmap_, 0, NULL);
+ // Copy the current image into the pixmap, so the plugin can draw over it.
+ XCopyArea(display, windowless_shm_pixmap_, pixmap, xgc,
+ plugin_draw_rect.x(), plugin_draw_rect.y(),
+ pixmap_draw_rect.width(), pixmap_draw_rect.height(),
+ pixmap_draw_rect.x(), pixmap_draw_rect.y());
+
+ event.drawable = pixmap;
+ } else {
+ event.drawable = windowless_shm_pixmap_;
+ }
+
+ // Tell the plugin to paint into the pixmap.
+ static StatsRate plugin_paint("Plugin.Paint");
+ StatsScope<StatsRate> scope(plugin_paint);
+ NPError err = instance()->NPP_HandleEvent(&np_event);
+ DCHECK_EQ(err, NPERR_NO_ERROR);
+
+ if (pixmap != None) {
+ // Copy the rendered image pixmap back into the shm pixmap
+ // and thus the drawing buffer.
+ XCopyArea(display, pixmap, windowless_shm_pixmap_, xgc,
+ pixmap_draw_rect.x(), pixmap_draw_rect.y(),
+ pixmap_draw_rect.width(), pixmap_draw_rect.height(),
+ plugin_draw_rect.x(), plugin_draw_rect.y());
+ XSync(display, FALSE);
+ if (xgc)
+ XFreeGC(display, xgc);
+ XFreePixmap(display, pixmap);
+ } else {
+ XSync(display, FALSE);
+ }
+ } else {
+ EnsurePixmapAtLeastSize(pixmap_rect.width(), pixmap_rect.height());
- // Tell the plugin to paint into the pixmap.
- static StatsRate plugin_paint("Plugin.Paint");
- StatsScope<StatsRate> scope(plugin_paint);
- NPError err = instance()->NPP_HandleEvent(&np_event);
- DCHECK_EQ(err, NPERR_NO_ERROR);
+ // Copy the current image into the pixmap, so the plugin can draw over
+ // this background.
+ cairo_t* cairo = gdk_cairo_create(pixmap_);
+ BlitContextToContext(cairo, pixmap_draw_rect, context, draw_rect.origin());
+ cairo_destroy(cairo);
- cairo_save(context);
- // Now copy the rendered image pixmap back into the drawing buffer.
- gdk_cairo_set_source_pixmap(context, pixmap_, -offset_x, -offset_y);
- cairo_rectangle(context, draw_rect.x(), draw_rect.y(),
- draw_rect.width(), draw_rect.height());
- cairo_clip(context);
- cairo_paint(context);
+ event.drawable = GDK_PIXMAP_XID(pixmap_);
+
+ // Tell the plugin to paint into the pixmap.
+ static StatsRate plugin_paint("Plugin.Paint");
+ StatsScope<StatsRate> scope(plugin_paint);
+ NPError err = instance()->NPP_HandleEvent(&np_event);
+ DCHECK_EQ(err, NPERR_NO_ERROR);
+
+ cairo_save(context);
+ // Now copy the rendered image pixmap back into the drawing buffer.
+ gdk_cairo_set_source_pixmap(context, pixmap_, -offset_x, -offset_y);
+ cairo_rectangle(context, draw_rect.x(), draw_rect.y(),
+ draw_rect.width(), draw_rect.height());
+ cairo_clip(context);
+ cairo_paint(context);
#ifdef DEBUG_RECTANGLES
- // Draw some debugging rectangles.
- // Pixmap rect = blue.
- DrawDebugRectangle(context, pixmap_rect, 0, 0, 1);
- // Drawing rect = red.
- DrawDebugRectangle(context, draw_rect, 1, 0, 0);
+ // Draw some debugging rectangles.
+ // Pixmap rect = blue.
+ DrawDebugRectangle(context, pixmap_rect, 0, 0, 1);
+ // Drawing rect = red.
+ DrawDebugRectangle(context, draw_rect, 1, 0, 0);
#endif
- cairo_restore(context);
+ cairo_restore(context);
+ }
}
void WebPluginDelegateImpl::WindowlessSetWindow() {