mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2025-01-13 14:00:09 +00:00
gl: Add more OpenGL ES checks
Check for the appropriate extensions depending on which type of API we're using.
This commit is contained in:
parent
8bb4eb5544
commit
1620b7bda7
26
gdk/gdkgl.c
26
gdk/gdkgl.c
@ -370,6 +370,9 @@ gdk_cairo_draw_from_gl (cairo_t *cr,
|
|||||||
{
|
{
|
||||||
glBindTexture (GL_TEXTURE_2D, source);
|
glBindTexture (GL_TEXTURE_2D, source);
|
||||||
|
|
||||||
|
if (gdk_gl_context_get_use_es (paint_context))
|
||||||
|
alpha_size = 1;
|
||||||
|
else
|
||||||
glGetTexLevelParameteriv (GL_TEXTURE_2D, 0, GL_TEXTURE_ALPHA_SIZE, &alpha_size);
|
glGetTexLevelParameteriv (GL_TEXTURE_2D, 0, GL_TEXTURE_ALPHA_SIZE, &alpha_size);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -419,7 +422,22 @@ gdk_cairo_draw_from_gl (cairo_t *cr,
|
|||||||
glEnable (GL_SCISSOR_TEST);
|
glEnable (GL_SCISSOR_TEST);
|
||||||
|
|
||||||
gdk_window_get_unscaled_size (impl_window, NULL, &unscaled_window_height);
|
gdk_window_get_unscaled_size (impl_window, NULL, &unscaled_window_height);
|
||||||
|
|
||||||
|
if (!gdk_gl_context_get_use_es (paint_context))
|
||||||
glDrawBuffer (GL_BACK);
|
glDrawBuffer (GL_BACK);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int maj, min;
|
||||||
|
|
||||||
|
gdk_gl_context_get_version (paint_context, &maj, &min);
|
||||||
|
|
||||||
|
if ((maj * 100 + min) >= 300)
|
||||||
|
{
|
||||||
|
static const GLenum buffers[] = { GL_BACK };
|
||||||
|
|
||||||
|
glDrawBuffers (G_N_ELEMENTS (buffers), buffers);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#define FLIP_Y(_y) (unscaled_window_height - (_y))
|
#define FLIP_Y(_y) (unscaled_window_height - (_y))
|
||||||
|
|
||||||
@ -518,8 +536,16 @@ gdk_cairo_draw_from_gl (cairo_t *cr,
|
|||||||
|
|
||||||
glBindTexture (GL_TEXTURE_2D, source);
|
glBindTexture (GL_TEXTURE_2D, source);
|
||||||
|
|
||||||
|
if (gdk_gl_context_get_use_es (paint_context))
|
||||||
|
{
|
||||||
|
texture_width = width;
|
||||||
|
texture_height = height;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
glGetTexLevelParameteriv (GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &texture_width);
|
glGetTexLevelParameteriv (GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &texture_width);
|
||||||
glGetTexLevelParameteriv (GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &texture_height);
|
glGetTexLevelParameteriv (GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &texture_height);
|
||||||
|
}
|
||||||
|
|
||||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||||
|
@ -100,6 +100,7 @@ typedef struct {
|
|||||||
guint use_texture_rectangle : 1;
|
guint use_texture_rectangle : 1;
|
||||||
guint has_gl_framebuffer_blit : 1;
|
guint has_gl_framebuffer_blit : 1;
|
||||||
guint has_frame_terminator : 1;
|
guint has_frame_terminator : 1;
|
||||||
|
guint has_unpack_subimage : 1;
|
||||||
guint extensions_checked : 1;
|
guint extensions_checked : 1;
|
||||||
guint debug_enabled : 1;
|
guint debug_enabled : 1;
|
||||||
guint forward_compatible : 1;
|
guint forward_compatible : 1;
|
||||||
@ -240,13 +241,23 @@ gdk_gl_context_upload_texture (GdkGLContext *context,
|
|||||||
int height,
|
int height,
|
||||||
guint texture_target)
|
guint texture_target)
|
||||||
{
|
{
|
||||||
|
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
|
||||||
|
|
||||||
g_return_if_fail (GDK_IS_GL_CONTEXT (context));
|
g_return_if_fail (GDK_IS_GL_CONTEXT (context));
|
||||||
|
|
||||||
|
/* GL_UNPACK_ROW_LENGTH is available on desktop GL, OpenGL ES >= 3.0, or if
|
||||||
|
* the GL_EXT_unpack_subimage extension for OpenGL ES 2.0 is available
|
||||||
|
*/
|
||||||
|
if (epoxy_is_desktop_gl () || priv->gl_version >= 30 || priv->has_unpack_subimage)
|
||||||
|
{
|
||||||
glPixelStorei (GL_UNPACK_ALIGNMENT, 4);
|
glPixelStorei (GL_UNPACK_ALIGNMENT, 4);
|
||||||
glPixelStorei (GL_UNPACK_ROW_LENGTH, cairo_image_surface_get_stride (image_surface)/4);
|
glPixelStorei (GL_UNPACK_ROW_LENGTH, cairo_image_surface_get_stride (image_surface) / 4);
|
||||||
glTexImage2D (texture_target, 0, GL_RGBA, width, height, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
|
glTexImage2D (texture_target, 0, GL_RGBA, width, height, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
|
||||||
cairo_image_surface_get_data (image_surface));
|
cairo_image_surface_get_data (image_surface));
|
||||||
glPixelStorei (GL_UNPACK_ROW_LENGTH, 0);
|
glPixelStorei (GL_UNPACK_ROW_LENGTH, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
g_critical ("Unable to upload the contents of the image surface");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -379,6 +390,14 @@ gdk_gl_context_has_frame_terminator (GdkGLContext *context)
|
|||||||
return priv->has_frame_terminator;
|
return priv->has_frame_terminator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gdk_gl_context_has_unpack_subimage (GdkGLContext *context)
|
||||||
|
{
|
||||||
|
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
|
||||||
|
|
||||||
|
return priv->has_unpack_subimage;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gdk_gl_context_set_debug_enabled:
|
* gdk_gl_context_set_debug_enabled:
|
||||||
* @context: a #GdkGLContext
|
* @context: a #GdkGLContext
|
||||||
@ -515,10 +534,10 @@ gdk_gl_context_set_required_version (GdkGLContext *context,
|
|||||||
/* Enforce a minimum context version number of 3.2 */
|
/* Enforce a minimum context version number of 3.2 */
|
||||||
version = (major * 100) + minor;
|
version = (major * 100) + minor;
|
||||||
|
|
||||||
if (!priv->use_es)
|
if (priv->use_es || (_gdk_gl_flags & GDK_GL_GLES) != 0)
|
||||||
min_ver = 302;
|
|
||||||
else
|
|
||||||
min_ver = 200;
|
min_ver = 200;
|
||||||
|
else
|
||||||
|
min_ver = 302;
|
||||||
|
|
||||||
if (version < min_ver)
|
if (version < min_ver)
|
||||||
{
|
{
|
||||||
@ -551,16 +570,16 @@ gdk_gl_context_get_required_version (GdkGLContext *context,
|
|||||||
|
|
||||||
g_return_if_fail (GDK_IS_GL_CONTEXT (context));
|
g_return_if_fail (GDK_IS_GL_CONTEXT (context));
|
||||||
|
|
||||||
if (!priv->use_es)
|
if (priv->use_es || (_gdk_gl_flags & GDK_GL_GLES) != 0)
|
||||||
{
|
|
||||||
default_major = 3;
|
|
||||||
default_minor = 2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
default_major = 2;
|
default_major = 2;
|
||||||
default_minor = 0;
|
default_minor = 0;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
default_major = 3;
|
||||||
|
default_minor = 2;
|
||||||
|
}
|
||||||
|
|
||||||
if (priv->major > 0)
|
if (priv->major > 0)
|
||||||
maj = priv->major;
|
maj = priv->major;
|
||||||
@ -623,20 +642,50 @@ gdk_gl_context_set_is_legacy (GdkGLContext *context,
|
|||||||
priv->is_legacy = !!is_legacy;
|
priv->is_legacy = !!is_legacy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gdk_gl_context_set_use_es:
|
||||||
|
* @context: a #GdkGLContext:
|
||||||
|
* @use_es: whether the context should use OpenGL ES instead of OpenGL
|
||||||
|
*
|
||||||
|
* Requests that GDK create a OpenGL ES context instead of an OpenGL one.
|
||||||
|
*
|
||||||
|
* The @context must not have been realized.
|
||||||
|
*
|
||||||
|
* You should check the return value of gdk_gl_context_get_use_es() to
|
||||||
|
* decide whether to use the OpenGL or OpenGL ES API, extensions, or
|
||||||
|
* shaders.
|
||||||
|
*
|
||||||
|
* Since: 3.22
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
gdk_gl_context_set_use_es (GdkGLContext *context,
|
gdk_gl_context_set_use_es (GdkGLContext *context,
|
||||||
gboolean use_es)
|
gboolean use_es)
|
||||||
{
|
{
|
||||||
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
|
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
|
||||||
|
|
||||||
|
g_return_if_fail (GDK_IS_GL_CONTEXT (context));
|
||||||
|
g_return_if_fail (!priv->realized);
|
||||||
|
|
||||||
priv->use_es = !!use_es;
|
priv->use_es = !!use_es;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gdk_gl_context_get_use_es:
|
||||||
|
* @context: a #GdkGLContext
|
||||||
|
*
|
||||||
|
* Checks whether the @context is using an OpenGL or OpenGL ES profile.
|
||||||
|
*
|
||||||
|
* Returns: %TRUE if the #GdkGLContext is using an OpenGL ES profile
|
||||||
|
*
|
||||||
|
* Since: 3.22
|
||||||
|
*/
|
||||||
gboolean
|
gboolean
|
||||||
gdk_gl_context_get_use_es (GdkGLContext *context)
|
gdk_gl_context_get_use_es (GdkGLContext *context)
|
||||||
{
|
{
|
||||||
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
|
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
|
||||||
|
|
||||||
|
g_return_val_if_fail (GDK_IS_GL_CONTEXT (context), FALSE);
|
||||||
|
|
||||||
return priv->use_es;
|
return priv->use_es;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -681,15 +730,36 @@ gdk_gl_context_check_extensions (GdkGLContext *context)
|
|||||||
if (priv->extensions_checked)
|
if (priv->extensions_checked)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
priv->use_es = !epoxy_is_desktop_gl ();
|
||||||
priv->gl_version = epoxy_gl_version ();
|
priv->gl_version = epoxy_gl_version ();
|
||||||
|
|
||||||
|
if (priv->use_es)
|
||||||
|
{
|
||||||
|
has_npot = priv->gl_version >= 20;
|
||||||
|
has_texture_rectangle = FALSE;
|
||||||
|
|
||||||
|
/* This should check for GL_NV_framebuffer_blit - see extension at:
|
||||||
|
*
|
||||||
|
* https://www.khronos.org/registry/gles/extensions/NV/NV_framebuffer_blit.txt
|
||||||
|
*/
|
||||||
|
priv->has_gl_framebuffer_blit = FALSE;
|
||||||
|
|
||||||
|
/* No OES version */
|
||||||
|
priv->has_frame_terminator = FALSE;
|
||||||
|
|
||||||
|
priv->has_unpack_subimage = epoxy_has_gl_extension ("GL_EXT_unpack_subimage");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
has_npot = epoxy_has_gl_extension ("GL_ARB_texture_non_power_of_two");
|
has_npot = epoxy_has_gl_extension ("GL_ARB_texture_non_power_of_two");
|
||||||
has_texture_rectangle = epoxy_has_gl_extension ("GL_ARB_texture_rectangle");
|
has_texture_rectangle = epoxy_has_gl_extension ("GL_ARB_texture_rectangle");
|
||||||
|
|
||||||
priv->has_gl_framebuffer_blit = epoxy_has_gl_extension ("GL_EXT_framebuffer_blit");
|
priv->has_gl_framebuffer_blit = epoxy_has_gl_extension ("GL_EXT_framebuffer_blit");
|
||||||
priv->has_frame_terminator = epoxy_has_gl_extension ("GL_GREMEDY_frame_terminator");
|
priv->has_frame_terminator = epoxy_has_gl_extension ("GL_GREMEDY_frame_terminator");
|
||||||
|
priv->has_unpack_subimage = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
if (G_UNLIKELY (_gdk_gl_flags & GDK_GL_TEXTURE_RECTANGLE))
|
if (!priv->use_es && G_UNLIKELY (_gdk_gl_flags & GDK_GL_TEXTURE_RECTANGLE))
|
||||||
priv->use_texture_rectangle = TRUE;
|
priv->use_texture_rectangle = TRUE;
|
||||||
else if (has_npot)
|
else if (has_npot)
|
||||||
priv->use_texture_rectangle = FALSE;
|
priv->use_texture_rectangle = FALSE;
|
||||||
@ -699,13 +769,14 @@ gdk_gl_context_check_extensions (GdkGLContext *context)
|
|||||||
g_warning ("GL implementation doesn't support any form of non-power-of-two textures");
|
g_warning ("GL implementation doesn't support any form of non-power-of-two textures");
|
||||||
|
|
||||||
GDK_NOTE (OPENGL,
|
GDK_NOTE (OPENGL,
|
||||||
g_message ("OpenGL version: %d.%d\n"
|
g_message ("%s version: %d.%d\n"
|
||||||
"Extensions checked:\n"
|
"* Extensions checked:\n"
|
||||||
" - GL_ARB_texture_non_power_of_two: %s\n"
|
" - GL_ARB_texture_non_power_of_two: %s\n"
|
||||||
" - GL_ARB_texture_rectangle: %s\n"
|
" - GL_ARB_texture_rectangle: %s\n"
|
||||||
" - GL_EXT_framebuffer_blit: %s\n"
|
" - GL_EXT_framebuffer_blit: %s\n"
|
||||||
" - GL_GREMEDY_frame_terminator: %s\n"
|
" - GL_GREMEDY_frame_terminator: %s\n"
|
||||||
"Using texture rectangle: %s",
|
"* Using texture rectangle: %s",
|
||||||
|
priv->use_es ? "OpenGL ES" : "OpenGL",
|
||||||
priv->gl_version / 10, priv->gl_version % 10,
|
priv->gl_version / 10, priv->gl_version % 10,
|
||||||
has_npot ? "yes" : "no",
|
has_npot ? "yes" : "no",
|
||||||
has_texture_rectangle ? "yes" : "no",
|
has_texture_rectangle ? "yes" : "no",
|
||||||
|
@ -84,6 +84,7 @@ GdkGLContextPaintData * gdk_gl_context_get_paint_data (GdkGLContext
|
|||||||
gboolean gdk_gl_context_use_texture_rectangle (GdkGLContext *context);
|
gboolean gdk_gl_context_use_texture_rectangle (GdkGLContext *context);
|
||||||
gboolean gdk_gl_context_has_framebuffer_blit (GdkGLContext *context);
|
gboolean gdk_gl_context_has_framebuffer_blit (GdkGLContext *context);
|
||||||
gboolean gdk_gl_context_has_frame_terminator (GdkGLContext *context);
|
gboolean gdk_gl_context_has_frame_terminator (GdkGLContext *context);
|
||||||
|
gboolean gdk_gl_context_has_unpack_subimage (GdkGLContext *context);
|
||||||
void gdk_gl_context_end_frame (GdkGLContext *context,
|
void gdk_gl_context_end_frame (GdkGLContext *context,
|
||||||
cairo_region_t *painted,
|
cairo_region_t *painted,
|
||||||
cairo_region_t *damage);
|
cairo_region_t *damage);
|
||||||
|
Loading…
Reference in New Issue
Block a user