1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/browser/compositor/software_output_device_x11.h"
10 #include "content/public/browser/browser_thread.h"
11 #include "third_party/skia/include/core/SkBitmap.h"
12 #include "third_party/skia/include/core/SkDevice.h"
13 #include "ui/base/x/x11_util.h"
14 #include "ui/base/x/x11_util_internal.h"
15 #include "ui/compositor/compositor.h"
16 #include "ui/gfx/x/x11_types.h"
20 SoftwareOutputDeviceX11::SoftwareOutputDeviceX11(ui::Compositor
* compositor
)
21 : compositor_(compositor
), display_(gfx::GetXDisplay()), gc_(NULL
) {
22 // TODO(skaslev) Remove this when crbug.com/180702 is fixed.
23 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
25 gc_
= XCreateGC(display_
, compositor_
->widget(), 0, NULL
);
26 if (!XGetWindowAttributes(display_
, compositor_
->widget(), &attributes_
)) {
27 LOG(ERROR
) << "XGetWindowAttributes failed for window "
28 << compositor_
->widget();
33 SoftwareOutputDeviceX11::~SoftwareOutputDeviceX11() {
34 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
36 XFreeGC(display_
, gc_
);
39 void SoftwareOutputDeviceX11::EndPaint() {
40 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
42 SoftwareOutputDevice::EndPaint();
47 gfx::Rect rect
= damage_rect_
;
48 rect
.Intersect(gfx::Rect(viewport_pixel_size_
));
52 int bpp
= gfx::BitsPerPixelForPixmapDepth(display_
, attributes_
.depth
);
54 if (bpp
!= 32 && bpp
!= 16 && ui::QueryRenderSupport(display_
)) {
55 // gfx::PutARGBImage only supports 16 and 32 bpp, but Xrender can do other
57 Pixmap pixmap
= XCreatePixmap(
58 display_
, compositor_
->widget(), rect
.width(), rect
.height(), 32);
59 GC gc
= XCreateGC(display_
, pixmap
, 0, NULL
);
61 memset(&image
, 0, sizeof(image
));
65 const void* addr
= surface_
->peekPixels(&info
, &rowBytes
);
66 image
.width
= viewport_pixel_size_
.width();
67 image
.height
= viewport_pixel_size_
.height();
69 image
.bits_per_pixel
= 32;
70 image
.format
= ZPixmap
;
71 image
.byte_order
= LSBFirst
;
72 image
.bitmap_unit
= 8;
73 image
.bitmap_bit_order
= LSBFirst
;
74 image
.bytes_per_line
= rowBytes
;
75 image
.red_mask
= 0xff;
76 image
.green_mask
= 0xff00;
77 image
.blue_mask
= 0xff0000;
78 image
.data
= const_cast<char*>(static_cast<const char*>(addr
));
85 rect
.y() /* source x, y */,
90 XFreeGC(display_
, gc
);
91 Picture picture
= XRenderCreatePicture(
92 display_
, pixmap
, ui::GetRenderARGB32Format(display_
), 0, NULL
);
93 XRenderPictFormat
* pictformat
=
94 XRenderFindVisualFormat(display_
, attributes_
.visual
);
95 Picture dest_picture
= XRenderCreatePicture(
96 display_
, compositor_
->widget(), pictformat
, 0, NULL
);
97 XRenderComposite(display_
,
101 dest_picture
, // dest
108 rect
.width(), // width
109 rect
.height()); // height
110 XRenderFreePicture(display_
, picture
);
111 XRenderFreePicture(display_
, dest_picture
);
112 XFreePixmap(display_
, pixmap
);
116 // TODO(jbauman): Switch to XShmPutImage since it's async.
119 const void* addr
= surface_
->peekPixels(&info
, &rowBytes
);
120 gfx::PutARGBImage(display_
,
123 compositor_
->widget(),
125 static_cast<const uint8
*>(addr
),
126 viewport_pixel_size_
.width(),
127 viewport_pixel_size_
.height(),
136 } // namespace content