xref: /aosp_15_r20/external/angle/src/libANGLE/renderer/gl/RendererGL.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 // RendererGL.cpp: Implements the class methods for RendererGL.
8 
9 #include "libANGLE/renderer/gl/RendererGL.h"
10 
11 #include <EGL/eglext.h>
12 #include <thread>
13 
14 #include "common/debug.h"
15 #include "common/system_utils.h"
16 #include "libANGLE/AttributeMap.h"
17 #include "libANGLE/Context.h"
18 #include "libANGLE/Display.h"
19 #include "libANGLE/State.h"
20 #include "libANGLE/Surface.h"
21 #include "libANGLE/renderer/gl/BlitGL.h"
22 #include "libANGLE/renderer/gl/BufferGL.h"
23 #include "libANGLE/renderer/gl/ClearMultiviewGL.h"
24 #include "libANGLE/renderer/gl/CompilerGL.h"
25 #include "libANGLE/renderer/gl/ContextGL.h"
26 #include "libANGLE/renderer/gl/DisplayGL.h"
27 #include "libANGLE/renderer/gl/FenceNVGL.h"
28 #include "libANGLE/renderer/gl/FramebufferGL.h"
29 #include "libANGLE/renderer/gl/FunctionsGL.h"
30 #include "libANGLE/renderer/gl/ProgramGL.h"
31 #include "libANGLE/renderer/gl/QueryGL.h"
32 #include "libANGLE/renderer/gl/RenderbufferGL.h"
33 #include "libANGLE/renderer/gl/SamplerGL.h"
34 #include "libANGLE/renderer/gl/ShaderGL.h"
35 #include "libANGLE/renderer/gl/StateManagerGL.h"
36 #include "libANGLE/renderer/gl/SurfaceGL.h"
37 #include "libANGLE/renderer/gl/SyncGL.h"
38 #include "libANGLE/renderer/gl/TextureGL.h"
39 #include "libANGLE/renderer/gl/TransformFeedbackGL.h"
40 #include "libANGLE/renderer/gl/VertexArrayGL.h"
41 #include "libANGLE/renderer/gl/renderergl_utils.h"
42 #include "libANGLE/renderer/renderer_utils.h"
43 
44 namespace
45 {
46 
SetMaxShaderCompilerThreads(const rx::FunctionsGL * functions,GLuint count)47 void SetMaxShaderCompilerThreads(const rx::FunctionsGL *functions, GLuint count)
48 {
49     if (functions->maxShaderCompilerThreadsKHR != nullptr)
50     {
51         functions->maxShaderCompilerThreadsKHR(count);
52     }
53     else
54     {
55         ASSERT(functions->maxShaderCompilerThreadsARB != nullptr);
56         functions->maxShaderCompilerThreadsARB(count);
57     }
58 }
59 
60 #if defined(ANGLE_PLATFORM_ANDROID)
61 const char *kIgnoredErrors[] = {
62     // Wrong error message on Android Q Pixel 2. http://anglebug.com/42262155
63     "FreeAllocationOnTimestamp - Reference to buffer created from "
64     "different context without a share list. Application failed to pass "
65     "share_context to eglCreateContext. Results are undefined.",
66     // http://crbug.com/1348684
67     "UpdateTimestamp - Reference to buffer created from different context without a share list. "
68     "Application failed to pass share_context to eglCreateContext. Results are undefined.",
69     "Attempt to use resource over contexts without enabling context sharing. App must pass a "
70     "share_context to eglCreateContext() to share resources.",
71 };
72 #endif  // defined(ANGLE_PLATFORM_ANDROID)
73 
74 const char *kIgnoredWarnings[] = {
75     // We always request GL_ARB_gpu_shader5 and GL_EXT_gpu_shader5 when compiling shaders but some
76     // drivers warn when it is not present. This ends up spamming the console on every shader
77     // compile.
78     "extension `GL_ARB_gpu_shader5' unsupported in",
79     "extension `GL_EXT_gpu_shader5' unsupported in",
80 };
81 
82 }  // namespace
83 
LogGLDebugMessage(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar * message,const void * userParam)84 static void INTERNAL_GL_APIENTRY LogGLDebugMessage(GLenum source,
85                                                    GLenum type,
86                                                    GLuint id,
87                                                    GLenum severity,
88                                                    GLsizei length,
89                                                    const GLchar *message,
90                                                    const void *userParam)
91 {
92     std::string sourceText   = gl::GetDebugMessageSourceString(source);
93     std::string typeText     = gl::GetDebugMessageTypeString(type);
94     std::string severityText = gl::GetDebugMessageSeverityString(severity);
95 
96 #if defined(ANGLE_PLATFORM_ANDROID)
97     if (type == GL_DEBUG_TYPE_ERROR)
98     {
99         for (const char *&err : kIgnoredErrors)
100         {
101             if (strncmp(err, message, length) == 0)
102             {
103                 // There is only one ignored message right now and it is quite spammy, around 3MB
104                 // for a complete end2end tests run, so don't print it even as a warning.
105                 return;
106             }
107         }
108     }
109 #endif  // defined(ANGLE_PLATFORM_ANDROID)
110 
111     if (type == GL_DEBUG_TYPE_ERROR)
112     {
113         ERR() << std::endl
114               << "\tSource: " << sourceText << std::endl
115               << "\tType: " << typeText << std::endl
116               << "\tID: " << gl::FmtHex(id) << std::endl
117               << "\tSeverity: " << severityText << std::endl
118               << "\tMessage: " << message;
119     }
120     else if (type != GL_DEBUG_TYPE_PERFORMANCE)
121     {
122         // Don't print performance warnings. They tend to be very spammy in the dEQP test suite and
123         // there is very little we can do about them.
124 
125         for (const char *&warn : kIgnoredWarnings)
126         {
127             if (strstr(message, warn) != nullptr)
128             {
129                 return;
130             }
131         }
132 
133         // TODO(ynovikov): filter into WARN and INFO if INFO is ever implemented
134         WARN() << std::endl
135                << "\tSource: " << sourceText << std::endl
136                << "\tType: " << typeText << std::endl
137                << "\tID: " << gl::FmtHex(id) << std::endl
138                << "\tSeverity: " << severityText << std::endl
139                << "\tMessage: " << message;
140     }
141 }
142 
143 namespace rx
144 {
145 
RendererGL(std::unique_ptr<FunctionsGL> functions,const egl::AttributeMap & attribMap,DisplayGL * display)146 RendererGL::RendererGL(std::unique_ptr<FunctionsGL> functions,
147                        const egl::AttributeMap &attribMap,
148                        DisplayGL *display)
149     : mMaxSupportedESVersion(0, 0),
150       mFunctions(std::move(functions)),
151       mStateManager(nullptr),
152       mBlitter(nullptr),
153       mMultiviewClearer(nullptr),
154       mUseDebugOutput(false),
155       mCapsInitialized(false),
156       mMultiviewImplementationType(MultiviewImplementationTypeGL::UNSPECIFIED),
157       mNativeParallelCompileEnabled(false),
158       mNeedsFlushBeforeDeleteTextures(false)
159 {
160     ASSERT(mFunctions);
161     ApplyFeatureOverrides(&mFeatures, display->getState().featureOverrides);
162     if (!display->getState().featureOverrides.allDisabled)
163     {
164         nativegl_gl::InitializeFeatures(mFunctions.get(), &mFeatures);
165     }
166     mStateManager =
167         new StateManagerGL(mFunctions.get(), getNativeCaps(), getNativeExtensions(), mFeatures);
168     mBlitter          = new BlitGL(mFunctions.get(), mFeatures, mStateManager);
169     mMultiviewClearer = new ClearMultiviewGL(mFunctions.get(), mStateManager);
170 
171     bool hasDebugOutput = mFunctions->isAtLeastGL(gl::Version(4, 3)) ||
172                           mFunctions->hasGLExtension("GL_KHR_debug") ||
173                           mFunctions->isAtLeastGLES(gl::Version(3, 2)) ||
174                           mFunctions->hasGLESExtension("GL_KHR_debug");
175 
176     mUseDebugOutput = hasDebugOutput && ShouldUseDebugLayers(attribMap);
177 
178     if (mUseDebugOutput)
179     {
180         mFunctions->enable(GL_DEBUG_OUTPUT);
181         mFunctions->enable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
182         mFunctions->debugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_HIGH, 0,
183                                         nullptr, GL_TRUE);
184         mFunctions->debugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_MEDIUM, 0,
185                                         nullptr, GL_TRUE);
186         mFunctions->debugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_LOW, 0,
187                                         nullptr, GL_FALSE);
188         mFunctions->debugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_NOTIFICATION,
189                                         0, nullptr, GL_FALSE);
190         mFunctions->debugMessageCallback(&LogGLDebugMessage, nullptr);
191     }
192 
193     if (mFeatures.initializeCurrentVertexAttributes.enabled)
194     {
195         GLint maxVertexAttribs = 0;
196         mFunctions->getIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxVertexAttribs);
197 
198         for (GLint i = 0; i < maxVertexAttribs; ++i)
199         {
200             mFunctions->vertexAttrib4f(i, 0.0f, 0.0f, 0.0f, 1.0f);
201         }
202     }
203 
204     if (hasNativeParallelCompile() && !mNativeParallelCompileEnabled)
205     {
206         SetMaxShaderCompilerThreads(mFunctions.get(), 0xffffffff);
207         mNativeParallelCompileEnabled = true;
208     }
209 }
210 
~RendererGL()211 RendererGL::~RendererGL()
212 {
213     SafeDelete(mBlitter);
214     SafeDelete(mMultiviewClearer);
215     SafeDelete(mStateManager);
216 }
217 
flush()218 angle::Result RendererGL::flush()
219 {
220     if (!mWorkDoneSinceLastFlush && !mNeedsFlushBeforeDeleteTextures)
221     {
222         return angle::Result::Continue;
223     }
224 
225     mFunctions->flush();
226     mNeedsFlushBeforeDeleteTextures = false;
227     mWorkDoneSinceLastFlush         = false;
228     return angle::Result::Continue;
229 }
230 
finish()231 angle::Result RendererGL::finish()
232 {
233     if (mFeatures.finishDoesNotCauseQueriesToBeAvailable.enabled && mUseDebugOutput)
234     {
235         mFunctions->enable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
236     }
237 
238     mFunctions->finish();
239     mNeedsFlushBeforeDeleteTextures = false;
240     mWorkDoneSinceLastFlush         = false;
241 
242     if (mFeatures.finishDoesNotCauseQueriesToBeAvailable.enabled && mUseDebugOutput)
243     {
244         mFunctions->disable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
245     }
246 
247     return angle::Result::Continue;
248 }
249 
getResetStatus()250 gl::GraphicsResetStatus RendererGL::getResetStatus()
251 {
252     return gl::FromGLenum<gl::GraphicsResetStatus>(mFunctions->getGraphicsResetStatus());
253 }
254 
insertEventMarker(GLsizei length,const char * marker)255 void RendererGL::insertEventMarker(GLsizei length, const char *marker) {}
256 
pushGroupMarker(GLsizei length,const char * marker)257 void RendererGL::pushGroupMarker(GLsizei length, const char *marker) {}
258 
popGroupMarker()259 void RendererGL::popGroupMarker() {}
260 
pushDebugGroup(GLenum source,GLuint id,const std::string & message)261 void RendererGL::pushDebugGroup(GLenum source, GLuint id, const std::string &message) {}
262 
popDebugGroup()263 void RendererGL::popDebugGroup() {}
264 
getMaxSupportedESVersion() const265 const gl::Version &RendererGL::getMaxSupportedESVersion() const
266 {
267     // Force generation of caps
268     getNativeCaps();
269 
270     return mMaxSupportedESVersion;
271 }
272 
generateCaps(gl::Caps * outCaps,gl::TextureCapsMap * outTextureCaps,gl::Extensions * outExtensions,gl::Limitations * outLimitations) const273 void RendererGL::generateCaps(gl::Caps *outCaps,
274                               gl::TextureCapsMap *outTextureCaps,
275                               gl::Extensions *outExtensions,
276                               gl::Limitations *outLimitations) const
277 {
278     nativegl_gl::GenerateCaps(mFunctions.get(), mFeatures, outCaps, outTextureCaps, outExtensions,
279                               outLimitations, &mMaxSupportedESVersion,
280                               &mMultiviewImplementationType, &mNativePLSOptions);
281 }
282 
getGPUDisjoint()283 GLint RendererGL::getGPUDisjoint()
284 {
285     // TODO(ewell): On GLES backends we should find a way to reliably query disjoint events
286     return 0;
287 }
288 
getTimestamp()289 GLint64 RendererGL::getTimestamp()
290 {
291     GLint64 result = 0;
292     mFunctions->getInteger64v(GL_TIMESTAMP, &result);
293     return result;
294 }
295 
ensureCapsInitialized() const296 void RendererGL::ensureCapsInitialized() const
297 {
298     if (!mCapsInitialized)
299     {
300         generateCaps(&mNativeCaps, &mNativeTextureCaps, &mNativeExtensions, &mNativeLimitations);
301         mCapsInitialized = true;
302     }
303 }
304 
getNativeCaps() const305 const gl::Caps &RendererGL::getNativeCaps() const
306 {
307     ensureCapsInitialized();
308     return mNativeCaps;
309 }
310 
getNativeTextureCaps() const311 const gl::TextureCapsMap &RendererGL::getNativeTextureCaps() const
312 {
313     ensureCapsInitialized();
314     return mNativeTextureCaps;
315 }
316 
getNativeExtensions() const317 const gl::Extensions &RendererGL::getNativeExtensions() const
318 {
319     ensureCapsInitialized();
320     return mNativeExtensions;
321 }
322 
getNativeLimitations() const323 const gl::Limitations &RendererGL::getNativeLimitations() const
324 {
325     ensureCapsInitialized();
326     return mNativeLimitations;
327 }
328 
getNativePixelLocalStorageOptions() const329 const ShPixelLocalStorageOptions &RendererGL::getNativePixelLocalStorageOptions() const
330 {
331     return mNativePLSOptions;
332 }
333 
getMultiviewImplementationType() const334 MultiviewImplementationTypeGL RendererGL::getMultiviewImplementationType() const
335 {
336     ensureCapsInitialized();
337     return mMultiviewImplementationType;
338 }
339 
initializeFrontendFeatures(angle::FrontendFeatures * features) const340 void RendererGL::initializeFrontendFeatures(angle::FrontendFeatures *features) const
341 {
342     ensureCapsInitialized();
343     nativegl_gl::InitializeFrontendFeatures(mFunctions.get(), features);
344 }
345 
dispatchCompute(const gl::Context * context,GLuint numGroupsX,GLuint numGroupsY,GLuint numGroupsZ)346 angle::Result RendererGL::dispatchCompute(const gl::Context *context,
347                                           GLuint numGroupsX,
348                                           GLuint numGroupsY,
349                                           GLuint numGroupsZ)
350 {
351     mFunctions->dispatchCompute(numGroupsX, numGroupsY, numGroupsZ);
352     mWorkDoneSinceLastFlush = true;
353     return angle::Result::Continue;
354 }
355 
dispatchComputeIndirect(const gl::Context * context,GLintptr indirect)356 angle::Result RendererGL::dispatchComputeIndirect(const gl::Context *context, GLintptr indirect)
357 {
358     mFunctions->dispatchComputeIndirect(indirect);
359     mWorkDoneSinceLastFlush = true;
360     return angle::Result::Continue;
361 }
362 
memoryBarrier(GLbitfield barriers)363 angle::Result RendererGL::memoryBarrier(GLbitfield barriers)
364 {
365     mFunctions->memoryBarrier(barriers);
366     mWorkDoneSinceLastFlush = true;
367     return angle::Result::Continue;
368 }
memoryBarrierByRegion(GLbitfield barriers)369 angle::Result RendererGL::memoryBarrierByRegion(GLbitfield barriers)
370 {
371     mFunctions->memoryBarrierByRegion(barriers);
372     mWorkDoneSinceLastFlush = true;
373     return angle::Result::Continue;
374 }
375 
framebufferFetchBarrier()376 void RendererGL::framebufferFetchBarrier()
377 {
378     mFunctions->framebufferFetchBarrierEXT();
379     mWorkDoneSinceLastFlush = true;
380 }
381 
hasNativeParallelCompile()382 bool RendererGL::hasNativeParallelCompile()
383 {
384     if (mFeatures.disableNativeParallelCompile.enabled)
385     {
386         return false;
387     }
388     return mFunctions->maxShaderCompilerThreadsKHR != nullptr ||
389            mFunctions->maxShaderCompilerThreadsARB != nullptr;
390 }
391 
setMaxShaderCompilerThreads(GLuint count)392 void RendererGL::setMaxShaderCompilerThreads(GLuint count)
393 {
394     if (hasNativeParallelCompile())
395     {
396         SetMaxShaderCompilerThreads(mFunctions.get(), count);
397     }
398 }
399 
setNeedsFlushBeforeDeleteTextures()400 void RendererGL::setNeedsFlushBeforeDeleteTextures()
401 {
402     mNeedsFlushBeforeDeleteTextures = true;
403 }
404 
markWorkSubmitted()405 void RendererGL::markWorkSubmitted()
406 {
407     mWorkDoneSinceLastFlush = true;
408 }
409 
flushIfNecessaryBeforeDeleteTextures()410 void RendererGL::flushIfNecessaryBeforeDeleteTextures()
411 {
412     if (mNeedsFlushBeforeDeleteTextures)
413     {
414         (void)flush();
415     }
416 }
417 
handleGPUSwitch()418 void RendererGL::handleGPUSwitch()
419 {
420     nativegl_gl::ReInitializeFeaturesAtGPUSwitch(mFunctions.get(), &mFeatures);
421 }
422 
423 }  // namespace rx
424