| Index: skia/ext/bitmap_platform_device_linux.cc
|
| diff --git a/skia/ext/bitmap_platform_device_linux.cc b/skia/ext/bitmap_platform_device_linux.cc
|
| index f6a0e6d07b80e11cb2b8570400a17c2fba5cc84a..310c867bf7612b98489458ebea2f5fc27860218a 100644
|
| --- a/skia/ext/bitmap_platform_device_linux.cc
|
| +++ b/skia/ext/bitmap_platform_device_linux.cc
|
| @@ -5,6 +5,9 @@
|
| #include "skia/ext/bitmap_platform_device_linux.h"
|
|
|
| #include <cairo/cairo.h>
|
| +#include <cairo/cairo-xlib.h>
|
| +#include <gdk/gdk.h>
|
| +#include <gdk/gdkx.h>
|
|
|
| namespace skia {
|
|
|
| @@ -18,15 +21,31 @@ class BitmapPlatformDeviceLinux::BitmapPlatformDeviceLinuxData
|
| : public base::RefCounted<BitmapPlatformDeviceLinuxData> {
|
| public:
|
| explicit BitmapPlatformDeviceLinuxData(cairo_surface_t* surface)
|
| - : surface_(surface) { }
|
| + : surface_(surface), pixmap_(NULL) { }
|
|
|
| cairo_surface_t* surface() const { return surface_; }
|
|
|
| + // We can optionally track a pixmap that is temporarily holding the
|
| + // content of our surface. This is only necessary for plugin
|
| + // rendering. Takes ownership of the pixmap.
|
| + void set_pixmap(GdkPixmap* pixmap) { pixmap_ = pixmap; }
|
| + GdkPixmap* pixmap() const { return pixmap_; }
|
| +
|
| + void FreePixmap() {
|
| + if (pixmap_) {
|
| + g_object_unref(pixmap_);
|
| + pixmap_ = NULL;
|
| + }
|
| + }
|
| +
|
| protected:
|
| cairo_surface_t *const surface_;
|
|
|
| + GdkPixmap* pixmap_;
|
| +
|
| friend class base::RefCounted<BitmapPlatformDeviceLinuxData>;
|
| ~BitmapPlatformDeviceLinuxData() {
|
| + FreePixmap();
|
| cairo_surface_destroy(surface_);
|
| }
|
|
|
| @@ -96,6 +115,52 @@ BitmapPlatformDeviceLinux::BitmapPlatformDeviceLinux(
|
| BitmapPlatformDeviceLinux::~BitmapPlatformDeviceLinux() {
|
| }
|
|
|
| +PlatformDeviceLinux::XDrawable BitmapPlatformDeviceLinux::GetXDrawable() {
|
| + // We've been asked to provide an XDrawable representing our surface.
|
| + // We create one and copy our content into it.
|
| +
|
| + data_->FreePixmap();
|
| +
|
| + // sys_visual is owned by gdk; we shouldn't free it.
|
| + GdkVisual* sys_visual = gdk_visual_get_system();
|
| + GdkPixmap* pixmap =
|
| + gdk_pixmap_new(NULL, // use width/height/depth params
|
| + cairo_image_surface_get_width(data_->surface()),
|
| + cairo_image_surface_get_height(data_->surface()),
|
| + sys_visual->depth);
|
| + // XXX we leak the colormap.
|
| + GdkColormap* colormap = gdk_colormap_new(gdk_visual_get_system(),
|
| + FALSE);
|
| + gdk_drawable_set_colormap(GDK_DRAWABLE(pixmap), colormap);
|
| + cairo_t* pix_cairo = gdk_cairo_create(GDK_DRAWABLE(pixmap));
|
| +
|
| + // Copy the current content to the pixmap.
|
| + cairo_set_source_surface(pix_cairo, data_->surface(), 0, 0);
|
| + cairo_paint(pix_cairo);
|
| +
|
| + cairo_destroy(pix_cairo);
|
| +
|
| + data_->set_pixmap(pixmap);
|
| + return GDK_PIXMAP_XID(pixmap);
|
| +}
|
| +
|
| +void BitmapPlatformDeviceLinux::onAccessBitmap(SkBitmap* bitmap) {
|
| + // TODO(evanm): OPTIMIZATION: We should only flush if we know a drawing
|
| + // operation has occurred on our pixmap. (This note is copied over from
|
| + // the Windows code).
|
| + if (!data_->pixmap())
|
| + return;
|
| +
|
| + // The plugin has finished its drawing over our pixmap; we need to
|
| + // copy it back into our backing buffer.
|
| + cairo_t* cairo = cairo_create(data_->surface());
|
| + gdk_cairo_set_source_pixmap(cairo, data_->pixmap(),
|
| + 0, 0); // destination (x, y)
|
| + cairo_paint(cairo);
|
| + cairo_destroy(cairo);
|
| + data_->FreePixmap();
|
| +}
|
| +
|
| cairo_surface_t* BitmapPlatformDeviceLinux::surface() const {
|
| return data_->surface();
|
| }
|
|
|