compositor: reorganize struct weston_buffer_viewport

Queueing in the Presentation extension requires splitting the viewport
state into buffer state and surface state. To conveniently allow
assigning only one, the other, or both, reorganize the
weston_buffer_viewport structure.

Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
dev
Pekka Paalanen 11 years ago committed by Kristian Høgsberg
parent 7ed251c119
commit 952b6c8004
  1. 6
      desktop-shell/shell.c
  2. 12
      src/compositor-drm.c
  3. 70
      src/compositor.c
  4. 27
      src/compositor.h
  5. 2
      src/gl-renderer.c
  6. 25
      src/pixman-renderer.c

@ -2661,11 +2661,11 @@ shell_configure_fullscreen(struct shell_surface *shsurf)
case WL_SHELL_SURFACE_FULLSCREEN_METHOD_DRIVER: case WL_SHELL_SURFACE_FULLSCREEN_METHOD_DRIVER:
if (shell_surface_is_top_fullscreen(shsurf)) { if (shell_surface_is_top_fullscreen(shsurf)) {
struct weston_mode mode = {0, struct weston_mode mode = {0,
surf_width * surface->buffer_viewport.scale, surf_width * surface->buffer_viewport.buffer.scale,
surf_height * surface->buffer_viewport.scale, surf_height * surface->buffer_viewport.buffer.scale,
shsurf->fullscreen.framerate}; shsurf->fullscreen.framerate};
if (weston_output_switch_mode(output, &mode, surface->buffer_viewport.scale, if (weston_output_switch_mode(output, &mode, surface->buffer_viewport.buffer.scale,
WESTON_MODE_SWITCH_SET_TEMPORARY) == 0) { WESTON_MODE_SWITCH_SET_TEMPORARY) == 0) {
weston_view_set_position(shsurf->view, weston_view_set_position(shsurf->view,
output->x - surf_x, output->x - surf_x,

@ -455,6 +455,7 @@ drm_output_prepare_scanout_view(struct weston_output *_output,
struct drm_compositor *c = struct drm_compositor *c =
(struct drm_compositor *) output->base.compositor; (struct drm_compositor *) output->base.compositor;
struct weston_buffer *buffer = ev->surface->buffer_ref.buffer; struct weston_buffer *buffer = ev->surface->buffer_ref.buffer;
struct weston_buffer_viewport *viewport = &ev->surface->buffer_viewport;
struct gbm_bo *bo; struct gbm_bo *bo;
uint32_t format; uint32_t format;
@ -463,7 +464,7 @@ drm_output_prepare_scanout_view(struct weston_output *_output,
buffer == NULL || c->gbm == NULL || buffer == NULL || c->gbm == NULL ||
buffer->width != output->base.current_mode->width || buffer->width != output->base.current_mode->width ||
buffer->height != output->base.current_mode->height || buffer->height != output->base.current_mode->height ||
output->base.transform != ev->surface->buffer_viewport.transform || output->base.transform != viewport->buffer.transform ||
ev->transform.enabled) ev->transform.enabled)
return NULL; return NULL;
@ -808,6 +809,7 @@ drm_output_prepare_overlay_view(struct weston_output *output_base,
{ {
struct weston_compositor *ec = output_base->compositor; struct weston_compositor *ec = output_base->compositor;
struct drm_compositor *c =(struct drm_compositor *) ec; struct drm_compositor *c =(struct drm_compositor *) ec;
struct weston_buffer_viewport *viewport = &ev->surface->buffer_viewport;
struct drm_sprite *s; struct drm_sprite *s;
int found = 0; int found = 0;
struct gbm_bo *bo; struct gbm_bo *bo;
@ -819,10 +821,10 @@ drm_output_prepare_overlay_view(struct weston_output *output_base,
if (c->gbm == NULL) if (c->gbm == NULL)
return NULL; return NULL;
if (ev->surface->buffer_viewport.transform != output_base->transform) if (viewport->buffer.transform != output_base->transform)
return NULL; return NULL;
if (ev->surface->buffer_viewport.scale != output_base->current_scale) if (viewport->buffer.scale != output_base->current_scale)
return NULL; return NULL;
if (c->sprites_are_broken) if (c->sprites_are_broken)
@ -932,8 +934,8 @@ drm_output_prepare_overlay_view(struct weston_output *output_base,
tbox = weston_transformed_rect(wl_fixed_from_int(ev->surface->width), tbox = weston_transformed_rect(wl_fixed_from_int(ev->surface->width),
wl_fixed_from_int(ev->surface->height), wl_fixed_from_int(ev->surface->height),
ev->surface->buffer_viewport.transform, viewport->buffer.transform,
ev->surface->buffer_viewport.scale, viewport->buffer.scale,
tbox); tbox);
s->src_x = tbox.x1 << 8; s->src_x = tbox.x1 << 8;

@ -400,9 +400,9 @@ weston_surface_create(struct weston_compositor *compositor)
surface->compositor = compositor; surface->compositor = compositor;
surface->ref_count = 1; surface->ref_count = 1;
surface->buffer_viewport.transform = WL_OUTPUT_TRANSFORM_NORMAL; surface->buffer_viewport.buffer.transform = WL_OUTPUT_TRANSFORM_NORMAL;
surface->buffer_viewport.scale = 1; surface->buffer_viewport.buffer.scale = 1;
surface->buffer_viewport.viewport_set = 0; surface->buffer_viewport.buffer.viewport_set = 0;
surface->pending.buffer_viewport = surface->buffer_viewport; surface->pending.buffer_viewport = surface->buffer_viewport;
surface->output = NULL; surface->output = NULL;
surface->pending.newly_attached = 0; surface->pending.newly_attached = 0;
@ -639,16 +639,18 @@ static void
scaler_surface_to_buffer(struct weston_surface *surface, scaler_surface_to_buffer(struct weston_surface *surface,
float sx, float sy, float *bx, float *by) float sx, float sy, float *bx, float *by)
{ {
if (surface->buffer_viewport.viewport_set) { struct weston_buffer_viewport *vp = &surface->buffer_viewport;
if (vp->buffer.viewport_set) {
double a, b; double a, b;
a = sx / surface->buffer_viewport.dst_width; a = sx / vp->surface.width;
b = a * wl_fixed_to_double(surface->buffer_viewport.src_width); b = a * wl_fixed_to_double(vp->buffer.src_width);
*bx = b + wl_fixed_to_double(surface->buffer_viewport.src_x); *bx = b + wl_fixed_to_double(vp->buffer.src_x);
a = sy / surface->buffer_viewport.dst_height; a = sy / vp->surface.height;
b = a * wl_fixed_to_double(surface->buffer_viewport.src_height); b = a * wl_fixed_to_double(vp->buffer.src_height);
*by = b + wl_fixed_to_double(surface->buffer_viewport.src_y); *by = b + wl_fixed_to_double(vp->buffer.src_y);
} else { } else {
*bx = sx; *bx = sx;
*by = sy; *by = sy;
@ -659,13 +661,13 @@ WL_EXPORT void
weston_surface_to_buffer_float(struct weston_surface *surface, weston_surface_to_buffer_float(struct weston_surface *surface,
float sx, float sy, float *bx, float *by) float sx, float sy, float *bx, float *by)
{ {
struct weston_buffer_viewport *vp = &surface->buffer_viewport;
/* first transform coordinates if the scaler is set */ /* first transform coordinates if the scaler is set */
scaler_surface_to_buffer(surface, sx, sy, bx, by); scaler_surface_to_buffer(surface, sx, sy, bx, by);
weston_transformed_coord(surface->width, weston_transformed_coord(surface->width, surface->height,
surface->height, vp->buffer.transform, vp->buffer.scale,
surface->buffer_viewport.transform,
surface->buffer_viewport.scale,
*bx, *by, bx, by); *bx, *by, bx, by);
} }
@ -686,6 +688,7 @@ WL_EXPORT pixman_box32_t
weston_surface_to_buffer_rect(struct weston_surface *surface, weston_surface_to_buffer_rect(struct weston_surface *surface,
pixman_box32_t rect) pixman_box32_t rect)
{ {
struct weston_buffer_viewport *vp = &surface->buffer_viewport;
float xf, yf; float xf, yf;
/* first transform box coordinates if the scaler is set */ /* first transform box coordinates if the scaler is set */
@ -697,10 +700,8 @@ weston_surface_to_buffer_rect(struct weston_surface *surface,
rect.x2 = floorf(xf); rect.x2 = floorf(xf);
rect.y2 = floorf(yf); rect.y2 = floorf(yf);
return weston_transformed_rect(surface->width, return weston_transformed_rect(surface->width, surface->height,
surface->height, vp->buffer.transform, vp->buffer.scale,
surface->buffer_viewport.transform,
surface->buffer_viewport.scale,
rect); rect);
} }
@ -1195,6 +1196,7 @@ weston_surface_set_size(struct weston_surface *surface,
static void static void
weston_surface_set_size_from_buffer(struct weston_surface *surface) weston_surface_set_size_from_buffer(struct weston_surface *surface)
{ {
struct weston_buffer_viewport *vp = &surface->buffer_viewport;
int32_t width, height; int32_t width, height;
if (!surface->buffer_ref.buffer) { if (!surface->buffer_ref.buffer) {
@ -1202,13 +1204,13 @@ weston_surface_set_size_from_buffer(struct weston_surface *surface)
return; return;
} }
if (surface->buffer_viewport.viewport_set) { if (vp->buffer.viewport_set) {
surface_set_size(surface, surface->buffer_viewport.dst_width, surface_set_size(surface, vp->surface.width,
surface->buffer_viewport.dst_height); vp->surface.height);
return; return;
} }
switch (surface->buffer_viewport.transform) { switch (vp->buffer.transform) {
case WL_OUTPUT_TRANSFORM_90: case WL_OUTPUT_TRANSFORM_90:
case WL_OUTPUT_TRANSFORM_270: case WL_OUTPUT_TRANSFORM_270:
case WL_OUTPUT_TRANSFORM_FLIPPED_90: case WL_OUTPUT_TRANSFORM_FLIPPED_90:
@ -1222,8 +1224,8 @@ weston_surface_set_size_from_buffer(struct weston_surface *surface)
break; break;
} }
width = width / surface->buffer_viewport.scale; width = width / vp->buffer.scale;
height = height / surface->buffer_viewport.scale; height = height / vp->buffer.scale;
surface_set_size(surface, width, height); surface_set_size(surface, width, height);
} }
@ -2108,7 +2110,7 @@ surface_set_buffer_transform(struct wl_client *client,
{ {
struct weston_surface *surface = wl_resource_get_user_data(resource); struct weston_surface *surface = wl_resource_get_user_data(resource);
surface->pending.buffer_viewport.transform = transform; surface->pending.buffer_viewport.buffer.transform = transform;
} }
static void static void
@ -2118,7 +2120,7 @@ surface_set_buffer_scale(struct wl_client *client,
{ {
struct weston_surface *surface = wl_resource_get_user_data(resource); struct weston_surface *surface = wl_resource_get_user_data(resource);
surface->pending.buffer_viewport.scale = scale; surface->pending.buffer_viewport.buffer.scale = scale;
} }
static const struct wl_surface_interface surface_interface = { static const struct wl_surface_interface surface_interface = {
@ -3357,7 +3359,7 @@ destroy_viewport(struct wl_resource *resource)
wl_resource_get_user_data(resource); wl_resource_get_user_data(resource);
surface->viewport_resource = NULL; surface->viewport_resource = NULL;
surface->pending.buffer_viewport.viewport_set = 0; surface->pending.buffer_viewport.buffer.viewport_set = 0;
} }
static void static void
@ -3400,14 +3402,14 @@ viewport_set(struct wl_client *client,
return; return;
} }
surface->pending.buffer_viewport.viewport_set = 1; surface->pending.buffer_viewport.buffer.viewport_set = 1;
surface->pending.buffer_viewport.src_x = src_x; surface->pending.buffer_viewport.buffer.src_x = src_x;
surface->pending.buffer_viewport.src_y = src_y; surface->pending.buffer_viewport.buffer.src_y = src_y;
surface->pending.buffer_viewport.src_width = src_width; surface->pending.buffer_viewport.buffer.src_width = src_width;
surface->pending.buffer_viewport.src_height = src_height; surface->pending.buffer_viewport.buffer.src_height = src_height;
surface->pending.buffer_viewport.dst_width = dst_width; surface->pending.buffer_viewport.surface.width = dst_width;
surface->pending.buffer_viewport.dst_height = dst_height; surface->pending.buffer_viewport.surface.height = dst_height;
} }
static const struct wl_viewport_interface viewport_interface = { static const struct wl_viewport_interface viewport_interface = {

@ -655,20 +655,25 @@ struct weston_buffer_reference {
}; };
struct weston_buffer_viewport { struct weston_buffer_viewport {
/* wl_surface.set_buffer_transform */ struct {
uint32_t transform; /* wl_surface.set_buffer_transform */
uint32_t transform;
/* wl_surface.set_scaling_factor */ /* wl_surface.set_scaling_factor */
int32_t scale; int32_t scale;
/* bool for whether wl_viewport.set has been
* called yet (before this is called there is no
* cropping or scaling on the surface) */
int viewport_set; /* bool */
/* bool for whether wl_viewport.set has been wl_fixed_t src_x, src_y;
* called yet (before this is called there is no wl_fixed_t src_width, src_height;
* cropping or scaling on the surface) */ } buffer;
int viewport_set; /* bool */
wl_fixed_t src_x, src_y; struct {
wl_fixed_t src_width, src_height; int32_t width, height;
int32_t dst_width, dst_height; } surface;
}; };
struct weston_region { struct weston_region {

@ -553,7 +553,7 @@ draw_view(struct weston_view *ev, struct weston_output *output,
shader_uniforms(gs->shader, ev, output); shader_uniforms(gs->shader, ev, output);
if (ev->transform.enabled || output->zoom.active || if (ev->transform.enabled || output->zoom.active ||
output->current_scale != ev->surface->buffer_viewport.scale) output->current_scale != ev->surface->buffer_viewport.buffer.scale)
filter = GL_LINEAR; filter = GL_LINEAR;
else else
filter = GL_NEAREST; filter = GL_NEAREST;

@ -147,6 +147,7 @@ repaint_region(struct weston_view *ev, struct weston_output *output,
(struct pixman_renderer *) output->compositor->renderer; (struct pixman_renderer *) output->compositor->renderer;
struct pixman_surface_state *ps = get_surface_state(ev->surface); struct pixman_surface_state *ps = get_surface_state(ev->surface);
struct pixman_output_state *po = get_output_state(output); struct pixman_output_state *po = get_output_state(output);
struct weston_buffer_viewport *vp = &ev->surface->buffer_viewport;
pixman_region32_t final_region; pixman_region32_t final_region;
float view_x, view_y; float view_x, view_y;
pixman_transform_t transform; pixman_transform_t transform;
@ -257,17 +258,17 @@ repaint_region(struct weston_view *ev, struct weston_output *output,
pixman_double_to_fixed ((double)-ev->geometry.y)); pixman_double_to_fixed ((double)-ev->geometry.y));
} }
if (ev->surface->buffer_viewport.viewport_set) { if (vp->buffer.viewport_set) {
double viewport_x, viewport_y, viewport_width, viewport_height; double viewport_x, viewport_y, viewport_width, viewport_height;
double ratio_x, ratio_y; double ratio_x, ratio_y;
viewport_x = wl_fixed_to_double(ev->surface->buffer_viewport.src_x); viewport_x = wl_fixed_to_double(vp->buffer.src_x);
viewport_y = wl_fixed_to_double(ev->surface->buffer_viewport.src_y); viewport_y = wl_fixed_to_double(vp->buffer.src_y);
viewport_width = wl_fixed_to_double(ev->surface->buffer_viewport.src_width); viewport_width = wl_fixed_to_double(vp->buffer.src_width);
viewport_height = wl_fixed_to_double(ev->surface->buffer_viewport.src_height); viewport_height = wl_fixed_to_double(vp->buffer.src_height);
ratio_x = viewport_width / ev->surface->buffer_viewport.dst_width; ratio_x = viewport_width / vp->surface.width;
ratio_y = viewport_height / ev->surface->buffer_viewport.dst_height; ratio_y = viewport_height / vp->surface.height;
pixman_transform_scale(&transform, NULL, pixman_transform_scale(&transform, NULL,
pixman_double_to_fixed(ratio_x), pixman_double_to_fixed(ratio_x),
@ -279,7 +280,7 @@ repaint_region(struct weston_view *ev, struct weston_output *output,
fw = pixman_int_to_fixed(ev->surface->width); fw = pixman_int_to_fixed(ev->surface->width);
fh = pixman_int_to_fixed(ev->surface->height); fh = pixman_int_to_fixed(ev->surface->height);
switch (ev->surface->buffer_viewport.transform) { switch (vp->buffer.transform) {
case WL_OUTPUT_TRANSFORM_FLIPPED: case WL_OUTPUT_TRANSFORM_FLIPPED:
case WL_OUTPUT_TRANSFORM_FLIPPED_90: case WL_OUTPUT_TRANSFORM_FLIPPED_90:
case WL_OUTPUT_TRANSFORM_FLIPPED_180: case WL_OUTPUT_TRANSFORM_FLIPPED_180:
@ -291,7 +292,7 @@ repaint_region(struct weston_view *ev, struct weston_output *output,
break; break;
} }
switch (ev->surface->buffer_viewport.transform) { switch (vp->buffer.transform) {
default: default:
case WL_OUTPUT_TRANSFORM_NORMAL: case WL_OUTPUT_TRANSFORM_NORMAL:
case WL_OUTPUT_TRANSFORM_FLIPPED: case WL_OUTPUT_TRANSFORM_FLIPPED:
@ -314,12 +315,12 @@ repaint_region(struct weston_view *ev, struct weston_output *output,
} }
pixman_transform_scale(&transform, NULL, pixman_transform_scale(&transform, NULL,
pixman_double_to_fixed(ev->surface->buffer_viewport.scale), pixman_double_to_fixed(vp->buffer.scale),
pixman_double_to_fixed(ev->surface->buffer_viewport.scale)); pixman_double_to_fixed(vp->buffer.scale));
pixman_image_set_transform(ps->image, &transform); pixman_image_set_transform(ps->image, &transform);
if (ev->transform.enabled || output->current_scale != ev->surface->buffer_viewport.scale) if (ev->transform.enabled || output->current_scale != vp->buffer.scale)
pixman_image_set_filter(ps->image, PIXMAN_FILTER_BILINEAR, NULL, 0); pixman_image_set_filter(ps->image, PIXMAN_FILTER_BILINEAR, NULL, 0);
else else
pixman_image_set_filter(ps->image, PIXMAN_FILTER_NEAREST, NULL, 0); pixman_image_set_filter(ps->image, PIXMAN_FILTER_NEAREST, NULL, 0);

Loading…
Cancel
Save