[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