xref: /aosp_15_r20/external/angle/src/libANGLE/renderer/gl/DisplayGL.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1 //
2 // Copyright 2015 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 // DisplayGL.h: GL implementation of egl::Display
8 
9 #include "libANGLE/renderer/gl/DisplayGL.h"
10 
11 #include "libANGLE/AttributeMap.h"
12 #include "libANGLE/Context.h"
13 #include "libANGLE/Display.h"
14 #include "libANGLE/Surface.h"
15 #include "libANGLE/renderer/gl/ContextGL.h"
16 #include "libANGLE/renderer/gl/RendererGL.h"
17 #include "libANGLE/renderer/gl/StateManagerGL.h"
18 #include "libANGLE/renderer/gl/SurfaceGL.h"
19 
20 #include <EGL/eglext.h>
21 
22 namespace rx
23 {
24 
25 // On Linux with the amdgpu driver, the renderer string looks like:
26 //
27 // AMD Radeon (TM) <GPU model> Graphics (<GPUgeneration>, DRM <DRMversion>, <kernelversion>,
28 // LLVM <LLVMversion>) eg. AMD Radeon (TM) RX 460 Graphics (POLARIS11,
29 // DRM 3.35.0, 5.4.0-65-generic, LLVM 11.0.0)
30 //
31 // We also want to handle the case without GPUGeneration:
32 // AMD Radeon GPU model (DRM DRMversion, kernelversion, LLVM LLVMversion)
33 //
34 // Thanks to Kelsey Gilbert of Mozilla for this example
35 // https://phabricator.services.mozilla.com/D105636
SanitizeRendererString(std::string rendererString)36 std::string SanitizeRendererString(std::string rendererString)
37 {
38     size_t pos = rendererString.find(", DRM ");
39     if (pos != std::string::npos)
40     {
41         rendererString.resize(pos);
42         rendererString.push_back(')');
43         return rendererString;
44     }
45     pos = rendererString.find(" (DRM ");
46     if (pos != std::string::npos)
47     {
48         rendererString.resize(pos);
49         return rendererString;
50     }
51     return rendererString;
52 }
53 
54 // OpenGL ES requires a prefix of "OpenGL ES" for the GL_VERSION string.
55 // We can also add the prefix to desktop OpenGL for consistency.
SanitizeVersionString(std::string versionString,bool isES,bool includeFullVersion)56 std::string SanitizeVersionString(std::string versionString, bool isES, bool includeFullVersion)
57 {
58     const std::string GLString = "OpenGL ";
59     const std::string ESString = "ES ";
60     size_t openGLESPos         = versionString.find(GLString);
61     std::ostringstream result;
62 
63     if (openGLESPos == std::string::npos)
64     {
65         openGLESPos = 0;
66     }
67     else
68     {
69         openGLESPos += GLString.size() + (isES ? ESString.size() : 0);
70     }
71 
72     result << GLString << (isES ? ESString : "");
73     if (includeFullVersion)
74     {
75         result << versionString.substr(openGLESPos);
76     }
77     else
78     {
79         size_t postVersionSpace = versionString.find(" ", openGLESPos);
80         result << versionString.substr(openGLESPos, postVersionSpace - openGLESPos);
81     }
82 
83     return result.str();
84 }
85 
DisplayGL(const egl::DisplayState & state)86 DisplayGL::DisplayGL(const egl::DisplayState &state) : DisplayImpl(state) {}
87 
~DisplayGL()88 DisplayGL::~DisplayGL() {}
89 
initialize(egl::Display * display)90 egl::Error DisplayGL::initialize(egl::Display *display)
91 {
92     return egl::NoError();
93 }
94 
terminate()95 void DisplayGL::terminate() {}
96 
createImage(const egl::ImageState & state,const gl::Context * context,EGLenum target,const egl::AttributeMap & attribs)97 ImageImpl *DisplayGL::createImage(const egl::ImageState &state,
98                                   const gl::Context *context,
99                                   EGLenum target,
100                                   const egl::AttributeMap &attribs)
101 {
102     UNIMPLEMENTED();
103     return nullptr;
104 }
105 
createPbufferFromClientBuffer(const egl::SurfaceState & state,EGLenum buftype,EGLClientBuffer clientBuffer,const egl::AttributeMap & attribs)106 SurfaceImpl *DisplayGL::createPbufferFromClientBuffer(const egl::SurfaceState &state,
107                                                       EGLenum buftype,
108                                                       EGLClientBuffer clientBuffer,
109                                                       const egl::AttributeMap &attribs)
110 {
111     UNIMPLEMENTED();
112     return nullptr;
113 }
114 
createStreamProducerD3DTexture(egl::Stream::ConsumerType consumerType,const egl::AttributeMap & attribs)115 StreamProducerImpl *DisplayGL::createStreamProducerD3DTexture(
116     egl::Stream::ConsumerType consumerType,
117     const egl::AttributeMap &attribs)
118 {
119     UNIMPLEMENTED();
120     return nullptr;
121 }
122 
createShareGroup(const egl::ShareGroupState & state)123 ShareGroupImpl *DisplayGL::createShareGroup(const egl::ShareGroupState &state)
124 {
125     return new ShareGroupGL(state);
126 }
127 
makeCurrent(egl::Display * display,egl::Surface * drawSurface,egl::Surface * readSurface,gl::Context * context)128 egl::Error DisplayGL::makeCurrent(egl::Display *display,
129                                   egl::Surface *drawSurface,
130                                   egl::Surface *readSurface,
131                                   gl::Context *context)
132 {
133     // Ensure that the correct global DebugAnnotator is installed when the end2end tests change
134     // the ANGLE back-end (done frequently).
135     display->setGlobalDebugAnnotator();
136 
137     if (!context)
138     {
139         return egl::NoError();
140     }
141 
142     // Pause transform feedback before making a new surface current, to workaround
143     // anglebug.com/42260421
144     ContextGL *glContext = GetImplAs<ContextGL>(context);
145     glContext->getStateManager()->pauseTransformFeedback();
146 
147     if (drawSurface == nullptr)
148     {
149         ANGLE_TRY(makeCurrentSurfaceless(context));
150     }
151 
152     return egl::NoError();
153 }
154 
getMaxConformantESVersion() const155 gl::Version DisplayGL::getMaxConformantESVersion() const
156 {
157     // 3.1 support is in progress.
158     return std::min(getMaxSupportedESVersion(), gl::Version(3, 0));
159 }
160 
generateExtensions(egl::DisplayExtensions * outExtensions) const161 void DisplayGL::generateExtensions(egl::DisplayExtensions *outExtensions) const
162 {
163     // Advertise robust resource initialization on all OpenGL backends for testing even though it is
164     // not fully implemented.
165     outExtensions->robustResourceInitializationANGLE = true;
166 }
167 
makeCurrentSurfaceless(gl::Context * context)168 egl::Error DisplayGL::makeCurrentSurfaceless(gl::Context *context)
169 {
170     UNIMPLEMENTED();
171     return egl::NoError();
172 }
173 
getRendererDescription()174 std::string DisplayGL::getRendererDescription()
175 {
176     std::string rendererString        = GetRendererString(getRenderer()->getFunctions());
177     const angle::FeaturesGL &features = getRenderer()->getFeatures();
178 
179     if (features.sanitizeAMDGPURendererString.enabled)
180     {
181         return SanitizeRendererString(rendererString);
182     }
183     return rendererString;
184 }
185 
getVendorString()186 std::string DisplayGL::getVendorString()
187 {
188     return GetVendorString(getRenderer()->getFunctions());
189 }
190 
getVersionString(bool includeFullVersion)191 std::string DisplayGL::getVersionString(bool includeFullVersion)
192 {
193     std::string versionString = GetVersionString(getRenderer()->getFunctions());
194     return SanitizeVersionString(versionString,
195                                  getRenderer()->getFunctions()->standard == STANDARD_GL_ES,
196                                  includeFullVersion);
197 }
198 
199 }  // namespace rx
200