Index: content/browser/compositor/software_output_device_x11.cc |
diff --git a/content/browser/compositor/software_output_device_x11.cc b/content/browser/compositor/software_output_device_x11.cc |
index 016b4915f834f8d85daa4111d1d8ca99ed0dac24..44267d4d31ff98a832e1cefccee8c5b11db496cf 100644 |
--- a/content/browser/compositor/software_output_device_x11.cc |
+++ b/content/browser/compositor/software_output_device_x11.cc |
@@ -10,6 +10,8 @@ |
#include "content/public/browser/browser_thread.h" |
#include "third_party/skia/include/core/SkBitmap.h" |
#include "third_party/skia/include/core/SkDevice.h" |
+#include "ui/base/x/x11_util.h" |
+#include "ui/base/x/x11_util_internal.h" |
#include "ui/compositor/compositor.h" |
#include "ui/gfx/x/x11_types.h" |
@@ -49,6 +51,70 @@ void SoftwareOutputDeviceX11::EndPaint(cc::SoftwareFrameData* frame_data) { |
if (rect.IsEmpty()) |
return; |
+ int bpp = gfx::BitsPerPixelForPixmapDepth(display_, attributes_.depth); |
+ |
+ if (bpp != 32 && bpp != 16 && ui::QueryRenderSupport(display_)) { |
+ // gfx::PutARGBImage only supports 16 and 32 bpp, but Xrender can do other |
+ // conversions. |
+ Pixmap pixmap = XCreatePixmap( |
+ display_, compositor_->widget(), rect.width(), rect.height(), 32); |
+ GC gc = XCreateGC(display_, pixmap, 0, NULL); |
+ XImage image; |
+ memset(&image, 0, sizeof(image)); |
+ |
+ SkImageInfo info; |
+ size_t rowBytes; |
+ const void* addr = canvas_->peekPixels(&info, &rowBytes); |
+ image.width = viewport_size_.width(); |
+ image.height = viewport_size_.height(); |
+ image.depth = 32; |
+ image.bits_per_pixel = 32; |
+ image.format = ZPixmap; |
+ image.byte_order = LSBFirst; |
+ image.bitmap_unit = 8; |
+ image.bitmap_bit_order = LSBFirst; |
+ image.bytes_per_line = rowBytes; |
+ image.red_mask = 0xff; |
+ image.green_mask = 0xff00; |
+ image.blue_mask = 0xff0000; |
+ image.data = const_cast<char*>(static_cast<const char*>(addr)); |
+ |
+ XPutImage(display_, |
+ pixmap, |
+ gc, |
+ &image, |
+ rect.x(), |
+ rect.y() /* source x, y */, |
+ 0, |
+ 0 /* dest x, y */, |
+ rect.width(), |
+ rect.height()); |
+ XFreeGC(display_, gc); |
+ Picture picture = XRenderCreatePicture( |
+ display_, pixmap, ui::GetRenderARGB32Format(display_), 0, NULL); |
+ XRenderPictFormat* pictformat = |
+ XRenderFindVisualFormat(display_, attributes_.visual); |
+ Picture dest_picture = XRenderCreatePicture( |
+ display_, compositor_->widget(), pictformat, 0, NULL); |
+ XRenderComposite(display_, |
+ PictOpSrc, // op |
+ picture, // src |
+ 0, // mask |
+ dest_picture, // dest |
+ 0, // src_x |
+ 0, // src_y |
+ 0, // mask_x |
+ 0, // mask_y |
+ rect.x(), // dest_x |
+ rect.y(), // dest_y |
+ rect.width(), // width |
+ rect.height()); // height |
+ XRenderFreePicture(display_, picture); |
+ XRenderFreePicture(display_, dest_picture); |
+ XFreePixmap(display_, pixmap); |
+ return; |
+ } |
+ |
// TODO(jbauman): Switch to XShmPutImage since it's async. |
SkImageInfo info; |
size_t rowBytes; |