Optimize fullscreen scanout abit

Use the drm fb_id used for the scanout-test
as well for the corresponding pageflip.

Move most of the scanout details into compositor-drm.
dev
Benjamin Franzke 14 years ago
parent 218c0349ed
commit 66aa235b4c
  1. 53
      compositor/compositor-drm.c
  2. 9
      compositor/compositor-wayland.c
  3. 9
      compositor/compositor-x11.c
  4. 43
      compositor/compositor.c
  5. 6
      compositor/compositor.h

@ -64,6 +64,8 @@ struct drm_output {
EGLImageKHR image[2]; EGLImageKHR image[2];
uint32_t current; uint32_t current;
struct wlsc_surface *scanout_surface;
uint32_t fs_surf_fb_id; uint32_t fs_surf_fb_id;
uint32_t pending_fs_surf_fb_id; uint32_t pending_fs_surf_fb_id;
}; };
@ -90,7 +92,6 @@ drm_output_present(struct wlsc_output *output_base)
struct drm_output *output = (struct drm_output *) output_base; struct drm_output *output = (struct drm_output *) output_base;
struct drm_compositor *c = struct drm_compositor *c =
(struct drm_compositor *) output->base.compositor; (struct drm_compositor *) output->base.compositor;
int ret;
uint32_t fb_id = 0; uint32_t fb_id = 0;
if (drm_output_prepare_render(&output->base)) if (drm_output_prepare_render(&output->base))
@ -99,22 +100,8 @@ drm_output_present(struct wlsc_output *output_base)
output->current ^= 1; output->current ^= 1;
if (output->base.scanout_surface) { if (output->scanout_surface != NULL) {
EGLint handle, stride; output->scanout_surface = NULL;
eglExportDRMImageMESA(c->base.display,
output->base.scanout_surface->image,
NULL, &handle, &stride);
ret = drmModeAddFB(c->drm.fd,
output->base.width, output->base.height,
32, 32, stride, handle,
&output->fs_surf_fb_id);
if (ret)
return -1;
printf("pageflip to fullscreen buffer: %d\n", handle);
fb_id = output->fs_surf_fb_id; fb_id = output->fs_surf_fb_id;
} else { } else {
fb_id = output->fb_id[output->current ^ 1]; fb_id = output->fb_id[output->current ^ 1];
@ -151,8 +138,8 @@ page_flip_handler(int fd, unsigned int frame,
} }
static int static int
drm_output_image_is_scanoutable(struct wlsc_output *output_base, drm_output_prepare_scanout_surface(struct wlsc_output *output_base,
EGLImageKHR image) struct wlsc_surface *es)
{ {
struct drm_output *output = (struct drm_output *) output_base; struct drm_output *output = (struct drm_output *) output_base;
struct drm_compositor *c = struct drm_compositor *c =
@ -161,22 +148,28 @@ drm_output_image_is_scanoutable(struct wlsc_output *output_base,
int ret; int ret;
uint32_t fb_id = 0; uint32_t fb_id = 0;
eglExportDRMImageMESA(c->base.display, image, if (es->width != output->base.width ||
es->height != output->base.height ||
es->image == EGL_NO_IMAGE_KHR)
return -1;
eglExportDRMImageMESA(c->base.display, es->image,
NULL, &handle, &stride); NULL, &handle, &stride);
if (handle == 0)
return -1;
ret = drmModeAddFB(c->drm.fd, ret = drmModeAddFB(c->drm.fd,
output->base.width, output->base.height, output->base.width, output->base.height,
32, 32, stride, handle, 32, 32, stride, handle, &fb_id);
&fb_id);
if (ret) if (ret)
return 0; return -1;
/* FIXME: change interface to keep this fb_id, output->fs_surf_fb_id = fb_id;
* to be used directly in next pageflip? */ output->scanout_surface = es;
if (fb_id)
drmModeRmFB(c->drm.fd, fb_id);
return fb_id != 0; return 0;
} }
static int static int
@ -412,9 +405,11 @@ create_output_for_connector(struct drm_compositor *ec,
return -1; return -1;
} }
output->scanout_surface = NULL;
output->base.prepare_render = drm_output_prepare_render; output->base.prepare_render = drm_output_prepare_render;
output->base.present = drm_output_present; output->base.present = drm_output_present;
output->base.image_is_scanoutable = drm_output_image_is_scanoutable; output->base.prepare_scanout_surface =
drm_output_prepare_scanout_surface;
output->base.set_hardware_cursor = drm_output_set_cursor; output->base.set_hardware_cursor = drm_output_set_cursor;
wl_list_insert(ec->base.output_list.prev, &output->base.link); wl_list_insert(ec->base.output_list.prev, &output->base.link);

@ -197,10 +197,10 @@ wayland_output_present(struct wlsc_output *output_base)
} }
static int static int
wayland_output_image_is_scanoutable(struct wlsc_output *output_base, wayland_output_prepare_scanout_surface(struct wlsc_output *output_base,
EGLImageKHR image) struct wlsc_surface *es)
{ {
return 0; return -1;
} }
static int static int
@ -260,7 +260,8 @@ wayland_compositor_create_output(struct wayland_compositor *c,
output->base.prepare_render = wayland_output_prepare_render; output->base.prepare_render = wayland_output_prepare_render;
output->base.present = wayland_output_present; output->base.present = wayland_output_present;
output->base.image_is_scanoutable = wayland_output_image_is_scanoutable; output->base.prepare_scanout_surface =
wayland_output_prepare_scanout_surface;
output->base.set_hardware_cursor = wayland_output_set_cursor; output->base.set_hardware_cursor = wayland_output_set_cursor;
wl_list_insert(c->base.output_list.prev, &output->base.link); wl_list_insert(c->base.output_list.prev, &output->base.link);

@ -192,10 +192,10 @@ x11_output_present(struct wlsc_output *output_base)
} }
static int static int
x11_output_image_is_scanoutable(struct wlsc_output *output_base, x11_output_prepare_scanout_surface(struct wlsc_output *output_base,
EGLImageKHR image) struct wlsc_surface *es)
{ {
return 0; return -1;
} }
static int static int
@ -354,7 +354,8 @@ x11_compositor_create_output(struct x11_compositor *c, int width, int height)
output->base.prepare_render = x11_output_prepare_render; output->base.prepare_render = x11_output_prepare_render;
output->base.present = x11_output_present; output->base.present = x11_output_present;
output->base.image_is_scanoutable = x11_output_image_is_scanoutable; output->base.prepare_scanout_surface =
x11_output_prepare_scanout_surface;
output->base.set_hardware_cursor = x11_output_set_cursor; output->base.set_hardware_cursor = x11_output_set_cursor;
wl_list_insert(c->base.output_list.prev, &output->base.link); wl_list_insert(c->base.output_list.prev, &output->base.link);

@ -550,21 +550,6 @@ wlsc_output_finish_frame(struct wlsc_output *output, int msecs)
compositor->repaint_on_timeout = 1; compositor->repaint_on_timeout = 1;
} }
static int
wlsc_surface_is_scanoutable(struct wlsc_surface *es,
struct wlsc_output *output)
{
if (es->width != output->width ||
es->height != output->height ||
es->image == NULL)
return 0;
if (!output->image_is_scanoutable(output, es->image))
return 0;
return 1;
}
static void static void
wlsc_output_repaint(struct wlsc_output *output) wlsc_output_repaint(struct wlsc_output *output)
{ {
@ -597,25 +582,25 @@ wlsc_output_repaint(struct wlsc_output *output)
if (output->set_hardware_cursor(output, ec->input_device) < 0) if (output->set_hardware_cursor(output, ec->input_device) < 0)
using_hardware_cursor = 0; using_hardware_cursor = 0;
output->scanout_surface = NULL;
es = container_of(ec->surface_list.next, struct wlsc_surface, link); es = container_of(ec->surface_list.next, struct wlsc_surface, link);
if (es->map_type == WLSC_SURFACE_MAP_FULLSCREEN && if (es->map_type == WLSC_SURFACE_MAP_FULLSCREEN &&
es->fullscreen_output == output) { es->fullscreen_output == output) {
if (es->visual == &ec->compositor.rgb_visual && if (es->visual == &ec->compositor.rgb_visual &&
using_hardware_cursor && using_hardware_cursor) {
wlsc_surface_is_scanoutable(es, output)) { if (output->prepare_scanout_surface(output, es) == 0) {
output->scanout_surface = es; /* We're drawing nothing now,
/* we're drawing nothing now, draw the damages later */ * draw the damaged regions later. */
pixman_region32_union(&ec->damage_region, pixman_region32_union(&ec->damage_region,
&ec->damage_region, &ec->damage_region,
&total_damage); &total_damage);
} else { return;
if (es->width < output->width || }
es->height < output->height)
glClear(GL_COLOR_BUFFER_BIT);
wlsc_surface_draw(es, output, &total_damage);
} }
if (es->width < output->width ||
es->height < output->height)
glClear(GL_COLOR_BUFFER_BIT);
wlsc_surface_draw(es, output, &total_damage);
} else { } else {
wl_list_for_each(es, &ec->surface_list, link) { wl_list_for_each(es, &ec->surface_list, link) {
if (es->visual != &ec->compositor.rgb_visual) if (es->visual != &ec->compositor.rgb_visual)

@ -51,12 +51,10 @@ struct wlsc_output {
int repaint_needed; int repaint_needed;
int finished; int finished;
struct wlsc_surface *scanout_surface;
int (*prepare_render)(struct wlsc_output *output); int (*prepare_render)(struct wlsc_output *output);
int (*present)(struct wlsc_output *output); int (*present)(struct wlsc_output *output);
int (*image_is_scanoutable)(struct wlsc_output *output, int (*prepare_scanout_surface)(struct wlsc_output *output,
EGLImageKHR image); struct wlsc_surface *es);
int (*set_hardware_cursor)(struct wlsc_output *output, int (*set_hardware_cursor)(struct wlsc_output *output,
struct wl_input_device *input); struct wl_input_device *input);
}; };

Loading…
Cancel
Save