summaryrefslogtreecommitdiff
path: root/gdk/gdkgl.c
diff options
context:
space:
mode:
authorJasper St. Pierre <jstpierre@mecheye.net>2014-11-22 09:47:35 -0800
committerJasper St. Pierre <jstpierre@mecheye.net>2014-11-22 10:13:58 -0800
commit37ad6e11477060c74c2818210583b6fa37b1b027 (patch)
treec2312fc677fbb1697abb5d56c388ce8c299b4b00 /gdk/gdkgl.c
parent7312c01f62b701d01ed29fca33e9a05041bf5b2a (diff)
downloadgtk+-37ad6e11477060c74c2818210583b6fa37b1b027.tar.gz
gdkgl: Texture many quads at once for performance reasons
This isn't fully performant yet. To be fully performant, we'd need to do everything in one giant buffer.
Diffstat (limited to 'gdk/gdkgl.c')
-rw-r--r--gdk/gdkgl.c83
1 files changed, 55 insertions, 28 deletions
diff --git a/gdk/gdkgl.c b/gdk/gdkgl.c
index d61c87ddf4..78be22354d 100644
--- a/gdk/gdkgl.c
+++ b/gdk/gdkgl.c
@@ -205,9 +205,10 @@ use_texture_rect_program (GdkGLContextPaintData *paint_data)
}
void
-gdk_gl_texture_quad (GdkGLContext *paint_context,
- guint texture_target,
- GdkTexturedQuad *quad)
+gdk_gl_texture_quads (GdkGLContext *paint_context,
+ guint texture_target,
+ int n_quads,
+ GdkTexturedQuad *quads)
{
GdkGLContextPaintData *paint_data = gdk_gl_context_get_paint_data (paint_context);
GdkGLContextProgram *program;
@@ -215,18 +216,7 @@ gdk_gl_texture_quad (GdkGLContext *paint_context,
int window_scale = gdk_window_get_scale_factor (window);
float w = gdk_window_get_width (window) * window_scale;
float h = gdk_window_get_height (window) * window_scale;
- float vertex_buffer_data[] = {
- (quad->x2 * 2) / w - 1, (quad->y1 * 2) / h - 1,
- (quad->x2 * 2) / w - 1, (quad->y2 * 2) / h - 1,
- (quad->x1 * 2) / w - 1, (quad->y2 * 2) / h - 1,
- (quad->x1 * 2) / w - 1, (quad->y1 * 2) / h - 1,
- };
- float uv_buffer_data[] = {
- quad->u2, quad->v1,
- quad->u2, quad->v2,
- quad->u1, quad->v2,
- quad->u1, quad->v1,
- };
+ int i;
bind_vao (paint_data);
@@ -247,14 +237,37 @@ gdk_gl_texture_quad (GdkGLContext *paint_context,
glUniform1i(program->map_location, 0); /* Use texture unit 0 */
glEnableVertexAttribArray (0);
+ glEnableVertexAttribArray (1);
glBindBuffer (GL_ARRAY_BUFFER, paint_data->tmp_vertex_buffer);
- glBufferData (GL_ARRAY_BUFFER, sizeof(vertex_buffer_data), vertex_buffer_data, GL_STREAM_DRAW);
glVertexAttribPointer (program->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 (program->uv_location, 2, GL_FLOAT, GL_FALSE, 0, NULL);
- glDrawArrays (GL_TRIANGLE_FAN, 0, 4);
+
+ for (i = 0; i < n_quads; i++)
+ {
+ GdkTexturedQuad *quad = &quads[i];
+ float vertex_buffer_data[] = {
+ (quad->x2 * 2) / w - 1, (quad->y1 * 2) / h - 1,
+ (quad->x2 * 2) / w - 1, (quad->y2 * 2) / h - 1,
+ (quad->x1 * 2) / w - 1, (quad->y2 * 2) / h - 1,
+ (quad->x1 * 2) / w - 1, (quad->y1 * 2) / h - 1,
+ };
+ float uv_buffer_data[] = {
+ quad->u2, quad->v1,
+ quad->u2, quad->v2,
+ quad->u1, quad->v2,
+ quad->u1, quad->v1,
+ };
+
+ glBindBuffer (GL_ARRAY_BUFFER, paint_data->tmp_vertex_buffer);
+ glBufferData (GL_ARRAY_BUFFER, sizeof(vertex_buffer_data), vertex_buffer_data, GL_STREAM_DRAW);
+
+ glBindBuffer (GL_ARRAY_BUFFER, paint_data->tmp_uv_buffer);
+ glBufferData (GL_ARRAY_BUFFER, sizeof(uv_buffer_data), uv_buffer_data, GL_STREAM_DRAW);
+
+ glDrawArrays (GL_TRIANGLE_FAN, 0, 4);
+ }
+
glDisableVertexAttribArray (0);
glDisableVertexAttribArray (1);
}
@@ -460,7 +473,9 @@ gdk_cairo_draw_from_gl (cairo_t *cr,
int unscaled_window_height;
GLint texture_width;
GLint texture_height;
- int i;
+ int i, n_rects;
+ GdkTexturedQuad *quads;
+ cairo_rectangle_int_t clip_rect;
/* Translate to impl coords */
cairo_region_translate (clip_region, dx, dy);
@@ -506,9 +521,16 @@ gdk_cairo_draw_from_gl (cairo_t *cr,
#define FLIP_Y(_y) (unscaled_window_height - (_y))
- for (i = 0; i < cairo_region_num_rectangles (clip_region); i++)
+ cairo_region_get_extents (clip_region, &clip_rect);
+
+ glScissor (clip_rect.x, FLIP_Y (clip_rect.y + clip_rect.height),
+ clip_rect.width, clip_rect.height);
+
+ n_rects = cairo_region_num_rectangles (clip_region);
+ quads = g_new (GdkTexturedQuad, n_rects);
+ for (i = 0; i < n_rects; i++)
{
- cairo_rectangle_int_t clip_rect, dest;
+ cairo_rectangle_int_t dest;
cairo_region_get_rectangle (clip_region, i, &clip_rect);
@@ -517,9 +539,6 @@ gdk_cairo_draw_from_gl (cairo_t *cr,
clip_rect.width *= window_scale;
clip_rect.height *= window_scale;
- glScissor (clip_rect.x, FLIP_Y (clip_rect.y + clip_rect.height),
- clip_rect.width, clip_rect.height);
-
dest.x = dx * window_scale;
dest.y = dy * window_scale;
dest.width = width * window_scale / buffer_scale;
@@ -536,7 +555,7 @@ gdk_cairo_draw_from_gl (cairo_t *cr,
(clipped_src_x + dest.width) / (float)texture_width, clipped_src_y / (float)texture_height,
};
- gdk_gl_texture_quad (paint_context, GL_TEXTURE_2D, &quad);
+ quads[i] = quad;
if (impl_window->current_paint.flushed_region)
{
@@ -555,11 +574,13 @@ gdk_cairo_draw_from_gl (cairo_t *cr,
}
}
+ gdk_gl_texture_quads (paint_context, GL_TEXTURE_2D, n_rects, quads);
+ g_free (quads);
+
if (alpha_size != 0)
glDisable (GL_BLEND);
glDisable (GL_TEXTURE_2D);
- glDisable (GL_SCISSOR_TEST);
#undef FLIP_Y
@@ -636,6 +657,7 @@ gdk_gl_texture_from_surface (cairo_surface_t *surface,
float umax, vmax;
gboolean use_texture_rectangle;
guint target;
+ GdkTexturedQuad *quads;
paint_context = gdk_gl_context_get_current ();
if ((_gdk_gl_flags & GDK_GL_SOFTWARE_DRAW_SURFACE) == 0 &&
@@ -673,6 +695,8 @@ gdk_gl_texture_from_surface (cairo_surface_t *surface,
glTexParameteri (target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
n_rects = cairo_region_num_rectangles (region);
+ quads = g_new (GdkTexturedQuad, n_rects);
+
for (i = 0; i < n_rects; i++)
{
cairo_region_get_rectangle (region, i, &rect);
@@ -718,10 +742,13 @@ gdk_gl_texture_from_surface (cairo_surface_t *surface,
umax, vmax,
};
- gdk_gl_texture_quad (paint_context, target, &quad);
+ quads[i] = quad;
}
}
+ gdk_gl_texture_quads (paint_context, target, n_rects, quads);
+ g_free (quads);
+
glDisable (GL_SCISSOR_TEST);
glDisable (target);
glDeleteTextures (1, &texture_id);