From 44148675a8e6008862dbee9574eab01727686b0d Mon Sep 17 00:00:00 2001 From: Junghoon Date: Sun, 22 Nov 2015 15:21:29 +0900 Subject: [PATCH] render: pixman-renderer: change repaint_view - apply buffer transform & scale - repaint opaque region separately Change-Id: I98b0d2f148d940755c267f3427fab56050101bac --- src/lib/pepper/misc.c | 2 +- src/lib/pepper/pepper.h | 3 + src/lib/render/pixman-renderer.c | 136 +++++++++++++++++++++++++++---- 3 files changed, 125 insertions(+), 16 deletions(-) diff --git a/src/lib/pepper/misc.c b/src/lib/pepper/misc.c index fa9fba5..aefe908 100644 --- a/src/lib/pepper/misc.c +++ b/src/lib/pepper/misc.c @@ -28,7 +28,7 @@ #include "pepper-internal.h" -void +PEPPER_API void pepper_pixman_region_global_to_output(pixman_region32_t *region, pepper_output_t *output) { pixman_box32_t *box, b; diff --git a/src/lib/pepper/pepper.h b/src/lib/pepper/pepper.h index 52ab10d..01c6a42 100644 --- a/src/lib/pepper/pepper.h +++ b/src/lib/pepper/pepper.h @@ -1270,6 +1270,9 @@ PEPPER_API void pepper_view_get_global_coordinate(pepper_view_t *view, double lx, double ly, double *gx, double *gy); /* Misc */ +PEPPER_API void +pepper_pixman_region_global_to_output(pixman_region32_t *region, pepper_output_t *output); + PEPPER_API void pepper_coordinates_surface_to_buffer(pepper_surface_t *surface, double sx, double sy, double *bx, double *by); diff --git a/src/lib/render/pixman-renderer.c b/src/lib/render/pixman-renderer.c index 3077e03..76319d7 100644 --- a/src/lib/render/pixman-renderer.c +++ b/src/lib/render/pixman-renderer.c @@ -285,10 +285,15 @@ pixman_transform_from_pepper_mat4(pixman_transform_t *transform, pepper_mat4_t * } static void -repaint_view(pepper_renderer_t *renderer, pepper_render_item_t *node, pixman_region32_t *damage) +repaint_view(pepper_renderer_t *renderer, pepper_output_t *output, + pepper_render_item_t *node, pixman_region32_t *damage) { + int32_t x, y, w, h, scale; + pepper_surface_t *surface = pepper_view_get_surface(node->view); + pixman_render_target_t *target = (pixman_render_target_t*)renderer->target; - pixman_region32_t repaint; + pixman_region32_t repaint, repaint_surface; + pixman_region32_t surface_blend, *surface_opaque; pixman_surface_state_t *ps = get_surface_state(renderer, pepper_view_get_surface(node->view)); pixman_region32_init(&repaint); @@ -308,23 +313,124 @@ repaint_view(pepper_renderer_t *renderer, pepper_render_item_t *node, pixman_reg } else { - pixman_transform_from_pepper_mat4(&trans, &node->transform); - pixman_transform_invert(&trans, &trans); + pixman_transform_from_pepper_mat4(&trans, &node->inverse); filter = PIXMAN_FILTER_BILINEAR; } + scale = pepper_surface_get_buffer_scale(surface); + pepper_surface_get_buffer_offset(surface, &x, &y); + pepper_surface_get_size(surface, &w, &h); + pixman_transform_scale(&trans, NULL, + pixman_double_to_fixed(1.0 / scale), + pixman_double_to_fixed(1.0 / scale)); + + switch (pepper_surface_get_buffer_transform(surface)) + { + case WL_OUTPUT_TRANSFORM_FLIPPED: + case WL_OUTPUT_TRANSFORM_FLIPPED_180: + pixman_transform_scale(&trans, NULL, pixman_int_to_fixed(-1), pixman_int_to_fixed(1)); + pixman_transform_translate(&trans, NULL, pixman_int_to_fixed(w), 0); + break; + case WL_OUTPUT_TRANSFORM_FLIPPED_90: + case WL_OUTPUT_TRANSFORM_FLIPPED_270: + pixman_transform_scale(&trans, NULL, pixman_int_to_fixed(-1), pixman_int_to_fixed(1)); + pixman_transform_translate(&trans, NULL, pixman_int_to_fixed(h), 0); + break; + } + switch (pepper_surface_get_buffer_transform(surface)) + { + case WL_OUTPUT_TRANSFORM_NORMAL: + case WL_OUTPUT_TRANSFORM_FLIPPED: + break; + case WL_OUTPUT_TRANSFORM_90: + case WL_OUTPUT_TRANSFORM_FLIPPED_270: + pixman_transform_rotate(&trans, NULL, 0, -pixman_fixed_1); + pixman_transform_translate(&trans, NULL, 0, pixman_int_to_fixed(w)); + break; + case WL_OUTPUT_TRANSFORM_180: + case WL_OUTPUT_TRANSFORM_FLIPPED_180: + pixman_transform_rotate(&trans, NULL, -pixman_fixed_1, 0); + pixman_transform_translate(&trans, NULL, + pixman_int_to_fixed(w), + pixman_int_to_fixed(h)); + break; + case WL_OUTPUT_TRANSFORM_270: + case WL_OUTPUT_TRANSFORM_FLIPPED_90: + pixman_transform_rotate(&trans, NULL, 0, pixman_fixed_1); + pixman_transform_translate(&trans, NULL, pixman_int_to_fixed(h), 0); + break; + } + + pixman_transform_translate(&trans, NULL, + pixman_int_to_fixed(x), pixman_int_to_fixed(y)); + pixman_image_set_transform(ps->image, &trans); pixman_image_set_filter(ps->image, filter, NULL, 0); - pixman_image_set_clip_region32(target->image, &repaint); - - wl_shm_buffer_begin_access(ps->shm_buffer); - pixman_image_composite32(PIXMAN_OP_OVER, ps->image, NULL, target->image, - 0, 0, /* src_x, src_y */ - 0, 0, /* mask_x, mask_y */ - 0, 0, /* dest_x, dest_y */ - pixman_image_get_width(target->image), - pixman_image_get_height(target->image)); - wl_shm_buffer_end_access(ps->shm_buffer); + + pixman_region32_init(&repaint_surface); + pixman_region32_init_rect(&surface_blend, 0, 0, w, h); + + if (node->transform.flags <= PEPPER_MATRIX_TRANSLATE) + { + surface_opaque = pepper_surface_get_opaque_region(surface); + pixman_region32_subtract(&surface_blend, &surface_blend, surface_opaque); + + if (pixman_region32_not_empty(surface_opaque)) + { + pixman_region32_translate(surface_opaque, + (int)node->transform.m[12], (int)node->transform.m[13]); + pepper_pixman_region_global_to_output(surface_opaque, output); + pixman_region32_intersect(&repaint_surface, &repaint, surface_opaque); + pixman_image_set_clip_region32(target->image, &repaint_surface); + + wl_shm_buffer_begin_access(ps->shm_buffer); + pixman_image_composite32(PIXMAN_OP_SRC, ps->image, NULL, target->image, + 0, 0, /* src_x, src_y */ + 0, 0, /* mask_x, mask_y */ + 0, 0, /* dest_x, dest_y */ + pixman_image_get_width(target->image), + pixman_image_get_height(target->image)); + wl_shm_buffer_end_access(ps->shm_buffer); + } + + if (pixman_region32_not_empty(&surface_blend)) + { + pixman_region32_translate(&surface_blend, + (int)node->transform.m[12], (int)node->transform.m[13]); + pepper_pixman_region_global_to_output(&surface_blend, output); + pixman_region32_intersect(&repaint_surface, &repaint, &surface_blend); + pixman_image_set_clip_region32(target->image, &repaint_surface); + + wl_shm_buffer_begin_access(ps->shm_buffer); + pixman_image_composite32(PIXMAN_OP_OVER, ps->image, NULL, target->image, + 0, 0, /* src_x, src_y */ + 0, 0, /* mask_x, mask_y */ + 0, 0, /* dest_x, dest_y */ + pixman_image_get_width(target->image), + pixman_image_get_height(target->image)); + wl_shm_buffer_end_access(ps->shm_buffer); + } + } + else + { + pixman_region32_translate(&surface_blend, + (int)node->transform.m[12], (int)node->transform.m[13]); + pepper_pixman_region_global_to_output(&surface_blend, output); + pixman_region32_intersect(&repaint_surface, &repaint, &surface_blend); + pixman_image_set_clip_region32(target->image, &repaint_surface); + + wl_shm_buffer_begin_access(ps->shm_buffer); + pixman_image_composite32(PIXMAN_OP_OVER, ps->image, NULL, target->image, + 0, 0, /* src_x, src_y */ + 0, 0, /* mask_x, mask_y */ + 0, 0, /* dest_x, dest_y */ + pixman_image_get_width(target->image), + pixman_image_get_height(target->image)); + wl_shm_buffer_end_access(ps->shm_buffer); + } + + pixman_region32_fini(&repaint_surface); + pixman_region32_fini(&surface_blend); } pixman_region32_fini(&repaint); @@ -356,7 +462,7 @@ pixman_renderer_repaint_output(pepper_renderer_t *renderer, pepper_output_t *out clear_background((pixman_renderer_t *)renderer, damage); pepper_list_for_each_list_reverse(l, render_list) - repaint_view(renderer, (pepper_render_item_t *)l->item, damage); + repaint_view(renderer, output, (pepper_render_item_t *)l->item, damage); } } -- 2.34.1