Compare commits
4 Commits
main
...
wip/matthi
Author | SHA1 | Date | |
---|---|---|---|
|
843537c8e7 | ||
|
0acb26a076 | ||
|
f6a36fe834 | ||
|
675cbcc1e7 |
@@ -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));
|
||||
@@ -2987,14 +2988,14 @@ add_offscreen_ops (GskGLRenderer *self,
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_gl_renderer_render_ops (GskGLRenderer *self,
|
||||
gsize vertex_data_size)
|
||||
gsk_gl_renderer_render_ops (GskGLRenderer *self)
|
||||
{
|
||||
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);
|
||||
gsize vertex_data_size = self->op_builder.vertices->len * sizeof (GskQuadVertex);
|
||||
float *vertex_data = (float*)self->op_builder.vertices->data;
|
||||
OpBufferIter iter;
|
||||
OpKind kind;
|
||||
gpointer ptr;
|
||||
|
||||
/*g_message ("%s: Buffer size: %ld", __FUNCTION__, vertex_data_size);*/
|
||||
|
||||
@@ -3006,19 +3007,6 @@ 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 ++)
|
||||
{
|
||||
const RenderOp *op = &g_array_index (self->render_ops, RenderOp, i);
|
||||
|
||||
if (op->op == OP_CHANGE_VAO)
|
||||
{
|
||||
memcpy (vertex_data + buffer_index, &op->vertex_data, sizeof (GskQuadVertex) * GL_N_VERTICES);
|
||||
buffer_index += sizeof (GskQuadVertex) * GL_N_VERTICES / sizeof (float);
|
||||
}
|
||||
}
|
||||
|
||||
// Set buffer data
|
||||
glBufferData (GL_ARRAY_BUFFER, vertex_data_size, vertex_data, GL_STATIC_DRAW);
|
||||
|
||||
@@ -3035,41 +3023,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)
|
||||
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 +3067,108 @@ 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_NONE:
|
||||
case OP_LAST:
|
||||
default:
|
||||
g_warn_if_reached ();
|
||||
}
|
||||
@@ -3174,9 +3176,6 @@ gsk_gl_renderer_render_ops (GskGLRenderer *self,
|
||||
OP_PRINT ("\n");
|
||||
}
|
||||
|
||||
/* Done drawing, destroy the buffer again.
|
||||
* TODO: Can we reuse the memory, though? */
|
||||
g_free (vertex_data);
|
||||
glDeleteVertexArrays (1, &vao_id);
|
||||
glDeleteBuffers (1, &buffer_id);
|
||||
}
|
||||
@@ -3190,7 +3189,6 @@ gsk_gl_renderer_do_render (GskRenderer *renderer,
|
||||
{
|
||||
GskGLRenderer *self = GSK_GL_RENDERER (renderer);
|
||||
graphene_matrix_t projection;
|
||||
gsize buffer_size;
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
GskProfiler *profiler;
|
||||
gint64 gpu_time, cpu_time, start_time;
|
||||
@@ -3267,7 +3265,6 @@ gsk_gl_renderer_do_render (GskRenderer *renderer,
|
||||
g_assert_cmpint (self->op_builder.current_render_target, ==, fbo_id);
|
||||
ops_pop_modelview (&self->op_builder);
|
||||
ops_pop_clip (&self->op_builder);
|
||||
buffer_size = self->op_builder.buffer_size;
|
||||
ops_finish (&self->op_builder);
|
||||
|
||||
/*g_message ("Ops: %u", self->render_ops->len);*/
|
||||
@@ -3295,7 +3292,7 @@ gsk_gl_renderer_do_render (GskRenderer *renderer,
|
||||
glBlendEquation (GL_FUNC_ADD);
|
||||
|
||||
gdk_gl_context_push_debug_group (self->gl_context, "Rendering ops");
|
||||
gsk_gl_renderer_render_ops (self, buffer_size);
|
||||
gsk_gl_renderer_render_ops (self);
|
||||
gdk_gl_context_pop_debug_group (self->gl_context);
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
@@ -3462,11 +3459,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
|
||||
{
|
||||
|
@@ -28,7 +28,6 @@ ops_finish (RenderOpBuilder *builder)
|
||||
g_array_free (builder->clip_stack, TRUE);
|
||||
builder->clip_stack = NULL;
|
||||
|
||||
builder->buffer_size = 0;
|
||||
builder->dx = 0;
|
||||
builder->dy = 0;
|
||||
builder->current_modelview = NULL;
|
||||
@@ -57,23 +56,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 +181,9 @@ ops_init (RenderOpBuilder *builder)
|
||||
|
||||
builder->current_opacity = 1.0f;
|
||||
|
||||
op_buffer_init (&builder->render_ops);
|
||||
builder->vertices = g_array_new (FALSE, TRUE, sizeof (GskQuadVertex));
|
||||
|
||||
for (i = 0; i < GL_N_PROGRAMS; i ++)
|
||||
{
|
||||
builder->program_state[i].opacity = 1.0f;
|
||||
@@ -197,6 +199,9 @@ ops_free (RenderOpBuilder *builder)
|
||||
{
|
||||
gsk_transform_unref (builder->program_state[i].modelview);
|
||||
}
|
||||
|
||||
g_array_unref (builder->vertices);
|
||||
op_buffer_destroy (&builder->render_ops);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -208,7 +213,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 +230,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 +251,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 +282,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 (!(op = op_buffer_peek_tail_checked (&builder->render_ops, OP_CHANGE_CLIP)))
|
||||
op = op_buffer_add (&builder->render_ops, OP_CHANGE_CLIP);
|
||||
|
||||
if (last_op->op == OP_CHANGE_CLIP)
|
||||
{
|
||||
last_op->clip = *clip;
|
||||
}
|
||||
else
|
||||
{
|
||||
RenderOp *op;
|
||||
|
||||
op = ops_begin (builder, OP_CHANGE_CLIP);
|
||||
op->clip = *clip;
|
||||
}
|
||||
}
|
||||
op->clip = *clip;
|
||||
|
||||
if (builder->current_program != NULL)
|
||||
current_program_state->clip = *clip;
|
||||
@@ -343,8 +346,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 +358,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 +479,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 +501,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 +524,7 @@ void
|
||||
ops_set_texture (RenderOpBuilder *builder,
|
||||
int texture_id)
|
||||
{
|
||||
RenderOp *op;
|
||||
OpTexture *op;
|
||||
|
||||
if (builder->current_texture == texture_id)
|
||||
return;
|
||||
@@ -563,7 +538,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 +546,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 +561,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 (!(op = op_buffer_peek_tail_checked (&builder->render_ops, OP_CHANGE_OPACITY)))
|
||||
op = op_buffer_add (&builder->render_ops, OP_CHANGE_OPACITY);
|
||||
|
||||
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;
|
||||
}
|
||||
op->opacity = opacity;
|
||||
|
||||
prev_opacity = builder->current_opacity;
|
||||
builder->current_opacity = opacity;
|
||||
@@ -641,7 +586,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 +594,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 +603,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 +617,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 +626,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 +635,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 +643,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 +653,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,68 +664,37 @@ 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)
|
||||
rgba_to_float (color, fcolor);
|
||||
|
||||
if (memcmp (fcolor, ¤t_program_state->border.color, sizeof fcolor) == 0)
|
||||
return;
|
||||
|
||||
rgba_to_float (color, current_program_state->border.color);
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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);
|
||||
op->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);
|
||||
|
||||
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 = builder->vertices->len;
|
||||
op->vao_size = GL_N_VERTICES;
|
||||
}
|
||||
|
||||
/* We added new vertex data in both cases so increase the buffer size */
|
||||
builder->buffer_size += sizeof (GskQuadVertex) * GL_N_VERTICES;
|
||||
g_array_append_vals (builder->vertices, vertex_data, GL_N_VERTICES);
|
||||
}
|
||||
|
||||
/* The offset is only valid for the current modelview.
|
||||
@@ -795,15 +709,22 @@ ops_offset (RenderOpBuilder *builder,
|
||||
builder->dy += y;
|
||||
}
|
||||
|
||||
RenderOp *
|
||||
gpointer
|
||||
ops_begin (RenderOpBuilder *builder,
|
||||
guint kind)
|
||||
OpKind kind)
|
||||
{
|
||||
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;
|
||||
return op_buffer_add (&builder->render_ops, kind);
|
||||
}
|
||||
|
||||
void
|
||||
ops_reset (RenderOpBuilder *builder)
|
||||
{
|
||||
op_buffer_clear (&builder->render_ops);
|
||||
g_array_set_size (builder->vertices, 0);
|
||||
}
|
||||
|
||||
OpBuffer *
|
||||
ops_get_buffer (RenderOpBuilder *builder)
|
||||
{
|
||||
return &builder->render_ops;
|
||||
}
|
||||
|
@@ -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
|
||||
{
|
||||
@@ -276,9 +153,9 @@ typedef struct
|
||||
float current_opacity;
|
||||
float dx, dy;
|
||||
|
||||
gsize buffer_size;
|
||||
OpBuffer render_ops;
|
||||
GArray *vertices;
|
||||
|
||||
GArray *render_ops;
|
||||
GskGLRenderer *renderer;
|
||||
|
||||
/* Stack of modelview matrices */
|
||||
@@ -298,6 +175,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 +236,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
|
||||
|
133
gsk/gl/opbuffer.c
Normal file
133
gsk/gl/opbuffer.c
Normal file
@@ -0,0 +1,133 @@
|
||||
#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 (OpRepeat),
|
||||
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),
|
||||
};
|
||||
|
||||
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];
|
||||
}
|
257
gsk/gl/opbuffer.h
Normal file
257
gsk/gl/opbuffer.h
Normal file
@@ -0,0 +1,257 @@
|
||||
#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_REPEAT = 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_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
|
||||
{
|
||||
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__ */
|
@@ -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',
|
||||
])
|
||||
|
||||
|
Reference in New Issue
Block a user