1 // Copyright 2020 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.
4
5 #include "ui/gl/gl_image_glx_native_pixmap.h"
6
7 #include <xcb/dri3.h>
8 #include <xcb/xcb.h>
9
10 #include "base/posix/eintr_wrapper.h"
11 #include "ui/gfx/buffer_types.h"
12 #include "ui/gfx/linux/native_pixmap_dmabuf.h"
13 #include "ui/gfx/x/x11.h"
14 #include "ui/gl/buffer_format_utils.h"
15 #include "ui/gl/gl_bindings.h"
16
17 namespace gl {
18
19 namespace {
20
Depth(gfx::BufferFormat format)21 int Depth(gfx::BufferFormat format) {
22 switch (format) {
23 case gfx::BufferFormat::BGR_565:
24 return 16;
25 case gfx::BufferFormat::BGRX_8888:
26 return 24;
27 case gfx::BufferFormat::BGRA_1010102:
28 // It's unclear why this is 32 instead of 30.
29 return 32;
30 case gfx::BufferFormat::BGRA_8888:
31 return 32;
32 default:
33 NOTREACHED();
34 return 0;
35 }
36 }
37
Bpp(gfx::BufferFormat format)38 int Bpp(gfx::BufferFormat format) {
39 switch (format) {
40 case gfx::BufferFormat::BGR_565:
41 return 16;
42 case gfx::BufferFormat::BGRX_8888:
43 case gfx::BufferFormat::BGRA_1010102:
44 case gfx::BufferFormat::BGRA_8888:
45 return 32;
46 default:
47 NOTREACHED();
48 return 0;
49 }
50 }
51
XPixmapFromNativePixmap(const gfx::NativePixmapDmaBuf & native_pixmap,int depth,int bpp)52 XID XPixmapFromNativePixmap(const gfx::NativePixmapDmaBuf& native_pixmap,
53 int depth,
54 int bpp) {
55 XDisplay* display = gfx::GetXDisplay();
56 xcb_connection_t* connection = XGetXCBConnection(display);
57
58 int fd = HANDLE_EINTR(dup(native_pixmap.GetDmaBufFd(0)));
59 if (fd < 0)
60 return 0;
61
62 uint32_t pixmap_id = xcb_generate_id(connection);
63 xcb_dri3_pixmap_from_buffer(connection, pixmap_id, DefaultRootWindow(display),
64 native_pixmap.GetDmaBufPlaneSize(0),
65 native_pixmap.GetBufferSize().width(),
66 native_pixmap.GetBufferSize().height(),
67 native_pixmap.GetDmaBufPitch(0), depth, bpp, fd);
68 return pixmap_id;
69 }
70
71 } // namespace
72
GLImageGLXNativePixmap(const gfx::Size & size,gfx::BufferFormat format)73 GLImageGLXNativePixmap::GLImageGLXNativePixmap(const gfx::Size& size,
74 gfx::BufferFormat format)
75 : GLImageGLX(size, format) {}
76
77 GLImageGLXNativePixmap::~GLImageGLXNativePixmap() = default;
78
Initialize(scoped_refptr<gfx::NativePixmap> pixmap)79 bool GLImageGLXNativePixmap::Initialize(
80 scoped_refptr<gfx::NativePixmap> pixmap) {
81 native_pixmap_ = pixmap;
82
83 return GLImageGLX::Initialize(XPixmapFromNativePixmap(
84 *static_cast<gfx::NativePixmapDmaBuf*>(native_pixmap_.get()),
85 Depth(format()), Bpp(format())));
86 }
87
88 } // namespace gl
89