Hello Tobias,
I was in vacation last week, so I could run your code today. I found that what g2d_move() does is actually copying not moving, because the operation does not clear the previous area. Would it be possible to generalize g2d_copy() works better, so it could works well in case of the src buffer and dst buffer being same. If it is possible, I think it would be better way to do that. If it is not, at least chaning the function name is needed. I tested it on my Odroid U3 board.
Best regards, Hyungwon Hwang
On Tue, 22 Sep 2015 17:54:58 +0200 Tobias Jakobi tjakobi@math.uni-bielefeld.de wrote:
We already have g2d_copy() which implements G2D copy operations from one buffer to another. However we can't do a overlapping copy operation in one buffer.
Add g2d_move() which acts like the standard memmove() and properly handles overlapping copies.
Signed-off-by: Tobias Jakobi tjakobi@math.uni-bielefeld.de
exynos/exynos_fimg2d.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++ exynos/exynos_fimg2d.h | 3 ++ 2 files changed, 97 insertions(+)
diff --git a/exynos/exynos_fimg2d.c b/exynos/exynos_fimg2d.c index 4d5419c..8703629 100644 --- a/exynos/exynos_fimg2d.c +++ b/exynos/exynos_fimg2d.c @@ -540,6 +540,100 @@ g2d_copy(struct g2d_context *ctx, struct g2d_image *src, }
/**
- g2d_move - move content inside single buffer.
- Similar to 'memmove' this moves a rectangular region
- of the provided buffer to another location (the source
- and destination region potentially overlapping).
- @ctx: a pointer to g2d_context structure.
- @img: a pointer to g2d_image structure providing
- buffer information.
- @src_x: x position of source rectangle.
- @src_y: y position of source rectangle.
- @dst_x: x position of destination rectangle.
- @dst_y: y position of destination rectangle.
- @w: width of rectangle to move.
- @h: height of rectangle to move.
- */
+int +g2d_move(struct g2d_context *ctx, struct g2d_image *img,
unsigned int src_x, unsigned int src_y,
unsigned int dst_x, unsigned dst_y, unsigned int w,
unsigned int h)
+{
- union g2d_rop4_val rop4;
- union g2d_point_val pt;
- union g2d_direction_val dir;
- unsigned int src_w, src_h, dst_w, dst_h;
- src_w = w;
- src_h = h;
- if (src_x + img->width > w)
src_w = img->width - src_x;
- if (src_y + img->height > h)
src_h = img->height - src_y;
- dst_w = w;
- dst_h = w;
- if (dst_x + img->width > w)
dst_w = img->width - dst_x;
- if (dst_y + img->height > h)
dst_h = img->height - dst_y;
- w = MIN(src_w, dst_w);
- h = MIN(src_h, dst_h);
- if (w == 0 || h == 0) {
fprintf(stderr, MSG_PREFIX "invalid width or
height.\n");
return -EINVAL;
- }
- if (g2d_check_space(ctx, 13, 2))
return -ENOSPC;
- g2d_add_cmd(ctx, DST_SELECT_REG, G2D_SELECT_MODE_BGCOLOR);
- g2d_add_cmd(ctx, SRC_SELECT_REG, G2D_SELECT_MODE_NORMAL);
- g2d_add_cmd(ctx, DST_COLOR_MODE_REG, img->color_mode);
- g2d_add_cmd(ctx, SRC_COLOR_MODE_REG, img->color_mode);
- g2d_add_base_addr(ctx, img, g2d_dst);
- g2d_add_base_addr(ctx, img, g2d_src);
- g2d_add_cmd(ctx, DST_STRIDE_REG, img->stride);
- g2d_add_cmd(ctx, SRC_STRIDE_REG, img->stride);
- dir.val[0] = dir.val[1] = 0;
- if (dst_x >= src_x)
dir.data.src_x_direction = dir.data.dst_x_direction
= 1;
- if (dst_y >= src_y)
dir.data.src_y_direction = dir.data.dst_y_direction
= 1; +
- g2d_set_direction(ctx, &dir);
- pt.data.x = src_x;
- pt.data.y = src_y;
- g2d_add_cmd(ctx, SRC_LEFT_TOP_REG, pt.val);
- pt.data.x = src_x + w;
- pt.data.y = src_y + h;
- g2d_add_cmd(ctx, SRC_RIGHT_BOTTOM_REG, pt.val);
- pt.data.x = dst_x;
- pt.data.y = dst_y;
- g2d_add_cmd(ctx, DST_LEFT_TOP_REG, pt.val);
- pt.data.x = dst_x + w;
- pt.data.y = dst_y + h;
- g2d_add_cmd(ctx, DST_RIGHT_BOTTOM_REG, pt.val);
- rop4.val = 0;
- rop4.data.unmasked_rop3 = G2D_ROP3_SRC;
- g2d_add_cmd(ctx, ROP4_REG, rop4.val);
- return g2d_flush(ctx);
+}
+/**
- g2d_copy_with_scale - copy contents in source buffer to
destination buffer
- scaling up or down properly.
diff --git a/exynos/exynos_fimg2d.h b/exynos/exynos_fimg2d.h index 9eee7c0..2700686 100644 --- a/exynos/exynos_fimg2d.h +++ b/exynos/exynos_fimg2d.h @@ -343,6 +343,9 @@ int g2d_copy(struct g2d_context *ctx, struct g2d_image *src, struct g2d_image *dst, unsigned int src_x, unsigned int src_y, unsigned int dst_x, unsigned int dst_y, unsigned int w, unsigned int h); +int g2d_move(struct g2d_context *ctx, struct g2d_image *img,
unsigned int src_x, unsigned int src_y, unsigned int
dst_x,
unsigned dst_y, unsigned int w, unsigned int h);
int g2d_copy_with_scale(struct g2d_context *ctx, struct g2d_image *src, struct g2d_image *dst, unsigned int src_x, unsigned int src_y, unsigned int src_w,