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