diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c index 52b5dd70c..bcf8962f5 100644 --- a/libweston/compositor-drm.c +++ b/libweston/compositor-drm.c @@ -4109,7 +4109,8 @@ drm_output_init_pixman(struct drm_output *output, struct drm_backend *b) goto err; } - if (pixman_renderer_output_create(&output->base) < 0) + if (pixman_renderer_output_create(&output->base, + PIXMAN_RENDERER_OUTPUT_USE_SHADOW) < 0) goto err; pixman_region32_init_rect(&output->previous_damage, diff --git a/libweston/compositor-fbdev.c b/libweston/compositor-fbdev.c index de40c2191..a78f6fab6 100644 --- a/libweston/compositor-fbdev.c +++ b/libweston/compositor-fbdev.c @@ -511,7 +511,8 @@ fbdev_output_enable(struct weston_output *base) output->base.start_repaint_loop = fbdev_output_start_repaint_loop; output->base.repaint = fbdev_output_repaint; - if (pixman_renderer_output_create(&output->base) < 0) + if (pixman_renderer_output_create(&output->base, + PIXMAN_RENDERER_OUTPUT_USE_SHADOW) < 0) goto out_hw_surface; loop = wl_display_get_event_loop(backend->compositor->wl_display); diff --git a/libweston/compositor-headless.c b/libweston/compositor-headless.c index 6cb4f2066..61a5bd93e 100644 --- a/libweston/compositor-headless.c +++ b/libweston/compositor-headless.c @@ -172,7 +172,8 @@ headless_output_enable(struct weston_output *base) output->image_buf, output->base.current_mode->width * 4); - if (pixman_renderer_output_create(&output->base) < 0) + if (pixman_renderer_output_create(&output->base, + PIXMAN_RENDERER_OUTPUT_USE_SHADOW) < 0) goto err_renderer; pixman_renderer_output_set_buffer(&output->base, diff --git a/libweston/compositor-rdp.c b/libweston/compositor-rdp.c index 693f136a0..fd0651afb 100644 --- a/libweston/compositor-rdp.c +++ b/libweston/compositor-rdp.c @@ -460,7 +460,7 @@ rdp_switch_mode(struct weston_output *output, struct weston_mode *target_mode) output->current_mode->flags |= WL_OUTPUT_MODE_CURRENT; pixman_renderer_output_destroy(output); - pixman_renderer_output_create(output); + pixman_renderer_output_create(output, PIXMAN_RENDERER_OUTPUT_USE_SHADOW); new_shadow_buffer = pixman_image_create_bits(PIXMAN_x8r8g8b8, target_mode->width, target_mode->height, 0, target_mode->width * 4); @@ -546,7 +546,8 @@ rdp_output_enable(struct weston_output *base) return -1; } - if (pixman_renderer_output_create(&output->base) < 0) { + if (pixman_renderer_output_create(&output->base, + PIXMAN_RENDERER_OUTPUT_USE_SHADOW) < 0) { pixman_image_unref(output->shadow_surface); return -1; } diff --git a/libweston/compositor-wayland.c b/libweston/compositor-wayland.c index 2473f0879..56ed474a5 100644 --- a/libweston/compositor-wayland.c +++ b/libweston/compositor-wayland.c @@ -782,7 +782,8 @@ cleanup_window: static int wayland_output_init_pixman_renderer(struct wayland_output *output) { - return pixman_renderer_output_create(&output->base); + return pixman_renderer_output_create(&output->base, + PIXMAN_RENDERER_OUTPUT_USE_SHADOW); } static void diff --git a/libweston/compositor-x11.c b/libweston/compositor-x11.c index 78b0d7c60..4a9d068f6 100644 --- a/libweston/compositor-x11.c +++ b/libweston/compositor-x11.c @@ -849,7 +849,8 @@ x11_output_switch_mode(struct weston_output *base, struct weston_mode *mode) return -1; } - if (pixman_renderer_output_create(&output->base) < 0) { + if (pixman_renderer_output_create(&output->base, + PIXMAN_RENDERER_OUTPUT_USE_SHADOW) < 0) { weston_log("Failed to create pixman renderer for output\n"); x11_output_deinit_shm(b, output); return -1; @@ -1021,7 +1022,8 @@ x11_output_enable(struct weston_output *base) weston_log("Failed to initialize SHM for the X11 output\n"); goto err; } - if (pixman_renderer_output_create(&output->base) < 0) { + if (pixman_renderer_output_create(&output->base, + PIXMAN_RENDERER_OUTPUT_USE_SHADOW) < 0) { weston_log("Failed to create pixman renderer for output\n"); x11_output_deinit_shm(b, output); goto err; diff --git a/libweston/pixman-renderer.c b/libweston/pixman-renderer.c index cf43b15d2..1ea275b49 100644 --- a/libweston/pixman-renderer.c +++ b/libweston/pixman-renderer.c @@ -337,13 +337,19 @@ repaint_region(struct weston_view *ev, struct weston_output *output, struct pixman_surface_state *ps = get_surface_state(ev->surface); struct pixman_output_state *po = get_output_state(output); struct weston_buffer_viewport *vp = &ev->surface->buffer_viewport; + pixman_image_t *target_image; pixman_transform_t transform; pixman_filter_t filter; pixman_image_t *mask_image; pixman_color_t mask = { 0, }; - /* Clip rendering to the damaged output region */ - pixman_image_set_clip_region32(po->shadow_image, repaint_output); + if (po->shadow_image) + target_image = po->shadow_image; + else + target_image = po->hw_buffer; + + /* Clip rendering to the damaged output region */ + pixman_image_set_clip_region32(target_image, repaint_output); pixman_renderer_compute_transform(&transform, ev, output); @@ -363,11 +369,11 @@ repaint_region(struct weston_view *ev, struct weston_output *output, } if (source_clip) - composite_clipped(ps->image, mask_image, po->shadow_image, + composite_clipped(ps->image, mask_image, target_image, &transform, filter, source_clip); else composite_whole(pixman_op, ps->image, mask_image, - po->shadow_image, &transform, filter); + target_image, &transform, filter); if (mask_image) pixman_image_unref(mask_image); @@ -379,14 +385,14 @@ repaint_region(struct weston_view *ev, struct weston_output *output, pixman_image_composite32(PIXMAN_OP_OVER, pr->debug_color, /* src */ NULL /* mask */, - po->shadow_image, /* dest */ + target_image, /* dest */ 0, 0, /* src_x, src_y */ 0, 0, /* mask_x, mask_y */ 0, 0, /* dest_x, dest_y */ - pixman_image_get_width (po->shadow_image), /* width */ - pixman_image_get_height (po->shadow_image) /* height */); + pixman_image_get_width (target_image), /* width */ + pixman_image_get_height (target_image) /* height */); - pixman_image_set_clip_region32 (po->shadow_image, NULL); + pixman_image_set_clip_region32(target_image, NULL); } static void @@ -575,9 +581,12 @@ pixman_renderer_repaint_output(struct weston_output *output, pixman_region32_copy(&hw_damage, output_damage); } - repaint_surfaces(output, output_damage); - - copy_to_hw_buffer(output, &hw_damage); + if (po->shadow_image) { + repaint_surfaces(output, output_damage); + copy_to_hw_buffer(output, &hw_damage); + } else { + repaint_surfaces(output, &hw_damage); + } pixman_region32_fini(&hw_damage); pixman_region32_copy(&output->previous_damage, output_damage); @@ -902,7 +911,7 @@ pixman_renderer_output_set_hw_extra_damage(struct weston_output *output, } WL_EXPORT int -pixman_renderer_output_create(struct weston_output *output) +pixman_renderer_output_create(struct weston_output *output, uint32_t flags) { struct pixman_output_state *po; int w, h; @@ -911,25 +920,27 @@ pixman_renderer_output_create(struct weston_output *output) if (po == NULL) return -1; - /* set shadow image transformation */ - w = output->current_mode->width; - h = output->current_mode->height; + if (flags & PIXMAN_RENDERER_OUTPUT_USE_SHADOW) { + /* set shadow image transformation */ + w = output->current_mode->width; + h = output->current_mode->height; - po->shadow_buffer = malloc(w * h * 4); + po->shadow_buffer = malloc(w * h * 4); - if (!po->shadow_buffer) { - free(po); - return -1; - } + if (!po->shadow_buffer) { + free(po); + return -1; + } - po->shadow_image = - pixman_image_create_bits(PIXMAN_x8r8g8b8, w, h, - po->shadow_buffer, w * 4); + po->shadow_image = + pixman_image_create_bits(PIXMAN_x8r8g8b8, w, h, + po->shadow_buffer, w * 4); - if (!po->shadow_image) { - free(po->shadow_buffer); - free(po); - return -1; + if (!po->shadow_image) { + free(po->shadow_buffer); + free(po); + return -1; + } } output->renderer_state = po; @@ -942,7 +953,8 @@ pixman_renderer_output_destroy(struct weston_output *output) { struct pixman_output_state *po = get_output_state(output); - pixman_image_unref(po->shadow_image); + if (po->shadow_image) + pixman_image_unref(po->shadow_image); if (po->hw_buffer) pixman_image_unref(po->hw_buffer); diff --git a/libweston/pixman-renderer.h b/libweston/pixman-renderer.h index f19e14779..7a5f72901 100644 --- a/libweston/pixman-renderer.h +++ b/libweston/pixman-renderer.h @@ -30,8 +30,12 @@ int pixman_renderer_init(struct weston_compositor *ec); +enum pixman_renderer_output_flags { + PIXMAN_RENDERER_OUTPUT_USE_SHADOW = (1 << 0), +}; + int -pixman_renderer_output_create(struct weston_output *output); +pixman_renderer_output_create(struct weston_output *output, uint32_t flags); void pixman_renderer_output_set_buffer(struct weston_output *output,