Compare commits
5 Commits
matthiasc/
...
wip-mask-c
Author | SHA1 | Date | |
---|---|---|---|
|
3a119bb8f7 | ||
|
3fb6eb1ce5 | ||
|
14634fafa2 | ||
|
bfcbd18209 | ||
|
268f5d123b |
@@ -70,6 +70,7 @@ style-check-diff:
|
||||
- "${CI_PROJECT_DIR}/_build/testsuite/tools/output/*/*"
|
||||
- "${CI_PROJECT_DIR}/_build/testsuite/gsk/compare/*/*/*.png"
|
||||
- "${CI_PROJECT_DIR}/_build/testsuite/css/output/*/*.syscap"
|
||||
- "${CI_PROJECT_DIR}/_build/testsuite/headless/*/*.log"
|
||||
- "${CI_PROJECT_DIR}/_build_hello/meson-logs"
|
||||
cache:
|
||||
key: "$CI_JOB_NAME"
|
||||
|
@@ -74,7 +74,7 @@ struct _GskGLBindFramebuffer
|
||||
G_STATIC_ASSERT (sizeof (GskGLBindFramebuffer) == 4);
|
||||
|
||||
/* Increase if shaders add more textures */
|
||||
#define GSK_GL_MAX_TEXTURES_PER_PROGRAM 4
|
||||
#define GSK_GL_MAX_TEXTURES_PER_PROGRAM 5
|
||||
|
||||
struct _GskGLAttachmentState
|
||||
{
|
||||
|
@@ -373,6 +373,7 @@ gsk_gl_driver_load_programs (GskGLDriver *self,
|
||||
gsk_gl_compiler_set_source (compiler, GSK_GL_COMPILER_VERTEX, NULL); \
|
||||
gsk_gl_compiler_set_source (compiler, GSK_GL_COMPILER_FRAGMENT, NULL); \
|
||||
sources \
|
||||
GSK_GL_COMPILE_PROGRAM(name ## _mask_clip, uniforms, "#define MASK_CLIP 1\n"); \
|
||||
GSK_GL_COMPILE_PROGRAM(name ## _no_clip, uniforms, "#define NO_CLIP 1\n"); \
|
||||
GSK_GL_COMPILE_PROGRAM(name ## _rect_clip, uniforms, "#define RECT_CLIP 1\n"); \
|
||||
GSK_GL_COMPILE_PROGRAM(name, uniforms, "");
|
||||
@@ -381,6 +382,7 @@ gsk_gl_driver_load_programs (GskGLDriver *self,
|
||||
GskGLProgram *program; \
|
||||
gboolean have_alpha; \
|
||||
gboolean have_source; \
|
||||
gboolean have_mask; \
|
||||
\
|
||||
if (!(program = gsk_gl_compiler_compile (compiler, #name, clip, error))) \
|
||||
goto failure; \
|
||||
@@ -391,10 +393,12 @@ gsk_gl_driver_load_programs (GskGLDriver *self,
|
||||
gsk_gl_program_add_uniform (program, "u_viewport", UNIFORM_SHARED_VIEWPORT); \
|
||||
gsk_gl_program_add_uniform (program, "u_projection", UNIFORM_SHARED_PROJECTION); \
|
||||
gsk_gl_program_add_uniform (program, "u_modelview", UNIFORM_SHARED_MODELVIEW); \
|
||||
have_mask = gsk_gl_program_add_uniform (program, "u_clip_mask", UNIFORM_SHARED_CLIP_MASK); \
|
||||
gsk_gl_program_add_uniform (program, "u_mask_mode", UNIFORM_SHARED_MASK_MODE); \
|
||||
\
|
||||
uniforms \
|
||||
\
|
||||
gsk_gl_program_uniforms_added (program, have_source); \
|
||||
gsk_gl_program_uniforms_added (program, have_source || have_mask); \
|
||||
if (have_alpha) \
|
||||
gsk_gl_program_set_uniform1f (program, UNIFORM_SHARED_ALPHA, 0, 1.0f); \
|
||||
\
|
||||
|
@@ -34,6 +34,8 @@ enum {
|
||||
UNIFORM_SHARED_VIEWPORT,
|
||||
UNIFORM_SHARED_PROJECTION,
|
||||
UNIFORM_SHARED_MODELVIEW,
|
||||
UNIFORM_SHARED_CLIP_MASK,
|
||||
UNIFORM_SHARED_MASK_MODE,
|
||||
|
||||
UNIFORM_SHARED_LAST
|
||||
};
|
||||
@@ -113,6 +115,7 @@ struct _GskGLDriver
|
||||
#define GSK_GL_NO_UNIFORMS
|
||||
#define GSK_GL_ADD_UNIFORM(pos, KEY, name)
|
||||
#define GSK_GL_DEFINE_PROGRAM(name, resource, uniforms) \
|
||||
GskGLProgram *name ## _mask_clip; \
|
||||
GskGLProgram *name ## _no_clip; \
|
||||
GskGLProgram *name ## _rect_clip; \
|
||||
GskGLProgram *name;
|
||||
|
@@ -60,11 +60,6 @@ GSK_GL_DEFINE_PROGRAM (linear_gradient,
|
||||
GSK_GL_ADD_UNIFORM (3, LINEAR_GRADIENT_POINTS, u_points)
|
||||
GSK_GL_ADD_UNIFORM (4, LINEAR_GRADIENT_REPEAT, u_repeat))
|
||||
|
||||
GSK_GL_DEFINE_PROGRAM (mask,
|
||||
GSK_GL_SHADER_SINGLE (GSK_GL_SHADER_RESOURCE ("mask.glsl")),
|
||||
GSK_GL_ADD_UNIFORM (1, MASK_SOURCE, u_mask)
|
||||
GSK_GL_ADD_UNIFORM (2, MASK_MODE, u_mode))
|
||||
|
||||
GSK_GL_DEFINE_PROGRAM (outset_shadow,
|
||||
GSK_GL_SHADER_SINGLE (GSK_GL_SHADER_RESOURCE ("outset_shadow.glsl")),
|
||||
GSK_GL_ADD_UNIFORM (1, OUTSET_SHADOW_OUTLINE_RECT, u_outline_rect))
|
||||
|
@@ -60,8 +60,11 @@ G_STATIC_ASSERT ((MAX_GRADIENT_STOPS * 5) < (1 << GSK_GL_UNIFORM_ARRAY_BITS));
|
||||
typedef struct _GskGLRenderClip
|
||||
{
|
||||
GskRoundedRect rect;
|
||||
guint is_rectilinear : 1;
|
||||
guint is_fully_contained : 1;
|
||||
unsigned int is_rectilinear : 1;
|
||||
unsigned int is_fully_contained : 1;
|
||||
unsigned int is_mask : 1;
|
||||
unsigned int mask_mode : 3;
|
||||
unsigned int mask;
|
||||
} GskGLRenderClip;
|
||||
|
||||
typedef struct _GskGLRenderModelview
|
||||
@@ -76,6 +79,14 @@ typedef struct _GskGLRenderModelview
|
||||
graphene_matrix_t matrix;
|
||||
} GskGLRenderModelview;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned int texture_id;
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
const char *name;
|
||||
} TextureToSave;
|
||||
|
||||
struct _GskGLRenderJob
|
||||
{
|
||||
/* The context containing the framebuffer we are drawing to. Generally this
|
||||
@@ -141,6 +152,10 @@ struct _GskGLRenderJob
|
||||
const GskGLRenderModelview *current_modelview;
|
||||
GskGLProgram *current_program;
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
GArray *textures_to_save;
|
||||
#endif
|
||||
|
||||
/* If we should be rendering red zones over fallback nodes */
|
||||
guint debug_fallback : 1;
|
||||
|
||||
@@ -182,6 +197,9 @@ typedef struct _GskGLRenderOffscreen
|
||||
/* Return location for whether we created a texture */
|
||||
guint was_offscreen : 1;
|
||||
guint has_mipmap : 1;
|
||||
|
||||
int texture_width;
|
||||
int texture_height;
|
||||
} GskGLRenderOffscreen;
|
||||
|
||||
static void gsk_gl_render_job_visit_node (GskGLRenderJob *job,
|
||||
@@ -645,6 +663,37 @@ gsk_gl_render_job_push_clip (GskGLRenderJob *job,
|
||||
memcpy (&clip->rect, rect, sizeof *rect);
|
||||
clip->is_rectilinear = gsk_rounded_rect_is_rectilinear (rect);
|
||||
clip->is_fully_contained = FALSE;
|
||||
clip->is_mask = FALSE;
|
||||
clip->mask_mode = 0;
|
||||
clip->mask = 0;
|
||||
|
||||
job->current_clip = clip;
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_gl_render_job_push_clip_mask (GskGLRenderJob *job,
|
||||
unsigned int mask,
|
||||
GskMaskMode mode,
|
||||
const graphene_rect_t *bounds)
|
||||
{
|
||||
GskGLRenderClip *clip;
|
||||
|
||||
g_assert (job != NULL);
|
||||
g_assert (job->clip != NULL);
|
||||
g_assert (mask != 0);
|
||||
|
||||
job->driver->stamps[UNIFORM_SHARED_CLIP_MASK]++;
|
||||
|
||||
g_array_set_size (job->clip, job->clip->len + 1);
|
||||
|
||||
clip = &g_array_index (job->clip, GskGLRenderClip, job->clip->len - 1);
|
||||
memset (&clip->rect, 0, sizeof clip->rect);
|
||||
clip->is_rectilinear = FALSE;
|
||||
clip->is_fully_contained = FALSE;
|
||||
clip->is_mask = TRUE;
|
||||
clip->mask_mode = mode;
|
||||
clip->mask = mask;
|
||||
clip->rect.bounds = *bounds;
|
||||
|
||||
job->current_clip = clip;
|
||||
}
|
||||
@@ -670,6 +719,9 @@ gsk_gl_render_job_push_contained_clip (GskGLRenderJob *job)
|
||||
memset (clip->rect.corner, 0, sizeof clip->rect.corner);
|
||||
clip->is_rectilinear = TRUE;
|
||||
clip->is_fully_contained = TRUE;
|
||||
clip->is_mask = FALSE;
|
||||
clip->mask_mode = 0;
|
||||
clip->mask = 0;
|
||||
|
||||
job->current_clip = clip;
|
||||
}
|
||||
@@ -931,6 +983,12 @@ gsk_gl_render_job_update_clip (GskGLRenderJob *job,
|
||||
|
||||
*pushed_clip = FALSE;
|
||||
|
||||
if (job->current_clip->is_mask)
|
||||
{
|
||||
/* FIXME */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (job->current_clip->is_fully_contained)
|
||||
{
|
||||
/* Already fully contained - no further checks needed */
|
||||
@@ -1095,6 +1153,27 @@ gsk_gl_render_job_draw_rect_with_color (GskGLRenderJob *job,
|
||||
bounds->size.height,
|
||||
color);
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
gsk_gl_render_job_draw_subrect_with_color (GskGLRenderJob *job,
|
||||
const graphene_rect_t *bounds,
|
||||
const graphene_rect_t *rect,
|
||||
guint16 color[4])
|
||||
{
|
||||
float min_x = job->offset_x + rect->origin.x;
|
||||
float min_y = job->offset_y + rect->origin.y;
|
||||
float max_x = min_x + rect->size.width;
|
||||
float max_y = min_y + rect->size.height;
|
||||
float min_u = (rect->origin.x - bounds->origin.x) / bounds->size.width;
|
||||
float max_u = (rect->origin.x + rect->size.width - bounds->origin.x) / bounds->size.width;
|
||||
float min_v = 1. - (rect->origin.y - bounds->origin.y) / bounds->size.height;
|
||||
float max_v = 1. - (rect->origin.y + rect->size.height - bounds->origin.y) / bounds->size.height;
|
||||
|
||||
gsk_gl_render_job_draw_coords (job, min_x, min_y, max_x, max_y, min_u, min_v, max_u, max_v, color);
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
gsk_gl_render_job_draw_rect (GskGLRenderJob *job,
|
||||
const graphene_rect_t *bounds)
|
||||
@@ -1159,6 +1238,22 @@ gsk_gl_render_job_begin_draw (GskGLRenderJob *job,
|
||||
job->driver->stamps[UNIFORM_SHARED_CLIP_RECT],
|
||||
&job->current_clip->rect);
|
||||
|
||||
if (job->current_clip->is_mask)
|
||||
{
|
||||
gsk_gl_program_set_uniform_texture (job->current_program,
|
||||
UNIFORM_SHARED_CLIP_MASK,
|
||||
job->driver->stamps[UNIFORM_SHARED_CLIP_MASK],
|
||||
GL_TEXTURE_2D,
|
||||
GL_TEXTURE4,
|
||||
job->current_clip->mask);
|
||||
|
||||
gsk_gl_uniform_state_set1i (program->uniforms,
|
||||
program->program_info,
|
||||
UNIFORM_SHARED_MASK_MODE,
|
||||
job->driver->stamps[UNIFORM_SHARED_CLIP_MASK],
|
||||
job->current_clip->mask_mode);
|
||||
}
|
||||
|
||||
gsk_gl_uniform_state_set1f (program->uniforms,
|
||||
program->program_info,
|
||||
UNIFORM_SHARED_ALPHA,
|
||||
@@ -1171,7 +1266,9 @@ gsk_gl_render_job_begin_draw (GskGLRenderJob *job,
|
||||
? job->driver->name ## _no_clip \
|
||||
: (job->current_clip->is_rectilinear \
|
||||
? job->driver->name ## _rect_clip \
|
||||
: job->driver->name))
|
||||
: (job->current_clip->is_mask \
|
||||
? job->driver->name ## _mask_clip \
|
||||
: job->driver->name)))
|
||||
|
||||
static inline void
|
||||
gsk_gl_render_job_split_draw (GskGLRenderJob *job)
|
||||
@@ -1499,6 +1596,7 @@ gsk_gl_render_job_visit_color_node (GskGLRenderJob *job,
|
||||
/* Limit the size, or we end up with a coordinate overflow somewhere. */
|
||||
if (node->bounds.size.width < 300 &&
|
||||
node->bounds.size.height < 300 &&
|
||||
!job->current_clip->is_mask &&
|
||||
batch->any.kind == GSK_GL_COMMAND_KIND_DRAW &&
|
||||
batch->any.program == program->id)
|
||||
{
|
||||
@@ -1526,7 +1624,10 @@ gsk_gl_render_job_visit_color_node (GskGLRenderJob *job,
|
||||
else
|
||||
{
|
||||
gsk_gl_render_job_begin_draw (job, CHOOSE_PROGRAM (job, color));
|
||||
gsk_gl_render_job_draw_rect_with_color (job, &node->bounds, color);
|
||||
if (job->current_clip->is_mask)
|
||||
gsk_gl_render_job_draw_subrect_with_color (job, &job->current_clip->rect.bounds, &node->bounds, color);
|
||||
else
|
||||
gsk_gl_render_job_draw_rect_with_color (job, &node->bounds, color);
|
||||
gsk_gl_render_job_end_draw (job);
|
||||
}
|
||||
}
|
||||
@@ -1802,33 +1903,37 @@ gsk_gl_render_job_visit_rect_border_node (GskGLRenderJob *job,
|
||||
if (widths[0] > 0)
|
||||
{
|
||||
rgba_to_half (&colors[0], color);
|
||||
gsk_gl_render_job_draw_rect_with_color (job,
|
||||
&GRAPHENE_RECT_INIT (origin->x, origin->y, size->width - widths[1], widths[0]),
|
||||
color);
|
||||
gsk_gl_render_job_draw_subrect_with_color (job,
|
||||
&node->bounds,
|
||||
&GRAPHENE_RECT_INIT (origin->x, origin->y, size->width - widths[1], widths[0]),
|
||||
color);
|
||||
}
|
||||
|
||||
if (widths[1] > 0)
|
||||
{
|
||||
rgba_to_half (&colors[1], color);
|
||||
gsk_gl_render_job_draw_rect_with_color (job,
|
||||
&GRAPHENE_RECT_INIT (origin->x + size->width - widths[1], origin->y, widths[1], size->height - widths[2]),
|
||||
color);
|
||||
gsk_gl_render_job_draw_subrect_with_color (job,
|
||||
&node->bounds,
|
||||
&GRAPHENE_RECT_INIT (origin->x + size->width - widths[1], origin->y, widths[1], size->height - widths[2]),
|
||||
color);
|
||||
}
|
||||
|
||||
if (widths[2] > 0)
|
||||
{
|
||||
rgba_to_half (&colors[2], color);
|
||||
gsk_gl_render_job_draw_rect_with_color (job,
|
||||
&GRAPHENE_RECT_INIT (origin->x + widths[3], origin->y + size->height - widths[2], size->width - widths[3], widths[2]),
|
||||
color);
|
||||
gsk_gl_render_job_draw_subrect_with_color (job,
|
||||
&node->bounds,
|
||||
&GRAPHENE_RECT_INIT (origin->x + widths[3], origin->y + size->height - widths[2], size->width - widths[3], widths[2]),
|
||||
color);
|
||||
}
|
||||
|
||||
if (widths[3] > 0)
|
||||
{
|
||||
rgba_to_half (&colors[3], color);
|
||||
gsk_gl_render_job_draw_rect_with_color (job,
|
||||
&GRAPHENE_RECT_INIT (origin->x, origin->y + widths[0], widths[3], size->height - widths[0]),
|
||||
color);
|
||||
gsk_gl_render_job_draw_subrect_with_color (job,
|
||||
&node->bounds,
|
||||
&GRAPHENE_RECT_INIT (origin->x, origin->y + widths[0], widths[3], size->height - widths[0]),
|
||||
color);
|
||||
}
|
||||
|
||||
gsk_gl_render_job_end_draw (job);
|
||||
@@ -1851,6 +1956,7 @@ gsk_gl_render_job_visit_border_node (GskGLRenderJob *job,
|
||||
float max_y = min_y + node->bounds.size.height;
|
||||
GskRoundedRect outline;
|
||||
guint16 color[4];
|
||||
float u, v;
|
||||
|
||||
memset (sizes, 0, sizeof sizes);
|
||||
|
||||
@@ -1897,11 +2003,19 @@ gsk_gl_render_job_visit_border_node (GskGLRenderJob *job,
|
||||
rgba_to_half (&colors[0], color);
|
||||
|
||||
vertices[0] = (GskGLDrawVertex) { .position = { min_x, min_y }, .uv = { 0, 1 }, .color = { color[0], color[1], color[2], color[3] } };
|
||||
vertices[1] = (GskGLDrawVertex) { .position = { min_x + sizes[0].w, min_y + sizes[0].h }, .uv = { 0, 0 }, .color = { color[0], color[1], color[2], color[3] } };
|
||||
|
||||
u = sizes[0].w / (max_x - min_x);
|
||||
v = 1. - sizes[0].h / (max_y - min_y);
|
||||
vertices[1] = (GskGLDrawVertex) { .position = { min_x + sizes[0].w, min_y + sizes[0].h }, .uv = { u, v }, .color = { color[0], color[1], color[2], color[3] } };
|
||||
vertices[2] = (GskGLDrawVertex) { .position = { max_x, min_y }, .uv = { 1, 1 }, .color = { color[0], color[1], color[2], color[3] } };
|
||||
|
||||
vertices[3] = (GskGLDrawVertex) { .position = { max_x - sizes[1].w, min_y + sizes[1].h }, .uv = { 1, 0 }, .color = { color[0], color[1], color[2], color[3] } };
|
||||
vertices[4] = (GskGLDrawVertex) { .position = { min_x + sizes[0].w, min_y + sizes[0].h }, .uv = { 0, 0 }, .color = { color[0], color[1], color[2], color[3] } };
|
||||
u = 1. - sizes[1].w / (max_x - min_x);
|
||||
v = 1. - sizes[1].h / (max_y - min_y);
|
||||
vertices[3] = (GskGLDrawVertex) { .position = { max_x - sizes[1].w, min_y + sizes[1].h }, .uv = { u, v }, .color = { color[0], color[1], color[2], color[3] } };
|
||||
|
||||
u = sizes[0].w / (max_x - min_x);
|
||||
v = 1. - sizes[0].h / (max_y - min_y);
|
||||
vertices[4] = (GskGLDrawVertex) { .position = { min_x + sizes[0].w, min_y + sizes[0].h }, .uv = { u, v }, .color = { color[0], color[1], color[2], color[3] } };
|
||||
vertices[5] = (GskGLDrawVertex) { .position = { max_x, min_y }, .uv = { 1, 1 }, .color = { color[0], color[1], color[2], color[3] } };
|
||||
}
|
||||
|
||||
@@ -1911,12 +2025,20 @@ gsk_gl_render_job_visit_border_node (GskGLRenderJob *job,
|
||||
|
||||
rgba_to_half (&colors[1], color);
|
||||
|
||||
vertices[0] = (GskGLDrawVertex) { .position = { max_x - sizes[1].w, min_y + sizes[1].h }, .uv = { 0, 1 }, .color = { color[0], color[1], color[2], color[3] } };
|
||||
vertices[1] = (GskGLDrawVertex) { .position = { max_x - sizes[2].w, max_y - sizes[2].h }, .uv = { 0, 0 }, .color = { color[0], color[1], color[2], color[3] } };
|
||||
u = 1. - sizes[1].w / (max_x - min_x);
|
||||
v = 1. - sizes[1].h / (max_y - min_y);
|
||||
vertices[0] = (GskGLDrawVertex) { .position = { max_x - sizes[1].w, min_y + sizes[1].h }, .uv = { u, v }, .color = { color[0], color[1], color[2], color[3] } };
|
||||
|
||||
u = 1. - sizes[2].w / (max_x - min_x);
|
||||
v = sizes[2].h / (max_y - min_y);
|
||||
vertices[1] = (GskGLDrawVertex) { .position = { max_x - sizes[2].w, max_y - sizes[2].h }, .uv = { u, v }, .color = { color[0], color[1], color[2], color[3] } };
|
||||
vertices[2] = (GskGLDrawVertex) { .position = { max_x, min_y }, .uv = { 1, 1 }, .color = { color[0], color[1], color[2], color[3] } };
|
||||
|
||||
vertices[3] = (GskGLDrawVertex) { .position = { max_x, max_y }, .uv = { 1, 0 }, .color = { color[0], color[1], color[2], color[3] } };
|
||||
vertices[4] = (GskGLDrawVertex) { .position = { max_x - sizes[2].w, max_y - sizes[2].h }, .uv = { 0, 0 }, .color = { color[0], color[1], color[2], color[3] } };
|
||||
|
||||
u = 1. - sizes[2].w / (max_x - min_x);
|
||||
v = sizes[2].h / (max_y - min_y);
|
||||
vertices[4] = (GskGLDrawVertex) { .position = { max_x - sizes[2].w, max_y - sizes[2].h }, .uv = { u, v }, .color = { color[0], color[1], color[2], color[3] } };
|
||||
vertices[5] = (GskGLDrawVertex) { .position = { max_x, min_y }, .uv = { 1, 1 }, .color = { color[0], color[1], color[2], color[3] } };
|
||||
}
|
||||
|
||||
@@ -1926,13 +2048,21 @@ gsk_gl_render_job_visit_border_node (GskGLRenderJob *job,
|
||||
|
||||
rgba_to_half (&colors[2], color);
|
||||
|
||||
vertices[0] = (GskGLDrawVertex) { .position = { min_x + sizes[3].w, max_y - sizes[3].h }, .uv = { 0, 1 }, .color = { color[0], color[1], color[2], color[3] } };
|
||||
u = sizes[3].w / (max_x - min_x);
|
||||
v = sizes[3].h / (max_y - min_y);
|
||||
vertices[0] = (GskGLDrawVertex) { .position = { min_x + sizes[3].w, max_y - sizes[3].h }, .uv = { u, v }, .color = { color[0], color[1], color[2], color[3] } };
|
||||
vertices[1] = (GskGLDrawVertex) { .position = { min_x, max_y }, .uv = { 0, 0 }, .color = { color[0], color[1], color[2], color[3] } };
|
||||
vertices[2] = (GskGLDrawVertex) { .position = { max_x - sizes[2].w, max_y - sizes[2].h }, .uv = { 1, 1 }, .color = { color[0], color[1], color[2], color[3] } };
|
||||
|
||||
u = 1. - sizes[2].w / (max_x - min_x);
|
||||
v = sizes[2].h / (max_y - min_y);
|
||||
vertices[2] = (GskGLDrawVertex) { .position = { max_x - sizes[2].w, max_y - sizes[2].h }, .uv = { u, v }, .color = { color[0], color[1], color[2], color[3] } };
|
||||
|
||||
vertices[3] = (GskGLDrawVertex) { .position = { max_x, max_y }, .uv = { 1, 0 }, .color = { color[0], color[1], color[2], color[3] } };
|
||||
vertices[4] = (GskGLDrawVertex) { .position = { min_x , max_y }, .uv = { 0, 0 }, .color = { color[0], color[1], color[2], color[3] } };
|
||||
vertices[5] = (GskGLDrawVertex) { .position = { max_x - sizes[2].w, max_y - sizes[2].h }, .uv = { 1, 1 }, .color = { color[0], color[1], color[2], color[3] } };
|
||||
|
||||
u = 1. - sizes[2].w / (max_x - min_x);
|
||||
v = sizes[2].h / (max_y - min_y);
|
||||
vertices[5] = (GskGLDrawVertex) { .position = { max_x - sizes[2].w, max_y - sizes[2].h }, .uv = { u, v }, .color = { color[0], color[1], color[2], color[3] } };
|
||||
}
|
||||
|
||||
if (widths[3] > 0)
|
||||
@@ -1943,11 +2073,19 @@ gsk_gl_render_job_visit_border_node (GskGLRenderJob *job,
|
||||
|
||||
vertices[0] = (GskGLDrawVertex) { .position = { min_x, min_y }, .uv = { 0, 1 }, .color = { color[0], color[1], color[2], color[3] } };
|
||||
vertices[1] = (GskGLDrawVertex) { .position = { min_x, max_y }, .uv = { 0, 0 }, .color = { color[0], color[1], color[2], color[3] } };
|
||||
vertices[2] = (GskGLDrawVertex) { .position = { min_x + sizes[0].w, min_y + sizes[0].h }, .uv = { 1, 1 }, .color = { color[0], color[1], color[2], color[3] } };
|
||||
|
||||
vertices[3] = (GskGLDrawVertex) { .position = { min_x + sizes[3].w, max_y - sizes[3].h }, .uv = { 1, 0 }, .color = { color[0], color[1], color[2], color[3] } };
|
||||
u = sizes[2].w / (max_x - min_x);
|
||||
v = 1. - sizes[0].h / (max_y - min_y);
|
||||
vertices[2] = (GskGLDrawVertex) { .position = { min_x + sizes[0].w, min_y + sizes[0].h }, .uv = { u, v }, .color = { color[0], color[1], color[2], color[3] } };
|
||||
|
||||
u = sizes[3].w / (max_x - min_x);
|
||||
v = sizes[3].h / (max_y - min_y);
|
||||
vertices[3] = (GskGLDrawVertex) { .position = { min_x + sizes[3].w, max_y - sizes[3].h }, .uv = { u, v }, .color = { color[0], color[1], color[2], color[3] } };
|
||||
vertices[4] = (GskGLDrawVertex) { .position = { min_x, max_y }, .uv = { 0, 0 }, .color = { color[0], color[1], color[2], color[3] } };
|
||||
vertices[5] = (GskGLDrawVertex) { .position = { min_x + sizes[0].w, min_y + sizes[0].h }, .uv = { 1, 1 }, .color = { color[0], color[1], color[2], color[3] } };
|
||||
|
||||
u = sizes[0].w / (max_x - min_x);
|
||||
v = 1. - sizes[0].h / (max_y - min_y);
|
||||
vertices[5] = (GskGLDrawVertex) { .position = { min_x + sizes[0].w, min_y + sizes[0].h }, .uv = { u, v }, .color = { color[0], color[1], color[2], color[3] } };
|
||||
}
|
||||
|
||||
gsk_gl_render_job_end_draw (job);
|
||||
@@ -1996,12 +2134,12 @@ gsk_gl_render_job_visit_css_background (GskGLRenderJob *job,
|
||||
|
||||
vertices = gsk_gl_command_queue_add_vertices (job->command_queue);
|
||||
|
||||
vertices[0] = (GskGLDrawVertex) { .position = { min_x, min_y }, .color = { color[0], color[1], color[2], color[3] }, .color2 = { color2[0], color2[1], color2[2], color2[3] } };
|
||||
vertices[1] = (GskGLDrawVertex) { .position = { min_x, max_y }, .color = { color[0], color[1], color[2], color[3] }, .color2 = { color2[0], color2[1], color2[2], color2[3] } };
|
||||
vertices[2] = (GskGLDrawVertex) { .position = { max_x, min_y }, .color = { color[0], color[1], color[2], color[3] }, .color2 = { color2[0], color2[1], color2[2], color2[3] } };
|
||||
vertices[3] = (GskGLDrawVertex) { .position = { max_x, max_y }, .color = { color[0], color[1], color[2], color[3] }, .color2 = { color2[0], color2[1], color2[2], color2[3] } };
|
||||
vertices[4] = (GskGLDrawVertex) { .position = { min_x, max_y }, .color = { color[0], color[1], color[2], color[3] }, .color2 = { color2[0], color2[1], color2[2], color2[3] } };
|
||||
vertices[5] = (GskGLDrawVertex) { .position = { max_x, min_y }, .color = { color[0], color[1], color[2], color[3] }, .color2 = { color2[0], color2[1], color2[2], color2[3] } };
|
||||
vertices[0] = (GskGLDrawVertex) { .position = { min_x, min_y }, .uv = { 0, 1 }, .color = { color[0], color[1], color[2], color[3] }, .color2 = { color2[0], color2[1], color2[2], color2[3] } };
|
||||
vertices[1] = (GskGLDrawVertex) { .position = { min_x, max_y }, .uv = { 0, 0 }, .color = { color[0], color[1], color[2], color[3] }, .color2 = { color2[0], color2[1], color2[2], color2[3] } };
|
||||
vertices[2] = (GskGLDrawVertex) { .position = { max_x, min_y }, .uv = { 1, 1 }, .color = { color[0], color[1], color[2], color[3] }, .color2 = { color2[0], color2[1], color2[2], color2[3] } };
|
||||
vertices[3] = (GskGLDrawVertex) { .position = { max_x, max_y }, .uv = { 1, 0 }, .color = { color[0], color[1], color[2], color[3] }, .color2 = { color2[0], color2[1], color2[2], color2[3] } };
|
||||
vertices[4] = (GskGLDrawVertex) { .position = { min_x, max_y }, .uv = { 0, 0 }, .color = { color[0], color[1], color[2], color[3] }, .color2 = { color2[0], color2[1], color2[2], color2[3] } };
|
||||
vertices[5] = (GskGLDrawVertex) { .position = { max_x, min_y }, .uv = { 1, 1 }, .color = { color[0], color[1], color[2], color[3] }, .color2 = { color2[0], color2[1], color2[2], color2[3] } };
|
||||
|
||||
gsk_gl_render_job_end_draw (job);
|
||||
}
|
||||
@@ -3300,58 +3438,31 @@ gsk_gl_render_job_visit_mask_node (GskGLRenderJob *job,
|
||||
{
|
||||
const GskRenderNode *source = gsk_mask_node_get_source (node);
|
||||
const GskRenderNode *mask = gsk_mask_node_get_mask (node);
|
||||
GskGLRenderOffscreen source_offscreen = {0};
|
||||
GskMaskMode mode = gsk_mask_node_get_mask_mode (node);
|
||||
GskGLRenderOffscreen mask_offscreen = {0};
|
||||
|
||||
source_offscreen.bounds = &node->bounds;
|
||||
source_offscreen.force_offscreen = TRUE;
|
||||
source_offscreen.reset_clip = TRUE;
|
||||
|
||||
mask_offscreen.bounds = &node->bounds;
|
||||
mask_offscreen.force_offscreen = TRUE;
|
||||
mask_offscreen.reset_clip = TRUE;
|
||||
mask_offscreen.reset_clip = FALSE;
|
||||
mask_offscreen.do_not_cache = TRUE;
|
||||
|
||||
gsk_gl_render_job_set_modelview (job, gsk_transform_scale (NULL, fabs (job->scale_x), fabs (job->scale_y)));
|
||||
|
||||
/* TODO: We create 2 textures here as big as the mask node, but both
|
||||
* nodes might be a lot smaller than that.
|
||||
*/
|
||||
if (!gsk_gl_render_job_visit_node_with_offscreen (job, source, &source_offscreen))
|
||||
{
|
||||
gsk_gl_render_job_pop_modelview (job);
|
||||
gsk_gl_render_job_visit_node (job, source);
|
||||
return;
|
||||
}
|
||||
|
||||
g_assert (source_offscreen.was_offscreen);
|
||||
|
||||
if (!gsk_gl_render_job_visit_node_with_offscreen (job, mask, &mask_offscreen))
|
||||
{
|
||||
gsk_gl_render_job_pop_modelview (job);
|
||||
return;
|
||||
}
|
||||
return;
|
||||
|
||||
g_assert (mask_offscreen.was_offscreen);
|
||||
|
||||
gsk_gl_render_job_pop_modelview (job);
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
if (mask_offscreen.texture_width > 0 && mask_offscreen.texture_height > 0)
|
||||
g_array_append_vals (job->textures_to_save,
|
||||
&(TextureToSave) { mask_offscreen.texture_id,
|
||||
mask_offscreen.texture_width,
|
||||
mask_offscreen.texture_height,
|
||||
"mask" }, 1);
|
||||
#endif
|
||||
|
||||
gsk_gl_render_job_begin_draw (job, CHOOSE_PROGRAM (job, mask));
|
||||
gsk_gl_program_set_uniform_texture (job->current_program,
|
||||
UNIFORM_SHARED_SOURCE, 0,
|
||||
GL_TEXTURE_2D,
|
||||
GL_TEXTURE0,
|
||||
source_offscreen.texture_id);
|
||||
gsk_gl_program_set_uniform_texture (job->current_program,
|
||||
UNIFORM_MASK_SOURCE, 0,
|
||||
GL_TEXTURE_2D,
|
||||
GL_TEXTURE1,
|
||||
mask_offscreen.texture_id);
|
||||
gsk_gl_program_set_uniform1i (job->current_program,
|
||||
UNIFORM_MASK_MODE, 0,
|
||||
gsk_mask_node_get_mask_mode (node));
|
||||
gsk_gl_render_job_draw_offscreen_rect (job, &node->bounds);
|
||||
gsk_gl_render_job_end_draw (job);
|
||||
gsk_gl_render_job_push_clip_mask (job, mask_offscreen.texture_id, mode, &node->bounds);
|
||||
gsk_gl_render_job_visit_node (job, source);
|
||||
gsk_gl_render_job_pop_clip (job);
|
||||
}
|
||||
|
||||
static inline void
|
||||
@@ -3557,6 +3668,9 @@ gsk_gl_render_job_upload_texture (GskGLRenderJob *job,
|
||||
if (gl_texture && offscreen->texture_id == gdk_gl_texture_get_id (gl_texture))
|
||||
offscreen->sync = gdk_gl_texture_get_sync (gl_texture);
|
||||
}
|
||||
|
||||
offscreen->texture_width = gdk_texture_get_width (texture);
|
||||
offscreen->texture_height = gdk_texture_get_height (texture);
|
||||
}
|
||||
|
||||
static inline void
|
||||
@@ -4291,6 +4405,8 @@ gsk_gl_render_job_visit_node_with_offscreen (GskGLRenderJob *job,
|
||||
offscreen->texture_id = gsk_gl_driver_release_render_target (job->driver,
|
||||
render_target,
|
||||
FALSE);
|
||||
offscreen->texture_width = texture_width;
|
||||
offscreen->texture_height = texture_height;
|
||||
|
||||
if (!offscreen->do_not_cache)
|
||||
gsk_gl_driver_cache_texture (job->driver, &key, offscreen->texture_id);
|
||||
@@ -4355,6 +4471,19 @@ gsk_gl_render_job_render_flipped (GskGLRenderJob *job,
|
||||
gsk_gl_command_queue_execute (job->command_queue, surface_height, 1, NULL, job->default_framebuffer);
|
||||
gdk_gl_context_pop_debug_group (job->command_queue->context);
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
for (unsigned int i = 0; i < job->textures_to_save->len; i++)
|
||||
{
|
||||
TextureToSave *t = &g_array_index (job->textures_to_save, TextureToSave, i);
|
||||
|
||||
g_print ("save texture\n");
|
||||
char *filename = g_strdup_printf ("%s-%u.png", t->name, i);
|
||||
gsk_gl_driver_save_texture_to_png (job->driver, t->texture_id, t->width, t->height, filename);
|
||||
g_free (filename);
|
||||
}
|
||||
g_array_set_size (job->textures_to_save, 0);
|
||||
#endif
|
||||
|
||||
glDeleteFramebuffers (1, &framebuffer_id);
|
||||
glDeleteTextures (1, &texture_id);
|
||||
}
|
||||
@@ -4405,6 +4534,19 @@ gsk_gl_render_job_render (GskGLRenderJob *job,
|
||||
gsk_gl_command_queue_execute (job->command_queue, surface_height, scale, job->region, job->default_framebuffer);
|
||||
gdk_gl_context_pop_debug_group (job->command_queue->context);
|
||||
gdk_profiler_add_mark (start_time, GDK_PROFILER_CURRENT_TIME-start_time, "Execute GL command queue", "");
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
for (unsigned int i = 0; i < job->textures_to_save->len; i++)
|
||||
{
|
||||
TextureToSave *t = &g_array_index (job->textures_to_save, TextureToSave, i);
|
||||
|
||||
g_print ("save texture\n");
|
||||
char *filename = g_strdup_printf ("%s-%u.png", t->name, i);
|
||||
gsk_gl_driver_save_texture_to_png (job->driver, t->texture_id, t->width, t->height, filename);
|
||||
g_free (filename);
|
||||
}
|
||||
g_array_set_size (job->textures_to_save, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
@@ -4513,6 +4655,10 @@ gsk_gl_render_job_new (GskGLDriver *driver,
|
||||
clip_rect->size.width,
|
||||
clip_rect->size.height));
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
job->textures_to_save = g_array_new (0, 0, sizeof (TextureToSave));
|
||||
#endif
|
||||
|
||||
return job;
|
||||
}
|
||||
|
||||
@@ -4533,5 +4679,8 @@ gsk_gl_render_job_free (GskGLRenderJob *job)
|
||||
g_clear_pointer (&job->region, cairo_region_destroy);
|
||||
g_clear_pointer (&job->modelview, g_array_unref);
|
||||
g_clear_pointer (&job->clip, g_array_unref);
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
g_clear_pointer (&job->textures_to_save, g_array_unref);
|
||||
#endif
|
||||
g_free (job);
|
||||
}
|
||||
|
@@ -24,6 +24,8 @@ void main() {
|
||||
|
||||
gsk_rounded_rect_encode(outside, transformed_outside_outline);
|
||||
gsk_rounded_rect_encode(inside, transformed_inside_outline);
|
||||
|
||||
vUv = vec2(aUv.x, aUv.y);
|
||||
}
|
||||
|
||||
// FRAGMENT_SHADER:
|
||||
|
@@ -6,6 +6,8 @@ _OUT_ vec4 final_color;
|
||||
void main() {
|
||||
gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
|
||||
|
||||
vUv = vec2(aUv.x, aUv.y);
|
||||
|
||||
final_color = gsk_scaled_premultiply(aColor, u_alpha);
|
||||
}
|
||||
|
||||
|
@@ -8,6 +8,8 @@ _OUT_ vec2 coord;
|
||||
void main() {
|
||||
gl_Position = u_projection * (u_modelview * vec4(aPosition, 0.0, 1.0));
|
||||
|
||||
vUv = vec2(aUv.x, aUv.y);
|
||||
|
||||
vec2 mv0 = u_modelview[0].xy;
|
||||
vec2 mv1 = u_modelview[1].xy;
|
||||
vec2 offset = aPosition - u_geometry.xy;
|
||||
|
@@ -26,6 +26,8 @@ void main() {
|
||||
|
||||
gsk_rounded_rect_encode(outside, transformed_outside_outline);
|
||||
gsk_rounded_rect_encode(inside, transformed_inside_outline);
|
||||
|
||||
vUv = vec2(aUv.x, aUv.y);
|
||||
}
|
||||
|
||||
// FRAGMENT_SHADER:
|
||||
|
@@ -27,6 +27,8 @@ void main() {
|
||||
|
||||
gsk_rounded_rect_encode(outside, transformed_outside_outline);
|
||||
gsk_rounded_rect_encode(inside, transformed_inside_outline);
|
||||
|
||||
vUv = vec2(aUv.x, aUv.y);
|
||||
}
|
||||
|
||||
// FRAGMENT_SHADER:
|
||||
|
@@ -7,6 +7,8 @@ _OUT_ vec4 info;
|
||||
void main() {
|
||||
gl_Position = u_projection * (u_modelview * vec4(aPosition, 0.0, 1.0));
|
||||
|
||||
vUv = vec2(aUv.x, aUv.y);
|
||||
|
||||
vec2 mv0 = u_modelview[0].xy;
|
||||
vec2 mv1 = u_modelview[1].xy;
|
||||
vec2 offset = aPosition - u_points.xy;
|
||||
|
@@ -1,33 +0,0 @@
|
||||
// VERTEX_SHADER:
|
||||
// mask.glsl
|
||||
|
||||
void main() {
|
||||
gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
|
||||
|
||||
vUv = vec2(aUv.x, aUv.y);
|
||||
}
|
||||
|
||||
// FRAGMENT_SHADER:
|
||||
// mask.glsl
|
||||
|
||||
uniform int u_mode;
|
||||
uniform sampler2D u_mask;
|
||||
|
||||
void main() {
|
||||
vec4 source = GskTexture(u_source, vUv);
|
||||
vec4 mask = GskTexture(u_mask, vUv);
|
||||
float mask_value;
|
||||
|
||||
if (u_mode == 0)
|
||||
mask_value = mask.a;
|
||||
else if (u_mode == 1)
|
||||
mask_value = 1.0 - mask.a;
|
||||
else if (u_mode == 2)
|
||||
mask_value = (0.2126 * mask.r + 0.7152 * mask.g + 0.0722 * mask.b) * mask.a;
|
||||
else if (u_mode == 3)
|
||||
mask_value = 1.0 - (0.2126 * mask.r + 0.7152 * mask.g + 0.0722 * mask.b) * mask.a;
|
||||
else
|
||||
mask_value = 0.0;
|
||||
|
||||
gskSetOutputColor(vec4 (source * mask_value));
|
||||
}
|
@@ -5,6 +5,11 @@ uniform float u_alpha;
|
||||
uniform vec4 u_viewport;
|
||||
uniform vec4[3] u_clip_rect;
|
||||
|
||||
#if defined(MASK_CLIP)
|
||||
uniform int u_mask_mode;
|
||||
uniform sampler2D u_clip_mask;
|
||||
#endif
|
||||
|
||||
#if defined(GSK_LEGACY)
|
||||
_OUT_ vec4 outputColor;
|
||||
#elif !defined(GSK_GLES)
|
||||
@@ -124,7 +129,28 @@ vec2 gsk_get_frag_coord() {
|
||||
void gskSetOutputColor(vec4 color) {
|
||||
vec4 result;
|
||||
|
||||
#if defined(NO_CLIP)
|
||||
#if defined(MASK_CLIP)
|
||||
vec4 mask = GskTexture(u_clip_mask, vUv);
|
||||
float mask_value;
|
||||
switch (u_mask_mode)
|
||||
{
|
||||
case 0:
|
||||
mask_value = mask.a;
|
||||
break;
|
||||
case 1:
|
||||
mask_value = 1.0 - mask.a;
|
||||
break;
|
||||
case 2:
|
||||
mask_value = (0.2126 * mask.r + 0.7152 * mask.g + 0.0722 * mask.b) * mask.a;
|
||||
break;
|
||||
case 3:
|
||||
mask_value = 1.0 - (0.2126 * mask.r + 0.7152 * mask.g + 0.0722 * mask.b) * mask.a;
|
||||
break;
|
||||
default:
|
||||
mask_value = 0.0;
|
||||
}
|
||||
result = color * mask_value;
|
||||
#elif defined(NO_CLIP)
|
||||
result = color;
|
||||
#elif defined(RECT_CLIP)
|
||||
float coverage = gsk_rect_coverage(gsk_get_bounds(u_clip_rect),
|
||||
@@ -146,7 +172,28 @@ void gskSetOutputColor(vec4 color) {
|
||||
void gskSetScaledOutputColor(vec4 color, float alpha) {
|
||||
vec4 result;
|
||||
|
||||
#if defined(NO_CLIP)
|
||||
#if defined(MASK_CLIP)
|
||||
vec4 mask = GskTexture(u_clip_mask, vUv);
|
||||
float mask_value;
|
||||
switch (u_mask_mode)
|
||||
{
|
||||
case 0:
|
||||
mask_value = mask.a;
|
||||
break;
|
||||
case 1:
|
||||
mask_value = 1.0 - mask.a;
|
||||
break;
|
||||
case 2:
|
||||
mask_value = (0.2126 * mask.r + 0.7152 * mask.g + 0.0722 * mask.b) * mask.a;
|
||||
break;
|
||||
case 3:
|
||||
mask_value = 1.0 - (0.2126 * mask.r + 0.7152 * mask.g + 0.0722 * mask.b) * mask.a;
|
||||
break;
|
||||
default:
|
||||
mask_value = 0.0;
|
||||
}
|
||||
result = color * (alpha * mask_value);
|
||||
#elif defined(NO_CLIP)
|
||||
result = color * alpha;
|
||||
#elif defined(RECT_CLIP)
|
||||
float coverage = gsk_rect_coverage(gsk_get_bounds(u_clip_rect),
|
||||
|
@@ -15,6 +15,8 @@ void main() {
|
||||
dot(mv1, offset));
|
||||
|
||||
coord = dir * u_geometry.zw;
|
||||
|
||||
vUv = vec2(aUv.x, aUv.y);
|
||||
}
|
||||
|
||||
// FRAGMENT_SHADER:
|
||||
|
@@ -24,6 +24,8 @@ void main() {
|
||||
|
||||
gsk_rounded_rect_encode(outside, transformed_outside_outline);
|
||||
gsk_rounded_rect_encode(inside, transformed_inside_outline);
|
||||
|
||||
vUv = vec2(aUv.x, aUv.y);
|
||||
}
|
||||
|
||||
// FRAGMENT_SHADER:
|
||||
|
@@ -19,7 +19,6 @@ gsk_private_gl_shaders = [
|
||||
'gl/resources/repeat.glsl',
|
||||
'gl/resources/custom.glsl',
|
||||
'gl/resources/filled_border.glsl',
|
||||
'gl/resources/mask.glsl',
|
||||
]
|
||||
|
||||
gsk_public_sources = files([
|
||||
|
@@ -24,12 +24,17 @@ loop = None
|
||||
|
||||
def quit_cb(loop):
|
||||
loop.quit()
|
||||
print('timed out while waiting')
|
||||
|
||||
def wait(millis):
|
||||
global loop
|
||||
before = GLib.get_monotonic_time()
|
||||
loop = GLib.MainLoop()
|
||||
GLib.timeout_add(millis, quit_cb, loop)
|
||||
loop.run()
|
||||
if verbose:
|
||||
time = (GLib.get_monotonic_time() - before) / 1000
|
||||
print(f'waited for {time} milliseconds')
|
||||
|
||||
display = None
|
||||
window = None
|
||||
@@ -41,10 +46,10 @@ def key_pressed_cb (controller, keyval, keycode, state):
|
||||
|
||||
if verbose:
|
||||
print(f'got key press: {keyval}, state {state}')
|
||||
assert expected_change != None, "Unexpected key press"
|
||||
assert expected_change['type'] == 'press', "Key press event expected"
|
||||
assert keyval == expected_change['keyval'], "Unexpected keyval in key press event"
|
||||
assert state == expected_change['state'], "Unexpected state in key press event"
|
||||
assert expected_change != None, 'Unexpected key press'
|
||||
assert expected_change['type'] == 'press', 'Key press event expected'
|
||||
assert keyval == expected_change['keyval'], 'Unexpected keyval in key press event'
|
||||
assert state == expected_change['state'], 'Unexpected state in key press event'
|
||||
|
||||
expected_change = None
|
||||
loop.quit()
|
||||
@@ -55,10 +60,10 @@ def key_released_cb (controller, keyval, keycode, state):
|
||||
|
||||
if verbose:
|
||||
print(f'got key release: {keyval}, state {state}')
|
||||
assert expected_change != None, "Unexpected key release"
|
||||
assert expected_change['type'] == 'release', "Key release event expected"
|
||||
assert keyval == expected_change['keyval'], "Unexpected keyval in key release event"
|
||||
assert state == expected_change['state'], "Unexpected state in key release event"
|
||||
assert expected_change != None, 'Unexpected key release'
|
||||
assert expected_change['type'] == 'release', 'Key release event expected'
|
||||
assert keyval == expected_change['keyval'], 'Unexpected keyval in key release event'
|
||||
assert state == expected_change['state'], 'Unexpected state in key release event'
|
||||
|
||||
expected_change = None
|
||||
loop.quit()
|
||||
@@ -70,9 +75,9 @@ def motion_cb (controller, x, y):
|
||||
if verbose:
|
||||
print(f'got motion: {x}, {y}')
|
||||
if expected_change != None:
|
||||
assert expected_change['type'] == 'motion', "Motion event expected"
|
||||
assert x == expected_change['x'], "Unexpected x coord in motion event"
|
||||
assert y == expected_change['y'], "Unexpected y coord in motion event"
|
||||
assert expected_change['type'] == 'motion', 'Motion event expected'
|
||||
assert x == expected_change['x'], 'Unexpected x coord in motion event'
|
||||
assert y == expected_change['y'], 'Unexpected y coord in motion event'
|
||||
expected_change = None
|
||||
loop.quit()
|
||||
|
||||
@@ -82,10 +87,10 @@ def enter_cb (controller, x, y):
|
||||
|
||||
if verbose:
|
||||
print(f'got enter: {x}, {y}')
|
||||
assert expected_change != None, "Unexpected enter"
|
||||
assert expected_change['type'] == 'enter', "Enter event expected"
|
||||
assert x == expected_change['x'], "Unexpected x coord in enter event"
|
||||
assert y == expected_change['y'], "Unexpected y coord in enter event"
|
||||
assert expected_change != None, 'Unexpected enter'
|
||||
assert expected_change['type'] == 'enter', 'Enter event expected'
|
||||
assert x == expected_change['x'], 'Unexpected x coord in enter event'
|
||||
assert y == expected_change['y'], 'Unexpected y coord in enter event'
|
||||
|
||||
expected_change = None
|
||||
loop.quit()
|
||||
@@ -96,11 +101,11 @@ def pressed_cb(controller, n, x, y):
|
||||
|
||||
if verbose:
|
||||
print(f'got pressed')
|
||||
assert expected_change != None, "Unexpected event"
|
||||
assert expected_change['type'] == 'press', "Button press expected"
|
||||
assert expected_change['button'] == controller.get_current_button(), "Unexpected button pressed"
|
||||
assert x == expected_change['x'], "Unexpected x coord in motion event"
|
||||
assert y == expected_change['y'], "Unexpected y coord in motion event"
|
||||
assert expected_change != None, 'Unexpected event'
|
||||
assert expected_change['type'] == 'press', 'Button press expected'
|
||||
assert expected_change['button'] == controller.get_current_button(), 'Unexpected button pressed'
|
||||
assert x == expected_change['x'], 'Unexpected x coord in motion event'
|
||||
assert y == expected_change['y'], 'Unexpected y coord in motion event'
|
||||
|
||||
expected_change = None
|
||||
loop.quit()
|
||||
@@ -111,8 +116,8 @@ def released_cb(controller, n, x, y):
|
||||
|
||||
if verbose:
|
||||
print(f'got released')
|
||||
assert expected_change != None, "Unexpected event"
|
||||
assert expected_change['type'] == 'release', "Button release expected"
|
||||
assert expected_change != None, 'Unexpected event'
|
||||
assert expected_change['type'] == 'release', 'Button release expected'
|
||||
|
||||
expected_change = None
|
||||
loop.quit()
|
||||
@@ -125,7 +130,7 @@ def expect_key_press(keyval, state, timeout):
|
||||
'state' : state
|
||||
}
|
||||
wait(timeout)
|
||||
assert expected_change == None, "Expected event did not happen"
|
||||
assert expected_change == None, 'Expected event did not happen'
|
||||
|
||||
def expect_key_release(keyval, state, timeout):
|
||||
global expected_change
|
||||
@@ -135,7 +140,7 @@ def expect_key_release(keyval, state, timeout):
|
||||
'state' : state
|
||||
}
|
||||
wait(timeout)
|
||||
assert expected_change == None, "Expected event did not happen"
|
||||
assert expected_change == None, 'Expected event did not happen'
|
||||
|
||||
def expect_motion(x, y, timeout):
|
||||
global expected_change
|
||||
@@ -145,7 +150,7 @@ def expect_motion(x, y, timeout):
|
||||
'y' : y
|
||||
}
|
||||
wait(timeout)
|
||||
assert expected_change == None, "Expected event did not happen"
|
||||
assert expected_change == None, 'Expected event did not happen'
|
||||
|
||||
def expect_enter(x, y, timeout):
|
||||
global expected_change
|
||||
@@ -155,7 +160,7 @@ def expect_enter(x, y, timeout):
|
||||
'y' : y
|
||||
}
|
||||
wait(timeout)
|
||||
assert expected_change == None, "Expected event did not happen"
|
||||
assert expected_change == None, 'Expected event did not happen'
|
||||
|
||||
def expect_button_press(button, x, y, timeout):
|
||||
global expected_change
|
||||
@@ -166,7 +171,7 @@ def expect_button_press(button, x, y, timeout):
|
||||
'y' : y
|
||||
}
|
||||
wait(timeout)
|
||||
assert expected_change == None, "Button press did not arrive"
|
||||
assert expected_change == None, 'Button press did not arrive'
|
||||
|
||||
def expect_button_release(button, x, y, timeout):
|
||||
global expected_change
|
||||
@@ -177,7 +182,7 @@ def expect_button_release(button, x, y, timeout):
|
||||
'y' : y
|
||||
}
|
||||
wait(timeout)
|
||||
assert expected_change == None, "Button release did not arrive"
|
||||
assert expected_change == None, 'Button release did not arrive'
|
||||
|
||||
def got_active(object, pspec):
|
||||
global loop
|
||||
@@ -220,9 +225,9 @@ def launch_observer():
|
||||
|
||||
wait(500)
|
||||
|
||||
assert window.is_active(), "Observer not active"
|
||||
assert window.get_width() == 1024, "Window not maximized"
|
||||
assert window.get_height() == 768, "Window not maximized"
|
||||
assert window.is_active(), 'Observer not active'
|
||||
assert window.get_width() == 1024, 'Window not maximized'
|
||||
assert window.get_height() == 768, 'Window not maximized'
|
||||
|
||||
# we need to wait out the map animation, or pointer coords will be off
|
||||
wait(1000)
|
||||
@@ -265,6 +270,9 @@ def pointer_move(x, y):
|
||||
|
||||
def basic_keyboard_tests():
|
||||
try:
|
||||
if verbose:
|
||||
print('Starting basic keyboard tests')
|
||||
|
||||
launch_observer()
|
||||
|
||||
key_press(Gdk.KEY_a)
|
||||
@@ -287,11 +295,14 @@ def basic_keyboard_tests():
|
||||
|
||||
stop_observer()
|
||||
except AssertionError as e:
|
||||
print("Error in basic_keyboard_tests: {0}".format(e))
|
||||
print(f'Error in basic_keyboard_tests: {e}')
|
||||
terminate()
|
||||
|
||||
def basic_pointer_tests():
|
||||
try:
|
||||
if verbose:
|
||||
print('Starting basic pointer tests')
|
||||
|
||||
pointer_move(-100.0, -100.0)
|
||||
launch_observer()
|
||||
|
||||
@@ -313,7 +324,7 @@ def basic_pointer_tests():
|
||||
|
||||
stop_observer()
|
||||
except AssertionError as e:
|
||||
print("Error in basic_pointer_tests: {0}".format(e))
|
||||
print(f'Error in basic_pointer_tests: {e}')
|
||||
terminate()
|
||||
|
||||
ds_window = None
|
||||
@@ -324,9 +335,9 @@ def drag_begin(controller, drag):
|
||||
global loop
|
||||
|
||||
if verbose:
|
||||
print(f'got drag begin')
|
||||
assert expected_change != None, "Unexpected drag begin"
|
||||
assert expected_change['type'] == 'drag', "Drag begin expected"
|
||||
print('got drag begin')
|
||||
assert expected_change != None, 'Unexpected drag begin'
|
||||
assert expected_change['type'] == 'drag', 'Drag begin expected'
|
||||
|
||||
expected_change = None
|
||||
loop.quit()
|
||||
@@ -362,9 +373,9 @@ def launch_drag_source(value):
|
||||
|
||||
wait(500)
|
||||
|
||||
assert ds_window.is_active(), "drag source not active"
|
||||
assert ds_window.get_width() == 1024, "Window not maximized"
|
||||
assert ds_window.get_height() == 768, "Window not maximized"
|
||||
assert ds_window.is_active(), 'drag source not active'
|
||||
assert ds_window.get_width() == 1024, 'Window not maximized'
|
||||
assert ds_window.get_height() == 768, 'Window not maximized'
|
||||
|
||||
# we need to wait out the map animation, or pointer coords will be off
|
||||
wait(1000)
|
||||
@@ -382,9 +393,9 @@ def do_drop(controller, value, x, y):
|
||||
|
||||
if verbose:
|
||||
print(f'got drop {value}')
|
||||
assert expected_change != None, "Unexpected drop begin"
|
||||
assert expected_change['type'] == 'drop', "Drop expected"
|
||||
assert expected_change['value'] == value, "Unexpected value dropped"
|
||||
assert expected_change != None, 'Unexpected drop begin'
|
||||
assert expected_change['type'] == 'drop', 'Drop expected'
|
||||
assert expected_change['value'] == value, 'Unexpected value dropped'
|
||||
|
||||
expected_change = None
|
||||
loop.quit()
|
||||
@@ -412,9 +423,9 @@ def launch_drop_target():
|
||||
|
||||
wait(500)
|
||||
|
||||
assert dt_window.is_active(), "drop target not active"
|
||||
assert dt_window.get_width() == 1024, "Window not maximized"
|
||||
assert dt_window.get_height() == 768, "Window not maximized"
|
||||
assert dt_window.is_active(), 'drop target not active'
|
||||
assert dt_window.get_width() == 1024, 'Window not maximized'
|
||||
assert dt_window.get_height() == 768, 'Window not maximized'
|
||||
|
||||
# we need to wait out the map animation, or pointer coords will be off
|
||||
wait(1000)
|
||||
@@ -430,7 +441,7 @@ def expect_drag(timeout):
|
||||
'type' : 'drag',
|
||||
}
|
||||
wait(timeout)
|
||||
assert expected_change == None, "DND operation not started"
|
||||
assert expected_change == None, 'DND operation not started'
|
||||
|
||||
def expect_drop(value, timeout):
|
||||
global expected_change
|
||||
@@ -439,10 +450,13 @@ def expect_drop(value, timeout):
|
||||
'value' : value
|
||||
}
|
||||
wait(timeout)
|
||||
assert expected_change == None, "Drop has not happened"
|
||||
assert expected_change == None, 'Drop has not happened'
|
||||
|
||||
def dnd_tests():
|
||||
try:
|
||||
if verbose:
|
||||
print('Starting dnd tests')
|
||||
|
||||
pointer_move(-100, -100)
|
||||
|
||||
launch_drag_source('abc')
|
||||
@@ -466,12 +480,17 @@ def dnd_tests():
|
||||
stop_drop_target()
|
||||
stop_drag_source()
|
||||
except AssertionError as e:
|
||||
print("Error in dnd_tests: {0}".format(e))
|
||||
print(f'Error in dnd_tests: {e}')
|
||||
terminate()
|
||||
|
||||
def session_closed_cb():
|
||||
print('Session closed')
|
||||
|
||||
def run_commands():
|
||||
basic_keyboard_tests()
|
||||
basic_pointer_tests()
|
||||
dnd_tests()
|
||||
|
||||
def mutter_appeared(name):
|
||||
global remote_desktop
|
||||
global session
|
||||
@@ -479,13 +498,13 @@ def mutter_appeared(name):
|
||||
global done
|
||||
|
||||
if verbose:
|
||||
print("mutter appeared on the bus")
|
||||
print('mutter appeared on the bus')
|
||||
|
||||
remote_desktop = bus.get('org.gnome.Mutter.RemoteDesktop',
|
||||
'/org/gnome/Mutter/RemoteDesktop')
|
||||
device_types = remote_desktop.Get('org.gnome.Mutter.RemoteDesktop', 'SupportedDeviceTypes')
|
||||
assert device_types & 1 == 1, "No keyboard"
|
||||
assert device_types & 2 == 2, "No pointer"
|
||||
assert device_types & 1 == 1, 'No keyboard'
|
||||
assert device_types & 2 == 2, 'No pointer'
|
||||
|
||||
screen_cast = bus.get('org.gnome.Mutter.ScreenCast',
|
||||
'/org/gnome/Mutter/ScreenCast')
|
||||
@@ -505,19 +524,19 @@ def mutter_appeared(name):
|
||||
key_release(Gdk.KEY_Control_L)
|
||||
pointer_move(-100, -100)
|
||||
|
||||
basic_keyboard_tests()
|
||||
basic_pointer_tests()
|
||||
dnd_tests()
|
||||
run_commands()
|
||||
|
||||
session.Stop()
|
||||
|
||||
if verbose:
|
||||
print('Done running commands, exiting...')
|
||||
done = True
|
||||
|
||||
def mutter_vanished():
|
||||
global done
|
||||
if remote_desktop != None:
|
||||
if verbose:
|
||||
print("mutter left the bus")
|
||||
print('mutter left the bus')
|
||||
done = True
|
||||
|
||||
bus = SessionBus()
|
||||
|
@@ -26,6 +26,9 @@ def terminate():
|
||||
|
||||
def stream_added_closure(name):
|
||||
def stream_added(node_id):
|
||||
if verbose:
|
||||
print('pipewire stream added')
|
||||
|
||||
monitor = monitors[name];
|
||||
|
||||
freq = monitor['freq'];
|
||||
@@ -36,7 +39,7 @@ def stream_added_closure(name):
|
||||
# Use gstreamer out-of-process, since the gst gl support gets
|
||||
# itself into a twist with its wayland connection when monitors
|
||||
# disappear
|
||||
pipeline_desc = f'gst-launch-1.0 --verbose pipewiresrc path={node_id} ! video/x-raw,max-framerate={freq}/1,width={width},height={height} ! videoconvert ! glimagesink'
|
||||
pipeline_desc = f'gst-launch-1.0 pipewiresrc path={node_id} ! video/x-raw,max-framerate={freq}/1,width={width},height={height} ! videoconvert ! glimagesink' # >& gstreamer-monitor.log'
|
||||
if verbose:
|
||||
print(f'launching {pipeline_desc}')
|
||||
monitor['pipeline'] = subprocess.Popen([pipeline_desc], shell=True)
|
||||
@@ -49,11 +52,11 @@ def add_monitor(name, width, height, scale, freq):
|
||||
session_path = screen_cast.CreateSession({})
|
||||
session = bus.get('org.gnome.Mutter.ScreenCast', session_path)
|
||||
monitors[name] = {
|
||||
"session": session,
|
||||
"width": width,
|
||||
"height": height,
|
||||
"scale": scale,
|
||||
"freq": freq
|
||||
'session': session,
|
||||
'width': width,
|
||||
'height': height,
|
||||
'scale': scale,
|
||||
'freq': freq
|
||||
}
|
||||
stream_path = session.RecordVirtual({})
|
||||
stream = bus.get('org.gnome.Mutter.ScreenCast', stream_path)
|
||||
@@ -70,7 +73,7 @@ def remove_monitor(name):
|
||||
session = monitor['session']
|
||||
session.Stop()
|
||||
except KeyError:
|
||||
print("failed to remove monitor")
|
||||
print('failed to remove monitor')
|
||||
monitors[name] = None
|
||||
|
||||
expected_change = None
|
||||
@@ -78,23 +81,28 @@ loop = None
|
||||
|
||||
def quit_cb(loop):
|
||||
loop.quit()
|
||||
print('timed out while waiting')
|
||||
|
||||
def wait(millis):
|
||||
global loop
|
||||
before = GLib.get_monotonic_time()
|
||||
loop = GLib.MainLoop()
|
||||
GLib.timeout_add(millis, quit_cb, loop)
|
||||
loop.run()
|
||||
if verbose:
|
||||
time = (GLib.get_monotonic_time() - before) / 1000
|
||||
print(f'waited for {time} milliseconds')
|
||||
|
||||
def monitors_changed(monitors, position, removed, added):
|
||||
global expected_change
|
||||
|
||||
assert expected_change != None, "No change expected"
|
||||
assert position == expected_change['position'], "Unexpected position in monitors-changed"
|
||||
assert removed == expected_change['removed'], "Unexpected removed in monitors-changed"
|
||||
assert added == expected_change['added'], "Unexpected added in monitors-changed"
|
||||
assert expected_change != None, 'No change expected'
|
||||
assert position == expected_change['position'], 'Unexpected position in monitors-changed'
|
||||
assert removed == expected_change['removed'], 'Unexpected removed in monitors-changed'
|
||||
assert added == expected_change['added'], 'Unexpected added in monitors-changed'
|
||||
|
||||
if verbose:
|
||||
print('got expected change')
|
||||
print('got expected monitors-changed signal')
|
||||
|
||||
expected_change = None
|
||||
loop.quit()
|
||||
@@ -110,7 +118,7 @@ def launch_observer():
|
||||
print('launch observer')
|
||||
|
||||
monitor_model = display.get_monitors()
|
||||
assert monitor_model.get_n_items() == 0, "Unexpected initial monitors"
|
||||
assert monitor_model.get_n_items() == 0, 'Unexpected initial monitors'
|
||||
monitor_model.connect('items-changed', monitors_changed)
|
||||
|
||||
def expect_monitors_changed(position, removed, added, timeout):
|
||||
@@ -121,7 +129,7 @@ def expect_monitors_changed(position, removed, added, timeout):
|
||||
'added' : added
|
||||
}
|
||||
wait(timeout)
|
||||
assert expected_change == None, "Expected change did not happen"
|
||||
assert expected_change == None, 'Expected change did not happen'
|
||||
|
||||
def got_connector(monitor, pspec):
|
||||
loop.quit()
|
||||
@@ -130,15 +138,18 @@ def expect_monitor(position, width, height, scale, freq):
|
||||
assert monitor_model.get_n_items() > position, f'Monitor {position} not present'
|
||||
monitor = monitor_model.get_item(position)
|
||||
if monitor.get_connector() == None:
|
||||
if verbose:
|
||||
print('waiting for connector')
|
||||
handler = monitor.connect('notify::connector', got_connector)
|
||||
wait(500)
|
||||
monitor.disconnect(handler)
|
||||
assert monitor.is_valid(), "Monitor is not valid"
|
||||
assert monitor.get_connector() != None, 'Monitor has no connector'
|
||||
assert monitor.is_valid(), 'Monitor is not valid'
|
||||
geometry = monitor.get_geometry()
|
||||
assert geometry.width == width, "Unexpected monitor width"
|
||||
assert geometry.height == height, "Unexpected monitor height"
|
||||
assert monitor.get_scale_factor() == scale, "Unexpected scale factor"
|
||||
assert monitor.get_refresh_rate() == freq, "Unexpected monitor frequency"
|
||||
assert geometry.width == width, 'Unexpected monitor width'
|
||||
assert geometry.height == height, 'Unexpected monitor height'
|
||||
assert monitor.get_scale_factor() == scale, 'Unexpected scale factor'
|
||||
assert monitor.get_refresh_rate() == freq, 'Unexpected monitor frequency'
|
||||
if verbose:
|
||||
print(f'monitor {position}: {geometry.width}x{geometry.height} frequency {monitor.get_refresh_rate()} scale {monitor.get_scale_factor()} model \'{monitor.get_model()}\' connector \'{monitor.get_connector()}\'')
|
||||
|
||||
@@ -146,41 +157,41 @@ def run_commands():
|
||||
try:
|
||||
launch_observer()
|
||||
|
||||
add_monitor("0", width=100, height=100, scale=1, freq=60)
|
||||
expect_monitors_changed(0, 0, 1, 5000)
|
||||
add_monitor('0', width=100, height=100, scale=1, freq=60)
|
||||
expect_monitors_changed(0, 0, 1, 10000)
|
||||
expect_monitor (position=0, width=100, height=100, scale=1, freq=60000)
|
||||
|
||||
add_monitor("1", width=1024, height=768, scale=1, freq=144)
|
||||
expect_monitors_changed(1, 0, 1, 5000)
|
||||
add_monitor('1', width=1024, height=768, scale=1, freq=144)
|
||||
expect_monitors_changed(1, 0, 1, 10000)
|
||||
expect_monitor (position=1, width=1024, height=768, scale=1, freq=144000)
|
||||
|
||||
remove_monitor("0")
|
||||
remove_monitor('0')
|
||||
expect_monitors_changed(0, 1, 0, 11000) # mutter takes 10 seconds to remove it
|
||||
|
||||
remove_monitor("1")
|
||||
remove_monitor('1')
|
||||
expect_monitors_changed(0, 1, 0, 11000)
|
||||
except AssertionError as e:
|
||||
print("Error: {0}".format(e))
|
||||
print(f'Error: {e}')
|
||||
terminate()
|
||||
|
||||
def mutter_appeared(name):
|
||||
global screen_cast
|
||||
global done
|
||||
if verbose:
|
||||
print("mutter appeared on the bus")
|
||||
print('mutter appeared on the bus')
|
||||
screen_cast = bus.get('org.gnome.Mutter.ScreenCast',
|
||||
'/org/gnome/Mutter/ScreenCast')
|
||||
run_commands()
|
||||
|
||||
if verbose:
|
||||
print ("Done running commands, exiting...")
|
||||
print ('Done running commands, exiting...')
|
||||
done = True
|
||||
|
||||
def mutter_vanished():
|
||||
global done
|
||||
if screen_cast != None:
|
||||
if verbose:
|
||||
print("mutter left the bus")
|
||||
print('mutter left the bus')
|
||||
done = True
|
||||
|
||||
bus = SessionBus()
|
||||
|
@@ -5,6 +5,7 @@ env.prepend('GI_TYPELIB_PATH',
|
||||
)
|
||||
env.prepend('LD_PRELOAD', project_build_root / 'gtk' / 'libgtk-4.so')
|
||||
env.prepend('MESON_CURRENT_SOURCE_DIR', meson.current_source_dir())
|
||||
env.prepend('MESON_CURRENT_BUILD_DIR', meson.current_build_dir())
|
||||
|
||||
test('monitor',
|
||||
find_program('run-headless-monitor-tests.sh', dirs: meson.current_source_dir()),
|
||||
|
@@ -1,26 +1,35 @@
|
||||
#! /bin/sh
|
||||
|
||||
srcdir=${MESON_CURRENT_SOURCE_DIR:-./testsuite/headless}
|
||||
builddir=${MESON_CURRENT_BUILD_DIR:-.}
|
||||
outputdir=${builddir}/input
|
||||
|
||||
dbus-run-session sh <<EOF
|
||||
mkdir -p ${outputdir}
|
||||
|
||||
export XDG_RUNTIME_DIR="$(mktemp -p $(pwd) -d xdg-runtime-XXXXXX)"
|
||||
|
||||
pipewire &
|
||||
pipewire_pid=\$!
|
||||
wireplumber &
|
||||
wireplumber_pid=\$!
|
||||
sleep 1
|
||||
|
||||
#echo DBUS_SESSION_BUS_ADDRESS=\$DBUS_SESSION_BUS_ADDRESS
|
||||
#echo WAYLAND_DISPLAY=gtk-test
|
||||
|
||||
export GTK_A11Y=none
|
||||
export GIO_USE_VFS=local
|
||||
|
||||
mutter --headless --virtual-monitor 1024x768 --no-x11 --wayland-display gtk-test2 >&mutter2.log &
|
||||
dbus-run-session sh 2>${outputdir}/dbus-stderr.log <<EOF
|
||||
|
||||
export XDG_RUNTIME_DIR="$(mktemp -p $(pwd) -d xdg-runtime-XXXXXX)"
|
||||
|
||||
pipewire >&${outputdir}/pipewire.log &
|
||||
pipewire_pid=\$!
|
||||
sleep 2
|
||||
|
||||
wireplumber >&${outputdir}/wireplumber.log &
|
||||
wireplumber_pid=\$!
|
||||
sleep 2
|
||||
|
||||
#echo DBUS_SESSION_BUS_ADDRESS=\$DBUS_SESSION_BUS_ADDRESS
|
||||
#echo WAYLAND_DISPLAY=gtk-test
|
||||
|
||||
mutter --headless --virtual-monitor 1024x768 --no-x11 --wayland-display gtk-test2 >&${outputdir}/mutter.log &
|
||||
mutter_pid=\$!
|
||||
|
||||
sleep 2
|
||||
|
||||
export WAYLAND_DISPLAY=gtk-test2
|
||||
export GDK_BACKEND=wayland
|
||||
|
||||
|
@@ -1,19 +1,24 @@
|
||||
#! /bin/sh
|
||||
|
||||
srcdir=${MESON_CURRENT_SOURCE_DIR:-./testsuite/headless}
|
||||
builddir=${MESON_CURRENT_BUILD_DIR:-.}
|
||||
outputdir=${builddir}/monitor
|
||||
|
||||
mkdir -p ${outputdir}
|
||||
|
||||
|
||||
export GTK_A11Y=none
|
||||
export GIO_USE_VFS=local
|
||||
|
||||
dbus-run-session sh <<EOF
|
||||
dbus-run-session sh 2>${outputdir}/dbus-stderr.log <<EOF
|
||||
|
||||
export XDG_RUNTIME_DIR="$(mktemp -p $(pwd) -d xdg-runtime-XXXXXX)"
|
||||
|
||||
pipewire &
|
||||
pipewire >&${outputdir}/pipewire.log &
|
||||
pipewire_pid=\$!
|
||||
sleep 2
|
||||
|
||||
wireplumber &
|
||||
wireplumber >&${outputdir}/wireplumber.log &
|
||||
wireplumber_pid=\$!
|
||||
sleep 2
|
||||
|
||||
@@ -22,7 +27,7 @@ sleep 2
|
||||
|
||||
export MUTTER_DEBUG=screen-cast
|
||||
|
||||
mutter --headless --no-x11 --wayland-display gtk-test &
|
||||
mutter --headless --no-x11 --wayland-display gtk-test >&${outputdir}/mutter.log &
|
||||
mutter_pid=\$!
|
||||
|
||||
sleep 2
|
||||
|
Reference in New Issue
Block a user