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 "base/posix/eintr_wrapper.h"
8 #include "ui/gfx/buffer_types.h"
9 #include "ui/gfx/linux/native_pixmap_dmabuf.h"
10 #include "ui/gfx/x/connection.h"
11 #include "ui/gfx/x/dri3.h"
12 #include "ui/gfx/x/xproto_types.h"
13 #include "ui/gl/buffer_format_utils.h"
14 #include "ui/gl/gl_bindings.h"
15 
16 namespace gl {
17 
18 namespace {
19 
Depth(gfx::BufferFormat format)20 int Depth(gfx::BufferFormat format) {
21   switch (format) {
22     case gfx::BufferFormat::BGR_565:
23       return 16;
24     case gfx::BufferFormat::BGRX_8888:
25       return 24;
26     case gfx::BufferFormat::BGRA_1010102:
27       // It's unclear why this is 32 instead of 30.
28       return 32;
29     case gfx::BufferFormat::BGRA_8888:
30       return 32;
31     default:
32       NOTREACHED();
33       return 0;
34   }
35 }
36 
Bpp(gfx::BufferFormat format)37 int Bpp(gfx::BufferFormat format) {
38   switch (format) {
39     case gfx::BufferFormat::BGR_565:
40       return 16;
41     case gfx::BufferFormat::BGRX_8888:
42     case gfx::BufferFormat::BGRA_1010102:
43     case gfx::BufferFormat::BGRA_8888:
44       return 32;
45     default:
46       NOTREACHED();
47       return 0;
48   }
49 }
50 
XPixmapFromNativePixmap(const gfx::NativePixmapDmaBuf & native_pixmap,int depth,int bpp)51 x11::Pixmap XPixmapFromNativePixmap(
52     const gfx::NativePixmapDmaBuf& native_pixmap,
53     int depth,
54     int bpp) {
55   auto fd = HANDLE_EINTR(dup(native_pixmap.GetDmaBufFd(0)));
56   if (fd < 0)
57     return x11::Pixmap::None;
58   base::ScopedFD scoped_fd(fd);
59 
60   auto* connection = x11::Connection::Get();
61   x11::Pixmap pixmap_id = connection->GenerateId<x11::Pixmap>();
62   connection->dri3().PixmapFromBuffer({pixmap_id, connection->default_root(),
63                                        native_pixmap.GetDmaBufPlaneSize(0),
64                                        native_pixmap.GetBufferSize().width(),
65                                        native_pixmap.GetBufferSize().height(),
66                                        native_pixmap.GetDmaBufPitch(0), depth,
67                                        bpp, std::move(scoped_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