mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-12-26 21:51:08 +00:00
opengl: Use GL_TEXTURE_2D rather than GL_TEXTURE_RECTANGLE_ARB when possible
This is more standard, and most driver support non-power-of-2 TEXTURE_2D these days. We fall back for ancient drivers.
This commit is contained in:
parent
08d44648ea
commit
f7b1ba0943
73
gdk/gdkgl.c
73
gdk/gdkgl.c
@ -113,20 +113,15 @@ gdk_cairo_draw_from_gl (cairo_t *cr,
|
||||
glBindRenderbufferEXT (GL_RENDERBUFFER_EXT, source);
|
||||
glFramebufferRenderbufferEXT (GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
|
||||
GL_RENDERBUFFER_EXT, source);
|
||||
glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0);
|
||||
glBindFramebufferEXT (GL_DRAW_FRAMEBUFFER_EXT, 0);
|
||||
}
|
||||
else if (source_type == GL_TEXTURE)
|
||||
{
|
||||
glBindTexture (GL_TEXTURE_2D, source);
|
||||
|
||||
glGetTexLevelParameteriv (GL_TEXTURE_2D, 0, GL_TEXTURE_ALPHA_SIZE, &alpha_size);
|
||||
|
||||
glBindTexture (GL_TEXTURE_2D, source);
|
||||
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_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glFramebufferTexture2DEXT (GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
|
||||
GL_TEXTURE_2D, source, 0);
|
||||
glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0);
|
||||
glBindFramebufferEXT (GL_DRAW_FRAMEBUFFER_EXT, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -234,9 +229,6 @@ gdk_cairo_draw_from_gl (cairo_t *cr,
|
||||
/* Translate to impl coords */
|
||||
cairo_region_translate (clip_region, dx, dy);
|
||||
|
||||
glGetTexLevelParameteriv (GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &texture_width);
|
||||
glGetTexLevelParameteriv (GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &texture_height);
|
||||
|
||||
if (alpha_size != 0)
|
||||
{
|
||||
cairo_region_t *opaque_region, *blend_region;
|
||||
@ -260,6 +252,19 @@ gdk_cairo_draw_from_gl (cairo_t *cr,
|
||||
cairo_region_destroy (opaque_region);
|
||||
cairo_region_destroy (blend_region);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
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_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glFramebufferTexture2DEXT (GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
|
||||
GL_TEXTURE_2D, source, 0);
|
||||
|
||||
glEnable (GL_SCISSOR_TEST);
|
||||
glEnable (GL_TEXTURE_2D);
|
||||
|
||||
@ -389,6 +394,9 @@ gdk_gl_texture_from_surface (cairo_surface_t *surface,
|
||||
unsigned int texture_id;
|
||||
int window_scale;
|
||||
double sx, sy;
|
||||
float umax, vmax;
|
||||
gboolean use_texture_rectangle;
|
||||
guint target;
|
||||
|
||||
current = gdk_gl_context_get_current ();
|
||||
if (current &&
|
||||
@ -398,7 +406,9 @@ gdk_gl_texture_from_surface (cairo_surface_t *surface,
|
||||
|
||||
/* Software fallback */
|
||||
|
||||
window = gdk_gl_context_get_window (gdk_gl_context_get_current ());
|
||||
use_texture_rectangle = gdk_gl_context_use_texture_rectangle (current);
|
||||
|
||||
window = gdk_gl_context_get_window (current);
|
||||
window_scale = gdk_window_get_scale_factor (window);
|
||||
window_height = gdk_window_get_height (window);
|
||||
|
||||
@ -411,8 +421,18 @@ gdk_gl_texture_from_surface (cairo_surface_t *surface,
|
||||
&device_x_offset, &device_y_offset);
|
||||
|
||||
glGenTextures (1, &texture_id);
|
||||
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture_id);
|
||||
glEnable (GL_TEXTURE_RECTANGLE_ARB);
|
||||
if (use_texture_rectangle)
|
||||
target = GL_TEXTURE_RECTANGLE_ARB;
|
||||
else
|
||||
target = GL_TEXTURE_2D;
|
||||
|
||||
glBindTexture (target, texture_id);
|
||||
glEnable (target);
|
||||
|
||||
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_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
|
||||
n_rects = cairo_region_num_rectangles (region);
|
||||
for (i = 0; i < n_rects; i++)
|
||||
@ -433,7 +453,7 @@ gdk_gl_texture_from_surface (cairo_surface_t *surface,
|
||||
|
||||
glPixelStorei (GL_UNPACK_ALIGNMENT, 4);
|
||||
glPixelStorei (GL_UNPACK_ROW_LENGTH, cairo_image_surface_get_stride (image)/4);
|
||||
glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, 4, e.width, e.height, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
|
||||
glTexImage2D (target, 0, 4, e.width, e.height, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
|
||||
cairo_image_surface_get_data (image));
|
||||
glPixelStorei (GL_UNPACK_ROW_LENGTH, 0);
|
||||
|
||||
@ -441,21 +461,32 @@ gdk_gl_texture_from_surface (cairo_surface_t *surface,
|
||||
|
||||
#define FLIP_Y(_y) (window_height - (_y))
|
||||
|
||||
if (use_texture_rectangle)
|
||||
{
|
||||
umax = rect.width * sx;
|
||||
vmax = rect.height * sy;
|
||||
}
|
||||
else
|
||||
{
|
||||
umax = 1.0;
|
||||
vmax = 1.0;
|
||||
}
|
||||
|
||||
glBegin (GL_QUADS);
|
||||
glTexCoord2f (0.0f * sx, rect.height * sy);
|
||||
glTexCoord2f (0, vmax);
|
||||
glVertex2f (rect.x * window_scale, FLIP_Y(rect.y + rect.height) * window_scale);
|
||||
|
||||
glTexCoord2f (rect.width * sx, rect.height * sy);
|
||||
glTexCoord2f (umax, vmax);
|
||||
glVertex2f ((rect.x + rect.width) * window_scale, FLIP_Y(rect.y + rect.height) * window_scale);
|
||||
|
||||
glTexCoord2f (rect.width * sx, 0.0f * sy);
|
||||
glTexCoord2f (umax, 0);
|
||||
glVertex2f ((rect.x + rect.width) * window_scale, FLIP_Y(rect.y) * window_scale);
|
||||
|
||||
glTexCoord2f (0.0f * sx, 0.0f * sy);
|
||||
glTexCoord2f (0, 0);
|
||||
glVertex2f (rect.x * window_scale, FLIP_Y(rect.y) * window_scale);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
glDisable (GL_TEXTURE_RECTANGLE_ARB);
|
||||
glDisable (target);
|
||||
glDeleteTextures (1, &texture_id);
|
||||
}
|
||||
|
@ -288,41 +288,64 @@ glx_pixmap_get (cairo_surface_t *surface)
|
||||
XVisualInfo *visinfo;
|
||||
int i, value;
|
||||
gboolean y_inverted;
|
||||
const int pixmap_attributes[] = {
|
||||
GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT,
|
||||
GLX_TEXTURE_FORMAT_EXT, GLX_TEXTURE_FORMAT_RGBA_EXT,
|
||||
gboolean with_alpha;
|
||||
guint target = 0;
|
||||
guint format = 0;
|
||||
int pixmap_attributes[] = {
|
||||
GLX_TEXTURE_TARGET_EXT, 0,
|
||||
GLX_TEXTURE_FORMAT_EXT, 0,
|
||||
None
|
||||
};
|
||||
|
||||
with_alpha = cairo_surface_get_content (surface) == CAIRO_CONTENT_COLOR_ALPHA;
|
||||
|
||||
y_inverted = FALSE;
|
||||
fbconfigs = glXGetFBConfigs (display, XScreenNumberOfScreen (screen), &nfbconfigs);
|
||||
for (i = 0; i < nfbconfigs; i++)
|
||||
{
|
||||
visinfo = glXGetVisualFromFBConfig (display, fbconfigs[i]);
|
||||
if (!visinfo || visinfo->visualid != XVisualIDFromVisual (visual))
|
||||
continue;
|
||||
continue;
|
||||
|
||||
glXGetFBConfigAttrib (display, fbconfigs[i], GLX_DRAWABLE_TYPE, &value);
|
||||
if (!(value & GLX_PIXMAP_BIT))
|
||||
continue;
|
||||
|
||||
glXGetFBConfigAttrib (display, fbconfigs[i],
|
||||
GLX_BIND_TO_TEXTURE_TARGETS_EXT,
|
||||
&value);
|
||||
if ((value & GLX_TEXTURE_RECTANGLE_BIT_EXT))
|
||||
continue;
|
||||
|
||||
glXGetFBConfigAttrib (display, fbconfigs[i],
|
||||
GLX_BIND_TO_TEXTURE_RGBA_EXT,
|
||||
&value);
|
||||
if (value == FALSE)
|
||||
continue;
|
||||
|
||||
glXGetFBConfigAttrib (display, fbconfigs[i],
|
||||
GLX_Y_INVERTED_EXT,
|
||||
&value);
|
||||
GLX_BIND_TO_TEXTURE_TARGETS_EXT,
|
||||
&value);
|
||||
if ((value & (GLX_TEXTURE_RECTANGLE_BIT_EXT | GLX_TEXTURE_2D_BIT_EXT)) == 0)
|
||||
continue;
|
||||
if ((value & GLX_TEXTURE_2D_BIT_EXT))
|
||||
target = GLX_TEXTURE_2D_EXT;
|
||||
else
|
||||
target = GLX_TEXTURE_RECTANGLE_EXT;
|
||||
|
||||
if (!with_alpha)
|
||||
{
|
||||
glXGetFBConfigAttrib (display, fbconfigs[i],
|
||||
GLX_BIND_TO_TEXTURE_RGB_EXT,
|
||||
&value);
|
||||
if (!value)
|
||||
continue;
|
||||
|
||||
format = GLX_TEXTURE_FORMAT_RGB_EXT;
|
||||
}
|
||||
else
|
||||
{
|
||||
glXGetFBConfigAttrib (display, fbconfigs[i],
|
||||
GLX_BIND_TO_TEXTURE_RGBA_EXT,
|
||||
&value);
|
||||
if (!value)
|
||||
continue;
|
||||
format = GLX_TEXTURE_FORMAT_RGBA_EXT;
|
||||
}
|
||||
|
||||
glXGetFBConfigAttrib (display, fbconfigs[i],
|
||||
GLX_Y_INVERTED_EXT,
|
||||
&value);
|
||||
if (value == TRUE)
|
||||
y_inverted = TRUE;
|
||||
y_inverted = TRUE;
|
||||
|
||||
break;
|
||||
}
|
||||
@ -330,6 +353,9 @@ glx_pixmap_get (cairo_surface_t *surface)
|
||||
if (i == nfbconfigs)
|
||||
return NULL;
|
||||
|
||||
pixmap_attributes[1] = target;
|
||||
pixmap_attributes[3] = format;
|
||||
|
||||
glx_pixmap = g_slice_new0 (GdkGLXPixmap);
|
||||
glx_pixmap->y_inverted = y_inverted;
|
||||
glx_pixmap->display = display;
|
||||
@ -345,6 +371,7 @@ gdk_x11_gl_context_texture_from_surface (GdkGLContext *context,
|
||||
cairo_surface_t *surface,
|
||||
cairo_region_t *region)
|
||||
{
|
||||
GdkGLContext *current;
|
||||
GdkGLXPixmap *glx_pixmap;
|
||||
double device_x_offset, device_y_offset;
|
||||
cairo_rectangle_int_t rect;
|
||||
@ -353,7 +380,10 @@ gdk_x11_gl_context_texture_from_surface (GdkGLContext *context,
|
||||
int window_height;
|
||||
int window_scale;
|
||||
unsigned int texture_id;
|
||||
gboolean use_texture_rectangle;
|
||||
guint target;
|
||||
double sx, sy;
|
||||
float uscale, vscale;
|
||||
|
||||
if (cairo_surface_get_type (surface) != CAIRO_SURFACE_TYPE_XLIB)
|
||||
return FALSE;
|
||||
@ -362,7 +392,11 @@ gdk_x11_gl_context_texture_from_surface (GdkGLContext *context,
|
||||
if (glx_pixmap == NULL)
|
||||
return FALSE;
|
||||
|
||||
window = gdk_gl_context_get_window (gdk_gl_context_get_current ())->impl_window;
|
||||
current = gdk_gl_context_get_current ();
|
||||
|
||||
use_texture_rectangle = gdk_gl_context_use_texture_rectangle (current);
|
||||
|
||||
window = gdk_gl_context_get_window (current)->impl_window;
|
||||
window_scale = gdk_window_get_scale_factor (window);
|
||||
window_height = gdk_window_get_height (window);
|
||||
|
||||
@ -377,9 +411,19 @@ gdk_x11_gl_context_texture_from_surface (GdkGLContext *context,
|
||||
/* Ensure all the X stuff are synced before we read it back via texture-from-pixmap */
|
||||
glXWaitX();
|
||||
|
||||
if (use_texture_rectangle)
|
||||
target = GL_TEXTURE_RECTANGLE_ARB;
|
||||
else
|
||||
target = GL_TEXTURE_2D;
|
||||
|
||||
glGenTextures (1, &texture_id);
|
||||
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture_id);
|
||||
glEnable (GL_TEXTURE_RECTANGLE_ARB);
|
||||
glBindTexture (target, texture_id);
|
||||
glEnable (target);
|
||||
|
||||
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_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
|
||||
glXBindTexImageEXT (glx_pixmap->display, glx_pixmap->drawable,
|
||||
GLX_FRONT_LEFT_EXT, NULL);
|
||||
@ -401,17 +445,28 @@ gdk_x11_gl_context_texture_from_surface (GdkGLContext *context,
|
||||
|
||||
#define FLIP_Y(_y) (window_height - (_y))
|
||||
|
||||
if (use_texture_rectangle)
|
||||
{
|
||||
uscale = 1.0;
|
||||
vscale = 1.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
uscale = 1.0 / cairo_xlib_surface_get_width (surface);
|
||||
vscale = 1.0 / cairo_xlib_surface_get_height (surface);
|
||||
}
|
||||
|
||||
glBegin (GL_QUADS);
|
||||
glTexCoord2f (src_x, src_y + src_height);
|
||||
glTexCoord2f (uscale * src_x, vscale * (src_y + src_height));
|
||||
glVertex2f (rect.x * window_scale, FLIP_Y(rect.y + rect.height) * window_scale);
|
||||
|
||||
glTexCoord2f (src_x + src_width, src_y + src_height);
|
||||
glTexCoord2f (uscale * (src_x + src_width), vscale * (src_y + src_height));
|
||||
glVertex2f ((rect.x + rect.width) * window_scale, FLIP_Y(rect.y + rect.height) * window_scale);
|
||||
|
||||
glTexCoord2f (src_x + src_width, src_y);
|
||||
glTexCoord2f (uscale * (src_x + src_width), vscale * src_y);
|
||||
glVertex2f ((rect.x + rect.width) * window_scale, FLIP_Y(rect.y) * window_scale);
|
||||
|
||||
glTexCoord2f (src_x, src_y);
|
||||
glTexCoord2f (uscale * src_x, vscale * src_y);
|
||||
glVertex2f (rect.x * window_scale, FLIP_Y(rect.y) * window_scale);
|
||||
glEnd();
|
||||
}
|
||||
@ -419,7 +474,7 @@ gdk_x11_gl_context_texture_from_surface (GdkGLContext *context,
|
||||
glXReleaseTexImageEXT (glx_pixmap->display, glx_pixmap->drawable,
|
||||
GLX_FRONT_LEFT_EXT);
|
||||
|
||||
glDisable (GL_TEXTURE_RECTANGLE_ARB);
|
||||
glDisable (target);
|
||||
glDeleteTextures (1, &texture_id);
|
||||
|
||||
glx_pixmap_destroy(glx_pixmap);
|
||||
|
Loading…
Reference in New Issue
Block a user