summaryrefslogtreecommitdiff
path: root/gdk
diff options
context:
space:
mode:
authorAlexander Larsson <alexl@redhat.com>2014-11-06 11:31:01 +0100
committerAlexander Larsson <alexl@redhat.com>2014-11-06 12:24:43 +0100
commit5f9e6ec2dc2e5ae4442d5cdb64684cd4a51d20d4 (patch)
treee562034855cdee512e00b8fa1f4b00eb24e37d24 /gdk
parent650c9f3b7eaade447aa341d7c8dd7d9a9aa10188 (diff)
downloadgtk+-5f9e6ec2dc2e5ae4442d5cdb64684cd4a51d20d4.tar.gz
GdkGL: Fix up GL_ARB_texture_rectangle support
This broke when gdk_gl_texture_quad moved to shaders. We need a specialized shader for the rectangle case.
Diffstat (limited to 'gdk')
-rw-r--r--gdk/gdkgl.c80
-rw-r--r--gdk/gdkglcontextprivate.h5
-rw-r--r--gdk/gdkinternals.h1
-rw-r--r--gdk/x11/gdkglcontext-x11.c47
4 files changed, 103 insertions, 30 deletions
diff --git a/gdk/gdkgl.c b/gdk/gdkgl.c
index 44d205edf0..6d0e8f41f4 100644
--- a/gdk/gdkgl.c
+++ b/gdk/gdkgl.c
@@ -140,7 +140,10 @@ bind_vao (GdkGLContextPaintData *paint_data)
}
static void
-use_texture_program (GdkGLContextPaintData *paint_data)
+use_texture_2d_program (GdkGLContextPaintData *paint_data,
+ guint *position_location,
+ guint *uv_location,
+ guint *map_location)
{
const char *vertex_shader_code =
"#version 120\n"
@@ -165,6 +168,7 @@ use_texture_program (GdkGLContextPaintData *paint_data)
paint_data->texture_quad_program = make_program (vertex_shader_code, fragment_shader_code);
paint_data->texture_quad_program_position_location = glGetAttribLocation (paint_data->texture_quad_program, "position");
paint_data->texture_quad_program_uv_location = glGetAttribLocation (paint_data->texture_quad_program, "uv");
+ paint_data->texture_quad_program_map_location = glGetUniformLocation (paint_data->texture_quad_program, "map");
}
if (paint_data->current_program != paint_data->texture_quad_program)
@@ -172,10 +176,59 @@ use_texture_program (GdkGLContextPaintData *paint_data)
glUseProgram (paint_data->texture_quad_program);
paint_data->current_program = paint_data->texture_quad_program;
}
+
+ *position_location = paint_data->texture_quad_program_position_location;
+ *uv_location = paint_data->texture_quad_program_uv_location;
+ *map_location = paint_data->texture_quad_program_map_location;
}
+static void
+use_texture_rect_program (GdkGLContextPaintData *paint_data,
+ guint *position_location,
+ guint *uv_location,
+ guint *map_location)
+{
+ const char *vertex_shader_code =
+ "#version 120\n"
+ "uniform sampler2DRect map;"
+ "attribute vec2 position;\n"
+ "attribute vec2 uv;\n"
+ "varying vec2 vUv;\n"
+ "void main() {\n"
+ " gl_Position = vec4(position, 0, 1);\n"
+ " vUv = uv;\n"
+ "}\n";
+ const char *fragment_shader_code =
+ "#version 120\n"
+ "varying vec2 vUv;\n"
+ "uniform sampler2DRect map;\n"
+ "void main() {\n"
+ " gl_FragColor = texture2DRect (map, vUv);\n"
+ "}\n";
+
+ if (paint_data->texture_quad_rect_program == 0)
+ {
+ paint_data->texture_quad_rect_program = make_program (vertex_shader_code, fragment_shader_code);
+ paint_data->texture_quad_rect_program_position_location = glGetAttribLocation (paint_data->texture_quad_rect_program, "position");
+ paint_data->texture_quad_rect_program_uv_location = glGetAttribLocation (paint_data->texture_quad_rect_program, "uv");
+ paint_data->texture_quad_rect_program_map_location = glGetUniformLocation (paint_data->texture_quad_rect_program, "map");
+ }
+
+ if (paint_data->current_program != paint_data->texture_quad_rect_program)
+ {
+ glUseProgram (paint_data->texture_quad_rect_program);
+ paint_data->current_program = paint_data->texture_quad_rect_program;
+ }
+
+ *position_location = paint_data->texture_quad_rect_program_position_location;
+ *uv_location = paint_data->texture_quad_rect_program_uv_location;
+ *map_location = paint_data->texture_quad_rect_program_map_location;
+}
+
+
void
gdk_gl_texture_quad (GdkGLContext *paint_context,
+ guint texture_target,
float x1, float y1,
float x2, float y2,
float u1, float v1,
@@ -197,6 +250,7 @@ gdk_gl_texture_quad (GdkGLContext *paint_context,
u1, v2,
u1, v1,
};
+ guint position_location, uv_location, map_location;
bind_vao (paint_data);
@@ -206,19 +260,22 @@ gdk_gl_texture_quad (GdkGLContext *paint_context,
if (paint_data->tmp_uv_buffer == 0)
glGenBuffers(1, &paint_data->tmp_uv_buffer);
- use_texture_program (paint_data);
+ if (texture_target == GL_TEXTURE_RECTANGLE_ARB)
+ use_texture_rect_program (paint_data, &position_location, &uv_location, &map_location);
+ else
+ use_texture_2d_program (paint_data, &position_location, &uv_location, &map_location);
glActiveTexture (GL_TEXTURE0);
+ glUniform1i(map_location, 0); /* Use texture unit 0 */
+
glEnableVertexAttribArray (0);
glBindBuffer (GL_ARRAY_BUFFER, paint_data->tmp_vertex_buffer);
glBufferData (GL_ARRAY_BUFFER, sizeof(vertex_buffer_data), vertex_buffer_data, GL_STREAM_DRAW);
- glVertexAttribPointer (paint_data->texture_quad_program_position_location,
- 2, GL_FLOAT, GL_FALSE, 0, NULL);
+ glVertexAttribPointer (position_location, 2, GL_FLOAT, GL_FALSE, 0, NULL);
glEnableVertexAttribArray (1);
glBindBuffer (GL_ARRAY_BUFFER, paint_data->tmp_uv_buffer);
glBufferData (GL_ARRAY_BUFFER, sizeof(uv_buffer_data), uv_buffer_data, GL_STREAM_DRAW);
- glVertexAttribPointer (paint_data->texture_quad_program_uv_location,
- 2, GL_FLOAT, GL_FALSE, 0, NULL);
+ glVertexAttribPointer (uv_location, 2, GL_FLOAT, GL_FALSE, 0, NULL);
glDrawArrays (GL_TRIANGLE_FAN, 0, 4);
glDisableVertexAttribArray (0);
glDisableVertexAttribArray (1);
@@ -497,6 +554,7 @@ gdk_cairo_draw_from_gl (cairo_t *cr,
int clipped_src_y = y + (height - dest.height - (dest.y - dy * window_scale));
gdk_gl_texture_quad (paint_context,
+ GL_TEXTURE_2D,
dest.x, FLIP_Y(dest.y),
dest.x + dest.width, FLIP_Y(dest.y + dest.height),
clipped_src_x / (float)texture_width, (clipped_src_y + dest.height) / (float)texture_height,
@@ -634,10 +692,10 @@ gdk_gl_texture_from_surface (cairo_surface_t *surface,
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);
+ glTexParameteri (target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri (target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glTexParameteri (target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri (target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
n_rects = cairo_region_num_rectangles (region);
for (i = 0; i < n_rects; i++)
@@ -677,7 +735,7 @@ gdk_gl_texture_from_surface (cairo_surface_t *surface,
vmax = 1.0;
}
- gdk_gl_texture_quad (paint_context,
+ gdk_gl_texture_quad (paint_context, target,
rect.x * window_scale, FLIP_Y(rect.y) * window_scale,
(rect.x + rect.width) * window_scale, FLIP_Y(rect.y + rect.height) * window_scale,
0, 0,
diff --git a/gdk/gdkglcontextprivate.h b/gdk/gdkglcontextprivate.h
index c738fa51ce..ec4ab334a0 100644
--- a/gdk/gdkglcontextprivate.h
+++ b/gdk/gdkglcontextprivate.h
@@ -65,6 +65,11 @@ typedef struct {
guint texture_quad_program;
guint texture_quad_program_position_location;
guint texture_quad_program_uv_location;
+ guint texture_quad_program_map_location;
+ guint texture_quad_rect_program;
+ guint texture_quad_rect_program_position_location;
+ guint texture_quad_rect_program_uv_location;
+ guint texture_quad_rect_program_map_location;
} GdkGLContextPaintData;
GdkGLContextPaintData *gdk_gl_context_get_paint_data (GdkGLContext *context);
diff --git a/gdk/gdkinternals.h b/gdk/gdkinternals.h
index 14141bde4c..6543f55b41 100644
--- a/gdk/gdkinternals.h
+++ b/gdk/gdkinternals.h
@@ -351,6 +351,7 @@ gboolean _gdk_cairo_surface_extents (cairo_surface_t *surface,
void gdk_gl_texture_from_surface (cairo_surface_t *surface,
cairo_region_t *region);
void gdk_gl_texture_quad (GdkGLContext *paint_context,
+ guint texture_target,
float x1, float y1,
float x2, float y2,
float u1, float v1,
diff --git a/gdk/x11/gdkglcontext-x11.c b/gdk/x11/gdkglcontext-x11.c
index a0258b9feb..fe1b18ad3c 100644
--- a/gdk/x11/gdkglcontext-x11.c
+++ b/gdk/x11/gdkglcontext-x11.c
@@ -280,7 +280,7 @@ glx_pixmap_destroy (void *data)
}
static GdkGLXPixmap *
-glx_pixmap_get (cairo_surface_t *surface)
+glx_pixmap_get (cairo_surface_t *surface, guint texture_target)
{
Display *display = cairo_xlib_surface_get_display (surface);
Screen *screen = cairo_xlib_surface_get_screen (surface);
@@ -324,12 +324,22 @@ glx_pixmap_get (cairo_surface_t *surface)
glXGetFBConfigAttrib (display, fbconfigs[i],
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;
+ if (texture_target == GL_TEXTURE_2D)
+ {
+ if (value & GLX_TEXTURE_2D_BIT_EXT)
+ target = GLX_TEXTURE_2D_EXT;
+ else
+ continue;
+ }
+ else if (texture_target == GL_TEXTURE_RECTANGLE_ARB)
+ {
+ if (value & GLX_TEXTURE_RECTANGLE_BIT_EXT)
+ target = GLX_TEXTURE_RECTANGLE_EXT;
+ else
+ continue;
+ }
else
- target = GLX_TEXTURE_RECTANGLE_EXT;
+ continue;
if (!with_alpha)
{
@@ -400,12 +410,16 @@ gdk_x11_gl_context_texture_from_surface (GdkGLContext *paint_context,
if (cairo_surface_get_type (surface) != CAIRO_SURFACE_TYPE_XLIB)
return FALSE;
- glx_pixmap = glx_pixmap_get (surface);
+ use_texture_rectangle = gdk_gl_context_use_texture_rectangle (paint_context);
+ if (use_texture_rectangle)
+ target = GL_TEXTURE_RECTANGLE_ARB;
+ else
+ target = GL_TEXTURE_2D;
+
+ glx_pixmap = glx_pixmap_get (surface, target);
if (glx_pixmap == NULL)
return FALSE;
- use_texture_rectangle = gdk_gl_context_use_texture_rectangle (paint_context);
-
window = gdk_gl_context_get_window (paint_context)->impl_window;
window_scale = gdk_window_get_scale_factor (window);
window_height = gdk_window_get_height (window);
@@ -421,19 +435,14 @@ gdk_x11_gl_context_texture_from_surface (GdkGLContext *paint_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 (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);
+ glTexParameteri (target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri (target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glTexParameteri (target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri (target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glXBindTexImageEXT (glx_pixmap->display, glx_pixmap->drawable,
GLX_FRONT_LEFT_EXT, NULL);
@@ -466,7 +475,7 @@ gdk_x11_gl_context_texture_from_surface (GdkGLContext *paint_context,
vscale = 1.0 / cairo_xlib_surface_get_height (surface);
}
- gdk_gl_texture_quad (paint_context,
+ gdk_gl_texture_quad (paint_context, target,
rect.x * window_scale, FLIP_Y(rect.y) * window_scale,
(rect.x + rect.width) * window_scale, FLIP_Y(rect.y + rect.height) * window_scale,
uscale * src_x, vscale * src_y,