mirror of
https://github.com/brl/mutter.git
synced 2025-04-12 21:29:38 +00:00
cogl-pango-display-list: Use CoglPrimitive instead of CoglVertexBuffer
When rendering text through a VBO, CoglPangoDisplayList now uses the CoglPrimitive API instead of CoglVertexBuffer. CoglVertexBuffer is just a layer on top of the attribute buffer API anyway so it should be slightly faster. https://bugzilla.gnome.org/show_bug.cgi?id=656303 Reviewed-by: Robert Bragg <robert@linux.intel.com>
This commit is contained in:
parent
9270412495
commit
7c8c0f1023
@ -40,7 +40,6 @@ typedef enum
|
|||||||
} CoglPangoDisplayListNodeType;
|
} CoglPangoDisplayListNodeType;
|
||||||
|
|
||||||
typedef struct _CoglPangoDisplayListNode CoglPangoDisplayListNode;
|
typedef struct _CoglPangoDisplayListNode CoglPangoDisplayListNode;
|
||||||
typedef struct _CoglPangoDisplayListVertex CoglPangoDisplayListVertex;
|
|
||||||
|
|
||||||
struct _CoglPangoDisplayList
|
struct _CoglPangoDisplayList
|
||||||
{
|
{
|
||||||
@ -68,8 +67,8 @@ struct _CoglPangoDisplayListNode
|
|||||||
CoglHandle texture;
|
CoglHandle texture;
|
||||||
/* Array of vertex data to render out of this texture */
|
/* Array of vertex data to render out of this texture */
|
||||||
GArray *verts;
|
GArray *verts;
|
||||||
/* A VBO representing those vertices */
|
/* A primitive representing those vertices */
|
||||||
CoglHandle vertex_buffer;
|
CoglPrimitive *primitive;
|
||||||
} texture;
|
} texture;
|
||||||
|
|
||||||
struct
|
struct
|
||||||
@ -90,11 +89,6 @@ struct _CoglPangoDisplayListNode
|
|||||||
} d;
|
} d;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _CoglPangoDisplayListVertex
|
|
||||||
{
|
|
||||||
float x, y, t_x, t_y;
|
|
||||||
};
|
|
||||||
|
|
||||||
CoglPangoDisplayList *
|
CoglPangoDisplayList *
|
||||||
_cogl_pango_display_list_new (CoglPangoPipelineCache *pipeline_cache)
|
_cogl_pango_display_list_new (CoglPangoPipelineCache *pipeline_cache)
|
||||||
{
|
{
|
||||||
@ -138,7 +132,7 @@ _cogl_pango_display_list_add_texture (CoglPangoDisplayList *dl,
|
|||||||
float tx_2, float ty_2)
|
float tx_2, float ty_2)
|
||||||
{
|
{
|
||||||
CoglPangoDisplayListNode *node;
|
CoglPangoDisplayListNode *node;
|
||||||
CoglPangoDisplayListVertex *verts;
|
CoglVertexP2T2 *verts;
|
||||||
|
|
||||||
/* Add to the last node if it is a texture node with the same
|
/* Add to the last node if it is a texture node with the same
|
||||||
target texture */
|
target texture */
|
||||||
@ -150,10 +144,10 @@ _cogl_pango_display_list_add_texture (CoglPangoDisplayList *dl,
|
|||||||
: !node->color_override))
|
: !node->color_override))
|
||||||
{
|
{
|
||||||
/* Get rid of the vertex buffer so that it will be recreated */
|
/* Get rid of the vertex buffer so that it will be recreated */
|
||||||
if (node->d.texture.vertex_buffer != COGL_INVALID_HANDLE)
|
if (node->d.texture.primitive != NULL)
|
||||||
{
|
{
|
||||||
cogl_handle_unref (node->d.texture.vertex_buffer);
|
cogl_object_unref (node->d.texture.primitive);
|
||||||
node->d.texture.vertex_buffer = COGL_INVALID_HANDLE;
|
node->d.texture.primitive = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -167,8 +161,8 @@ _cogl_pango_display_list_add_texture (CoglPangoDisplayList *dl,
|
|||||||
node->pipeline = NULL;
|
node->pipeline = NULL;
|
||||||
node->d.texture.texture = cogl_handle_ref (texture);
|
node->d.texture.texture = cogl_handle_ref (texture);
|
||||||
node->d.texture.verts
|
node->d.texture.verts
|
||||||
= g_array_new (FALSE, FALSE, sizeof (CoglPangoDisplayListVertex));
|
= g_array_new (FALSE, FALSE, sizeof (CoglVertexP2T2));
|
||||||
node->d.texture.vertex_buffer = COGL_INVALID_HANDLE;
|
node->d.texture.primitive = NULL;
|
||||||
|
|
||||||
_cogl_pango_display_list_append_node (dl, node);
|
_cogl_pango_display_list_append_node (dl, node);
|
||||||
}
|
}
|
||||||
@ -176,28 +170,28 @@ _cogl_pango_display_list_add_texture (CoglPangoDisplayList *dl,
|
|||||||
g_array_set_size (node->d.texture.verts,
|
g_array_set_size (node->d.texture.verts,
|
||||||
node->d.texture.verts->len + 4);
|
node->d.texture.verts->len + 4);
|
||||||
verts = &g_array_index (node->d.texture.verts,
|
verts = &g_array_index (node->d.texture.verts,
|
||||||
CoglPangoDisplayListVertex,
|
CoglVertexP2T2,
|
||||||
node->d.texture.verts->len - 4);
|
node->d.texture.verts->len - 4);
|
||||||
|
|
||||||
verts->x = x_1;
|
verts->x = x_1;
|
||||||
verts->y = y_1;
|
verts->y = y_1;
|
||||||
verts->t_x = tx_1;
|
verts->s = tx_1;
|
||||||
verts->t_y = ty_1;
|
verts->t = ty_1;
|
||||||
verts++;
|
verts++;
|
||||||
verts->x = x_1;
|
verts->x = x_1;
|
||||||
verts->y = y_2;
|
verts->y = y_2;
|
||||||
verts->t_x = tx_1;
|
verts->s = tx_1;
|
||||||
verts->t_y = ty_2;
|
verts->t = ty_2;
|
||||||
verts++;
|
verts++;
|
||||||
verts->x = x_2;
|
verts->x = x_2;
|
||||||
verts->y = y_2;
|
verts->y = y_2;
|
||||||
verts->t_x = tx_2;
|
verts->s = tx_2;
|
||||||
verts->t_y = ty_2;
|
verts->t = ty_2;
|
||||||
verts++;
|
verts++;
|
||||||
verts->x = x_2;
|
verts->x = x_2;
|
||||||
verts->y = y_1;
|
verts->y = y_1;
|
||||||
verts->t_x = tx_2;
|
verts->s = tx_2;
|
||||||
verts->t_y = ty_1;
|
verts->t = ty_1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -251,15 +245,15 @@ emit_rectangles_through_journal (CoglPangoDisplayListNode *node)
|
|||||||
|
|
||||||
for (i = 0; i < node->d.texture.verts->len; i += 4)
|
for (i = 0; i < node->d.texture.verts->len; i += 4)
|
||||||
{
|
{
|
||||||
CoglPangoDisplayListVertex *v0 =
|
CoglVertexP2T2 *v0 =
|
||||||
&g_array_index (node->d.texture.verts,
|
&g_array_index (node->d.texture.verts,
|
||||||
CoglPangoDisplayListVertex, i);
|
CoglVertexP2T2, i);
|
||||||
CoglPangoDisplayListVertex *v1 =
|
CoglVertexP2T2 *v1 =
|
||||||
&g_array_index (node->d.texture.verts,
|
&g_array_index (node->d.texture.verts,
|
||||||
CoglPangoDisplayListVertex, i + 2);
|
CoglVertexP2T2, i + 2);
|
||||||
cogl_rectangle_with_texture_coords (v0->x, v0->y, v1->x, v1->y,
|
cogl_rectangle_with_texture_coords (v0->x, v0->y, v1->x, v1->y,
|
||||||
v0->t_x, v0->t_y,
|
v0->s, v0->t,
|
||||||
v1->t_x, v1->t_y);
|
v1->s, v1->t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -276,47 +270,60 @@ emit_vertex_buffer_geometry (CoglPangoDisplayListNode *node)
|
|||||||
* be re-used avoiding the repeated cost of validating the data and
|
* be re-used avoiding the repeated cost of validating the data and
|
||||||
* mapping it into the GPU... */
|
* mapping it into the GPU... */
|
||||||
|
|
||||||
if (node->d.texture.vertex_buffer == COGL_INVALID_HANDLE)
|
if (node->d.texture.primitive == NULL)
|
||||||
{
|
{
|
||||||
CoglHandle vb = cogl_vertex_buffer_new (node->d.texture.verts->len);
|
CoglAttributeBuffer *buffer;
|
||||||
|
CoglAttribute *attributes[2];
|
||||||
|
CoglPrimitive *prim;
|
||||||
|
|
||||||
cogl_vertex_buffer_add (vb, "gl_Vertex", 2,
|
buffer
|
||||||
COGL_ATTRIBUTE_TYPE_FLOAT, FALSE,
|
= cogl_attribute_buffer_new (node->d.texture.verts->len
|
||||||
sizeof (CoglPangoDisplayListVertex),
|
* sizeof (CoglVertexP2T2),
|
||||||
&g_array_index (node->d.texture.verts,
|
node->d.texture.verts->data);
|
||||||
CoglPangoDisplayListVertex, 0).x);
|
attributes[0] = cogl_attribute_new (buffer,
|
||||||
cogl_vertex_buffer_add (vb, "gl_MultiTexCoord0", 2,
|
"cogl_position_in",
|
||||||
COGL_ATTRIBUTE_TYPE_FLOAT, FALSE,
|
sizeof (CoglVertexP2T2),
|
||||||
sizeof (CoglPangoDisplayListVertex),
|
G_STRUCT_OFFSET (CoglVertexP2T2, x),
|
||||||
&g_array_index (node->d.texture.verts,
|
2, /* n_components */
|
||||||
CoglPangoDisplayListVertex,
|
COGL_ATTRIBUTE_TYPE_FLOAT);
|
||||||
0).t_x);
|
attributes[1] = cogl_attribute_new (buffer,
|
||||||
cogl_vertex_buffer_submit (vb);
|
"cogl_tex_coord0_in",
|
||||||
|
sizeof (CoglVertexP2T2),
|
||||||
|
G_STRUCT_OFFSET (CoglVertexP2T2, s),
|
||||||
|
2, /* n_components */
|
||||||
|
COGL_ATTRIBUTE_TYPE_FLOAT);
|
||||||
|
|
||||||
node->d.texture.vertex_buffer = vb;
|
prim = cogl_primitive_new_with_attributes (COGL_VERTICES_MODE_TRIANGLES,
|
||||||
}
|
node->d.texture.verts->len,
|
||||||
|
attributes,
|
||||||
|
2 /* n_attributes */);
|
||||||
|
|
||||||
#ifdef CLUTTER_COGL_HAS_GL
|
#ifdef CLUTTER_COGL_HAS_GL
|
||||||
if (ctx->driver == COGL_DRIVER_GL)
|
if (ctx->driver == COGL_DRIVER_GL)
|
||||||
cogl_vertex_buffer_draw (node->d.texture.vertex_buffer,
|
cogl_primitive_set_mode (prim, GL_QUADS);
|
||||||
GL_QUADS,
|
else
|
||||||
0, node->d.texture.verts->len);
|
|
||||||
else
|
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
/* GLES doesn't support GL_QUADS so instead we use a VBO with
|
/* GLES doesn't support GL_QUADS so instead we use a VBO
|
||||||
indexed vertices to generate GL_TRIANGLES from the quads */
|
with indexed vertices to generate GL_TRIANGLES from the
|
||||||
|
quads */
|
||||||
|
|
||||||
int n_indices = node->d.texture.verts->len / 4 * 6;
|
CoglIndices *indices =
|
||||||
CoglHandle indices_vbo
|
cogl_get_rectangle_indices (node->d.texture.verts->len / 4);
|
||||||
= cogl_vertex_buffer_indices_get_for_quads (n_indices);
|
|
||||||
|
|
||||||
cogl_vertex_buffer_draw_elements (node->d.texture.vertex_buffer,
|
cogl_primitive_set_indices (prim, indices);
|
||||||
COGL_VERTICES_MODE_TRIANGLES,
|
cogl_primitive_set_n_vertices (prim,
|
||||||
indices_vbo,
|
node->d.texture.verts->len / 4 * 6);
|
||||||
0, node->d.texture.verts->len - 1,
|
}
|
||||||
0, n_indices);
|
|
||||||
|
node->d.texture.primitive = prim;
|
||||||
|
|
||||||
|
cogl_object_unref (buffer);
|
||||||
|
cogl_object_unref (attributes[0]);
|
||||||
|
cogl_object_unref (attributes[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cogl_primitive_draw (node->d.texture.primitive);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -418,8 +425,8 @@ _cogl_pango_display_list_node_free (CoglPangoDisplayListNode *node)
|
|||||||
g_array_free (node->d.texture.verts, TRUE);
|
g_array_free (node->d.texture.verts, TRUE);
|
||||||
if (node->d.texture.texture != COGL_INVALID_HANDLE)
|
if (node->d.texture.texture != COGL_INVALID_HANDLE)
|
||||||
cogl_handle_unref (node->d.texture.texture);
|
cogl_handle_unref (node->d.texture.texture);
|
||||||
if (node->d.texture.vertex_buffer != COGL_INVALID_HANDLE)
|
if (node->d.texture.primitive != NULL)
|
||||||
cogl_handle_unref (node->d.texture.vertex_buffer);
|
cogl_object_unref (node->d.texture.primitive);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node->pipeline)
|
if (node->pipeline)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user