#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"
void SoftwareOutputDeviceX11::EndPaint(cc::SoftwareFrameData* frame_data) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- DCHECK(device_);
+ DCHECK(canvas_);
DCHECK(frame_data);
- if (!device_)
+ if (!canvas_)
return;
SoftwareOutputDevice::EndPaint(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.
- const SkBitmap& bitmap = device_->accessBitmap(false);
+ SkImageInfo info;
+ size_t rowBytes;
+ const void* addr = canvas_->peekPixels(&info, &rowBytes);
gfx::PutARGBImage(display_,
attributes_.visual,
attributes_.depth,
compositor_->widget(),
gc_,
- static_cast<const uint8*>(bitmap.getPixels()),
+ static_cast<const uint8*>(addr),
viewport_size_.width(),
viewport_size_.height(),
rect.x(),