[PATCH 2/6] add set_fullscreen for surface

juan.j.zhao at linux.intel.com juan.j.zhao at linux.intel.com
Fri Dec 30 12:21:22 PST 2011


From: Juan Zhao <juan.j.zhao at linux.intel.com>

add set_fullscreen method for surface and upate the fullscreen rendering part
---
 compositor/compositor.c |   83 ++++++++++++++++++++++++++++++++++++++++-------
 compositor/compositor.h |    5 +++
 2 files changed, 76 insertions(+), 12 deletions(-)

diff --git a/compositor/compositor.c b/compositor/compositor.c
index bef6867..23c1054 100644
--- a/compositor/compositor.c
+++ b/compositor/compositor.c
@@ -227,6 +227,7 @@ wlsc_surface_create(struct wlsc_compositor *compositor,
 	surface->height = height;
 	surface->alpha = 255;
 
+	surface->fs_support.fullscreen_output = NULL;
 	surface->fs_support.fs_method = WLSC_SURFACE_FULLSCREEN_NONE;
 	surface->buffer = NULL;
 	surface->output = NULL;
@@ -316,6 +317,54 @@ wlsc_surface_center_on_output( struct wlsc_surface *surface,
 	surface->y = output->y + (mode->height - surface->height) / 2;
 }
 
+int
+wlsc_surface_set_fullscreen( struct wlsc_output *output,
+			     struct wlsc_surface *surface)
+{
+	char mode[16];
+
+	switch(surface->fs_support.fs_method) {
+		case WLSC_SURFACE_FULLSCREEN_NONE:
+			wlsc_surface_damage(surface);
+			break;
+		case WLSC_SURFACE_FULLSCREEN_FORCE:
+			if(output->current->width == surface->width &&
+			    output->current->height == surface->height)
+				return 0;
+			memset(mode, 0, sizeof(mode));
+			sprintf(mode, "%dx%d",surface->width,surface->height);
+			if (!output->set_mode) {
+				fprintf(stderr,
+					"set_mode not implemented,   \
+					 fallback to FILL method\n");
+			} else if(output->set_mode(output, mode) == 0 ) {
+				wlsc_surface_damage(surface);
+				fprintf(stderr,
+					"mode setting error,       \
+					 fallback to FILL method\n");
+				break;
+			} else {
+				/*did not find the mode, fall back */
+				sprintf(mode, "%dx%d",
+					output->current->width,
+					output->current->height);
+				output->set_mode(output, mode);
+				fprintf(stderr,
+					"failed to set mode,         \
+					 fallback to FILL method\n");
+			}
+		case WLSC_SURFACE_FULLSCREEN_FILL:
+			/*make it on the center at first*/
+			wlsc_surface_center_on_output(surface, output);
+			wlsc_surface_damage(surface);
+			break;
+		default:
+			break;
+	}
+
+	return 0;
+}
+
 WL_EXPORT uint32_t
 wlsc_compositor_get_time(void)
 {
@@ -539,7 +588,7 @@ wlsc_surface_draw(struct wlsc_surface *es,
 	pixman_region32_init_rect(&repaint,
 				  es->x, es->y, es->width, es->height);
 	pixman_region32_intersect(&repaint, &repaint, clip);
-	if (!pixman_region32_not_empty(&repaint))
+	if (!pixman_region32_not_empty(&repaint) || !ec)
 		return;
 
 	switch (es->visual) {
@@ -763,8 +812,6 @@ wlsc_output_repaint(struct wlsc_output *output)
 
 	output->prepare_render(output);
 
-	glViewport(0, 0, output->current->width, output->current->height);
-
 	glUseProgram(ec->texture_shader.program);
 	glUniformMatrix4fv(ec->texture_shader.proj_uniform,
 			   1, GL_FALSE, output->matrix.d);
@@ -797,24 +844,36 @@ wlsc_output_repaint(struct wlsc_output *output)
 		/* We're drawing nothing, just let the damage accumulate */
 		return;
 
-	if (es->fs_support.fullscreen_output == output) {
-		if (es->width < output->current->width ||
-		    es->height < output->current->height)
-			glClear(GL_COLOR_BUFFER_BIT);
+	if (es->fs_support.fullscreen_output == output ) {
+		if (es->width != output->current->width ||
+		     es->height != output->current->height) {
+			wlsc_surface_set_fullscreen(output, es);
+			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_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);
+			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,
+			pixman_region32_intersect(&repaint,
+						  &output->region,
 						  &es->damage);
 			wlsc_surface_draw(es, output, &repaint);
 			pixman_region32_subtract(&es->damage,
-						 &es->damage, &output->region);
+						 &es->damage,
+						 &output->region);
 		}
 	}
 
diff --git a/compositor/compositor.h b/compositor/compositor.h
index 9ba107d..e7aca1a 100644
--- a/compositor/compositor.h
+++ b/compositor/compositor.h
@@ -98,6 +98,7 @@ struct wlsc_output {
 	int (*set_hardware_cursor)(struct wlsc_output *output,
 				   struct wlsc_input_device *input);
 	void (*destroy)(struct wlsc_output *output);
+	int (*set_mode)(struct wlsc_output *output_base, char *mode);
 };
 
 struct wlsc_input_device {
@@ -389,6 +390,10 @@ wlsc_surface_damage_rectangle(struct wlsc_surface *surface,
 			      int32_t x, int32_t y,
 			      int32_t width, int32_t height);
 
+int
+wlsc_surface_set_fullscreen(struct wlsc_output *output,
+			    struct wlsc_surface *surface);
+
 struct wlsc_surface *
 pick_surface(struct wl_input_device *device, int32_t *sx, int32_t *sy);
 
-- 
1.7.2.2



More information about the wayland-devel mailing list