mirror of
https://gitlab.freedesktop.org/wayland/weston
synced 2024-07-05 17:29:06 +00:00
Compare commits
3 Commits
7abe5a62f1
...
56f2d01c25
Author | SHA1 | Date | |
---|---|---|---|
|
56f2d01c25 | ||
|
4566eae245 | ||
|
0729ffbdb8 |
|
@ -88,7 +88,7 @@ static inline const char *
|
|||
dump_format(uint32_t format, char out[4])
|
||||
{
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
format = __builtin_bswap32(format);
|
||||
format = bswap32(format);
|
||||
#endif
|
||||
memcpy(out, &format, 4);
|
||||
return out;
|
||||
|
|
|
@ -201,7 +201,7 @@ data_offer_set_actions(struct wl_client *client,
|
|||
|
||||
if (preferred_action &&
|
||||
(!(preferred_action & dnd_actions) ||
|
||||
__builtin_popcount(preferred_action) > 1)) {
|
||||
bitcount32(preferred_action) > 1)) {
|
||||
wl_resource_post_error(offer->resource,
|
||||
WL_DATA_OFFER_ERROR_INVALID_ACTION,
|
||||
"invalid action %x", preferred_action);
|
||||
|
|
|
@ -131,8 +131,11 @@ uniform sampler2D tex;
|
|||
|
||||
varying HIGHPRECISION vec2 v_texcoord;
|
||||
varying HIGHPRECISION vec4 v_color;
|
||||
varying HIGHPRECISION vec3 v_barycentric;
|
||||
|
||||
uniform sampler2D tex1;
|
||||
uniform sampler2D tex2;
|
||||
uniform sampler2D tex_wireframe;
|
||||
uniform float view_alpha;
|
||||
uniform vec4 unicolor;
|
||||
|
||||
|
@ -428,6 +431,17 @@ color_pipeline(vec4 color)
|
|||
return color;
|
||||
}
|
||||
|
||||
vec4
|
||||
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;
|
||||
}
|
||||
|
||||
void
|
||||
main()
|
||||
{
|
||||
|
@ -436,9 +450,6 @@ main()
|
|||
/* Electrical (non-linear) RGBA values, may be premult or not */
|
||||
color = sample_input_texture();
|
||||
|
||||
if (c_wireframe)
|
||||
color *= v_color;
|
||||
|
||||
if (c_need_color_pipeline)
|
||||
color = color_pipeline(color); /* Produces straight alpha */
|
||||
|
||||
|
@ -451,5 +462,10 @@ main()
|
|||
if (c_green_tint)
|
||||
color = vec4(0.0, 0.3, 0.0, 0.2) + color * 0.8;
|
||||
|
||||
if (c_wireframe) {
|
||||
vec4 src = wireframe();
|
||||
color = color * vec4(1.0 - src.a) + src;
|
||||
}
|
||||
|
||||
gl_FragColor = color;
|
||||
}
|
||||
|
|
|
@ -76,6 +76,7 @@ enum gl_shader_attrib_loc {
|
|||
SHADER_ATTRIB_LOC_POSITION = 0,
|
||||
SHADER_ATTRIB_LOC_TEXCOORD,
|
||||
SHADER_ATTRIB_LOC_COLOR,
|
||||
SHADER_ATTRIB_LOC_BARYCENTRIC,
|
||||
};
|
||||
|
||||
/** GL shader requirements key
|
||||
|
@ -115,6 +116,8 @@ struct gl_shader;
|
|||
struct weston_color_transform;
|
||||
|
||||
#define GL_SHADER_INPUT_TEX_MAX 3
|
||||
#define GL_SHADER_WIREFRAME_TEX_UNIT GL_SHADER_INPUT_TEX_MAX
|
||||
|
||||
struct gl_shader_config {
|
||||
struct gl_shader_requirements req;
|
||||
|
||||
|
@ -124,6 +127,7 @@ struct gl_shader_config {
|
|||
GLfloat unicolor[4];
|
||||
GLint input_tex_filter; /* GL_NEAREST or GL_LINEAR */
|
||||
GLuint input_tex[GL_SHADER_INPUT_TEX_MAX];
|
||||
GLuint wireframe_tex;
|
||||
|
||||
union {
|
||||
struct {
|
||||
|
@ -161,10 +165,14 @@ struct gl_renderer {
|
|||
struct weston_compositor *compositor;
|
||||
struct weston_log_scope *renderer_scope;
|
||||
|
||||
bool fragment_shader_debug;
|
||||
bool wireframe_debug;
|
||||
struct weston_binding *fragment_binding;
|
||||
bool fragment_shader_debug;
|
||||
|
||||
struct weston_binding *wireframe_binding;
|
||||
bool wireframe_debug;
|
||||
bool wireframe_dirty;
|
||||
GLuint wireframe_tex;
|
||||
int wireframe_size;
|
||||
|
||||
EGLenum platform;
|
||||
EGLDisplay egl_display;
|
||||
|
@ -176,7 +184,8 @@ struct gl_renderer {
|
|||
/* Vertex streams. */
|
||||
struct wl_array position_stream;
|
||||
struct wl_array color_stream;
|
||||
struct wl_array indices[2];
|
||||
struct wl_array barycentric_stream;
|
||||
struct wl_array indices;
|
||||
|
||||
EGLDeviceEXT egl_device;
|
||||
const char *drm_device;
|
||||
|
|
|
@ -242,7 +242,7 @@ static inline const char *
|
|||
dump_format(uint32_t format, char out[4])
|
||||
{
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
format = __builtin_bswap32(format);
|
||||
format = bswap32(format);
|
||||
#endif
|
||||
memcpy(out, &format, 4);
|
||||
return out;
|
||||
|
@ -1300,64 +1300,38 @@ transform_damage(const struct weston_paint_node *pnode,
|
|||
free(rects);
|
||||
}
|
||||
|
||||
/* Colorise a wireframe sub-mesh. 8 colors (32 bytes) are stored unconditionally
|
||||
* into 'color_stream'.
|
||||
/* 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'.
|
||||
*/
|
||||
static void
|
||||
store_wireframes(uint32_t *color_stream)
|
||||
store_wireframes(size_t count,
|
||||
uint32_t *restrict color_stream,
|
||||
uint32_t *restrict 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] = {
|
||||
{}, {}, {},
|
||||
{ x, z, y, 0, 0, 0, 0, 0 },
|
||||
{ x, z, x, y, 0, 0, 0, 0 },
|
||||
{ x, z, y, x, y, 0, 0, 0 },
|
||||
{ x, z, y, z, x, y, 0, 0 },
|
||||
{ x, z, y, x, z, x, y, 0 },
|
||||
{ x, z, y, x, y, z, x, y },
|
||||
};
|
||||
static size_t idx = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
color_stream[i] = colors[idx % ARRAY_LENGTH(colors)];
|
||||
assert(count < ARRAY_LENGTH(barycentrics));
|
||||
|
||||
idx++;
|
||||
for (i = 0; i < 8; i++) {
|
||||
barycentric_stream[i] = barycentrics[count][i];
|
||||
color_stream[i] = colors[idx % ARRAY_LENGTH(colors)];
|
||||
}
|
||||
|
||||
/* Triangulate a wireframe sub-mesh of 'count' vertices as indexed lines. 'bias'
|
||||
* is added to each index. 'count' must be less than or equal to 8. 32 indices
|
||||
* (64 bytes) are stored unconditionally into 'indices'. The return value is the
|
||||
* index count.
|
||||
*/
|
||||
static int
|
||||
store_lines(size_t count,
|
||||
uint16_t bias,
|
||||
uint16_t *indices)
|
||||
{
|
||||
/* Look-up table of triangle lines with last entry storing the index
|
||||
* count. Padded to 32 elements for compilers to emit packed adds. */
|
||||
static const uint16_t lines[][32] = {
|
||||
{}, {}, {}, {
|
||||
2, 0, 0, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6
|
||||
},{
|
||||
3, 0, 0, 1, 1, 2, 2, 3, 3, 1, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10
|
||||
},{
|
||||
4, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 1, 1, 3, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14
|
||||
},{
|
||||
5, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 1, 1, 4,
|
||||
4, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18
|
||||
},{
|
||||
6, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 1,
|
||||
1, 5, 5, 2, 2, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22
|
||||
},{
|
||||
7, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7,
|
||||
7, 1, 1, 6, 6, 2, 2, 5, 5, 3, 0, 0, 0, 0, 0, 26
|
||||
},
|
||||
};
|
||||
int i;
|
||||
|
||||
assert(count < ARRAY_LENGTH(lines));
|
||||
|
||||
for (i = 0; i < 32; i++)
|
||||
indices[i] = lines[count][i] + bias;
|
||||
|
||||
return lines[count][31];
|
||||
idx++;
|
||||
}
|
||||
|
||||
/* Triangulate a sub-mesh of 'count' vertices as an indexed triangle strip.
|
||||
|
@ -1368,7 +1342,7 @@ store_lines(size_t count,
|
|||
* indices.
|
||||
*/
|
||||
static int
|
||||
store_strips(size_t count,
|
||||
store_indices(size_t count,
|
||||
uint16_t bias,
|
||||
uint16_t *indices)
|
||||
{
|
||||
|
@ -1396,55 +1370,43 @@ store_strips(size_t count,
|
|||
static void
|
||||
draw_mesh(struct gl_renderer *gr,
|
||||
struct weston_paint_node *pnode,
|
||||
const struct gl_shader_config *sconf,
|
||||
struct gl_shader_config *sconf,
|
||||
const struct clipper_vertex *positions,
|
||||
const uint32_t *colors,
|
||||
const uint32_t *barycentrics,
|
||||
const uint16_t *strip,
|
||||
int nstrip,
|
||||
const uint16_t *lines,
|
||||
int nlines)
|
||||
bool wireframe)
|
||||
{
|
||||
struct gl_shader_config alt;
|
||||
struct weston_color_transform *ctransf;
|
||||
|
||||
assert(nstrip > 0);
|
||||
|
||||
if (wireframe) {
|
||||
/* Wireframe rendering is based on Celes & Abraham's "Fast and
|
||||
* versatile texture-based wireframe rendering", 2011. */
|
||||
glEnableVertexAttribArray(SHADER_ATTRIB_LOC_COLOR);
|
||||
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);
|
||||
|
||||
sconf->req.wireframe = wireframe;
|
||||
sconf->wireframe_tex = gr->wireframe_tex;
|
||||
}
|
||||
|
||||
if (!gl_renderer_use_program(gr, sconf))
|
||||
gl_renderer_send_shader_error(pnode); /* Use fallback shader. */
|
||||
|
||||
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, positions);
|
||||
glVertexAttribPointer(SHADER_ATTRIB_LOC_POSITION, 2, GL_FLOAT, GL_FALSE,
|
||||
0, positions);
|
||||
glDrawElements(GL_TRIANGLE_STRIP, nstrip, GL_UNSIGNED_SHORT, strip);
|
||||
|
||||
if (nlines == 0)
|
||||
return;
|
||||
|
||||
/* Wireframe debugging is rendered as lines colored with the solid
|
||||
* shader variant filtered per sub-mesh using vertex colors. */
|
||||
alt = (struct gl_shader_config) {
|
||||
.req = {
|
||||
.variant = SHADER_VARIANT_SOLID,
|
||||
.input_is_premult = true,
|
||||
.wireframe = true,
|
||||
},
|
||||
.projection = sconf->projection,
|
||||
.view_alpha = 1.0f,
|
||||
.unicolor = { 1.0f, 1.0f, 1.0f, 1.0f },
|
||||
};
|
||||
ctransf = pnode->output->color_outcome->from_sRGB_to_blend;
|
||||
if (!gl_shader_config_set_color_transform(gr, &alt, ctransf)) {
|
||||
weston_log("GL-renderer: %s failed to generate a color "
|
||||
"transformation.\n", __func__);
|
||||
return;
|
||||
}
|
||||
if (!gl_renderer_use_program(gr, &alt))
|
||||
return;
|
||||
|
||||
glEnableVertexAttribArray(SHADER_ATTRIB_LOC_COLOR);
|
||||
glVertexAttribPointer(SHADER_ATTRIB_LOC_COLOR, 4, GL_UNSIGNED_BYTE,
|
||||
GL_FALSE, 0, colors);
|
||||
glDrawElements(GL_LINES, nlines, GL_UNSIGNED_SHORT, lines);
|
||||
if (wireframe) {
|
||||
glDisableVertexAttribArray(SHADER_ATTRIB_LOC_BARYCENTRIC);
|
||||
glDisableVertexAttribArray(SHADER_ATTRIB_LOC_COLOR);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
repaint_region(struct gl_renderer *gr,
|
||||
|
@ -1452,22 +1414,20 @@ repaint_region(struct gl_renderer *gr,
|
|||
struct clipper_quad *quads,
|
||||
int nquads,
|
||||
pixman_region32_t *region,
|
||||
const struct gl_shader_config *sconf)
|
||||
struct gl_shader_config *sconf)
|
||||
{
|
||||
pixman_box32_t *rects;
|
||||
struct clipper_vertex *positions;
|
||||
uint32_t *colors = NULL;
|
||||
uint16_t *strips, *lines = NULL;
|
||||
int i, j, n, nrects, positions_size, colors_size, strips_size;
|
||||
int lines_size, nvtx = 0, nstrips = 0, nlines = 0;
|
||||
uint32_t *colors = NULL, *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;
|
||||
|
||||
/* Build-time sub-mesh constants. Clipping emits 8 vertices max.
|
||||
* store_strips() and store_lines() respectively store 10 and 26 indices
|
||||
* at most. */
|
||||
* store_indices() store at most 10 indices. */
|
||||
const int nvtx_max = 8;
|
||||
const int nstrips_max = 10;
|
||||
const int nlines_max = 26;
|
||||
const int nidx_max = 10;
|
||||
|
||||
rects = pixman_region32_rectangles(region, &nrects);
|
||||
assert((nrects > 0) && (nquads > 0));
|
||||
|
@ -1476,14 +1436,15 @@ repaint_region(struct gl_renderer *gr,
|
|||
n = nquads * nrects;
|
||||
positions_size = n * nvtx_max * sizeof *positions;
|
||||
colors_size = ROUND_UP_N(n * nvtx_max * sizeof *colors, 32);
|
||||
strips_size = ROUND_UP_N(n * nstrips_max * sizeof *strips, 32);
|
||||
lines_size = ROUND_UP_N(n * nlines_max * sizeof *lines, 64);
|
||||
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);
|
||||
strips = wl_array_add(&gr->indices[0], strips_size);
|
||||
indices = wl_array_add(&gr->indices, indices_size);
|
||||
if (wireframe) {
|
||||
colors = wl_array_add(&gr->color_stream, colors_size);
|
||||
lines = wl_array_add(&gr->indices[1], lines_size);
|
||||
barycentrics = wl_array_add(&gr->barycentric_stream,
|
||||
barycentrics_size);
|
||||
}
|
||||
|
||||
/* A node's damage mesh is created by clipping damage quads to surface
|
||||
|
@ -1508,32 +1469,32 @@ repaint_region(struct gl_renderer *gr,
|
|||
for (j = 0; j < nrects; j++) {
|
||||
n = clipper_quad_clip_box32(&quads[i], &rects[j],
|
||||
&positions[nvtx]);
|
||||
nstrips += store_strips(n, nvtx, &strips[nstrips]);
|
||||
if (wireframe) {
|
||||
store_wireframes(&colors[nvtx]);
|
||||
nlines += store_lines(n, nvtx, &lines[nlines]);
|
||||
}
|
||||
nidx += store_indices(n, nvtx, &indices[nidx]);
|
||||
if (wireframe)
|
||||
store_wireframes(n, &colors[nvtx],
|
||||
&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,
|
||||
strips, nstrips - 2, lines, nlines);
|
||||
nvtx = nstrips = nlines = 0;
|
||||
barycentrics, indices, nidx - 2,
|
||||
wireframe);
|
||||
nvtx = nidx = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (nvtx)
|
||||
draw_mesh(gr, pnode, sconf, positions, colors, strips,
|
||||
nstrips - 2, lines, nlines);
|
||||
draw_mesh(gr, pnode, sconf, positions, colors, barycentrics,
|
||||
indices, nidx - 2, wireframe);
|
||||
|
||||
gr->position_stream.size = 0;
|
||||
gr->indices[0].size = 0;
|
||||
gr->indices.size = 0;
|
||||
if (wireframe) {
|
||||
gr->color_stream.size = 0;
|
||||
gr->indices[1].size = 0;
|
||||
gr->barycentric_stream.size = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1731,6 +1692,55 @@ update_buffer_release_fences(struct weston_compositor *compositor,
|
|||
}
|
||||
}
|
||||
|
||||
/* Update the wireframe texture. The texture is either created, deleted or
|
||||
* resized depending on the wireframe debugging state and the area.
|
||||
*/
|
||||
static void
|
||||
update_wireframe_tex(struct gl_renderer *gr,
|
||||
const struct weston_geometry *area)
|
||||
{
|
||||
int new_size, i;
|
||||
uint8_t *buffer;
|
||||
|
||||
if (!gr->wireframe_debug) {
|
||||
if (gr->wireframe_size) {
|
||||
glDeleteTextures(1, &gr->wireframe_tex);
|
||||
gr->wireframe_size = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* Texture size at mip level 0 should be at least as large as the area
|
||||
* in order to correctly anti-alias triangles covering it entirely. */
|
||||
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &new_size);
|
||||
new_size = MIN(round_up_pow2_32(MAX(area->width, area->height)),
|
||||
round_down_pow2_32(new_size));
|
||||
if (new_size <= gr->wireframe_size)
|
||||
return;
|
||||
|
||||
if (gr->wireframe_size == 0) {
|
||||
glGenTextures(1, &gr->wireframe_tex);
|
||||
glBindTexture(GL_TEXTURE_2D, gr->wireframe_tex);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
|
||||
GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
|
||||
GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
|
||||
GL_LINEAR_MIPMAP_LINEAR);
|
||||
} else {
|
||||
glBindTexture(GL_TEXTURE_2D, gr->wireframe_tex);
|
||||
}
|
||||
gr->wireframe_size = new_size;
|
||||
|
||||
/* Generate mip chain with a wireframe thickness of 1.0. */
|
||||
buffer = xzalloc(new_size);
|
||||
buffer[0] = 0xff;
|
||||
for (i = 0; new_size; i++, new_size >>= 1)
|
||||
glTexImage2D(GL_TEXTURE_2D, i, GL_LUMINANCE, new_size, 1, 0,
|
||||
GL_LUMINANCE, GL_UNSIGNED_BYTE, buffer);
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
static void
|
||||
draw_output_border_texture(struct gl_renderer *gr,
|
||||
struct gl_output_state *go,
|
||||
|
@ -2207,6 +2217,11 @@ gl_renderer_repaint_output(struct weston_output *output,
|
|||
go->area.width, go->area.height);
|
||||
}
|
||||
|
||||
if (gr->wireframe_dirty) {
|
||||
update_wireframe_tex(gr, &go->area);
|
||||
gr->wireframe_dirty = false;
|
||||
}
|
||||
|
||||
/* In wireframe debug mode, redraw everything to make sure that we clear
|
||||
* any wireframes left over from previous draws on this buffer. This
|
||||
* precludes the use of EGL_EXT_swap_buffers_with_damage and
|
||||
|
@ -3888,6 +3903,7 @@ gl_renderer_resize_output(struct weston_output *output,
|
|||
const struct weston_size *fb_size,
|
||||
const struct weston_geometry *area)
|
||||
{
|
||||
struct gl_renderer *gr = get_renderer(output->compositor);
|
||||
struct gl_output_state *go = get_output_state(output);
|
||||
const struct pixel_format_info *shfmt = go->shadow_format;
|
||||
bool ret;
|
||||
|
@ -3898,6 +3914,7 @@ gl_renderer_resize_output(struct weston_output *output,
|
|||
|
||||
go->fb_size = *fb_size;
|
||||
go->area = *area;
|
||||
gr->wireframe_dirty = true;
|
||||
|
||||
weston_output_update_capture_info(output,
|
||||
WESTON_OUTPUT_CAPTURE_SOURCE_FRAMEBUFFER,
|
||||
|
@ -4112,6 +4129,9 @@ gl_renderer_destroy(struct weston_compositor *ec)
|
|||
if (gr->fallback_shader)
|
||||
gl_shader_destroy(gr, gr->fallback_shader);
|
||||
|
||||
if (gr->wireframe_size)
|
||||
glDeleteTextures(1, &gr->wireframe_tex);
|
||||
|
||||
/* Work around crash in egl_dri2.c's dri2_make_current() - when does this apply? */
|
||||
eglMakeCurrent(gr->egl_display,
|
||||
EGL_NO_SURFACE, EGL_NO_SURFACE,
|
||||
|
@ -4127,8 +4147,8 @@ gl_renderer_destroy(struct weston_compositor *ec)
|
|||
|
||||
wl_array_release(&gr->position_stream);
|
||||
wl_array_release(&gr->color_stream);
|
||||
wl_array_release(&gr->indices[0]);
|
||||
wl_array_release(&gr->indices[1]);
|
||||
wl_array_release(&gr->barycentric_stream);
|
||||
wl_array_release(&gr->indices);
|
||||
|
||||
if (gr->fragment_binding)
|
||||
weston_binding_destroy(gr->fragment_binding);
|
||||
|
@ -4357,6 +4377,7 @@ wireframe_debug_repaint_binding(struct weston_keyboard *keyboard,
|
|||
struct gl_renderer *gr = get_renderer(compositor);
|
||||
|
||||
gr->wireframe_debug = !gr->wireframe_debug;
|
||||
gr->wireframe_dirty = true;
|
||||
weston_compositor_damage_all(compositor);
|
||||
}
|
||||
|
||||
|
|
|
@ -61,6 +61,7 @@ struct gl_shader {
|
|||
GLint proj_uniform;
|
||||
GLint surface_to_buffer_uniform;
|
||||
GLint tex_uniforms[3];
|
||||
GLint tex_uniform_wireframe;
|
||||
GLint view_alpha_uniform;
|
||||
GLint color_uniform;
|
||||
union {
|
||||
|
@ -359,9 +360,13 @@ 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)
|
||||
if (requirements->wireframe) {
|
||||
glBindAttribLocation(shader->program, SHADER_ATTRIB_LOC_COLOR,
|
||||
"color");
|
||||
glBindAttribLocation(shader->program,
|
||||
SHADER_ATTRIB_LOC_BARYCENTRIC,
|
||||
"barycentric");
|
||||
}
|
||||
|
||||
glLinkProgram(shader->program);
|
||||
glGetProgramiv(shader->program, GL_LINK_STATUS, &status);
|
||||
|
@ -380,6 +385,9 @@ gl_shader_create(struct gl_renderer *gr,
|
|||
shader->tex_uniforms[0] = glGetUniformLocation(shader->program, "tex");
|
||||
shader->tex_uniforms[1] = glGetUniformLocation(shader->program, "tex1");
|
||||
shader->tex_uniforms[2] = glGetUniformLocation(shader->program, "tex2");
|
||||
if (requirements->wireframe)
|
||||
shader->tex_uniform_wireframe =
|
||||
glGetUniformLocation(shader->program, "tex_wireframe");
|
||||
shader->view_alpha_uniform = glGetUniformLocation(shader->program, "view_alpha");
|
||||
if (requirements->variant == SHADER_VARIANT_SOLID) {
|
||||
shader->color_uniform = glGetUniformLocation(shader->program,
|
||||
|
@ -753,6 +761,13 @@ gl_shader_load_config(struct gl_shader *shader,
|
|||
sconf->color_post_curve.parametric.clamped_input);
|
||||
break;
|
||||
}
|
||||
|
||||
if (sconf->req.wireframe) {
|
||||
assert(sconf->wireframe_tex != 0);
|
||||
glUniform1i(shader->tex_uniform_wireframe, GL_SHADER_WIREFRAME_TEX_UNIT);
|
||||
glActiveTexture(GL_TEXTURE0 + GL_SHADER_WIREFRAME_TEX_UNIT);
|
||||
glBindTexture(GL_TEXTURE_2D, sconf->wireframe_tex);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
@ -47,10 +47,12 @@ 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;
|
||||
compile_const bool c_wireframe = DEF_WIREFRAME;
|
||||
|
@ -64,6 +66,8 @@ 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)
|
||||
if (c_wireframe) {
|
||||
v_color = color;
|
||||
v_barycentric = barycentric.xyz;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -252,6 +252,9 @@ static uint32_t *
|
|||
output_run(uint32_t *p, uint32_t delta, int run)
|
||||
{
|
||||
int i;
|
||||
#if !defined(HAVE_BUILTIN_CLZ)
|
||||
int tmp;
|
||||
#endif
|
||||
|
||||
while (run > 0) {
|
||||
if (run <= 0xe0) {
|
||||
|
@ -259,7 +262,11 @@ output_run(uint32_t *p, uint32_t delta, int run)
|
|||
break;
|
||||
}
|
||||
|
||||
#if defined(HAVE_BUILTIN_CLZ)
|
||||
i = 24 - __builtin_clz(run);
|
||||
#else
|
||||
for (i = 0, tmp = u >> 8; tmp; i++, tmp >>= 1);
|
||||
#endif
|
||||
*p++ = delta | ((i + 0xe0) << 24);
|
||||
run -= 1 << (7 + i);
|
||||
}
|
||||
|
|
11
meson.build
11
meson.build
|
@ -94,6 +94,17 @@ foreach hdr : optional_system_headers
|
|||
endif
|
||||
endforeach
|
||||
|
||||
optional_builtins = {
|
||||
'builtin_clz': 'return __builtin_clz(1);',
|
||||
'builtin_bswap32': 'return __builtin_bswap32(0);',
|
||||
'builtin_popcount': 'return __builtin_popcount(0);',
|
||||
}
|
||||
foreach name, check : optional_builtins
|
||||
if cc.links('int main(void) { @0@ }'.format(check), name: name)
|
||||
config_h.set('HAVE_' + name.to_upper(), 1)
|
||||
endif
|
||||
endforeach
|
||||
|
||||
env_modmap = ''
|
||||
|
||||
config_h.set('_GNU_SOURCE', '1')
|
||||
|
|
|
@ -22,6 +22,8 @@
|
|||
#ifndef WESTON_HELPERS_H
|
||||
#define WESTON_HELPERS_H
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -233,6 +235,101 @@ do { \
|
|||
#define unreachable(str) assert(!str)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Returns number of bits set in 32-bit value x.
|
||||
*
|
||||
* @param x a 32-bit value.
|
||||
* @return the number of bits set.
|
||||
*/
|
||||
static inline int
|
||||
bitcount32(uint32_t x)
|
||||
{
|
||||
#if defined(HAVE_BUILTIN_POPCOUNT)
|
||||
return __builtin_popcount(x);
|
||||
#else
|
||||
int n;
|
||||
|
||||
for (n = 0; x; n++)
|
||||
x &= x - 1;
|
||||
|
||||
return n;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns 32-bit value x in reversed byte order.
|
||||
*
|
||||
* @param x a 32-bit value.
|
||||
* @return the reversed 32-bit value.
|
||||
*/
|
||||
static inline uint32_t
|
||||
bswap32(uint32_t x)
|
||||
{
|
||||
#if defined(HAVE_BUILTIN_BSWAP32)
|
||||
return __builtin_bswap32(x);
|
||||
#else
|
||||
return (x >> 24) |
|
||||
((x >> 8) & 0x0000ff00) |
|
||||
((x << 8) & 0x00ff0000) |
|
||||
(x << 24);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the highest power of two lesser than or equal to 32-bit value x.
|
||||
* Saturated to 0 (which isn't a power of two) if x is lesser than 2^0.
|
||||
*
|
||||
* @param x a 32-bit value.
|
||||
* @return the rounded down 32-bit value.
|
||||
*/
|
||||
static inline uint32_t
|
||||
round_down_pow2_32(uint32_t x)
|
||||
{
|
||||
#if defined(HAVE_BUILTIN_CLZ)
|
||||
/* clz depends on the underlying architecture when x is 0. */
|
||||
return x ? (1u << ((32 - __builtin_clz(x)) - 1)) : 0;
|
||||
#else
|
||||
/* See Hacker's Delight 2nd Edition, Chapter 3-2. */
|
||||
x |= x >> 1;
|
||||
x |= x >> 2;
|
||||
x |= x >> 4;
|
||||
x |= x >> 8;
|
||||
x |= x >> 16;
|
||||
x -= x >> 1;
|
||||
|
||||
return x;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the smallest power of two greater than or equal to 32-bit value x.
|
||||
* Saturated to 2^32 - 1 (which isn't a power of two) if x is greater than 2^31.
|
||||
*
|
||||
* @param x a 32-bit value.
|
||||
* @return the rounded up 32-bit value.
|
||||
*/
|
||||
static inline uint32_t
|
||||
round_up_pow2_32(uint32_t x)
|
||||
{
|
||||
if (x > (1u << 31))
|
||||
return UINT32_MAX;
|
||||
|
||||
#if defined(HAVE_BUILTIN_CLZ)
|
||||
return (x > 1) ? (1 << (32 - __builtin_clz(x - 1))) : 1;
|
||||
#else
|
||||
/* Slight change from the Hacker's Delight version (which subtracts 1
|
||||
* unconditionally) in order to return 1 if x is 0. */
|
||||
x -= x != 0;
|
||||
x |= x >> 1;
|
||||
x |= x >> 2;
|
||||
x |= x >> 4;
|
||||
x |= x >> 8;
|
||||
x |= x >> 16;
|
||||
|
||||
return x + 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue
Block a user