X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fcompositor-drm.c;h=d558f7da017656f202548338b360b6f363094560;hb=6b423de3169d75a6178c570d15f7933427a86564;hp=154e15e4c79ba40d70c98b6688d8720a0892f3c1;hpb=b3955b095317466afd05b474666eef938b7f72d0;p=profile%2Fivi%2Fweston-ivi-shell.git diff --git a/src/compositor-drm.c b/src/compositor-drm.c index 154e15e..d558f7d 100644 --- a/src/compositor-drm.c +++ b/src/compositor-drm.c @@ -41,13 +41,13 @@ #include #include -#include #include +#include "libbacklight.h" #include "compositor.h" #include "gl-renderer.h" #include "pixman-renderer.h" -#include "udev-seat.h" +#include "udev-input.h" #include "launcher-util.h" #include "vaapi-recorder.h" @@ -55,6 +55,18 @@ #define DRM_CAP_TIMESTAMP_MONOTONIC 0x6 #endif +#ifndef DRM_CAP_CURSOR_WIDTH +#define DRM_CAP_CURSOR_WIDTH 0x8 +#endif + +#ifndef DRM_CAP_CURSOR_HEIGHT +#define DRM_CAP_CURSOR_HEIGHT 0x9 +#endif + +#ifndef GBM_BO_USE_CURSOR +#define GBM_BO_USE_CURSOR GBM_BO_USE_CURSOR_64X64 +#endif + static int option_current_mode = 0; enum output_config { @@ -108,6 +120,10 @@ struct drm_compositor { clockid_t clock; struct udev_input input; + char *main_seat; + + uint32_t cursor_width; + uint32_t cursor_height; }; struct drm_mode { @@ -147,10 +163,12 @@ struct drm_output { drmModeCrtcPtr original_crtc; struct drm_edid edid; drmModePropertyPtr dpms_prop; + uint32_t format; int vblank_pending; int page_flip_pending; int destroy_pending; + int force_modeset; struct gbm_surface *surface; struct gbm_bo *cursor_bo[2]; @@ -420,8 +438,6 @@ static uint32_t drm_output_check_scanout_format(struct drm_output *output, struct weston_surface *es, struct gbm_bo *bo) { - struct drm_compositor *c = - (struct drm_compositor *) output->base.compositor; uint32_t format; pixman_region32_t r; @@ -442,7 +458,7 @@ drm_output_check_scanout_format(struct drm_output *output, pixman_region32_fini(&r); } - if (c->format == format) + if (output->format == format) return format; return 0; @@ -456,6 +472,7 @@ drm_output_prepare_scanout_view(struct weston_output *_output, struct drm_compositor *c = (struct drm_compositor *) output->base.compositor; struct weston_buffer *buffer = ev->surface->buffer_ref.buffer; + struct weston_buffer_viewport *viewport = &ev->surface->buffer_viewport; struct gbm_bo *bo; uint32_t format; @@ -464,7 +481,7 @@ drm_output_prepare_scanout_view(struct weston_output *_output, buffer == NULL || c->gbm == NULL || buffer->width != output->base.current_mode->width || buffer->height != output->base.current_mode->height || - output->base.transform != ev->surface->buffer_viewport.transform || + output->base.transform != viewport->buffer.transform || ev->transform.enabled) return NULL; @@ -507,7 +524,7 @@ drm_output_render_gl(struct drm_output *output, pixman_region32_t *damage) return; } - output->next = drm_fb_get_from_bo(bo, c, c->format); + output->next = drm_fb_get_from_bo(bo, c, output->format); if (!output->next) { weston_log("failed to get drm_fb for bo\n"); gbm_surface_release_buffer(output->surface, bo); @@ -598,7 +615,8 @@ drm_output_repaint(struct weston_output *output_base, mode = container_of(output->base.current_mode, struct drm_mode, base); if (!output->current || - output->current->stride != output->next->stride) { + output->current->stride != output->next->stride || + output->force_modeset) { ret = drmModeSetCrtc(compositor->drm.fd, output->crtc_id, output->next->fb_id, 0, 0, &output->connector_id, 1, @@ -608,6 +626,7 @@ drm_output_repaint(struct weston_output *output_base, goto err_pageflip; } output_base->set_dpms(output_base, WESTON_DPMS_ON); + output->force_modeset = 0; } if (drmModePageFlip(compositor->drm.fd, output->crtc_id, @@ -809,6 +828,7 @@ drm_output_prepare_overlay_view(struct weston_output *output_base, { struct weston_compositor *ec = output_base->compositor; struct drm_compositor *c =(struct drm_compositor *) ec; + struct weston_buffer_viewport *viewport = &ev->surface->buffer_viewport; struct drm_sprite *s; int found = 0; struct gbm_bo *bo; @@ -820,10 +840,10 @@ drm_output_prepare_overlay_view(struct weston_output *output_base, if (c->gbm == NULL) return NULL; - if (ev->surface->buffer_viewport.transform != output_base->transform) + if (viewport->buffer.transform != output_base->transform) return NULL; - if (ev->surface->buffer_viewport.scale != output_base->current_scale) + if (viewport->buffer.scale != output_base->current_scale) return NULL; if (c->sprites_are_broken) @@ -884,7 +904,7 @@ drm_output_prepare_overlay_view(struct weston_output *output_base, /* * Calculate the source & dest rects properly based on actual - * position (note the caller has called weston_surface_update_transform() + * position (note the caller has called weston_view_update_transform() * for us already). */ pixman_region32_init(&dest_rect); @@ -933,8 +953,8 @@ drm_output_prepare_overlay_view(struct weston_output *output_base, tbox = weston_transformed_rect(wl_fixed_from_int(ev->surface->width), wl_fixed_from_int(ev->surface->height), - ev->surface->buffer_viewport.transform, - ev->surface->buffer_viewport.scale, + viewport->buffer.transform, + viewport->buffer.scale, tbox); s->src_x = tbox.x1 << 8; @@ -952,12 +972,15 @@ drm_output_prepare_cursor_view(struct weston_output *output_base, { struct drm_compositor *c = (struct drm_compositor *) output_base->compositor; + struct weston_buffer_viewport *viewport = &ev->surface->buffer_viewport; struct drm_output *output = (struct drm_output *) output_base; if (c->gbm == NULL) return NULL; if (output->base.transform != WL_OUTPUT_TRANSFORM_NORMAL) return NULL; + if (viewport->buffer.scale != output_base->current_scale) + return NULL; if (output->cursor_view) return NULL; if (ev->output_mask != (1u << output_base->id)) @@ -983,7 +1006,7 @@ drm_output_set_cursor(struct drm_output *output) (struct drm_compositor *) output->base.compositor; EGLint handle, stride; struct gbm_bo *bo; - uint32_t buf[64 * 64]; + uint32_t buf[c->cursor_width * c->cursor_height]; unsigned char *s; int i, x, y; @@ -1006,7 +1029,7 @@ drm_output_set_cursor(struct drm_output *output) s = wl_shm_buffer_get_data(buffer->shm_buffer); wl_shm_buffer_begin_access(buffer->shm_buffer); for (i = 0; i < ev->surface->height; i++) - memcpy(buf + i * 64, s + i * stride, + memcpy(buf + i * c->cursor_width, s + i * stride, ev->surface->width * 4); wl_shm_buffer_end_access(buffer->shm_buffer); @@ -1014,8 +1037,8 @@ drm_output_set_cursor(struct drm_output *output) weston_log("failed update cursor: %m\n"); handle = gbm_bo_get_handle(bo).s32; - if (drmModeSetCursor(c->drm.fd, - output->crtc_id, handle, 64, 64)) { + if (drmModeSetCursor(c->drm.fd, output->crtc_id, handle, + c->cursor_width, c->cursor_height)) { weston_log("failed to set cursor: %m\n"); c->cursors_are_broken = 1; } @@ -1292,6 +1315,18 @@ init_drm(struct drm_compositor *ec, struct udev_device *device) else ec->clock = CLOCK_REALTIME; + ret = drmGetCap(fd, DRM_CAP_CURSOR_WIDTH, &cap); + if (ret == 0) + ec->cursor_width = cap; + else + ec->cursor_width = 64; + + ret = drmGetCap(fd, DRM_CAP_CURSOR_HEIGHT, &cap); + if (ret == 0) + ec->cursor_height = cap; + else + ec->cursor_height = 64; + return 0; } @@ -1528,12 +1563,13 @@ find_crtc_for_connector(struct drm_compositor *ec, static int drm_output_init_egl(struct drm_output *output, struct drm_compositor *ec) { + EGLint format = output->format; int i, flags; output->surface = gbm_surface_create(ec->gbm, output->base.current_mode->width, output->base.current_mode->height, - ec->format, + format, GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING); if (!output->surface) { @@ -1541,21 +1577,23 @@ drm_output_init_egl(struct drm_output *output, struct drm_compositor *ec) return -1; } - if (gl_renderer->output_create(&output->base, output->surface) < 0) { + if (gl_renderer->output_create(&output->base, output->surface, + gl_renderer->opaque_attribs, + &format) < 0) { weston_log("failed to create gl renderer output state\n"); gbm_surface_destroy(output->surface); return -1; } - flags = GBM_BO_USE_CURSOR_64X64 | GBM_BO_USE_WRITE; + flags = GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE; for (i = 0; i < 2; i++) { if (output->cursor_bo[i]) continue; output->cursor_bo[i] = - gbm_bo_create(ec->gbm, 64, 64, GBM_FORMAT_ARGB8888, - flags); + gbm_bo_create(ec->gbm, ec->cursor_width, ec->cursor_height, + GBM_FORMAT_ARGB8888, flags); } if (output->cursor_bo[0] == NULL || output->cursor_bo[1] == NULL) { @@ -1842,17 +1880,53 @@ setup_output_seat_constraint(struct drm_compositor *ec, struct udev_seat *seat; seat = udev_seat_get_named(&ec->base, s); - if (seat) - seat->base.output = output; - - if (seat && seat->base.pointer) - weston_pointer_clamp(seat->base.pointer, + if (seat) { + udev_seat_link_output(seat, output); +#if HAVE_MULTISEAT + if (!seat->input.libinput) + udev_input_init(&seat->input, &ec->base, + ec->udev, s); + else if (seat->input.suspended) + udev_input_enable(&seat->input); +#endif + if (seat->base.pointer) + weston_pointer_clamp(seat->base.pointer, &seat->base.pointer->x, &seat->base.pointer->y); + } } } static int +get_gbm_format_from_section(struct weston_config_section *section, + uint32_t default_value, + uint32_t *format) +{ + char *s; + int ret = 0; + + weston_config_section_get_string(section, + "gbm-format", &s, NULL); + + if (s == NULL) + *format = default_value; + else if (strcmp(s, "xrgb8888") == 0) + *format = GBM_FORMAT_XRGB8888; + else if (strcmp(s, "rgb565") == 0) + *format = GBM_FORMAT_RGB565; + else if (strcmp(s, "xrgb2101010") == 0) + *format = GBM_FORMAT_XRGB2101010; + else { + weston_log("fatal: unrecognized pixel format: %s\n", s); + ret = -1; + } + + free(s); + + return ret; +} + +static int create_output_for_connector(struct drm_compositor *ec, drmModeRes *resources, drmModeConnector *connector, @@ -1870,6 +1944,7 @@ create_output_for_connector(struct drm_compositor *ec, const char *type_name; enum output_config config; uint32_t transform; + int default_output; i = find_crtc_for_connector(ec, resources, connector); if (i < 0) { @@ -1918,8 +1993,18 @@ create_output_for_connector(struct drm_compositor *ec, weston_config_section_get_string(section, "transform", &s, "normal"); transform = parse_transform(s, output->base.name); free(s); + weston_config_section_get_int(section, "default_output", + &default_output, 0); + + if (get_gbm_format_from_section(section, + ec->format, + &output->format) == -1) + output->format = ec->format; weston_config_section_get_string(section, "seat", &s, ""); + output->base.seat_data.seatname = strdup(s); + weston_log("output %p belongs to seat '%s'\n", output, + output->base.seat_data.seatname); setup_output_seat_constraint(ec, &output->base, s); free(s); @@ -2035,6 +2120,8 @@ create_output_for_connector(struct drm_compositor *ec, } wl_list_insert(ec->base.output_list.prev, &output->base.link); + if (default_output) + ec->base.default_output = &output->base; find_and_parse_output_edid(ec, output, connector); if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS) @@ -2335,8 +2422,6 @@ drm_destroy(struct weston_compositor *ec) { struct drm_compositor *d = (struct drm_compositor *) ec; - udev_input_destroy(&d->input); - wl_event_source_remove(d->udev_drm_source); wl_event_source_remove(d->drm_source); @@ -2350,7 +2435,7 @@ drm_destroy(struct weston_compositor *ec) weston_launcher_destroy(d->base.launcher); close(d->drm.fd); - + free (d->main_seat); free(d); } @@ -2393,16 +2478,24 @@ session_notify(struct wl_listener *listener, void *data) struct drm_compositor *ec = data; struct drm_sprite *sprite; struct drm_output *output; + struct udev_seat *useat; + struct weston_seat *seat, *next; if (ec->base.session_active) { weston_log("activating session\n"); compositor->state = ec->prev_state; drm_compositor_set_modes(ec); weston_compositor_damage_all(compositor); - udev_input_enable(&ec->input, ec->udev); + wl_list_for_each_safe(seat, next, &ec->base.seat_list, link) { + useat = container_of(seat, struct udev_seat, base); + udev_input_enable(&useat->input); + } } else { weston_log("deactivating session\n"); - udev_input_disable(&ec->input); + wl_list_for_each_safe(seat, next, &ec->base.seat_list, link) { + useat = container_of(seat, struct udev_seat, base); + udev_input_disable(&useat->input); + } ec->prev_state = compositor->state; weston_compositor_offscreen(compositor); @@ -2517,6 +2610,18 @@ planes_binding(struct weston_seat *seat, uint32_t time, uint32_t key, void *data #ifdef BUILD_VAAPI_RECORDER static void +recorder_destroy(struct drm_output *output) +{ + vaapi_recorder_destroy(output->recorder); + output->recorder = NULL; + + output->base.disable_planes--; + + wl_list_remove(&output->recorder_frame_listener.link); + weston_log("[libva recorder] done\n"); +} + +static void recorder_frame_notify(struct wl_listener *listener, void *data) { struct drm_output *output; @@ -2538,7 +2643,12 @@ recorder_frame_notify(struct wl_listener *listener, void *data) return; } - vaapi_recorder_frame(output->recorder, fd, output->current->stride / 4); + ret = vaapi_recorder_frame(output->recorder, fd, + output->current->stride); + if (ret < 0) { + weston_log("[libva recorder] aborted: %m\n"); + recorder_destroy(output); + } } static void * @@ -2570,6 +2680,12 @@ recorder_binding(struct weston_seat *seat, uint32_t time, uint32_t key, struct drm_output, base.link); if (!output->recorder) { + if (output->format != GBM_FORMAT_XRGB8888) { + weston_log("failed to start vaapi recorder: " + "output format not supported\n"); + return; + } + width = output->base.current_mode->width; height = output->base.current_mode->height; @@ -2590,13 +2706,7 @@ recorder_binding(struct weston_seat *seat, uint32_t time, uint32_t key, weston_log("[libva recorder] initialized\n"); } else { - vaapi_recorder_destroy(output->recorder); - output->recorder = NULL; - - output->base.disable_planes--; - - wl_list_remove(&output->recorder_frame_listener.link); - weston_log("[libva recorder] done\n"); + recorder_destroy(output); } } #else @@ -2637,8 +2747,11 @@ switch_to_gl_renderer(struct drm_compositor *c) assert(0); } - wl_list_for_each(output, &c->base.output_list, base.link) + wl_list_for_each(output, &c->base.output_list, base.link) { + /* Workaround page flip not setting the tiling mode on BYT */ + output->force_modeset = 1; drm_output_init_egl(output, c); + } c->use_pixman = 0; } @@ -2652,6 +2765,23 @@ renderer_switch_binding(struct weston_seat *seat, uint32_t time, uint32_t key, switch_to_gl_renderer(c); } +static int +create_seats(struct drm_compositor *ec, int connector, + struct udev_device *drm_device) +{ + struct udev_seat *seat = udev_seat_get_named(&ec->base, ec->main_seat); + if (seat && udev_input_init(&seat->input, &ec->base, + ec->udev, ec->main_seat) < 0) { + weston_log("failed to create input devices\n"); + return -1; + } + + if (create_outputs(ec, connector, drm_device) < 0) + return -1; + + return 0; +} + static struct weston_compositor * drm_compositor_create(struct wl_display *display, struct drm_parameters *param, @@ -2663,7 +2793,6 @@ drm_compositor_create(struct wl_display *display, struct udev_device *drm_device; struct wl_event_loop *loop; const char *path; - char *s; uint32_t key; weston_log("initializing drm backend\n"); @@ -2677,20 +2806,10 @@ drm_compositor_create(struct wl_display *display, ec->sprites_are_broken = 1; section = weston_config_get_section(config, "core", NULL, NULL); - weston_config_section_get_string(section, - "gbm-format", &s, "xrgb8888"); - if (strcmp(s, "xrgb8888") == 0) - ec->format = GBM_FORMAT_XRGB8888; - else if (strcmp(s, "rgb565") == 0) - ec->format = GBM_FORMAT_RGB565; - else if (strcmp(s, "xrgb2101010") == 0) - ec->format = GBM_FORMAT_XRGB2101010; - else { - weston_log("fatal: unrecognized pixel format: %s\n", s); - free(s); + if (get_gbm_format_from_section(section, + GBM_FORMAT_XRGB8888, + &ec->format) == -1) goto err_base; - } - free(s); ec->use_pixman = param->use_pixman; @@ -2756,18 +2875,18 @@ drm_compositor_create(struct wl_display *display, wl_list_init(&ec->sprite_list); create_sprites(ec); - if (create_outputs(ec, param->connector, drm_device) < 0) { + ec->main_seat = strdup(param->seat_id); + if (create_seats(ec, param->connector, drm_device) < 0) { weston_log("failed to create output for %s\n", path); goto err_sprite; } - path = NULL; + /* A this point we have some idea of whether or not we have a working + * cursor plane. */ + if (!ec->cursors_are_broken) + ec->base.capabilities |= WESTON_CAP_CURSOR_PLANE; - if (udev_input_init(&ec->input, - &ec->base, ec->udev, param->seat_id) < 0) { - weston_log("failed to create input devices\n"); - goto err_sprite; - } + path = NULL; loop = wl_display_get_event_loop(ec->base.wl_display); ec->drm_source = @@ -2811,7 +2930,6 @@ err_udev_monitor: udev_monitor_unref(ec->udev_monitor); err_drm_source: wl_event_source_remove(ec->drm_source); - udev_input_destroy(&ec->input); err_sprite: ec->base.renderer->destroy(&ec->base); gbm_device_destroy(ec->gbm); @@ -2825,6 +2943,7 @@ err_udev: err_compositor: weston_compositor_shutdown(&ec->base); err_base: + free(ec->main_seat); free(ec); return NULL; }