gl renderer: Fall back to cairo if gradients use too many stops

This commit is contained in:
Timm Bäder 2020-09-21 21:19:19 +02:00
parent 12cc178756
commit 8d7b3bade3
3 changed files with 51 additions and 35 deletions

View File

@ -1175,21 +1175,29 @@ render_linear_gradient_node (GskGLRenderer *self,
GskRenderNode *node, GskRenderNode *node,
RenderOpBuilder *builder) RenderOpBuilder *builder)
{ {
const int n_color_stops = MIN (8, gsk_linear_gradient_node_get_n_color_stops (node)); const int n_color_stops = gsk_linear_gradient_node_get_n_color_stops (node);
const GskColorStop *stops = gsk_linear_gradient_node_peek_color_stops (node, NULL);
const graphene_point_t *start = gsk_linear_gradient_node_peek_start (node);
const graphene_point_t *end = gsk_linear_gradient_node_peek_end (node);
ops_set_program (builder, &self->programs->linear_gradient_program); if (n_color_stops < GL_MAX_GRADIENT_STOPS)
ops_set_linear_gradient (builder, {
n_color_stops, const GskColorStop *stops = gsk_linear_gradient_node_peek_color_stops (node, NULL);
stops, const graphene_point_t *start = gsk_linear_gradient_node_peek_start (node);
builder->dx + start->x, const graphene_point_t *end = gsk_linear_gradient_node_peek_end (node);
builder->dy + start->y,
builder->dx + end->x,
builder->dy + end->y);
load_vertex_data (ops_draw (builder, NULL), node, builder); ops_set_program (builder, &self->programs->linear_gradient_program);
ops_set_linear_gradient (builder,
n_color_stops,
stops,
builder->dx + start->x,
builder->dy + start->y,
builder->dx + end->x,
builder->dy + end->y);
load_vertex_data (ops_draw (builder, NULL), node, builder);
}
else
{
render_fallback_node (self, node, builder);
}
} }
static inline void static inline void
@ -1197,25 +1205,33 @@ render_radial_gradient_node (GskGLRenderer *self,
GskRenderNode *node, GskRenderNode *node,
RenderOpBuilder *builder) RenderOpBuilder *builder)
{ {
const int n_color_stops = MIN (8, gsk_radial_gradient_node_get_n_color_stops (node)); const int n_color_stops = gsk_radial_gradient_node_get_n_color_stops (node);
const GskColorStop *stops = gsk_radial_gradient_node_peek_color_stops (node, NULL);
const graphene_point_t *center = gsk_radial_gradient_node_peek_center (node);
const float start = gsk_radial_gradient_node_get_start (node);
const float end = gsk_radial_gradient_node_get_end (node);
const float hradius = gsk_radial_gradient_node_get_hradius (node);
const float vradius = gsk_radial_gradient_node_get_vradius (node);
ops_set_program (builder, &self->programs->radial_gradient_program); if (n_color_stops < GL_MAX_GRADIENT_STOPS)
ops_set_radial_gradient (builder, {
n_color_stops, const GskColorStop *stops = gsk_radial_gradient_node_peek_color_stops (node, NULL);
stops, const graphene_point_t *center = gsk_radial_gradient_node_peek_center (node);
builder->dx + center->x, const float start = gsk_radial_gradient_node_get_start (node);
builder->dy + center->y, const float end = gsk_radial_gradient_node_get_end (node);
start, end, const float hradius = gsk_radial_gradient_node_get_hradius (node);
hradius * builder->scale_x, const float vradius = gsk_radial_gradient_node_get_vradius (node);
vradius * builder->scale_y);
load_vertex_data (ops_draw (builder, NULL), node, builder); ops_set_program (builder, &self->programs->radial_gradient_program);
ops_set_radial_gradient (builder,
n_color_stops,
stops,
builder->dx + center->x,
builder->dy + center->y,
start, end,
hradius * builder->scale_x,
vradius * builder->scale_y);
load_vertex_data (ops_draw (builder, NULL), node, builder);
}
else
{
render_fallback_node (self, node, builder);
}
} }
static inline gboolean static inline gboolean

View File

@ -909,7 +909,7 @@ ops_set_linear_gradient (RenderOpBuilder *self,
{ {
ProgramState *current_program_state = get_current_program_state (self); ProgramState *current_program_state = get_current_program_state (self);
OpLinearGradient *op; OpLinearGradient *op;
const guint real_n_color_stops = MIN (MAX_GRADIENT_STOPS, n_color_stops); const guint real_n_color_stops = MIN (GL_MAX_GRADIENT_STOPS, n_color_stops);
g_assert (current_program_state); g_assert (current_program_state);
@ -972,7 +972,7 @@ ops_set_radial_gradient (RenderOpBuilder *self,
float hradius, float hradius,
float vradius) float vradius)
{ {
const guint real_n_color_stops = MIN (MAX_GRADIENT_STOPS, n_color_stops); const guint real_n_color_stops = MIN (GL_MAX_GRADIENT_STOPS, n_color_stops);
OpRadialGradient *op; OpRadialGradient *op;
/* TODO: State tracking? */ /* TODO: State tracking? */

View File

@ -14,7 +14,7 @@
#define GL_N_VERTICES 6 #define GL_N_VERTICES 6
#define GL_N_PROGRAMS 14 #define GL_N_PROGRAMS 14
#define MAX_GRADIENT_STOPS 8 #define GL_MAX_GRADIENT_STOPS 8
typedef struct typedef struct
{ {
@ -147,13 +147,13 @@ typedef struct
} unblurred_outset_shadow; } unblurred_outset_shadow;
struct { struct {
int n_color_stops; int n_color_stops;
GskColorStop color_stops[MAX_GRADIENT_STOPS]; GskColorStop color_stops[GL_MAX_GRADIENT_STOPS];
float start_point[2]; float start_point[2];
float end_point[2]; float end_point[2];
} linear_gradient; } linear_gradient;
struct { struct {
int n_color_stops; int n_color_stops;
GskColorStop color_stops[MAX_GRADIENT_STOPS]; GskColorStop color_stops[GL_MAX_GRADIENT_STOPS];
float center[2]; float center[2];
float start; float start;
float end; float end;