diff --git a/compositor/compositor-drm.c b/compositor/compositor-drm.c index 4133c197..ecc074f4 100644 --- a/compositor/compositor-drm.c +++ b/compositor/compositor-drm.c @@ -64,6 +64,8 @@ struct drm_output { EGLImageKHR image[2]; uint32_t current; + struct wlsc_surface *scanout_surface; + uint32_t 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_compositor *c = (struct drm_compositor *) output->base.compositor; - int ret; uint32_t fb_id = 0; if (drm_output_prepare_render(&output->base)) @@ -99,22 +100,8 @@ drm_output_present(struct wlsc_output *output_base) output->current ^= 1; - if (output->base.scanout_surface) { - EGLint handle, stride; - - 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); - + if (output->scanout_surface != NULL) { + output->scanout_surface = NULL; fb_id = output->fs_surf_fb_id; } else { fb_id = output->fb_id[output->current ^ 1]; @@ -151,8 +138,8 @@ page_flip_handler(int fd, unsigned int frame, } static int -drm_output_image_is_scanoutable(struct wlsc_output *output_base, - EGLImageKHR image) +drm_output_prepare_scanout_surface(struct wlsc_output *output_base, + struct wlsc_surface *es) { struct drm_output *output = (struct drm_output *) output_base; struct drm_compositor *c = @@ -161,22 +148,28 @@ drm_output_image_is_scanoutable(struct wlsc_output *output_base, int ret; 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); + if (handle == 0) + return -1; + ret = drmModeAddFB(c->drm.fd, output->base.width, output->base.height, - 32, 32, stride, handle, - &fb_id); + 32, 32, stride, handle, &fb_id); + if (ret) - return 0; + return -1; - /* FIXME: change interface to keep this fb_id, - * to be used directly in next pageflip? */ - if (fb_id) - drmModeRmFB(c->drm.fd, fb_id); + output->fs_surf_fb_id = fb_id; + output->scanout_surface = es; - return fb_id != 0; + return 0; } static int @@ -412,9 +405,11 @@ create_output_for_connector(struct drm_compositor *ec, return -1; } + output->scanout_surface = NULL; output->base.prepare_render = drm_output_prepare_render; 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; wl_list_insert(ec->base.output_list.prev, &output->base.link); diff --git a/compositor/compositor-wayland.c b/compositor/compositor-wayland.c index f457570a..b2ec7c1c 100644 --- a/compositor/compositor-wayland.c +++ b/compositor/compositor-wayland.c @@ -197,10 +197,10 @@ wayland_output_present(struct wlsc_output *output_base) } static int -wayland_output_image_is_scanoutable(struct wlsc_output *output_base, - EGLImageKHR image) +wayland_output_prepare_scanout_surface(struct wlsc_output *output_base, + struct wlsc_surface *es) { - return 0; + return -1; } static int @@ -260,7 +260,8 @@ wayland_compositor_create_output(struct wayland_compositor *c, output->base.prepare_render = wayland_output_prepare_render; 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; wl_list_insert(c->base.output_list.prev, &output->base.link); diff --git a/compositor/compositor-x11.c b/compositor/compositor-x11.c index 47843d4b..04eca071 100644 --- a/compositor/compositor-x11.c +++ b/compositor/compositor-x11.c @@ -192,10 +192,10 @@ x11_output_present(struct wlsc_output *output_base) } static int -x11_output_image_is_scanoutable(struct wlsc_output *output_base, - EGLImageKHR image) +x11_output_prepare_scanout_surface(struct wlsc_output *output_base, + struct wlsc_surface *es) { - return 0; + return -1; } 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.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; wl_list_insert(c->base.output_list.prev, &output->base.link); diff --git a/compositor/compositor.c b/compositor/compositor.c index 5ff7a45c..333ab220 100644 --- a/compositor/compositor.c +++ b/compositor/compositor.c @@ -550,21 +550,6 @@ wlsc_output_finish_frame(struct wlsc_output *output, int msecs) 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 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) using_hardware_cursor = 0; - output->scanout_surface = NULL; - es = container_of(ec->surface_list.next, struct wlsc_surface, link); if (es->map_type == WLSC_SURFACE_MAP_FULLSCREEN && es->fullscreen_output == output) { if (es->visual == &ec->compositor.rgb_visual && - using_hardware_cursor && - wlsc_surface_is_scanoutable(es, output)) { - output->scanout_surface = es; - /* we're drawing nothing now, draw the damages later */ - pixman_region32_union(&ec->damage_region, - &ec->damage_region, - &total_damage); - } else { - if (es->width < output->width || - es->height < output->height) - glClear(GL_COLOR_BUFFER_BIT); - wlsc_surface_draw(es, output, &total_damage); + using_hardware_cursor) { + if (output->prepare_scanout_surface(output, es) == 0) { + /* We're drawing nothing now, + * draw the damaged regions later. */ + pixman_region32_union(&ec->damage_region, + &ec->damage_region, + &total_damage); + return; + } } + + if (es->width < output->width || + es->height < output->height) + glClear(GL_COLOR_BUFFER_BIT); + wlsc_surface_draw(es, output, &total_damage); } else { wl_list_for_each(es, &ec->surface_list, link) { if (es->visual != &ec->compositor.rgb_visual) diff --git a/compositor/compositor.h b/compositor/compositor.h index 84c01397..6a7991cf 100644 --- a/compositor/compositor.h +++ b/compositor/compositor.h @@ -51,12 +51,10 @@ struct wlsc_output { int repaint_needed; int finished; - struct wlsc_surface *scanout_surface; - int (*prepare_render)(struct wlsc_output *output); int (*present)(struct wlsc_output *output); - int (*image_is_scanoutable)(struct wlsc_output *output, - EGLImageKHR image); + int (*prepare_scanout_surface)(struct wlsc_output *output, + struct wlsc_surface *es); int (*set_hardware_cursor)(struct wlsc_output *output, struct wl_input_device *input); };