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 Jeff 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)56 std::string SanitizeVersionString(std::string versionString, bool isES)
57 {
58 if (versionString.find("OpenGL") == std::string::npos)
59 {
60 std::string prefix = "OpenGL ";
61 if (isES)
62 {
63 prefix += "ES ";
64 }
65 versionString = prefix + versionString;
66 }
67 return versionString;
68 }
69
DisplayGL(const egl::DisplayState & state)70 DisplayGL::DisplayGL(const egl::DisplayState &state) : DisplayImpl(state) {}
71
~DisplayGL()72 DisplayGL::~DisplayGL() {}
73
initialize(egl::Display * display)74 egl::Error DisplayGL::initialize(egl::Display *display)
75 {
76 return egl::NoError();
77 }
78
terminate()79 void DisplayGL::terminate() {}
80
createImage(const egl::ImageState & state,const gl::Context * context,EGLenum target,const egl::AttributeMap & attribs)81 ImageImpl *DisplayGL::createImage(const egl::ImageState &state,
82 const gl::Context *context,
83 EGLenum target,
84 const egl::AttributeMap &attribs)
85 {
86 UNIMPLEMENTED();
87 return nullptr;
88 }
89
createStreamProducerD3DTexture(egl::Stream::ConsumerType consumerType,const egl::AttributeMap & attribs)90 StreamProducerImpl *DisplayGL::createStreamProducerD3DTexture(
91 egl::Stream::ConsumerType consumerType,
92 const egl::AttributeMap &attribs)
93 {
94 UNIMPLEMENTED();
95 return nullptr;
96 }
97
createShareGroup()98 ShareGroupImpl *DisplayGL::createShareGroup()
99 {
100 return new ShareGroupGL();
101 }
102
makeCurrent(egl::Display * display,egl::Surface * drawSurface,egl::Surface * readSurface,gl::Context * context)103 egl::Error DisplayGL::makeCurrent(egl::Display *display,
104 egl::Surface *drawSurface,
105 egl::Surface *readSurface,
106 gl::Context *context)
107 {
108 // Ensure that the correct global DebugAnnotator is installed when the end2end tests change
109 // the ANGLE back-end (done frequently).
110 display->setGlobalDebugAnnotator();
111
112 if (!context)
113 {
114 return egl::NoError();
115 }
116
117 // Pause transform feedback before making a new surface current, to workaround anglebug.com/1426
118 ContextGL *glContext = GetImplAs<ContextGL>(context);
119 glContext->getStateManager()->pauseTransformFeedback();
120
121 if (drawSurface == nullptr)
122 {
123 ANGLE_TRY(makeCurrentSurfaceless(context));
124 }
125
126 return egl::NoError();
127 }
128
getMaxConformantESVersion() const129 gl::Version DisplayGL::getMaxConformantESVersion() const
130 {
131 // 3.1 support is in progress.
132 return std::min(getMaxSupportedESVersion(), gl::Version(3, 0));
133 }
134
generateExtensions(egl::DisplayExtensions * outExtensions) const135 void DisplayGL::generateExtensions(egl::DisplayExtensions *outExtensions) const
136 {
137 // Advertise robust resource initialization on all OpenGL backends for testing even though it is
138 // not fully implemented.
139 outExtensions->robustResourceInitialization = true;
140 }
141
makeCurrentSurfaceless(gl::Context * context)142 egl::Error DisplayGL::makeCurrentSurfaceless(gl::Context *context)
143 {
144 UNIMPLEMENTED();
145 return egl::NoError();
146 }
147
getRendererDescription()148 std::string DisplayGL::getRendererDescription()
149 {
150 std::string rendererString = GetRendererString(getRenderer()->getFunctions());
151 const angle::FeaturesGL &features = getRenderer()->getFeatures();
152
153 if (features.sanitizeAmdGpuRendererString.enabled)
154 {
155 return SanitizeRendererString(rendererString);
156 }
157 return rendererString;
158 }
159
getVendorString()160 std::string DisplayGL::getVendorString()
161 {
162 return GetVendorString(getRenderer()->getFunctions());
163 }
164
getVersionString()165 std::string DisplayGL::getVersionString()
166 {
167 std::string versionString = GetVersionString(getRenderer()->getFunctions());
168 return SanitizeVersionString(versionString,
169 getRenderer()->getFunctions()->standard == STANDARD_GL_ES);
170 }
171
172 } // namespace rx
173