mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-11-08 17:50:10 +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
34
gdk/gdkgl.c
34
gdk/gdkgl.c
@ -370,7 +370,10 @@ gdk_cairo_draw_from_gl (cairo_t *cr,
|
||||
{
|
||||
glBindTexture (GL_TEXTURE_2D, source);
|
||||
|
||||
glGetTexLevelParameteriv (GL_TEXTURE_2D, 0, GL_TEXTURE_ALPHA_SIZE, &alpha_size);
|
||||
if (gdk_gl_context_get_use_es (paint_context))
|
||||
alpha_size = 1;
|
||||
else
|
||||
glGetTexLevelParameteriv (GL_TEXTURE_2D, 0, GL_TEXTURE_ALPHA_SIZE, &alpha_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -419,7 +422,22 @@ gdk_cairo_draw_from_gl (cairo_t *cr,
|
||||
glEnable (GL_SCISSOR_TEST);
|
||||
|
||||
gdk_window_get_unscaled_size (impl_window, NULL, &unscaled_window_height);
|
||||
glDrawBuffer (GL_BACK);
|
||||
|
||||
if (!gdk_gl_context_get_use_es (paint_context))
|
||||
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))
|
||||
|
||||
@ -518,8 +536,16 @@ gdk_cairo_draw_from_gl (cairo_t *cr,
|
||||
|
||||
glBindTexture (GL_TEXTURE_2D, source);
|
||||
|
||||
glGetTexLevelParameteriv (GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &texture_width);
|
||||
glGetTexLevelParameteriv (GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &texture_height);
|
||||
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_HEIGHT, &texture_height);
|
||||
}
|
||||
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
|
@ -100,6 +100,7 @@ typedef struct {
|
||||
guint use_texture_rectangle : 1;
|
||||
guint has_gl_framebuffer_blit : 1;
|
||||
guint has_frame_terminator : 1;
|
||||
guint has_unpack_subimage : 1;
|
||||
guint extensions_checked : 1;
|
||||
guint debug_enabled : 1;
|
||||
guint forward_compatible : 1;
|
||||
@ -240,13 +241,23 @@ gdk_gl_context_upload_texture (GdkGLContext *context,
|
||||
int height,
|
||||
guint texture_target)
|
||||
{
|
||||
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
|
||||
|
||||
g_return_if_fail (GDK_IS_GL_CONTEXT (context));
|
||||
|
||||
glPixelStorei (GL_UNPACK_ALIGNMENT, 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,
|
||||
cairo_image_surface_get_data (image_surface));
|
||||
glPixelStorei (GL_UNPACK_ROW_LENGTH, 0);
|
||||
/* 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_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,
|
||||
cairo_image_surface_get_data (image_surface));
|
||||
glPixelStorei (GL_UNPACK_ROW_LENGTH, 0);
|
||||
}
|
||||
else
|
||||
g_critical ("Unable to upload the contents of the image surface");
|
||||
}
|
||||
|
||||
static void
|
||||
@ -379,6 +390,14 @@ gdk_gl_context_has_frame_terminator (GdkGLContext *context)
|
||||
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:
|
||||
* @context: a #GdkGLContext
|
||||
@ -515,10 +534,10 @@ gdk_gl_context_set_required_version (GdkGLContext *context,
|
||||
/* Enforce a minimum context version number of 3.2 */
|
||||
version = (major * 100) + minor;
|
||||
|
||||
if (!priv->use_es)
|
||||
min_ver = 302;
|
||||
else
|
||||
if (priv->use_es || (_gdk_gl_flags & GDK_GL_GLES) != 0)
|
||||
min_ver = 200;
|
||||
else
|
||||
min_ver = 302;
|
||||
|
||||
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));
|
||||
|
||||
if (!priv->use_es)
|
||||
{
|
||||
default_major = 3;
|
||||
default_minor = 2;
|
||||
}
|
||||
else
|
||||
if (priv->use_es || (_gdk_gl_flags & GDK_GL_GLES) != 0)
|
||||
{
|
||||
default_major = 2;
|
||||
default_minor = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
default_major = 3;
|
||||
default_minor = 2;
|
||||
}
|
||||
|
||||
if (priv->major > 0)
|
||||
maj = priv->major;
|
||||
@ -623,20 +642,50 @@ gdk_gl_context_set_is_legacy (GdkGLContext *context,
|
||||
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
|
||||
gdk_gl_context_set_use_es (GdkGLContext *context,
|
||||
gboolean use_es)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
gdk_gl_context_get_use_es (GdkGLContext *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;
|
||||
}
|
||||
|
||||
@ -681,15 +730,36 @@ gdk_gl_context_check_extensions (GdkGLContext *context)
|
||||
if (priv->extensions_checked)
|
||||
return;
|
||||
|
||||
priv->use_es = !epoxy_is_desktop_gl ();
|
||||
priv->gl_version = epoxy_gl_version ();
|
||||
|
||||
has_npot = epoxy_has_gl_extension ("GL_ARB_texture_non_power_of_two");
|
||||
has_texture_rectangle = epoxy_has_gl_extension ("GL_ARB_texture_rectangle");
|
||||
if (priv->use_es)
|
||||
{
|
||||
has_npot = priv->gl_version >= 20;
|
||||
has_texture_rectangle = FALSE;
|
||||
|
||||
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");
|
||||
/* 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;
|
||||
|
||||
if (G_UNLIKELY (_gdk_gl_flags & GDK_GL_TEXTURE_RECTANGLE))
|
||||
/* 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_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_frame_terminator = epoxy_has_gl_extension ("GL_GREMEDY_frame_terminator");
|
||||
priv->has_unpack_subimage = TRUE;
|
||||
}
|
||||
|
||||
if (!priv->use_es && G_UNLIKELY (_gdk_gl_flags & GDK_GL_TEXTURE_RECTANGLE))
|
||||
priv->use_texture_rectangle = TRUE;
|
||||
else if (has_npot)
|
||||
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");
|
||||
|
||||
GDK_NOTE (OPENGL,
|
||||
g_message ("OpenGL version: %d.%d\n"
|
||||
"Extensions checked:\n"
|
||||
g_message ("%s version: %d.%d\n"
|
||||
"* Extensions checked:\n"
|
||||
" - GL_ARB_texture_non_power_of_two: %s\n"
|
||||
" - GL_ARB_texture_rectangle: %s\n"
|
||||
" - GL_EXT_framebuffer_blit: %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,
|
||||
has_npot ? "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_has_framebuffer_blit (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,
|
||||
cairo_region_t *painted,
|
||||
cairo_region_t *damage);
|
||||
|
Loading…
Reference in New Issue
Block a user