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(cc::SoftwareFrameData
* frame_data
) {
40 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
47 SoftwareOutputDevice::EndPaint(frame_data
);
49 gfx::Rect rect
= damage_rect_
;
50 rect
.Intersect(gfx::Rect(viewport_pixel_size_
));
54 int bpp
= gfx::BitsPerPixelForPixmapDepth(display_
, attributes_
.depth
);
56 if (bpp
!= 32 && bpp
!= 16 && ui::QueryRenderSupport(display_
)) {
57 // gfx::PutARGBImage only supports 16 and 32 bpp, but Xrender can do other
59 Pixmap pixmap
= XCreatePixmap(
60 display_
, compositor_
->widget(), rect
.width(), rect
.height(), 32);
61 GC gc
= XCreateGC(display_
, pixmap
, 0, NULL
);
63 memset(&image
, 0, sizeof(image
));
67 const void* addr
= surface_
->peekPixels(&info
, &rowBytes
);
68 image
.width
= viewport_pixel_size_
.width();
69 image
.height
= viewport_pixel_size_
.height();
71 image
.bits_per_pixel
= 32;
72 image
.format
= ZPixmap
;
73 image
.byte_order
= LSBFirst
;
74 image
.bitmap_unit
= 8;
75 image
.bitmap_bit_order
= LSBFirst
;
76 image
.bytes_per_line
= rowBytes
;
77 image
.red_mask
= 0xff;
78 image
.green_mask
= 0xff00;
79 image
.blue_mask
= 0xff0000;
80 image
.data
= const_cast<char*>(static_cast<const char*>(addr
));
87 rect
.y() /* source x, y */,
92 XFreeGC(display_
, gc
);
93 Picture picture
= XRenderCreatePicture(
94 display_
, pixmap
, ui::GetRenderARGB32Format(display_
), 0, NULL
);
95 XRenderPictFormat
* pictformat
=
96 XRenderFindVisualFormat(display_
, attributes_
.visual
);
97 Picture dest_picture
= XRenderCreatePicture(
98 display_
, compositor_
->widget(), pictformat
, 0, NULL
);
99 XRenderComposite(display_
,
103 dest_picture
, // dest
110 rect
.width(), // width
111 rect
.height()); // height
112 XRenderFreePicture(display_
, picture
);
113 XRenderFreePicture(display_
, dest_picture
);
114 XFreePixmap(display_
, pixmap
);
118 // TODO(jbauman): Switch to XShmPutImage since it's async.
121 const void* addr
= surface_
->peekPixels(&info
, &rowBytes
);
122 gfx::PutARGBImage(display_
,
125 compositor_
->widget(),
127 static_cast<const uint8
*>(addr
),
128 viewport_pixel_size_
.width(),
129 viewport_pixel_size_
.height(),
138 } // namespace content