Skip to content
Commits on Source (11)
......@@ -1711,7 +1711,7 @@ handle_non_csi_escape(struct terminal *terminal, char code)
break;
case 'E': /* NEL - Newline */
terminal->column = 0;
// fallthrough
FALLTHROUGH;
case 'D': /* IND - Linefeed */
terminal->row += 1;
if (terminal->row > terminal->margin_bottom) {
......@@ -1893,7 +1893,7 @@ handle_special_char(struct terminal *terminal, char c)
if (terminal->mode & MODE_LF_NEWLINE) {
terminal->column = 0;
}
/* fallthrough */
FALLTHROUGH;
case '\v':
case '\f':
terminal->row++;
......
......@@ -398,13 +398,13 @@ get_output_work_area(struct desktop_shell *shell,
switch (shell->panel_position) {
case WESTON_DESKTOP_SHELL_PANEL_POSITION_TOP:
area->y += sh_output->panel_surface->height;
/* fallthrough */
FALLTHROUGH;
case WESTON_DESKTOP_SHELL_PANEL_POSITION_BOTTOM:
area->height -= sh_output->panel_surface->height;
break;
case WESTON_DESKTOP_SHELL_PANEL_POSITION_LEFT:
area->x += sh_output->panel_surface->width;
/* fallthrough */
FALLTHROUGH;
case WESTON_DESKTOP_SHELL_PANEL_POSITION_RIGHT:
area->width -= sh_output->panel_surface->width;
break;
......
......@@ -2941,8 +2941,8 @@ wayland_backend_create(struct weston_compositor *compositor,
if (renderer != WESTON_RENDERER_PIXMAN)
break;
weston_log_continue("; falling back to Pixman.\n");
FALLTHROUGH;
}
/* fallthrough */
case WESTON_RENDERER_PIXMAN:
if (weston_compositor_init_renderer(compositor,
WESTON_RENDERER_PIXMAN,
......
......@@ -87,7 +87,7 @@ compile_const int c_color_post_curve = DEF_COLOR_POST_CURVE;
compile_const int c_color_channel_order = DEF_COLOR_CHANNEL_ORDER;
compile_const bool c_input_is_premult = DEF_INPUT_IS_PREMULT;
compile_const bool c_green_tint = DEF_GREEN_TINT;
compile_const bool c_tint = DEF_TINT;
compile_const bool c_wireframe = DEF_WIREFRAME;
compile_const bool c_need_color_pipeline =
c_color_pre_curve != SHADER_COLOR_CURVE_IDENTITY ||
......@@ -138,6 +138,7 @@ uniform sampler2D tex2;
uniform sampler2D tex_wireframe;
uniform float view_alpha;
uniform vec4 unicolor;
uniform vec4 tint;
#define MAX_CURVE_PARAMS 10
#define MAX_CURVESET_PARAMS (MAX_CURVE_PARAMS * 3)
......@@ -437,9 +438,8 @@ wireframe()
float edge1 = texture2D(tex_wireframe, vec2(v_barycentric.x, 0.5)).r;
float edge2 = texture2D(tex_wireframe, vec2(v_barycentric.y, 0.5)).r;
float edge3 = texture2D(tex_wireframe, vec2(v_barycentric.z, 0.5)).r;
float edge = clamp(edge1 + edge2 + edge3, 0.0, 1.0);
return vec4(edge) * v_color;
return vec4(clamp(edge1 + edge2 + edge3, 0.0, 1.0));
}
void
......@@ -459,8 +459,8 @@ main()
color *= view_alpha;
if (c_green_tint)
color = vec4(0.0, 0.3, 0.0, 0.2) + color * 0.8;
if (c_tint)
color = color * vec4(1.0 - tint.a) + tint;
if (c_wireframe) {
vec4 src = wireframe();
......
......@@ -75,7 +75,6 @@ enum gl_shader_color_mapping {
enum gl_shader_attrib_loc {
SHADER_ATTRIB_LOC_POSITION = 0,
SHADER_ATTRIB_LOC_TEXCOORD,
SHADER_ATTRIB_LOC_COLOR,
SHADER_ATTRIB_LOC_BARYCENTRIC,
};
......@@ -94,7 +93,7 @@ struct gl_shader_requirements
unsigned variant:4; /* enum gl_shader_texture_variant */
bool input_is_premult:1;
bool green_tint:1;
bool tint:1;
bool wireframe:1;
unsigned color_pre_curve:2; /* enum gl_shader_color_curve */
......@@ -125,6 +124,7 @@ struct gl_shader_config {
struct weston_matrix surface_to_buffer;
float view_alpha;
GLfloat unicolor[4];
GLfloat tint[4];
GLint input_tex_filter; /* GL_NEAREST or GL_LINEAR */
GLuint input_tex[GL_SHADER_INPUT_TEX_MAX];
GLuint wireframe_tex;
......@@ -165,14 +165,14 @@ struct gl_renderer {
struct weston_compositor *compositor;
struct weston_log_scope *renderer_scope;
struct weston_binding *fragment_binding;
bool fragment_shader_debug;
struct weston_binding *wireframe_binding;
bool wireframe_debug;
/* Debug modes. */
struct weston_binding *debug_mode_binding;
int debug_mode;
bool debug_clear;
bool wireframe_dirty;
GLuint wireframe_tex;
int wireframe_size;
int nbatches;
EGLenum platform;
EGLDisplay egl_display;
......@@ -183,7 +183,6 @@ struct gl_renderer {
/* Vertex streams. */
struct wl_array position_stream;
struct wl_array color_stream;
struct wl_array barycentric_stream;
struct wl_array indices;
......
......@@ -66,6 +66,15 @@
#define BUFFER_DAMAGE_COUNT 2
enum gl_debug_mode {
DEBUG_MODE_NONE = 0,
DEBUG_MODE_WIREFRAME,
DEBUG_MODE_BATCHES,
DEBUG_MODE_DAMAGE,
DEBUG_MODE_OPAQUE,
DEBUG_MODE_LAST,
};
enum gl_border_status {
BORDER_STATUS_CLEAN = 0,
BORDER_TOP_DIRTY = 1 << GL_RENDERER_BORDER_TOP,
......@@ -248,6 +257,12 @@ dump_format(uint32_t format, char out[4])
return out;
}
static inline void
copy_uniform4f(float dst[4], const float src[4])
{
memcpy(dst, src, 4 * sizeof(float));
}
static inline struct gl_output_state *
get_output_state(struct weston_output *output)
{
......@@ -1139,8 +1154,7 @@ gl_shader_config_set_input_textures(struct gl_shader_config *sconf,
sconf->req.input_is_premult =
gl_shader_texture_variant_can_be_premult(gb->shader_variant);
for (i = 0; i < 4; i++)
sconf->unicolor[i] = gb->color[i];
copy_uniform4f(sconf->unicolor, gb->color);
assert(gb->num_textures <= GL_SHADER_INPUT_TEX_MAX);
for (i = 0; i < gb->num_textures; i++)
......@@ -1300,17 +1314,14 @@ transform_damage(const struct weston_paint_node *pnode,
free(rects);
}
/* Colorise and set barycentric coordinates of a sub-mesh of 'count' vertices. 8
* colors (32 bytes) and 8 barycentric coordinates (32 bytes too) are stored
* unconditionally into 'color_stream' and 'barycentric_stream'.
/* Set barycentric coordinates of a sub-mesh of 'count' vertices. 8 barycentric
* coordinates (32 bytes too) are stored unconditionally into
* 'barycentric_stream'.
*/
static void
store_wireframes(size_t count,
uint32_t *restrict color_stream,
uint32_t *restrict barycentric_stream)
uint32_t *barycentric_stream)
{
static const uint32_t colors[] =
{ 0xff0000ff, 0xff00ff00, 0xffff0000, 0xfffffff };
const uint32_t x = 0xff0000, y = 0x00ff00, z = 0x0000ff;
static const uint32_t barycentrics[][8] = {
{}, {}, {},
......@@ -1321,17 +1332,12 @@ store_wireframes(size_t count,
{ x, z, y, x, z, x, y, 0 },
{ x, z, y, x, y, z, x, y },
};
static size_t idx = 0;
int i;
assert(count < ARRAY_LENGTH(barycentrics));
for (i = 0; i < 8; i++) {
for (i = 0; i < 8; i++)
barycentric_stream[i] = barycentrics[count][i];
color_stream[i] = colors[idx % ARRAY_LENGTH(colors)];
}
idx++;
}
/* Triangulate a sub-mesh of 'count' vertices as an indexed triangle strip.
......@@ -1368,44 +1374,89 @@ store_indices(size_t count,
}
static void
draw_mesh(struct gl_renderer *gr,
struct weston_paint_node *pnode,
struct gl_shader_config *sconf,
const struct clipper_vertex *positions,
const uint32_t *colors,
const uint32_t *barycentrics,
const uint16_t *strip,
int nstrip,
bool wireframe)
set_debug_mode(struct gl_renderer *gr,
struct gl_shader_config *sconf,
const uint32_t *barycentrics,
bool opaque)
{
assert(nstrip > 0);
/* Debug mode tints indexed by gl_debug_mode enumeration. While tints
* are meant to be premultiplied, debug modes can have invalid colors in
* order to create visual effects. */
static const float tints[DEBUG_MODE_LAST][4] = {
{}, /* DEBUG_MODE_NONE */
{ 0.0f, 0.0f, 0.0f, 0.3f }, /* DEBUG_MODE_WIREFRAME */
{}, /* DEBUG_MODE_BATCHES */
{ 0.4f, -0.4f, -0.4f, 0.0f }, /* DEBUG_MODE_DAMAGE */
{ -0.4f, -0.4f, 0.7f, 0.0f }, /* DEBUG_MODE_OPAQUE */
};
static const float batch_tints[][4] = {
{ 0.9f, 0.0f, 0.0f, 0.9f },
{ 0.0f, 0.9f, 0.0f, 0.9f },
{ 0.0f, 0.0f, 0.9f, 0.9f },
{ 0.9f, 0.9f, 0.0f, 0.9f },
{ 0.9f, 0.0f, 0.9f, 0.9f },
{ 0.0f, 0.9f, 0.9f, 0.9f },
{ 0.9f, 0.9f, 0.9f, 0.9f },
};
int i;
if (wireframe) {
switch (gr->debug_mode) {
case DEBUG_MODE_WIREFRAME:
/* Wireframe rendering is based on Celes & Abraham's "Fast and
* versatile texture-based wireframe rendering", 2011. */
glEnableVertexAttribArray(SHADER_ATTRIB_LOC_COLOR);
sconf->req.wireframe = true;
sconf->wireframe_tex = gr->wireframe_tex;
glEnableVertexAttribArray(SHADER_ATTRIB_LOC_BARYCENTRIC);
glVertexAttribPointer(SHADER_ATTRIB_LOC_COLOR, 4,
GL_UNSIGNED_BYTE, GL_TRUE, 0, colors);
glVertexAttribPointer(SHADER_ATTRIB_LOC_BARYCENTRIC, 4,
GL_UNSIGNED_BYTE, GL_TRUE, 0,
barycentrics);
FALLTHROUGH;
sconf->req.wireframe = wireframe;
sconf->wireframe_tex = gr->wireframe_tex;
case DEBUG_MODE_DAMAGE:
sconf->req.tint = true;
copy_uniform4f(sconf->tint, tints[gr->debug_mode]);
break;
case DEBUG_MODE_OPAQUE:
sconf->req.tint = opaque;
copy_uniform4f(sconf->tint, tints[gr->debug_mode]);
break;
case DEBUG_MODE_BATCHES:
sconf->req.tint = true;
i = gr->nbatches++ % ARRAY_LENGTH(batch_tints);
copy_uniform4f(sconf->tint, batch_tints[i]);
break;
default:
unreachable("Invalid debug mode");
}
}
static void
draw_mesh(struct gl_renderer *gr,
struct weston_paint_node *pnode,
struct gl_shader_config *sconf,
const struct clipper_vertex *positions,
const uint32_t *barycentrics,
const uint16_t *indices,
int nidx,
bool opaque)
{
assert(nidx > 0);
if (gr->debug_mode)
set_debug_mode(gr, sconf, barycentrics, opaque);
if (!gl_renderer_use_program(gr, sconf))
gl_renderer_send_shader_error(pnode); /* Use fallback shader. */
glVertexAttribPointer(SHADER_ATTRIB_LOC_POSITION, 2, GL_FLOAT, GL_FALSE,
0, positions);
glDrawElements(GL_TRIANGLE_STRIP, nstrip, GL_UNSIGNED_SHORT, strip);
glDrawElements(GL_TRIANGLE_STRIP, nidx, GL_UNSIGNED_SHORT, indices);
if (wireframe) {
if (gr->debug_mode == DEBUG_MODE_WIREFRAME)
glDisableVertexAttribArray(SHADER_ATTRIB_LOC_BARYCENTRIC);
glDisableVertexAttribArray(SHADER_ATTRIB_LOC_COLOR);
}
}
static void
......@@ -1414,15 +1465,16 @@ repaint_region(struct gl_renderer *gr,
struct clipper_quad *quads,
int nquads,
pixman_region32_t *region,
struct gl_shader_config *sconf)
struct gl_shader_config *sconf,
bool opaque)
{
pixman_box32_t *rects;
struct clipper_vertex *positions;
uint32_t *colors = NULL, *barycentrics = NULL;
uint32_t *barycentrics = NULL;
uint16_t *indices;
int i, j, n, nrects, positions_size, colors_size, barycentrics_size;
int indices_size, nvtx = 0, nidx = 0;
bool wireframe = gr->wireframe_debug;
int i, j, n, nrects, positions_size, barycentrics_size, indices_size;
int nvtx = 0, nidx = 0;
bool wireframe = gr->debug_mode == DEBUG_MODE_WIREFRAME;
/* Build-time sub-mesh constants. Clipping emits 8 vertices max.
* store_indices() store at most 10 indices. */
......@@ -1435,17 +1487,14 @@ repaint_region(struct gl_renderer *gr,
/* Worst case allocation sizes per sub-mesh. */
n = nquads * nrects;
positions_size = n * nvtx_max * sizeof *positions;
colors_size = ROUND_UP_N(n * nvtx_max * sizeof *colors, 32);
barycentrics_size = ROUND_UP_N(n * nvtx_max * sizeof *barycentrics, 32);
indices_size = ROUND_UP_N(n * nidx_max * sizeof *indices, 32);
positions = wl_array_add(&gr->position_stream, positions_size);
indices = wl_array_add(&gr->indices, indices_size);
if (wireframe) {
colors = wl_array_add(&gr->color_stream, colors_size);
if (wireframe)
barycentrics = wl_array_add(&gr->barycentric_stream,
barycentrics_size);
}
/* A node's damage mesh is created by clipping damage quads to surface
* rects and by chaining the resulting sub-meshes into an indexed
......@@ -1471,31 +1520,28 @@ repaint_region(struct gl_renderer *gr,
&positions[nvtx]);
nidx += store_indices(n, nvtx, &indices[nidx]);
if (wireframe)
store_wireframes(n, &colors[nvtx],
&barycentrics[nvtx]);
store_wireframes(n, &barycentrics[nvtx]);
nvtx += n;
/* Highly unlikely flush to prevent index wraparound.
* Subtracting 2 removes the last chaining indices. */
if ((nvtx + nvtx_max) > UINT16_MAX) {
draw_mesh(gr, pnode, sconf, positions, colors,
draw_mesh(gr, pnode, sconf, positions,
barycentrics, indices, nidx - 2,
wireframe);
opaque);
nvtx = nidx = 0;
}
}
}
if (nvtx)
draw_mesh(gr, pnode, sconf, positions, colors, barycentrics,
indices, nidx - 2, wireframe);
draw_mesh(gr, pnode, sconf, positions, barycentrics, indices,
nidx - 2, opaque);
gr->position_stream.size = 0;
gr->indices.size = 0;
if (wireframe) {
gr->color_stream.size = 0;
if (wireframe)
gr->barycentric_stream.size = 0;
}
}
static void
......@@ -1583,14 +1629,16 @@ draw_paint_node(struct weston_paint_node *pnode,
glDisable(GL_BLEND);
transform_damage(pnode, &repaint, &quads, &nquads);
repaint_region(gr, pnode, quads, nquads, &surface_opaque, &alt);
repaint_region(gr, pnode, quads, nquads, &surface_opaque, &alt,
true);
gs->used_in_output_repaint = true;
}
if (pixman_region32_not_empty(&surface_blend)) {
glEnable(GL_BLEND);
transform_damage(pnode, &repaint, &quads, &nquads);
repaint_region(gr, pnode, quads, nquads, &surface_blend, &sconf);
repaint_region(gr, pnode, quads, nquads, &surface_blend, &sconf,
false);
gs->used_in_output_repaint = true;
}
......@@ -1607,8 +1655,11 @@ out:
static void
repaint_views(struct weston_output *output, pixman_region32_t *damage)
{
struct gl_renderer *gr = get_renderer(output->compositor);
struct weston_paint_node *pnode;
gr->nbatches = 0;
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glEnableVertexAttribArray(SHADER_ATTRIB_LOC_POSITION);
......@@ -1702,7 +1753,7 @@ update_wireframe_tex(struct gl_renderer *gr,
int new_size, i;
uint8_t *buffer;
if (!gr->wireframe_debug) {
if (gr->debug_mode != DEBUG_MODE_WIREFRAME) {
if (gr->wireframe_size) {
glDeleteTextures(1, &gr->wireframe_tex);
gr->wireframe_size = 0;
......@@ -2226,18 +2277,20 @@ gl_renderer_repaint_output(struct weston_output *output,
* any wireframes left over from previous draws on this buffer. This
* precludes the use of EGL_EXT_swap_buffers_with_damage and
* EGL_KHR_partial_update, since we damage the whole area. */
if (gr->wireframe_debug) {
if (gr->debug_clear) {
pixman_region32_t undamaged;
int debug_mode = gr->debug_mode;
pixman_region32_init(&undamaged);
pixman_region32_subtract(&undamaged, &output->region,
output_damage);
gr->wireframe_debug = false;
gr->debug_mode = DEBUG_MODE_NONE;
repaint_views(output, &undamaged);
gr->wireframe_debug = true;
gr->debug_mode = debug_mode;
pixman_region32_fini(&undamaged);
}
if (gr->has_egl_partial_update && !gr->wireframe_debug) {
if (gr->has_egl_partial_update && !gr->debug_clear) {
int n_egl_rects;
EGLint *egl_rects;
......@@ -2283,7 +2336,7 @@ gl_renderer_repaint_output(struct weston_output *output,
if (go->egl_surface != EGL_NO_SURFACE) {
EGLBoolean ret;
if (gr->swap_buffers_with_damage && !gr->wireframe_debug) {
if (gr->swap_buffers_with_damage && !gr->debug_clear) {
int n_egl_rects;
EGLint *egl_rects;
......@@ -2333,7 +2386,7 @@ gl_renderer_repaint_output(struct weston_output *output,
extents = weston_matrix_transform_rect(&output->matrix,
rb->base.damage.extents);
if (gr->wireframe_debug) {
if (gr->debug_clear) {
rect.y = go->fb_size.height - go->area.y - go->area.height;
rect.height = go->area.height;
} else {
......@@ -2342,8 +2395,7 @@ gl_renderer_repaint_output(struct weston_output *output,
pixels += rect.width * extents.y1;
}
if (gr->gl_version >= gr_gl_version(3, 0) &&
! gr->wireframe_debug) {
if (gr->gl_version >= gr_gl_version(3, 0) && !gr->debug_clear) {
glPixelStorei(GL_PACK_ROW_LENGTH, width);
rect.width = extents.x2 - extents.x1;
rect.x += extents.x1;
......@@ -4145,14 +4197,11 @@ gl_renderer_destroy(struct weston_compositor *ec)
eglReleaseThread();
wl_array_release(&gr->position_stream);
wl_array_release(&gr->color_stream);
wl_array_release(&gr->barycentric_stream);
wl_array_release(&gr->indices);
if (gr->fragment_binding)
weston_binding_destroy(gr->fragment_binding);
if (gr->wireframe_binding)
weston_binding_destroy(gr->wireframe_binding);
if (gr->debug_mode_binding)
weston_binding_destroy(gr->debug_mode_binding);
weston_log_scope_destroy(gr->shader_scope);
weston_log_scope_destroy(gr->renderer_scope);
......@@ -4353,30 +4402,22 @@ fail:
}
static void
fragment_debug_binding(struct weston_keyboard *keyboard,
const struct timespec *time,
uint32_t key, void *data)
{
struct weston_compositor *ec = data;
struct gl_renderer *gr = get_renderer(ec);
struct weston_output *output;
gr->fragment_shader_debug = !gr->fragment_shader_debug;
wl_list_for_each(output, &ec->output_list, link)
weston_output_damage(output);
}
static void
wireframe_debug_repaint_binding(struct weston_keyboard *keyboard,
const struct timespec *time,
uint32_t key, void *data)
debug_mode_binding(struct weston_keyboard *keyboard,
const struct timespec *time,
uint32_t key, void *data)
{
struct weston_compositor *compositor = data;
struct gl_renderer *gr = get_renderer(compositor);
int mode;
mode = (gr->debug_mode + 1) % DEBUG_MODE_LAST;
gr->debug_mode = mode;
gr->debug_clear = mode == DEBUG_MODE_WIREFRAME ||
mode == DEBUG_MODE_BATCHES ||
mode == DEBUG_MODE_DAMAGE ||
mode == DEBUG_MODE_OPAQUE;
gr->wireframe_dirty = mode == DEBUG_MODE_WIREFRAME;
gr->wireframe_debug = !gr->wireframe_debug;
gr->wireframe_dirty = true;
weston_compositor_damage_all(compositor);
}
......@@ -4608,14 +4649,9 @@ gl_renderer_setup(struct weston_compositor *ec)
return -1;
}
gr->fragment_binding =
weston_compositor_add_debug_binding(ec, KEY_S,
fragment_debug_binding,
ec);
gr->wireframe_binding =
weston_compositor_add_debug_binding(ec, KEY_F,
wireframe_debug_repaint_binding,
ec);
gr->debug_mode_binding =
weston_compositor_add_debug_binding(ec, KEY_M,
debug_mode_binding, ec);
weston_log("GL ES %d.%d - renderer features:\n",
gr_gl_version_major(gr->gl_version),
......
......@@ -64,6 +64,7 @@ struct gl_shader {
GLint tex_uniform_wireframe;
GLint view_alpha_uniform;
GLint color_uniform;
GLint tint_uniform;
union {
struct {
GLint tex_2d_uniform;
......@@ -235,7 +236,7 @@ create_shader_description_string(const struct gl_shader_requirements *req)
int size;
char *str;
size = asprintf(&str, "%s %s %s %s %s %s %cinput_is_premult %cgreen",
size = asprintf(&str, "%s %s %s %s %s %s %cinput_is_premult %ctint",
gl_shader_texcoord_input_to_string(req->texcoord_input),
gl_shader_texture_variant_to_string(req->variant),
gl_shader_color_curve_to_string(req->color_pre_curve),
......@@ -243,7 +244,7 @@ create_shader_description_string(const struct gl_shader_requirements *req)
gl_shader_color_curve_to_string(req->color_post_curve),
gl_shader_color_order_to_string(req->color_channel_order),
req->input_is_premult ? '+' : '-',
req->green_tint ? '+' : '-');
req->tint ? '+' : '-');
if (size < 0)
return NULL;
return str;
......@@ -277,7 +278,7 @@ create_fragment_shader_config_string(const struct gl_shader_requirements *req)
req->color_channel_order == SHADER_CHANNEL_ORDER_RGBA);
size = asprintf(&str,
"#define DEF_GREEN_TINT %s\n"
"#define DEF_TINT %s\n"
"#define DEF_INPUT_IS_PREMULT %s\n"
"#define DEF_WIREFRAME %s\n"
"#define DEF_COLOR_PRE_CURVE %s\n"
......@@ -285,7 +286,7 @@ create_fragment_shader_config_string(const struct gl_shader_requirements *req)
"#define DEF_COLOR_POST_CURVE %s\n"
"#define DEF_COLOR_CHANNEL_ORDER %s\n"
"#define DEF_VARIANT %s\n",
req->green_tint ? "true" : "false",
req->tint ? "true" : "false",
req->input_is_premult ? "true" : "false",
req->wireframe ? "true" : "false",
gl_shader_color_curve_to_string(req->color_pre_curve),
......@@ -360,13 +361,10 @@ gl_shader_create(struct gl_renderer *gr,
if (requirements->texcoord_input == SHADER_TEXCOORD_INPUT_ATTRIB)
glBindAttribLocation(shader->program,
SHADER_ATTRIB_LOC_TEXCOORD, "texcoord");
if (requirements->wireframe) {
glBindAttribLocation(shader->program, SHADER_ATTRIB_LOC_COLOR,
"color");
if (requirements->wireframe)
glBindAttribLocation(shader->program,
SHADER_ATTRIB_LOC_BARYCENTRIC,
"barycentric");
}
glLinkProgram(shader->program);
glGetProgramiv(shader->program, GL_LINK_STATUS, &status);
......@@ -396,6 +394,13 @@ gl_shader_create(struct gl_renderer *gr,
} else {
shader->color_uniform = -1;
}
if (requirements->tint) {
shader->tint_uniform = glGetUniformLocation(shader->program,
"tint");
assert(shader->tint_uniform != -1);
} else {
shader->tint_uniform = -1;
}
switch(requirements->color_pre_curve) {
case SHADER_COLOR_CURVE_IDENTITY:
......@@ -587,9 +592,6 @@ gl_renderer_get_program(struct gl_renderer *gr,
assert(reqs.pad_bits_ == 0);
if (gr->fragment_shader_debug)
reqs.green_tint = true;
if (gr->current_shader &&
gl_shader_requirements_cmp(&reqs, &gr->current_shader->key) == 0)
return gr->current_shader;
......@@ -673,6 +675,8 @@ gl_shader_load_config(struct gl_shader *shader,
if (shader->color_uniform != -1)
glUniform4fv(shader->color_uniform, 1, sconf->unicolor);
if (shader->tint_uniform != -1)
glUniform4fv(shader->tint_uniform, 1, sconf->tint);
glUniform1f(shader->view_alpha_uniform, sconf->view_alpha);
......
......@@ -46,12 +46,10 @@ uniform mat4 surface_to_buffer;
attribute vec2 position;
attribute vec2 texcoord;
attribute vec4 color;
attribute vec4 barycentric;
/* Match the varying precision to the fragment shader */
varying FRAG_PRECISION vec2 v_texcoord;
varying FRAG_PRECISION vec4 v_color;
varying FRAG_PRECISION vec3 v_barycentric;
compile_const int c_texcoord_input = DEF_TEXCOORD_INPUT;
......@@ -66,8 +64,6 @@ void main()
else if (c_texcoord_input == SHADER_TEXCOORD_INPUT_SURFACE)
v_texcoord = vec2(surface_to_buffer * vec4(position, 0.0, 1.0));
if (c_wireframe) {
v_color = color;
if (c_wireframe)
v_barycentric = barycentric.xyz;
}
}
......@@ -124,9 +124,9 @@ Rotate the window (if supported)
.SS DEBUG BINDINGS
The combination \fBmod + Shift + Space\fR begins a debug binding. Debug
bindings are completed by pressing an additional key. For example, pressing
F may toggle texture mesh wireframes with the GL renderer.
(In fact, most debug effects can be disabled again by repeating the command.)
Debug bindings are often tied to specific backends. Below are the debug bindings available.
M may cycle through the GL renderer debug modes. Most debug effects can be
disabled again by repeating the command. Debug bindings are often tied to
specific backends. Below are the debug bindings available.
.RS
- KEY_D :
......@@ -145,13 +145,9 @@ Enable/Disable overlay planes.
.RS 4
Start VAAPI recorder.
.RE
- KEY_S :
- KEY_M :
.RS 4
Enable fragment debugging for gl-renderer.
.RE
- KEY_F :
.RS 4
Enable wireframe debugging for gl-renderer.
Cycle through gl-renderer debug modes: none, wireframe, batches, damage, opaque.
.RE
- KEY_R :
.RS 4
......
......@@ -235,6 +235,13 @@ do { \
#define unreachable(str) assert(!str)
#endif
#if __has_attribute(fallthrough)
/* Supported at least by gcc and clang. */
#define FALLTHROUGH __attribute__((fallthrough))
#else
#define FALLTHROUGH do {} while(0)
#endif
/**
* Returns number of bits set in 32-bit value x.
*
......
......@@ -728,31 +728,31 @@ create_subsurface_tree(struct client *client, struct wl_surface **surfs,
case 11:
SUB_LINK(10, 2);
/* fallthrough */
FALLTHROUGH;
case 10:
SUB_LINK(9, 2);
/* fallthrough */
FALLTHROUGH;
case 9:
SUB_LINK(8, 6);
/* fallthrough */
FALLTHROUGH;
case 8:
SUB_LINK(7, 6);
/* fallthrough */
FALLTHROUGH;
case 7:
SUB_LINK(6, 2);
/* fallthrough */
FALLTHROUGH;
case 6:
SUB_LINK(5, 1);
/* fallthrough */
FALLTHROUGH;
case 5:
SUB_LINK(4, 3);
/* fallthrough */
FALLTHROUGH;
case 4:
SUB_LINK(3, 1);
/* fallthrough */
FALLTHROUGH;
case 3:
SUB_LINK(2, 0);
/* fallthrough */
FALLTHROUGH;
case 2:
SUB_LINK(1, 0);
......