Merge remote-tracking branch 'pq/transform-fixes2'
This commit is contained in:
commit
9b8a82bf6d
@ -117,7 +117,7 @@ AM_CONDITIONAL(BUILD_CLIENTS, test x$enable_clients == xyes)
|
||||
if test x$enable_clients == xyes; then
|
||||
AC_DEFINE([BUILD_CLIENTS], [1], [Build the Wayland clients])
|
||||
|
||||
PKG_CHECK_MODULES(CLIENT, [wayland-client wayland-egl egl >= 7.10 cairo >= 1.10.0 gdk-pixbuf-2.0 glib-2.0 gobject-2.0 gio-2.0 xkbcommon])
|
||||
PKG_CHECK_MODULES(CLIENT, [wayland-client wayland-egl egl >= 7.10 cairo >= 1.10.0 gdk-pixbuf-2.0 glib-2.0 gobject-2.0 gio-2.0 xkbcommon libpng])
|
||||
|
||||
PKG_CHECK_MODULES(POPPLER, [poppler-glib],
|
||||
[have_poppler=yes], [have_poppler=no])
|
||||
|
@ -181,7 +181,6 @@ draw_border(struct wayland_output *output)
|
||||
|
||||
glUniform1i(shader->tex_uniform, 0);
|
||||
glUniform1f(shader->alpha_uniform, 1);
|
||||
c->base.current_alpha = 255;
|
||||
glUniform1f(shader->texwidth_uniform, 1);
|
||||
|
||||
n = texture_border(output);
|
||||
|
@ -314,12 +314,10 @@ weston_surface_update_transform(struct weston_surface *surface)
|
||||
&surface->transform.boundingbox);
|
||||
}
|
||||
|
||||
WL_EXPORT void
|
||||
weston_surface_to_global(struct weston_surface *surface,
|
||||
int32_t sx, int32_t sy, int32_t *x, int32_t *y)
|
||||
static void
|
||||
surface_to_global_float(struct weston_surface *surface,
|
||||
int32_t sx, int32_t sy, GLfloat *x, GLfloat *y)
|
||||
{
|
||||
weston_surface_update_transform(surface);
|
||||
|
||||
if (surface->transform.enabled) {
|
||||
struct weston_vector v = { { sx, sy, 0.0f, 1.0f } };
|
||||
|
||||
@ -334,14 +332,27 @@ weston_surface_to_global(struct weston_surface *surface,
|
||||
return;
|
||||
}
|
||||
|
||||
*x = floorf(v.f[0] / v.f[3]);
|
||||
*y = floorf(v.f[1] / v.f[3]);
|
||||
*x = v.f[0] / v.f[3];
|
||||
*y = v.f[1] / v.f[3];
|
||||
} else {
|
||||
*x = sx + surface->geometry.x;
|
||||
*y = sy + surface->geometry.y;
|
||||
}
|
||||
}
|
||||
|
||||
WL_EXPORT void
|
||||
weston_surface_to_global(struct weston_surface *surface,
|
||||
int32_t sx, int32_t sy, int32_t *x, int32_t *y)
|
||||
{
|
||||
GLfloat xf, yf;
|
||||
|
||||
weston_surface_update_transform(surface);
|
||||
|
||||
surface_to_global_float(surface, sx, sy, &xf, &yf);
|
||||
*x = floorf(xf);
|
||||
*y = floorf(yf);
|
||||
}
|
||||
|
||||
static void
|
||||
surface_from_global_float(struct weston_surface *surface,
|
||||
int32_t x, int32_t y, GLfloat *sx, GLfloat *sy)
|
||||
@ -452,7 +463,7 @@ weston_surface_flush_damage(struct weston_surface *surface)
|
||||
|
||||
WL_EXPORT void
|
||||
weston_surface_configure(struct weston_surface *surface,
|
||||
int x, int y, int width, int height)
|
||||
GLfloat x, GLfloat y, int width, int height)
|
||||
{
|
||||
weston_surface_damage_below(surface);
|
||||
|
||||
@ -466,7 +477,8 @@ weston_surface_configure(struct weston_surface *surface,
|
||||
weston_surface_damage(surface);
|
||||
|
||||
pixman_region32_fini(&surface->opaque);
|
||||
if (surface->visual == WESTON_RGB_VISUAL)
|
||||
if (surface->visual == WESTON_RGB_VISUAL &&
|
||||
surface->transform.enabled == 0)
|
||||
pixman_region32_init_rect(&surface->opaque,
|
||||
surface->geometry.x,
|
||||
surface->geometry.y,
|
||||
@ -684,6 +696,9 @@ weston_surface_draw(struct weston_surface *es, struct weston_output *output)
|
||||
&output->region);
|
||||
pixman_region32_intersect(&repaint, &repaint, &es->damage);
|
||||
|
||||
/* Clear damage, assume outputs do not overlap. */
|
||||
pixman_region32_subtract(&es->damage, &es->damage, &output->region);
|
||||
|
||||
if (!pixman_region32_not_empty(&repaint))
|
||||
goto out;
|
||||
|
||||
@ -707,19 +722,9 @@ weston_surface_draw(struct weston_surface *es, struct weston_output *output)
|
||||
|
||||
glUniformMatrix4fv(es->shader->proj_uniform,
|
||||
1, GL_FALSE, output->matrix.d);
|
||||
|
||||
if (es->shader->tex_uniform != GL_NONE)
|
||||
glUniform1i(es->shader->tex_uniform, 0);
|
||||
|
||||
if (es->shader->color_uniform != GL_NONE)
|
||||
glUniform4fv(es->shader->color_uniform, 1, es->color);
|
||||
|
||||
if (es->shader->alpha_uniform && es->alpha != ec->current_alpha) {
|
||||
glUniform1f(es->shader->alpha_uniform, es->alpha / 255.0);
|
||||
ec->current_alpha = es->alpha;
|
||||
}
|
||||
|
||||
if (es->shader->texwidth_uniform != GL_NONE)
|
||||
glUniform1f(es->shader->texwidth_uniform,
|
||||
(GLfloat)es->geometry.width / es->pitch);
|
||||
|
||||
@ -1115,12 +1120,11 @@ surface_attach(struct wl_client *client,
|
||||
} else if (sx != 0 || sy != 0 ||
|
||||
es->geometry.width != buffer->width ||
|
||||
es->geometry.height != buffer->height) {
|
||||
int32_t from_x, from_y;
|
||||
int32_t to_x, to_y;
|
||||
GLfloat from_x, from_y;
|
||||
GLfloat to_x, to_y;
|
||||
|
||||
/* FIXME: this has serious cumulating rounding errors */
|
||||
weston_surface_to_global(es, 0, 0, &from_x, &from_y);
|
||||
weston_surface_to_global(es, sx, sy, &to_x, &to_y);
|
||||
surface_to_global_float(es, 0, 0, &from_x, &from_y);
|
||||
surface_to_global_float(es, sx, sy, &to_x, &to_y);
|
||||
shell->configure(shell, es,
|
||||
es->geometry.x + to_x - from_x,
|
||||
es->geometry.y + to_y - from_y,
|
||||
@ -1857,43 +1861,13 @@ weston_shader_init(struct weston_shader *shader,
|
||||
shader->proj_uniform = glGetUniformLocation(shader->program, "proj");
|
||||
shader->tex_uniform = glGetUniformLocation(shader->program, "tex");
|
||||
shader->alpha_uniform = glGetUniformLocation(shader->program, "alpha");
|
||||
shader->color_uniform = glGetUniformLocation(shader->program, "color");
|
||||
shader->texwidth_uniform = glGetUniformLocation(shader->program,
|
||||
"texwidth");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
init_solid_shader(struct weston_shader *shader,
|
||||
GLuint vertex_shader, const char *fragment_source)
|
||||
{
|
||||
GLint status;
|
||||
char msg[512];
|
||||
|
||||
shader->vertex_shader = vertex_shader;
|
||||
shader->fragment_shader =
|
||||
compile_shader(GL_FRAGMENT_SHADER, fragment_source);
|
||||
|
||||
shader->program = glCreateProgram();
|
||||
glAttachShader(shader->program, shader->vertex_shader);
|
||||
glAttachShader(shader->program, shader->fragment_shader);
|
||||
glBindAttribLocation(shader->program, 0, "position");
|
||||
glBindAttribLocation(shader->program, 1, "texcoord");
|
||||
|
||||
glLinkProgram(shader->program);
|
||||
glGetProgramiv(shader->program, GL_LINK_STATUS, &status);
|
||||
if (!status) {
|
||||
glGetProgramInfoLog(shader->program, sizeof msg, NULL, msg);
|
||||
fprintf(stderr, "link info: %s\n", msg);
|
||||
return -1;
|
||||
}
|
||||
|
||||
shader->proj_uniform = glGetUniformLocation(shader->program, "proj");
|
||||
shader->color_uniform = glGetUniformLocation(shader->program, "color");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
WL_EXPORT void
|
||||
weston_output_destroy(struct weston_output *output)
|
||||
{
|
||||
@ -2072,9 +2046,8 @@ weston_compositor_init(struct weston_compositor *ec, struct wl_display *display)
|
||||
if (weston_shader_init(&ec->texture_shader,
|
||||
vertex_shader, texture_fragment_shader) < 0)
|
||||
return -1;
|
||||
if (init_solid_shader(&ec->solid_shader,
|
||||
ec->texture_shader.vertex_shader,
|
||||
solid_fragment_shader) < 0)
|
||||
if (weston_shader_init(&ec->solid_shader,
|
||||
vertex_shader, solid_fragment_shader) < 0)
|
||||
return -1;
|
||||
|
||||
loop = wl_display_get_event_loop(ec->wl_display);
|
||||
|
@ -104,11 +104,11 @@ enum weston_visual {
|
||||
struct weston_shader {
|
||||
GLuint program;
|
||||
GLuint vertex_shader, fragment_shader;
|
||||
GLuint proj_uniform;
|
||||
GLuint tex_uniform;
|
||||
GLuint alpha_uniform;
|
||||
GLuint color_uniform;
|
||||
GLuint texwidth_uniform;
|
||||
GLint proj_uniform;
|
||||
GLint tex_uniform;
|
||||
GLint alpha_uniform;
|
||||
GLint color_uniform;
|
||||
GLint texwidth_uniform;
|
||||
};
|
||||
|
||||
struct weston_animation {
|
||||
@ -133,7 +133,7 @@ struct weston_shell {
|
||||
int32_t width, int32_t height);
|
||||
void (*configure)(struct weston_shell *shell,
|
||||
struct weston_surface *surface,
|
||||
int32_t x, int32_t y, int32_t width, int32_t height);
|
||||
GLfloat x, GLfloat y, int32_t width, int32_t height);
|
||||
void (*destroy)(struct weston_shell *shell);
|
||||
};
|
||||
|
||||
@ -153,7 +153,6 @@ struct weston_compositor {
|
||||
EGLContext context;
|
||||
EGLConfig config;
|
||||
GLuint fbo;
|
||||
uint32_t current_alpha;
|
||||
struct weston_shader texture_shader;
|
||||
struct weston_shader solid_shader;
|
||||
struct weston_shader *current_shader;
|
||||
@ -214,6 +213,31 @@ enum weston_output_flags {
|
||||
WL_OUTPUT_FLIPPED = 0x01
|
||||
};
|
||||
|
||||
/* Using weston_surface transformations
|
||||
*
|
||||
* To add a transformation to a surface, create a struct weston_transform, and
|
||||
* add it to the list surface->geometry.transformation_list. Whenever you
|
||||
* change the list, anything under surface->geometry, or anything in the
|
||||
* weston_transforms linked into the list, you must set
|
||||
* surface->geometry.dirty = 1.
|
||||
*
|
||||
* The order in the list defines the order of transformations. Let the list
|
||||
* contain the transformation matrices M1, ..., Mn as head to tail. The
|
||||
* transformation is applied to surface-local coordinate vector p as
|
||||
* P = Mn * ... * M2 * M1 * p
|
||||
* to produce the global coordinate vector P. The total transform
|
||||
* Mn * ... * M2 * M1
|
||||
* is cached in surface->transform.matrix, and the inverse of it in
|
||||
* surface->transform.inverse.
|
||||
*
|
||||
* The list always contains surface->transform.position transformation, which
|
||||
* is the translation by surface->geometry.x and y.
|
||||
*
|
||||
* If you want to apply a transformation in local coordinates, add your
|
||||
* weston_transform to the head of the list. If you want to apply a
|
||||
* transformation in global coordinates, add it to the tail of the list.
|
||||
*/
|
||||
|
||||
struct weston_surface {
|
||||
struct wl_surface surface;
|
||||
struct weston_compositor *compositor;
|
||||
@ -234,7 +258,7 @@ struct weston_surface {
|
||||
* That includes the transformations referenced from the list.
|
||||
*/
|
||||
struct {
|
||||
int32_t x, y; /* surface translation on display */
|
||||
GLfloat x, y; /* surface translation on display */
|
||||
int32_t width, height;
|
||||
|
||||
/* struct weston_transform */
|
||||
@ -378,7 +402,7 @@ weston_surface_create(struct weston_compositor *compositor);
|
||||
|
||||
void
|
||||
weston_surface_configure(struct weston_surface *surface,
|
||||
int x, int y, int width, int height);
|
||||
GLfloat x, GLfloat y, int width, int height);
|
||||
|
||||
void
|
||||
weston_surface_assign_output(struct weston_surface *surface);
|
||||
|
21
src/shell.c
21
src/shell.c
@ -103,6 +103,7 @@ struct shell_surface {
|
||||
struct wl_grab grab;
|
||||
uint32_t time;
|
||||
int32_t x, y;
|
||||
struct weston_transform parent_transform;
|
||||
int32_t initial_up;
|
||||
} popup;
|
||||
|
||||
@ -521,8 +522,22 @@ shell_map_popup(struct shell_surface *shsurf, uint32_t time)
|
||||
shsurf->popup.grab.interface = &popup_grab_interface;
|
||||
device = es->compositor->input_device;
|
||||
|
||||
es->geometry.x = shsurf->parent->surface->geometry.x + shsurf->popup.x;
|
||||
es->geometry.y = shsurf->parent->surface->geometry.y + shsurf->popup.y;
|
||||
weston_surface_update_transform(parent);
|
||||
if (parent->transform.enabled) {
|
||||
shsurf->popup.parent_transform.matrix =
|
||||
parent->transform.matrix;
|
||||
} else {
|
||||
/* construct x, y translation matrix */
|
||||
weston_matrix_init(&shsurf->popup.parent_transform.matrix);
|
||||
shsurf->popup.parent_transform.matrix.d[12] =
|
||||
parent->geometry.x;
|
||||
shsurf->popup.parent_transform.matrix.d[13] =
|
||||
parent->geometry.y;
|
||||
}
|
||||
wl_list_insert(es->geometry.transformation_list.prev,
|
||||
&shsurf->popup.parent_transform.link);
|
||||
es->geometry.x = shsurf->popup.x;
|
||||
es->geometry.y = shsurf->popup.y;
|
||||
es->geometry.dirty = 1;
|
||||
|
||||
shsurf->popup.grab.input_device = device;
|
||||
@ -1397,7 +1412,7 @@ map(struct weston_shell *base,
|
||||
|
||||
static void
|
||||
configure(struct weston_shell *base, struct weston_surface *surface,
|
||||
int32_t x, int32_t y, int32_t width, int32_t height)
|
||||
GLfloat x, GLfloat y, int32_t width, int32_t height)
|
||||
{
|
||||
struct wl_shell *shell = container_of(base, struct wl_shell, shell);
|
||||
int do_configure = !shell->locked;
|
||||
|
@ -141,7 +141,7 @@ tablet_shell_map(struct weston_shell *base, struct weston_surface *surface,
|
||||
static void
|
||||
tablet_shell_configure(struct weston_shell *base,
|
||||
struct weston_surface *surface,
|
||||
int32_t x, int32_t y,
|
||||
GLfloat x, GLfloat y,
|
||||
int32_t width, int32_t height)
|
||||
{
|
||||
weston_surface_configure(surface, x, y, width, height);
|
||||
|
Loading…
Reference in New Issue
Block a user