forked from AuroraMiddleware/gtk
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.
This commit is contained in:
parent
7312c01f62
commit
37ad6e1147
85
gdk/gdkgl.c
85
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);
|
||||
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_vertex_buffer);
|
||||
glVertexAttribPointer (program->position_location, 2, GL_FLOAT, GL_FALSE, 0, NULL);
|
||||
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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user