diff options
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | packaging/hal-backend-tdm-vc4.spec | 1 | ||||
-rw-r--r-- | src/tdm_vc4_hwc.c | 277 |
3 files changed, 218 insertions, 62 deletions
diff --git a/configure.ac b/configure.ac index 9f38f12..e105b33 100644 --- a/configure.ac +++ b/configure.ac @@ -23,7 +23,7 @@ LT_INIT([disable-static]) # Enable quiet compiles on automake 1.11. m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) -PKG_CHECK_MODULES(LIBHAL_BACKEND_TDM_VC4, hal-api-common hal-api-tdm hal-api-tbm libdrm dlog pixman-1 libtbm) +PKG_CHECK_MODULES(LIBHAL_BACKEND_TDM_VC4, hal-api-common hal-api-tdm hal-api-tbm libdrm dlog libtbm) PKG_CHECK_MODULES(UDEV, libudev, [udev=yes], [udev=no]) if test x"$udev" = xyes; then diff --git a/packaging/hal-backend-tdm-vc4.spec b/packaging/hal-backend-tdm-vc4.spec index 384455b..9e19607 100644 --- a/packaging/hal-backend-tdm-vc4.spec +++ b/packaging/hal-backend-tdm-vc4.spec @@ -14,7 +14,6 @@ BuildRequires: pkgconfig(libtbm) BuildRequires: pkgconfig(hal-api-common) BuildRequires: pkgconfig(hal-api-tdm) BuildRequires: pkgconfig(hal-api-tbm) -BuildRequires: pkgconfig(pixman-1) ExclusiveArch: %{arm} aarch64 %description diff --git a/src/tdm_vc4_hwc.c b/src/tdm_vc4_hwc.c index 7656db6..c5bbc95 100644 --- a/src/tdm_vc4_hwc.c +++ b/src/tdm_vc4_hwc.c @@ -33,7 +33,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #endif #include "tdm_backend_vc4.h" -#include <pixman.h> #define NUM_BUFFERS 3 @@ -149,89 +148,247 @@ _vc4_hwc_window_get_cursor_tbm_buffer_queue(hal_tdm_hwc_window *hwc_window, hal_ return tqueue; } -static int -_vc4_hwc_cursor_buffer_image_render(tdm_vc4_hwc *hwc_data, tdm_vc4_hwc_window *hwc_window_data) +static void +_vc4_hwc_cursor_buffer_rotate90(void *src_ptr, int src_w, int src_h, void *dst_ptr, int dst_stride) +{ + int i, j, size = 4; + + for (i = 0; i < src_h; i++) { + for (j = 0; j < src_w; j++) { + memcpy(dst_ptr + (i + (src_w - 1 - j) * src_h) * 4, src_ptr + (j + i * src_w) * 4, size); + } + } +} + +static void +_vc4_hwc_cursor_buffer_rotate180(void *src_ptr, int src_w, int src_h, void *dst_ptr, int dst_stride) +{ + int i, j, size = 4; + + for (i = 0; i < src_h; i++) { + for (j = 0; j < src_w; j++) { + memcpy(dst_ptr + ((src_w - 1 - j) + (src_h - 1 - i) * dst_stride / 4) * 4, src_ptr + (j + i * src_w) * 4, size); + } + } +} + +static void +_vc4_hwc_cursor_buffer_rotate270(void *src_ptr, int src_w, int src_h, void *dst_ptr, int dst_stride) +{ + int i, j, size = 4; + + for (i = 0; i < src_h; i++) { + for (j = 0; j < src_w; j++) { + memcpy(dst_ptr + ((src_h - 1 - i) + j * src_h) * 4, src_ptr + (j + i * src_w) * 4, size); + } + } +} + +static void +_vc4_hwc_cursor_buffer_flip(void *src_ptr, int src_w, int src_h, void *dst_ptr, int dst_stride) +{ + int i, j, size = 4; + + for (i = 0; i < src_h; i++) { + for (j = 0; j < src_w; j++) { + memcpy(dst_ptr + ((src_w - 1 - j) + i * dst_stride / 4) * 4, src_ptr + (j + i * src_w) * 4, size); + } + } +} + +static void +_vc4_hwc_cursor_buffer_flip_rotate90(void *src_ptr, int src_w, int src_h, void *dst_ptr, int dst_stride) +{ + int i, j, size = 4; + void *tmp_ptr; + + tmp_ptr = calloc(src_w * src_h, sizeof(uint32_t)); + + for (i = 0; i < src_h; i++) { + for (j = 0; j < src_w; j++) { + memcpy(tmp_ptr + (i + (src_w - 1 - j) * src_h) * 4, src_ptr + (j + i * src_w) * 4, size); + } + } + + for (i = 0; i < src_w; i++) { + for (j = 0; j < src_h; j++) { + memcpy(dst_ptr + ((src_h - 1 - j) + i * dst_stride / 4) * 4, tmp_ptr + (j + i * src_h) * 4, size); + } + } + + free(tmp_ptr); +} + +static void +_vc4_hwc_cursor_buffer_flip_rotate180(void *src_ptr, int src_w, int src_h, void *dst_ptr, int dst_stride) +{ + int i, j, size = 4; + void *tmp_ptr; + + tmp_ptr = calloc(src_w * src_h, sizeof(uint32_t)); + + for (i = 0; i < src_h; i++) { + for (j = 0; j < src_w; j++) { + memcpy(tmp_ptr + ((src_w - 1 - j) + (src_h - 1 - i) * src_w) * 4, src_ptr + (j + i * src_w) * 4, size); + } + } + + for (i = 0; i < src_h; i++) { + for (j = 0; j < src_w; j++) { + memcpy(dst_ptr + ((src_w - 1 - j) + i * dst_stride / 4) * 4, tmp_ptr + (j + i * src_w) * 4, size); + } + } + + free(tmp_ptr); +} + +static void +_vc4_hwc_cursor_buffer_flip_rotate270(void *src_ptr, int src_w, int src_h, void *dst_ptr, int dst_stride) +{ + int i, j, size = 4; + void *tmp_ptr; + + tmp_ptr = calloc(src_w * src_h, sizeof(uint32_t)); + + for (i = 0; i < src_h; i++) { + for (j = 0; j < src_w; j++) { + memcpy(tmp_ptr + ((src_h - 1 - i) + j * src_h) * 4, src_ptr + (j + i * src_w) * 4, size); + } + } + + for (i = 0; i < src_w; i++) { + for (j = 0; j < src_h; j++) { + memcpy(dst_ptr + ((src_h - 1 - j) + i * dst_stride / 4) * 4, tmp_ptr + (j + i * src_h) * 4, size); + } + } + + free(tmp_ptr); +} + +static tbm_surface_h +_vc4_hwc_cursor_buffer_make_src(void *src_ptr, int src_w, int src_h, int transform) { + tbm_surface_h tmp_surface = NULL; tbm_surface_info_s tsurface_info; tbm_surface_error_e ret = TBM_SURFACE_ERROR_NONE; - void *src_ptr = NULL, *dst_ptr = NULL; - int src_stride, transform, img_w, img_h; - pixman_image_t *src_img = NULL, *dst_img = NULL; - pixman_transform_t t; - struct pixman_f_transform ft; - int c = 0, s = 0, tx = 0, ty = 0; - int i; + void *dst_ptr = NULL; + int stride = 0; + + if (transform % 2) + tmp_surface = tbm_surface_create(src_h, src_w, TBM_FORMAT_ARGB8888); + else + tmp_surface = tbm_surface_create(src_w, src_h, TBM_FORMAT_ARGB8888); + + if (tmp_surface == NULL) { + TDM_BACKEND_ERR("Failed to create tsurface\n"); + return NULL; + } - ret = tbm_surface_map(hwc_data->cursor_tsurface, TBM_SURF_OPTION_WRITE, &tsurface_info); + ret = tbm_surface_map(tmp_surface, TBM_SURF_OPTION_WRITE, &tsurface_info); if (ret != TBM_SURFACE_ERROR_NONE) { TDM_BACKEND_ERR("Failed to map tsurface\n"); - return 0; + tbm_surface_destroy(tmp_surface); + return NULL; + } + + dst_ptr = tsurface_info.planes[0].ptr; + stride = tsurface_info.planes[0].stride; + memset(dst_ptr, 0, stride * tsurface_info.height); + + switch (transform) { + case HAL_TDM_TRANSFORM_90: + _vc4_hwc_cursor_buffer_rotate90(src_ptr, src_w, src_h, dst_ptr, stride); + break; + case HAL_TDM_TRANSFORM_180: + _vc4_hwc_cursor_buffer_rotate180(src_ptr, src_w, src_h, dst_ptr, stride); + break; + case HAL_TDM_TRANSFORM_270: + _vc4_hwc_cursor_buffer_rotate270(src_ptr, src_w, src_h, dst_ptr, stride); + break; + case HAL_TDM_TRANSFORM_FLIPPED: + _vc4_hwc_cursor_buffer_flip(src_ptr, src_w, src_h, dst_ptr, stride); + break; + case HAL_TDM_TRANSFORM_FLIPPED_90: + _vc4_hwc_cursor_buffer_flip_rotate90(src_ptr, src_w, src_h, dst_ptr, stride); + break; + case HAL_TDM_TRANSFORM_FLIPPED_180: + _vc4_hwc_cursor_buffer_flip_rotate180(src_ptr, src_w, src_h, dst_ptr, stride); + break; + case HAL_TDM_TRANSFORM_FLIPPED_270: + _vc4_hwc_cursor_buffer_flip_rotate270(src_ptr, src_w, src_h, dst_ptr, stride); + break; + default: + tbm_surface_unmap(tmp_surface); + tbm_surface_destroy(tmp_surface); + return NULL; + } + + ret = tbm_surface_unmap(tmp_surface); + if (ret != TBM_SURFACE_ERROR_NONE) { + TDM_BACKEND_ERR("Failed to unmap tsurface\n"); + tbm_surface_destroy(tmp_surface); + return NULL; } + return tmp_surface; +} + +static int +_vc4_hwc_cursor_buffer_image_render(tdm_vc4_hwc *hwc_data, tdm_vc4_hwc_window *hwc_window_data) +{ + tbm_surface_h tmp_surface = NULL; + tbm_surface_info_s tsurface_info_src, tsurface_info_dst; + tbm_surface_error_e ret = TBM_SURFACE_ERROR_NONE; + void *src_ptr = NULL, *dst_ptr = NULL; + int src_stride, dst_stride, transform, img_w, img_h; + int i; + src_ptr = hwc_window_data->cursor_img.ptr; src_stride = hwc_window_data->cursor_img.stride; img_w = hwc_window_data->cursor_img.width; img_h = hwc_window_data->cursor_img.height; transform = hwc_window_data->info.transform; - dst_ptr = tsurface_info.planes[0].ptr; - - memset(dst_ptr, 0, tsurface_info.planes[0].stride * tsurface_info.height); - - if (transform) { - src_img = pixman_image_create_bits(PIXMAN_a8r8g8b8, img_w, img_h, (uint32_t*)src_ptr, src_stride); - if (!src_img) { - TDM_BACKEND_ERR("Failed to create src pixman\n"); + if (transform != HAL_TDM_TRANSFORM_NORMAL) { + tmp_surface = _vc4_hwc_cursor_buffer_make_src(src_ptr, img_w, img_h, transform); + if (tmp_surface == NULL) { + TDM_BACKEND_ERR("Failed to create src surface\n"); return 0; } - dst_img = pixman_image_create_bits(PIXMAN_a8r8g8b8, tsurface_info.width, tsurface_info.height, - (uint32_t*)dst_ptr, tsurface_info.planes[0].stride); - if (!dst_img) { - TDM_BACKEND_ERR("Failed to create dst pixman\n"); - pixman_image_unref(src_img); + ret = tbm_surface_map(tmp_surface, TBM_SURF_OPTION_READ, &tsurface_info_src); + if (ret != TBM_SURFACE_ERROR_NONE) { + tbm_surface_destroy(tmp_surface); + TDM_BACKEND_ERR("Failed to map tsurface\n"); return 0; } - pixman_f_transform_init_identity(&ft); + src_ptr = tsurface_info_src.planes[0].ptr; + src_stride = tsurface_info_src.planes[0].stride; + } - if (transform >= HAL_TDM_TRANSFORM_FLIPPED) { - pixman_f_transform_scale(&ft, NULL, -1, 1); - pixman_f_transform_translate(&ft, NULL, tsurface_info.width, 0); - } + ret = tbm_surface_map(hwc_data->cursor_tsurface, TBM_SURF_OPTION_WRITE, &tsurface_info_dst); + if (ret != TBM_SURFACE_ERROR_NONE) { + tbm_surface_unmap(tmp_surface); + tbm_surface_destroy(tmp_surface); + TDM_BACKEND_ERR("Failed to map tsurface\n"); + return 0; + } - switch (transform) { - case HAL_TDM_TRANSFORM_90: - case HAL_TDM_TRANSFORM_FLIPPED_90: - c = 0, s = 1, ty = -tsurface_info.height; - break; - case HAL_TDM_TRANSFORM_180: - case HAL_TDM_TRANSFORM_FLIPPED_180: - c = -1, s = 0, tx = -tsurface_info.width, ty = -tsurface_info.height; - break; - case HAL_TDM_TRANSFORM_270: - case HAL_TDM_TRANSFORM_FLIPPED_270: - c = 0, s = -1, tx = -tsurface_info.width; - break; - default: - break; - } + dst_ptr = tsurface_info_dst.planes[0].ptr; + dst_stride = tsurface_info_dst.planes[0].stride; - pixman_f_transform_translate(&ft, NULL, tx, ty); - pixman_f_transform_rotate(&ft, NULL, c, s); - pixman_transform_from_pixman_f_transform(&t, &ft); - pixman_image_set_transform(src_img, &t); - pixman_image_composite(PIXMAN_OP_SRC, src_img, NULL, dst_img, 0, 0, 0, 0, 0, 0, - tsurface_info.width, tsurface_info.height); - pixman_image_unref(src_img); - pixman_image_unref(dst_img); + memset(dst_ptr, 0, dst_stride * tsurface_info_dst.height); + + for (i = 0 ; i < img_h ; i++) { + memcpy(dst_ptr, src_ptr, src_stride); + dst_ptr += dst_stride; + src_ptr += src_stride; } - else { - for (i = 0 ; i < img_h ; i++) { - memcpy(dst_ptr, src_ptr, src_stride); - dst_ptr += tsurface_info.planes[0].stride; - src_ptr += src_stride; - } + + if (tmp_surface) { + tbm_surface_unmap(tmp_surface); + tbm_surface_destroy(tmp_surface); } tbm_surface_unmap(hwc_data->cursor_tsurface); |