Split the geometry information from weston_surface out into weston_view

The weston_surface structure is split into two structures:

 * The weston_surface structure storres everything required for a
   client-side or server-side surface.  This includes buffers; callbacks;
   backend private data; input, damage, and opaque regions; and a few other
   bookkeeping bits.

 * The weston_view structure represents an entity in the scenegraph and
   storres all of the geometry information.  This includes clip region,
   alpha, position, and the transformation list as well as all of the
   temporary information derived from the geometry state.  Because a view,
   and not a surface, is a scenegraph element, the view is what is placed
   in layers and planes.

There are a few things worth noting about the surface/view split:

 1. This is *not* a modification to the protocol.  It is, instead, a
    modification to Weston's internal scenegraph to allow a single surface
    to exist in multiple places at a time.  Clients are completely unaware
    of how many views to a particular surface exist.

 2. A view is considered a direct child of a surface and is destroyed when
    the surface is destroyed.  Because of this, the view.surface pointer is
    always valid and non-null.

 3. The compositor's surface_list is replaced with a view_list.  Due to
    subsurfaces, building the view list is a little more complicated than
    it used to be and involves building a tree of views on the fly whenever
    subsurfaces are used.  However, this means that backends can remain
    completely subsurface-agnostic.

 4. Surfaces and views both keep track of which outputs they are on.

 5. The weston_surface structure now has width and height fields.  These
    are populated when a new buffer is attached before surface.configure
    is called.  This is because there are many surface-based operations
    that really require the width and height and digging through the views
    didn't work well.

Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
dev
Jason Ekstrand 11 years ago committed by Kristian Høgsberg
parent d4c1cd77c3
commit a7af70436b
  1. 116
      src/animation.c
  2. 148
      src/compositor-drm.c
  3. 796
      src/compositor.c
  4. 191
      src/compositor.h
  5. 80
      src/data-device.c
  6. 96
      src/gl-renderer.c
  7. 145
      src/input.c
  8. 84
      src/pixman-renderer.c
  9. 431
      src/rpi-renderer.c
  10. 744
      src/shell.c
  11. 4
      src/spring-tool.c
  12. 72
      src/tablet-shell.c
  13. 26
      src/xwayland/window-manager.c
  14. 153
      src/zoom.c
  15. 23
      tests/surface-global-test.c
  16. 15
      tests/surface-test.c
  17. 32
      tests/weston-test.c

@ -114,52 +114,52 @@ weston_spring_done(struct weston_spring *spring)
fabs(spring->current - spring->target) < 0.002;
}
typedef void (*weston_surface_animation_frame_func_t)(struct weston_surface_animation *animation);
typedef void (*weston_view_animation_frame_func_t)(struct weston_view_animation *animation);
struct weston_surface_animation {
struct weston_surface *surface;
struct weston_view_animation {
struct weston_view *view;
struct weston_animation animation;
struct weston_spring spring;
struct weston_transform transform;
struct wl_listener listener;
float start, stop;
weston_surface_animation_frame_func_t frame;
weston_surface_animation_frame_func_t reset;
weston_surface_animation_done_func_t done;
weston_view_animation_frame_func_t frame;
weston_view_animation_frame_func_t reset;
weston_view_animation_done_func_t done;
void *data;
};
static void
weston_surface_animation_destroy(struct weston_surface_animation *animation)
weston_view_animation_destroy(struct weston_view_animation *animation)
{
wl_list_remove(&animation->animation.link);
wl_list_remove(&animation->listener.link);
wl_list_remove(&animation->transform.link);
if (animation->reset)
animation->reset(animation);
weston_surface_geometry_dirty(animation->surface);
weston_view_geometry_dirty(animation->view);
if (animation->done)
animation->done(animation, animation->data);
free(animation);
}
static void
handle_animation_surface_destroy(struct wl_listener *listener, void *data)
handle_animation_view_destroy(struct wl_listener *listener, void *data)
{
struct weston_surface_animation *animation =
struct weston_view_animation *animation =
container_of(listener,
struct weston_surface_animation, listener);
struct weston_view_animation, listener);
weston_surface_animation_destroy(animation);
weston_view_animation_destroy(animation);
}
static void
weston_surface_animation_frame(struct weston_animation *base,
weston_view_animation_frame(struct weston_animation *base,
struct weston_output *output, uint32_t msecs)
{
struct weston_surface_animation *animation =
struct weston_view_animation *animation =
container_of(base,
struct weston_surface_animation, animation);
struct weston_view_animation, animation);
if (base->frame_counter <= 1)
animation->spring.timestamp = msecs;
@ -167,32 +167,32 @@ weston_surface_animation_frame(struct weston_animation *base,
weston_spring_update(&animation->spring, msecs);
if (weston_spring_done(&animation->spring)) {
weston_surface_animation_destroy(animation);
weston_view_animation_destroy(animation);
return;
}
if (animation->frame)
animation->frame(animation);
weston_surface_geometry_dirty(animation->surface);
weston_compositor_schedule_repaint(animation->surface->compositor);
weston_view_geometry_dirty(animation->view);
weston_view_schedule_repaint(animation->view);
}
static struct weston_surface_animation *
weston_surface_animation_run(struct weston_surface *surface,
static struct weston_view_animation *
weston_view_animation_run(struct weston_view *view,
float start, float stop,
weston_surface_animation_frame_func_t frame,
weston_surface_animation_frame_func_t reset,
weston_surface_animation_done_func_t done,
weston_view_animation_frame_func_t frame,
weston_view_animation_frame_func_t reset,
weston_view_animation_done_func_t done,
void *data)
{
struct weston_surface_animation *animation;
struct weston_view_animation *animation;
animation = malloc(sizeof *animation);
if (!animation)
return NULL;
animation->surface = surface;
animation->view = view;
animation->frame = frame;
animation->reset = reset;
animation->done = done;
@ -200,35 +200,35 @@ weston_surface_animation_run(struct weston_surface *surface,
animation->start = start;
animation->stop = stop;
weston_matrix_init(&animation->transform.matrix);
wl_list_insert(&surface->geometry.transformation_list,
wl_list_insert(&view->geometry.transformation_list,
&animation->transform.link);
weston_spring_init(&animation->spring, 200.0, 0.0, 1.0);
animation->spring.friction = 700;
animation->animation.frame_counter = 0;
animation->animation.frame = weston_surface_animation_frame;
weston_surface_animation_frame(&animation->animation, NULL, 0);
animation->animation.frame = weston_view_animation_frame;
weston_view_animation_frame(&animation->animation, NULL, 0);
animation->listener.notify = handle_animation_surface_destroy;
wl_signal_add(&surface->destroy_signal, &animation->listener);
animation->listener.notify = handle_animation_view_destroy;
wl_signal_add(&view->destroy_signal, &animation->listener);
wl_list_insert(&surface->output->animation_list,
wl_list_insert(&view->output->animation_list,
&animation->animation.link);
return animation;
}
static void
reset_alpha(struct weston_surface_animation *animation)
reset_alpha(struct weston_view_animation *animation)
{
struct weston_surface *surface = animation->surface;
struct weston_view *view = animation->view;
surface->alpha = animation->stop;
view->alpha = animation->stop;
}
static void
zoom_frame(struct weston_surface_animation *animation)
zoom_frame(struct weston_view_animation *animation)
{
struct weston_surface *es = animation->surface;
struct weston_view *es = animation->view;
float scale;
scale = animation->start +
@ -248,13 +248,13 @@ zoom_frame(struct weston_surface_animation *animation)
es->alpha = 1.0;
}
WL_EXPORT struct weston_surface_animation *
weston_zoom_run(struct weston_surface *surface, float start, float stop,
weston_surface_animation_done_func_t done, void *data)
WL_EXPORT struct weston_view_animation *
weston_zoom_run(struct weston_view *view, float start, float stop,
weston_view_animation_done_func_t done, void *data)
{
struct weston_surface_animation *zoom;
struct weston_view_animation *zoom;
zoom = weston_surface_animation_run(surface, start, stop,
zoom = weston_view_animation_run(view, start, stop,
zoom_frame, reset_alpha,
done, data);
@ -266,24 +266,24 @@ weston_zoom_run(struct weston_surface *surface, float start, float stop,
}
static void
fade_frame(struct weston_surface_animation *animation)
fade_frame(struct weston_view_animation *animation)
{
if (animation->spring.current > 0.999)
animation->surface->alpha = 1;
animation->view->alpha = 1;
else if (animation->spring.current < 0.001 )
animation->surface->alpha = 0;
animation->view->alpha = 0;
else
animation->surface->alpha = animation->spring.current;
animation->view->alpha = animation->spring.current;
}
WL_EXPORT struct weston_surface_animation *
weston_fade_run(struct weston_surface *surface,
WL_EXPORT struct weston_view_animation *
weston_fade_run(struct weston_view *view,
float start, float end, float k,
weston_surface_animation_done_func_t done, void *data)
weston_view_animation_done_func_t done, void *data)
{
struct weston_surface_animation *fade;
struct weston_view_animation *fade;
fade = weston_surface_animation_run(surface, 0, end,
fade = weston_view_animation_run(view, 0, end,
fade_frame, reset_alpha,
done, data);
@ -292,19 +292,19 @@ weston_fade_run(struct weston_surface *surface,
fade->spring.friction = 1400;
fade->spring.previous = -(end - start) * 0.03;
surface->alpha = start;
view->alpha = start;
return fade;
}
WL_EXPORT void
weston_fade_update(struct weston_surface_animation *fade, float target)
weston_fade_update(struct weston_view_animation *fade, float target)
{
fade->spring.target = target;
}
static void
slide_frame(struct weston_surface_animation *animation)
slide_frame(struct weston_view_animation *animation)
{
float scale;
@ -315,13 +315,13 @@ slide_frame(struct weston_surface_animation *animation)
weston_matrix_translate(&animation->transform.matrix, 0, scale, 0);
}
WL_EXPORT struct weston_surface_animation *
weston_slide_run(struct weston_surface *surface, float start, float stop,
weston_surface_animation_done_func_t done, void *data)
WL_EXPORT struct weston_view_animation *
weston_slide_run(struct weston_view *view, float start, float stop,
weston_view_animation_done_func_t done, void *data)
{
struct weston_surface_animation *animation;
struct weston_view_animation *animation;
animation = weston_surface_animation_run(surface, start, stop,
animation = weston_view_animation_run(view, start, stop,
slide_frame, NULL, done,
data);
if (!animation)

@ -156,7 +156,7 @@ struct drm_output {
struct gbm_bo *cursor_bo[2];
struct weston_plane cursor_plane;
struct weston_plane fb_plane;
struct weston_surface *cursor_surface;
struct weston_view *cursor_view;
int current_cursor;
struct drm_fb *current, *next;
struct backlight *backlight;
@ -448,23 +448,23 @@ drm_output_check_scanout_format(struct drm_output *output,
}
static struct weston_plane *
drm_output_prepare_scanout_surface(struct weston_output *_output,
struct weston_surface *es)
drm_output_prepare_scanout_view(struct weston_output *_output,
struct weston_view *ev)
{
struct drm_output *output = (struct drm_output *) _output;
struct drm_compositor *c =
(struct drm_compositor *) output->base.compositor;
struct weston_buffer *buffer = es->buffer_ref.buffer;
struct weston_buffer *buffer = ev->surface->buffer_ref.buffer;
struct gbm_bo *bo;
uint32_t format;
if (es->geometry.x != output->base.x ||
es->geometry.y != output->base.y ||
if (ev->geometry.x != output->base.x ||
ev->geometry.y != output->base.y ||
buffer == NULL || c->gbm == NULL ||
buffer->width != output->base.current_mode->width ||
buffer->height != output->base.current_mode->height ||
output->base.transform != es->buffer_transform ||
es->transform.enabled)
output->base.transform != ev->surface->buffer_transform ||
ev->transform.enabled)
return NULL;
bo = gbm_bo_import(c->gbm, GBM_BO_IMPORT_WL_BUFFER,
@ -474,7 +474,7 @@ drm_output_prepare_scanout_surface(struct weston_output *_output,
if (!bo)
return NULL;
format = drm_output_check_scanout_format(output, es, bo);
format = drm_output_check_scanout_format(output, ev->surface, bo);
if (format == 0) {
gbm_bo_destroy(bo);
return NULL;
@ -766,7 +766,7 @@ page_flip_handler(int fd, unsigned int frame,
static uint32_t
drm_output_check_sprite_format(struct drm_sprite *s,
struct weston_surface *es, struct gbm_bo *bo)
struct weston_view *ev, struct gbm_bo *bo)
{
uint32_t i, format;
@ -776,9 +776,9 @@ drm_output_check_sprite_format(struct drm_sprite *s,
pixman_region32_t r;
pixman_region32_init_rect(&r, 0, 0,
es->geometry.width,
es->geometry.height);
pixman_region32_subtract(&r, &r, &es->opaque);
ev->geometry.width,
ev->geometry.height);
pixman_region32_subtract(&r, &r, &ev->surface->opaque);
if (!pixman_region32_not_empty(&r))
format = GBM_FORMAT_XRGB8888;
@ -794,15 +794,15 @@ drm_output_check_sprite_format(struct drm_sprite *s,
}
static int
drm_surface_transform_supported(struct weston_surface *es)
drm_view_transform_supported(struct weston_view *ev)
{
return !es->transform.enabled ||
(es->transform.matrix.type < WESTON_MATRIX_TRANSFORM_ROTATE);
return !ev->transform.enabled ||
(ev->transform.matrix.type < WESTON_MATRIX_TRANSFORM_ROTATE);
}
static struct weston_plane *
drm_output_prepare_overlay_surface(struct weston_output *output_base,
struct weston_surface *es)
drm_output_prepare_overlay_view(struct weston_output *output_base,
struct weston_view *ev)
{
struct weston_compositor *ec = output_base->compositor;
struct drm_compositor *c =(struct drm_compositor *) ec;
@ -817,28 +817,28 @@ drm_output_prepare_overlay_surface(struct weston_output *output_base,
if (c->gbm == NULL)
return NULL;
if (es->buffer_transform != output_base->transform)
if (ev->surface->buffer_transform != output_base->transform)
return NULL;
if (es->buffer_scale != output_base->current_scale)
if (ev->surface->buffer_scale != output_base->current_scale)
return NULL;
if (c->sprites_are_broken)
return NULL;
if (es->output_mask != (1u << output_base->id))
if (ev->output_mask != (1u << output_base->id))
return NULL;
if (es->buffer_ref.buffer == NULL)
if (ev->surface->buffer_ref.buffer == NULL)
return NULL;
if (es->alpha != 1.0f)
if (ev->alpha != 1.0f)
return NULL;
if (wl_shm_buffer_get(es->buffer_ref.buffer->resource))
if (wl_shm_buffer_get(ev->surface->buffer_ref.buffer->resource))
return NULL;
if (!drm_surface_transform_supported(es))
if (!drm_view_transform_supported(ev))
return NULL;
wl_list_for_each(s, &c->sprite_list, link) {
@ -856,12 +856,12 @@ drm_output_prepare_overlay_surface(struct weston_output *output_base,
return NULL;
bo = gbm_bo_import(c->gbm, GBM_BO_IMPORT_WL_BUFFER,
es->buffer_ref.buffer->resource,
ev->surface->buffer_ref.buffer->resource,
GBM_BO_USE_SCANOUT);
if (!bo)
return NULL;
format = drm_output_check_sprite_format(s, es, bo);
format = drm_output_check_sprite_format(s, ev, bo);
if (format == 0) {
gbm_bo_destroy(bo);
return NULL;
@ -873,9 +873,9 @@ drm_output_prepare_overlay_surface(struct weston_output *output_base,
return NULL;
}
drm_fb_set_buffer(s->next, es->buffer_ref.buffer);
drm_fb_set_buffer(s->next, ev->surface->buffer_ref.buffer);
box = pixman_region32_extents(&es->transform.boundingbox);
box = pixman_region32_extents(&ev->transform.boundingbox);
s->plane.x = box->x1;
s->plane.y = box->y1;
@ -885,7 +885,7 @@ drm_output_prepare_overlay_surface(struct weston_output *output_base,
* for us already).
*/
pixman_region32_init(&dest_rect);
pixman_region32_intersect(&dest_rect, &es->transform.boundingbox,
pixman_region32_intersect(&dest_rect, &ev->transform.boundingbox,
&output_base->region);
pixman_region32_translate(&dest_rect, -output_base->x, -output_base->y);
box = pixman_region32_extents(&dest_rect);
@ -901,15 +901,15 @@ drm_output_prepare_overlay_surface(struct weston_output *output_base,
pixman_region32_fini(&dest_rect);
pixman_region32_init(&src_rect);
pixman_region32_intersect(&src_rect, &es->transform.boundingbox,
pixman_region32_intersect(&src_rect, &ev->transform.boundingbox,
&output_base->region);
box = pixman_region32_extents(&src_rect);
weston_surface_from_global_fixed(es,
weston_view_from_global_fixed(ev,
wl_fixed_from_int(box->x1),
wl_fixed_from_int(box->y1),
&sx1, &sy1);
weston_surface_from_global_fixed(es,
weston_view_from_global_fixed(ev,
wl_fixed_from_int(box->x2),
wl_fixed_from_int(box->y2),
&sx2, &sy2);
@ -918,19 +918,20 @@ drm_output_prepare_overlay_surface(struct weston_output *output_base,
sx1 = 0;
if (sy1 < 0)
sy1 = 0;
if (sx2 > wl_fixed_from_int(es->geometry.width))
sx2 = wl_fixed_from_int(es->geometry.width);
if (sy2 > wl_fixed_from_int(es->geometry.height))
sy2 = wl_fixed_from_int(es->geometry.height);
if (sx2 > wl_fixed_from_int(ev->geometry.width))
sx2 = wl_fixed_from_int(ev->geometry.width);
if (sy2 > wl_fixed_from_int(ev->geometry.height))
sy2 = wl_fixed_from_int(ev->geometry.height);
tbox.x1 = sx1;
tbox.y1 = sy1;
tbox.x2 = sx2;
tbox.y2 = sy2;
tbox = weston_transformed_rect(wl_fixed_from_int(es->geometry.width),
wl_fixed_from_int(es->geometry.height),
es->buffer_transform, es->buffer_scale, tbox);
tbox = weston_transformed_rect(wl_fixed_from_int(ev->geometry.width),
wl_fixed_from_int(ev->geometry.height),
ev->surface->buffer_transform,
ev->surface->buffer_scale, tbox);
s->src_x = tbox.x1 << 8;
s->src_y = tbox.y1 << 8;
@ -942,8 +943,8 @@ drm_output_prepare_overlay_surface(struct weston_output *output_base,
}
static struct weston_plane *
drm_output_prepare_cursor_surface(struct weston_output *output_base,
struct weston_surface *es)
drm_output_prepare_cursor_view(struct weston_output *output_base,
struct weston_view *ev)
{
struct drm_compositor *c =
(struct drm_compositor *) output_base->compositor;
@ -953,18 +954,18 @@ drm_output_prepare_cursor_surface(struct weston_output *output_base,
return NULL;
if (output->base.transform != WL_OUTPUT_TRANSFORM_NORMAL)
return NULL;
if (output->cursor_surface)
if (output->cursor_view)
return NULL;
if (es->output_mask != (1u << output_base->id))
if (ev->output_mask != (1u << output_base->id))
return NULL;
if (c->cursors_are_broken)
return NULL;
if (es->buffer_ref.buffer == NULL ||
!wl_shm_buffer_get(es->buffer_ref.buffer->resource) ||
es->geometry.width > 64 || es->geometry.height > 64)
if (ev->surface->buffer_ref.buffer == NULL ||
!wl_shm_buffer_get(ev->surface->buffer_ref.buffer->resource) ||
ev->geometry.width > 64 || ev->geometry.height > 64)
return NULL;
output->cursor_surface = es;
output->cursor_view = ev;
return &output->cursor_plane;
}
@ -972,7 +973,7 @@ drm_output_prepare_cursor_surface(struct weston_output *output_base,
static void
drm_output_set_cursor(struct drm_output *output)
{
struct weston_surface *es = output->cursor_surface;
struct weston_view *ev = output->cursor_view;
struct drm_compositor *c =
(struct drm_compositor *) output->base.compositor;
EGLint handle, stride;
@ -981,24 +982,24 @@ drm_output_set_cursor(struct drm_output *output)
unsigned char *s;
int i, x, y;
output->cursor_surface = NULL;
if (es == NULL) {
output->cursor_view = NULL;
if (ev == NULL) {
drmModeSetCursor(c->drm.fd, output->crtc_id, 0, 0, 0);
return;
}
if (es->buffer_ref.buffer &&
if (ev->surface->buffer_ref.buffer &&
pixman_region32_not_empty(&output->cursor_plane.damage)) {
pixman_region32_fini(&output->cursor_plane.damage);
pixman_region32_init(&output->cursor_plane.damage);
output->current_cursor ^= 1;
bo = output->cursor_bo[output->current_cursor];
memset(buf, 0, sizeof buf);
stride = wl_shm_buffer_get_stride(es->buffer_ref.buffer->shm_buffer);
s = wl_shm_buffer_get_data(es->buffer_ref.buffer->shm_buffer);
for (i = 0; i < es->geometry.height; i++)
stride = wl_shm_buffer_get_stride(ev->surface->buffer_ref.buffer->shm_buffer);
s = wl_shm_buffer_get_data(ev->surface->buffer_ref.buffer->shm_buffer);
for (i = 0; i < ev->geometry.height; i++)
memcpy(buf + i * 64, s + i * stride,
es->geometry.width * 4);
ev->geometry.width * 4);
if (gbm_bo_write(bo, buf, sizeof buf) < 0)
weston_log("failed update cursor: %m\n");
@ -1011,8 +1012,8 @@ drm_output_set_cursor(struct drm_output *output)
}
}
x = (es->geometry.x - output->base.x) * output->base.current_scale;
y = (es->geometry.y - output->base.y) * output->base.current_scale;
x = (ev->geometry.x - output->base.x) * output->base.current_scale;
y = (ev->geometry.y - output->base.y) * output->base.current_scale;
if (output->cursor_plane.x != x || output->cursor_plane.y != y) {
if (drmModeMoveCursor(c->drm.fd, output->crtc_id, x, y)) {
weston_log("failed to move cursor: %m\n");
@ -1029,7 +1030,7 @@ drm_assign_planes(struct weston_output *output)
{
struct drm_compositor *c =
(struct drm_compositor *) output->compositor;
struct weston_surface *es, *next;
struct weston_view *ev, *next;
pixman_region32_t overlap, surface_overlap;
struct weston_plane *primary, *next_plane;
@ -1048,36 +1049,39 @@ drm_assign_planes(struct weston_output *output)
*/
pixman_region32_init(&overlap);
primary = &c->base.primary_plane;
wl_list_for_each_safe(es, next, &c->base.surface_list, link) {
/* Flag all visible surfaces as keep_buffer = 1 */
wl_list_for_each(ev, &c->base.view_list, link)
ev->surface->keep_buffer = 1;
wl_list_for_each_safe(ev, next, &c->base.view_list, link) {
/* test whether this buffer can ever go into a plane:
* non-shm, or small enough to be a cursor
*/
if ((es->buffer_ref.buffer &&
!wl_shm_buffer_get(es->buffer_ref.buffer->resource)) ||
(es->geometry.width <= 64 && es->geometry.height <= 64))
es->keep_buffer = 1;
else
es->keep_buffer = 0;
if (!ev->surface->buffer_ref.buffer ||
(wl_shm_buffer_get(ev->surface->buffer_ref.buffer->resource) &&
(ev->geometry.width > 64 || ev->geometry.height > 64)))
ev->surface->keep_buffer = 0;
pixman_region32_init(&surface_overlap);
pixman_region32_intersect(&surface_overlap, &overlap,
&es->transform.boundingbox);
&ev->transform.boundingbox);
next_plane = NULL;
if (pixman_region32_not_empty(&surface_overlap))
next_plane = primary;
if (next_plane == NULL)
next_plane = drm_output_prepare_cursor_surface(output, es);
next_plane = drm_output_prepare_cursor_view(output, ev);
if (next_plane == NULL)
next_plane = drm_output_prepare_scanout_surface(output, es);
next_plane = drm_output_prepare_scanout_view(output, ev);
if (next_plane == NULL)
next_plane = drm_output_prepare_overlay_surface(output, es);
next_plane = drm_output_prepare_overlay_view(output, ev);
if (next_plane == NULL)
next_plane = primary;
weston_surface_move_to_plane(es, next_plane);
weston_view_move_to_plane(ev, next_plane);
if (next_plane == primary)
pixman_region32_union(&overlap, &overlap,
&es->transform.boundingbox);
&ev->transform.boundingbox);
pixman_region32_fini(&surface_overlap);
}

File diff suppressed because it is too large Load Diff

@ -92,6 +92,8 @@ struct weston_shell_interface {
struct shell_surface *(*create_shell_surface)(void *shell,
struct weston_surface *surface,
const struct weston_shell_client *client);
struct weston_view *(*get_primary_view)(void *shell,
struct shell_surface *shsurf);
void (*set_toplevel)(struct shell_surface *shsurf);
@ -140,18 +142,12 @@ struct weston_spring {
uint32_t clip;
};
enum {
ZOOM_FOCUS_POINTER,
ZOOM_FOCUS_TEXT
};
struct weston_fixed_point {
wl_fixed_t x, y;
};
struct weston_output_zoom {
int active;
uint32_t type;
float increment;
float level;
float max_level;
@ -163,7 +159,6 @@ struct weston_output_zoom {
struct weston_fixed_point from;
struct weston_fixed_point to;
struct weston_fixed_point current;
struct weston_fixed_point text_cursor;
};
/* bit compatible with drm definitions. */
@ -311,11 +306,11 @@ struct weston_pointer {
struct wl_list resource_list;
struct wl_list focus_resource_list;
struct weston_surface *focus;
struct weston_view *focus;
uint32_t focus_serial;
struct wl_signal focus_signal;
struct weston_surface *sprite;
struct weston_view *sprite;
struct wl_listener sprite_destroy_listener;
int32_t hotspot_x, hotspot_y;
@ -336,7 +331,7 @@ struct weston_touch {
struct wl_list resource_list;
struct wl_list focus_resource_list;
struct weston_surface *focus;
struct weston_view *focus;
uint32_t focus_serial;
struct wl_signal focus_signal;
@ -354,7 +349,7 @@ void
weston_pointer_destroy(struct weston_pointer *pointer);
void
weston_pointer_set_focus(struct weston_pointer *pointer,
struct weston_surface *surface,
struct weston_view *view,
wl_fixed_t sx, wl_fixed_t sy);
void
weston_pointer_start_grab(struct weston_pointer *pointer,
@ -384,7 +379,7 @@ void
weston_touch_destroy(struct weston_touch *touch);
void
weston_touch_set_focus(struct weston_seat *seat,
struct weston_surface *surface);
struct weston_view *view);
void
weston_touch_start_grab(struct weston_touch *device,
struct weston_touch_grab *grab);
@ -504,7 +499,7 @@ enum {
};
struct weston_layer {
struct wl_list surface_list;
struct wl_list view_list;
struct wl_list link;
};
@ -525,10 +520,12 @@ struct weston_renderer {
void (*flush_damage)(struct weston_surface *surface);
void (*attach)(struct weston_surface *es, struct weston_buffer *buffer);
int (*create_surface)(struct weston_surface *surface);
int (*create_view)(struct weston_view *view);
void (*surface_set_color)(struct weston_surface *surface,
float red, float green,
float blue, float alpha);
void (*destroy_surface)(struct weston_surface *surface);
void (*destroy_view)(struct weston_view *view);
void (*destroy)(struct weston_compositor *ec);
};
@ -574,7 +571,7 @@ struct weston_compositor {
struct wl_list output_list;
struct wl_list seat_list;
struct wl_list layer_list;
struct wl_list surface_list;
struct wl_list view_list;
struct wl_list plane_list;
struct wl_list key_binding_list;
struct wl_list button_binding_list;
@ -685,51 +682,52 @@ struct weston_subsurface {
} cached;
int synchronized;
/* Used for constructing the view tree */
struct wl_list unused_views;
};
/* Using weston_surface transformations
/* Using weston_view 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
* To add a transformation to a view, create a struct weston_transform, and
* add it to the list view->geometry.transformation_list. Whenever you
* change the list, anything under view->geometry, or anything in the
* weston_transforms linked into the list, you must call
* weston_surface_geometry_dirty().
* weston_view_geometry_dirty().
*
* 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
* transformation is applied to view-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.
* is cached in view->transform.matrix, and the inverse of it in
* view->transform.inverse.
*
* The list always contains surface->transform.position transformation, which
* is the translation by surface->geometry.x and y.
* The list always contains view->transform.position transformation, which
* is the translation by view->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.
*
* If surface->geometry.parent is set, the total transformation of this
* surface will be the parent's total transformation and this transformation
* If view->geometry.parent is set, the total transformation of this
* view will be the parent's total transformation and this transformation
* combined:
* Mparent * Mn * ... * M2 * M1
*/
struct weston_surface {
struct wl_resource *resource;
struct weston_view {
struct weston_surface *surface;
struct wl_list surface_link;
struct wl_signal destroy_signal;
struct weston_compositor *compositor;
pixman_region32_t clip;
pixman_region32_t damage;
pixman_region32_t opaque; /* part of geometry, see below */
pixman_region32_t input;
struct wl_list link;
struct wl_list layer_link;
float alpha; /* part of geometry, see below */
struct weston_plane *plane;
int32_t ref_count;
pixman_region32_t clip;
float alpha; /* part of geometry, see below */
void *renderer_state;
@ -745,14 +743,14 @@ struct weston_surface {
struct wl_list transformation_list;
/* managed by weston_surface_set_transform_parent() */
struct weston_surface *parent;
struct weston_view *parent;
struct wl_listener parent_destroy_listener;
struct wl_list child_list; /* geometry.parent_link */
struct wl_list parent_link;
} geometry;
/* State derived from geometry state, read-only.
* This is updated by weston_surface_update_transform().
* This is updated by weston_view_update_transform().
*/
struct {
int dirty;
@ -782,6 +780,39 @@ struct weston_surface {
* displayed on.
*/
uint32_t output_mask;
};
struct weston_surface {
struct wl_resource *resource;
struct wl_signal destroy_signal;
struct weston_compositor *compositor;
pixman_region32_t damage;
pixman_region32_t opaque; /* part of geometry, see below */
pixman_region32_t input;
int32_t width, height;
int32_t ref_count;
/* Not for long-term storage. This exists for book-keeping while
* iterating over surfaces and views
*/
int32_t touched;
void *renderer_state;
struct wl_list views;
/*
* Which output to vsync this surface to.
* Used to determine, whether to send or queue frame events.
* Must be NULL, if 'link' is not in weston_compositor::surface_list.
*/
struct weston_output *output;
/*
* A more complete representation of all outputs this surface is
* displayed on.
*/
uint32_t output_mask;
struct wl_list frame_callback_list;
@ -843,29 +874,29 @@ void
weston_version(int *major, int *minor, int *micro);
void
weston_surface_update_transform(struct weston_surface *surface);
weston_view_update_transform(struct weston_view *view);
void
weston_surface_geometry_dirty(struct weston_surface *surface);
weston_view_geometry_dirty(struct weston_view *view);
void
weston_surface_to_global_fixed(struct weston_surface *surface,
weston_view_to_global_fixed(struct weston_view *view,
wl_fixed_t sx, wl_fixed_t sy,
wl_fixed_t *x, wl_fixed_t *y);
void
weston_surface_to_global_float(struct weston_surface *surface,
weston_view_to_global_float(struct weston_view *view,
float sx, float sy, float *x, float *y);
void
weston_surface_from_global_float(struct weston_surface *surface,
float x, float y, float *sx, float *sy);
weston_view_from_global_float(struct weston_view *view,
float x, float y, float *vx, float *vy);
void
weston_surface_from_global(struct weston_surface *surface,
int32_t x, int32_t y, int32_t *sx, int32_t *sy);
weston_view_from_global(struct weston_view *view,
int32_t x, int32_t y, int32_t *vx, int32_t *vy);
void
weston_surface_from_global_fixed(struct weston_surface *surface,
weston_view_from_global_fixed(struct weston_view *view,
wl_fixed_t x, wl_fixed_t y,
wl_fixed_t *sx, wl_fixed_t *sy);
wl_fixed_t *vx, wl_fixed_t *vy);
int32_t
weston_surface_buffer_width(struct weston_surface *surface);
int32_t
@ -877,7 +908,6 @@ weston_surface_to_buffer_float(struct weston_surface *surface,
WL_EXPORT void
weston_surface_to_buffer(struct weston_surface *surface,
int sx, int sy, int *bx, int *by);
pixman_box32_t
weston_surface_to_buffer_rect(struct weston_surface *surface,
pixman_box32_t rect);
@ -959,8 +989,8 @@ void
weston_compositor_offscreen(struct weston_compositor *compositor);
void
weston_compositor_sleep(struct weston_compositor *compositor);
struct weston_surface *
weston_compositor_pick_surface(struct weston_compositor *compositor,
struct weston_view *
weston_compositor_pick_view(struct weston_compositor *compositor,
wl_fixed_t x, wl_fixed_t y,
wl_fixed_t *sx, wl_fixed_t *sy);
@ -1048,20 +1078,32 @@ weston_compositor_top(struct weston_compositor *compositor);
struct weston_surface *
weston_surface_create(struct weston_compositor *compositor);
struct weston_view *
weston_view_create(struct weston_surface *surface);
void
weston_surface_configure(struct weston_surface *surface,
weston_view_destroy(struct weston_view *view);
void
weston_view_configure(struct weston_view *view,
float x, float y, int width, int height);
void
weston_surface_restack(struct weston_surface *surface, struct wl_list *below);
weston_view_restack(struct weston_view *surface, struct wl_list *below);
void
weston_surface_set_position(struct weston_surface *surface,
weston_view_set_position(struct weston_view *view,
float x, float y);
void
weston_surface_set_transform_parent(struct weston_surface *surface,
struct weston_surface *parent);
weston_view_set_transform_parent(struct weston_view *view,
struct weston_view *parent);
int
weston_view_is_mapped(struct weston_view *view);
void
weston_view_schedule_repaint(struct weston_view *view);
int
weston_surface_is_mapped(struct weston_surface *surface);
@ -1073,11 +1115,14 @@ void
weston_surface_damage(struct weston_surface *surface);
void
weston_surface_damage_below(struct weston_surface *surface);
weston_view_damage_below(struct weston_view *view);
void
weston_surface_move_to_plane(struct weston_surface *surface,
weston_view_move_to_plane(struct weston_view *view,
struct weston_plane *plane);
void
weston_view_unmap(struct weston_view *view);
void
weston_surface_unmap(struct weston_surface *surface);
@ -1100,12 +1145,9 @@ weston_compositor_init(struct weston_compositor *ec, struct wl_display *display,
void
weston_compositor_shutdown(struct weston_compositor *ec);
void
weston_text_cursor_position_notify(struct weston_surface *surface,
wl_fixed_t x, wl_fixed_t y);
void
weston_output_init_zoom(struct weston_output *output);
void
weston_output_update_zoom(struct weston_output *output, uint32_t type);
weston_output_update_zoom(struct weston_output *output);
void
weston_output_update_matrix(struct weston_output *output);
void
@ -1187,9 +1229,6 @@ screenshooter_create(struct weston_compositor *ec);
struct clipboard *
clipboard_create(struct weston_seat *seat);
void
text_cursor_position_notifier_create(struct weston_compositor *ec);
int
text_backend_init(struct weston_compositor *ec);
@ -1212,23 +1251,23 @@ weston_client_launch(struct weston_compositor *compositor,
void
weston_watch_process(struct weston_process *process);
struct weston_surface_animation;
typedef void (*weston_surface_animation_done_func_t)(struct weston_surface_animation *animation, void *data);
struct weston_view_animation;
typedef void (*weston_view_animation_done_func_t)(struct weston_view_animation *animation, void *data);
struct weston_surface_animation *
weston_zoom_run(struct weston_surface *surface, float start, float stop,
weston_surface_animation_done_func_t done, void *data);
struct weston_view_animation *
weston_zoom_run(struct weston_view *view, float start, float stop,
weston_view_animation_done_func_t done, void *data);
struct weston_surface_animation *
weston_fade_run(struct weston_surface *surface,
struct weston_view_animation *
weston_fade_run(struct weston_view *view,
float start, float end, float k,
weston_surface_animation_done_func_t done, void *data);
weston_view_animation_done_func_t done, void *data);
void
weston_fade_update(struct weston_surface_animation *fade, float target);
weston_fade_update(struct weston_view_animation *fade, float target);
struct weston_surface_animation *
weston_slide_run(struct weston_surface *surface, float start, float stop,
weston_surface_animation_done_func_t done, void *data);
struct weston_view_animation *
weston_slide_run(struct weston_view *view, float start, float stop,
weston_view_animation_done_func_t done, void *data);
void
weston_surface_set_color(struct weston_surface *surface,

@ -26,6 +26,7 @@
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include <assert.h>
#include "compositor.h"
@ -33,11 +34,11 @@ struct weston_drag {
struct wl_client *client;
struct weston_data_source *data_source;
struct wl_listener data_source_listener;
struct weston_surface *focus;
struct weston_view *focus;
struct wl_resource *focus_resource;
struct wl_listener focus_listener;
struct weston_pointer_grab grab;
struct weston_surface *icon;
struct weston_view *icon;
struct wl_listener icon_destroy_listener;
int32_t dx, dy;
};
@ -178,14 +179,17 @@ drag_surface_configure(struct weston_surface *es, int32_t sx, int32_t sy, int32_
struct wl_list *list;
float fx, fy;
assert(es->configure == drag_surface_configure);
if (!weston_surface_is_mapped(es) && es->buffer_ref.buffer) {
if (pointer->sprite && weston_surface_is_mapped(pointer->sprite))
if (pointer->sprite && weston_view_is_mapped(pointer->sprite))
list = &pointer->sprite->layer_link;
else
list = &es->compositor->cursor_layer.surface_list;
list = &es->compositor->cursor_layer.view_list;
wl_list_insert(list, &es->layer_link);
weston_surface_update_transform(es);
wl_list_remove(&drag->icon->layer_link);
wl_list_insert(list, &drag->icon->layer_link);
weston_view_update_transform(drag->icon);
empty_region(&es->pending.input);
}
@ -194,7 +198,7 @@ drag_surface_configure(struct weston_surface *es, int32_t sx, int32_t sy, int32_
fx = wl_fixed_to_double(pointer->x) + drag->dx;
fy = wl_fixed_to_double(pointer->y) + drag->dy;
weston_surface_configure(es, fx, fy, width, height);
weston_view_configure(drag->icon, fx, fy, width, height);
}
static void
@ -207,7 +211,7 @@ destroy_drag_focus(struct wl_listener *listener, void *data)
}
static void
weston_drag_set_focus(struct weston_drag *drag, struct weston_surface *surface,
weston_drag_set_focus(struct weston_drag *drag, struct weston_view *view,
wl_fixed_t sx, wl_fixed_t sy)
{
struct weston_pointer *pointer = drag->grab.pointer;
@ -215,6 +219,11 @@ weston_drag_set_focus(struct weston_drag *drag, struct weston_surface *surface,
struct wl_display *display = pointer->seat->compositor->wl_display;
uint32_t serial;
if (drag->focus && view && drag->focus->surface == view->surface) {
drag->focus = view;
return;
}
if (drag->focus_resource) {
wl_data_device_send_leave(drag->focus_resource);
wl_list_remove(&drag->focus_listener.link);
@ -222,15 +231,15 @@ weston_drag_set_focus(struct weston_drag *drag, struct weston_surface *surface,
drag->focus = NULL;
}
if (!surface)
if (!view || !view->surface->resource)
return;
if (!drag->data_source &&
wl_resource_get_client(surface->resource) != drag->client)
wl_resource_get_client(view->surface->resource) != drag->client)
return;
resource = wl_resource_find_for_client(&pointer->seat->drag_resource_list,
wl_resource_get_client(surface->resource));
wl_resource_get_client(view->surface->resource));
if (!resource)
return;
@ -243,10 +252,10 @@ weston_drag_set_focus(struct weston_drag *drag, struct weston_surface *surface,
return;
}
wl_data_device_send_enter(resource, serial, surface->resource,
wl_data_device_send_enter(resource, serial, view->surface->resource,
sx, sy, offer);
drag->focus = surface;
drag->focus = view;
drag->focus_listener.notify = destroy_drag_focus;
wl_resource_add_destroy_listener(resource, &drag->focus_listener);
drag->focus_resource = resource;
@ -258,14 +267,14 @@ drag_grab_focus(struct weston_pointer_grab *grab)
struct weston_drag *drag =
container_of(grab, struct weston_drag, grab);
struct weston_pointer *pointer = grab->pointer;
struct weston_surface *surface;
struct weston_view *view;
wl_fixed_t sx, sy;
surface = weston_compositor_pick_surface(pointer->seat->compositor,
view = weston_compositor_pick_view(pointer->seat->compositor,
pointer->x, pointer->y,
&sx, &sy);
if (drag->focus != surface)
weston_drag_set_focus(drag, surface, sx, sy);
if (drag->focus != view)
weston_drag_set_focus(drag, view, sx, sy);
}
static void
@ -280,12 +289,12 @@ drag_grab_motion(struct weston_pointer_grab *grab, uint32_t time)
if (drag->icon) {
fx = wl_fixed_to_double(pointer->x) + drag->dx;
fy = wl_fixed_to_double(pointer->y) + drag->dy;
weston_surface_set_position(drag->icon, fx, fy);
weston_surface_schedule_repaint(drag->icon);
weston_view_set_position(drag->icon, fx, fy);
weston_view_schedule_repaint(drag->icon);
}
if (drag->focus_resource) {
weston_surface_from_global_fixed(drag->focus,
weston_view_from_global_fixed(drag->focus,
pointer->x, pointer->y,
&sx, &sy);
@ -297,12 +306,13 @@ static void
data_device_end_drag_grab(struct weston_drag *drag)
{
if (drag->icon) {
if (weston_surface_is_mapped(drag->icon))
weston_surface_unmap(drag->icon);
if (weston_view_is_mapped(drag->icon))
weston_view_unmap(drag->icon);
drag->icon->configure = NULL;
empty_region(&drag->icon->pending.input);
drag->icon->surface->configure = NULL;
empty_region(&drag->icon->surface->pending.input);
wl_list_remove(&drag->icon_destroy_listener.link);
weston_view_destroy(drag->icon);
}
weston_drag_set_focus(drag, NULL, 0, 0);
@ -373,21 +383,28 @@ weston_seat_start_drag(struct weston_seat *seat,
drag->grab.interface = &drag_grab_interface;
drag->client = client;
drag->data_source = source;
drag->icon = icon;
if (source) {
drag->data_source_listener.notify = destroy_data_device_source;
wl_signal_add(&source->destroy_signal,
&drag->data_source_listener);
if (icon) {
drag->icon = weston_view_create(icon);
if (drag->icon == NULL) {
free(drag);
return -1;
}
if (icon) {
drag->icon_destroy_listener.notify = handle_drag_icon_destroy;
wl_signal_add(&icon->destroy_signal,
&drag->icon_destroy_listener);
icon->configure = drag_surface_configure;
icon->configure_private = drag;
} else {
drag->icon = NULL;
}
if (source) {
drag->data_source_listener.notify = destroy_data_device_source;
wl_signal_add(&source->destroy_signal,
&drag->data_source_listener);
}
weston_pointer_set_focus(seat->pointer, NULL,
@ -409,7 +426,8 @@ data_device_start_drag(struct wl_client *client, struct wl_resource *resource,
if (seat->pointer->button_count == 0 ||
seat->pointer->grab_serial != serial ||
seat->pointer->focus != wl_resource_get_user_data(origin_resource))
!seat->pointer->focus ||
seat->pointer->focus->surface != wl_resource_get_user_data(origin_resource))
return;
/* FIXME: Check that the data source type array isn't empty. */

@ -193,7 +193,7 @@ gl_renderer_print_egl_error_state(void)
* polygon area.
*/
static int
calculate_edges(struct weston_surface *es, pixman_box32_t *rect,
calculate_edges(struct weston_view *ev, pixman_box32_t *rect,
pixman_box32_t *surf_rect, GLfloat *ex, GLfloat *ey)
{
@ -213,7 +213,7 @@ calculate_edges(struct weston_surface *es, pixman_box32_t *rect,
/* transform surface to screen space: */
for (i = 0; i < surf.n; i++)
weston_surface_to_global_float(es, surf.x[i], surf.y[i],
weston_view_to_global_float(ev, surf.x[i], surf.y[i],
&surf.x[i], &surf.y[i]);
/* find bounding box: */
@ -238,9 +238,8 @@ calculate_edges(struct weston_surface *es, pixman_box32_t *rect,
* there will be only four edges. We just need to clip the surface
* vertices to the clip rect bounds:
*/
if (!es->transform.enabled) {
if (!ev->transform.enabled)
return clip_simple(&ctx, &surf, ex, ey);
}
/* Transformed case: use a general polygon clipping algorithm to
* clip the surface rectangle with each side of 'rect'.
@ -257,11 +256,11 @@ calculate_edges(struct weston_surface *es, pixman_box32_t *rect,
}
static int
texture_region(struct weston_surface *es, pixman_region32_t *region,
texture_region(struct weston_view *ev, pixman_region32_t *region,
pixman_region32_t *surf_region)
{
struct gl_surface_state *gs = get_surface_state(es);
struct weston_compositor *ec = es->compositor;
struct gl_surface_state *gs = get_surface_state(ev->surface);
struct weston_compositor *ec = ev->surface->compositor;
struct gl_renderer *gr = get_renderer(ec);
GLfloat *v, inv_width, inv_height;
unsigned int *vtxcnt, nvtx = 0;
@ -302,18 +301,20 @@ texture_region(struct weston_surface *es, pixman_region32_t *region,
* form the intersection of the clip rect and the transformed
* surface.
*/
n = calculate_edges(es, rect, surf_rect, ex, ey);
n = calculate_edges(ev, rect, surf_rect, ex, ey);
if (n < 3)
continue;
/* emit edge points: */
for (k = 0; k < n; k++) {
weston_surface_from_global_float(es, ex[k], ey[k], &sx, &sy);
weston_view_from_global_float(ev, ex[k], ey[k],
&sx, &sy);
/* position: */
*(v++) = ex[k];
*(v++) = ey[k];
/* texcoord: */
weston_surface_to_buffer_float(es, sx, sy,
weston_surface_to_buffer_float(ev->surface,
sx, sy,
&bx, &by);
*(v++) = bx * inv_width;
if (gs->y_inverted) {
@ -331,9 +332,9 @@ texture_region(struct weston_surface *es, pixman_region32_t *region,
}
static void
triangle_fan_debug(struct weston_surface *surface, int first, int count)
triangle_fan_debug(struct weston_view *view, int first, int count)
{
struct weston_compositor *compositor = surface->compositor;
struct weston_compositor *compositor = view->surface->compositor;
struct gl_renderer *gr = get_renderer(compositor);
int i;
GLushort *buffer;
@ -371,10 +372,10 @@ triangle_fan_debug(struct weston_surface *surface, int first, int count)
}
static void
repaint_region(struct weston_surface *es, pixman_region32_t *region,
repaint_region(struct weston_view *ev, pixman_region32_t *region,
pixman_region32_t *surf_region)
{
struct weston_compositor *ec = es->compositor;
struct weston_compositor *ec = ev->surface->compositor;
struct gl_renderer *gr = get_renderer(ec);
GLfloat *v;
unsigned int *vtxcnt;
@ -388,7 +389,7 @@ repaint_region(struct weston_surface *es, pixman_region32_t *region,
* polygon for each pair, and store it as a triangle fan if
* it has a non-zero area (at least 3 vertices1, actually).
*/
nfans = texture_region(es, region, surf_region);
nfans = texture_region(ev, region, surf_region);
v = gr->vertices.data;
vtxcnt = gr->vtxcnt.data;
@ -404,7 +405,7 @@ repaint_region(struct weston_surface *es, pixman_region32_t *region,
for (i = 0, first = 0; i < nfans; i++) {
glDrawArrays(GL_TRIANGLE_FAN, first, vtxcnt[i]);
if (gr->fan_debug)
triangle_fan_debug(es, first, vtxcnt[i]);
triangle_fan_debug(ev, first, vtxcnt[i]);
first += vtxcnt[i];
}
@ -464,28 +465,28 @@ use_shader(struct gl_renderer *gr, struct gl_shader *shader)
static void
shader_uniforms(struct gl_shader *shader,
struct weston_surface *surface,
struct weston_view *view,
struct weston_output *output)
{
int i;
struct gl_surface_state *gs = get_surface_state(surface);
struct gl_surface_state *gs = get_surface_state(view->surface);
glUniformMatrix4fv(shader->proj_uniform,
1, GL_FALSE, output->matrix.d);
glUniform4fv(shader->color_uniform, 1, gs->color);
glUniform1f(shader->alpha_uniform, surface->alpha);
glUniform1f(shader->alpha_uniform, view->alpha);
for (i = 0; i < gs->num_textures; i++)
glUniform1i(shader->tex_uniforms[i], i);
}
static void
draw_surface(struct weston_surface *es, struct weston_output *output,
draw_view(struct weston_view *ev, struct weston_output *output,
pixman_region32_t *damage) /* in global coordinates */
{
struct weston_compositor *ec = es->compositor;
struct weston_compositor *ec = ev->surface->compositor;
struct gl_renderer *gr = get_renderer(ec);
struct gl_surface_state *gs = get_surface_state(es);
struct gl_surface_state *gs = get_surface_state(ev->surface);
/* repaint bounding region in global coordinates: */
pixman_region32_t repaint;
/* non-opaque region in surface coordinates: */
@ -495,8 +496,8 @@ draw_surface(struct weston_surface *es, struct weston_output *output,
pixman_region32_init(&repaint);
pixman_region32_intersect(&repaint,
&es->transform.boundingbox, damage);
pixman_region32_subtract(&repaint, &repaint, &es->clip);
&ev->transform.boundingbox, damage);
pixman_region32_subtract(&repaint, &repaint, &ev->clip);
if (!pixman_region32_not_empty(&repaint))
goto out;
@ -505,13 +506,14 @@ draw_surface(struct weston_surface *es, struct weston_output *output,
if (gr->fan_debug) {
use_shader(gr, &gr->solid_shader);
shader_uniforms(&gr->solid_shader, es, output);
shader_uniforms(&gr->solid_shader, ev, output);
}
use_shader(gr, gs->shader);
shader_uniforms(gs->shader, es, output);
shader_uniforms(gs->shader, ev, output);
if (es->transform.enabled || output->zoom.active || output->current_scale != es->buffer_scale)
if (ev->transform.enabled || output->zoom.active ||
output->current_scale != ev->surface->buffer_scale)
filter = GL_LINEAR;
else
filter = GL_NEAREST;
@ -525,10 +527,11 @@ draw_surface(struct weston_surface *es, struct weston_output *output,
/* blended region is whole surface minus opaque region: */
pixman_region32_init_rect(&surface_blend, 0, 0,
es->geometry.width, es->geometry.height);
pixman_region32_subtract(&surface_blend, &surface_blend, &es->opaque);
ev->geometry.width, ev->geometry.height);
pixman_region32_subtract(&surface_blend, &surface_blend, &ev->surface->opaque);
if (pixman_region32_not_empty(&es->opaque)) {
/* XXX: Should we be using ev->transform.opaque here? */
if (pixman_region32_not_empty(&ev->surface->opaque)) {
if (gs->shader == &gr->texture_shader_rgba) {
/* Special case for RGBA textures with possibly
* bad data in alpha channel: use the shader
@ -536,21 +539,21 @@ draw_surface(struct weston_surface *es, struct weston_output *output,
* Xwayland surfaces need this.
*/
use_shader(gr, &gr->texture_shader_rgbx);
shader_uniforms(&gr->texture_shader_rgbx, es, output);
shader_uniforms(&gr->texture_shader_rgbx, ev, output);
}
if (es->alpha < 1.0)
if (ev->alpha < 1.0)
glEnable(GL_BLEND);
else
glDisable(GL_BLEND);
repaint_region(es, &repaint, &es->opaque);
repaint_region(ev, &repaint, &ev->surface->opaque);
}
if (pixman_region32_not_empty(&surface_blend)) {
use_shader(gr, gs->shader);
glEnable(GL_BLEND);
repaint_region(es, &repaint, &surface_blend);
repaint_region(ev, &repaint, &surface_blend);
}
pixman_region32_fini(&surface_blend);
@ -560,14 +563,14 @@ out:
}
static void
repaint_surfaces(struct weston_output *output, pixman_region32_t *damage)
repaint_views(struct weston_output *output, pixman_region32_t *damage)
{
struct weston_compositor *compositor = output->compositor;
struct weston_surface *surface;
struct weston_view *view;
wl_list_for_each_reverse(surface, &compositor->surface_list, link)
if (surface->plane == &compositor->primary_plane)
draw_surface(surface, output, damage);
wl_list_for_each_reverse(view, &compositor->view_list, link)
if (view->plane == &compositor->primary_plane)
draw_view(view, output, damage);
}
@ -762,7 +765,7 @@ gl_renderer_repaint_output(struct weston_output *output,
pixman_region32_subtract(&undamaged, &output->region,
output_damage);
gr->fan_debug = 0;
repaint_surfaces(output, &undamaged);
repaint_views(output, &undamaged);
gr->fan_debug = 1;
pixman_region32_fini(&undamaged);
}
@ -775,7 +778,7 @@ gl_renderer_repaint_output(struct weston_output *output,
pixman_region32_union(&total_damage, &buffer_damage, output_damage);
repaint_surfaces(output, &total_damage);
repaint_views(output, &total_damage);
pixman_region32_fini(&total_damage);
pixman_region32_fini(&buffer_damage);
@ -830,6 +833,8 @@ gl_renderer_flush_damage(struct weston_surface *surface)
struct gl_renderer *gr = get_renderer(surface->compositor);
struct gl_surface_state *gs = get_surface_state(surface);
struct weston_buffer *buffer = gs->buffer_ref.buffer;
struct weston_view *view;
int texture_used;
GLenum format;
int pixel_type;
@ -850,7 +855,14 @@ gl_renderer_flush_damage(struct weston_surface *surface)
* hold the reference to the buffer, in case the surface
* migrates back to the primary plane.
*/
if (surface->plane != &surface->compositor->primary_plane)
texture_used = 0;
wl_list_for_each(view, &surface->views, surface_link) {
if (view->plane == &surface->compositor->primary_plane) {
texture_used = 1;
break;
}
}
if (!texture_used)
return;
if (!pixman_region32_not_empty(&gs->texture_damage))

@ -96,18 +96,18 @@ static void
default_grab_focus(struct weston_pointer_grab *grab)
{
struct weston_pointer *pointer = grab->pointer;
struct weston_surface *surface;
struct weston_view *view;
wl_fixed_t sx, sy;
if (pointer->button_count > 0)
return;
surface = weston_compositor_pick_surface(pointer->seat->compositor,
view = weston_compositor_pick_view(pointer->seat->compositor,
pointer->x, pointer->y,
&sx, &sy);
if (pointer->focus != surface)
weston_pointer_set_focus(pointer, surface, sx, sy);
if (pointer->focus != view)
weston_pointer_set_focus(pointer, view, sx, sy);
}
static void
@ -120,7 +120,7 @@ default_grab_motion(struct weston_pointer_grab *grab, uint32_t time)
resource_list = &pointer->focus_resource_list;
wl_resource_for_each(resource, resource_list) {
weston_surface_from_global_fixed(pointer->focus,
weston_view_from_global_fixed(pointer->focus,
pointer->x, pointer->y,
&sx, &sy);
wl_pointer_send_motion(resource, time, sx, sy);
@ -133,7 +133,7 @@ default_grab_button(struct weston_pointer_grab *grab,
{
struct weston_pointer *pointer = grab->pointer;
struct weston_compositor *compositor = pointer->seat->compositor;
struct weston_surface *surface;
struct weston_view *view;
struct wl_resource *resource;
uint32_t serial;
enum wl_pointer_button_state state = state_w;
@ -154,12 +154,11 @@ default_grab_button(struct weston_pointer_grab *grab,
if (pointer->button_count == 0 &&
state == WL_POINTER_BUTTON_STATE_RELEASED) {
surface = weston_compositor_pick_surface(compositor,
pointer->x,
pointer->y,
view = weston_compositor_pick_view(compositor,
pointer->x, pointer->y,
&sx, &sy);
weston_pointer_set_focus(pointer, surface, sx, sy);
weston_pointer_set_focus(pointer, view, sx, sy);
}
}
@ -186,7 +185,7 @@ default_grab_touch_down(struct weston_touch_grab *grab, uint32_t time,
serial = wl_display_next_serial(display);
wl_resource_for_each(resource, resource_list)
wl_touch_send_down(resource, serial, time,
touch->focus->resource,
touch->focus->surface->resource,
touch_id, sx, sy);
}
}
@ -295,6 +294,15 @@ find_resource_for_surface(struct wl_list *list, struct weston_surface *surface)
return wl_resource_find_for_client(list, wl_resource_get_client(surface->resource));
}
static struct wl_resource *
find_resource_for_view(struct wl_list *list, struct weston_view *view)
{
if (!view)
return NULL;
return find_resource_for_surface(list, view->surface);
}
static void
default_grab_modifiers(struct weston_keyboard_grab *grab, uint32_t serial,
uint32_t mods_depressed, uint32_t mods_latched,
@ -311,9 +319,9 @@ default_grab_modifiers(struct weston_keyboard_grab *grab, uint32_t serial,
wl_keyboard_send_modifiers(resource, serial, mods_depressed,
mods_latched, mods_locked, group);
}
if (pointer && pointer->focus && pointer->focus != keyboard->focus) {
if (pointer && pointer->focus && pointer->focus->surface != keyboard->focus) {
struct wl_client *pointer_client =
wl_resource_get_client(pointer->focus->resource);
wl_resource_get_client(pointer->focus->surface->resource);
send_modifiers_to_client_in_list(pointer_client,
&keyboard->resource_list,
serial,
@ -330,12 +338,13 @@ static const struct weston_keyboard_grab_interface
static void
pointer_unmap_sprite(struct weston_pointer *pointer)
{
if (weston_surface_is_mapped(pointer->sprite))
weston_surface_unmap(pointer->sprite);
if (weston_surface_is_mapped(pointer->sprite->surface))
weston_surface_unmap(pointer->sprite->surface);
wl_list_remove(&pointer->sprite_destroy_listener.link);
pointer->sprite->configure = NULL;
pointer->sprite->configure_private = NULL;
pointer->sprite->surface->configure = NULL;
pointer->sprite->surface->configure_private = NULL;
weston_view_destroy(pointer->sprite);
pointer->sprite = NULL;
}
@ -461,7 +470,7 @@ seat_send_updated_caps(struct weston_seat *seat)
WL_EXPORT void
weston_pointer_set_focus(struct weston_pointer *pointer,
struct weston_surface *surface,
struct weston_view *view,
wl_fixed_t sx, wl_fixed_t sy)
{
struct weston_keyboard *kbd = pointer->seat->keyboard;
@ -469,27 +478,33 @@ weston_pointer_set_focus(struct weston_pointer *pointer,
struct wl_display *display = pointer->seat->compositor->wl_display;
uint32_t serial;
struct wl_list *focus_resource_list;
int different_surface = 0;
if ((!pointer->focus && view) ||
(pointer->focus && !view) ||
(pointer->focus && pointer->focus->surface != view->surface))
different_surface = 1;
focus_resource_list = &pointer->focus_resource_list;
if (!wl_list_empty(focus_resource_list) && pointer->focus != surface) {
if (!wl_list_empty(focus_resource_list) && different_surface) {
serial = wl_display_next_serial(display);
wl_resource_for_each(resource, focus_resource_list) {
wl_pointer_send_leave(resource, serial,
pointer->focus->resource);
pointer->focus->surface->resource);
}
move_resources(&pointer->resource_list, focus_resource_list);
}
if (find_resource_for_surface(&pointer->resource_list, surface) &&
pointer->focus != surface) {
if (find_resource_for_view(&pointer->resource_list, view) &&
different_surface) {
struct wl_client *surface_client =
wl_resource_get_client(surface->resource);
wl_resource_get_client(view->surface->resource);
serial = wl_display_next_serial(display);
if (kbd && kbd->focus != pointer->focus)
if (kbd && kbd->focus != view->surface)
send_modifiers_to_client_in_list(surface_client,
&kbd->resource_list,
serial,
@ -502,14 +517,14 @@ weston_pointer_set_focus(struct weston_pointer *pointer,
wl_resource_for_each(resource, focus_resource_list) {
wl_pointer_send_enter(resource,
serial,
surface->resource,
view->surface->resource,
sx, sy);
}
pointer->focus_serial = serial;
}
pointer->focus = surface;
pointer->focus = view;
wl_signal_emit(&pointer->focus_signal, pointer);
}
@ -676,13 +691,13 @@ move_pointer(struct weston_seat *seat, wl_fixed_t x, wl_fixed_t y)
if (output->zoom.active &&
pixman_region32_contains_point(&output->region,
ix, iy, NULL))
weston_output_update_zoom(output, ZOOM_FOCUS_POINTER);
weston_output_update_zoom(output);
if (pointer->sprite) {
weston_surface_set_position(pointer->sprite,
weston_view_set_position(pointer->sprite,
ix - pointer->hotspot_x,
iy - pointer->hotspot_y);
weston_surface_schedule_repaint(pointer->sprite);
weston_view_schedule_repaint(pointer->sprite);
}
}
@ -906,8 +921,7 @@ notify_key(struct weston_seat *seat, uint32_t time, uint32_t key,
{
struct weston_compositor *compositor = seat->compositor;
struct weston_keyboard *keyboard = seat->keyboard;
struct weston_surface *focus =
(struct weston_surface *) keyboard->focus;
struct weston_surface *focus = keyboard->focus;
struct weston_keyboard_grab *grab = keyboard->grab;
uint32_t serial = wl_display_next_serial(compositor->wl_display);
uint32_t *k, *end;
@ -1045,28 +1059,30 @@ notify_keyboard_focus_out(struct weston_seat *seat)
}
WL_EXPORT void
weston_touch_set_focus(struct weston_seat *seat, struct weston_surface *surface)
weston_touch_set_focus(struct weston_seat *seat, struct weston_view *view)
{
struct wl_list *focus_resource_list;
focus_resource_list = &seat->touch->focus_resource_list;
if (seat->touch->focus == surface)
if (seat->touch->focus->surface == view->surface) {
seat->touch->focus = view;
return;
}
if (!wl_list_empty(focus_resource_list)) {
move_resources(&seat->touch->resource_list,
focus_resource_list);
}
if (surface) {
if (view) {
struct wl_client *surface_client =
wl_resource_get_client(surface->resource);
wl_resource_get_client(view->surface->resource);
move_resources_for_client(focus_resource_list,
&seat->touch->resource_list,
surface_client);
}
seat->touch->focus = surface;
seat->touch->focus = view;
}
/**
@ -1084,7 +1100,7 @@ notify_touch(struct weston_seat *seat, uint32_t time, int touch_id,
struct weston_compositor *ec = seat->compositor;
struct weston_touch *touch = seat->touch;
struct weston_touch_grab *grab = touch->grab;
struct weston_surface *es;
struct weston_view *ev;
wl_fixed_t sx, sy;
/* Update grab's global coordinates. */
@ -1099,15 +1115,15 @@ notify_touch(struct weston_seat *seat, uint32_t time, int touch_id,
seat->num_tp++;
/* the first finger down picks the surface, and all further go
* to that surface for the remainder of the touch session i.e.
/* the first finger down picks the view, and all further go
* to that view for the remainder of the touch session i.e.
* until all touch points are up again. */
if (seat->num_tp == 1) {
es = weston_compositor_pick_surface(ec, x, y, &sx, &sy);
weston_touch_set_focus(seat, es);
ev = weston_compositor_pick_view(ec, x, y, &sx, &sy);
weston_touch_set_focus(seat, ev);
} else if (touch->focus) {
es = (struct weston_surface *) touch->focus;
weston_surface_from_global_fixed(es, x, y, &sx, &sy);
ev = touch->focus;
weston_view_from_global_fixed(ev, x, y, &sx, &sy);
} else {
/* Unexpected condition: We have non-initial touch but
* there is no focused surface.
@ -1129,11 +1145,11 @@ notify_touch(struct weston_seat *seat, uint32_t time, int touch_id,
break;
case WL_TOUCH_MOTION:
es = (struct weston_surface *) touch->focus;
if (!es)
ev = touch->focus;
if (!ev)
break;
weston_surface_from_global_fixed(es, x, y, &sx, &sy);
weston_view_from_global_fixed(ev, x, y, &sx, &sy);
grab->interface->motion(grab, time, touch_id, sx, sy);
break;
case WL_TOUCH_UP:
@ -1159,7 +1175,7 @@ pointer_cursor_surface_configure(struct weston_surface *es,
if (width == 0)
return;
assert(es == pointer->sprite);
assert(es == pointer->sprite->surface);
pointer->hotspot_x -= dx;
pointer->hotspot_y -= dy;
@ -1167,14 +1183,14 @@ pointer_cursor_surface_configure(struct weston_surface *es,
x = wl_fixed_to_int(pointer->x) - pointer->hotspot_x;
y = wl_fixed_to_int(pointer->y) - pointer->hotspot_y;
weston_surface_configure(pointer->sprite, x, y, width, height);
weston_view_configure(pointer->sprite, x, y, width, height);
empty_region(&es->pending.input);
if (!weston_surface_is_mapped(es)) {
wl_list_insert(&es->compositor->cursor_layer.surface_list,
&es->layer_link);
weston_surface_update_transform(es);
wl_list_insert(&es->compositor->cursor_layer.view_list,
&pointer->sprite->layer_link);
weston_view_update_transform(pointer->sprite);
}
}
@ -1191,17 +1207,17 @@ pointer_set_cursor(struct wl_client *client, struct wl_resource *resource,
if (pointer->focus == NULL)
return;
/* pointer->focus->resource can be NULL. Surfaces like the
/* pointer->focus->surface->resource can be NULL. Surfaces like the
black_surface used in shell.c for fullscreen don't have
a resource, but can still have focus */
if (pointer->focus->resource == NULL)
if (pointer->focus->surface->resource == NULL)
return;
if (wl_resource_get_client(pointer->focus->resource) != client)
if (wl_resource_get_client(pointer->focus->surface->resource) != client)
return;
if (pointer->focus_serial - serial > UINT32_MAX / 2)
return;
if (surface && surface != pointer->sprite) {
if (surface && pointer->sprite && surface != pointer->sprite->surface) {
if (surface->configure) {
wl_resource_post_error(surface->resource,
WL_DISPLAY_ERROR_INVALID_OBJECT,
@ -1222,7 +1238,7 @@ pointer_set_cursor(struct wl_client *client, struct wl_resource *resource,
surface->configure = pointer_cursor_surface_configure;
surface->configure_private = pointer;
pointer->sprite = surface;
pointer->sprite = weston_view_create(surface);
pointer->hotspot_x = x;
pointer->hotspot_y = y;
@ -1266,24 +1282,21 @@ seat_get_pointer(struct wl_client *client, struct wl_resource *resource,
wl_resource_set_implementation(cr, &pointer_interface, seat->pointer,
unbind_resource);
if (seat->pointer->focus && seat->pointer->focus->resource &&
wl_resource_get_client(seat->pointer->focus->resource) == client) {
struct weston_surface *surface;
if (seat->pointer->focus && seat->pointer->focus->surface->resource &&
wl_resource_get_client(seat->pointer->focus->surface->resource) == client) {
wl_fixed_t sx, sy;
surface = (struct weston_surface *) seat->pointer->focus;
weston_surface_from_global_fixed(surface,
weston_view_from_global_fixed(seat->pointer->focus,
seat->pointer->x,
seat->pointer->y,
&sx,
&sy);
&sx, &sy);
wl_list_remove(wl_resource_get_link(cr));
wl_list_insert(&seat->pointer->focus_resource_list,
wl_resource_get_link(cr));
wl_pointer_send_enter(cr,
seat->pointer->focus_serial,
surface->resource,
seat->pointer->focus->surface->resource,
sx, sy);
}
}
@ -1309,7 +1322,7 @@ should_send_modifiers_to_client(struct weston_seat *seat,
if (seat->pointer &&
seat->pointer->focus &&
wl_resource_get_client(seat->pointer->focus->resource) == client)
wl_resource_get_client(seat->pointer->focus->surface->resource) == client)
return 1;
return 0;
@ -1406,7 +1419,7 @@ seat_get_touch(struct wl_client *client, struct wl_resource *resource,
}
if (seat->touch->focus &&
wl_resource_get_client(seat->touch->focus->resource) == client) {
wl_resource_get_client(seat->touch->focus->surface->resource) == client) {
wl_list_insert(&seat->touch->resource_list,
wl_resource_get_link(cr));
} else {

@ -223,16 +223,16 @@ region_global_to_output(struct weston_output *output, pixman_region32_t *region)
#define D2F(v) pixman_double_to_fixed((double)v)
static void
repaint_region(struct weston_surface *es, struct weston_output *output,
repaint_region(struct weston_view *ev, struct weston_output *output,
pixman_region32_t *region, pixman_region32_t *surf_region,
pixman_op_t pixman_op)
{
struct pixman_renderer *pr =
(struct pixman_renderer *) output->compositor->renderer;
struct pixman_surface_state *ps = get_surface_state(es);
struct pixman_surface_state *ps = get_surface_state(ev->surface);
struct pixman_output_state *po = get_output_state(output);
pixman_region32_t final_region;
float surface_x, surface_y;
float view_x, view_y;
pixman_transform_t transform;
pixman_fixed_t fw, fh;
@ -246,11 +246,11 @@ repaint_region(struct weston_surface *es, struct weston_output *output,
pixman_region32_copy(&final_region, surf_region);
/* Convert from surface to global coordinates */
if (!es->transform.enabled) {
pixman_region32_translate(&final_region, es->geometry.x, es->geometry.y);
if (!ev->transform.enabled) {
pixman_region32_translate(&final_region, ev->geometry.x, ev->geometry.y);
} else {
weston_surface_to_global_float(es, 0, 0, &surface_x, &surface_y);
pixman_region32_translate(&final_region, (int)surface_x, (int)surface_y);
weston_view_to_global_float(ev, 0, 0, &view_x, &view_y);
pixman_region32_translate(&final_region, (int)view_x, (int)view_y);
}
/* We need to paint the intersection */
@ -314,22 +314,22 @@ repaint_region(struct weston_surface *es, struct weston_output *output,
pixman_double_to_fixed (output->x),
pixman_double_to_fixed (output->y));
if (es->transform.enabled) {
if (ev->transform.enabled) {
/* Pixman supports only 2D transform matrix, but Weston uses 3D,
* so we're omitting Z coordinate here
*/
pixman_transform_t surface_transform = {{
{ D2F(es->transform.matrix.d[0]),
D2F(es->transform.matrix.d[4]),
D2F(es->transform.matrix.d[12]),
{ D2F(ev->transform.matrix.d[0]),
D2F(ev->transform.matrix.d[4]),
D2F(ev->transform.matrix.d[12]),
},
{ D2F(es->transform.matrix.d[1]),
D2F(es->transform.matrix.d[5]),
D2F(es->transform.matrix.d[13]),
{ D2F(ev->transform.matrix.d[1]),
D2F(ev->transform.matrix.d[5]),
D2F(ev->transform.matrix.d[13]),
},
{ D2F(es->transform.matrix.d[3]),
D2F(es->transform.matrix.d[7]),
D2F(es->transform.matrix.d[15]),
{ D2F(ev->transform.matrix.d[3]),
D2F(ev->transform.matrix.d[7]),
D2F(ev->transform.matrix.d[15]),
}
}};
@ -337,15 +337,15 @@ repaint_region(struct weston_surface *es, struct weston_output *output,
pixman_transform_multiply (&transform, &surface_transform, &transform);
} else {
pixman_transform_translate(&transform, NULL,
pixman_double_to_fixed ((double)-es->geometry.x),
pixman_double_to_fixed ((double)-es->geometry.y));
pixman_double_to_fixed ((double)-ev->geometry.x),
pixman_double_to_fixed ((double)-ev->geometry.y));
}
fw = pixman_int_to_fixed(es->geometry.width);
fh = pixman_int_to_fixed(es->geometry.height);
fw = pixman_int_to_fixed(ev->geometry.width);
fh = pixman_int_to_fixed(ev->geometry.height);
switch (es->buffer_transform) {
switch (ev->surface->buffer_transform) {
case WL_OUTPUT_TRANSFORM_FLIPPED:
case WL_OUTPUT_TRANSFORM_FLIPPED_90:
case WL_OUTPUT_TRANSFORM_FLIPPED_180:
@ -357,7 +357,7 @@ repaint_region(struct weston_surface *es, struct weston_output *output,
break;
}
switch (es->buffer_transform) {
switch (ev->surface->buffer_transform) {
default:
case WL_OUTPUT_TRANSFORM_NORMAL:
case WL_OUTPUT_TRANSFORM_FLIPPED:
@ -380,12 +380,12 @@ repaint_region(struct weston_surface *es, struct weston_output *output,
}
pixman_transform_scale(&transform, NULL,
pixman_double_to_fixed ((double)es->buffer_scale),
pixman_double_to_fixed ((double)es->buffer_scale));
pixman_double_to_fixed ((double)ev->surface->buffer_scale),
pixman_double_to_fixed ((double)ev->surface->buffer_scale));
pixman_image_set_transform(ps->image, &transform);
if (es->transform.enabled || output->current_scale != es->buffer_scale)
if (ev->transform.enabled || output->current_scale != ev->surface->buffer_scale)
pixman_image_set_filter(ps->image, PIXMAN_FILTER_BILINEAR, NULL, 0);
else
pixman_image_set_filter(ps->image, PIXMAN_FILTER_NEAREST, NULL, 0);
@ -417,10 +417,10 @@ repaint_region(struct weston_surface *es, struct weston_output *output,
}
static void
draw_surface(struct weston_surface *es, struct weston_output *output,
draw_view(struct weston_view *ev, struct weston_output *output,
pixman_region32_t *damage) /* in global coordinates */
{
struct pixman_surface_state *ps = get_surface_state(es);
struct pixman_surface_state *ps = get_surface_state(ev->surface);
/* repaint bounding region in global coordinates: */
pixman_region32_t repaint;
/* non-opaque region in surface coordinates: */
@ -432,8 +432,8 @@ draw_surface(struct weston_surface *es, struct weston_output *output,
pixman_region32_init(&repaint);
pixman_region32_intersect(&repaint,
&es->transform.boundingbox, damage);
pixman_region32_subtract(&repaint, &repaint, &es->clip);
&ev->transform.boundingbox, damage);
pixman_region32_subtract(&repaint, &repaint, &ev->clip);
if (!pixman_region32_not_empty(&repaint))
goto out;
@ -444,21 +444,21 @@ draw_surface(struct weston_surface *es, struct weston_output *output,
}
/* TODO: Implement repaint_region_complex() using pixman_composite_trapezoids() */
if (es->transform.enabled &&
es->transform.matrix.type != WESTON_MATRIX_TRANSFORM_TRANSLATE) {
repaint_region(es, output, &repaint, NULL, PIXMAN_OP_OVER);
if (ev->transform.enabled &&
ev->transform.matrix.type != WESTON_MATRIX_TRANSFORM_TRANSLATE) {
repaint_region(ev, output, &repaint, NULL, PIXMAN_OP_OVER);
} else {
/* blended region is whole surface minus opaque region: */
pixman_region32_init_rect(&surface_blend, 0, 0,
es->geometry.width, es->geometry.height);
pixman_region32_subtract(&surface_blend, &surface_blend, &es->opaque);
ev->geometry.width, ev->geometry.height);
pixman_region32_subtract(&surface_blend, &surface_blend, &ev->surface->opaque);
if (pixman_region32_not_empty(&es->opaque)) {
repaint_region(es, output, &repaint, &es->opaque, PIXMAN_OP_SRC);
if (pixman_region32_not_empty(&ev->surface->opaque)) {
repaint_region(ev, output, &repaint, &ev->surface->opaque, PIXMAN_OP_SRC);
}
if (pixman_region32_not_empty(&surface_blend)) {
repaint_region(es, output, &repaint, &surface_blend, PIXMAN_OP_OVER);
repaint_region(ev, output, &repaint, &surface_blend, PIXMAN_OP_OVER);
}
pixman_region32_fini(&surface_blend);
}
@ -471,11 +471,11 @@ static void
repaint_surfaces(struct weston_output *output, pixman_region32_t *damage)
{
struct weston_compositor *compositor = output->compositor;
struct weston_surface *surface;
struct weston_view *view;
wl_list_for_each_reverse(surface, &compositor->surface_list, link)
if (surface->plane == &compositor->primary_plane)
draw_surface(surface, output, damage);
wl_list_for_each_reverse(view, &compositor->view_list, link)
if (view->plane == &compositor->primary_plane)
draw_view(view, output, damage);
}
static void

@ -104,13 +104,8 @@ enum buffer_type {
struct rpir_surface {
struct weston_surface *surface;
/* If link is empty, the surface is guaranteed to not be on screen,
* i.e. updates removing Elements have completed.
*/
struct wl_list link;
DISPMANX_ELEMENT_HANDLE_T handle;
int layer;
struct wl_list views;
int visible_views;
int need_swap;
int single_buffer;
@ -127,6 +122,20 @@ struct rpir_surface {
enum buffer_type buffer_type;
};
struct rpir_view {
struct rpir_surface *surface;
struct wl_list surface_link;
struct weston_view *view;
/* If link is empty, the view is guaranteed to not be on screen,
* i.e. updates removing Elements have completed.
*/
struct wl_list link;
DISPMANX_ELEMENT_HANDLE_T handle;
int layer;
};
struct rpir_output {
DISPMANX_DISPLAY_HANDLE_T display;
@ -134,10 +143,10 @@ struct rpir_output {
struct weston_matrix matrix;
/* all Elements currently on screen */
struct wl_list surface_list; /* struct rpir_surface::link */
struct wl_list view_list; /* struct rpir_surface::link */
/* Elements just removed, waiting for update completion */
struct wl_list surface_cleanup_list; /* struct rpir_surface::link */
struct wl_list view_cleanup_list; /* struct rpir_surface::link */
struct rpi_resource capture_buffer;
uint8_t *capture_data;
@ -164,6 +173,12 @@ to_rpir_surface(struct weston_surface *surface)
return surface->renderer_state;
}
static inline struct rpir_view *
to_rpir_view(struct weston_view *view)
{
return view->renderer_state;
}
static inline struct rpir_output *
to_rpir_output(struct weston_output *output)
{
@ -356,9 +371,8 @@ rpir_surface_create(struct rpi_renderer *renderer)
if (!surface)
return NULL;
wl_list_init(&surface->link);
surface->visible_views = 0;
surface->single_buffer = renderer->single_buffer;
surface->handle = DISPMANX_NO_HANDLE;
rpi_resource_init(&surface->resources[0]);
rpi_resource_init(&surface->resources[1]);
surface->front = &surface->resources[0];
@ -376,15 +390,18 @@ rpir_surface_create(struct rpi_renderer *renderer)
static void
rpir_surface_destroy(struct rpir_surface *surface)
{
wl_list_remove(&surface->link);
if (surface->handle != DISPMANX_NO_HANDLE)
if (surface->visible_views)
weston_log("ERROR rpi: destroying on-screen element\n");
assert(wl_list_empty(&surface->views));
if (surface->surface)
surface->surface->renderer_state = NULL;
pixman_region32_fini(&surface->prev_damage);
rpi_resource_release(&surface->resources[0]);
rpi_resource_release(&surface->resources[1]);
DBG("rpir_surface %p destroyed (%u)\n", surface, surface->handle);
DBG("rpir_surface %p destroyed (%u)\n", surface, surface->visible_views);
if (surface->egl_back != NULL) {
weston_buffer_reference(&surface->egl_back->buffer_ref, NULL);
@ -436,6 +453,46 @@ rpir_surface_damage(struct rpir_surface *surface, struct weston_buffer *buffer,
return ret;
}
static struct rpir_view *
rpir_view_create(struct rpir_surface *surface)
{
struct rpir_view *view;
view = calloc(1, sizeof *view);
if (!view)
return NULL;
view->surface = surface;
wl_list_insert(&surface->views, &view->surface_link);
wl_list_init(&view->link);
view->handle = DISPMANX_NO_HANDLE;
return view;
}
static void
rpir_view_destroy(struct rpir_view *view)
{
wl_list_remove(&view->link);
if (view->handle != DISPMANX_NO_HANDLE) {
view->surface->visible_views--;
weston_log("ERROR rpi: destroying on-screen element\n");
}
if (view->view)
view->view->renderer_state = NULL;
wl_list_remove(&view->surface_link);
if (wl_list_empty(&view->surface->views) && view->surface->surface == NULL)
rpir_surface_destroy(view->surface);
DBG("rpir_view %p destroyed (%d)\n", view, view->handle);
free(view);
}
static void
matrix_type_str(struct weston_matrix *matrix, char *buf, int len)
{
@ -495,13 +552,13 @@ warn_bad_matrix(struct weston_matrix *total, struct weston_matrix *output,
/*#define SURFACE_TRANSFORM */
static int
rpir_surface_compute_rects(struct rpir_surface *surface,
rpir_view_compute_rects(struct rpir_view *view,
VC_RECT_T *src_rect, VC_RECT_T *dst_rect,
VC_IMAGE_TRANSFORM_T *flipmask)
{
struct weston_output *output_base = surface->surface->output;
struct weston_output *output_base = view->view->surface->output;
struct rpir_output *output = to_rpir_output(output_base);
struct weston_matrix matrix = surface->surface->transform.matrix;
struct weston_matrix matrix = view->view->transform.matrix;
VC_IMAGE_TRANSFORM_T flipt = 0;
int src_x, src_y;
int dst_x, dst_y;
@ -523,14 +580,15 @@ rpir_surface_compute_rects(struct rpir_surface *surface,
src_x = 0 << 16;
src_y = 0 << 16;
if (surface->buffer_type == BUFFER_TYPE_EGL) {
struct weston_buffer *buffer = surface->egl_front->buffer_ref.buffer;
if (view->surface->buffer_type == BUFFER_TYPE_EGL) {
struct weston_buffer *buffer =
view->surface->egl_front->buffer_ref.buffer;
src_width = buffer->width << 16;
src_height = buffer->height << 16;
} else {
src_width = surface->front->width << 16;
src_height = surface->front->height << 16;
src_width = view->surface->front->width << 16;
src_height = view->surface->front->height << 16;
}
weston_matrix_multiply(&matrix, &output->matrix);
@ -541,7 +599,7 @@ rpir_surface_compute_rects(struct rpir_surface *surface,
if (matrix.type >= WESTON_MATRIX_TRANSFORM_ROTATE) {
#endif
warn_bad_matrix(&matrix, &output->matrix,
&surface->surface->transform.matrix);
&view->view->transform.matrix);
} else {
if (matrix.type & WESTON_MATRIX_TRANSFORM_ROTATE) {
if (fabsf(matrix.d[0]) < 1e-4f &&
@ -552,13 +610,13 @@ rpir_surface_compute_rects(struct rpir_surface *surface,
/* no transpose */
} else {
warn_bad_matrix(&matrix, &output->matrix,
&surface->surface->transform.matrix);
&view->view->transform.matrix);
}
}
}
p2.f[0] = surface->surface->geometry.width;
p2.f[1] = surface->surface->geometry.height;
p2.f[0] = view->view->geometry.width;
p2.f[1] = view->view->geometry.height;
/* transform top-left and bot-right corner into screen coordinates */
weston_matrix_transform(&matrix, &p1);
@ -680,9 +738,9 @@ rpir_surface_compute_rects(struct rpir_surface *surface,
src_width = int_max(src_width, 0);
src_height = int_max(src_height, 0);
DBG("rpir_surface %p %dx%d: p1 %f, %f; p2 %f, %f\n", surface,
surface->surface->geometry.width,
surface->surface->geometry.height,
DBG("rpir_view %p %dx%d: p1 %f, %f; p2 %f, %f\n", view,
view->view->geometry.width,
view->view->geometry.height,
p1.f[0], p1.f[1], p2.f[0], p2.f[1]);
DBG("src rect %d;%d, %d;%d, %d;%dx%d;%d\n",
src_x >> 16, src_x & 0xffff,
@ -706,7 +764,7 @@ rpir_surface_compute_rects(struct rpir_surface *surface,
}
/* EGL buffers will be upside-down related to what DispmanX expects */
if (surface->buffer_type == BUFFER_TYPE_EGL)
if (view->surface->buffer_type == BUFFER_TYPE_EGL)
flipt ^= TRANSFORM_VFLIP;
vc_dispmanx_rect_set(src_rect, src_x, src_y, src_width, src_height);
@ -760,7 +818,7 @@ rpir_surface_get_resource(struct rpir_surface *surface)
}
static int
rpir_surface_dmx_add(struct rpir_surface *surface, struct rpir_output *output,
rpir_view_dmx_add(struct rpir_view *view, struct rpir_output *output,
DISPMANX_UPDATE_HANDLE_T update, int layer)
{
/* Do not use DISPMANX_FLAGS_ALPHA_PREMULT here.
@ -771,7 +829,7 @@ rpir_surface_dmx_add(struct rpir_surface *surface, struct rpir_output *output,
VC_DISPMANX_ALPHA_T alphasetup = {
DISPMANX_FLAGS_ALPHA_FROM_SOURCE |
DISPMANX_FLAGS_ALPHA_MIX,
float2uint8(surface->surface->alpha), /* opacity 0-255 */
float2uint8(view->view->alpha), /* opacity 0-255 */
0 /* mask resource handle */
};
VC_RECT_T dst_rect;
@ -780,18 +838,17 @@ rpir_surface_dmx_add(struct rpir_surface *surface, struct rpir_output *output,
int ret;
DISPMANX_RESOURCE_HANDLE_T resource_handle;
resource_handle = rpir_surface_get_resource(surface);
resource_handle = rpir_surface_get_resource(view->surface);
if (resource_handle == DISPMANX_NO_HANDLE) {
weston_log("%s: no buffer yet, aborting\n", __func__);
return 0;
}
ret = rpir_surface_compute_rects(surface, &src_rect, &dst_rect,
&flipmask);
ret = rpir_view_compute_rects(view, &src_rect, &dst_rect, &flipmask);
if (ret < 0)
return 0;
surface->handle = vc_dispmanx_element_add(
view->handle = vc_dispmanx_element_add(
update,
output->display,
layer,
@ -802,37 +859,42 @@ rpir_surface_dmx_add(struct rpir_surface *surface, struct rpir_output *output,
&alphasetup,
NULL /* clamp */,
vc_image2dispmanx_transform(flipmask));
DBG("rpir_surface %p add %u, alpha %f resource %d\n", surface,
surface->handle, surface->surface->alpha, resource_handle);
DBG("rpir_surface %p add %u, alpha %f resource %d\n", view,
view->handle, view->view->alpha, resource_handle);
if (view->handle == DISPMANX_NO_HANDLE)
return -1;
view->surface->visible_views++;
return 1;
}
static void
rpir_surface_dmx_swap(struct rpir_surface *surface,
rpir_view_dmx_swap(struct rpir_view *view,
DISPMANX_UPDATE_HANDLE_T update)
{
VC_RECT_T rect;
pixman_box32_t *r;
/* XXX: skip, iff resource was not reallocated, and single-buffering */
vc_dispmanx_element_change_source(update, surface->handle,
surface->front->handle);
vc_dispmanx_element_change_source(update, view->handle,
view->surface->front->handle);
/* This is current damage now, after rpir_surface_damage() */
r = pixman_region32_extents(&surface->prev_damage);
r = pixman_region32_extents(&view->surface->prev_damage);
vc_dispmanx_rect_set(&rect, r->x1, r->y1,
r->x2 - r->x1, r->y2 - r->y1);
vc_dispmanx_element_modified(update, surface->handle, &rect);
DBG("rpir_surface %p swap\n", surface);
vc_dispmanx_element_modified(update, view->handle, &rect);
DBG("rpir_view %p swap\n", view);
}
static int
rpir_surface_dmx_move(struct rpir_surface *surface,
rpir_view_dmx_move(struct rpir_view *view,
DISPMANX_UPDATE_HANDLE_T update, int layer)
{
uint8_t alpha = float2uint8(surface->surface->alpha);
uint8_t alpha = float2uint8(view->view->alpha);
VC_RECT_T dst_rect;
VC_RECT_T src_rect;
VC_IMAGE_TRANSFORM_T flipmask;
@ -840,28 +902,27 @@ rpir_surface_dmx_move(struct rpir_surface *surface,
/* XXX: return early, if all attributes stay the same */
if (surface->buffer_type == BUFFER_TYPE_EGL) {
if (view->surface->buffer_type == BUFFER_TYPE_EGL) {
DISPMANX_RESOURCE_HANDLE_T resource_handle;
resource_handle = rpir_surface_get_resource(surface);
resource_handle = rpir_surface_get_resource(view->surface);
if (resource_handle == DISPMANX_NO_HANDLE) {
weston_log("%s: no buffer yet, aborting\n", __func__);
return 0;
}
vc_dispmanx_element_change_source(update,
surface->handle,
view->handle,
resource_handle);
}
ret = rpir_surface_compute_rects(surface, &src_rect, &dst_rect,
&flipmask);
ret = rpir_view_compute_rects(view, &src_rect, &dst_rect, &flipmask);
if (ret < 0)
return 0;
ret = vc_dispmanx_element_change_attributes(
update,
surface->handle,
view->handle,
ELEMENT_CHANGE_LAYER |
ELEMENT_CHANGE_OPACITY |
ELEMENT_CHANGE_TRANSFORM |
@ -875,7 +936,7 @@ rpir_surface_dmx_move(struct rpir_surface *surface,
/* This really is DISPMANX_TRANSFORM_T, no matter
* what the header says. */
vc_image2dispmanx_transform(flipmask));
DBG("rpir_surface %p move\n", surface);
DBG("rpir_view %p move\n", view);
if (ret)
return -1;
@ -884,15 +945,16 @@ rpir_surface_dmx_move(struct rpir_surface *surface,
}
static void
rpir_surface_dmx_remove(struct rpir_surface *surface,
rpir_view_dmx_remove(struct rpir_view *view,
DISPMANX_UPDATE_HANDLE_T update)
{
if (surface->handle == DISPMANX_NO_HANDLE)
if (view->handle == DISPMANX_NO_HANDLE)
return;
vc_dispmanx_element_remove(update, surface->handle);
DBG("rpir_surface %p remove %u\n", surface, surface->handle);
surface->handle = DISPMANX_NO_HANDLE;
vc_dispmanx_element_remove(update, view->handle);
DBG("rpir_view %p remove %u\n", view, view->handle);
view->handle = DISPMANX_NO_HANDLE;
view->surface->visible_views--;
}
static void
@ -900,23 +962,31 @@ rpir_surface_swap_pointers(struct rpir_surface *surface)
{
struct rpi_resource *tmp;
if (surface->buffer_type == BUFFER_TYPE_EGL) {
if (surface->egl_back != NULL) {
assert(surface->egl_old_front == NULL);
surface->egl_old_front = surface->egl_front;
surface->egl_front = surface->egl_back;
surface->egl_back = NULL;
}
} else {
tmp = surface->front;
surface->front = surface->back;
surface->back = tmp;
surface->need_swap = 0;
}
DBG("new back %p, new front %p\n", surface->back, surface->front);
}
static int
is_surface_not_visible(struct weston_surface *surface)
is_view_not_visible(struct weston_view *view)
{
/* Return true, if surface is guaranteed to be totally obscured. */
int ret;
pixman_region32_t unocc;
pixman_region32_init(&unocc);
pixman_region32_subtract(&unocc, &surface->transform.boundingbox,
&surface->clip);
pixman_region32_subtract(&unocc, &view->transform.boundingbox,
&view->clip);
ret = !pixman_region32_not_empty(&unocc);
pixman_region32_fini(&unocc);
@ -924,81 +994,55 @@ is_surface_not_visible(struct weston_surface *surface)
}
static void
rpir_surface_update(struct rpir_surface *surface, struct rpir_output *output,
rpir_view_update(struct rpir_view *view, struct rpir_output *output,
DISPMANX_UPDATE_HANDLE_T update, int layer)
{
int need_swap = surface->need_swap;
int ret;
int obscured;
if (surface->buffer_type == BUFFER_TYPE_EGL) {
if (surface->egl_back != NULL) {
assert(surface->egl_old_front == NULL);
surface->egl_old_front = surface->egl_front;
surface->egl_front = surface->egl_back;
surface->egl_back = NULL;
}
if (surface->egl_front->buffer_ref.buffer == NULL) {
weston_log("warning: client unreffed current front buffer\n");
wl_list_remove(&surface->link);
if (surface->handle == DISPMANX_NO_HANDLE) {
wl_list_init(&surface->link);
} else {
rpir_surface_dmx_remove(surface, update);
wl_list_insert(&output->surface_cleanup_list,
&surface->link);
}
goto out;
}
} else {
if (need_swap)
rpir_surface_swap_pointers(surface);
}
obscured = is_surface_not_visible(surface->surface);
obscured = is_view_not_visible(view->view);
if (obscured) {
DBG("rpir_surface %p totally obscured.\n", surface);
DBG("rpir_view %p totally obscured.\n", view);
wl_list_remove(&surface->link);
if (surface->handle == DISPMANX_NO_HANDLE) {
wl_list_init(&surface->link);
wl_list_remove(&view->link);
if (view->handle == DISPMANX_NO_HANDLE) {
wl_list_init(&view->link);
} else {
rpir_surface_dmx_remove(surface, update);
wl_list_insert(&output->surface_cleanup_list,
&surface->link);
rpir_view_dmx_remove(view, update);
wl_list_insert(&output->view_cleanup_list,
&view->link);
}
goto out;
}
if (surface->handle == DISPMANX_NO_HANDLE) {
ret = rpir_surface_dmx_add(surface, output, update, layer);
if (view->handle == DISPMANX_NO_HANDLE) {
ret = rpir_view_dmx_add(view, output, update, layer);
if (ret == 0) {
wl_list_remove(&surface->link);
wl_list_init(&surface->link);
wl_list_remove(&view->link);
wl_list_init(&view->link);
} else if (ret < 0) {
weston_log("ERROR rpir_surface_dmx_add() failed.\n");
weston_log("ERROR rpir_view_dmx_add() failed.\n");
}
} else {
if (need_swap)
rpir_surface_dmx_swap(surface, update);
if (view->surface->need_swap)
rpir_view_dmx_swap(view, update);
ret = rpir_surface_dmx_move(surface, update, layer);
ret = rpir_view_dmx_move(view, update, layer);
if (ret == 0) {
rpir_surface_dmx_remove(surface, update);
rpir_view_dmx_remove(view, update);
wl_list_remove(&surface->link);
wl_list_insert(&output->surface_cleanup_list,
&surface->link);
wl_list_remove(&view->link);
wl_list_insert(&output->view_cleanup_list,
&view->link);
} else if (ret < 0) {
weston_log("ERROR rpir_surface_dmx_move() failed.\n");
weston_log("ERROR rpir_view_dmx_move() failed.\n");
}
}
out:
surface->layer = layer;
view->layer = layer;
}
static int
@ -1105,15 +1149,15 @@ static void
rpir_output_dmx_remove_all(struct rpir_output *output,
DISPMANX_UPDATE_HANDLE_T update)
{
struct rpir_surface *surface;
struct rpir_view *view;
while (!wl_list_empty(&output->surface_list)) {
surface = container_of(output->surface_list.next,
struct rpir_surface, link);
rpir_surface_dmx_remove(surface, update);
while (!wl_list_empty(&output->view_list)) {
view = container_of(output->view_list.next,
struct rpir_view, link);
rpir_view_dmx_remove(view, update);
wl_list_remove(&surface->link);
wl_list_insert(&output->surface_cleanup_list, &surface->link);
wl_list_remove(&view->link);
wl_list_insert(&output->view_cleanup_list, &view->link);
}
}
@ -1186,8 +1230,8 @@ rpi_renderer_repaint_output(struct weston_output *base,
{
struct weston_compositor *compositor = base->compositor;
struct rpir_output *output = to_rpir_output(base);
struct weston_surface *ws;
struct rpir_surface *surface;
struct weston_view *wv;
struct rpir_view *view;
struct wl_list done_list;
int layer = 1;
@ -1199,27 +1243,59 @@ rpi_renderer_repaint_output(struct weston_output *base,
free(output->capture_data);
output->capture_data = NULL;
/* Swap resources on surfaces as needed */
wl_list_for_each_reverse(wv, &compositor->view_list, link)
wv->surface->touched = 0;
wl_list_for_each_reverse(wv, &compositor->view_list, link) {
view = to_rpir_view(wv);
if (!wv->surface->touched) {
wv->surface->touched = 1;
if (view->surface->need_swap)
rpir_surface_swap_pointers(view->surface);
}
if (view->surface->egl_front->buffer_ref.buffer == NULL) {
weston_log("warning: client unreffed current front buffer\n");
wl_list_remove(&view->link);
if (view->handle == DISPMANX_NO_HANDLE) {
wl_list_init(&view->link);
} else {
rpir_view_dmx_remove(view, output->update);
wl_list_insert(&output->view_cleanup_list,
&view->link);
}
}
}
/* update all renderable surfaces */
wl_list_init(&done_list);
wl_list_for_each_reverse(ws, &compositor->surface_list, link) {
if (ws->plane != &compositor->primary_plane)
wl_list_for_each_reverse(wv, &compositor->view_list, link) {
if (wv->plane != &compositor->primary_plane)
continue;
surface = to_rpir_surface(ws);
assert(!wl_list_empty(&surface->link) ||
surface->handle == DISPMANX_NO_HANDLE);
view = to_rpir_view(wv);
assert(!wl_list_empty(&view->link) ||
view->handle == DISPMANX_NO_HANDLE);
wl_list_remove(&surface->link);
wl_list_insert(&done_list, &surface->link);
rpir_surface_update(surface, output, output->update, layer++);
wl_list_remove(&view->link);
wl_list_insert(&done_list, &view->link);
rpir_view_update(view, output, output->update, layer++);
}
/* Mark all surfaces as swapped */
wl_list_for_each_reverse(wv, &compositor->view_list, link)
to_rpir_surface(wv->surface)->need_swap = 0;
/* Remove all surfaces that are still on screen, but were
* not rendered this time.
*/
rpir_output_dmx_remove_all(output, output->update);
wl_list_insert_list(&output->surface_list, &done_list);
wl_list_insert_list(&output->view_list, &done_list);
output->update = DISPMANX_NO_HANDLE;
/* The frame_signal is emitted in rpi_renderer_finish_frame(),
@ -1263,7 +1339,7 @@ rpi_renderer_attach(struct weston_surface *base, struct weston_buffer *buffer)
/* XXX: need to check if in middle of update */
rpi_resource_release(surface->back);
if (surface->handle == DISPMANX_NO_HANDLE)
if (!surface->visible_views)
/* XXX: cannot do this, if middle of an update */
rpi_resource_release(surface->front);
@ -1336,6 +1412,23 @@ rpi_renderer_create_surface(struct weston_surface *base)
return 0;
}
static int
rpi_renderer_create_view(struct weston_view *base)
{
struct rpir_surface *surface = to_rpir_surface(base->surface);
struct rpir_view *view;
assert(base->renderer_state == NULL);
view = rpir_view_create(surface);
if (!view)
return -1;
view->view = base;
base->renderer_state = view;
return 0;
}
static void
rpi_renderer_surface_set_color(struct weston_surface *base,
float red, float green, float blue, float alpha)
@ -1390,13 +1483,27 @@ rpi_renderer_destroy_surface(struct weston_surface *base)
surface->surface = NULL;
base->renderer_state = NULL;
/* If guaranteed to not be on screen, just detroy it. */
if (wl_list_empty(&surface->link))
if (wl_list_empty(&surface->views))
rpir_surface_destroy(surface);
}
/* Otherwise, the surface is either on screen and needs
static void
rpi_renderer_destroy_view(struct weston_view *base)
{
struct rpir_view *view = to_rpir_view(base);
assert(view);
assert(view->view == base);
if (!view)
return;
/* If guaranteed to not be on screen, just detroy it. */
if (wl_list_empty(&view->link))
rpir_view_destroy(view);
/* Otherwise, the view is either on screen and needs
* to be removed by a repaint update, or it is in the
* surface_cleanup_list, and will be destroyed by
* view_cleanup_list, and will be destroyed by
* rpi_renderer_finish_frame().
*/
}
@ -1440,8 +1547,10 @@ rpi_renderer_create(struct weston_compositor *compositor,
renderer->base.flush_damage = rpi_renderer_flush_damage;
renderer->base.attach = rpi_renderer_attach;
renderer->base.create_surface = rpi_renderer_create_surface;
renderer->base.create_view = rpi_renderer_create_view;
renderer->base.surface_set_color = rpi_renderer_surface_set_color;
renderer->base.destroy_surface = rpi_renderer_destroy_surface;
renderer->base.destroy_view = rpi_renderer_destroy_view;
renderer->base.destroy = rpi_renderer_destroy;
#ifdef ENABLE_EGL
@ -1504,8 +1613,8 @@ rpi_renderer_output_create(struct weston_output *base,
output->display = display;
output->update = DISPMANX_NO_HANDLE;
wl_list_init(&output->surface_list);
wl_list_init(&output->surface_cleanup_list);
wl_list_init(&output->view_list);
wl_list_init(&output->view_cleanup_list);
rpi_resource_init(&output->capture_buffer);
base->renderer_state = output;
@ -1516,7 +1625,7 @@ WL_EXPORT void
rpi_renderer_output_destroy(struct weston_output *base)
{
struct rpir_output *output = to_rpir_output(base);
struct rpir_surface *surface;
struct rpir_view *view;
DISPMANX_UPDATE_HANDLE_T update;
rpi_resource_release(&output->capture_buffer);
@ -1527,12 +1636,10 @@ rpi_renderer_output_destroy(struct weston_output *base)
rpir_output_dmx_remove_all(output, update);
vc_dispmanx_update_submit_sync(update);
while (!wl_list_empty(&output->surface_cleanup_list)) {
surface = container_of(output->surface_cleanup_list.next,
struct rpir_surface, link);
if (surface->surface)
surface->surface->renderer_state = NULL;
rpir_surface_destroy(surface);
while (!wl_list_empty(&output->view_cleanup_list)) {
view = container_of(output->view_cleanup_list.next,
struct rpir_view, link);
rpir_view_destroy(view);
}
free(output);
@ -1553,41 +1660,41 @@ rpi_renderer_finish_frame(struct weston_output *base)
{
struct rpir_output *output = to_rpir_output(base);
struct weston_compositor *compositor = base->compositor;
struct weston_surface *ws;
struct rpir_surface *surface;
struct weston_view *wv;
struct rpir_view *view;
while (!wl_list_empty(&output->surface_cleanup_list)) {
surface = container_of(output->surface_cleanup_list.next,
struct rpir_surface, link);
while (!wl_list_empty(&output->view_cleanup_list)) {
view = container_of(output->view_cleanup_list.next,
struct rpir_view, link);
if (surface->surface) {
/* The weston_surface still exists, but is
if (view->view) {
/* The weston_view still exists, but is
* temporarily not visible, and hence its Element
* was removed. The current front buffer contents
* must be preserved.
*/
if (!surface->single_buffer)
rpi_resource_release(surface->back);
if (!view->surface->visible_views)
rpi_resource_release(view->surface->back);
wl_list_remove(&surface->link);
wl_list_init(&surface->link);
wl_list_remove(&view->link);
wl_list_init(&view->link);
} else {
rpir_surface_destroy(surface);
rpir_view_destroy(view);
}
}
wl_list_for_each(ws, &compositor->surface_list, link) {
surface = to_rpir_surface(ws);
wl_list_for_each(wv, &compositor->view_list, link) {
view = to_rpir_view(wv);
if (surface->buffer_type != BUFFER_TYPE_EGL)
if (view->surface->buffer_type != BUFFER_TYPE_EGL)
continue;
if(surface->egl_old_front == NULL)
if (view->surface->egl_old_front == NULL)
continue;
weston_buffer_reference(&surface->egl_old_front->buffer_ref, NULL);
free(surface->egl_old_front);
surface->egl_old_front = NULL;
weston_buffer_reference(&view->surface->egl_old_front->buffer_ref, NULL);
free(view->surface->egl_old_front);
view->surface->egl_old_front = NULL;
}
wl_signal_emit(&base->frame_signal, base);

File diff suppressed because it is too large Load Diff

@ -25,7 +25,7 @@
#include "compositor.h"
WL_EXPORT void
weston_surface_geometry_dirty(struct weston_surface *surface)
weston_view_geometry_dirty(struct weston_view *view)
{
}
@ -36,7 +36,7 @@ weston_log(const char *fmt, ...)
}
WL_EXPORT void
weston_compositor_schedule_repaint(struct weston_compositor *compositor)
weston_view_schedule_repaint(struct weston_view *view)
{
}

@ -28,6 +28,7 @@
#include <stdio.h>
#include <string.h>
#include <linux/input.h>
#include <assert.h>
#include "compositor.h"
#include "tablet-shell-server-protocol.h"
@ -124,27 +125,43 @@ tablet_shell_set_state(struct tablet_shell *shell, int state)
shell->state = state;
}
static struct weston_view *
get_surface_view(struct weston_surface *surface, int create)
{
if (!surface)
return NULL;
if (wl_list_empty(&surface->views)) {
if (create)
return weston_view_create(surface);
else
return NULL;
}
return container_of(surface->views.next, struct weston_view, surface_link);
}
static void
tablet_shell_surface_configure(struct weston_surface *surface,
int32_t sx, int32_t sy, int32_t width, int32_t height)
{
struct tablet_shell *shell = get_shell(surface->compositor);
struct weston_view *view = get_surface_view(surface, 0);
assert(view);
if (weston_surface_is_mapped(surface) || width == 0)
return;
weston_surface_configure(surface, 0, 0, width, height);
if (surface == shell->lockscreen_surface) {
wl_list_insert(&shell->lockscreen_layer.surface_list,
&surface->layer_link);
wl_list_insert(&shell->lockscreen_layer.view_list,
&view->layer_link);
} else if (surface == shell->switcher_surface) {
/* */
} else if (surface == shell->home_surface) {
if (shell->state == STATE_STARTING) {
/* homescreen always visible, at the bottom */
wl_list_insert(&shell->homescreen_layer.surface_list,
&surface->layer_link);
wl_list_insert(&shell->homescreen_layer.view_list,
&view->layer_link);
tablet_shell_set_state(shell, STATE_LOCKED);
shell->previous_state = STATE_HOME;
@ -155,12 +172,15 @@ tablet_shell_surface_configure(struct weston_surface *surface,
shell->current_client->client == wl_resource_get_client(surface->resource)) {
tablet_shell_set_state(shell, STATE_TASK);
shell->current_client->surface = surface;
weston_zoom_run(surface, 0.3, 1.0, NULL, NULL);
wl_list_insert(&shell->application_layer.surface_list,
&surface->layer_link);
weston_zoom_run(view, 0.3, 1.0, NULL, NULL);
wl_list_insert(&shell->application_layer.view_list,
&view->layer_link);
}
weston_surface_update_transform(surface);
if (view) {
weston_view_configure(view, 0, 0, width, height);
weston_view_update_transform(view);
}
}
static void
@ -181,10 +201,12 @@ tablet_shell_set_lockscreen(struct wl_client *client,
{
struct tablet_shell *shell = wl_resource_get_user_data(resource);
struct weston_surface *es = wl_resource_get_user_data(surface_resource);
struct weston_view *view;
weston_surface_set_position(es, 0, 0);
view = weston_view_create(es);
weston_view_set_position(view, 0, 0);
shell->lockscreen_surface = es;
shell->lockscreen_surface->configure = tablet_shell_surface_configure;
es->configure = tablet_shell_surface_configure;
shell->lockscreen_listener.notify = handle_lockscreen_surface_destroy;
wl_signal_add(&es->destroy_signal, &shell->lockscreen_listener);
}
@ -208,14 +230,16 @@ tablet_shell_set_switcher(struct wl_client *client,
{
struct tablet_shell *shell = wl_resource_get_user_data(resource);
struct weston_surface *es = wl_resource_get_user_data(surface_resource);
struct weston_view *view;
/* FIXME: Switcher should be centered and the compositor
* should do the tinting of the background. With the cache
* layer idea, we should be able to hit the framerate on the
* fade/zoom in. */
shell->switcher_surface = es;
weston_surface_set_position(shell->switcher_surface, 0, 0);
view = weston_view_create(es);
weston_view_set_position(view, 0, 0);
shell->switcher_surface = es;
shell->switcher_listener.notify = handle_switcher_surface_destroy;
wl_signal_add(&es->destroy_signal, &shell->switcher_listener);
}
@ -226,15 +250,18 @@ tablet_shell_set_homescreen(struct wl_client *client,
struct wl_resource *surface_resource)
{
struct tablet_shell *shell = wl_resource_get_user_data(resource);
struct weston_surface *es = wl_resource_get_user_data(surface_resource);
struct weston_view *view;
shell->home_surface = wl_resource_get_user_data(surface_resource);
shell->home_surface->configure = tablet_shell_surface_configure;
view = weston_view_create(es);
weston_view_set_position(view, 0, 0);
weston_surface_set_position(shell->home_surface, 0, 0);
shell->home_surface = es;
es->configure = tablet_shell_surface_configure;
}
static void
minimize_zoom_done(struct weston_surface_animation *zoom, void *data)
minimize_zoom_done(struct weston_view_animation *zoom, void *data)
{
struct tablet_shell *shell = data;
struct weston_compositor *compositor = shell->compositor;
@ -251,6 +278,7 @@ tablet_shell_switch_to(struct tablet_shell *shell,
struct weston_compositor *compositor = shell->compositor;
struct weston_seat *seat;
struct weston_surface *current;
struct weston_view *view = get_surface_view(surface, 1);
if (shell->state == STATE_SWITCHER) {
wl_list_remove(&shell->switcher_listener.link);
@ -262,15 +290,15 @@ tablet_shell_switch_to(struct tablet_shell *shell,
if (shell->current_client && shell->current_client->surface) {
current = shell->current_client->surface;
weston_zoom_run(current, 1.0, 0.3,
weston_zoom_run(get_surface_view(current, 0), 1.0, 0.3,
minimize_zoom_done, shell);
}
} else {
fprintf(stderr, "switch to %p\n", surface);
fprintf(stderr, "switch to %p\n", view);
wl_list_for_each(seat, &compositor->seat_list, link)
weston_surface_activate(surface, seat);
weston_surface_activate(view->surface, seat);
tablet_shell_set_state(shell, STATE_TASK);
weston_zoom_run(surface, 0.3, 1.0, NULL, NULL);
weston_zoom_run(view, 0.3, 1.0, NULL, NULL);
}
}

@ -124,6 +124,7 @@ struct weston_wm_window {
cairo_surface_t *cairo_surface;
struct weston_surface *surface;
struct shell_surface *shsurf;
struct weston_view *view;
struct wl_listener surface_destroy_listener;
struct wl_event_source *repaint_source;
struct wl_event_source *configure_source;
@ -716,13 +717,13 @@ weston_wm_window_transform(struct wl_listener *listener, void *data)
if (!window || !wm)
return;
if (!weston_surface_is_mapped(surface))
if (!window->view || !weston_view_is_mapped(window->view))
return;
if (window->x != surface->geometry.x ||
window->y != surface->geometry.y) {
values[0] = surface->geometry.x;
values[1] = surface->geometry.y;
if (window->x != window->view->geometry.x ||
window->y != window->view->geometry.y) {
values[0] = window->view->geometry.x;
values[1] = window->view->geometry.y;
mask = XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y;
xcb_configure_window(wm->conn, window->frame_id, mask, values);
@ -958,7 +959,8 @@ weston_wm_window_draw_decoration(void *data)
window->width + 2,
window->height + 2);
}
weston_surface_geometry_dirty(window->surface);
if (window->view)
weston_view_geometry_dirty(window->view);
}
if (window->surface && !window->fullscreen) {
@ -986,7 +988,8 @@ weston_wm_window_schedule_repaint(struct weston_wm_window *window)
pixman_region32_init_rect(&window->surface->pending.opaque, 0, 0,
width, height);
}
weston_surface_geometry_dirty(window->surface);
if (window->view)
weston_view_geometry_dirty(window->view);
}
return;
}
@ -1177,8 +1180,8 @@ weston_wm_window_handle_moveresize(struct weston_wm_window *window,
struct weston_shell_interface *shell_interface =
&wm->server->compositor->shell_interface;
if (seat->pointer->button_count != 1 ||
seat->pointer->focus != window->surface)
if (seat->pointer->button_count != 1 || !window->view
|| seat->pointer->focus != window->view)
return;
detail = client_message->data.data32[2];
@ -2169,10 +2172,15 @@ xserver_map_shell_surface(struct weston_wm *wm,
if (!shell_interface->create_shell_surface)
return;
if (!shell_interface->get_primary_view)
return;
window->shsurf =
shell_interface->create_shell_surface(shell_interface->shell,
window->surface,
&shell_client);
window->view = shell_interface->get_primary_view(shell_interface->shell,
window->shsurf);
if (window->name)
shell_interface->set_title(window->shsurf, window->name);

@ -27,97 +27,6 @@
#include "compositor.h"
#include "text-cursor-position-server-protocol.h"
struct text_cursor_position {
struct weston_compositor *ec;
struct wl_global *global;
struct wl_listener destroy_listener;
};
static void
text_cursor_position_notify(struct wl_client *client,
struct wl_resource *resource,
struct wl_resource *surface_resource,
wl_fixed_t x, wl_fixed_t y)
{
struct weston_surface *surface =
wl_resource_get_user_data(surface_resource);
weston_text_cursor_position_notify(surface, x, y);
}
struct text_cursor_position_interface text_cursor_position_implementation = {
text_cursor_position_notify
};
static void
bind_text_cursor_position(struct wl_client *client,
void *data, uint32_t version, uint32_t id)
{
struct wl_resource *resource;
resource = wl_resource_create(client,
&text_cursor_position_interface, 1, id);
if (resource)
wl_resource_set_implementation(resource,
&text_cursor_position_implementation,
data, NULL);
}
static void
text_cursor_position_notifier_destroy(struct wl_listener *listener, void *data)
{
struct text_cursor_position *text_cursor_position =
container_of(listener, struct text_cursor_position, destroy_listener);
wl_global_destroy(text_cursor_position->global);
free(text_cursor_position);
}
void
text_cursor_position_notifier_create(struct weston_compositor *ec)
{
struct text_cursor_position *text_cursor_position;
text_cursor_position = malloc(sizeof *text_cursor_position);
if (text_cursor_position == NULL)
return;
text_cursor_position->ec = ec;
text_cursor_position->global =
wl_global_create(ec->wl_display,
&text_cursor_position_interface, 1,
text_cursor_position,
bind_text_cursor_position);
text_cursor_position->destroy_listener.notify =
text_cursor_position_notifier_destroy;
wl_signal_add(&ec->destroy_signal, &text_cursor_position->destroy_listener);
}
WL_EXPORT void
weston_text_cursor_position_notify(struct weston_surface *surface,
wl_fixed_t cur_pos_x,
wl_fixed_t cur_pos_y)
{
struct weston_output *output;
wl_fixed_t global_x, global_y;
weston_surface_to_global_fixed(surface, cur_pos_x, cur_pos_y,
&global_x, &global_y);
wl_list_for_each(output, &surface->compositor->output_list, link)
if (output->zoom.active &&
pixman_region32_contains_point(&output->region,
wl_fixed_to_int(global_x),
wl_fixed_to_int(global_y),
NULL)) {
output->zoom.text_cursor.x = global_x;
output->zoom.text_cursor.y = global_y;
weston_output_update_zoom(output, ZOOM_FOCUS_TEXT);
}
}
static void
weston_zoom_frame_z(struct weston_animation *animation,
struct weston_output *output, uint32_t msecs)
@ -176,12 +85,8 @@ weston_zoom_frame_xy(struct weston_animation *animation,
if (weston_spring_done(&output->zoom.spring_xy)) {
output->zoom.spring_xy.current = output->zoom.spring_xy.target;
output->zoom.current.x =
output->zoom.type == ZOOM_FOCUS_POINTER ?
seat->pointer->x : output->zoom.text_cursor.x;
output->zoom.current.y =
output->zoom.type == ZOOM_FOCUS_POINTER ?
seat->pointer->y : output->zoom.text_cursor.y;
output->zoom.current.x = seat->pointer->x;
output->zoom.current.y = seat->pointer->y;
wl_list_remove(&animation->link);
wl_list_init(&animation->link);
}
@ -251,7 +156,6 @@ weston_zoom_apply_output_transform(struct weston_output *output,
static void
weston_output_update_zoom_transform(struct weston_output *output)
{
uint32_t type = output->zoom.type;
float global_x, global_y;
wl_fixed_t x = output->zoom.current.x;
wl_fixed_t y = output->zoom.current.y;
@ -265,8 +169,7 @@ weston_output_update_zoom_transform(struct weston_output *output)
level == 0.0f)
return;
if (type == ZOOM_FOCUS_POINTER &&
wl_list_empty(&output->zoom.animation_xy.link))
if (wl_list_empty(&output->zoom.animation_xy.link))
zoom_area_center_from_pointer(output, &x, &y);
global_x = wl_fixed_to_double(x);
@ -297,39 +200,8 @@ weston_output_update_zoom_transform(struct weston_output *output)
}
static void
weston_zoom_transition(struct weston_output *output, uint32_t type,
wl_fixed_t x, wl_fixed_t y)
weston_zoom_transition(struct weston_output *output, wl_fixed_t x, wl_fixed_t y)
{
if (output->zoom.type != type) {
/* Set from/to points and start animation */
output->zoom.spring_xy.current = 0.0;
output->zoom.spring_xy.previous = 0.0;
output->zoom.spring_xy.target = 1.0;
if (wl_list_empty(&output->zoom.animation_xy.link)) {
output->zoom.animation_xy.frame_counter = 0;
wl_list_insert(output->animation_list.prev,
&output->zoom.animation_xy.link);
output->zoom.from.x = (type == ZOOM_FOCUS_TEXT) ?
x : output->zoom.text_cursor.x;
output->zoom.from.y = (type == ZOOM_FOCUS_TEXT) ?
y : output->zoom.text_cursor.y;
} else {
output->zoom.from.x = output->zoom.current.x;
output->zoom.from.y = output->zoom.current.y;
}
output->zoom.to.x = (type == ZOOM_FOCUS_POINTER) ?
x : output->zoom.text_cursor.x;
output->zoom.to.y = (type == ZOOM_FOCUS_POINTER) ?
y : output->zoom.text_cursor.y;
output->zoom.current.x = output->zoom.from.x;
output->zoom.current.y = output->zoom.from.y;
output->zoom.type = type;
}
if (output->zoom.level != output->zoom.spring_z.current) {
output->zoom.spring_z.target = output->zoom.level;
if (wl_list_empty(&output->zoom.animation_z.link)) {
@ -344,7 +216,7 @@ weston_zoom_transition(struct weston_output *output, uint32_t type,
}
WL_EXPORT void
weston_output_update_zoom(struct weston_output *output, uint32_t type)
weston_output_update_zoom(struct weston_output *output)
{
struct weston_seat *seat = weston_zoom_pick_seat(output->compositor);
wl_fixed_t x = seat->pointer->x;
@ -352,7 +224,6 @@ weston_output_update_zoom(struct weston_output *output, uint32_t type)
zoom_area_center_from_pointer(output, &x, &y);
if (type == ZOOM_FOCUS_POINTER) {
if (wl_list_empty(&output->zoom.animation_xy.link)) {
output->zoom.current.x = seat->pointer->x;
output->zoom.current.y = seat->pointer->y;
@ -360,19 +231,8 @@ weston_output_update_zoom(struct weston_output *output, uint32_t type)
output->zoom.to.x = x;
output->zoom.to.y = y;
}
}
if (type == ZOOM_FOCUS_TEXT) {
if (wl_list_empty(&output->zoom.animation_xy.link)) {
output->zoom.current.x = output->zoom.text_cursor.x;
output->zoom.current.y = output->zoom.text_cursor.y;
} else {
output->zoom.to.x = output->zoom.text_cursor.x;
output->zoom.to.y = output->zoom.text_cursor.y;
}
}
weston_zoom_transition(output, type, x, y);
weston_zoom_transition(output, x, y);
weston_output_update_zoom_transform(output);
}
@ -385,7 +245,6 @@ weston_output_init_zoom(struct weston_output *output)
output->zoom.level = 0.0;
output->zoom.trans_x = 0.0;
output->zoom.trans_y = 0.0;
output->zoom.type = ZOOM_FOCUS_POINTER;
weston_spring_init(&output->zoom.spring_z, 250.0, 0.0, 0.0);
output->zoom.spring_z.friction = 1000;
output->zoom.animation_z.frame = weston_zoom_frame_z;

@ -29,39 +29,42 @@ surface_to_from_global(void *data)
{
struct weston_compositor *compositor = data;
struct weston_surface *surface;
struct weston_view *view;
float x, y;
wl_fixed_t fx, fy;
int32_t ix, iy;
surface = weston_surface_create(compositor);
assert(surface);
weston_surface_configure(surface, 5, 10, 50, 50);
weston_surface_update_transform(surface);
view = weston_view_create(surface);
assert(view);
weston_view_configure(view, 5, 10, 50, 50);
weston_view_update_transform(view);
weston_surface_to_global_float(surface, 33, 22, &x, &y);
weston_view_to_global_float(view, 33, 22, &x, &y);
assert(x == 38 && y == 32);
weston_surface_to_global_float(surface, -8, -2, &x, &y);
weston_view_to_global_float(view, -8, -2, &x, &y);
assert(x == -3 && y == 8);
weston_surface_to_global_fixed(surface, wl_fixed_from_int(12),
weston_view_to_global_fixed(view, wl_fixed_from_int(12),
wl_fixed_from_int(5), &fx, &fy);
assert(fx == wl_fixed_from_int(17) && fy == wl_fixed_from_int(15));
weston_surface_from_global_float(surface, 38, 32, &x, &y);
weston_view_from_global_float(view, 38, 32, &x, &y);
assert(x == 33 && y == 22);
weston_surface_from_global_float(surface, 42, 5, &x, &y);
weston_view_from_global_float(view, 42, 5, &x, &y);
assert(x == 37 && y == -5);
weston_surface_from_global_fixed(surface, wl_fixed_from_int(21),
weston_view_from_global_fixed(view, wl_fixed_from_int(21),
wl_fixed_from_int(100), &fx, &fy);
assert(fx == wl_fixed_from_int(16) && fy == wl_fixed_from_int(90));
weston_surface_from_global(surface, 0, 0, &ix, &iy);
weston_view_from_global(view, 0, 0, &ix, &iy);
assert(ix == -5 && iy == -10);
weston_surface_from_global(surface, 5, 10, &ix, &iy);
weston_view_from_global(view, 5, 10, &ix, &iy);
assert(ix == 0 && iy == 0);
wl_display_terminate(compositor->wl_display);

@ -31,20 +31,23 @@ surface_transform(void *data)
{
struct weston_compositor *compositor = data;
struct weston_surface *surface;
struct weston_view *view;
float x, y;
surface = weston_surface_create(compositor);
assert(surface);
weston_surface_configure(surface, 100, 100, 200, 200);
weston_surface_update_transform(surface);
weston_surface_to_global_float(surface, 20, 20, &x, &y);
view = weston_view_create(surface);
assert(view);
weston_view_configure(view, 100, 100, 200, 200);
weston_view_update_transform(view);
weston_view_to_global_float(view, 20, 20, &x, &y);
fprintf(stderr, "20,20 maps to %f, %f\n", x, y);
assert(x == 120 && y == 120);
weston_surface_set_position(surface, 150, 300);
weston_surface_update_transform(surface);
weston_surface_to_global_float(surface, 50, 40, &x, &y);
weston_view_set_position(view, 150, 300);
weston_view_update_transform(view);
weston_view_to_global_float(view, 50, 40, &x, &y);
assert(x == 200 && y == 340);
wl_display_terminate(compositor->wl_display);

@ -36,6 +36,7 @@ struct weston_test {
struct weston_test_surface {
struct weston_surface *surface;
struct weston_view *view;
int32_t x, y;
struct weston_test *test;
};
@ -79,15 +80,16 @@ test_surface_configure(struct weston_surface *surface, int32_t sx, int32_t sy, i
struct weston_test_surface *test_surface = surface->configure_private;
struct weston_test *test = test_surface->test;
if (wl_list_empty(&surface->layer_link))
wl_list_insert(&test->layer.surface_list,
&surface->layer_link);
if (wl_list_empty(&test_surface->view->layer_link))
wl_list_insert(&test->layer.view_list,
&test_surface->view->layer_link);
weston_surface_configure(surface, test_surface->x, test_surface->y,
weston_view_configure(test_surface->view,
test_surface->x, test_surface->y,
width, height);
if (!weston_surface_is_mapped(surface))
weston_surface_update_transform(surface);
if (!weston_view_is_mapped(test_surface->view))
weston_view_update_transform(test_surface->view);
}
static void
@ -99,15 +101,25 @@ move_surface(struct wl_client *client, struct wl_resource *resource,
wl_resource_get_user_data(surface_resource);
struct weston_test_surface *test_surface;
surface->configure = test_surface_configure;
if (surface->configure_private == NULL)
surface->configure_private = malloc(sizeof *test_surface);
test_surface = surface->configure_private;
if (test_surface == NULL) {
if (!test_surface) {
test_surface = malloc(sizeof *test_surface);
if (!test_surface) {
wl_resource_post_no_memory(resource);
return;
}
test_surface->view = weston_view_create(surface);
if (!test_surface->view) {
wl_resource_post_no_memory(resource);
free(test_surface);
return;
}
surface->configure_private = test_surface;
surface->configure = test_surface_configure;
}
test_surface->surface = surface;
test_surface->test = wl_resource_get_user_data(resource);
test_surface->x = x;

Loading…
Cancel
Save