• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2020 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 
7 // PixmapSurfaceGLX.cpp: GLX implementation of egl::Surface for Pixmaps
8 
9 #include "libANGLE/renderer/gl/glx/PixmapSurfaceGLX.h"
10 
11 #include "common/debug.h"
12 #include "libANGLE/Display.h"
13 #include "libANGLE/Surface.h"
14 #include "libANGLE/renderer/gl/glx/DisplayGLX.h"
15 #include "libANGLE/renderer/gl/glx/FunctionsGLX.h"
16 #include "libANGLE/renderer/gl/glx/glx_utils.h"
17 
18 #include <iostream>
19 
20 namespace rx
21 {
22 
23 namespace
24 {
25 
EGLTextureFormatToGLXTextureFormat(EGLint textureFormat)26 int EGLTextureFormatToGLXTextureFormat(EGLint textureFormat)
27 {
28     switch (textureFormat)
29     {
30         case EGL_NO_TEXTURE:
31             return GLX_TEXTURE_FORMAT_NONE_EXT;
32         case EGL_TEXTURE_RGB:
33             return GLX_TEXTURE_FORMAT_RGB_EXT;
34         case EGL_TEXTURE_RGBA:
35             return GLX_TEXTURE_FORMAT_RGBA_EXT;
36         default:
37             UNREACHABLE();
38             return GLX_TEXTURE_FORMAT_NONE_EXT;
39     }
40 }
41 
EGLTextureTargetToGLXTextureTarget(EGLint textureTarget)42 int EGLTextureTargetToGLXTextureTarget(EGLint textureTarget)
43 {
44     switch (textureTarget)
45     {
46         case EGL_NO_TEXTURE:
47             return 0;
48         case EGL_TEXTURE_2D:
49             return GLX_TEXTURE_2D_EXT;
50         default:
51             UNREACHABLE();
52             return 0;
53     }
54 }
55 
EGLBufferToGLXBuffer(EGLint buffer)56 int EGLBufferToGLXBuffer(EGLint buffer)
57 {
58     switch (buffer)
59     {
60         case EGL_BACK_BUFFER:
61             return GLX_BACK_EXT;
62         default:
63             UNREACHABLE();
64             return 0;
65     }
66 }
67 
68 }  // namespace
69 
PixmapSurfaceGLX(const egl::SurfaceState & state,Pixmap pixmap,Display * display,const FunctionsGLX & glx,glx::FBConfig fbConfig)70 PixmapSurfaceGLX::PixmapSurfaceGLX(const egl::SurfaceState &state,
71                                    Pixmap pixmap,
72                                    Display *display,
73                                    const FunctionsGLX &glx,
74                                    glx::FBConfig fbConfig)
75     : SurfaceGLX(state),
76       mWidth(0),
77       mHeight(0),
78       mGLX(glx),
79       mFBConfig(fbConfig),
80       mXPixmap(pixmap),
81       mGLXPixmap(0),
82       mDisplay(display)
83 {}
84 
~PixmapSurfaceGLX()85 PixmapSurfaceGLX::~PixmapSurfaceGLX()
86 {
87     if (mGLXPixmap)
88     {
89         mGLX.destroyPixmap(mGLXPixmap);
90     }
91 }
92 
initialize(const egl::Display * display)93 egl::Error PixmapSurfaceGLX::initialize(const egl::Display *display)
94 {
95     DisplayGLX *displayGLX = GetImplAs<DisplayGLX>(display);
96 
97     {
98         Window rootWindow;
99         int x                    = 0;
100         int y                    = 0;
101         unsigned int borderWidth = 0;
102         unsigned int depth       = 0;
103         int status = XGetGeometry(mDisplay, mXPixmap, &rootWindow, &x, &y, &mWidth, &mHeight,
104                                   &borderWidth, &depth);
105         if (!status)
106         {
107             return egl::EglBadSurface() << "XGetGeometry query failed on pixmap surface: "
108                                         << x11::XErrorToString(mDisplay, status);
109         }
110     }
111 
112     std::vector<int> pixmapAttribs;
113     if (mState.attributes.contains(EGL_TEXTURE_FORMAT))
114     {
115         pixmapAttribs.push_back(GLX_TEXTURE_FORMAT_EXT);
116         pixmapAttribs.push_back(
117             EGLTextureFormatToGLXTextureFormat(mState.attributes.getAsInt(EGL_TEXTURE_FORMAT)));
118     }
119     if (mState.attributes.contains(EGL_TEXTURE_TARGET))
120     {
121         pixmapAttribs.push_back(GLX_TEXTURE_TARGET_EXT);
122         pixmapAttribs.push_back(
123             EGLTextureTargetToGLXTextureTarget(mState.attributes.getAsInt(EGL_TEXTURE_TARGET)));
124     }
125 
126     pixmapAttribs.push_back(None);
127 
128     mGLXPixmap = mGLX.createPixmap(mFBConfig, mXPixmap, pixmapAttribs.data());
129     if (!mGLXPixmap)
130     {
131         return egl::EglBadAlloc() << "Failed to create a native GLX pixmap.";
132     }
133 
134     XFlush(mDisplay);
135     displayGLX->syncXCommands(false);
136 
137     return egl::NoError();
138 }
139 
makeCurrent(const gl::Context * context)140 egl::Error PixmapSurfaceGLX::makeCurrent(const gl::Context *context)
141 {
142     return egl::NoError();
143 }
144 
swap(const gl::Context * context)145 egl::Error PixmapSurfaceGLX::swap(const gl::Context *context)
146 {
147     UNREACHABLE();
148     return egl::NoError();
149 }
150 
postSubBuffer(const gl::Context * context,EGLint x,EGLint y,EGLint width,EGLint height)151 egl::Error PixmapSurfaceGLX::postSubBuffer(const gl::Context *context,
152                                            EGLint x,
153                                            EGLint y,
154                                            EGLint width,
155                                            EGLint height)
156 {
157     UNREACHABLE();
158     return egl::NoError();
159 }
160 
querySurfacePointerANGLE(EGLint attribute,void ** value)161 egl::Error PixmapSurfaceGLX::querySurfacePointerANGLE(EGLint attribute, void **value)
162 {
163     UNREACHABLE();
164     return egl::NoError();
165 }
166 
bindTexImage(const gl::Context * context,gl::Texture * texture,EGLint buffer)167 egl::Error PixmapSurfaceGLX::bindTexImage(const gl::Context *context,
168                                           gl::Texture *texture,
169                                           EGLint buffer)
170 {
171     const int attribs[] = {None};
172     mGLX.bindTexImageEXT(mGLXPixmap, EGLBufferToGLXBuffer(buffer), attribs);
173     return egl::NoError();
174 }
175 
releaseTexImage(const gl::Context * context,EGLint buffer)176 egl::Error PixmapSurfaceGLX::releaseTexImage(const gl::Context *context, EGLint buffer)
177 {
178     mGLX.releaseTexImageEXT(mGLXPixmap, EGLBufferToGLXBuffer(buffer));
179     return egl::NoError();
180 }
181 
setSwapInterval(EGLint interval)182 void PixmapSurfaceGLX::setSwapInterval(EGLint interval) {}
183 
getWidth() const184 EGLint PixmapSurfaceGLX::getWidth() const
185 {
186     return mWidth;
187 }
188 
getHeight() const189 EGLint PixmapSurfaceGLX::getHeight() const
190 {
191     return mHeight;
192 }
193 
isPostSubBufferSupported() const194 EGLint PixmapSurfaceGLX::isPostSubBufferSupported() const
195 {
196     UNREACHABLE();
197     return EGL_FALSE;
198 }
199 
getSwapBehavior() const200 EGLint PixmapSurfaceGLX::getSwapBehavior() const
201 {
202     return EGL_BUFFER_DESTROYED;
203 }
204 
checkForResize()205 egl::Error PixmapSurfaceGLX::checkForResize()
206 {
207     // The size of pbuffers never change
208     return egl::NoError();
209 }
210 
getDrawable() const211 glx::Drawable PixmapSurfaceGLX::getDrawable() const
212 {
213     return mGLXPixmap;
214 }
215 
216 }  // namespace rx
217