[PATCH 3/6] add existing fullscreen rendering part
juan.j.zhao at linux.intel.com
juan.j.zhao at linux.intel.com
Fri Dec 30 12:21:23 PST 2011
From: Juan Zhao <juan.j.zhao at linux.intel.com>
we will restore the mode and repaint the surfaces if the output is
changing back from fullscreen mode.
---
compositor/compositor.c | 92 +++++++++++++++++++++++++++++++++++++----------
compositor/compositor.h | 2 +
2 files changed, 75 insertions(+), 19 deletions(-)
diff --git a/compositor/compositor.c b/compositor/compositor.c
index 23c1054..d935ebc 100644
--- a/compositor/compositor.c
+++ b/compositor/compositor.c
@@ -75,6 +75,35 @@ sigchld_handler(int signal_number, void *data)
return 1;
}
+static int
+wlsc_output_restore_mode (struct wlsc_output *output)
+{
+ int ret;
+ char saved_mode[16];
+
+ if(!output->saved_mode ||
+ (output->saved_mode->width == output->current->width &&
+ output->saved_mode->height == output->current->height))
+ return 0;
+ memset(saved_mode, 0, sizeof saved_mode);
+ sprintf(saved_mode, "%dx%d",
+ output->saved_mode->width, output->saved_mode->height);
+
+ if (output->set_mode) {
+ ret = output->set_mode(output, saved_mode);
+ if (ret!=-1) {
+ output->saved_mode = NULL;
+ }
+ }
+ else {
+ fprintf(stderr, "Can't restore display mode\n");
+ ret = -1;
+ }
+
+ printf("set mode '%s', ret %d\n", saved_mode, ret);
+ return ret;
+}
+
WL_EXPORT void
wlsc_watch_process(struct wlsc_process *process)
{
@@ -325,6 +354,7 @@ wlsc_surface_set_fullscreen( struct wlsc_output *output,
switch(surface->fs_support.fs_method) {
case WLSC_SURFACE_FULLSCREEN_NONE:
+ output->fs_dirty = 1;
wlsc_surface_damage(surface);
break;
case WLSC_SURFACE_FULLSCREEN_FORCE:
@@ -333,7 +363,9 @@ wlsc_surface_set_fullscreen( struct wlsc_output *output,
return 0;
memset(mode, 0, sizeof(mode));
sprintf(mode, "%dx%d",surface->width,surface->height);
+ output->saved_mode = output->current;
if (!output->set_mode) {
+ output->saved_mode = NULL;
fprintf(stderr,
"set_mode not implemented, \
fallback to FILL method\n");
@@ -345,6 +377,8 @@ wlsc_surface_set_fullscreen( struct wlsc_output *output,
break;
} else {
/*did not find the mode, fall back */
+ output->current = output->saved_mode;
+ output->saved_mode = NULL;
sprintf(mode, "%dx%d",
output->current->width,
output->current->height);
@@ -355,6 +389,7 @@ wlsc_surface_set_fullscreen( struct wlsc_output *output,
}
case WLSC_SURFACE_FULLSCREEN_FILL:
/*make it on the center at first*/
+ output->fs_dirty = 1;
wlsc_surface_center_on_output(surface, output);
wlsc_surface_damage(surface);
break;
@@ -855,25 +890,44 @@ wlsc_output_repaint(struct wlsc_output *output)
}
wlsc_surface_draw(es, output, &total_damage);
} else {
- glViewport(0, 0,
- output->current->width,
- output->current->height);
- wl_list_for_each(es, &ec->surface_list, link) {
- pixman_region32_copy(&es->damage,
- &total_damage);
- pixman_region32_subtract(&total_damage,
- &total_damage,
- &es->opaque);
- }
- wl_list_for_each_reverse(es, &ec->surface_list, link) {
- pixman_region32_init(&repaint);
- pixman_region32_intersect(&repaint,
- &output->region,
- &es->damage);
- wlsc_surface_draw(es, output, &repaint);
- pixman_region32_subtract(&es->damage,
- &es->damage,
- &output->region);
+ if( output->saved_mode &&
+ (output->saved_mode->width!=output->current->width ||
+ output->saved_mode->height!=output->current->height) ) {
+ wlsc_output_restore_mode(output);
+ output->saved_mode = NULL;
+ output->fs_dirty = NULL;
+ output->prepare_render(output);
+ glViewport( 0, 0,
+ (GLint) output->current->width,
+ (GLint) output->current->height);
+ glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
+ wlsc_output_damage(output);
+ wlsc_output_repaint(output);
+ } else if (output->fs_dirty) {
+ output->fs_dirty = NULL;
+ wlsc_output_damage(output);
+ wlsc_output_repaint(output);
+ } else {
+ glViewport(0, 0,
+ output->current->width,
+ output->current->height);
+ wl_list_for_each(es, &ec->surface_list, link) {
+ pixman_region32_copy(&es->damage,
+ &total_damage);
+ pixman_region32_subtract(&total_damage,
+ &total_damage,
+ &es->opaque);
+ }
+ wl_list_for_each_reverse(es, &ec->surface_list, link) {
+ pixman_region32_init(&repaint);
+ pixman_region32_intersect(&repaint,
+ &output->region,
+ &es->damage);
+ wlsc_surface_draw(es, output, &repaint);
+ pixman_region32_subtract(&es->damage,
+ &es->damage,
+ &output->region);
+ }
}
}
diff --git a/compositor/compositor.h b/compositor/compositor.h
index e7aca1a..c9a5cae 100644
--- a/compositor/compositor.h
+++ b/compositor/compositor.h
@@ -80,11 +80,13 @@ struct wlsc_output {
uint32_t flags;
int repaint_needed;
int repaint_scheduled;
+ uint32_t fs_dirty;
char *make, *model;
uint32_t subpixel;
struct wlsc_mode *current;
+ struct wlsc_mode *saved_mode;
struct wl_list mode_list;
struct wl_buffer *scanout_buffer;
struct wl_listener scanout_buffer_destroy_listener;
--
1.7.2.2
More information about the wayland-devel
mailing list