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.
This commit is contained in:
+25
-30
@@ -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 -1;
|
||||||
|
|
||||||
|
output->fs_surf_fb_id = fb_id;
|
||||||
|
output->scanout_surface = es;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* FIXME: change interface to keep this fb_id,
|
|
||||||
* to be used directly in next pageflip? */
|
|
||||||
if (fb_id)
|
|
||||||
drmModeRmFB(c->drm.fd, fb_id);
|
|
||||||
|
|
||||||
return fb_id != 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);
|
||||||
|
|||||||
+8
-23
@@ -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 ||
|
if (es->width < output->width ||
|
||||||
es->height < output->height)
|
es->height < output->height)
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
wlsc_surface_draw(es, output, &total_damage);
|
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);
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user