diff options
author | Alexander Larsson <alexl@redhat.com> | 2014-11-06 11:31:01 +0100 |
---|---|---|
committer | Alexander Larsson <alexl@redhat.com> | 2014-11-06 12:24:43 +0100 |
commit | 5f9e6ec2dc2e5ae4442d5cdb64684cd4a51d20d4 (patch) | |
tree | e562034855cdee512e00b8fa1f4b00eb24e37d24 /gdk | |
parent | 650c9f3b7eaade447aa341d7c8dd7d9a9aa10188 (diff) | |
download | gtk+-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.c | 80 | ||||
-rw-r--r-- | gdk/gdkglcontextprivate.h | 5 | ||||
-rw-r--r-- | gdk/gdkinternals.h | 1 | ||||
-rw-r--r-- | gdk/x11/gdkglcontext-x11.c | 47 |
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, |