Merge remote-tracking branch 'pq/transform-fixes2'

This commit is contained in:
Kristian Høgsberg 2012-02-07 11:04:11 -05:00
commit 9b8a82bf6d
6 changed files with 89 additions and 78 deletions

View File

@ -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])

View File

@ -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);

View File

@ -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,21 +722,11 @@ 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);
glUniform1i(es->shader->tex_uniform, 0);
glUniform4fv(es->shader->color_uniform, 1, es->color);
glUniform1f(es->shader->alpha_uniform, es->alpha / 255.0);
glUniform1f(es->shader->texwidth_uniform,
(GLfloat)es->geometry.width / es->pitch);
if (es->transform.enabled)
filter = GL_LINEAR;
@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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);