diff options
author | Tobias Jakobi | 2015-03-11 14:38:41 -0500 |
---|---|---|
committer | Emil Velikov | 2015-03-16 17:18:05 -0500 |
commit | 03c9cccfa03b999874f794c02ddce7e7dfb04c93 (patch) | |
tree | 7fe91c64d35ace64aa832ab12565e2695e8310d1 | |
parent | 6f950de953ead6391ffa82b6c517fd4ea3ce3e29 (diff) | |
download | external-libdrm-03c9cccfa03b999874f794c02ddce7e7dfb04c93.tar.gz external-libdrm-03c9cccfa03b999874f794c02ddce7e7dfb04c93.tar.xz external-libdrm-03c9cccfa03b999874f794c02ddce7e7dfb04c93.zip |
exynos: add g2d_scale_and_blend
This is a combination of g2d_copy_with_scale and g2d_scale.
It is a pretty common operation to scale one buffer and then
blend it on top of another, so provide a direct way to that
operation.
Signed-off-by: Tobias Jakobi <tjakobi@math.uni-bielefeld.de>
Reviewed-by: Inki Dae <inki.dae@samsung.com>
Tested-by: Joonyoung Shim <jy0922.shim@samsung.com>
-rw-r--r-- | exynos/exynos_fimg2d.c | 129 | ||||
-rw-r--r-- | exynos/fimg2d.h | 5 |
2 files changed, 134 insertions, 0 deletions
diff --git a/exynos/exynos_fimg2d.c b/exynos/exynos_fimg2d.c index 7a3da823..20c31790 100644 --- a/exynos/exynos_fimg2d.c +++ b/exynos/exynos_fimg2d.c | |||
@@ -638,3 +638,132 @@ g2d_blend(struct g2d_context *ctx, struct g2d_image *src, | |||
638 | return 0; | 638 | return 0; |
639 | } | 639 | } |
640 | 640 | ||
641 | /** | ||
642 | * g2d_scale_and_blend - apply scaling to source buffer and then blend to destination buffer | ||
643 | * | ||
644 | * @ctx: a pointer to g2d_context structure. | ||
645 | * @src: a pointer to g2d_image structure including image and buffer | ||
646 | * information to source. | ||
647 | * @dst: a pointer to g2d_image structure including image and buffer | ||
648 | * information to destination. | ||
649 | * @src_x: x start position to source buffer. | ||
650 | * @src_y: y start position to source buffer. | ||
651 | * @src_w: width value to source buffer. | ||
652 | * @src_h: height value to source buffer. | ||
653 | * @dst_x: x start position to destination buffer. | ||
654 | * @dst_y: y start position to destination buffer. | ||
655 | * @dst_w: width value to destination buffer. | ||
656 | * @dst_h: height value to destination buffer. | ||
657 | * @op: blend operation type. | ||
658 | */ | ||
659 | drm_public int | ||
660 | g2d_scale_and_blend(struct g2d_context *ctx, struct g2d_image *src, | ||
661 | struct g2d_image *dst, unsigned int src_x, unsigned int src_y, | ||
662 | unsigned int src_w, unsigned int src_h, unsigned int dst_x, | ||
663 | unsigned int dst_y, unsigned int dst_w, unsigned int dst_h, | ||
664 | enum e_g2d_op op) | ||
665 | { | ||
666 | union g2d_point_val pt; | ||
667 | union g2d_bitblt_cmd_val bitblt; | ||
668 | union g2d_blend_func_val blend; | ||
669 | unsigned int scale; | ||
670 | unsigned int scale_x, scale_y; | ||
671 | |||
672 | bitblt.val = 0; | ||
673 | blend.val = 0; | ||
674 | |||
675 | if (op == G2D_OP_SRC || op == G2D_OP_CLEAR) | ||
676 | g2d_add_cmd(ctx, DST_SELECT_REG, G2D_SELECT_MODE_BGCOLOR); | ||
677 | else | ||
678 | g2d_add_cmd(ctx, DST_SELECT_REG, G2D_SELECT_MODE_NORMAL); | ||
679 | |||
680 | g2d_add_cmd(ctx, DST_COLOR_MODE_REG, dst->color_mode); | ||
681 | if (dst->buf_type == G2D_IMGBUF_USERPTR) | ||
682 | g2d_add_cmd(ctx, DST_BASE_ADDR_REG | G2D_BUF_USERPTR, | ||
683 | (unsigned long)&dst->user_ptr[0]); | ||
684 | else | ||
685 | g2d_add_cmd(ctx, DST_BASE_ADDR_REG, dst->bo[0]); | ||
686 | |||
687 | g2d_add_cmd(ctx, DST_STRIDE_REG, dst->stride); | ||
688 | |||
689 | g2d_add_cmd(ctx, SRC_SELECT_REG, src->select_mode); | ||
690 | g2d_add_cmd(ctx, SRC_COLOR_MODE_REG, src->color_mode); | ||
691 | |||
692 | switch (src->select_mode) { | ||
693 | case G2D_SELECT_MODE_NORMAL: | ||
694 | if (src->buf_type == G2D_IMGBUF_USERPTR) | ||
695 | g2d_add_cmd(ctx, SRC_BASE_ADDR_REG | G2D_BUF_USERPTR, | ||
696 | (unsigned long)&src->user_ptr[0]); | ||
697 | else | ||
698 | g2d_add_cmd(ctx, SRC_BASE_ADDR_REG, src->bo[0]); | ||
699 | |||
700 | g2d_add_cmd(ctx, SRC_STRIDE_REG, src->stride); | ||
701 | break; | ||
702 | case G2D_SELECT_MODE_FGCOLOR: | ||
703 | g2d_add_cmd(ctx, FG_COLOR_REG, src->color); | ||
704 | break; | ||
705 | case G2D_SELECT_MODE_BGCOLOR: | ||
706 | g2d_add_cmd(ctx, BG_COLOR_REG, src->color); | ||
707 | break; | ||
708 | default: | ||
709 | fprintf(stderr , "failed to set src.\n"); | ||
710 | return -EINVAL; | ||
711 | } | ||
712 | |||
713 | if (src_w == dst_w && src_h == dst_h) | ||
714 | scale = 0; | ||
715 | else { | ||
716 | scale = 1; | ||
717 | scale_x = g2d_get_scaling(src_w, dst_w); | ||
718 | scale_y = g2d_get_scaling(src_h, dst_h); | ||
719 | } | ||
720 | |||
721 | if (src_x + src_w > src->width) | ||
722 | src_w = src->width - src_x; | ||
723 | if (src_y + src_h > src->height) | ||
724 | src_h = src->height - src_y; | ||
725 | |||
726 | if (dst_x + dst_w > dst->width) | ||
727 | dst_w = dst->width - dst_x; | ||
728 | if (dst_y + dst_h > dst->height) | ||
729 | dst_h = dst->height - dst_y; | ||
730 | |||
731 | if (src_w <= 0 || src_h <= 0 || dst_w <= 0 || dst_h <= 0) { | ||
732 | fprintf(stderr, "invalid width or height.\n"); | ||
733 | g2d_reset(ctx); | ||
734 | return -EINVAL; | ||
735 | } | ||
736 | |||
737 | if (scale) { | ||
738 | g2d_add_cmd(ctx, SRC_SCALE_CTRL_REG, G2D_SCALE_MODE_BILINEAR); | ||
739 | g2d_add_cmd(ctx, SRC_XSCALE_REG, scale_x); | ||
740 | g2d_add_cmd(ctx, SRC_YSCALE_REG, scale_y); | ||
741 | } | ||
742 | |||
743 | bitblt.data.alpha_blend_mode = G2D_ALPHA_BLEND_MODE_ENABLE; | ||
744 | blend.val = g2d_get_blend_op(op); | ||
745 | g2d_add_cmd(ctx, BITBLT_COMMAND_REG, bitblt.val); | ||
746 | g2d_add_cmd(ctx, BLEND_FUNCTION_REG, blend.val); | ||
747 | |||
748 | pt.val = 0; | ||
749 | pt.data.x = src_x; | ||
750 | pt.data.y = src_y; | ||
751 | g2d_add_cmd(ctx, SRC_LEFT_TOP_REG, pt.val); | ||
752 | pt.val = 0; | ||
753 | pt.data.x = src_x + src_w; | ||
754 | pt.data.y = src_y + src_h; | ||
755 | g2d_add_cmd(ctx, SRC_RIGHT_BOTTOM_REG, pt.val); | ||
756 | |||
757 | pt.val = 0; | ||
758 | pt.data.x = dst_x; | ||
759 | pt.data.y = dst_y; | ||
760 | g2d_add_cmd(ctx, DST_LEFT_TOP_REG, pt.val); | ||
761 | pt.val = 0; | ||
762 | pt.data.x = dst_x + dst_w; | ||
763 | pt.data.y = dst_y + dst_h; | ||
764 | g2d_add_cmd(ctx, DST_RIGHT_BOTTOM_REG, pt.val); | ||
765 | |||
766 | g2d_flush(ctx); | ||
767 | |||
768 | return 0; | ||
769 | } | ||
diff --git a/exynos/fimg2d.h b/exynos/fimg2d.h index c6d67caf..f76f2a9f 100644 --- a/exynos/fimg2d.h +++ b/exynos/fimg2d.h | |||
@@ -314,4 +314,9 @@ int g2d_blend(struct g2d_context *ctx, struct g2d_image *src, | |||
314 | struct g2d_image *dst, unsigned int src_x, | 314 | struct g2d_image *dst, unsigned int src_x, |
315 | unsigned int src_y, unsigned int dst_x, unsigned int dst_y, | 315 | unsigned int src_y, unsigned int dst_x, unsigned int dst_y, |
316 | unsigned int w, unsigned int h, enum e_g2d_op op); | 316 | unsigned int w, unsigned int h, enum e_g2d_op op); |
317 | int g2d_scale_and_blend(struct g2d_context *ctx, struct g2d_image *src, | ||
318 | struct g2d_image *dst, unsigned int src_x, unsigned int src_y, | ||
319 | unsigned int src_w, unsigned int src_h, unsigned int dst_x, | ||
320 | unsigned int dst_y, unsigned int dst_w, unsigned int dst_h, | ||
321 | enum e_g2d_op op); | ||
317 | #endif /* _FIMG2D_H_ */ | 322 | #endif /* _FIMG2D_H_ */ |