1 // Copyright (c) 2012 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 <dlfcn.h>
6 
7 #include <memory>
8 
9 #include "base/logging.h"
10 #include "ui/gl/buffer_format_utils.h"
11 #include "ui/gl/gl_bindings.h"
12 #include "ui/gl/gl_image_glx.h"
13 #include "ui/gl/gl_surface_glx.h"
14 #include "ui/gl/gl_visual_picker_glx.h"
15 #include "ui/gl/glx_util.h"
16 
17 namespace gl {
18 namespace {
19 
TextureFormat(gfx::BufferFormat format)20 int TextureFormat(gfx::BufferFormat format) {
21   switch (format) {
22     case gfx::BufferFormat::BGR_565:
23     case gfx::BufferFormat::BGRX_8888:
24     case gfx::BufferFormat::BGRA_1010102:
25       return GLX_TEXTURE_FORMAT_RGB_EXT;
26     case gfx::BufferFormat::BGRA_8888:
27       return GLX_TEXTURE_FORMAT_RGBA_EXT;
28     default:
29       NOTREACHED();
30       return 0;
31   }
32 }
33 
34 }  // namespace
35 
GLImageGLX(const gfx::Size & size,gfx::BufferFormat format)36 GLImageGLX::GLImageGLX(const gfx::Size& size, gfx::BufferFormat format)
37     : glx_pixmap_(0), size_(size), format_(format) {}
38 
~GLImageGLX()39 GLImageGLX::~GLImageGLX() {
40   if (glx_pixmap_) {
41     glXDestroyGLXPixmap(
42         x11::Connection::Get()->GetXlibDisplay(x11::XlibDisplayType::kFlushing),
43         glx_pixmap_);
44   }
45 }
46 
Initialize(x11::Pixmap pixmap)47 bool GLImageGLX::Initialize(x11::Pixmap pixmap) {
48   auto fbconfig_id =
49       GLVisualPickerGLX::GetInstance()->GetFbConfigForFormat(format_);
50 
51   auto* connection = x11::Connection::Get();
52   GLXFBConfig config = GetGlxFbConfigForXProtoFbConfig(connection, fbconfig_id);
53   if (!config)
54     return false;
55 
56   int pixmap_attribs[] = {GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT,
57                           GLX_TEXTURE_FORMAT_EXT, TextureFormat(format_), 0};
58   glx_pixmap_ = glXCreatePixmap(
59       x11::Connection::Get()->GetXlibDisplay(x11::XlibDisplayType::kSyncing),
60       config, static_cast<::Pixmap>(pixmap), pixmap_attribs);
61   if (!glx_pixmap_) {
62     DVLOG(0) << "glXCreatePixmap failed.";
63     return false;
64   }
65 
66   return true;
67 }
68 
GetSize()69 gfx::Size GLImageGLX::GetSize() {
70   return size_;
71 }
72 
GetInternalFormat()73 unsigned GLImageGLX::GetInternalFormat() {
74   return gl::BufferFormatToGLInternalFormat(format_);
75 }
76 
GetDataType()77 unsigned GLImageGLX::GetDataType() {
78   return GL_UNSIGNED_BYTE;
79 }
80 
ShouldBindOrCopy()81 GLImageGLX::BindOrCopy GLImageGLX::ShouldBindOrCopy() {
82   return BIND;
83 }
84 
BindTexImage(unsigned target)85 bool GLImageGLX::BindTexImage(unsigned target) {
86   if (!glx_pixmap_)
87     return false;
88 
89   // Requires TEXTURE_2D target.
90   if (target != GL_TEXTURE_2D)
91     return false;
92 
93   glXBindTexImageEXT(
94       x11::Connection::Get()->GetXlibDisplay(x11::XlibDisplayType::kFlushing),
95       glx_pixmap_, GLX_FRONT_LEFT_EXT, nullptr);
96   return true;
97 }
98 
ReleaseTexImage(unsigned target)99 void GLImageGLX::ReleaseTexImage(unsigned target) {
100   DCHECK_NE(0u, glx_pixmap_);
101   DCHECK_EQ(static_cast<GLenum>(GL_TEXTURE_2D), target);
102 
103   glXReleaseTexImageEXT(
104       x11::Connection::Get()->GetXlibDisplay(x11::XlibDisplayType::kFlushing),
105       glx_pixmap_, GLX_FRONT_LEFT_EXT);
106 }
107 
CopyTexImage(unsigned target)108 bool GLImageGLX::CopyTexImage(unsigned target) {
109   NOTREACHED();
110   return false;
111 }
112 
CopyTexSubImage(unsigned target,const gfx::Point & offset,const gfx::Rect & rect)113 bool GLImageGLX::CopyTexSubImage(unsigned target,
114                                  const gfx::Point& offset,
115                                  const gfx::Rect& rect) {
116   return false;
117 }
118 
ScheduleOverlayPlane(gfx::AcceleratedWidget widget,int z_order,gfx::OverlayTransform transform,const gfx::Rect & bounds_rect,const gfx::RectF & crop_rect,bool enable_blend,std::unique_ptr<gfx::GpuFence> gpu_fence)119 bool GLImageGLX::ScheduleOverlayPlane(
120     gfx::AcceleratedWidget widget,
121     int z_order,
122     gfx::OverlayTransform transform,
123     const gfx::Rect& bounds_rect,
124     const gfx::RectF& crop_rect,
125     bool enable_blend,
126     std::unique_ptr<gfx::GpuFence> gpu_fence) {
127   return false;
128 }
129 
OnMemoryDump(base::trace_event::ProcessMemoryDump * pmd,uint64_t process_tracing_id,const std::string & dump_name)130 void GLImageGLX::OnMemoryDump(base::trace_event::ProcessMemoryDump* pmd,
131                               uint64_t process_tracing_id,
132                               const std::string& dump_name) {
133   // TODO(ericrk): Implement GLImage OnMemoryDump. crbug.com/514914
134 }
135 
136 }  // namespace gl
137