Use MESA variant of glFramebufferParameteri if possible

The GL_MESA_framebuffer_flip_y extension lets the client flip reads
and writes to the a fb via glFramebufferParameteri.
glFramebufferParameteri, however, is only available on GLES 3.1+, but
the flip y extension spec states that GLES 3.0 implementations can
still implement this extension by providing
glFramebufferParameteriMESA (see "Revision History" [1]).

Some old ChromeOS Flex devices only support GLES 3.0, but still
expose this extension. Currently, ANGLE segfaults when trying to
update the FLIP_Y param [2] (e.g. when we create a WebGL canvas) on
these devices because framebufferParameteri is only initialized on
GLES 3.1+ [3].

This CL fixes the crash by falling back to the MESA variant of
framebufferParameteri when framebufferParameteri is unavailable.

[1]:https://registry.khronos.org/OpenGL/extensions/MESA/MESA_framebuffer_flip_y.txt
[2]:https://source.chromium.org/chromium/chromium/src/+/main:third_party/angle/src/libANGLE/renderer/gl/FramebufferGL.cpp;l=1330;drc=bf5e9dbc89e2dddb9c36200396139e938467f58e
[3]:https://source.chromium.org/chromium/chromium/src/+/refs/heads/main:third_party/angle/src/libANGLE/renderer/gl/DispatchTableGL_autogen.cpp;l=2552;drc=837cc12de25a288edf3ac222f7265c9936e69552

Bug: b/264681962
Change-Id: I079937bcd54b580b79d875f57c2b80ae796f2d83
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/4425929
Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Commit-Queue: Brian Ho <hob@chromium.org>
Commit-Queue: Geoff Lang <geofflang@chromium.org>
This commit is contained in:
Brian Ho
2023-04-13 18:00:31 -04:00
committed by Angle LUCI CQ
parent 4e6cea962a
commit 4c8ab49da1
8 changed files with 41 additions and 7 deletions

View File

@@ -2,17 +2,17 @@
"src/libANGLE/renderer/angle_format.py":
"601bfb757e052c50ac8f4cb4e0b58eb5",
"src/libANGLE/renderer/gl/DispatchTableGL_autogen.cpp":
"a2359f6e62a34b03ad6304811df39ce7",
"26e64fe13d7248c4ae04d6c8f3ac5890",
"src/libANGLE/renderer/gl/DispatchTableGL_autogen.h":
"df251bcc28f69eb873b5f9773e814f32",
"94e376d7f3b7e2ef6587284f825dfe39",
"src/libANGLE/renderer/gl/generate_gl_dispatch_table.py":
"2fb7f3906b4966b192c629228bc3e961",
"src/libANGLE/renderer/gl/gl_bindings_data.json":
"c3859551f6e137dbf4663a81b088cbf7",
"1c8d597d390eff780a14c703105304c4",
"src/libANGLE/renderer/gl/null_functions.cpp":
"d5082eb846b2396b998d642b78a0019a",
"38cd5858fa583e39bd76744ff532db49",
"src/libANGLE/renderer/gl/null_functions.h":
"c2a35eb1408399f78b5d177bff70a9c6",
"dff00d65990f16e1f77a73d12085a408",
"third_party/OpenGL-Registry/src/xml/gl.xml":
"49f0afe5cac23951c74420e457b0cb23"
}

View File

@@ -2818,6 +2818,11 @@ void DispatchTableGL::initProcsSharedExtensions(const std::set<std::string> &ext
ASSIGN("glMaxShaderCompilerThreadsKHR", maxShaderCompilerThreadsKHR);
}
if (extensions.count("GL_MESA_framebuffer_flip_y") != 0)
{
ASSIGN("glFramebufferParameteriMESA", framebufferParameteriMESA);
}
if (extensions.count("GL_NV_fence") != 0)
{
ASSIGN("glDeleteFencesNV", deleteFencesNV);
@@ -5634,6 +5639,11 @@ void DispatchTableGL::initProcsSharedExtensionsNULL(const std::set<std::string>
maxShaderCompilerThreadsKHR = &glMaxShaderCompilerThreadsKHRNULL;
}
if (extensions.count("GL_MESA_framebuffer_flip_y") != 0)
{
framebufferParameteriMESA = &glFramebufferParameteriMESANULL;
}
if (extensions.count("GL_NV_fence") != 0)
{
deleteFencesNV = &glDeleteFencesNVNULL;

View File

@@ -807,6 +807,9 @@ class DispatchTableGL : angle::NonCopyable
// GL_KHR_parallel_shader_compile
PFNGLMAXSHADERCOMPILERTHREADSKHRPROC maxShaderCompilerThreadsKHR = nullptr;
// GL_MESA_framebuffer_flip_y
PFNGLFRAMEBUFFERPARAMETERIMESAPROC framebufferParameteriMESA = nullptr;
// GL_NV_framebuffer_blit
PFNGLBLITFRAMEBUFFERNVPROC blitFramebufferNV = nullptr;

View File

@@ -1327,8 +1327,17 @@ angle::Result FramebufferGL::syncState(const gl::Context *context,
mState.getDefaultLayers());
break;
case Framebuffer::DIRTY_BIT_FLIP_Y:
functions->framebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_FLIP_Y_MESA,
gl::ConvertToGLBoolean(mState.getFlipY()));
ASSERT(functions->framebufferParameteri || functions->framebufferParameteriMESA);
if (functions->framebufferParameteri)
{
functions->framebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_FLIP_Y_MESA,
gl::ConvertToGLBoolean(mState.getFlipY()));
}
else
{
functions->framebufferParameteriMESA(GL_FRAMEBUFFER, GL_FRAMEBUFFER_FLIP_Y_MESA,
gl::ConvertToGLBoolean(mState.getFlipY()));
}
break;
default:
{

View File

@@ -1993,6 +1993,9 @@ typedef void(INTERNAL_GL_APIENTRY *PFNGLPOLYGONOFFSETCLAMPEXTPROC)(GLfloat facto
// GL_EXT_shader_framebuffer_fetch_non_coherent
typedef void(INTERNAL_GL_APIENTRY *PFNGLFRAMEBUFFERFETCHBARRIEREXTPROC)();
// GL_MESA_framebuffer_flip_y
typedef void(INTERNAL_GL_APIENTRY *PFNGLFRAMEBUFFERPARAMETERIMESAPROC)(GLenum, GLenum, GLint);
} // namespace rx
#endif // LIBANGLE_RENDERER_GL_FUNCTIONSGLTYPEDEFS_H_

View File

@@ -876,5 +876,10 @@
"GL_EXT_shader_framebuffer_fetch_non_coherent":
[
"FramebufferFetchBarrierEXT"
],
"GL_MESA_framebuffer_flip_y":
[
"FramebufferParameteriMESA"
]
}

View File

@@ -814,6 +814,9 @@ void INTERNAL_GL_APIENTRY glFramebufferFetchBarrierEXTNULL() {}
void INTERNAL_GL_APIENTRY glFramebufferParameteriNULL(GLenum target, GLenum pname, GLint param) {}
void INTERNAL_GL_APIENTRY glFramebufferParameteriMESANULL(GLenum target, GLenum pname, GLint param)
{}
void INTERNAL_GL_APIENTRY glFramebufferRenderbufferNULL(GLenum target,
GLenum attachment,
GLenum renderbuffertarget,

View File

@@ -551,6 +551,7 @@ void INTERNAL_GL_APIENTRY glFlushMappedNamedBufferRangeNULL(GLuint buffer,
GLsizeiptr length);
void INTERNAL_GL_APIENTRY glFramebufferFetchBarrierEXTNULL();
void INTERNAL_GL_APIENTRY glFramebufferParameteriNULL(GLenum target, GLenum pname, GLint param);
void INTERNAL_GL_APIENTRY glFramebufferParameteriMESANULL(GLenum target, GLenum pname, GLint param);
void INTERNAL_GL_APIENTRY glFramebufferRenderbufferNULL(GLenum target,
GLenum attachment,
GLenum renderbuffertarget,