[gtk+] gdkgl: Texture many quads at once for performance reasons
- From: Jasper St. Pierre <jstpierre src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+] gdkgl: Texture many quads at once for performance reasons
- Date: Sat, 22 Nov 2014 18:39:55 +0000 (UTC)
commit 37ad6e11477060c74c2818210583b6fa37b1b027
Author: Jasper St. Pierre <jstpierre mecheye net>
Date: Sat Nov 22 09:47:35 2014 -0800
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.
gdk/gdkgl.c | 83 +++++++++++++++++++++++++++++---------------
gdk/gdkinternals.h | 7 ++--
gdk/x11/gdkglcontext-x11.c | 22 ++++++++---
3 files changed, 75 insertions(+), 37 deletions(-)
---
diff --git a/gdk/gdkgl.c b/gdk/gdkgl.c
index d61c87d..78be223 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);
diff --git a/gdk/gdkinternals.h b/gdk/gdkinternals.h
index d945a19..67a58da 100644
--- a/gdk/gdkinternals.h
+++ b/gdk/gdkinternals.h
@@ -356,9 +356,10 @@ typedef struct {
float u1, v1, u2, v2;
} GdkTexturedQuad;
-void gdk_gl_texture_quad (GdkGLContext *paint_context,
- guint texture_target,
- GdkTexturedQuad *quad);
+void gdk_gl_texture_quads (GdkGLContext *paint_context,
+ guint texture_target,
+ int n_quads,
+ GdkTexturedQuad *quads);
void gdk_cairo_surface_mark_as_direct (cairo_surface_t *surface,
GdkWindow *window);
diff --git a/gdk/x11/gdkglcontext-x11.c b/gdk/x11/gdkglcontext-x11.c
index 171ad05..566473a 100644
--- a/gdk/x11/gdkglcontext-x11.c
+++ b/gdk/x11/gdkglcontext-x11.c
@@ -431,6 +431,7 @@ gdk_x11_gl_context_texture_from_surface (GdkGLContext *paint_context,
guint target;
double sx, sy;
float uscale, vscale;
+ GdkTexturedQuad *quads;
if (cairo_surface_get_type (surface) != CAIRO_SURFACE_TYPE_XLIB)
return FALSE;
@@ -473,22 +474,25 @@ gdk_x11_gl_context_texture_from_surface (GdkGLContext *paint_context,
glEnable (GL_SCISSOR_TEST);
n_rects = cairo_region_num_rectangles (region);
+ quads = g_new (GdkTexturedQuad, n_rects);
+
+#define FLIP_Y(_y) (window_height - (_y))
+
+ cairo_region_get_extents (region, &rect);
+ glScissor (rect.x * window_scale, FLIP_Y(rect.y) * window_scale,
+ (rect.x + rect.width) * window_scale, FLIP_Y (rect.y + rect.height) * window_scale);
+
for (i = 0; i < n_rects; i++)
{
int src_x, src_y, src_height, src_width;
cairo_region_get_rectangle (region, i, &rect);
- glScissor (rect.x * window_scale, (window_height - rect.y - rect.height) * window_scale,
- rect.width * window_scale, rect.height * window_scale);
-
src_x = rect.x * sx + device_x_offset;
src_y = rect.y * sy + device_y_offset;
src_width = rect.width * sx;
src_height = rect.height * sy;
-#define FLIP_Y(_y) (window_height - (_y))
-
if (use_texture_rectangle)
{
uscale = 1.0;
@@ -507,12 +511,18 @@ gdk_x11_gl_context_texture_from_surface (GdkGLContext *paint_context,
uscale * src_x, vscale * src_y,
uscale * (src_x + src_width), vscale * (src_y + src_height),
};
- gdk_gl_texture_quad (paint_context, target, &quad);
+
+ quads[i] = quad;
}
}
+#undef FLIP_Y
+
glDisable (GL_SCISSOR_TEST);
+ gdk_gl_texture_quads (paint_context, target, n_rects, quads);
+ g_free (quads);
+
glXReleaseTexImageEXT (glx_pixmap->display, glx_pixmap->drawable,
GLX_FRONT_LEFT_EXT);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]