summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.ac2
-rw-r--r--packaging/hal-backend-tdm-vc4.spec1
-rw-r--r--src/tdm_vc4_hwc.c277
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);