EGLImageKHR image[2];
uint32_t current;
+ struct wlsc_surface *scanout_surface;
+
uint32_t fs_surf_fb_id;
uint32_t pending_fs_surf_fb_id;
};
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))
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];
}
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 =
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
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);
}
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
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);
}
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
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);
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)
{
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)
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);
};