gl: avoid copying RenderOp to GArray

Instead of copying the (rather large) RenderOp to the GArray, we can
simply set the fields directly in the allocated space for the struct.
In most cases, there wont be any allocations to make as the array size
is kept in tact across frame renderings.
This commit is contained in:
Christian Hergert 2019-10-09 15:41:53 -07:00
parent b29feb193e
commit 528297f5e5
3 changed files with 174 additions and 196 deletions

View File

@ -1064,34 +1064,35 @@ render_linear_gradient_node (GskGLRenderer *self,
RenderOpBuilder *builder,
const GskQuadVertex *vertex_data)
{
RenderOp op;
RenderOp *op;
int n_color_stops = MIN (8, gsk_linear_gradient_node_get_n_color_stops (node));
const GskColorStop *stops = gsk_linear_gradient_node_peek_color_stops (node);
const graphene_point_t *start = gsk_linear_gradient_node_peek_start (node);
const graphene_point_t *end = gsk_linear_gradient_node_peek_end (node);
int i;
ops_set_program (builder, &self->linear_gradient_program);
op = ops_begin (builder, OP_CHANGE_LINEAR_GRADIENT);
for (i = 0; i < n_color_stops; i ++)
{
const GskColorStop *stop = stops + i;
op.linear_gradient.color_stops[(i * 4) + 0] = stop->color.red;
op.linear_gradient.color_stops[(i * 4) + 1] = stop->color.green;
op.linear_gradient.color_stops[(i * 4) + 2] = stop->color.blue;
op.linear_gradient.color_stops[(i * 4) + 3] = stop->color.alpha;
op.linear_gradient.color_offsets[i] = stop->offset;
op->linear_gradient.color_stops[(i * 4) + 0] = stop->color.red;
op->linear_gradient.color_stops[(i * 4) + 1] = stop->color.green;
op->linear_gradient.color_stops[(i * 4) + 2] = stop->color.blue;
op->linear_gradient.color_stops[(i * 4) + 3] = stop->color.alpha;
op->linear_gradient.color_offsets[i] = stop->offset;
}
ops_set_program (builder, &self->linear_gradient_program);
op.op = OP_CHANGE_LINEAR_GRADIENT;
op.linear_gradient.n_color_stops = n_color_stops;
op.linear_gradient.start_point = *start;
op.linear_gradient.start_point.x += builder->dx;
op.linear_gradient.start_point.y += builder->dy;
op.linear_gradient.end_point = *end;
op.linear_gradient.end_point.x += builder->dx;
op.linear_gradient.end_point.y += builder->dy;
ops_add (builder, &op);
op->linear_gradient.n_color_stops = n_color_stops;
op->linear_gradient.start_point = *start;
op->linear_gradient.start_point.x += builder->dx;
op->linear_gradient.start_point.y += builder->dy;
op->linear_gradient.end_point = *end;
op->linear_gradient.end_point.x += builder->dx;
op->linear_gradient.end_point.y += builder->dy;
ops_draw (builder, vertex_data);
}
@ -1297,7 +1298,7 @@ render_blur_node (GskGLRenderer *self,
const float blur_radius = gsk_blur_node_get_radius (node);
TextureRegion region;
gboolean is_offscreen;
RenderOp op;
RenderOp *op;
if (blur_radius <= 0)
{
@ -1317,10 +1318,10 @@ render_blur_node (GskGLRenderer *self,
RESET_CLIP | FORCE_OFFSCREEN | RESET_OPACITY);
ops_set_program (builder, &self->blur_program);
op.op = OP_CHANGE_BLUR;
graphene_size_init_from_size (&op.blur.size, &node->bounds.size);
op.blur.radius = blur_radius;
ops_add (builder, &op);
op = ops_begin (builder, OP_CHANGE_BLUR);
graphene_size_init_from_size (&op->blur.size, &node->bounds.size);
op->blur.radius = blur_radius;
ops_set_texture (builder, region.texture_id);
@ -1351,7 +1352,7 @@ render_inset_shadow_node (GskGLRenderer *self,
const GskQuadVertex *vertex_data)
{
const float scale = ops_get_scale (builder);
RenderOp op;
RenderOp *op;
/* TODO: Implement blurred inset shadows as well */
if (gsk_inset_shadow_node_get_blur_radius (node) > 0)
@ -1360,20 +1361,20 @@ render_inset_shadow_node (GskGLRenderer *self,
return;
}
op.op = OP_CHANGE_INSET_SHADOW;
rgba_to_float (gsk_inset_shadow_node_peek_color (node), op.inset_shadow.color);
ops_set_program (builder, &self->inset_shadow_program);
op = ops_begin (builder, OP_CHANGE_INSET_SHADOW);
rgba_to_float (gsk_inset_shadow_node_peek_color (node), op->inset_shadow.color);
rounded_rect_to_floats (self, builder,
gsk_inset_shadow_node_peek_outline (node),
op.inset_shadow.outline,
op.inset_shadow.corner_widths,
op.inset_shadow.corner_heights);
op.inset_shadow.radius = gsk_inset_shadow_node_get_blur_radius (node) * scale;
op.inset_shadow.spread = gsk_inset_shadow_node_get_spread (node) * scale;
op.inset_shadow.offset[0] = gsk_inset_shadow_node_get_dx (node) * scale;
op.inset_shadow.offset[1] = -gsk_inset_shadow_node_get_dy (node) * scale;
op->inset_shadow.outline,
op->inset_shadow.corner_widths,
op->inset_shadow.corner_heights);
op->inset_shadow.radius = gsk_inset_shadow_node_get_blur_radius (node) * scale;
op->inset_shadow.spread = gsk_inset_shadow_node_get_spread (node) * scale;
op->inset_shadow.offset[0] = gsk_inset_shadow_node_get_dx (node) * scale;
op->inset_shadow.offset[1] = -gsk_inset_shadow_node_get_dy (node) * scale;
ops_set_program (builder, &self->inset_shadow_program);
ops_add (builder, &op);
ops_draw (builder, vertex_data);
}
@ -1386,25 +1387,25 @@ render_unblurred_outset_shadow_node (GskGLRenderer *self,
const float scale = ops_get_scale (builder);
const float spread = gsk_outset_shadow_node_get_spread (node);
GskRoundedRect r = *gsk_outset_shadow_node_peek_outline (node);
RenderOp op;
RenderOp *op;
op.op = OP_CHANGE_UNBLURRED_OUTSET_SHADOW;
rgba_to_float (gsk_outset_shadow_node_peek_color (node), op.unblurred_outset_shadow.color);
ops_set_program (builder, &self->unblurred_outset_shadow_program);
op = ops_begin (builder, OP_CHANGE_UNBLURRED_OUTSET_SHADOW);
rgba_to_float (gsk_outset_shadow_node_peek_color (node), op->unblurred_outset_shadow.color);
gsk_rounded_rect_shrink (&r, -spread, -spread, -spread, -spread);
rounded_rect_to_floats (self, builder,
&r,
op.unblurred_outset_shadow.outline,
op.unblurred_outset_shadow.corner_widths,
op.unblurred_outset_shadow.corner_heights);
op->unblurred_outset_shadow.outline,
op->unblurred_outset_shadow.corner_widths,
op->unblurred_outset_shadow.corner_heights);
op.unblurred_outset_shadow.spread = gsk_outset_shadow_node_get_spread (node) * scale;
op.unblurred_outset_shadow.offset[0] = gsk_outset_shadow_node_get_dx (node) * scale;
op.unblurred_outset_shadow.offset[1] = -gsk_outset_shadow_node_get_dy (node) * scale;
op->unblurred_outset_shadow.spread = gsk_outset_shadow_node_get_spread (node) * scale;
op->unblurred_outset_shadow.offset[0] = gsk_outset_shadow_node_get_dx (node) * scale;
op->unblurred_outset_shadow.offset[1] = -gsk_outset_shadow_node_get_dy (node) * scale;
ops_set_program (builder, &self->unblurred_outset_shadow_program);
ops_add (builder, &op);
ops_draw (builder, vertex_data);
}
@ -1425,7 +1426,7 @@ render_outset_shadow_node (GskGLRenderer *self,
const float max_x = min_x + outline->bounds.size.width + (spread + blur_extra/2.0) * 2;
const float max_y = min_y + outline->bounds.size.height + (spread + blur_extra/2.0) * 2;
float texture_width, texture_height;
RenderOp op;
RenderOp *op;
graphene_matrix_t prev_projection;
graphene_rect_t prev_viewport;
graphene_matrix_t item_proj;
@ -1476,8 +1477,7 @@ render_outset_shadow_node (GskGLRenderer *self,
graphene_matrix_scale (&item_proj, 1, -1, 1);
prev_render_target = ops_set_render_target (builder, render_target);
op.op = OP_CLEAR;
ops_add (builder, &op);
ops_begin (builder, OP_CLEAR);
prev_projection = ops_set_projection (builder, &item_proj);
ops_set_modelview (builder, NULL); /* Modelview */
prev_viewport = ops_set_viewport (builder, &GRAPHENE_RECT_INIT (0, 0, texture_width, texture_height));
@ -1505,18 +1505,17 @@ render_outset_shadow_node (GskGLRenderer *self,
ops_set_render_target (builder, blurred_render_target);
ops_pop_clip (builder);
op.op = OP_CLEAR;
ops_add (builder, &op);
ops_begin (builder, OP_CLEAR);
gsk_rounded_rect_init_from_rect (&blit_clip,
&GRAPHENE_RECT_INIT (0, 0, texture_width, texture_height), 0.0f);
ops_set_program (builder, &self->blur_program);
op.op = OP_CHANGE_BLUR;
op.blur.size.width = texture_width;
op.blur.size.height = texture_height;
op.blur.radius = blur_radius;
ops_add (builder, &op);
op = ops_begin (builder, OP_CHANGE_BLUR);
op->blur.size.width = texture_width;
op->blur.size.height = texture_height;
op->blur.radius = blur_radius;
ops_push_clip (builder, &blit_clip);
ops_set_texture (builder, texture_id);
@ -1550,13 +1549,13 @@ render_outset_shadow_node (GskGLRenderer *self,
ops_set_program (builder, &self->outset_shadow_program);
ops_set_texture (builder, blurred_texture_id);
op.op = OP_CHANGE_OUTSET_SHADOW;
op = ops_begin (builder, OP_CHANGE_OUTSET_SHADOW);
rounded_rect_to_floats (self, builder,
outline,
op.outset_shadow.outline,
op.outset_shadow.corner_widths,
op.outset_shadow.corner_heights);
ops_add (builder, &op);
op->outset_shadow.outline,
op->outset_shadow.corner_widths,
op->outset_shadow.corner_heights);
/* We use the one outset shadow op from above to draw all 8 sides/corners. */
{
@ -1892,7 +1891,7 @@ render_cross_fade_node (GskGLRenderer *self,
TextureRegion start_region;
TextureRegion end_region;
gboolean is_offscreen1, is_offscreen2;
RenderOp op;
RenderOp *op;
const GskQuadVertex vertex_data[GL_N_VERTICES] = {
{ { min_x, min_y }, { 0, 1 }, },
{ { min_x, max_y }, { 0, 0 }, },
@ -1919,10 +1918,11 @@ render_cross_fade_node (GskGLRenderer *self,
FORCE_OFFSCREEN | RESET_CLIP | RESET_OPACITY);
ops_set_program (builder, &self->cross_fade_program);
op.op = OP_CHANGE_CROSS_FADE;
op.cross_fade.progress = progress;
op.cross_fade.source2 = end_region.texture_id;
ops_add (builder, &op);
op = ops_begin (builder, OP_CHANGE_CROSS_FADE);
op->cross_fade.progress = progress;
op->cross_fade.source2 = end_region.texture_id;
ops_set_texture (builder, start_region.texture_id);
ops_draw (builder, vertex_data);
@ -1942,7 +1942,7 @@ render_blend_node (GskGLRenderer *self,
TextureRegion top_region;
TextureRegion bottom_region;
gboolean is_offscreen1, is_offscreen2;
RenderOp op;
RenderOp *op;
const GskQuadVertex vertex_data[GL_N_VERTICES] = {
{ { min_x, min_y }, { 0, 1 }, },
{ { min_x, max_y }, { 0, 0 }, },
@ -1969,10 +1969,11 @@ render_blend_node (GskGLRenderer *self,
ops_set_program (builder, &self->blend_program);
ops_set_texture (builder, bottom_region.texture_id);
op.op = OP_CHANGE_BLEND;
op.blend.source2 = top_region.texture_id;
op.blend.mode = gsk_blend_node_get_blend_mode (node);
ops_add (builder, &op);
op = ops_begin (builder, OP_CHANGE_BLEND);
op->blend.source2 = top_region.texture_id;
op->blend.mode = gsk_blend_node_get_blend_mode (node);
ops_draw (builder, vertex_data);
}
@ -1989,7 +1990,7 @@ render_repeat_node (GskGLRenderer *self,
const graphene_rect_t *child_bounds = gsk_repeat_node_peek_child_bounds (node);
TextureRegion region;
gboolean is_offscreen;
RenderOp op;
RenderOp *op;
if (child_bounds != NULL &&
!graphene_rect_equal (child_bounds, &child->bounds))
@ -2008,28 +2009,27 @@ render_repeat_node (GskGLRenderer *self,
ops_set_program (builder, &self->repeat_program);
ops_set_texture (builder, region.texture_id);
op.op = OP_CHANGE_REPEAT;
op.repeat.child_bounds[0] = 0; /* Both currently unused */
op.repeat.child_bounds[1] = 0;
op.repeat.child_bounds[2] = node->bounds.size.width / child_bounds->size.width;
op.repeat.child_bounds[3] = node->bounds.size.height / child_bounds->size.height;
op.repeat.texture_rect[0] = region.x;
op.repeat.texture_rect[2] = region.x2;
op = ops_begin (builder, OP_CHANGE_REPEAT);
op->repeat.child_bounds[0] = 0; /* Both currently unused */
op->repeat.child_bounds[1] = 0;
op->repeat.child_bounds[2] = node->bounds.size.width / child_bounds->size.width;
op->repeat.child_bounds[3] = node->bounds.size.height / child_bounds->size.height;
op->repeat.texture_rect[0] = region.x;
op->repeat.texture_rect[2] = region.x2;
if (is_offscreen)
{
op.repeat.texture_rect[1] = region.y2;
op.repeat.texture_rect[3] = region.y;
op->repeat.texture_rect[1] = region.y2;
op->repeat.texture_rect[3] = region.y;
}
else
{
op.repeat.texture_rect[1] = region.y;
op.repeat.texture_rect[3] = region.y2;
op->repeat.texture_rect[1] = region.y;
op->repeat.texture_rect[3] = region.y2;
}
ops_add (builder, &op);
if (is_offscreen)
{
const GskQuadVertex offscreen_vertex_data[GL_N_VERTICES] = {
@ -2885,7 +2885,6 @@ add_offscreen_ops (GskGLRenderer *self,
const float dy = builder->dy;
int render_target;
int prev_render_target;
RenderOp op;
graphene_matrix_t modelview;
graphene_matrix_t prev_projection;
graphene_rect_t prev_viewport;
@ -2935,8 +2934,7 @@ add_offscreen_ops (GskGLRenderer *self,
prev_render_target = ops_set_render_target (builder, render_target);
/* Clear since we use this rendertarget for the first time */
op.op = OP_CLEAR;
ops_add (builder, &op);
ops_begin (builder, OP_CLEAR);
prev_projection = ops_set_projection (builder, &item_proj);
ops_set_modelview (builder, gsk_transform_scale (NULL, scale, scale));
prev_viewport = ops_set_viewport (builder,

View File

@ -57,36 +57,29 @@ ops_dump_framebuffer (RenderOpBuilder *builder,
int width,
int height)
{
RenderOp op;
RenderOp *op;
op.op = OP_DUMP_FRAMEBUFFER;
op.dump.filename = g_strdup (filename);
op.dump.width = width;
op.dump.height = height;
g_array_append_val (builder->render_ops, op);
op = ops_begin (builder, OP_DUMP_FRAMEBUFFER);
op->dump.filename = g_strdup (filename);
op->dump.width = width;
op->dump.height = height;
}
void
ops_push_debug_group (RenderOpBuilder *builder,
const char *text)
{
RenderOp op;
RenderOp *op;
op.op = OP_PUSH_DEBUG_GROUP;
strncpy (op.debug_group.text, text, sizeof(op.debug_group.text) - 1);
op.debug_group.text[sizeof(op.debug_group.text) - 1] = 0; /* Ensure zero terminated */
g_array_append_val (builder->render_ops, op);
op = ops_begin (builder, OP_PUSH_DEBUG_GROUP);
strncpy (op->debug_group.text, text, sizeof(op->debug_group.text) - 1);
op->debug_group.text[sizeof(op->debug_group.text) - 1] = 0; /* Ensure zero terminated */
}
void
ops_pop_debug_group (RenderOpBuilder *builder)
{
RenderOp op;
op.op = OP_POP_DEBUG_GROUP;
g_array_append_val (builder->render_ops, op);
ops_begin (builder, OP_POP_DEBUG_GROUP);
}
float
@ -215,15 +208,15 @@ ops_set_program (RenderOpBuilder *builder,
static const GskRoundedRect empty_clip;
static const graphene_matrix_t empty_matrix;
static const graphene_rect_t empty_rect;
RenderOp op;
RenderOp *op;
ProgramState *program_state;
if (builder->current_program == program)
return;
op.op = OP_CHANGE_PROGRAM;
op.program = program;
g_array_append_val (builder->render_ops, op);
op = ops_begin (builder, OP_CHANGE_PROGRAM);
op->program = program;
builder->current_program = program;
program_state = &builder->program_state[program->index];
@ -232,18 +225,16 @@ ops_set_program (RenderOpBuilder *builder,
if (memcmp (&empty_matrix, &program_state->projection, sizeof (graphene_matrix_t)) == 0 ||
memcmp (&builder->current_projection, &program_state->projection, sizeof (graphene_matrix_t)) != 0)
{
op.op = OP_CHANGE_PROJECTION;
op.projection = builder->current_projection;
g_array_append_val (builder->render_ops, op);
op = ops_begin (builder, OP_CHANGE_PROJECTION);
op->projection = builder->current_projection;
program_state->projection = builder->current_projection;
}
if (program_state->modelview == NULL ||
!gsk_transform_equal (builder->current_modelview, program_state->modelview))
{
op.op = OP_CHANGE_MODELVIEW;
gsk_transform_to_matrix (builder->current_modelview, &op.modelview);
g_array_append_val (builder->render_ops, op);
op = ops_begin (builder, OP_CHANGE_MODELVIEW);
gsk_transform_to_matrix (builder->current_modelview, &op->modelview);
gsk_transform_unref (program_state->modelview);
program_state->modelview = gsk_transform_ref (builder->current_modelview);
}
@ -251,26 +242,23 @@ ops_set_program (RenderOpBuilder *builder,
if (rect_equal (&empty_rect, &program_state->viewport) ||
!rect_equal (&builder->current_viewport, &program_state->viewport))
{
op.op = OP_CHANGE_VIEWPORT;
op.viewport = builder->current_viewport;
g_array_append_val (builder->render_ops, op);
op = ops_begin (builder, OP_CHANGE_VIEWPORT);
op->viewport = builder->current_viewport;
program_state->viewport = builder->current_viewport;
}
if (memcmp (&empty_clip, &program_state->clip, sizeof (GskRoundedRect)) == 0 ||
memcmp (&builder->current_clip, &program_state->clip, sizeof (GskRoundedRect)) != 0)
{
op.op = OP_CHANGE_CLIP;
op.clip = *builder->current_clip;
g_array_append_val (builder->render_ops, op);
op = ops_begin (builder, OP_CHANGE_CLIP);
op->clip = *builder->current_clip;
program_state->clip = *builder->current_clip;
}
if (program_state->opacity != builder->current_opacity)
{
op.op = OP_CHANGE_OPACITY;
op.opacity = builder->current_opacity;
g_array_append_val (builder->render_ops, op);
op = ops_begin (builder, OP_CHANGE_OPACITY);
op->opacity = builder->current_opacity;
program_state->opacity = builder->current_opacity;
}
}
@ -296,11 +284,10 @@ ops_set_clip (RenderOpBuilder *builder,
}
else
{
RenderOp op;
RenderOp *op;
op.op = OP_CHANGE_CLIP;
op.clip = *clip;
g_array_append_val (builder->render_ops, op);
op = ops_begin (builder, OP_CHANGE_CLIP);
op->clip = *clip;
}
}
@ -356,7 +343,7 @@ ops_set_modelview_internal (RenderOpBuilder *builder,
GskTransform *transform)
{
ProgramState *current_program_state = get_current_program_state (builder);
RenderOp op;
RenderOp *op;
graphene_matrix_t matrix;
#if 0
@ -377,16 +364,14 @@ ops_set_modelview_internal (RenderOpBuilder *builder,
}
else
{
op.op = OP_CHANGE_MODELVIEW;
op.modelview = matrix;
g_array_append_val (builder->render_ops, op);
op = ops_begin (builder, OP_CHANGE_MODELVIEW);
op->modelview = matrix;
}
}
else
{
op.op = OP_CHANGE_MODELVIEW;
op.modelview = matrix;
g_array_append_val (builder->render_ops, op);
op = ops_begin (builder, OP_CHANGE_MODELVIEW);
op->modelview = matrix;
}
if (builder->current_program != NULL)
@ -505,7 +490,7 @@ ops_set_projection (RenderOpBuilder *builder,
const graphene_matrix_t *projection)
{
ProgramState *current_program_state = get_current_program_state (builder);
RenderOp op;
RenderOp *op;
graphene_matrix_t prev_mv;
if (builder->render_ops->len > 0)
@ -517,16 +502,14 @@ ops_set_projection (RenderOpBuilder *builder,
}
else
{
op.op = OP_CHANGE_PROJECTION;
op.projection = *projection;
g_array_append_val (builder->render_ops, op);
op = ops_begin (builder, OP_CHANGE_PROJECTION);
op->projection = *projection;
}
}
else
{
op.op = OP_CHANGE_PROJECTION;
op.projection = *projection;
g_array_append_val (builder->render_ops, op);
op = ops_begin (builder, OP_CHANGE_PROJECTION);
op->projection = *projection;
}
if (builder->current_program != NULL)
@ -543,16 +526,15 @@ ops_set_viewport (RenderOpBuilder *builder,
const graphene_rect_t *viewport)
{
ProgramState *current_program_state = get_current_program_state (builder);
RenderOp op;
RenderOp *op;
graphene_rect_t prev_viewport;
if (current_program_state != NULL &&
rect_equal (&current_program_state->viewport, viewport))
return current_program_state->viewport;
op.op = OP_CHANGE_VIEWPORT;
op.viewport = *viewport;
g_array_append_val (builder->render_ops, op);
op = ops_begin (builder, OP_CHANGE_VIEWPORT);
op->viewport = *viewport;
if (builder->current_program != NULL)
current_program_state->viewport = *viewport;
@ -567,14 +549,13 @@ void
ops_set_texture (RenderOpBuilder *builder,
int texture_id)
{
RenderOp op;
RenderOp *op;
if (builder->current_texture == texture_id)
return;
op.op = OP_CHANGE_SOURCE_TEXTURE;
op.texture_id = texture_id;
g_array_append_val (builder->render_ops, op);
op = ops_begin (builder, OP_CHANGE_SOURCE_TEXTURE);
op->texture_id = texture_id;
builder->current_texture = texture_id;
}
@ -582,7 +563,7 @@ int
ops_set_render_target (RenderOpBuilder *builder,
int render_target_id)
{
RenderOp op;
RenderOp *op;
int prev_render_target;
if (builder->current_render_target == render_target_id)
@ -599,16 +580,14 @@ ops_set_render_target (RenderOpBuilder *builder,
}
else
{
op.op = OP_CHANGE_RENDER_TARGET;
op.render_target_id = render_target_id;
g_array_append_val (builder->render_ops, op);
op = ops_begin (builder, OP_CHANGE_RENDER_TARGET);
op->render_target_id = render_target_id;
}
}
else
{
op.op = OP_CHANGE_RENDER_TARGET;
op.render_target_id = render_target_id;
g_array_append_val (builder->render_ops, op);
op = ops_begin (builder, OP_CHANGE_RENDER_TARGET);
op->render_target_id = render_target_id;
}
builder->current_render_target = render_target_id;
@ -621,7 +600,7 @@ ops_set_opacity (RenderOpBuilder *builder,
float opacity)
{
ProgramState *current_program_state = get_current_program_state (builder);
RenderOp op;
RenderOp *op;
float prev_opacity;
RenderOp *last_op;
@ -638,16 +617,14 @@ ops_set_opacity (RenderOpBuilder *builder,
}
else
{
op.op = OP_CHANGE_OPACITY;
op.opacity = opacity;
g_array_append_val (builder->render_ops, op);
op = ops_begin (builder, OP_CHANGE_OPACITY);
op->opacity = opacity;
}
}
else
{
op.op = OP_CHANGE_OPACITY;
op.opacity = opacity;
g_array_append_val (builder->render_ops, op);
op = ops_begin (builder, OP_CHANGE_OPACITY);
op->opacity = opacity;
}
prev_opacity = builder->current_opacity;
@ -664,16 +641,15 @@ ops_set_color (RenderOpBuilder *builder,
const GdkRGBA *color)
{
ProgramState *current_program_state = get_current_program_state (builder);
RenderOp op;
RenderOp *op;
if (gdk_rgba_equal (color, &current_program_state->color))
return;
current_program_state->color = *color;
op.op = OP_CHANGE_COLOR;
op.color = *color;
g_array_append_val (builder->render_ops, op);
op = ops_begin (builder, OP_CHANGE_COLOR);
op->color = *color;
}
void
@ -682,7 +658,7 @@ ops_set_color_matrix (RenderOpBuilder *builder,
const graphene_vec4_t *offset)
{
ProgramState *current_program_state = get_current_program_state (builder);
RenderOp op;
RenderOp *op;
if (memcmp (matrix,
&current_program_state->color_matrix.matrix,
@ -695,10 +671,9 @@ ops_set_color_matrix (RenderOpBuilder *builder,
current_program_state->color_matrix.matrix = *matrix;
current_program_state->color_matrix.offset = *offset;
op.op = OP_CHANGE_COLOR_MATRIX;
op.color_matrix.matrix = *matrix;
op.color_matrix.offset = *offset;
g_array_append_val (builder->render_ops, op);
op = ops_begin (builder, OP_CHANGE_COLOR_MATRIX);
op->color_matrix.matrix = *matrix;
op->color_matrix.offset = *offset;
}
void
@ -706,7 +681,7 @@ ops_set_border (RenderOpBuilder *builder,
const GskRoundedRect *outline)
{
ProgramState *current_program_state = get_current_program_state (builder);
RenderOp op;
RenderOp *op;
if (memcmp (&current_program_state->border.outline,
outline, sizeof (GskRoundedRect)) == 0)
@ -714,9 +689,8 @@ ops_set_border (RenderOpBuilder *builder,
current_program_state->border.outline = *outline;
op.op = OP_CHANGE_BORDER;
op.border.outline = *outline;
g_array_append_val (builder->render_ops, op);
op = ops_begin (builder, OP_CHANGE_BORDER);
op->border.outline = *outline;
}
void
@ -724,7 +698,7 @@ ops_set_border_width (RenderOpBuilder *builder,
const float *widths)
{
ProgramState *current_program_state = get_current_program_state (builder);
RenderOp op;
RenderOp *op;
if (memcmp (current_program_state->border.widths,
widths, sizeof (float) * 4) == 0)
@ -733,13 +707,11 @@ ops_set_border_width (RenderOpBuilder *builder,
memcpy (&current_program_state->border.widths,
widths, sizeof (float) * 4);
op.op = OP_CHANGE_BORDER_WIDTH;
op.border.widths[0] = widths[0];
op.border.widths[1] = widths[1];
op.border.widths[2] = widths[2];
op.border.widths[3] = widths[3];
g_array_append_val (builder->render_ops, op);
op = ops_begin (builder, OP_CHANGE_BORDER_WIDTH);
op->border.widths[0] = widths[0];
op->border.widths[1] = widths[1];
op->border.widths[2] = widths[2];
op->border.widths[3] = widths[3];
}
void
@ -775,16 +747,18 @@ ops_draw (RenderOpBuilder *builder,
/* We allow ourselves a little trick here. We still have to add a CHANGE_VAO op for
* this draw call so we can add our vertex data there, but we want it to be placed before
* the last draw call, so we reorder those. */
RenderOp new_draw;
new_draw.op = OP_DRAW;
new_draw.draw.vao_offset = last_op->draw.vao_offset;
new_draw.draw.vao_size = last_op->draw.vao_size + GL_N_VERTICES;
RenderOp *new_draw;
new_draw = ops_begin (builder, OP_DRAW);
/* last_op may have moved in memory */
last_op = &g_array_index (builder->render_ops, RenderOp, builder->render_ops->len - 2);
new_draw->draw.vao_offset = last_op->draw.vao_offset;
new_draw->draw.vao_size = last_op->draw.vao_size + GL_N_VERTICES;
last_op->op = OP_CHANGE_VAO;
memcpy (&last_op->vertex_data, vertex_data, sizeof(GskQuadVertex) * GL_N_VERTICES);
/* Now add the DRAW */
g_array_append_val (builder->render_ops, new_draw);
}
else
{
@ -821,9 +795,15 @@ ops_offset (RenderOpBuilder *builder,
builder->dy += y;
}
void
ops_add (RenderOpBuilder *builder,
const RenderOp *op)
RenderOp *
ops_begin (RenderOpBuilder *builder,
guint kind)
{
g_array_append_val (builder->render_ops, *op);
RenderOp *op;
g_array_set_size (builder->render_ops, builder->render_ops->len + 1);
op = &g_array_index (builder->render_ops, RenderOp, builder->render_ops->len - 1);
op->op = kind;
return op;
}

View File

@ -358,7 +358,7 @@ void ops_offset (RenderOpBuilder *builder,
float x,
float y);
void ops_add (RenderOpBuilder *builder,
const RenderOp *op);
RenderOp *ops_begin (RenderOpBuilder *builder,
guint kind);
#endif