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