OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "skia/ext/bitmap_platform_device_linux.h" | 5 #include "skia/ext/bitmap_platform_device_linux.h" |
6 | 6 |
7 #include <cairo/cairo.h> | 7 #include <cairo/cairo.h> |
| 8 #include <cairo/cairo-xlib.h> |
| 9 #include <gdk/gdk.h> |
| 10 #include <gdk/gdkx.h> |
8 | 11 |
9 namespace skia { | 12 namespace skia { |
10 | 13 |
11 // ----------------------------------------------------------------------------- | 14 // ----------------------------------------------------------------------------- |
12 // These objects are reference counted and own a Cairo surface. The surface is | 15 // These objects are reference counted and own a Cairo surface. The surface is |
13 // the backing store for a Skia bitmap and we reference count it so that we can | 16 // the backing store for a Skia bitmap and we reference count it so that we can |
14 // copy BitmapPlatformDeviceLinux objects without having to copy all the image | 17 // copy BitmapPlatformDeviceLinux objects without having to copy all the image |
15 // data. | 18 // data. |
16 // ----------------------------------------------------------------------------- | 19 // ----------------------------------------------------------------------------- |
17 class BitmapPlatformDeviceLinux::BitmapPlatformDeviceLinuxData | 20 class BitmapPlatformDeviceLinux::BitmapPlatformDeviceLinuxData |
18 : public base::RefCounted<BitmapPlatformDeviceLinuxData> { | 21 : public base::RefCounted<BitmapPlatformDeviceLinuxData> { |
19 public: | 22 public: |
20 explicit BitmapPlatformDeviceLinuxData(cairo_surface_t* surface) | 23 explicit BitmapPlatformDeviceLinuxData(cairo_surface_t* surface) |
21 : surface_(surface) { } | 24 : surface_(surface), pixmap_(NULL) { } |
22 | 25 |
23 cairo_surface_t* surface() const { return surface_; } | 26 cairo_surface_t* surface() const { return surface_; } |
24 | 27 |
| 28 // We can optionally track a pixmap that is temporarily holding the |
| 29 // content of our surface. This is only necessary for plugin |
| 30 // rendering. Takes ownership of the pixmap. |
| 31 void set_pixmap(GdkPixmap* pixmap) { pixmap_ = pixmap; } |
| 32 GdkPixmap* pixmap() const { return pixmap_; } |
| 33 |
| 34 void FreePixmap() { |
| 35 if (pixmap_) { |
| 36 g_object_unref(pixmap_); |
| 37 pixmap_ = NULL; |
| 38 } |
| 39 } |
| 40 |
25 protected: | 41 protected: |
26 cairo_surface_t *const surface_; | 42 cairo_surface_t *const surface_; |
27 | 43 |
| 44 GdkPixmap* pixmap_; |
| 45 |
28 friend class base::RefCounted<BitmapPlatformDeviceLinuxData>; | 46 friend class base::RefCounted<BitmapPlatformDeviceLinuxData>; |
29 ~BitmapPlatformDeviceLinuxData() { | 47 ~BitmapPlatformDeviceLinuxData() { |
| 48 FreePixmap(); |
30 cairo_surface_destroy(surface_); | 49 cairo_surface_destroy(surface_); |
31 } | 50 } |
32 | 51 |
33 // Disallow copy & assign. | 52 // Disallow copy & assign. |
34 BitmapPlatformDeviceLinuxData(const BitmapPlatformDeviceLinuxData&); | 53 BitmapPlatformDeviceLinuxData(const BitmapPlatformDeviceLinuxData&); |
35 BitmapPlatformDeviceLinuxData& operator=( | 54 BitmapPlatformDeviceLinuxData& operator=( |
36 const BitmapPlatformDeviceLinuxData&); | 55 const BitmapPlatformDeviceLinuxData&); |
37 }; | 56 }; |
38 | 57 |
39 // We use this static factory function instead of the regular constructor so | 58 // We use this static factory function instead of the regular constructor so |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
89 BitmapPlatformDeviceLinux::BitmapPlatformDeviceLinux( | 108 BitmapPlatformDeviceLinux::BitmapPlatformDeviceLinux( |
90 const BitmapPlatformDeviceLinux& other) | 109 const BitmapPlatformDeviceLinux& other) |
91 : PlatformDeviceLinux(const_cast<BitmapPlatformDeviceLinux&>( | 110 : PlatformDeviceLinux(const_cast<BitmapPlatformDeviceLinux&>( |
92 other).accessBitmap(true)), | 111 other).accessBitmap(true)), |
93 data_(other.data_) { | 112 data_(other.data_) { |
94 } | 113 } |
95 | 114 |
96 BitmapPlatformDeviceLinux::~BitmapPlatformDeviceLinux() { | 115 BitmapPlatformDeviceLinux::~BitmapPlatformDeviceLinux() { |
97 } | 116 } |
98 | 117 |
| 118 PlatformDeviceLinux::XDrawable BitmapPlatformDeviceLinux::GetXDrawable() { |
| 119 // We've been asked to provide an XDrawable representing our surface. |
| 120 // We create one and copy our content into it. |
| 121 |
| 122 data_->FreePixmap(); |
| 123 |
| 124 // sys_visual is owned by gdk; we shouldn't free it. |
| 125 GdkVisual* sys_visual = gdk_visual_get_system(); |
| 126 GdkPixmap* pixmap = |
| 127 gdk_pixmap_new(NULL, // use width/height/depth params |
| 128 cairo_image_surface_get_width(data_->surface()), |
| 129 cairo_image_surface_get_height(data_->surface()), |
| 130 sys_visual->depth); |
| 131 // XXX we leak the colormap. |
| 132 GdkColormap* colormap = gdk_colormap_new(gdk_visual_get_system(), |
| 133 FALSE); |
| 134 gdk_drawable_set_colormap(GDK_DRAWABLE(pixmap), colormap); |
| 135 cairo_t* pix_cairo = gdk_cairo_create(GDK_DRAWABLE(pixmap)); |
| 136 |
| 137 // Copy the current content to the pixmap. |
| 138 cairo_set_source_surface(pix_cairo, data_->surface(), 0, 0); |
| 139 cairo_paint(pix_cairo); |
| 140 |
| 141 cairo_destroy(pix_cairo); |
| 142 |
| 143 data_->set_pixmap(pixmap); |
| 144 return GDK_PIXMAP_XID(pixmap); |
| 145 } |
| 146 |
| 147 void BitmapPlatformDeviceLinux::onAccessBitmap(SkBitmap* bitmap) { |
| 148 // TODO(evanm): OPTIMIZATION: We should only flush if we know a drawing |
| 149 // operation has occurred on our pixmap. (This note is copied over from |
| 150 // the Windows code). |
| 151 if (!data_->pixmap()) |
| 152 return; |
| 153 |
| 154 // The plugin has finished its drawing over our pixmap; we need to |
| 155 // copy it back into our backing buffer. |
| 156 cairo_t* cairo = cairo_create(data_->surface()); |
| 157 gdk_cairo_set_source_pixmap(cairo, data_->pixmap(), |
| 158 0, 0); // destination (x, y) |
| 159 cairo_paint(cairo); |
| 160 cairo_destroy(cairo); |
| 161 data_->FreePixmap(); |
| 162 } |
| 163 |
99 cairo_surface_t* BitmapPlatformDeviceLinux::surface() const { | 164 cairo_surface_t* BitmapPlatformDeviceLinux::surface() const { |
100 return data_->surface(); | 165 return data_->surface(); |
101 } | 166 } |
102 | 167 |
103 BitmapPlatformDeviceLinux& BitmapPlatformDeviceLinux::operator=( | 168 BitmapPlatformDeviceLinux& BitmapPlatformDeviceLinux::operator=( |
104 const BitmapPlatformDeviceLinux& other) { | 169 const BitmapPlatformDeviceLinux& other) { |
105 data_ = other.data_; | 170 data_ = other.data_; |
106 return *this; | 171 return *this; |
107 } | 172 } |
108 | 173 |
109 } // namespace skia | 174 } // namespace skia |
OLD | NEW |