[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