Investigate glGetError frequency in WebGL/WebVR |
|||
Issue descriptionSummary: WebGL/WebVR rendering appears to involve a large number of glGetError calls, mostly related to texture and FBO setup. Since glGetError includes an implicit driver flush, we should investigate the performance impact and (if applicable) see if we can reduce this. bajones@ mentioned that a fair amount of error checking had historically been added to work around specific driver bugs, and not all of this may be necessary on any one given GPU and driver. One specific concern is that apparently glFlush can be very expensive on some tiling GPUs since it may trigger a rendering pass to start, potentially including main memory save/restore of tile memory. The implicit flush that's done as part of glGetError doesn't have to do this, but I'm unsure how specific drivers deal with this. I took a GL command trace while investigating a performance bug ( issue 750306 ), and noticed that there's a large number of glGetError calls in the command stream: $ zcat slow-commands-full.txt.gz | grep bindings_autogen | grep SwapBuffers | wc -l 72 $ zcat slow-commands-full.txt.gz | grep bindings_autogen | grep glGetError | wc -l 1871 Assuming that there's one SwapBuffers per frame, this would be about 25 glGetError calls every output frame. The page in question was https://sketchfab.com/models/uFqGJrS9ZjVr9Myk9kg4fubPNPz , both outside VR and after entering VR.
,
Sep 1 2017
Correction: the build that was using GL command tracing apparently adds extra glGetError calls that aren't present in a production build. According to an instrumented production build, there appear to be four glGetError calls per WebVR frame for a simple test page. Not as bad as I originally thought, but are these all necessary? Source is error_state.cc::GetErrorHandleContextLoss: https://cs.chromium.org/chromium/src/gpu/command_buffer/service/error_state.cc?type=cs&q=GetErrorHandleContextLoss+file:%5Esrc/+package:%5Echromium$&l=110 GLenum ErrorStateImpl::GetErrorHandleContextLoss() { GLenum error = glGetError(); if (error == GL_CONTEXT_LOST_KHR) { client_->OnContextLostError(); // Do not expose GL_CONTEXT_LOST_KHR, as the version of the robustness // extension that introduces the error is not exposed by the command // buffer. error = GL_NO_ERROR; } return error; } chromium: [INFO:vr_shell_gl.cc(1219)] ;;; pose prediction=65.366ms (js=17.041ms, render=23.268ms), fps=31.4168 chromium: [INFO:error_state.cc(110)] GetErrorHandleContextLoss;;; glGetError chatty : uid=10133(org.chromium.chrome) CrGpuMain identical 2 lines chromium: [INFO:error_state.cc(110)] GetErrorHandleContextLoss;;; glGetError chromium: [INFO:vr_shell_gl.cc(1219)] ;;; pose prediction=65.578ms (js=18.18ms, render=22.341ms), fps=33.3351 chromium: [INFO:error_state.cc(110)] GetErrorHandleContextLoss;;; glGetError chatty : uid=10133(org.chromium.chrome) CrGpuMain identical 2 lines chromium: [INFO:error_state.cc(110)] GetErrorHandleContextLoss;;; glGetError chromium: [INFO:vr_shell_gl.cc(1219)] ;;; pose prediction=64.261ms (js=17.685ms, render=21.52ms), fps=33.5862 For reference, here's how I added this logging: diff --git a/ui/gl/gl_bindings_autogen_gl.h b/ui/gl/gl_bindings_autogen_gl.h index d077f3eb1c17..9b36e92ab93f 100644 --- a/ui/gl/gl_bindings_autogen_gl.h +++ b/ui/gl/gl_bindings_autogen_gl.h @@ -3568,7 +3568,10 @@ class GL_EXPORT GLApi { #define glGetBufferPointervRobustANGLE \ ::gl::g_current_gl_context->glGetBufferPointervRobustANGLEFn #define glGetDebugMessageLog ::gl::g_current_gl_context->glGetDebugMessageLogFn -#define glGetError ::gl::g_current_gl_context->glGetErrorFn +#define glGetError(x) ({\ + LOG(INFO) << __FUNCTION__ << ";;; glGetError"; \ + ::gl::g_current_gl_context->glGetErrorFn(); \ +}) #define glGetFenceivNV ::gl::g_current_gl_context->glGetFenceivNVFn #define glGetFloatv ::gl::g_current_gl_context->glGetFloatvFn #define glGetFloatvRobustANGLE \
,
Sep 5 2017
It's hard to tell without seeing a stack trace. These calls are being made on the GPU process side, rather than the renderer side, so they shouldn't be that expensive. When allocating textures, for example, the only way to know whether the texture allocation succeeded is to call glGetError. In general the command buffer service side shouldn't be making extraneous calls to glGetError, so it's likely that the ones remaining are needed.
,
Jul 4
,
Aug 7
Removing Blink>WebVR component and assigning to Blink>WebXR
,
Aug 7
|
|||
►
Sign in to add a comment |
|||
Comment 1 by cjgrant@chromium.org
, Aug 10 2017