[gtk/wip/chergert/opbuffer] prototype OpBuffer helper for building op buffer
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/chergert/opbuffer] prototype OpBuffer helper for building op buffer
- Date: Fri, 11 Oct 2019 14:26:55 +0000 (UTC)
commit 675cbcc1e713c539ed6a4e1e2cc72709db60ae36
Author: Christian Hergert <chergert redhat com>
Date: Fri Oct 11 10:23:33 2019 -0400
prototype OpBuffer helper for building op buffer
gsk/gl/gskglrenderer.c | 438 +++++++++++++++++++++--------------------
gsk/gl/gskglrenderops.c | 280 ++++++++++----------------
gsk/gl/gskglrenderopsprivate.h | 140 +------------
gsk/gl/opbuffer.c | 134 +++++++++++++
gsk/gl/opbuffer.h | 263 +++++++++++++++++++++++++
gsk/meson.build | 1 +
6 files changed, 743 insertions(+), 513 deletions(-)
---
diff --git a/gsk/gl/gskglrenderer.c b/gsk/gl/gskglrenderer.c
index 3835aaa2bb..fe2a6b9271 100644
--- a/gsk/gl/gskglrenderer.c
+++ b/gsk/gl/gskglrenderer.c
@@ -8,6 +8,7 @@
#include "gskglprofilerprivate.h"
#include "gskprofilerprivate.h"
#include "gskrendererprivate.h"
+#include "gskrendernodeprivate.h"
#include "gsktransformprivate.h"
#include "gskshaderbuilderprivate.h"
#include "gskglglyphcacheprivate.h"
@@ -345,7 +346,6 @@ struct _GskGLRenderer
};
RenderOpBuilder op_builder;
- GArray *render_ops;
GskGLTextureAtlases *atlases;
GskGLGlyphCache *glyph_cache;
@@ -1064,7 +1064,7 @@ render_linear_gradient_node (GskGLRenderer *self,
RenderOpBuilder *builder,
const GskQuadVertex *vertex_data)
{
- RenderOp *op;
+ OpLinearGradient *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);
@@ -1079,20 +1079,18 @@ render_linear_gradient_node (GskGLRenderer *self,
{
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->color_stops[(i * 4) + 0] = stop->color.red;
+ op->color_stops[(i * 4) + 1] = stop->color.green;
+ op->color_stops[(i * 4) + 2] = stop->color.blue;
+ op->color_stops[(i * 4) + 3] = stop->color.alpha;
+ op->color_offsets[i] = stop->offset;
}
- 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;
+ op->n_color_stops = n_color_stops;
+ op->start_point.x += start->x + builder->dx;
+ op->start_point.y += start->y + builder->dy;
+ op->end_point.x += end->x + builder->dx;
+ op->end_point.y += end->y + builder->dy;
ops_draw (builder, vertex_data);
}
@@ -1298,7 +1296,7 @@ render_blur_node (GskGLRenderer *self,
const float blur_radius = gsk_blur_node_get_radius (node);
TextureRegion region;
gboolean is_offscreen;
- RenderOp *op;
+ OpBlur *op;
if (blur_radius <= 0)
{
@@ -1320,8 +1318,8 @@ render_blur_node (GskGLRenderer *self,
ops_set_program (builder, &self->blur_program);
op = ops_begin (builder, OP_CHANGE_BLUR);
- graphene_size_init_from_size (&op->blur.size, &node->bounds.size);
- op->blur.radius = blur_radius;
+ graphene_size_init_from_size (&op->size, &node->bounds.size);
+ op->radius = blur_radius;
ops_set_texture (builder, region.texture_id);
@@ -1352,7 +1350,7 @@ render_inset_shadow_node (GskGLRenderer *self,
const GskQuadVertex *vertex_data)
{
const float scale = ops_get_scale (builder);
- RenderOp *op;
+ OpShadow *op;
/* TODO: Implement blurred inset shadows as well */
if (gsk_inset_shadow_node_get_blur_radius (node) > 0)
@@ -1364,16 +1362,16 @@ render_inset_shadow_node (GskGLRenderer *self,
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);
+ rgba_to_float (gsk_inset_shadow_node_peek_color (node), op->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->outline,
+ op->corner_widths,
+ op->corner_heights);
+ op->radius = gsk_inset_shadow_node_get_blur_radius (node) * scale;
+ op->spread = gsk_inset_shadow_node_get_spread (node) * scale;
+ op->offset[0] = gsk_inset_shadow_node_get_dx (node) * scale;
+ op->offset[1] = -gsk_inset_shadow_node_get_dy (node) * scale;
ops_draw (builder, vertex_data);
}
@@ -1387,24 +1385,24 @@ 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;
+ OpShadow *op;
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);
+ rgba_to_float (gsk_outset_shadow_node_peek_color (node), op->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->outline,
+ op->corner_widths,
+ op->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->spread = gsk_outset_shadow_node_get_spread (node) * scale;
+ op->offset[0] = gsk_outset_shadow_node_get_dx (node) * scale;
+ op->offset[1] = -gsk_outset_shadow_node_get_dy (node) * scale;
ops_draw (builder, vertex_data);
}
@@ -1426,7 +1424,8 @@ 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;
+ OpBlur *op;
+ OpShadow *shadow;
graphene_matrix_t prev_projection;
graphene_rect_t prev_viewport;
graphene_matrix_t item_proj;
@@ -1513,9 +1512,9 @@ render_outset_shadow_node (GskGLRenderer *self,
ops_set_program (builder, &self->blur_program);
op = ops_begin (builder, OP_CHANGE_BLUR);
- op->blur.size.width = texture_width;
- op->blur.size.height = texture_height;
- op->blur.radius = blur_radius;
+ op->size.width = texture_width;
+ op->size.height = texture_height;
+ op->radius = blur_radius;
ops_push_clip (builder, &blit_clip);
ops_set_texture (builder, texture_id);
@@ -1550,12 +1549,12 @@ render_outset_shadow_node (GskGLRenderer *self,
ops_set_program (builder, &self->outset_shadow_program);
ops_set_texture (builder, blurred_texture_id);
- op = ops_begin (builder, OP_CHANGE_OUTSET_SHADOW);
+ shadow = 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);
+ shadow->outline,
+ shadow->corner_widths,
+ shadow->corner_heights);
/* We use the one outset shadow op from above to draw all 8 sides/corners. */
{
@@ -1891,7 +1890,7 @@ render_cross_fade_node (GskGLRenderer *self,
TextureRegion start_region;
TextureRegion end_region;
gboolean is_offscreen1, is_offscreen2;
- RenderOp *op;
+ OpCrossFade *op;
const GskQuadVertex vertex_data[GL_N_VERTICES] = {
{ { min_x, min_y }, { 0, 1 }, },
{ { min_x, max_y }, { 0, 0 }, },
@@ -1920,8 +1919,8 @@ render_cross_fade_node (GskGLRenderer *self,
ops_set_program (builder, &self->cross_fade_program);
op = ops_begin (builder, OP_CHANGE_CROSS_FADE);
- op->cross_fade.progress = progress;
- op->cross_fade.source2 = end_region.texture_id;
+ op->progress = progress;
+ op->source2 = end_region.texture_id;
ops_set_texture (builder, start_region.texture_id);
@@ -1942,7 +1941,7 @@ render_blend_node (GskGLRenderer *self,
TextureRegion top_region;
TextureRegion bottom_region;
gboolean is_offscreen1, is_offscreen2;
- RenderOp *op;
+ OpBlend *op;
const GskQuadVertex vertex_data[GL_N_VERTICES] = {
{ { min_x, min_y }, { 0, 1 }, },
{ { min_x, max_y }, { 0, 0 }, },
@@ -1971,8 +1970,8 @@ render_blend_node (GskGLRenderer *self,
ops_set_texture (builder, bottom_region.texture_id);
op = ops_begin (builder, OP_CHANGE_BLEND);
- op->blend.source2 = top_region.texture_id;
- op->blend.mode = gsk_blend_node_get_blend_mode (node);
+ op->source2 = top_region.texture_id;
+ op->mode = gsk_blend_node_get_blend_mode (node);
ops_draw (builder, vertex_data);
}
@@ -1990,7 +1989,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;
+ OpRepeat *op;
if (child_bounds != NULL &&
!graphene_rect_equal (child_bounds, &child->bounds))
@@ -2011,23 +2010,23 @@ render_repeat_node (GskGLRenderer *self,
ops_set_texture (builder, region.texture_id);
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->child_bounds[0] = 0; /* Both currently unused */
+ op->child_bounds[1] = 0;
+ op->child_bounds[2] = node->bounds.size.width / child_bounds->size.width;
+ op->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->texture_rect[0] = region.x;
+ op->texture_rect[2] = region.x2;
if (is_offscreen)
{
- op->repeat.texture_rect[1] = region.y2;
- op->repeat.texture_rect[3] = region.y;
+ op->texture_rect[1] = region.y2;
+ op->texture_rect[3] = region.y;
}
else
{
- op->repeat.texture_rect[1] = region.y;
- op->repeat.texture_rect[3] = region.y2;
+ op->texture_rect[1] = region.y;
+ op->texture_rect[3] = region.y2;
}
if (is_offscreen)
@@ -2061,10 +2060,12 @@ render_repeat_node (GskGLRenderer *self,
}
static inline void
-apply_viewport_op (const Program *program,
- const RenderOp *op)
+apply_viewport_op (const Program *program,
+ const OpViewport *op)
{
- OP_PRINT (" -> New Viewport: %f, %f, %f, %f", op->viewport.origin.x, op->viewport.origin.y,
op->viewport.size.width, op->viewport.size.height);
+ OP_PRINT (" -> New Viewport: %f, %f, %f, %f",
+ op->viewport.origin.x, op->viewport.origin.y,
+ op->viewport.size.width, op->viewport.size.height);
glUniform4f (program->viewport_location,
op->viewport.origin.x, op->viewport.origin.y,
op->viewport.size.width, op->viewport.size.height);
@@ -2073,38 +2074,38 @@ apply_viewport_op (const Program *program,
static inline void
apply_modelview_op (const Program *program,
- const RenderOp *op)
+ const OpMatrix *op)
{
float mat[16];
OP_PRINT (" -> Modelview");
- graphene_matrix_to_float (&op->modelview, mat);
+ graphene_matrix_to_float (&op->matrix, mat);
glUniformMatrix4fv (program->modelview_location, 1, GL_FALSE, mat);
}
static inline void
apply_projection_op (const Program *program,
- const RenderOp *op)
+ const OpMatrix *op)
{
float mat[16];
OP_PRINT (" -> Projection");
- graphene_matrix_to_float (&op->projection, mat);
+ graphene_matrix_to_float (&op->matrix, mat);
glUniformMatrix4fv (program->projection_location, 1, GL_FALSE, mat);
}
static inline void
apply_program_op (const Program *program,
- const RenderOp *op)
+ const OpProgram *op)
{
OP_PRINT (" -> Program: %d", op->program->index);
glUseProgram (op->program->id);
}
static inline void
-apply_render_target_op (GskGLRenderer *self,
- const Program *program,
- const RenderOp *op)
+apply_render_target_op (GskGLRenderer *self,
+ const Program *program,
+ const OpRenderTarget *op)
{
OP_PRINT (" -> Render Target: %d", op->render_target_id);
@@ -2117,25 +2118,26 @@ apply_render_target_op (GskGLRenderer *self,
}
static inline void
-apply_color_op (const Program *program,
- const RenderOp *op)
+apply_color_op (const Program *program,
+ const OpColor *op)
{
- OP_PRINT (" -> Color: (%f, %f, %f, %f)", op->color.red, op->color.green, op->color.blue, op->color.alpha);
+ OP_PRINT (" -> Color: (%f, %f, %f, %f)",
+ op->rgba.red, op->rgba.green, op->rgba.blue, op->rgba.alpha);
glUniform4f (program->color.color_location,
- op->color.red, op->color.green, op->color.blue, op->color.alpha);
+ op->rgba.red, op->rgba.green, op->rgba.blue, op->rgba.alpha);
}
static inline void
-apply_opacity_op (const Program *program,
- const RenderOp *op)
+apply_opacity_op (const Program *program,
+ const OpOpacity *op)
{
OP_PRINT (" -> Opacity %f", op->opacity);
glUniform1f (program->alpha_location, op->opacity);
}
static inline void
-apply_source_texture_op (const Program *program,
- const RenderOp *op)
+apply_source_texture_op (const Program *program,
+ const OpTexture *op)
{
g_assert(op->texture_id != 0);
OP_PRINT (" -> New texture: %d", op->texture_id);
@@ -2146,22 +2148,22 @@ apply_source_texture_op (const Program *program,
}
static inline void
-apply_color_matrix_op (const Program *program,
- const RenderOp *op)
+apply_color_matrix_op (const Program *program,
+ const OpColorMatrix *op)
{
float mat[16];
float vec[4];
OP_PRINT (" -> Color Matrix");
- graphene_matrix_to_float (&op->color_matrix.matrix, mat);
+ graphene_matrix_to_float (&op->matrix, mat);
glUniformMatrix4fv (program->color_matrix.color_matrix_location, 1, GL_FALSE, mat);
- graphene_vec4_to_float (&op->color_matrix.offset, vec);
+ graphene_vec4_to_float (&op->offset, vec);
glUniform4fv (program->color_matrix.color_offset_location, 1, vec);
}
static inline void
-apply_clip_op (const Program *program,
- const RenderOp *op)
+apply_clip_op (const Program *program,
+ const OpClip *op)
{
OP_PRINT (" -> Clip (%f, %f, %f, %f) (%f, %f, %f, %f), (%f, %f, %f, %f)",
op->clip.bounds.origin.x, op->clip.bounds.origin.y,
@@ -2192,85 +2194,85 @@ apply_clip_op (const Program *program,
static inline void
apply_inset_shadow_op (const Program *program,
- const RenderOp *op)
+ const OpShadow *op)
{
OP_PRINT (" -> inset shadow. Color: (%f, %f, %f, %f), Offset: (%f, %f), Spread: %f, Outline: (%f, %f, %f,
%f) Corner widths: (%f, %f, %f, %f), Corner Heights: (%f, %f, %f, %f)",
- op->inset_shadow.color[0],
- op->inset_shadow.color[1],
- op->inset_shadow.color[2],
- op->inset_shadow.color[3],
- op->inset_shadow.offset[0],
- op->inset_shadow.offset[1],
- op->inset_shadow.spread,
- op->inset_shadow.outline[0],
- op->inset_shadow.outline[1],
- op->inset_shadow.outline[2],
- op->inset_shadow.outline[3],
- op->inset_shadow.corner_widths[0],
- op->inset_shadow.corner_widths[1],
- op->inset_shadow.corner_widths[2],
- op->inset_shadow.corner_widths[3],
- op->inset_shadow.corner_heights[0],
- op->inset_shadow.corner_heights[1],
- op->inset_shadow.corner_heights[2],
- op->inset_shadow.corner_heights[3]);
- glUniform4fv (program->inset_shadow.color_location, 1, op->inset_shadow.color);
- glUniform2fv (program->inset_shadow.offset_location, 1, op->inset_shadow.offset);
- glUniform1f (program->inset_shadow.spread_location, op->inset_shadow.spread);
- glUniform4fv (program->inset_shadow.outline_location, 1, op->inset_shadow.outline);
- glUniform4fv (program->inset_shadow.corner_widths_location, 1, op->inset_shadow.corner_widths);
- glUniform4fv (program->inset_shadow.corner_heights_location, 1, op->inset_shadow.corner_heights);
+ op->color[0],
+ op->color[1],
+ op->color[2],
+ op->color[3],
+ op->offset[0],
+ op->offset[1],
+ op->spread,
+ op->outline[0],
+ op->outline[1],
+ op->outline[2],
+ op->outline[3],
+ op->corner_widths[0],
+ op->corner_widths[1],
+ op->corner_widths[2],
+ op->corner_widths[3],
+ op->corner_heights[0],
+ op->corner_heights[1],
+ op->corner_heights[2],
+ op->corner_heights[3]);
+ glUniform4fv (program->inset_shadow.color_location, 1, op->color);
+ glUniform2fv (program->inset_shadow.offset_location, 1, op->offset);
+ glUniform1f (program->inset_shadow.spread_location, op->spread);
+ glUniform4fv (program->inset_shadow.outline_location, 1, op->outline);
+ glUniform4fv (program->inset_shadow.corner_widths_location, 1, op->corner_widths);
+ glUniform4fv (program->inset_shadow.corner_heights_location, 1, op->corner_heights);
}
static inline void
apply_unblurred_outset_shadow_op (const Program *program,
- const RenderOp *op)
+ const OpShadow *op)
{
OP_PRINT (" -> unblurred outset shadow");
- glUniform4fv (program->unblurred_outset_shadow.color_location, 1, op->unblurred_outset_shadow.color);
- glUniform2fv (program->unblurred_outset_shadow.offset_location, 1, op->unblurred_outset_shadow.offset);
- glUniform1f (program->unblurred_outset_shadow.spread_location, op->unblurred_outset_shadow.spread);
- glUniform4fv (program->unblurred_outset_shadow.outline_location, 1, op->unblurred_outset_shadow.outline);
+ glUniform4fv (program->unblurred_outset_shadow.color_location, 1, op->color);
+ glUniform2fv (program->unblurred_outset_shadow.offset_location, 1, op->offset);
+ glUniform1f (program->unblurred_outset_shadow.spread_location, op->spread);
+ glUniform4fv (program->unblurred_outset_shadow.outline_location, 1, op->outline);
glUniform4fv (program->unblurred_outset_shadow.corner_widths_location, 1,
- op->unblurred_outset_shadow.corner_widths);
+ op->corner_widths);
glUniform4fv (program->unblurred_outset_shadow.corner_heights_location, 1,
- op->unblurred_outset_shadow.corner_heights);
+ op->corner_heights);
}
static inline void
apply_outset_shadow_op (const Program *program,
- const RenderOp *op)
+ const OpShadow *op)
{
OP_PRINT (" -> outset shadow");
- glUniform4fv (program->outset_shadow.outline_location, 1, op->outset_shadow.outline);
- glUniform4fv (program->outset_shadow.corner_widths_location, 1, op->outset_shadow.corner_widths);
- glUniform4fv (program->outset_shadow.corner_heights_location, 1, op->outset_shadow.corner_heights);
+ glUniform4fv (program->outset_shadow.outline_location, 1, op->outline);
+ glUniform4fv (program->outset_shadow.corner_widths_location, 1, op->corner_widths);
+ glUniform4fv (program->outset_shadow.corner_heights_location, 1, op->corner_heights);
}
static inline void
-apply_linear_gradient_op (const Program *program,
- const RenderOp *op)
+apply_linear_gradient_op (const Program *program,
+ const OpLinearGradient *op)
{
OP_PRINT (" -> Linear gradient");
glUniform1i (program->linear_gradient.num_color_stops_location,
- op->linear_gradient.n_color_stops);
+ op->n_color_stops);
glUniform4fv (program->linear_gradient.color_stops_location,
- op->linear_gradient.n_color_stops,
- op->linear_gradient.color_stops);
+ op->n_color_stops,
+ op->color_stops);
glUniform1fv (program->linear_gradient.color_offsets_location,
- op->linear_gradient.n_color_stops,
- op->linear_gradient.color_offsets);
+ op->n_color_stops,
+ op->color_offsets);
glUniform2f (program->linear_gradient.start_point_location,
- op->linear_gradient.start_point.x, op->linear_gradient.start_point.y);
+ op->start_point.x, op->start_point.y);
glUniform2f (program->linear_gradient.end_point_location,
- op->linear_gradient.end_point.x, op->linear_gradient.end_point.y);
+ op->end_point.x, op->end_point.y);
}
static inline void
apply_border_op (const Program *program,
- const RenderOp *op)
+ const OpBorder *op)
{
- const GskRoundedRect *o = &op->border.outline;
+ const GskRoundedRect *o = &op->outline;
float outline[4];
float widths[4];
float heights[4];
@@ -2295,63 +2297,63 @@ apply_border_op (const Program *program,
static inline void
apply_border_width_op (const Program *program,
- const RenderOp *op)
+ const OpBorder *op)
{
OP_PRINT (" -> Border width (%f, %f, %f, %f)",
- op->border.widths[0], op->border.widths[1], op->border.widths[2], op->border.widths[3]);
+ op->widths[0], op->widths[1], op->widths[2], op->widths[3]);
- glUniform4fv (program->border.widths_location, 1, op->border.widths);
+ glUniform4fv (program->border.widths_location, 1, op->widths);
}
static inline void
apply_border_color_op (const Program *program,
- const RenderOp *op)
+ const OpBorder *op)
{
OP_PRINT (" -> Border color (%f, %f, %f, %f)",
- op->border.color[0], op->border.color[1], op->border.color[2], op->border.color[3]);
- glUniform4fv (program->border.color_location, 1, op->border.color);
+ op->color[0], op->color[1], op->color[2], op->color[3]);
+ glUniform4fv (program->border.color_location, 1, op->color);
}
static inline void
-apply_blur_op (const Program *program,
- const RenderOp *op)
+apply_blur_op (const Program *program,
+ const OpBlur *op)
{
OP_PRINT (" -> Blur");
- glUniform1f (program->blur.blur_radius_location, op->blur.radius);
- glUniform2f (program->blur.blur_size_location, op->blur.size.width, op->blur.size.height);
- /*glUniform2f (program->blur.dir_location, op->blur.dir[0], op->blur.dir[1]);*/
+ glUniform1f (program->blur.blur_radius_location, op->radius);
+ glUniform2f (program->blur.blur_size_location, op->size.width, op->size.height);
+ /*glUniform2f (program->blur.dir_location, op->dir[0], op->dir[1]);*/
}
static inline void
-apply_cross_fade_op (const Program *program,
- const RenderOp *op)
+apply_cross_fade_op (const Program *program,
+ const OpCrossFade *op)
{
/* End texture id */
glUniform1i (program->cross_fade.source2_location, 1);
glActiveTexture (GL_TEXTURE0 + 1);
- glBindTexture (GL_TEXTURE_2D, op->cross_fade.source2);
+ glBindTexture (GL_TEXTURE_2D, op->source2);
/* progress */
- glUniform1f (program->cross_fade.progress_location, op->cross_fade.progress);
+ glUniform1f (program->cross_fade.progress_location, op->progress);
}
static inline void
-apply_blend_op (const Program *program,
- const RenderOp *op)
+apply_blend_op (const Program *program,
+ const OpBlend *op)
{
/* End texture id */
glUniform1i (program->blend.source2_location, 1);
glActiveTexture (GL_TEXTURE0 + 1);
- glBindTexture (GL_TEXTURE_2D, op->blend.source2);
+ glBindTexture (GL_TEXTURE_2D, op->source2);
/* progress */
- glUniform1i (program->blend.mode_location, op->blend.mode);
+ glUniform1i (program->blend.mode_location, op->mode);
}
static inline void
apply_repeat_op (const Program *program,
- const RenderOp *op)
+ const OpRepeat *op)
{
- glUniform4fv (program->repeat.child_bounds_location, 1, op->repeat.child_bounds);
- glUniform4fv (program->repeat.texture_rect_location, 1, op->repeat.texture_rect);
+ glUniform4fv (program->repeat.child_bounds_location, 1, op->child_bounds);
+ glUniform4fv (program->repeat.texture_rect_location, 1, op->texture_rect);
}
static void
@@ -2359,7 +2361,6 @@ gsk_gl_renderer_dispose (GObject *gobject)
{
GskGLRenderer *self = GSK_GL_RENDERER (gobject);
- g_clear_pointer (&self->render_ops, g_array_unref);
ops_free (&self->op_builder);
G_OBJECT_CLASS (gsk_gl_renderer_parent_class)->dispose (gobject);
@@ -2647,7 +2648,7 @@ gsk_gl_renderer_unrealize (GskRenderer *renderer)
/* We don't need to iterate to destroy the associated GL resources,
* as they will be dropped when we finalize the GskGLDriver
*/
- g_array_set_size (self->render_ops, 0);
+ ops_reset (&self->op_builder);
for (i = 0; i < GL_N_PROGRAMS; i ++)
glDeleteProgram (self->programs[i].id);
@@ -2676,7 +2677,7 @@ gsk_gl_renderer_clear_tree (GskGLRenderer *self)
gdk_gl_context_make_current (self->gl_context);
- g_array_remove_range (self->render_ops, 0, self->render_ops->len);
+ ops_reset (&self->op_builder);
removed_textures = gsk_gl_driver_collect_textures (self->gl_driver);
GSK_RENDERER_NOTE (GSK_RENDERER (self), OPENGL, g_message ("Collected: %d textures", removed_textures));
@@ -2990,11 +2991,13 @@ static void
gsk_gl_renderer_render_ops (GskGLRenderer *self,
gsize vertex_data_size)
{
- guint i;
- guint n_ops = self->render_ops->len;
const Program *program = NULL;
gsize buffer_index = 0;
float *vertex_data = g_malloc (vertex_data_size);
+ OpBuffer *buffer;
+ OpBufferIter iter;
+ OpKind kind;
+ gpointer ptr;
/*g_message ("%s: Buffer size: %ld", __FUNCTION__, vertex_data_size);*/
@@ -3006,15 +3009,16 @@ gsk_gl_renderer_render_ops (GskGLRenderer *self,
glGenBuffers (1, &buffer_id);
glBindBuffer (GL_ARRAY_BUFFER, buffer_id);
-
// Fill buffer data
- for (i = 0; i < n_ops; i ++)
+ buffer = ops_get_buffer (&self->op_builder);
+ op_buffer_iter_init (&iter, buffer);
+ while ((ptr = op_buffer_iter_next (&iter, &kind)))
{
- const RenderOp *op = &g_array_index (self->render_ops, RenderOp, i);
-
- if (op->op == OP_CHANGE_VAO)
+ if (kind == OP_CHANGE_VAO)
{
- memcpy (vertex_data + buffer_index, &op->vertex_data, sizeof (GskQuadVertex) * GL_N_VERTICES);
+ const OpVao *vao = ptr;
+
+ memcpy (vertex_data + buffer_index, &vao->vertex_data, sizeof (GskQuadVertex) * GL_N_VERTICES);
buffer_index += sizeof (GskQuadVertex) * GL_N_VERTICES / sizeof (float);
}
}
@@ -3035,41 +3039,42 @@ gsk_gl_renderer_render_ops (GskGLRenderer *self,
sizeof (GskQuadVertex),
(void *) G_STRUCT_OFFSET (GskQuadVertex, uv));
- for (i = 0; i < n_ops; i ++)
+ op_buffer_iter_init (&iter, ops_get_buffer (&self->op_builder));
+ while ((ptr = op_buffer_iter_next (&iter, &kind)))
{
- const RenderOp *op = &g_array_index (self->render_ops, RenderOp, i);
-
- if (op->op == OP_NONE ||
- op->op == OP_CHANGE_VAO)
+ if (kind == OP_NONE || kind == OP_CHANGE_VAO)
continue;
if (program == NULL &&
- op->op != OP_PUSH_DEBUG_GROUP &&
- op->op != OP_POP_DEBUG_GROUP &&
- op->op != OP_CHANGE_PROGRAM &&
- op->op != OP_CHANGE_RENDER_TARGET &&
- op->op != OP_CLEAR)
+ kind != OP_PUSH_DEBUG_GROUP &&
+ kind != OP_POP_DEBUG_GROUP &&
+ kind != OP_CHANGE_PROGRAM &&
+ kind != OP_CHANGE_RENDER_TARGET &&
+ kind != OP_CLEAR)
continue;
- OP_PRINT ("Op %u: %u", i, op->op);
+ OP_PRINT ("Op %u: %u", iter.pos - 2, kind);
- switch (op->op)
+ switch (kind)
{
case OP_CHANGE_PROJECTION:
- apply_projection_op (program, op);
+ apply_projection_op (program, ptr);
break;
case OP_CHANGE_MODELVIEW:
- apply_modelview_op (program, op);
+ apply_modelview_op (program, ptr);
break;
case OP_CHANGE_PROGRAM:
- apply_program_op (program, op);
- program = op->program;
- break;
+ {
+ const OpProgram *op = ptr;
+ apply_program_op (program, op);
+ program = op->program;
+ break;
+ }
case OP_CHANGE_RENDER_TARGET:
- apply_render_target_op (self, program, op);
+ apply_render_target_op (self, program, ptr);
break;
case OP_CLEAR:
@@ -3078,95 +3083,109 @@ gsk_gl_renderer_render_ops (GskGLRenderer *self,
break;
case OP_CHANGE_VIEWPORT:
- apply_viewport_op (program, op);
+ apply_viewport_op (program, ptr);
break;
case OP_CHANGE_OPACITY:
- apply_opacity_op (program, op);
+ apply_opacity_op (program, ptr);
break;
case OP_CHANGE_COLOR_MATRIX:
- apply_color_matrix_op (program, op);
+ apply_color_matrix_op (program, ptr);
break;
case OP_CHANGE_COLOR:
/*g_assert (program == &self->color_program || program == &self->coloring_program ||*/
/*program == &self->shadow_program);*/
- apply_color_op (program, op);
+ apply_color_op (program, ptr);
break;
case OP_CHANGE_BORDER_COLOR:
- apply_border_color_op (program, op);
+ apply_border_color_op (program, ptr);
break;
case OP_CHANGE_CLIP:
- apply_clip_op (program, op);
+ apply_clip_op (program, ptr);
break;
case OP_CHANGE_SOURCE_TEXTURE:
- apply_source_texture_op (program, op);
+ apply_source_texture_op (program, ptr);
break;
case OP_CHANGE_CROSS_FADE:
g_assert (program == &self->cross_fade_program);
- apply_cross_fade_op (program, op);
+ apply_cross_fade_op (program, ptr);
break;
case OP_CHANGE_BLEND:
g_assert (program == &self->blend_program);
- apply_blend_op (program, op);
+ apply_blend_op (program, ptr);
break;
case OP_CHANGE_LINEAR_GRADIENT:
- apply_linear_gradient_op (program, op);
+ apply_linear_gradient_op (program, ptr);
break;
case OP_CHANGE_BLUR:
- apply_blur_op (program, op);
+ apply_blur_op (program, ptr);
break;
case OP_CHANGE_INSET_SHADOW:
- apply_inset_shadow_op (program, op);
+ apply_inset_shadow_op (program, ptr);
break;
case OP_CHANGE_OUTSET_SHADOW:
- apply_outset_shadow_op (program, op);
+ apply_outset_shadow_op (program, ptr);
break;
case OP_CHANGE_BORDER:
- apply_border_op (program, op);
+ apply_border_op (program, ptr);
break;
case OP_CHANGE_BORDER_WIDTH:
- apply_border_width_op (program, op);
+ apply_border_width_op (program, ptr);
break;
case OP_CHANGE_UNBLURRED_OUTSET_SHADOW:
- apply_unblurred_outset_shadow_op (program, op);
+ apply_unblurred_outset_shadow_op (program, ptr);
break;
case OP_CHANGE_REPEAT:
- apply_repeat_op (program, op);
+ apply_repeat_op (program, ptr);
break;
case OP_DRAW:
- OP_PRINT (" -> draw %ld, size %ld and program %d\n",
- op->draw.vao_offset, op->draw.vao_size, program->index);
- glDrawArrays (GL_TRIANGLES, op->draw.vao_offset, op->draw.vao_size);
- break;
+ {
+ const OpDraw *op = ptr;
+
+ OP_PRINT (" -> draw %ld, size %ld and program %d\n",
+ op->vao_offset, op->vao_size, program->index);
+ glDrawArrays (GL_TRIANGLES, op->vao_offset, op->vao_size);
+ break;
+ }
case OP_DUMP_FRAMEBUFFER:
- dump_framebuffer (op->dump.filename, op->dump.width, op->dump.height);
- break;
+ {
+ const OpDumpFrameBuffer *op = ptr;
+
+ dump_framebuffer (op->filename, op->width, op->height);
+ break;
+ }
case OP_PUSH_DEBUG_GROUP:
- gdk_gl_context_push_debug_group (self->gl_context, op->debug_group.text);
- break;
+ {
+ const OpDebugGroup *op = ptr;
+ gdk_gl_context_push_debug_group (self->gl_context, op->text);
+ break;
+ }
case OP_POP_DEBUG_GROUP:
gdk_gl_context_pop_debug_group (self->gl_context);
break;
+ case OP_CHANGE_VAO:
+ case OP_NONE:
+ case OP_LAST:
default:
g_warn_if_reached ();
}
@@ -3462,11 +3481,8 @@ gsk_gl_renderer_init (GskGLRenderer *self)
{
gsk_ensure_resources ();
- self->render_ops = g_array_new (FALSE, FALSE, sizeof (RenderOp));
-
ops_init (&self->op_builder);
self->op_builder.renderer = self;
- self->op_builder.render_ops = self->render_ops;
#ifdef G_ENABLE_DEBUG
{
diff --git a/gsk/gl/gskglrenderops.c b/gsk/gl/gskglrenderops.c
index f7105f202a..663403aa2b 100644
--- a/gsk/gl/gskglrenderops.c
+++ b/gsk/gl/gskglrenderops.c
@@ -57,23 +57,23 @@ ops_dump_framebuffer (RenderOpBuilder *builder,
int width,
int height)
{
- RenderOp *op;
+ OpDumpFrameBuffer *op;
op = ops_begin (builder, OP_DUMP_FRAMEBUFFER);
- op->dump.filename = g_strdup (filename);
- op->dump.width = width;
- op->dump.height = height;
+ op->filename = g_strdup (filename);
+ op->width = width;
+ op->height = height;
}
void
ops_push_debug_group (RenderOpBuilder *builder,
const char *text)
{
- RenderOp *op;
+ OpDebugGroup *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 */
+ strncpy (op->text, text, sizeof(op->text) - 1);
+ op->text[sizeof(op->text) - 1] = 0; /* Ensure zero terminated */
}
void
@@ -182,6 +182,8 @@ ops_init (RenderOpBuilder *builder)
builder->current_opacity = 1.0f;
+ op_buffer_init (&builder->render_ops);
+
for (i = 0; i < GL_N_PROGRAMS; i ++)
{
builder->program_state[i].opacity = 1.0f;
@@ -197,6 +199,8 @@ ops_free (RenderOpBuilder *builder)
{
gsk_transform_unref (builder->program_state[i].modelview);
}
+
+ op_buffer_destroy (&builder->render_ops);
}
void
@@ -208,7 +212,7 @@ 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;
+ OpProgram *op;
ProgramState *program_state;
if (builder->current_program == program)
@@ -225,16 +229,20 @@ 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 = ops_begin (builder, OP_CHANGE_PROJECTION);
- op->projection = builder->current_projection;
+ OpMatrix *opm;
+
+ opm = ops_begin (builder, OP_CHANGE_PROJECTION);
+ opm->matrix = builder->current_projection;
program_state->projection = builder->current_projection;
}
if (program_state->modelview == NULL ||
!gsk_transform_equal (builder->current_modelview, program_state->modelview))
{
- op = ops_begin (builder, OP_CHANGE_MODELVIEW);
- gsk_transform_to_matrix (builder->current_modelview, &op->modelview);
+ OpMatrix *opm;
+
+ opm = ops_begin (builder, OP_CHANGE_MODELVIEW);
+ gsk_transform_to_matrix (builder->current_modelview, &opm->matrix);
gsk_transform_unref (program_state->modelview);
program_state->modelview = gsk_transform_ref (builder->current_modelview);
}
@@ -242,23 +250,29 @@ ops_set_program (RenderOpBuilder *builder,
if (rect_equal (&empty_rect, &program_state->viewport) ||
!rect_equal (&builder->current_viewport, &program_state->viewport))
{
- op = ops_begin (builder, OP_CHANGE_VIEWPORT);
- op->viewport = builder->current_viewport;
+ OpViewport *opv;
+
+ opv = ops_begin (builder, OP_CHANGE_VIEWPORT);
+ opv->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 = ops_begin (builder, OP_CHANGE_CLIP);
- op->clip = *builder->current_clip;
+ OpClip *opc;
+
+ opc = ops_begin (builder, OP_CHANGE_CLIP);
+ opc->clip = *builder->current_clip;
program_state->clip = *builder->current_clip;
}
if (program_state->opacity != builder->current_opacity)
{
- op = ops_begin (builder, OP_CHANGE_OPACITY);
- op->opacity = builder->current_opacity;
+ OpOpacity *opo;
+
+ opo = ops_begin (builder, OP_CHANGE_OPACITY);
+ opo->opacity = builder->current_opacity;
program_state->opacity = builder->current_opacity;
}
}
@@ -267,29 +281,17 @@ static void
ops_set_clip (RenderOpBuilder *builder,
const GskRoundedRect *clip)
{
- RenderOp *last_op;
ProgramState *current_program_state = get_current_program_state (builder);
+ OpClip *op;
if (current_program_state &&
memcmp (¤t_program_state->clip, clip,sizeof (GskRoundedRect)) == 0)
return;
- if (builder->render_ops->len > 0)
- {
- last_op = &g_array_index (builder->render_ops, RenderOp, builder->render_ops->len - 1);
-
- if (last_op->op == OP_CHANGE_CLIP)
- {
- last_op->clip = *clip;
- }
- else
- {
- RenderOp *op;
-
- op = ops_begin (builder, OP_CHANGE_CLIP);
- op->clip = *clip;
- }
- }
+ if (!(op = op_buffer_peek_tail_checked (&builder->render_ops, OP_CHANGE_CLIP)))
+ op = op_buffer_add (&builder->render_ops, OP_CHANGE_CLIP);
+
+ op->clip = *clip;
if (builder->current_program != NULL)
current_program_state->clip = *clip;
@@ -343,8 +345,8 @@ ops_set_modelview_internal (RenderOpBuilder *builder,
GskTransform *transform)
{
ProgramState *current_program_state = get_current_program_state (builder);
- RenderOp *op;
graphene_matrix_t matrix;
+ OpMatrix *op;
#if 0
XXX This is not possible if we want pop() to work.
@@ -355,24 +357,10 @@ ops_set_modelview_internal (RenderOpBuilder *builder,
gsk_transform_to_matrix (transform, &matrix);
- if (builder->render_ops->len > 0)
- {
- RenderOp *last_op = &g_array_index (builder->render_ops, RenderOp, builder->render_ops->len - 1);
- if (last_op->op == OP_CHANGE_MODELVIEW)
- {
- last_op->modelview = matrix;
- }
- else
- {
- op = ops_begin (builder, OP_CHANGE_MODELVIEW);
- op->modelview = matrix;
- }
- }
- else
- {
- op = ops_begin (builder, OP_CHANGE_MODELVIEW);
- op->modelview = matrix;
- }
+ if (!(op = op_buffer_peek_tail_checked (&builder->render_ops, OP_CHANGE_MODELVIEW)))
+ op = op_buffer_add (&builder->render_ops, OP_CHANGE_MODELVIEW);
+
+ op->matrix = matrix;
if (builder->current_program != NULL)
{
@@ -490,27 +478,13 @@ ops_set_projection (RenderOpBuilder *builder,
const graphene_matrix_t *projection)
{
ProgramState *current_program_state = get_current_program_state (builder);
- RenderOp *op;
graphene_matrix_t prev_mv;
+ OpMatrix *op;
- if (builder->render_ops->len > 0)
- {
- RenderOp *last_op = &g_array_index (builder->render_ops, RenderOp, builder->render_ops->len - 1);
- if (last_op->op == OP_CHANGE_PROJECTION)
- {
- last_op->projection = *projection;
- }
- else
- {
- op = ops_begin (builder, OP_CHANGE_PROJECTION);
- op->projection = *projection;
- }
- }
- else
- {
- op = ops_begin (builder, OP_CHANGE_PROJECTION);
- op->projection = *projection;
- }
+ if (!(op = op_buffer_peek_tail_checked (&builder->render_ops, OP_CHANGE_PROJECTION)))
+ op = op_buffer_add (&builder->render_ops, OP_CHANGE_PROJECTION);
+
+ op->matrix = *projection;
if (builder->current_program != NULL)
current_program_state->projection = *projection;
@@ -526,7 +500,7 @@ ops_set_viewport (RenderOpBuilder *builder,
const graphene_rect_t *viewport)
{
ProgramState *current_program_state = get_current_program_state (builder);
- RenderOp *op;
+ OpViewport *op;
graphene_rect_t prev_viewport;
if (current_program_state != NULL &&
@@ -549,7 +523,7 @@ void
ops_set_texture (RenderOpBuilder *builder,
int texture_id)
{
- RenderOp *op;
+ OpTexture *op;
if (builder->current_texture == texture_id)
return;
@@ -563,7 +537,7 @@ int
ops_set_render_target (RenderOpBuilder *builder,
int render_target_id)
{
- RenderOp *op;
+ OpRenderTarget *op;
int prev_render_target;
if (builder->current_render_target == render_target_id)
@@ -571,24 +545,10 @@ ops_set_render_target (RenderOpBuilder *builder,
prev_render_target = builder->current_render_target;
- if (builder->render_ops->len > 0)
- {
- RenderOp *last_op = &g_array_index (builder->render_ops, RenderOp, builder->render_ops->len - 1);
- if (last_op->op == OP_CHANGE_RENDER_TARGET)
- {
- last_op->render_target_id = render_target_id;
- }
- else
- {
- op = ops_begin (builder, OP_CHANGE_RENDER_TARGET);
- op->render_target_id = render_target_id;
- }
- }
- else
- {
- op = ops_begin (builder, OP_CHANGE_RENDER_TARGET);
- op->render_target_id = render_target_id;
- }
+ if (!(op = op_buffer_peek_tail_checked (&builder->render_ops, OP_CHANGE_RENDER_TARGET)))
+ op = op_buffer_add (&builder->render_ops, OP_CHANGE_RENDER_TARGET);
+
+ op->render_target_id = render_target_id;
builder->current_render_target = render_target_id;
@@ -600,32 +560,16 @@ ops_set_opacity (RenderOpBuilder *builder,
float opacity)
{
ProgramState *current_program_state = get_current_program_state (builder);
- RenderOp *op;
+ OpOpacity *op;
float prev_opacity;
- RenderOp *last_op;
if (builder->current_opacity == opacity)
return opacity;
- if (builder->render_ops->len > 0)
- {
- last_op = &g_array_index (builder->render_ops, RenderOp, builder->render_ops->len - 1);
-
- if (last_op->op == OP_CHANGE_OPACITY)
- {
- last_op->opacity = opacity;
- }
- else
- {
- op = ops_begin (builder, OP_CHANGE_OPACITY);
- op->opacity = opacity;
- }
- }
- else
- {
- op = ops_begin (builder, OP_CHANGE_OPACITY);
- op->opacity = opacity;
- }
+ if (!(op = op_buffer_peek_tail_checked (&builder->render_ops, OP_CHANGE_OPACITY)))
+ op = op_buffer_add (&builder->render_ops, OP_CHANGE_OPACITY);
+
+ op->opacity = opacity;
prev_opacity = builder->current_opacity;
builder->current_opacity = opacity;
@@ -641,7 +585,7 @@ ops_set_color (RenderOpBuilder *builder,
const GdkRGBA *color)
{
ProgramState *current_program_state = get_current_program_state (builder);
- RenderOp *op;
+ OpColor *op;
if (gdk_rgba_equal (color, ¤t_program_state->color))
return;
@@ -649,7 +593,7 @@ ops_set_color (RenderOpBuilder *builder,
current_program_state->color = *color;
op = ops_begin (builder, OP_CHANGE_COLOR);
- op->color = *color;
+ op->rgba = *color;
}
void
@@ -658,7 +602,7 @@ ops_set_color_matrix (RenderOpBuilder *builder,
const graphene_vec4_t *offset)
{
ProgramState *current_program_state = get_current_program_state (builder);
- RenderOp *op;
+ OpColorMatrix *op;
if (memcmp (matrix,
¤t_program_state->color_matrix.matrix,
@@ -672,8 +616,8 @@ ops_set_color_matrix (RenderOpBuilder *builder,
current_program_state->color_matrix.offset = *offset;
op = ops_begin (builder, OP_CHANGE_COLOR_MATRIX);
- op->color_matrix.matrix = *matrix;
- op->color_matrix.offset = *offset;
+ op->matrix = *matrix;
+ op->offset = *offset;
}
void
@@ -681,7 +625,7 @@ ops_set_border (RenderOpBuilder *builder,
const GskRoundedRect *outline)
{
ProgramState *current_program_state = get_current_program_state (builder);
- RenderOp *op;
+ OpBorder *op;
if (memcmp (¤t_program_state->border.outline,
outline, sizeof (GskRoundedRect)) == 0)
@@ -690,7 +634,7 @@ ops_set_border (RenderOpBuilder *builder,
current_program_state->border.outline = *outline;
op = ops_begin (builder, OP_CHANGE_BORDER);
- op->border.outline = *outline;
+ op->outline = *outline;
}
void
@@ -698,7 +642,7 @@ ops_set_border_width (RenderOpBuilder *builder,
const float *widths)
{
ProgramState *current_program_state = get_current_program_state (builder);
- RenderOp *op;
+ OpBorder *op;
if (memcmp (current_program_state->border.widths,
widths, sizeof (float) * 4) == 0)
@@ -708,10 +652,10 @@ ops_set_border_width (RenderOpBuilder *builder,
widths, sizeof (float) * 4);
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];
+ op->widths[0] = widths[0];
+ op->widths[1] = widths[1];
+ op->widths[2] = widths[2];
+ op->widths[3] = widths[3];
}
void
@@ -719,64 +663,50 @@ ops_set_border_color (RenderOpBuilder *builder,
const GdkRGBA *color)
{
ProgramState *current_program_state = get_current_program_state (builder);
- RenderOp op;
- op.op = OP_CHANGE_BORDER_COLOR;
- rgba_to_float (color, op.border.color);
+ OpBorder *op;
+ float fcolor[4];
- if (memcmp (&op.border.color, ¤t_program_state->border.color,
- sizeof (float) * 4) == 0)
- return;
+ rgba_to_float (color, fcolor);
- rgba_to_float (color, current_program_state->border.color);
+ if (memcmp (fcolor, ¤t_program_state->border.color, sizeof fcolor) == 0)
+ return;
- g_array_append_val (builder->render_ops, op);
+ op = op_buffer_add (&builder->render_ops, OP_CHANGE_BORDER_COLOR);
+ memcpy (op->color, fcolor, sizeof (float[4]));
+ memcpy (current_program_state->border.color, fcolor, sizeof (float[4]));
}
void
ops_draw (RenderOpBuilder *builder,
const GskQuadVertex vertex_data[GL_N_VERTICES])
{
- RenderOp *last_op;
+ OpDraw *op;
+ OpVao *vao;
- last_op = &g_array_index (builder->render_ops, RenderOp, builder->render_ops->len - 1);
- /* If the previous op was a DRAW as well, we didn't change anything between the two calls,
- * so these are just 2 subsequent draw calls. Same VAO, same program etc.
- * And the offsets into the vao are in order as well, so make it one draw call. */
- if (last_op->op == OP_DRAW)
+ if ((op = op_buffer_peek_tail_checked (&builder->render_ops, OP_DRAW)))
{
- /* 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;
+ gsize old_vao_offset = op->vao_offset;
+ gsize old_vao_size = op->vao_size;
- new_draw = ops_begin (builder, OP_DRAW);
+ op_buffer_pop_tail (&builder->render_ops);
- /* last_op may have moved in memory */
- last_op = &g_array_index (builder->render_ops, RenderOp, builder->render_ops->len - 2);
+ vao = op_buffer_add (&builder->render_ops, OP_CHANGE_VAO);
+ memcpy (vao->vertex_data, vertex_data, sizeof vao->vertex_data);
- 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);
+ op = op_buffer_add (&builder->render_ops, OP_DRAW);
+ op->vao_offset = old_vao_offset;
+ op->vao_size = old_vao_size + GL_N_VERTICES;
}
else
{
- const gsize n_ops = builder->render_ops->len;
- RenderOp *op;
gsize offset = builder->buffer_size / sizeof (GskQuadVertex);
- /* We will add two render ops here. */
- g_array_set_size (builder->render_ops, n_ops + 2);
-
- op = &g_array_index (builder->render_ops, RenderOp, n_ops);
- op->op = OP_CHANGE_VAO;
- memcpy (&op->vertex_data, vertex_data, sizeof(GskQuadVertex) * GL_N_VERTICES);
+ vao = op_buffer_add (&builder->render_ops, OP_CHANGE_VAO);
+ memcpy (vao->vertex_data, vertex_data, sizeof vao->vertex_data);
- op = &g_array_index (builder->render_ops, RenderOp, n_ops + 1);
- op->op = OP_DRAW;
- op->draw.vao_offset = offset;
- op->draw.vao_size = GL_N_VERTICES;
+ op = op_buffer_add (&builder->render_ops, OP_DRAW);
+ op->vao_offset = offset;
+ op->vao_size = GL_N_VERTICES;
}
/* We added new vertex data in both cases so increase the buffer size */
@@ -795,15 +725,21 @@ ops_offset (RenderOpBuilder *builder,
builder->dy += y;
}
-RenderOp *
+gpointer
ops_begin (RenderOpBuilder *builder,
- guint kind)
+ OpKind kind)
{
- RenderOp *op;
+ return op_buffer_add (&builder->render_ops, kind);
+}
- 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;
+void
+ops_reset (RenderOpBuilder *builder)
+{
+ op_buffer_clear (&builder->render_ops);
+}
- return op;
+OpBuffer *
+ops_get_buffer (RenderOpBuilder *builder)
+{
+ return &builder->render_ops;
}
diff --git a/gsk/gl/gskglrenderopsprivate.h b/gsk/gl/gskglrenderopsprivate.h
index 91ff2faa88..85765ad44f 100644
--- a/gsk/gl/gskglrenderopsprivate.h
+++ b/gsk/gl/gskglrenderopsprivate.h
@@ -10,6 +10,8 @@
#include "gskglrenderer.h"
#include "gskrendernodeprivate.h"
+#include "opbuffer.h"
+
#define GL_N_VERTICES 6
#define GL_N_PROGRAMS 13
@@ -32,38 +34,7 @@ typedef struct
OpsMatrixMetadata metadata;
} MatrixStackEntry;
-enum {
- OP_NONE,
- OP_CHANGE_OPACITY = 1,
- OP_CHANGE_COLOR = 2,
- OP_CHANGE_PROJECTION = 3,
- OP_CHANGE_MODELVIEW = 4,
- OP_CHANGE_PROGRAM = 5,
- OP_CHANGE_RENDER_TARGET = 6,
- OP_CHANGE_CLIP = 7,
- OP_CHANGE_VIEWPORT = 8,
- OP_CHANGE_SOURCE_TEXTURE = 9,
- OP_CHANGE_VAO = 10,
- OP_CHANGE_LINEAR_GRADIENT = 11,
- OP_CHANGE_COLOR_MATRIX = 12,
- OP_CHANGE_BLUR = 13,
- OP_CHANGE_INSET_SHADOW = 14,
- OP_CHANGE_OUTSET_SHADOW = 15,
- OP_CHANGE_BORDER = 16,
- OP_CHANGE_BORDER_COLOR = 17,
- OP_CHANGE_BORDER_WIDTH = 18,
- OP_CHANGE_CROSS_FADE = 19,
- OP_CHANGE_UNBLURRED_OUTSET_SHADOW = 20,
- OP_CLEAR = 21,
- OP_DRAW = 22,
- OP_DUMP_FRAMEBUFFER = 23,
- OP_PUSH_DEBUG_GROUP = 24,
- OP_POP_DEBUG_GROUP = 25,
- OP_CHANGE_BLEND = 26,
- OP_CHANGE_REPEAT = 27,
-};
-
-typedef struct
+struct _Program
{
int index; /* Into the renderer's program array */
@@ -145,101 +116,7 @@ typedef struct
int texture_rect_location;
} repeat;
};
-
-} Program;
-
-typedef struct
-{
- guint op;
-
- union {
- float opacity;
- graphene_matrix_t modelview;
- graphene_matrix_t projection;
- const Program *program;
- int texture_id;
- int render_target_id;
- GdkRGBA color;
- GskQuadVertex vertex_data[6];
- GskRoundedRect clip;
- graphene_rect_t viewport;
- struct {
- int n_color_stops;
- float color_offsets[8];
- float color_stops[4 * 8];
- graphene_point_t start_point;
- graphene_point_t end_point;
- } linear_gradient;
- struct {
- gsize vao_offset;
- gsize vao_size;
- } draw;
- struct {
- graphene_matrix_t matrix;
- graphene_vec4_t offset;
- } color_matrix;
- struct {
- float radius;
- graphene_size_t size;
- float dir[2];
- } blur;
- struct {
- float outline[4];
- float corner_widths[4];
- float corner_heights[4];
- float radius;
- float spread;
- float offset[2];
- float color[4];
- } inset_shadow;
- struct {
- float outline[4];
- float corner_widths[4];
- float corner_heights[4];
- float radius;
- float spread;
- float offset[2];
- float color[4];
- } outset_shadow;
- struct {
- float outline[4];
- float corner_widths[4];
- float corner_heights[4];
- float radius;
- float spread;
- float offset[2];
- float color[4];
- } unblurred_outset_shadow;
- struct {
- float color[4];
- } shadow;
- struct {
- float widths[4];
- float color[4];
- GskRoundedRect outline;
- } border;
- struct {
- float progress;
- int source2;
- } cross_fade;
- struct {
- int source2;
- int mode;
- } blend;
- struct {
- float child_bounds[4];
- float texture_rect[4];
- } repeat;
- struct {
- char *filename;
- int width;
- int height;
- } dump;
- struct {
- char text[180]; /* Size of linear_gradient, so 'should be enough' without growing RenderOp */
- } debug_group;
- };
-} RenderOp;
+};
typedef struct
{
@@ -278,7 +155,8 @@ typedef struct
gsize buffer_size;
- GArray *render_ops;
+ OpBuffer render_ops;
+
GskGLRenderer *renderer;
/* Stack of modelview matrices */
@@ -298,6 +176,7 @@ void ops_dump_framebuffer (RenderOpBuilder *builder,
int height);
void ops_init (RenderOpBuilder *builder);
void ops_free (RenderOpBuilder *builder);
+void ops_reset (RenderOpBuilder *builder);
void ops_push_debug_group (RenderOpBuilder *builder,
const char *text);
void ops_pop_debug_group (RenderOpBuilder *builder);
@@ -358,7 +237,8 @@ void ops_offset (RenderOpBuilder *builder,
float x,
float y);
-RenderOp *ops_begin (RenderOpBuilder *builder,
- guint kind);
+gpointer ops_begin (RenderOpBuilder *builder,
+ OpKind kind);
+OpBuffer *ops_get_buffer (RenderOpBuilder *builder);
#endif
diff --git a/gsk/gl/opbuffer.c b/gsk/gl/opbuffer.c
new file mode 100644
index 0000000000..2d3b16ffb6
--- /dev/null
+++ b/gsk/gl/opbuffer.c
@@ -0,0 +1,134 @@
+#include "opbuffer.h"
+
+#include <string.h>
+
+static guint op_sizes[OP_LAST] = {
+ 0,
+ sizeof (OpOpacity),
+ sizeof (OpColor),
+ sizeof (OpMatrix),
+ sizeof (OpMatrix),
+ sizeof (OpProgram),
+ sizeof (OpRenderTarget),
+ sizeof (OpClip),
+ sizeof (OpViewport),
+ sizeof (OpTexture),
+ sizeof (OpVao),
+ sizeof (OpLinearGradient),
+ sizeof (OpColorMatrix),
+ sizeof (OpBlur),
+ sizeof (OpShadow),
+ sizeof (OpShadow),
+ sizeof (OpBorder),
+ sizeof (OpBorder),
+ sizeof (OpBorder),
+ sizeof (OpCrossFade),
+ sizeof (OpShadow),
+ 0,
+ sizeof (OpDraw),
+ sizeof (OpDumpFrameBuffer),
+ sizeof (OpDebugGroup),
+ 0,
+ sizeof (OpBlend),
+ sizeof (OpRepeat),
+};
+
+void
+op_buffer_init (OpBuffer *buffer)
+{
+ static gsize initialized = FALSE;
+
+ if (g_once_init_enter (&initialized))
+ {
+ guint i;
+
+ for (i = 0; i < G_N_ELEMENTS (op_sizes); i++)
+ {
+ guint size = op_sizes[i];
+
+ if (size > 0)
+ {
+ /* Round all op entry sizes to the nearest 16 to ensure
+ * that we guarantee proper alignments for all op entries.
+ * This is only done once on first use.
+ */
+#define CHECK_SIZE(s) else if (size < (s)) { size = s; }
+ if (0) {}
+ CHECK_SIZE (16)
+ CHECK_SIZE (32)
+ CHECK_SIZE (48)
+ CHECK_SIZE (64)
+ CHECK_SIZE (80)
+ CHECK_SIZE (96)
+ CHECK_SIZE (112)
+ CHECK_SIZE (128)
+ CHECK_SIZE (144)
+ CHECK_SIZE (160)
+ CHECK_SIZE (176)
+ CHECK_SIZE (192)
+ else g_assert_not_reached ();
+#undef CHECK_SIZE
+
+ op_sizes[i] = size;
+ }
+ }
+
+ g_once_init_leave (&initialized, TRUE);
+ }
+
+ memset (buffer, 0, sizeof *buffer);
+
+ buffer->buflen = 4096;
+ buffer->bufpos = 0;
+ buffer->buf = g_malloc (buffer->buflen);
+ buffer->index = g_array_new (FALSE, FALSE, sizeof (OpBufferEntry));
+
+ /* Add dummy entry to guarantee non-empty index */
+ op_buffer_add (buffer, OP_NONE);
+}
+
+void
+op_buffer_destroy (OpBuffer *buffer)
+{
+ g_free (buffer->buf);
+ g_array_unref (buffer->index);
+}
+
+void
+op_buffer_clear (OpBuffer *buffer)
+{
+ if (buffer->index->len > 1)
+ g_array_remove_range (buffer->index, 1, buffer->index->len - 1);
+ buffer->bufpos = 0;
+}
+
+static inline void
+ensure_buffer_space_for (OpBuffer *buffer,
+ guint size)
+{
+ if G_UNLIKELY (buffer->bufpos + size >= buffer->buflen)
+ {
+ buffer->buflen *= 2;
+ buffer->buf = g_realloc (buffer->buf, buffer->buflen);
+ }
+}
+
+gpointer
+op_buffer_add (OpBuffer *buffer,
+ OpKind kind)
+{
+ guint size = op_sizes[kind];
+ OpBufferEntry entry;
+
+ entry.pos = buffer->bufpos;
+ entry.kind = kind;
+
+ if (size > 0)
+ ensure_buffer_space_for (buffer, size);
+
+ g_array_append_val (buffer->index, entry);
+
+ buffer->bufpos += size;
+
+ return &buffer->buf[entry.pos];
+}
diff --git a/gsk/gl/opbuffer.h b/gsk/gl/opbuffer.h
new file mode 100644
index 0000000000..d777e2ae41
--- /dev/null
+++ b/gsk/gl/opbuffer.h
@@ -0,0 +1,263 @@
+#ifndef __OP_BUFFER_H__
+#define __OP_BUFFER_H__
+
+#include <gdk/gdk.h>
+#include <gsk/gsk.h>
+#include <graphene.h>
+
+#include "gskgldriverprivate.h"
+
+typedef struct _Program Program;
+
+typedef enum
+{
+ OP_NONE = 0,
+ OP_CHANGE_OPACITY = 1,
+ OP_CHANGE_COLOR = 2,
+ OP_CHANGE_PROJECTION = 3,
+ OP_CHANGE_MODELVIEW = 4,
+ OP_CHANGE_PROGRAM = 5,
+ OP_CHANGE_RENDER_TARGET = 6,
+ OP_CHANGE_CLIP = 7,
+ OP_CHANGE_VIEWPORT = 8,
+ OP_CHANGE_SOURCE_TEXTURE = 9,
+ OP_CHANGE_VAO = 10,
+ OP_CHANGE_LINEAR_GRADIENT = 11,
+ OP_CHANGE_COLOR_MATRIX = 12,
+ OP_CHANGE_BLUR = 13,
+ OP_CHANGE_INSET_SHADOW = 14,
+ OP_CHANGE_OUTSET_SHADOW = 15,
+ OP_CHANGE_BORDER = 16,
+ OP_CHANGE_BORDER_COLOR = 17,
+ OP_CHANGE_BORDER_WIDTH = 18,
+ OP_CHANGE_CROSS_FADE = 19,
+ OP_CHANGE_UNBLURRED_OUTSET_SHADOW = 20,
+ OP_CLEAR = 21,
+ OP_DRAW = 22,
+ OP_DUMP_FRAMEBUFFER = 23,
+ OP_PUSH_DEBUG_GROUP = 24,
+ OP_POP_DEBUG_GROUP = 25,
+ OP_CHANGE_BLEND = 26,
+ OP_CHANGE_REPEAT = 27,
+ OP_LAST
+} OpKind;
+
+/* OpNode are allocated within OpBuffer.pos, but we keep
+ * a secondary index into the locations of that buffer
+ * from OpBuffer.index. This allows peeking at the kind
+ * and quickly replacing existing entries when necessary.
+ */
+typedef struct
+{
+ guint pos;
+ OpKind kind;
+} OpBufferEntry;
+
+typedef struct
+{
+ guint8 *buf;
+ gsize buflen;
+ gsize bufpos;
+ GArray *index;
+} OpBuffer;
+
+typedef struct
+{
+ float opacity;
+} OpOpacity;
+
+typedef struct
+{
+ graphene_matrix_t matrix;
+} OpMatrix;
+
+typedef struct
+{
+ const Program *program;
+} OpProgram;
+
+typedef struct
+{
+ GdkRGBA rgba;
+} OpColor;
+
+typedef struct
+{
+ int render_target_id;
+} OpRenderTarget;
+
+typedef struct
+{
+ GskRoundedRect clip;
+} OpClip;
+
+typedef struct
+{
+ graphene_rect_t viewport;
+} OpViewport;
+
+typedef struct
+{
+ int texture_id;
+} OpTexture;
+
+typedef struct
+{
+ gsize vao_offset;
+ gsize vao_size;
+} OpDraw;
+
+typedef struct
+{
+ GskQuadVertex vertex_data[6];
+} OpVao;
+
+typedef struct
+{
+ float color_offsets[8];
+ float color_stops[4 * 8];
+ graphene_point_t start_point;
+ graphene_point_t end_point;
+ int n_color_stops;
+} OpLinearGradient;
+
+typedef struct
+{
+ graphene_matrix_t matrix;
+ graphene_vec4_t offset;
+} OpColorMatrix;
+
+typedef struct
+{
+ float radius;
+ graphene_size_t size;
+ float dir[2];
+} OpBlur;
+
+typedef struct
+{
+ float outline[4];
+ float corner_widths[4];
+ float corner_heights[4];
+ float radius;
+ float spread;
+ float offset[2];
+ float color[4];
+} OpShadow;
+
+typedef struct
+{
+ float widths[4];
+ float color[4];
+ GskRoundedRect outline;
+} OpBorder;
+
+typedef struct
+{
+ float progress;
+ int source2;
+} OpCrossFade;
+
+typedef struct
+{
+ char *filename;
+ int width;
+ int height;
+} OpDumpFrameBuffer;
+
+typedef struct
+{
+ char text[64];
+} OpDebugGroup;
+
+typedef struct
+{
+ int source2;
+ int mode;
+} OpBlend;
+
+typedef struct
+{
+ float child_bounds[4];
+ float texture_rect[4];
+} OpRepeat;
+
+void op_buffer_init (OpBuffer *buffer);
+void op_buffer_destroy (OpBuffer *buffer);
+void op_buffer_clear (OpBuffer *buffer);
+gpointer op_buffer_add (OpBuffer *buffer,
+ OpKind kind);
+
+typedef struct
+{
+ GArray *index;
+ OpBuffer *buffer;
+ guint pos;
+} OpBufferIter;
+
+static inline void
+op_buffer_iter_init (OpBufferIter *iter,
+ OpBuffer *buffer)
+{
+ iter->index = buffer->index;
+ iter->buffer = buffer;
+ iter->pos = 1; /* Skip first OP_NONE */
+}
+
+static inline gpointer
+op_buffer_iter_next (OpBufferIter *iter,
+ OpKind *kind)
+{
+ const OpBufferEntry *entry;
+
+ if (iter->pos == iter->index->len)
+ return NULL;
+
+ entry = &g_array_index (iter->index, OpBufferEntry, iter->pos);
+
+ iter->pos++;
+
+ *kind = entry->kind;
+ return &iter->buffer->buf[entry->pos];
+}
+
+static inline void
+op_buffer_pop_tail (OpBuffer *buffer)
+{
+ /* Never truncate the first OP_NONE */
+ if G_LIKELY (buffer->index->len > 0)
+ buffer->index->len--;
+}
+
+static inline gpointer
+op_buffer_peek_tail (OpBuffer *buffer,
+ OpKind *kind)
+{
+ const OpBufferEntry *entry;
+
+ entry = &g_array_index (buffer->index, OpBufferEntry, buffer->index->len - 1);
+ *kind = entry->kind;
+ return &buffer->buf[entry->pos];
+}
+
+static inline gpointer
+op_buffer_peek_tail_checked (OpBuffer *buffer,
+ OpKind kind)
+{
+ const OpBufferEntry *entry;
+
+ entry = &g_array_index (buffer->index, OpBufferEntry, buffer->index->len - 1);
+
+ if (entry->kind == kind)
+ return &buffer->buf[entry->pos];
+
+ return NULL;
+}
+
+static inline guint
+op_buffer_n_ops (OpBuffer *buffer)
+{
+ return buffer->index->len - 1;
+}
+
+#endif /* __OP_BUFFER_H__ */
diff --git a/gsk/meson.build b/gsk/meson.build
index 6819ac5426..ed621284bb 100644
--- a/gsk/meson.build
+++ b/gsk/meson.build
@@ -48,6 +48,7 @@ gsk_private_sources = files([
'gl/gskglnodesample.c',
'gl/gskgltextureatlas.c',
'gl/gskgliconcache.c',
+ 'gl/opbuffer.c',
'gl/stb_rect_pack.c',
])
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]