gl-renderer: Implement & use check_extension

Using strstr(3) for checking for extensions is an error-prone mechanism
as extension names can be prefixes of other extension names (see
https://www.opengl.org/registry/doc/rules.html#using).

This change implements the check_extension() function to properly check
for an extension and replaces all usages of strstr(3).

Signed-off-by: Miguel A Vico Moya <mvicomoya@nvidia.com>
Reviewed-by: Andy Ritger <aritger@nvidia.com>
Reviewed-by: Daniel Stone <daniels@collabora.com>
[Pekka: move 'bool' to the same line with 'static']
Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
This commit is contained in:
Miguel A. Vico 2016-03-21 17:37:33 +01:00 committed by Pekka Paalanen
parent c6459c495d
commit cc3a192b44

View File

@ -2668,6 +2668,34 @@ gl_renderer_destroy(struct weston_compositor *ec)
free(gr); free(gr);
} }
static bool
check_extension(const char *extensions, const char *extension)
{
size_t extlen = strlen(extension);
const char *end = extensions + strlen(extensions);
while (extensions < end) {
size_t n = 0;
/* Skip whitespaces, if any */
if (*extensions == ' ') {
extensions++;
continue;
}
n = strcspn(extensions, " ");
/* Compare strings */
if (n == extlen && strncmp(extension, extensions, n) == 0)
return true; /* Found */
extensions += n;
}
/* Not found */
return false;
}
static void static void
renderer_setup_egl_client_extensions(struct gl_renderer *gr) renderer_setup_egl_client_extensions(struct gl_renderer *gr)
{ {
@ -2679,7 +2707,7 @@ renderer_setup_egl_client_extensions(struct gl_renderer *gr)
return; return;
} }
if (strstr(extensions, "EGL_EXT_platform_base")) if (check_extension(extensions, "EGL_EXT_platform_base"))
gr->create_platform_window = gr->create_platform_window =
(void *) eglGetProcAddress("eglCreatePlatformWindowSurfaceEXT"); (void *) eglGetProcAddress("eglCreatePlatformWindowSurfaceEXT");
else else
@ -2709,7 +2737,7 @@ gl_renderer_setup_egl_extensions(struct weston_compositor *ec)
return -1; return -1;
} }
if (strstr(extensions, "EGL_WL_bind_wayland_display")) if (check_extension(extensions, "EGL_WL_bind_wayland_display"))
gr->has_bind_display = 1; gr->has_bind_display = 1;
if (gr->has_bind_display) { if (gr->has_bind_display) {
ret = gr->bind_display(gr->egl_display, ec->wl_display); ret = gr->bind_display(gr->egl_display, ec->wl_display);
@ -2717,14 +2745,14 @@ gl_renderer_setup_egl_extensions(struct weston_compositor *ec)
gr->has_bind_display = 0; gr->has_bind_display = 0;
} }
if (strstr(extensions, "EGL_EXT_buffer_age")) if (check_extension(extensions, "EGL_EXT_buffer_age"))
gr->has_egl_buffer_age = 1; gr->has_egl_buffer_age = 1;
else else
weston_log("warning: EGL_EXT_buffer_age not supported. " weston_log("warning: EGL_EXT_buffer_age not supported. "
"Performance could be affected.\n"); "Performance could be affected.\n");
#ifdef EGL_EXT_swap_buffers_with_damage #ifdef EGL_EXT_swap_buffers_with_damage
if (strstr(extensions, "EGL_EXT_swap_buffers_with_damage")) if (check_extension(extensions, "EGL_EXT_swap_buffers_with_damage"))
gr->swap_buffers_with_damage = gr->swap_buffers_with_damage =
(void *) eglGetProcAddress("eglSwapBuffersWithDamageEXT"); (void *) eglGetProcAddress("eglSwapBuffersWithDamageEXT");
else else
@ -2733,12 +2761,12 @@ gl_renderer_setup_egl_extensions(struct weston_compositor *ec)
#endif #endif
#ifdef EGL_MESA_configless_context #ifdef EGL_MESA_configless_context
if (strstr(extensions, "EGL_MESA_configless_context")) if (check_extension(extensions, "EGL_MESA_configless_context"))
gr->has_configless_context = 1; gr->has_configless_context = 1;
#endif #endif
#ifdef EGL_EXT_image_dma_buf_import #ifdef EGL_EXT_image_dma_buf_import
if (strstr(extensions, "EGL_EXT_image_dma_buf_import")) if (check_extension(extensions, "EGL_EXT_image_dma_buf_import"))
gr->has_dmabuf_import = 1; gr->has_dmabuf_import = 1;
#endif #endif
@ -2807,19 +2835,19 @@ gl_renderer_supports(struct weston_compositor *ec,
extensions); extensions);
} }
if (!strstr(extensions, "EGL_EXT_platform_base")) if (!check_extension(extensions, "EGL_EXT_platform_base"))
return 0; return 0;
snprintf(s, sizeof s, "EGL_KHR_platform_%s", extension_suffix); snprintf(s, sizeof s, "EGL_KHR_platform_%s", extension_suffix);
if (strstr(extensions, s)) if (check_extension(extensions, s))
return 1; return 1;
snprintf(s, sizeof s, "EGL_EXT_platform_%s", extension_suffix); snprintf(s, sizeof s, "EGL_EXT_platform_%s", extension_suffix);
if (strstr(extensions, s)) if (check_extension(extensions, s))
return 1; return 1;
snprintf(s, sizeof s, "EGL_MESA_platform_%s", extension_suffix); snprintf(s, sizeof s, "EGL_MESA_platform_%s", extension_suffix);
if (strstr(extensions, s)) if (check_extension(extensions, s))
return 1; return 1;
/* at this point we definitely have some platform extensions but /* at this point we definitely have some platform extensions but
@ -3071,22 +3099,22 @@ gl_renderer_setup(struct weston_compositor *ec, EGLSurface egl_surface)
return -1; return -1;
} }
if (!strstr(extensions, "GL_EXT_texture_format_BGRA8888")) { if (!check_extension(extensions, "GL_EXT_texture_format_BGRA8888")) {
weston_log("GL_EXT_texture_format_BGRA8888 not available\n"); weston_log("GL_EXT_texture_format_BGRA8888 not available\n");
return -1; return -1;
} }
if (strstr(extensions, "GL_EXT_read_format_bgra")) if (check_extension(extensions, "GL_EXT_read_format_bgra"))
ec->read_format = PIXMAN_a8r8g8b8; ec->read_format = PIXMAN_a8r8g8b8;
else else
ec->read_format = PIXMAN_a8b8g8r8; ec->read_format = PIXMAN_a8b8g8r8;
#ifdef GL_EXT_unpack_subimage #ifdef GL_EXT_unpack_subimage
if (strstr(extensions, "GL_EXT_unpack_subimage")) if (check_extension(extensions, "GL_EXT_unpack_subimage"))
gr->has_unpack_subimage = 1; gr->has_unpack_subimage = 1;
#endif #endif
if (strstr(extensions, "GL_OES_EGL_image_external")) if (check_extension(extensions, "GL_OES_EGL_image_external"))
gr->has_egl_image_external = 1; gr->has_egl_image_external = 1;
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);